1(() => { 2 var __create = Object.create; 3 var __defProp = Object.defineProperty; 4 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 var __getOwnPropNames = Object.getOwnPropertyNames; 6 var __getProtoOf = Object.getPrototypeOf; 7 var __hasOwnProp = Object.prototype.hasOwnProperty; 8 var __commonJS = (cb, mod) => function __require() { 9 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 10 }; 11 var __copyProps = (to, from, except, desc) => { 12 if (from && typeof from === "object" || typeof from === "function") { 13 for (let key of __getOwnPropNames(from)) 14 if (!__hasOwnProp.call(to, key) && key !== except) 15 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 16 } 17 return to; 18 }; 19 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); 20 21
vendor: 17,367 bytes, lines 21-461
21// node_modules/tslib/tslib.js 22 var require_tslib = __commonJS({ 23 "node_modules/tslib/tslib.js"(exports, module) { 24 var __extends2; 25 var __assign2; 26 var __rest2; 27 var __decorate2; 28 var __param2; 29 var __metadata2; 30 var __awaiter2; 31 var __generator2; 32 var __exportStar2; 33 var __values2; 34 var __read2; 35 var __spread2; 36 var __spreadArrays2; 37 var __spreadArray2; 38 var __await2; 39 var __asyncGenerator2; 40 var __asyncDelegator2; 41 var __asyncValues2; 42 var __makeTemplateObject2; 43 var __importStar2; 44 var __importDefault2; 45 var __classPrivateFieldGet2; 46 var __classPrivateFieldSet2; 47 var __classPrivateFieldIn2; 48 var __createBinding2; 49 (function(factory2) { 50 var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; 51 if (typeof define === "function" && define.amd) { 52 define("tslib", ["exports"], function(exports2) { 53 factory2(createExporter(root, createExporter(exports2))); 54 }); 55 } else if (typeof module === "object" && typeof module.exports === "object") { 56 factory2(createExporter(root, createExporter(module.exports))); 57 } else { 58 factory2(createExporter(root)); 59 } 60 function createExporter(exports2, previous) { 61 if (exports2 !== root) { 62 if (typeof Object.create === "function") { 63 Object.defineProperty(exports2, "__esModule", { value: true }); 64 } else { 65 exports2.__esModule = true; 66 } 67 } 68 return function(id, v) { 69 return exports2[id] = previous ? previous(id, v) : v; 70 }; 71 } 72 })(function(exporter) { 73 var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) { 74 d.__proto__ = b; 75 } || function(d, b) { 76 for (var p in b) 77 if (Object.prototype.hasOwnProperty.call(b, p)) 78 d[p] = b[p]; 79 }; 80 __extends2 = function(d, b) { 81 if (typeof b !== "function" && b !== null) 82 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 83 extendStatics(d, b); 84 function __() { 85 this.constructor = d; 86 } 87 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 88 }; 89 __assign2 = Object.assign || function(t) { 90 for (var s, i = 1, n = arguments.length; i < n; i++) { 91 s = arguments[i]; 92 for (var p in s) 93 if (Object.prototype.hasOwnProperty.call(s, p)) 94 t[p] = s[p]; 95 } 96 return t; 97 }; 98 __rest2 = function(s, e) { 99 var t = {}; 100 for (var p in s) 101 if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 102 t[p] = s[p]; 103 if (s != null && typeof Object.getOwnPropertySymbols === "function") 104 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 105 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 106 t[p[i]] = s[p[i]]; 107 } 108 return t; 109 }; 110 __decorate2 = function(decorators, target, key, desc) { 111 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 112 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") 113 r = Reflect.decorate(decorators, target, key, desc); 114 else 115 for (var i = decorators.length - 1; i >= 0; i--) 116 if (d = decorators[i]) 117 r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 118 return c > 3 && r && Object.defineProperty(target, key, r), r; 119 }; 120 __param2 = function(paramIndex, decorator) { 121 return function(target, key) { 122 decorator(target, key, paramIndex); 123 }; 124 }; 125 __metadata2 = function(metadataKey, metadataValue) { 126 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") 127 return Reflect.metadata(metadataKey, metadataValue); 128 }; 129 __awaiter2 = function(thisArg, _arguments, P, generator) { 130 function adopt(value) { 131 return value instanceof P ? value : new P(function(resolve) { 132 resolve(value); 133 }); 134 } 135 return new (P || (P = Promise))(function(resolve, reject) { 136 function fulfilled(value) { 137 try { 138 step(generator.next(value)); 139 } catch (e) { 140 reject(e); 141 } 142 } 143 function rejected(value) { 144 try { 145 step(generator["throw"](value)); 146 } catch (e) { 147 reject(e); 148 } 149 } 150 function step(result) { 151 result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); 152 } 153 step((generator = generator.apply(thisArg, _arguments || [])).next()); 154 }); 155 }; 156 __generator2 = function(thisArg, body) { 157 var _ = { label: 0, sent: function() { 158 if (t[0] & 1) 159 throw t[1]; 160 return t[1]; 161 }, trys: [], ops: [] }, f, y, t, g; 162 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { 163 return this; 164 }), g; 165 function verb(n) { 166 return function(v) { 167 return step([n, v]); 168 }; 169 } 170 function step(op) { 171 if (f) 172 throw new TypeError("Generator is already executing."); 173 while (_) 174 try { 175 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) 176 return t; 177 if (y = 0, t) 178 op = [op[0] & 2, t.value]; 179 switch (op[0]) { 180 case 0: 181 case 1: 182 t = op; 183 break; 184 case 4: 185 _.label++; 186 return { value: op[1], done: false }; 187 case 5: 188 _.label++; 189 y = op[1]; 190 op = [0]; 191 continue; 192 case 7: 193 op = _.ops.pop(); 194 _.trys.pop(); 195 continue; 196 default: 197 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { 198 _ = 0; 199 continue; 200 } 201 if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { 202 _.label = op[1]; 203 break; 204 } 205 if (op[0] === 6 && _.label < t[1]) { 206 _.label = t[1]; 207 t = op; 208 break; 209 } 210 if (t && _.label < t[2]) { 211 _.label = t[2]; 212 _.ops.push(op); 213 break; 214 } 215 if (t[2]) 216 _.ops.pop(); 217 _.trys.pop(); 218 continue; 219 } 220 op = body.call(thisArg, _); 221 } catch (e) { 222 op = [6, e]; 223 y = 0; 224 } finally { 225 f = t = 0; 226 } 227 if (op[0] & 5) 228 throw op[1]; 229 return { value: op[0] ? op[1] : void 0, done: true }; 230 } 231 }; 232 __exportStar2 = function(m, o) { 233 for (var p in m) 234 if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) 235 __createBinding2(o, m, p); 236 }; 237 __createBinding2 = Object.create ? function(o, m, k, k2) { 238 if (k2 === void 0) 239 k2 = k; 240 var desc = Object.getOwnPropertyDescriptor(m, k); 241 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 242 desc = { enumerable: true, get: function() { 243 return m[k]; 244 } }; 245 } 246 Object.defineProperty(o, k2, desc); 247 } : function(o, m, k, k2) { 248 if (k2 === void 0) 249 k2 = k; 250 o[k2] = m[k]; 251 }; 252 __values2 = function(o) { 253 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 254 if (m) 255 return m.call(o); 256 if (o && typeof o.length === "number") 257 return { 258 next: function() { 259 if (o && i >= o.length) 260 o = void 0; 261 return { value: o && o[i++], done: !o }; 262 } 263 }; 264 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 265 }; 266 __read2 = function(o, n) { 267 var m = typeof Symbol === "function" && o[Symbol.iterator]; 268 if (!m) 269 return o; 270 var i = m.call(o), r, ar = [], e; 271 try { 272 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) 273 ar.push(r.value); 274 } catch (error2) { 275 e = { error: error2 }; 276 } finally { 277 try { 278 if (r && !r.done && (m = i["return"])) 279 m.call(i); 280 } finally { 281 if (e) 282 throw e.error; 283 } 284 } 285 return ar; 286 }; 287 __spread2 = function() { 288 for (var ar = [], i = 0; i < arguments.length; i++) 289 ar = ar.concat(__read2(arguments[i])); 290 return ar; 291 }; 292 __spreadArrays2 = function() { 293 for (var s = 0, i = 0, il = arguments.length; i < il; i++) 294 s += arguments[i].length; 295 for (var r = Array(s), k = 0, i = 0; i < il; i++) 296 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 297 r[k] = a[j]; 298 return r; 299 }; 300 __spreadArray2 = function(to, from, pack) { 301 if (pack || arguments.length === 2) 302 for (var i = 0, l = from.length, ar; i < l; i++) { 303 if (ar || !(i in from)) { 304 if (!ar) 305 ar = Array.prototype.slice.call(from, 0, i); 306 ar[i] = from[i]; 307 } 308 } 309 return to.concat(ar || Array.prototype.slice.call(from)); 310 }; 311 __await2 = function(v) { 312 return this instanceof __await2 ? (this.v = v, this) : new __await2(v); 313 }; 314 __asyncGenerator2 = function(thisArg, _arguments, generator) { 315 if (!Symbol.asyncIterator) 316 throw new TypeError("Symbol.asyncIterator is not defined."); 317 var g = generator.apply(thisArg, _arguments || []), i, q = []; 318 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { 319 return this; 320 }, i; 321 function verb(n) { 322 if (g[n]) 323 i[n] = function(v) { 324 return new Promise(function(a, b) { 325 q.push([n, v, a, b]) > 1 || resume(n, v); 326 }); 327 }; 328 } 329 function resume(n, v) { 330 try { 331 step(g[n](v)); 332 } catch (e) { 333 settle(q[0][3], e); 334 } 335 } 336 function step(r) { 337 r.value instanceof __await2 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); 338 } 339 function fulfill(value) { 340 resume("next", value); 341 } 342 function reject(value) { 343 resume("throw", value); 344 } 345 function settle(f, v) { 346 if (f(v), q.shift(), q.length) 347 resume(q[0][0], q[0][1]); 348 } 349 }; 350 __asyncDelegator2 = function(o) { 351 var i, p; 352 return i = {}, verb("next"), verb("throw", function(e) { 353 throw e; 354 }), verb("return"), i[Symbol.iterator] = function() { 355 return this; 356 }, i; 357 function verb(n, f) { 358 i[n] = o[n] ? function(v) { 359 return (p = !p) ? { value: __await2(o[n](v)), done: n === "return" } : f ? f(v) : v; 360 } : f; 361 } 362 }; 363 __asyncValues2 = function(o) { 364 if (!Symbol.asyncIterator) 365 throw new TypeError("Symbol.asyncIterator is not defined."); 366 var m = o[Symbol.asyncIterator], i; 367 return m ? m.call(o) : (o = typeof __values2 === "function" ? __values2(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { 368 return this; 369 }, i); 370 function verb(n) { 371 i[n] = o[n] && function(v) { 372 return new Promise(function(resolve, reject) { 373 v = o[n](v), settle(resolve, reject, v.done, v.value); 374 }); 375 }; 376 } 377 function settle(resolve, reject, d, v) { 378 Promise.resolve(v).then(function(v2) { 379 resolve({ value: v2, done: d }); 380 }, reject); 381 } 382 }; 383 __makeTemplateObject2 = function(cooked, raw) { 384 if (Object.defineProperty) { 385 Object.defineProperty(cooked, "raw", { value: raw }); 386 } else { 387 cooked.raw = raw; 388 } 389 return cooked; 390 }; 391 var __setModuleDefault = Object.create ? function(o, v) { 392 Object.defineProperty(o, "default", { enumerable: true, value: v }); 393 } : function(o, v) { 394 o["default"] = v; 395 }; 396 __importStar2 = function(mod) { 397 if (mod && mod.__esModule) 398 return mod; 399 var result = {}; 400 if (mod != null) { 401 for (var k in mod) 402 if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) 403 __createBinding2(result, mod, k); 404 } 405 __setModuleDefault(result, mod); 406 return result; 407 }; 408 __importDefault2 = function(mod) { 409 return mod && mod.__esModule ? mod : { "default": mod }; 410 }; 411 __classPrivateFieldGet2 = function(receiver, state, kind, f) { 412 if (kind === "a" && !f) 413 throw new TypeError("Private accessor was defined without a getter"); 414 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) 415 throw new TypeError("Cannot read private member from an object whose class did not declare it"); 416 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 417 }; 418 __classPrivateFieldSet2 = function(receiver, state, value, kind, f) { 419 if (kind === "m") 420 throw new TypeError("Private method is not writable"); 421 if (kind === "a" && !f) 422 throw new TypeError("Private accessor was defined without a setter"); 423 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) 424 throw new TypeError("Cannot write private member to an object whose class did not declare it"); 425 return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; 426 }; 427 __classPrivateFieldIn2 = function(state, receiver) { 428 if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") 429 throw new TypeError("Cannot use 'in' operator on non-object"); 430 return typeof state === "function" ? receiver === state : state.has(receiver); 431 }; 432 exporter("__extends", __extends2); 433 exporter("__assign", __assign2); 434 exporter("__rest", __rest2); 435 exporter("__decorate", __decorate2); 436 exporter("__param", __param2); 437 exporter("__metadata", __metadata2); 438 exporter("__awaiter", __awaiter2); 439 exporter("__generator", __generator2); 440 exporter("__exportStar", __exportStar2); 441 exporter("__createBinding", __createBinding2); 442 exporter("__values", __values2); 443 exporter("__read", __read2); 444 exporter("__spread", __spread2); 445 exporter("__spreadArrays", __spreadArrays2); 446 exporter("__spreadArray", __spreadArray2); 447 exporter("__await", __await2); 448 exporter("__asyncGenerator", __asyncGenerator2); 449 exporter("__asyncDelegator", __asyncDelegator2); 450 exporter("__asyncValues", __asyncValues2); 451 exporter("__makeTemplateObject", __makeTemplateObject2); 452 exporter("__importStar", __importStar2); 453 exporter("__importDefault", __importDefault2); 454 exporter("__classPrivateFieldGet", __classPrivateFieldGet2); 455 exporter("__classPrivateFieldSet", __classPrivateFieldSet2); 456 exporter("__classPrivateFieldIn", __classPrivateFieldIn2); 457 }); 458 } 459 }); 460 461
vendor: 24,025 bytes, lines 461-1272
461// node_modules/@firebase/util/dist/index.esm2017.js 462 var CONSTANTS = { 463 NODE_CLIENT: false, 464 NODE_ADMIN: false, 465 SDK_VERSION: "${JSCORE_VERSION}" 466 }; 467 var assert = function(assertion, message) { 468 if (!assertion) { 469 throw assertionError(message); 470 } 471 }; 472 var assertionError = function(message) { 473 return new Error("Firebase Database (" + CONSTANTS.SDK_VERSION + ") INTERNAL ASSERT FAILED: " + message); 474 }; 475 var stringToByteArray$1 = function(str) { 476 const out = []; 477 let p = 0; 478 for (let i = 0; i < str.length; i++) { 479 let c = str.charCodeAt(i); 480 if (c < 128) { 481 out[p++] = c; 482 } else if (c < 2048) { 483 out[p++] = c >> 6 | 192; 484 out[p++] = c & 63 | 128; 485 } else if ((c & 64512) === 55296 && i + 1 < str.length && (str.charCodeAt(i + 1) & 64512) === 56320) { 486 c = 65536 + ((c & 1023) << 10) + (str.charCodeAt(++i) & 1023); 487 out[p++] = c >> 18 | 240; 488 out[p++] = c >> 12 & 63 | 128; 489 out[p++] = c >> 6 & 63 | 128; 490 out[p++] = c & 63 | 128; 491 } else { 492 out[p++] = c >> 12 | 224; 493 out[p++] = c >> 6 & 63 | 128; 494 out[p++] = c & 63 | 128; 495 } 496 } 497 return out; 498 }; 499 var byteArrayToString = function(bytes) { 500 const out = []; 501 let pos = 0, c = 0; 502 while (pos < bytes.length) { 503 const c1 = bytes[pos++]; 504 if (c1 < 128) { 505 out[c++] = String.fromCharCode(c1); 506 } else if (c1 > 191 && c1 < 224) { 507 const c2 = bytes[pos++]; 508 out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); 509 } else if (c1 > 239 && c1 < 365) { 510 const c2 = bytes[pos++]; 511 const c3 = bytes[pos++]; 512 const c4 = bytes[pos++]; 513 const u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - 65536; 514 out[c++] = String.fromCharCode(55296 + (u >> 10)); 515 out[c++] = String.fromCharCode(56320 + (u & 1023)); 516 } else { 517 const c2 = bytes[pos++]; 518 const c3 = bytes[pos++]; 519 out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63); 520 } 521 } 522 return out.join(""); 523 }; 524 var base64 = { 525 byteToCharMap_: null, 526 charToByteMap_: null, 527 byteToCharMapWebSafe_: null, 528 charToByteMapWebSafe_: null, 529 ENCODED_VALS_BASE: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 530 get ENCODED_VALS() { 531 return this.ENCODED_VALS_BASE + "+/="; 532 }, 533 get ENCODED_VALS_WEBSAFE() { 534 return this.ENCODED_VALS_BASE + "-_."; 535 }, 536 HAS_NATIVE_SUPPORT: typeof atob === "function", 537 encodeByteArray(input, webSafe) { 538 if (!Array.isArray(input)) { 539 throw Error("encodeByteArray takes an array as a parameter"); 540 } 541 this.init_(); 542 const byteToCharMap = webSafe ? this.byteToCharMapWebSafe_ : this.byteToCharMap_; 543 const output = []; 544 for (let i = 0; i < input.length; i += 3) { 545 const byte1 = input[i]; 546 const haveByte2 = i + 1 < input.length; 547 const byte2 = haveByte2 ? input[i + 1] : 0; 548 const haveByte3 = i + 2 < input.length; 549 const byte3 = haveByte3 ? input[i + 2] : 0; 550 const outByte1 = byte1 >> 2; 551 const outByte2 = (byte1 & 3) << 4 | byte2 >> 4; 552 let outByte3 = (byte2 & 15) << 2 | byte3 >> 6; 553 let outByte4 = byte3 & 63; 554 if (!haveByte3) { 555 outByte4 = 64; 556 if (!haveByte2) { 557 outByte3 = 64; 558 } 559 } 560 output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]); 561 } 562 return output.join(""); 563 }, 564 encodeString(input, webSafe) { 565 if (this.HAS_NATIVE_SUPPORT && !webSafe) { 566 return btoa(input); 567 } 568 return this.encodeByteArray(stringToByteArray$1(input), webSafe); 569 }, 570 decodeString(input, webSafe) { 571 if (this.HAS_NATIVE_SUPPORT && !webSafe) { 572 return atob(input); 573 } 574 return byteArrayToString(this.decodeStringToByteArray(input, webSafe)); 575 }, 576 decodeStringToByteArray(input, webSafe) { 577 this.init_(); 578 const charToByteMap = webSafe ? this.charToByteMapWebSafe_ : this.charToByteMap_; 579 const output = []; 580 for (let i = 0; i < input.length; ) { 581 const byte1 = charToByteMap[input.charAt(i++)]; 582 const haveByte2 = i < input.length; 583 const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0; 584 ++i; 585 const haveByte3 = i < input.length; 586 const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64; 587 ++i; 588 const haveByte4 = i < input.length; 589 const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64; 590 ++i; 591 if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) { 592 throw Error(); 593 } 594 const outByte1 = byte1 << 2 | byte2 >> 4; 595 output.push(outByte1); 596 if (byte3 !== 64) { 597 const outByte2 = byte2 << 4 & 240 | byte3 >> 2; 598 output.push(outByte2); 599 if (byte4 !== 64) { 600 const outByte3 = byte3 << 6 & 192 | byte4; 601 output.push(outByte3); 602 } 603 } 604 } 605 return output; 606 }, 607 init_() { 608 if (!this.byteToCharMap_) { 609 this.byteToCharMap_ = {}; 610 this.charToByteMap_ = {}; 611 this.byteToCharMapWebSafe_ = {}; 612 this.charToByteMapWebSafe_ = {}; 613 for (let i = 0; i < this.ENCODED_VALS.length; i++) { 614 this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i); 615 this.charToByteMap_[this.byteToCharMap_[i]] = i; 616 this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i); 617 this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i; 618 if (i >= this.ENCODED_VALS_BASE.length) { 619 this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i; 620 this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i; 621 } 622 } 623 } 624 } 625 }; 626 var base64Encode = function(str) { 627 const utf8Bytes = stringToByteArray$1(str); 628 return base64.encodeByteArray(utf8Bytes, true); 629 }; 630 var base64urlEncodeWithoutPadding = function(str) { 631 return base64Encode(str).replace(/\./g, ""); 632 }; 633 var base64Decode = function(str) { 634 try { 635 return base64.decodeString(str, true); 636 } catch (e) { 637 console.error("base64Decode failed: ", e); 638 } 639 return null; 640 }; 641 function deepCopy(value) { 642 return deepExtend(void 0, value); 643 } 644 function deepExtend(target, source) { 645 if (!(source instanceof Object)) { 646 return source; 647 } 648 switch (source.constructor) { 649 case Date: 650 const dateValue = source; 651 return new Date(dateValue.getTime()); 652 case Object: 653 if (target === void 0) { 654 target = {}; 655 } 656 break; 657 case Array: 658 target = []; 659 break; 660 default: 661 return source; 662 } 663 for (const prop in source) { 664 if (!source.hasOwnProperty(prop) || !isValidKey(prop)) { 665 continue; 666 } 667 target[prop] = deepExtend(target[prop], source[prop]); 668 } 669 return target; 670 } 671 function isValidKey(key) { 672 return key !== "__proto__"; 673 } 674 var Deferred = class { 675 constructor() { 676 this.reject = () => { 677 }; 678 this.resolve = () => { 679 }; 680 this.promise = new Promise((resolve, reject) => { 681 this.resolve = resolve; 682 this.reject = reject; 683 }); 684 } 685 wrapCallback(callback) { 686 return (error2, value) => { 687 if (error2) { 688 this.reject(error2); 689 } else { 690 this.resolve(value); 691 } 692 if (typeof callback === "function") { 693 this.promise.catch(() => { 694 }); 695 if (callback.length === 1) { 696 callback(error2); 697 } else { 698 callback(error2, value); 699 } 700 } 701 }; 702 } 703 }; 704 function getUA() { 705 if (typeof navigator !== "undefined" && typeof navigator["userAgent"] === "string") { 706 return navigator["userAgent"]; 707 } else { 708 return ""; 709 } 710 } 711 function isMobileCordova() { 712 return typeof window !== "undefined" && !!(window["cordova"] || window["phonegap"] || window["PhoneGap"]) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()); 713 } 714 function isBrowserExtension() { 715 const runtime = typeof chrome === "object" ? chrome.runtime : typeof browser === "object" ? browser.runtime : void 0; 716 return typeof runtime === "object" && runtime.id !== void 0; 717 } 718 function isReactNative() { 719 return typeof navigator === "object" && navigator["product"] === "ReactNative"; 720 } 721 function isIE() { 722 const ua = getUA(); 723 return ua.indexOf("MSIE ") >= 0 || ua.indexOf("Trident/") >= 0; 724 } 725 function isNodeSdk() { 726 return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true; 727 } 728 function isIndexedDBAvailable() { 729 return typeof indexedDB === "object"; 730 } 731 function validateIndexedDBOpenable() { 732 return new Promise((resolve, reject) => { 733 try { 734 let preExist = true; 735 const DB_CHECK_NAME = "validate-browser-context-for-indexeddb-analytics-module"; 736 const request = self.indexedDB.open(DB_CHECK_NAME); 737 request.onsuccess = () => { 738 request.result.close(); 739 if (!preExist) { 740 self.indexedDB.deleteDatabase(DB_CHECK_NAME); 741 } 742 resolve(true); 743 }; 744 request.onupgradeneeded = () => { 745 preExist = false; 746 }; 747 request.onerror = () => { 748 var _a; 749 reject(((_a = request.error) === null || _a === void 0 ? void 0 : _a.message) || ""); 750 }; 751 } catch (error2) { 752 reject(error2); 753 } 754 }); 755 } 756 function areCookiesEnabled() { 757 if (typeof navigator === "undefined" || !navigator.cookieEnabled) { 758 return false; 759 } 760 return true; 761 } 762 var ERROR_NAME = "FirebaseError"; 763 var FirebaseError = class extends Error { 764 constructor(code, message, customData) { 765 super(message); 766 this.code = code; 767 this.customData = customData; 768 this.name = ERROR_NAME; 769 Object.setPrototypeOf(this, FirebaseError.prototype); 770 if (Error.captureStackTrace) { 771 Error.captureStackTrace(this, ErrorFactory.prototype.create); 772 } 773 } 774 }; 775 var ErrorFactory = class { 776 constructor(service, serviceName, errors) { 777 this.service = service; 778 this.serviceName = serviceName; 779 this.errors = errors; 780 } 781 create(code, ...data) { 782 const customData = data[0] || {}; 783 const fullCode = `${this.service}/${code}`; 784 const template = this.errors[code]; 785 const message = template ? replaceTemplate(template, customData) : "Error"; 786 const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`; 787 const error2 = new FirebaseError(fullCode, fullMessage, customData); 788 return error2; 789 } 790 }; 791 function replaceTemplate(template, data) { 792 return template.replace(PATTERN, (_, key) => { 793 const value = data[key]; 794 return value != null ? String(value) : `<${key}?>`; 795 }); 796 } 797 var PATTERN = /\{\$([^}]+)}/g; 798 function jsonEval(str) { 799 return JSON.parse(str); 800 } 801 function stringify(data) { 802 return JSON.stringify(data); 803 } 804 var decode = function(token) { 805 let header = {}, claims = {}, data = {}, signature = ""; 806 try { 807 const parts = token.split("."); 808 header = jsonEval(base64Decode(parts[0]) || ""); 809 claims = jsonEval(base64Decode(parts[1]) || ""); 810 signature = parts[2]; 811 data = claims["d"] || {}; 812 delete claims["d"]; 813 } catch (e) { 814 } 815 return { 816 header, 817 claims, 818 data, 819 signature 820 }; 821 }; 822 var isValidFormat = function(token) { 823 const decoded = decode(token), claims = decoded.claims; 824 return !!claims && typeof claims === "object" && claims.hasOwnProperty("iat"); 825 }; 826 var isAdmin = function(token) { 827 const claims = decode(token).claims; 828 return typeof claims === "object" && claims["admin"] === true; 829 }; 830 function contains(obj, key) { 831 return Object.prototype.hasOwnProperty.call(obj, key); 832 } 833 function safeGet(obj, key) { 834 if (Object.prototype.hasOwnProperty.call(obj, key)) { 835 return obj[key]; 836 } else { 837 return void 0; 838 } 839 } 840 function isEmpty(obj) { 841 for (const key in obj) { 842 if (Object.prototype.hasOwnProperty.call(obj, key)) { 843 return false; 844 } 845 } 846 return true; 847 } 848 function map(obj, fn, contextObj) { 849 const res = {}; 850 for (const key in obj) { 851 if (Object.prototype.hasOwnProperty.call(obj, key)) { 852 res[key] = fn.call(contextObj, obj[key], key, obj); 853 } 854 } 855 return res; 856 } 857 function deepEqual(a, b) { 858 if (a === b) { 859 return true; 860 } 861 const aKeys = Object.keys(a); 862 const bKeys = Object.keys(b); 863 for (const k of aKeys) { 864 if (!bKeys.includes(k)) { 865 return false; 866 } 867 const aProp = a[k]; 868 const bProp = b[k]; 869 if (isObject(aProp) && isObject(bProp)) { 870 if (!deepEqual(aProp, bProp)) { 871 return false; 872 } 873 } else if (aProp !== bProp) { 874 return false; 875 } 876 } 877 for (const k of bKeys) { 878 if (!aKeys.includes(k)) { 879 return false; 880 } 881 } 882 return true; 883 } 884 function isObject(thing) { 885 return thing !== null && typeof thing === "object"; 886 } 887 function querystring(querystringParams) { 888 const params = []; 889 for (const [key, value] of Object.entries(querystringParams)) { 890 if (Array.isArray(value)) { 891 value.forEach((arrayVal) => { 892 params.push(encodeURIComponent(key) + "=" + encodeURIComponent(arrayVal)); 893 }); 894 } else { 895 params.push(encodeURIComponent(key) + "=" + encodeURIComponent(value)); 896 } 897 } 898 return params.length ? "&" + params.join("&") : ""; 899 } 900 function querystringDecode(querystring2) { 901 const obj = {}; 902 const tokens = querystring2.replace(/^\?/, "").split("&"); 903 tokens.forEach((token) => { 904 if (token) { 905 const [key, value] = token.split("="); 906 obj[decodeURIComponent(key)] = decodeURIComponent(value); 907 } 908 }); 909 return obj; 910 } 911 function extractQuerystring(url) { 912 const queryStart = url.indexOf("?"); 913 if (!queryStart) { 914 return ""; 915 } 916 const fragmentStart = url.indexOf("#", queryStart); 917 return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : void 0); 918 } 919 var Sha1 = class { 920 constructor() { 921 this.chain_ = []; 922 this.buf_ = []; 923 this.W_ = []; 924 this.pad_ = []; 925 this.inbuf_ = 0; 926 this.total_ = 0; 927 this.blockSize = 512 / 8; 928 this.pad_[0] = 128; 929 for (let i = 1; i < this.blockSize; ++i) { 930 this.pad_[i] = 0; 931 } 932 this.reset(); 933 } 934 reset() { 935 this.chain_[0] = 1732584193; 936 this.chain_[1] = 4023233417; 937 this.chain_[2] = 2562383102; 938 this.chain_[3] = 271733878; 939 this.chain_[4] = 3285377520; 940 this.inbuf_ = 0; 941 this.total_ = 0; 942 } 943 compress_(buf, offset) { 944 if (!offset) { 945 offset = 0; 946 } 947 const W = this.W_; 948 if (typeof buf === "string") { 949 for (let i = 0; i < 16; i++) { 950 W[i] = buf.charCodeAt(offset) << 24 | buf.charCodeAt(offset + 1) << 16 | buf.charCodeAt(offset + 2) << 8 | buf.charCodeAt(offset + 3); 951 offset += 4; 952 } 953 } else { 954 for (let i = 0; i < 16; i++) { 955 W[i] = buf[offset] << 24 | buf[offset + 1] << 16 | buf[offset + 2] << 8 | buf[offset + 3]; 956 offset += 4; 957 } 958 } 959 for (let i = 16; i < 80; i++) { 960 const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; 961 W[i] = (t << 1 | t >>> 31) & 4294967295; 962 } 963 let a = this.chain_[0]; 964 let b = this.chain_[1]; 965 let c = this.chain_[2]; 966 let d = this.chain_[3]; 967 let e = this.chain_[4]; 968 let f, k; 969 for (let i = 0; i < 80; i++) { 970 if (i < 40) { 971 if (i < 20) { 972 f = d ^ b & (c ^ d); 973 k = 1518500249; 974 } else { 975 f = b ^ c ^ d; 976 k = 1859775393; 977 } 978 } else { 979 if (i < 60) { 980 f = b & c | d & (b | c); 981 k = 2400959708; 982 } else { 983 f = b ^ c ^ d; 984 k = 3395469782; 985 } 986 } 987 const t = (a << 5 | a >>> 27) + f + e + k + W[i] & 4294967295; 988 e = d; 989 d = c; 990 c = (b << 30 | b >>> 2) & 4294967295; 991 b = a; 992 a = t; 993 } 994 this.chain_[0] = this.chain_[0] + a & 4294967295; 995 this.chain_[1] = this.chain_[1] + b & 4294967295; 996 this.chain_[2] = this.chain_[2] + c & 4294967295; 997 this.chain_[3] = this.chain_[3] + d & 4294967295; 998 this.chain_[4] = this.chain_[4] + e & 4294967295; 999 } 1000 update(bytes, length) { 1001 if (bytes == null) { 1002 return; 1003 } 1004 if (length === void 0) { 1005 length = bytes.length; 1006 } 1007 const lengthMinusBlock = length - this.blockSize; 1008 let n = 0; 1009 const buf = this.buf_; 1010 let inbuf = this.inbuf_; 1011 while (n < length) { 1012 if (inbuf === 0) { 1013 while (n <= lengthMinusBlock) { 1014 this.compress_(bytes, n); 1015 n += this.blockSize; 1016 } 1017 } 1018 if (typeof bytes === "string") { 1019 while (n < length) { 1020 buf[inbuf] = bytes.charCodeAt(n); 1021 ++inbuf; 1022 ++n; 1023 if (inbuf === this.blockSize) { 1024 this.compress_(buf); 1025 inbuf = 0; 1026 break; 1027 } 1028 } 1029 } else { 1030 while (n < length) { 1031 buf[inbuf] = bytes[n]; 1032 ++inbuf; 1033 ++n; 1034 if (inbuf === this.blockSize) { 1035 this.compress_(buf); 1036 inbuf = 0; 1037 break; 1038 } 1039 } 1040 } 1041 } 1042 this.inbuf_ = inbuf; 1043 this.total_ += length; 1044 } 1045 digest() { 1046 const digest = []; 1047 let totalBits = this.total_ * 8; 1048 if (this.inbuf_ < 56) { 1049 this.update(this.pad_, 56 - this.inbuf_); 1050 } else { 1051 this.update(this.pad_, this.blockSize - (this.inbuf_ - 56)); 1052 } 1053 for (let i = this.blockSize - 1; i >= 56; i--) { 1054 this.buf_[i] = totalBits & 255; 1055 totalBits /= 256; 1056 } 1057 this.compress_(this.buf_); 1058 let n = 0; 1059 for (let i = 0; i < 5; i++) { 1060 for (let j = 24; j >= 0; j -= 8) { 1061 digest[n] = this.chain_[i] >> j & 255; 1062 ++n; 1063 } 1064 } 1065 return digest; 1066 } 1067 }; 1068 function createSubscribe(executor, onNoObservers) { 1069 const proxy = new ObserverProxy(executor, onNoObservers); 1070 return proxy.subscribe.bind(proxy); 1071 } 1072 var ObserverProxy = class { 1073 constructor(executor, onNoObservers) { 1074 this.observers = []; 1075 this.unsubscribes = []; 1076 this.observerCount = 0; 1077 this.task = Promise.resolve(); 1078 this.finalized = false; 1079 this.onNoObservers = onNoObservers; 1080 this.task.then(() => { 1081 executor(this); 1082 }).catch((e) => { 1083 this.error(e); 1084 }); 1085 } 1086 next(value) { 1087 this.forEachObserver((observer) => { 1088 observer.next(value); 1089 }); 1090 } 1091 error(error2) { 1092 this.forEachObserver((observer) => { 1093 observer.error(error2); 1094 }); 1095 this.close(error2); 1096 } 1097 complete() { 1098 this.forEachObserver((observer) => { 1099 observer.complete(); 1100 }); 1101 this.close(); 1102 } 1103 subscribe(nextOrObserver, error2, complete) { 1104 let observer; 1105 if (nextOrObserver === void 0 && error2 === void 0 && complete === void 0) { 1106 throw new Error("Missing Observer."); 1107 } 1108 if (implementsAnyMethods(nextOrObserver, [ 1109 "next", 1110 "error", 1111 "complete" 1112 ])) { 1113 observer = nextOrObserver; 1114 } else { 1115 observer = { 1116 next: nextOrObserver, 1117 error: error2, 1118 complete 1119 }; 1120 } 1121 if (observer.next === void 0) { 1122 observer.next = noop; 1123 } 1124 if (observer.error === void 0) { 1125 observer.error = noop; 1126 } 1127 if (observer.complete === void 0) { 1128 observer.complete = noop; 1129 } 1130 const unsub = this.unsubscribeOne.bind(this, this.observers.length); 1131 if (this.finalized) { 1132 this.task.then(() => { 1133 try { 1134 if (this.finalError) { 1135 observer.error(this.finalError); 1136 } else { 1137 observer.complete(); 1138 } 1139 } catch (e) { 1140 } 1141 return; 1142 }); 1143 } 1144 this.observers.push(observer); 1145 return unsub; 1146 } 1147 unsubscribeOne(i) { 1148 if (this.observers === void 0 || this.observers[i] === void 0) { 1149 return; 1150 } 1151 delete this.observers[i]; 1152 this.observerCount -= 1; 1153 if (this.observerCount === 0 && this.onNoObservers !== void 0) { 1154 this.onNoObservers(this); 1155 } 1156 } 1157 forEachObserver(fn) { 1158 if (this.finalized) { 1159 return; 1160 } 1161 for (let i = 0; i < this.observers.length; i++) { 1162 this.sendOne(i, fn); 1163 } 1164 } 1165 sendOne(i, fn) { 1166 this.task.then(() => { 1167 if (this.observers !== void 0 && this.observers[i] !== void 0) { 1168 try { 1169 fn(this.observers[i]); 1170 } catch (e) { 1171 if (typeof console !== "undefined" && console.error) { 1172 console.error(e); 1173 } 1174 } 1175 } 1176 }); 1177 } 1178 close(err) { 1179 if (this.finalized) { 1180 return; 1181 } 1182 this.finalized = true; 1183 if (err !== void 0) { 1184 this.finalError = err; 1185 } 1186 this.task.then(() => { 1187 this.observers = void 0; 1188 this.onNoObservers = void 0; 1189 }); 1190 } 1191 }; 1192 function implementsAnyMethods(obj, methods) { 1193 if (typeof obj !== "object" || obj === null) { 1194 return false; 1195 } 1196 for (const method of methods) { 1197 if (method in obj && typeof obj[method] === "function") { 1198 return true; 1199 } 1200 } 1201 return false; 1202 } 1203 function noop() { 1204 } 1205 function errorPrefix(fnName, argName) { 1206 return `${fnName} failed: ${argName} argument `; 1207 } 1208 var stringToByteArray = function(str) { 1209 const out = []; 1210 let p = 0; 1211 for (let i = 0; i < str.length; i++) { 1212 let c = str.charCodeAt(i); 1213 if (c >= 55296 && c <= 56319) { 1214 const high = c - 55296; 1215 i++; 1216 assert(i < str.length, "Surrogate pair missing trail surrogate."); 1217 const low = str.charCodeAt(i) - 56320; 1218 c = 65536 + (high << 10) + low; 1219 } 1220 if (c < 128) { 1221 out[p++] = c; 1222 } else if (c < 2048) { 1223 out[p++] = c >> 6 | 192; 1224 out[p++] = c & 63 | 128; 1225 } else if (c < 65536) { 1226 out[p++] = c >> 12 | 224; 1227 out[p++] = c >> 6 & 63 | 128; 1228 out[p++] = c & 63 | 128; 1229 } else { 1230 out[p++] = c >> 18 | 240; 1231 out[p++] = c >> 12 & 63 | 128; 1232 out[p++] = c >> 6 & 63 | 128; 1233 out[p++] = c & 63 | 128; 1234 } 1235 } 1236 return out; 1237 }; 1238 var stringLength = function(str) { 1239 let p = 0; 1240 for (let i = 0; i < str.length; i++) { 1241 const c = str.charCodeAt(i); 1242 if (c < 128) { 1243 p++; 1244 } else if (c < 2048) { 1245 p += 2; 1246 } else if (c >= 55296 && c <= 56319) { 1247 p += 4; 1248 i++; 1249 } else { 1250 p += 3; 1251 } 1252 } 1253 return p; 1254 }; 1255 var DEFAULT_INTERVAL_MILLIS = 1e3; 1256 var DEFAULT_BACKOFF_FACTOR = 2; 1257 var MAX_VALUE_MILLIS = 4 * 60 * 60 * 1e3; 1258 var RANDOM_FACTOR = 0.5; 1259 function calculateBackoffMillis(backoffCount, intervalMillis = DEFAULT_INTERVAL_MILLIS, backoffFactor = DEFAULT_BACKOFF_FACTOR) { 1260 const currBaseValue = intervalMillis * Math.pow(backoffFactor, backoffCount); 1261 const randomWait = Math.round(RANDOM_FACTOR * currBaseValue * (Math.random() - 0.5) * 2); 1262 return Math.min(MAX_VALUE_MILLIS, currBaseValue + randomWait); 1263 } 1264 function getModularInstance(service) { 1265 if (service && service._delegate) { 1266 return service._delegate; 1267 } else { 1268 return service; 1269 } 1270 } 1271 1272
vendor: 8,814 bytes, lines 1272-1521
1272// node_modules/@firebase/component/dist/esm/index.esm2017.js 1273 var Component = class { 1274 constructor(name7, instanceFactory, type) { 1275 this.name = name7; 1276 this.instanceFactory = instanceFactory; 1277 this.type = type; 1278 this.multipleInstances = false; 1279 this.serviceProps = {}; 1280 this.instantiationMode = "LAZY"; 1281 this.onInstanceCreated = null; 1282 } 1283 setInstantiationMode(mode) { 1284 this.instantiationMode = mode; 1285 return this; 1286 } 1287 setMultipleInstances(multipleInstances) { 1288 this.multipleInstances = multipleInstances; 1289 return this; 1290 } 1291 setServiceProps(props) { 1292 this.serviceProps = props; 1293 return this; 1294 } 1295 setInstanceCreatedCallback(callback) { 1296 this.onInstanceCreated = callback; 1297 return this; 1298 } 1299 }; 1300 var DEFAULT_ENTRY_NAME = "[DEFAULT]"; 1301 var Provider = class { 1302 constructor(name7, container) { 1303 this.name = name7; 1304 this.container = container; 1305 this.component = null; 1306 this.instances = /* @__PURE__ */ new Map(); 1307 this.instancesDeferred = /* @__PURE__ */ new Map(); 1308 this.instancesOptions = /* @__PURE__ */ new Map(); 1309 this.onInitCallbacks = /* @__PURE__ */ new Map(); 1310 } 1311 get(identifier) { 1312 const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier); 1313 if (!this.instancesDeferred.has(normalizedIdentifier)) { 1314 const deferred = new Deferred(); 1315 this.instancesDeferred.set(normalizedIdentifier, deferred); 1316 if (this.isInitialized(normalizedIdentifier) || this.shouldAutoInitialize()) { 1317 try { 1318 const instance = this.getOrInitializeService({ 1319 instanceIdentifier: normalizedIdentifier 1320 }); 1321 if (instance) { 1322 deferred.resolve(instance); 1323 } 1324 } catch (e) { 1325 } 1326 } 1327 } 1328 return this.instancesDeferred.get(normalizedIdentifier).promise; 1329 } 1330 getImmediate(options) { 1331 var _a; 1332 const normalizedIdentifier = this.normalizeInstanceIdentifier(options === null || options === void 0 ? void 0 : options.identifier); 1333 const optional = (_a = options === null || options === void 0 ? void 0 : options.optional) !== null && _a !== void 0 ? _a : false; 1334 if (this.isInitialized(normalizedIdentifier) || this.shouldAutoInitialize()) { 1335 try { 1336 return this.getOrInitializeService({ 1337 instanceIdentifier: normalizedIdentifier 1338 }); 1339 } catch (e) { 1340 if (optional) { 1341 return null; 1342 } else { 1343 throw e; 1344 } 1345 } 1346 } else { 1347 if (optional) { 1348 return null; 1349 } else { 1350 throw Error(`Service ${this.name} is not available`); 1351 } 1352 } 1353 } 1354 getComponent() { 1355 return this.component; 1356 } 1357 setComponent(component) { 1358 if (component.name !== this.name) { 1359 throw Error(`Mismatching Component ${component.name} for Provider ${this.name}.`); 1360 } 1361 if (this.component) { 1362 throw Error(`Component for ${this.name} has already been provided`); 1363 } 1364 this.component = component; 1365 if (!this.shouldAutoInitialize()) { 1366 return; 1367 } 1368 if (isComponentEager(component)) { 1369 try { 1370 this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME }); 1371 } catch (e) { 1372 } 1373 } 1374 for (const [instanceIdentifier, instanceDeferred] of this.instancesDeferred.entries()) { 1375 const normalizedIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier); 1376 try { 1377 const instance = this.getOrInitializeService({ 1378 instanceIdentifier: normalizedIdentifier 1379 }); 1380 instanceDeferred.resolve(instance); 1381 } catch (e) { 1382 } 1383 } 1384 } 1385 clearInstance(identifier = DEFAULT_ENTRY_NAME) { 1386 this.instancesDeferred.delete(identifier); 1387 this.instancesOptions.delete(identifier); 1388 this.instances.delete(identifier); 1389 } 1390 async delete() { 1391 const services = Array.from(this.instances.values()); 1392 await Promise.all([ 1393 ...services.filter((service) => "INTERNAL" in service).map((service) => service.INTERNAL.delete()), 1394 ...services.filter((service) => "_delete" in service).map((service) => service._delete()) 1395 ]); 1396 } 1397 isComponentSet() { 1398 return this.component != null; 1399 } 1400 isInitialized(identifier = DEFAULT_ENTRY_NAME) { 1401 return this.instances.has(identifier); 1402 } 1403 getOptions(identifier = DEFAULT_ENTRY_NAME) { 1404 return this.instancesOptions.get(identifier) || {}; 1405 } 1406 initialize(opts = {}) { 1407 const { options = {} } = opts; 1408 const normalizedIdentifier = this.normalizeInstanceIdentifier(opts.instanceIdentifier); 1409 if (this.isInitialized(normalizedIdentifier)) { 1410 throw Error(`${this.name}(${normalizedIdentifier}) has already been initialized`); 1411 } 1412 if (!this.isComponentSet()) { 1413 throw Error(`Component ${this.name} has not been registered yet`); 1414 } 1415 const instance = this.getOrInitializeService({ 1416 instanceIdentifier: normalizedIdentifier, 1417 options 1418 }); 1419 for (const [instanceIdentifier, instanceDeferred] of this.instancesDeferred.entries()) { 1420 const normalizedDeferredIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier); 1421 if (normalizedIdentifier === normalizedDeferredIdentifier) { 1422 instanceDeferred.resolve(instance); 1423 } 1424 } 1425 return instance; 1426 } 1427 onInit(callback, identifier) { 1428 var _a; 1429 const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier); 1430 const existingCallbacks = (_a = this.onInitCallbacks.get(normalizedIdentifier)) !== null && _a !== void 0 ? _a : /* @__PURE__ */ new Set(); 1431 existingCallbacks.add(callback); 1432 this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks); 1433 const existingInstance = this.instances.get(normalizedIdentifier); 1434 if (existingInstance) { 1435 callback(existingInstance, normalizedIdentifier); 1436 } 1437 return () => { 1438 existingCallbacks.delete(callback); 1439 }; 1440 } 1441 invokeOnInitCallbacks(instance, identifier) { 1442 const callbacks = this.onInitCallbacks.get(identifier); 1443 if (!callbacks) { 1444 return; 1445 } 1446 for (const callback of callbacks) { 1447 try { 1448 callback(instance, identifier); 1449 } catch (_a) { 1450 } 1451 } 1452 } 1453 getOrInitializeService({ instanceIdentifier, options = {} }) { 1454 let instance = this.instances.get(instanceIdentifier); 1455 if (!instance && this.component) { 1456 instance = this.component.instanceFactory(this.container, { 1457 instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier), 1458 options 1459 }); 1460 this.instances.set(instanceIdentifier, instance); 1461 this.instancesOptions.set(instanceIdentifier, options); 1462 this.invokeOnInitCallbacks(instance, instanceIdentifier); 1463 if (this.component.onInstanceCreated) { 1464 try { 1465 this.component.onInstanceCreated(this.container, instanceIdentifier, instance); 1466 } catch (_a) { 1467 } 1468 } 1469 } 1470 return instance || null; 1471 } 1472 normalizeInstanceIdentifier(identifier = DEFAULT_ENTRY_NAME) { 1473 if (this.component) { 1474 return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME; 1475 } else { 1476 return identifier; 1477 } 1478 } 1479 shouldAutoInitialize() { 1480 return !!this.component && this.component.instantiationMode !== "EXPLICIT"; 1481 } 1482 }; 1483 function normalizeIdentifierForFactory(identifier) { 1484 return identifier === DEFAULT_ENTRY_NAME ? void 0 : identifier; 1485 } 1486 function isComponentEager(component) { 1487 return component.instantiationMode === "EAGER"; 1488 } 1489 var ComponentContainer = class { 1490 constructor(name7) { 1491 this.name = name7; 1492 this.providers = /* @__PURE__ */ new Map(); 1493 } 1494 addComponent(component) { 1495 const provider = this.getProvider(component.name); 1496 if (provider.isComponentSet()) { 1497 throw new Error(`Component ${component.name} has already been registered with ${this.name}`); 1498 } 1499 provider.setComponent(component); 1500 } 1501 addOrOverwriteComponent(component) { 1502 const provider = this.getProvider(component.name); 1503 if (provider.isComponentSet()) { 1504 this.providers.delete(component.name); 1505 } 1506 this.addComponent(component); 1507 } 1508 getProvider(name7) { 1509 if (this.providers.has(name7)) { 1510 return this.providers.get(name7); 1511 } 1512 const provider = new Provider(name7, this); 1513 this.providers.set(name7, provider); 1514 return provider; 1515 } 1516 getProviders() { 1517 return Array.from(this.providers.values()); 1518 } 1519 }; 1520 1521
vendor: 3,069 bytes, lines 1521-1617
1521// node_modules/@firebase/logger/dist/esm/index.esm2017.js 1522 var instances = []; 1523 var LogLevel; 1524 (function(LogLevel2) { 1525 LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG"; 1526 LogLevel2[LogLevel2["VERBOSE"] = 1] = "VERBOSE"; 1527 LogLevel2[LogLevel2["INFO"] = 2] = "INFO"; 1528 LogLevel2[LogLevel2["WARN"] = 3] = "WARN"; 1529 LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR"; 1530 LogLevel2[LogLevel2["SILENT"] = 5] = "SILENT"; 1531 })(LogLevel || (LogLevel = {})); 1532 var levelStringToEnum = { 1533 "debug": LogLevel.DEBUG, 1534 "verbose": LogLevel.VERBOSE, 1535 "info": LogLevel.INFO, 1536 "warn": LogLevel.WARN, 1537 "error": LogLevel.ERROR, 1538 "silent": LogLevel.SILENT 1539 }; 1540 var defaultLogLevel = LogLevel.INFO; 1541 var ConsoleMethod = { 1542 [LogLevel.DEBUG]: "log", 1543 [LogLevel.VERBOSE]: "log", 1544 [LogLevel.INFO]: "info", 1545 [LogLevel.WARN]: "warn", 1546 [LogLevel.ERROR]: "error" 1547 }; 1548 var defaultLogHandler = (instance, logType, ...args) => { 1549 if (logType < instance.logLevel) { 1550 return; 1551 } 1552 const now = new Date().toISOString(); 1553 const method = ConsoleMethod[logType]; 1554 if (method) { 1555 console[method](`[${now}] ${instance.name}:`, ...args); 1556 } else { 1557 throw new Error(`Attempted to log a message with an invalid logType (value: ${logType})`); 1558 } 1559 }; 1560 var Logger = class { 1561 constructor(name7) { 1562 this.name = name7; 1563 this._logLevel = defaultLogLevel; 1564 this._logHandler = defaultLogHandler; 1565 this._userLogHandler = null; 1566 instances.push(this); 1567 } 1568 get logLevel() { 1569 return this._logLevel; 1570 } 1571 set logLevel(val) { 1572 if (!(val in LogLevel)) { 1573 throw new TypeError(`Invalid value "${val}" assigned to \`logLevel\``); 1574 } 1575 this._logLevel = val; 1576 } 1577 setLogLevel(val) { 1578 this._logLevel = typeof val === "string" ? levelStringToEnum[val] : val; 1579 } 1580 get logHandler() { 1581 return this._logHandler; 1582 } 1583 set logHandler(val) { 1584 if (typeof val !== "function") { 1585 throw new TypeError("Value assigned to `logHandler` must be a function"); 1586 } 1587 this._logHandler = val; 1588 } 1589 get userLogHandler() { 1590 return this._userLogHandler; 1591 } 1592 set userLogHandler(val) { 1593 this._userLogHandler = val; 1594 } 1595 debug(...args) { 1596 this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args); 1597 this._logHandler(this, LogLevel.DEBUG, ...args); 1598 } 1599 log(...args) { 1600 this._userLogHandler && this._userLogHandler(this, LogLevel.VERBOSE, ...args); 1601 this._logHandler(this, LogLevel.VERBOSE, ...args); 1602 } 1603 info(...args) { 1604 this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args); 1605 this._logHandler(this, LogLevel.INFO, ...args); 1606 } 1607 warn(...args) { 1608 this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args); 1609 this._logHandler(this, LogLevel.WARN, ...args); 1610 } 1611 error(...args) { 1612 this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args); 1613 this._logHandler(this, LogLevel.ERROR, ...args); 1614 } 1615 }; 1616 1617
vendor: 4,715 bytes, lines 1617-1760
1617// node_modules/idb/build/wrap-idb-value.js 1618 var instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c); 1619 var idbProxyableTypes; 1620 var cursorAdvanceMethods; 1621 function getIdbProxyableTypes() { 1622 return idbProxyableTypes || (idbProxyableTypes = [ 1623 IDBDatabase, 1624 IDBObjectStore, 1625 IDBIndex, 1626 IDBCursor, 1627 IDBTransaction 1628 ]); 1629 } 1630 function getCursorAdvanceMethods() { 1631 return cursorAdvanceMethods || (cursorAdvanceMethods = [ 1632 IDBCursor.prototype.advance, 1633 IDBCursor.prototype.continue, 1634 IDBCursor.prototype.continuePrimaryKey 1635 ]); 1636 } 1637 var cursorRequestMap = /* @__PURE__ */ new WeakMap(); 1638 var transactionDoneMap = /* @__PURE__ */ new WeakMap(); 1639 var transactionStoreNamesMap = /* @__PURE__ */ new WeakMap(); 1640 var transformCache = /* @__PURE__ */ new WeakMap(); 1641 var reverseTransformCache = /* @__PURE__ */ new WeakMap(); 1642 function promisifyRequest(request) { 1643 const promise = new Promise((resolve, reject) => { 1644 const unlisten = () => { 1645 request.removeEventListener("success", success); 1646 request.removeEventListener("error", error2); 1647 }; 1648 const success = () => { 1649 resolve(wrap(request.result)); 1650 unlisten(); 1651 }; 1652 const error2 = () => { 1653 reject(request.error); 1654 unlisten(); 1655 }; 1656 request.addEventListener("success", success); 1657 request.addEventListener("error", error2); 1658 }); 1659 promise.then((value) => { 1660 if (value instanceof IDBCursor) { 1661 cursorRequestMap.set(value, request); 1662 } 1663 }).catch(() => { 1664 }); 1665 reverseTransformCache.set(promise, request); 1666 return promise; 1667 } 1668 function cacheDonePromiseForTransaction(tx) { 1669 if (transactionDoneMap.has(tx)) 1670 return; 1671 const done = new Promise((resolve, reject) => { 1672 const unlisten = () => { 1673 tx.removeEventListener("complete", complete); 1674 tx.removeEventListener("error", error2); 1675 tx.removeEventListener("abort", error2); 1676 }; 1677 const complete = () => { 1678 resolve(); 1679 unlisten(); 1680 }; 1681 const error2 = () => { 1682 reject(tx.error || new DOMException("AbortError", "AbortError")); 1683 unlisten(); 1684 }; 1685 tx.addEventListener("complete", complete); 1686 tx.addEventListener("error", error2); 1687 tx.addEventListener("abort", error2); 1688 }); 1689 transactionDoneMap.set(tx, done); 1690 } 1691 var idbProxyTraps = { 1692 get(target, prop, receiver) { 1693 if (target instanceof IDBTransaction) { 1694 if (prop === "done") 1695 return transactionDoneMap.get(target); 1696 if (prop === "objectStoreNames") { 1697 return target.objectStoreNames || transactionStoreNamesMap.get(target); 1698 } 1699 if (prop === "store") { 1700 return receiver.objectStoreNames[1] ? void 0 : receiver.objectStore(receiver.objectStoreNames[0]); 1701 } 1702 } 1703 return wrap(target[prop]); 1704 }, 1705 set(target, prop, value) { 1706 target[prop] = value; 1707 return true; 1708 }, 1709 has(target, prop) { 1710 if (target instanceof IDBTransaction && (prop === "done" || prop === "store")) { 1711 return true; 1712 } 1713 return prop in target; 1714 } 1715 }; 1716 function replaceTraps(callback) { 1717 idbProxyTraps = callback(idbProxyTraps); 1718 } 1719 function wrapFunction(func) { 1720 if (func === IDBDatabase.prototype.transaction && !("objectStoreNames" in IDBTransaction.prototype)) { 1721 return function(storeNames, ...args) { 1722 const tx = func.call(unwrap(this), storeNames, ...args); 1723 transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]); 1724 return wrap(tx); 1725 }; 1726 } 1727 if (getCursorAdvanceMethods().includes(func)) { 1728 return function(...args) { 1729 func.apply(unwrap(this), args); 1730 return wrap(cursorRequestMap.get(this)); 1731 }; 1732 } 1733 return function(...args) { 1734 return wrap(func.apply(unwrap(this), args)); 1735 }; 1736 } 1737 function transformCachableValue(value) { 1738 if (typeof value === "function") 1739 return wrapFunction(value); 1740 if (value instanceof IDBTransaction) 1741 cacheDonePromiseForTransaction(value); 1742 if (instanceOfAny(value, getIdbProxyableTypes())) 1743 return new Proxy(value, idbProxyTraps); 1744 return value; 1745 } 1746 function wrap(value) { 1747 if (value instanceof IDBRequest) 1748 return promisifyRequest(value); 1749 if (transformCache.has(value)) 1750 return transformCache.get(value); 1751 const newValue = transformCachableValue(value); 1752 if (newValue !== value) { 1753 transformCache.set(value, newValue); 1754 reverseTransformCache.set(newValue, value); 1755 } 1756 return newValue; 1757 } 1758 var unwrap = (value) => reverseTransformCache.get(value); 1759 1760
vendor: 2,123 bytes, lines 1760-1814
1760// node_modules/idb/build/index.js 1761 function openDB(name7, version7, { blocked, upgrade, blocking, terminated } = {}) { 1762 const request = indexedDB.open(name7, version7); 1763 const openPromise = wrap(request); 1764 if (upgrade) { 1765 request.addEventListener("upgradeneeded", (event) => { 1766 upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction)); 1767 }); 1768 } 1769 if (blocked) 1770 request.addEventListener("blocked", () => blocked()); 1771 openPromise.then((db2) => { 1772 if (terminated) 1773 db2.addEventListener("close", () => terminated()); 1774 if (blocking) 1775 db2.addEventListener("versionchange", () => blocking()); 1776 }).catch(() => { 1777 }); 1778 return openPromise; 1779 } 1780 var readMethods = ["get", "getKey", "getAll", "getAllKeys", "count"]; 1781 var writeMethods = ["put", "add", "delete", "clear"]; 1782 var cachedMethods = /* @__PURE__ */ new Map(); 1783 function getMethod(target, prop) { 1784 if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === "string")) { 1785 return; 1786 } 1787 if (cachedMethods.get(prop)) 1788 return cachedMethods.get(prop); 1789 const targetFuncName = prop.replace(/FromIndex$/, ""); 1790 const useIndex = prop !== targetFuncName; 1791 const isWrite = writeMethods.includes(targetFuncName); 1792 if (!(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) { 1793 return; 1794 } 1795 const method = async function(storeName, ...args) { 1796 const tx = this.transaction(storeName, isWrite ? "readwrite" : "readonly"); 1797 let target2 = tx.store; 1798 if (useIndex) 1799 target2 = target2.index(args.shift()); 1800 return (await Promise.all([ 1801 target2[targetFuncName](...args), 1802 isWrite && tx.done 1803 ]))[0]; 1804 }; 1805 cachedMethods.set(prop, method); 1806 return method; 1807 } 1808 replaceTraps((oldTraps) => ({ 1809 ...oldTraps, 1810 get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver), 1811 has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop) 1812 })); 1813 1814
vendor: 16,040 bytes, lines 1814-2247
1814// node_modules/@firebase/app/dist/esm/index.esm2017.js 1815 var PlatformLoggerServiceImpl = class { 1816 constructor(container) { 1817 this.container = container; 1818 } 1819 getPlatformInfoString() { 1820 const providers = this.container.getProviders(); 1821 return providers.map((provider) => { 1822 if (isVersionServiceProvider(provider)) { 1823 const service = provider.getImmediate(); 1824 return `${service.library}/${service.version}`; 1825 } else { 1826 return null; 1827 } 1828 }).filter((logString) => logString).join(" "); 1829 } 1830 }; 1831 function isVersionServiceProvider(provider) { 1832 const component = provider.getComponent(); 1833 return (component === null || component === void 0 ? void 0 : component.type) === "VERSION"; 1834 } 1835 var name$o = "@firebase/app"; 1836 var version$1 = "0.7.32"; 1837 var logger = new Logger("@firebase/app"); 1838 var name$n = "@firebase/app-compat"; 1839 var name$m = "@firebase/analytics-compat"; 1840 var name$l = "@firebase/analytics"; 1841 var name$k = "@firebase/app-check-compat"; 1842 var name$j = "@firebase/app-check"; 1843 var name$i = "@firebase/auth"; 1844 var name$h = "@firebase/auth-compat"; 1845 var name$g = "@firebase/database"; 1846 var name$f = "@firebase/database-compat"; 1847 var name$e = "@firebase/functions"; 1848 var name$d = "@firebase/functions-compat"; 1849 var name$c = "@firebase/installations"; 1850 var name$b = "@firebase/installations-compat"; 1851 var name$a = "@firebase/messaging"; 1852 var name$9 = "@firebase/messaging-compat"; 1853 var name$8 = "@firebase/performance"; 1854 var name$7 = "@firebase/performance-compat"; 1855 var name$6 = "@firebase/remote-config"; 1856 var name$5 = "@firebase/remote-config-compat"; 1857 var name$4 = "@firebase/storage"; 1858 var name$3 = "@firebase/storage-compat"; 1859 var name$2 = "@firebase/firestore"; 1860 var name$1 = "@firebase/firestore-compat"; 1861 var name = "firebase"; 1862 var version = "9.9.4"; 1863 var DEFAULT_ENTRY_NAME2 = "[DEFAULT]"; 1864 var PLATFORM_LOG_STRING = { 1865 [name$o]: "fire-core", 1866 [name$n]: "fire-core-compat", 1867 [name$l]: "fire-analytics", 1868 [name$m]: "fire-analytics-compat", 1869 [name$j]: "fire-app-check", 1870 [name$k]: "fire-app-check-compat", 1871 [name$i]: "fire-auth", 1872 [name$h]: "fire-auth-compat", 1873 [name$g]: "fire-rtdb", 1874 [name$f]: "fire-rtdb-compat", 1875 [name$e]: "fire-fn", 1876 [name$d]: "fire-fn-compat", 1877 [name$c]: "fire-iid", 1878 [name$b]: "fire-iid-compat", 1879 [name$a]: "fire-fcm", 1880 [name$9]: "fire-fcm-compat", 1881 [name$8]: "fire-perf", 1882 [name$7]: "fire-perf-compat", 1883 [name$6]: "fire-rc", 1884 [name$5]: "fire-rc-compat", 1885 [name$4]: "fire-gcs", 1886 [name$3]: "fire-gcs-compat", 1887 [name$2]: "fire-fst", 1888 [name$1]: "fire-fst-compat", 1889 "fire-js": "fire-js", 1890 [name]: "fire-js-all" 1891 }; 1892 var _apps = /* @__PURE__ */ new Map(); 1893 var _components = /* @__PURE__ */ new Map(); 1894 function _addComponent(app2, component) { 1895 try { 1896 app2.container.addComponent(component); 1897 } catch (e) { 1898 logger.debug(`Component ${component.name} failed to register with FirebaseApp ${app2.name}`, e); 1899 } 1900 } 1901 function _registerComponent(component) { 1902 const componentName = component.name; 1903 if (_components.has(componentName)) { 1904 logger.debug(`There were multiple attempts to register component ${componentName}.`); 1905 return false; 1906 } 1907 _components.set(componentName, component); 1908 for (const app2 of _apps.values()) { 1909 _addComponent(app2, component); 1910 } 1911 return true; 1912 } 1913 function _getProvider(app2, name7) { 1914 const heartbeatController = app2.container.getProvider("heartbeat").getImmediate({ optional: true }); 1915 if (heartbeatController) { 1916 void heartbeatController.triggerHeartbeat(); 1917 } 1918 return app2.container.getProvider(name7); 1919 } 1920 var ERRORS = { 1921 ["no-app"]: "No Firebase App '{$appName}' has been created - call Firebase App.initializeApp()", 1922 ["bad-app-name"]: "Illegal App name: '{$appName}", 1923 ["duplicate-app"]: "Firebase App named '{$appName}' already exists with different options or config", 1924 ["app-deleted"]: "Firebase App named '{$appName}' already deleted", 1925 ["invalid-app-argument"]: "firebase.{$appName}() takes either no argument or a Firebase App instance.", 1926 ["invalid-log-argument"]: "First argument to `onLog` must be null or a function.", 1927 ["idb-open"]: "Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.", 1928 ["idb-get"]: "Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.", 1929 ["idb-set"]: "Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.", 1930 ["idb-delete"]: "Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}." 1931 }; 1932 var ERROR_FACTORY = new ErrorFactory("app", "Firebase", ERRORS); 1933 var FirebaseAppImpl = class { 1934 constructor(options, config, container) { 1935 this._isDeleted = false; 1936 this._options = Object.assign({}, options); 1937 this._config = Object.assign({}, config); 1938 this._name = config.name; 1939 this._automaticDataCollectionEnabled = config.automaticDataCollectionEnabled; 1940 this._container = container; 1941 this.container.addComponent(new Component("app", () => this, "PUBLIC")); 1942 } 1943 get automaticDataCollectionEnabled() { 1944 this.checkDestroyed(); 1945 return this._automaticDataCollectionEnabled; 1946 } 1947 set automaticDataCollectionEnabled(val) { 1948 this.checkDestroyed(); 1949 this._automaticDataCollectionEnabled = val; 1950 } 1951 get name() { 1952 this.checkDestroyed(); 1953 return this._name; 1954 } 1955 get options() { 1956 this.checkDestroyed(); 1957 return this._options; 1958 } 1959 get config() { 1960 this.checkDestroyed(); 1961 return this._config; 1962 } 1963 get container() { 1964 return this._container; 1965 } 1966 get isDeleted() { 1967 return this._isDeleted; 1968 } 1969 set isDeleted(val) { 1970 this._isDeleted = val; 1971 } 1972 checkDestroyed() { 1973 if (this.isDeleted) { 1974 throw ERROR_FACTORY.create("app-deleted", { appName: this._name }); 1975 } 1976 } 1977 }; 1978 var SDK_VERSION = version; 1979 function initializeApp(options, rawConfig = {}) { 1980 if (typeof rawConfig !== "object") { 1981 const name8 = rawConfig; 1982 rawConfig = { name: name8 }; 1983 } 1984 const config = Object.assign({ name: DEFAULT_ENTRY_NAME2, automaticDataCollectionEnabled: false }, rawConfig); 1985 const name7 = config.name; 1986 if (typeof name7 !== "string" || !name7) { 1987 throw ERROR_FACTORY.create("bad-app-name", { 1988 appName: String(name7) 1989 }); 1990 } 1991 const existingApp = _apps.get(name7); 1992 if (existingApp) { 1993 if (deepEqual(options, existingApp.options) && deepEqual(config, existingApp.config)) { 1994 return existingApp; 1995 } else { 1996 throw ERROR_FACTORY.create("duplicate-app", { appName: name7 }); 1997 } 1998 } 1999 const container = new ComponentContainer(name7); 2000 for (const component of _components.values()) { 2001 container.addComponent(component); 2002 } 2003 const newApp = new FirebaseAppImpl(options, config, container); 2004 _apps.set(name7, newApp); 2005 return newApp; 2006 } 2007 function getApp(name7 = DEFAULT_ENTRY_NAME2) { 2008 const app2 = _apps.get(name7); 2009 if (!app2) { 2010 throw ERROR_FACTORY.create("no-app", { appName: name7 }); 2011 } 2012 return app2; 2013 } 2014 function registerVersion(libraryKeyOrName, version7, variant) { 2015 var _a; 2016 let library = (_a = PLATFORM_LOG_STRING[libraryKeyOrName]) !== null && _a !== void 0 ? _a : libraryKeyOrName; 2017 if (variant) { 2018 library += `-${variant}`; 2019 } 2020 const libraryMismatch = library.match(/\s|\//); 2021 const versionMismatch = version7.match(/\s|\//); 2022 if (libraryMismatch || versionMismatch) { 2023 const warning = [ 2024 `Unable to register library "${library}" with version "${version7}":` 2025 ]; 2026 if (libraryMismatch) { 2027 warning.push(`library name "${library}" contains illegal characters (whitespace or "/")`); 2028 } 2029 if (libraryMismatch && versionMismatch) { 2030 warning.push("and"); 2031 } 2032 if (versionMismatch) { 2033 warning.push(`version name "${version7}" contains illegal characters (whitespace or "/")`); 2034 } 2035 logger.warn(warning.join(" ")); 2036 return; 2037 } 2038 _registerComponent(new Component(`${library}-version`, () => ({ library, version: version7 }), "VERSION")); 2039 } 2040 var DB_NAME = "firebase-heartbeat-database"; 2041 var DB_VERSION = 1; 2042 var STORE_NAME = "firebase-heartbeat-store"; 2043 var dbPromise = null; 2044 function getDbPromise() { 2045 if (!dbPromise) { 2046 dbPromise = openDB(DB_NAME, DB_VERSION, { 2047 upgrade: (db2, oldVersion) => { 2048 switch (oldVersion) { 2049 case 0: 2050 db2.createObjectStore(STORE_NAME); 2051 } 2052 } 2053 }).catch((e) => { 2054 throw ERROR_FACTORY.create("idb-open", { 2055 originalErrorMessage: e.message 2056 }); 2057 }); 2058 } 2059 return dbPromise; 2060 } 2061 async function readHeartbeatsFromIndexedDB(app2) { 2062 var _a; 2063 try { 2064 const db2 = await getDbPromise(); 2065 return db2.transaction(STORE_NAME).objectStore(STORE_NAME).get(computeKey(app2)); 2066 } catch (e) { 2067 if (e instanceof FirebaseError) { 2068 logger.warn(e.message); 2069 } else { 2070 const idbGetError = ERROR_FACTORY.create("idb-get", { 2071 originalErrorMessage: (_a = e) === null || _a === void 0 ? void 0 : _a.message 2072 }); 2073 logger.warn(idbGetError.message); 2074 } 2075 } 2076 } 2077 async function writeHeartbeatsToIndexedDB(app2, heartbeatObject) { 2078 var _a; 2079 try { 2080 const db2 = await getDbPromise(); 2081 const tx = db2.transaction(STORE_NAME, "readwrite"); 2082 const objectStore = tx.objectStore(STORE_NAME); 2083 await objectStore.put(heartbeatObject, computeKey(app2)); 2084 return tx.done; 2085 } catch (e) { 2086 if (e instanceof FirebaseError) { 2087 logger.warn(e.message); 2088 } else { 2089 const idbGetError = ERROR_FACTORY.create("idb-set", { 2090 originalErrorMessage: (_a = e) === null || _a === void 0 ? void 0 : _a.message 2091 }); 2092 logger.warn(idbGetError.message); 2093 } 2094 } 2095 } 2096 function computeKey(app2) { 2097 return `${app2.name}!${app2.options.appId}`; 2098 } 2099 var MAX_HEADER_BYTES = 1024; 2100 var STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1e3; 2101 var HeartbeatServiceImpl = class { 2102 constructor(container) { 2103 this.container = container; 2104 this._heartbeatsCache = null; 2105 const app2 = this.container.getProvider("app").getImmediate(); 2106 this._storage = new HeartbeatStorageImpl(app2); 2107 this._heartbeatsCachePromise = this._storage.read().then((result) => { 2108 this._heartbeatsCache = result; 2109 return result; 2110 }); 2111 } 2112 async triggerHeartbeat() { 2113 const platformLogger = this.container.getProvider("platform-logger").getImmediate(); 2114 const agent = platformLogger.getPlatformInfoString(); 2115 const date = getUTCDateString(); 2116 if (this._heartbeatsCache === null) { 2117 this._heartbeatsCache = await this._heartbeatsCachePromise; 2118 } 2119 if (this._heartbeatsCache.lastSentHeartbeatDate === date || this._heartbeatsCache.heartbeats.some((singleDateHeartbeat) => singleDateHeartbeat.date === date)) { 2120 return; 2121 } else { 2122 this._heartbeatsCache.heartbeats.push({ date, agent }); 2123 } 2124 this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter((singleDateHeartbeat) => { 2125 const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf(); 2126 const now = Date.now(); 2127 return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS; 2128 }); 2129 return this._storage.overwrite(this._heartbeatsCache); 2130 } 2131 async getHeartbeatsHeader() { 2132 if (this._heartbeatsCache === null) { 2133 await this._heartbeatsCachePromise; 2134 } 2135 if (this._heartbeatsCache === null || this._heartbeatsCache.heartbeats.length === 0) { 2136 return ""; 2137 } 2138 const date = getUTCDateString(); 2139 const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats); 2140 const headerString = base64urlEncodeWithoutPadding(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })); 2141 this._heartbeatsCache.lastSentHeartbeatDate = date; 2142 if (unsentEntries.length > 0) { 2143 this._heartbeatsCache.heartbeats = unsentEntries; 2144 await this._storage.overwrite(this._heartbeatsCache); 2145 } else { 2146 this._heartbeatsCache.heartbeats = []; 2147 void this._storage.overwrite(this._heartbeatsCache); 2148 } 2149 return headerString; 2150 } 2151 }; 2152 function getUTCDateString() { 2153 const today = new Date(); 2154 return today.toISOString().substring(0, 10); 2155 } 2156 function extractHeartbeatsForHeader(heartbeatsCache, maxSize = MAX_HEADER_BYTES) { 2157 const heartbeatsToSend = []; 2158 let unsentEntries = heartbeatsCache.slice(); 2159 for (const singleDateHeartbeat of heartbeatsCache) { 2160 const heartbeatEntry = heartbeatsToSend.find((hb) => hb.agent === singleDateHeartbeat.agent); 2161 if (!heartbeatEntry) { 2162 heartbeatsToSend.push({ 2163 agent: singleDateHeartbeat.agent, 2164 dates: [singleDateHeartbeat.date] 2165 }); 2166 if (countBytes(heartbeatsToSend) > maxSize) { 2167 heartbeatsToSend.pop(); 2168 break; 2169 } 2170 } else { 2171 heartbeatEntry.dates.push(singleDateHeartbeat.date); 2172 if (countBytes(heartbeatsToSend) > maxSize) { 2173 heartbeatEntry.dates.pop(); 2174 break; 2175 } 2176 } 2177 unsentEntries = unsentEntries.slice(1); 2178 } 2179 return { 2180 heartbeatsToSend, 2181 unsentEntries 2182 }; 2183 } 2184 var HeartbeatStorageImpl = class { 2185 constructor(app2) { 2186 this.app = app2; 2187 this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck(); 2188 } 2189 async runIndexedDBEnvironmentCheck() { 2190 if (!isIndexedDBAvailable()) { 2191 return false; 2192 } else { 2193 return validateIndexedDBOpenable().then(() => true).catch(() => false); 2194 } 2195 } 2196 async read() { 2197 const canUseIndexedDB = await this._canUseIndexedDBPromise; 2198 if (!canUseIndexedDB) { 2199 return { heartbeats: [] }; 2200 } else { 2201 const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app); 2202 return idbHeartbeatObject || { heartbeats: [] }; 2203 } 2204 } 2205 async overwrite(heartbeatsObject) { 2206 var _a; 2207 const canUseIndexedDB = await this._canUseIndexedDBPromise; 2208 if (!canUseIndexedDB) { 2209 return; 2210 } else { 2211 const existingHeartbeatsObject = await this.read(); 2212 return writeHeartbeatsToIndexedDB(this.app, { 2213 lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate, 2214 heartbeats: heartbeatsObject.heartbeats 2215 }); 2216 } 2217 } 2218 async add(heartbeatsObject) { 2219 var _a; 2220 const canUseIndexedDB = await this._canUseIndexedDBPromise; 2221 if (!canUseIndexedDB) { 2222 return; 2223 } else { 2224 const existingHeartbeatsObject = await this.read(); 2225 return writeHeartbeatsToIndexedDB(this.app, { 2226 lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate, 2227 heartbeats: [ 2228 ...existingHeartbeatsObject.heartbeats, 2229 ...heartbeatsObject.heartbeats 2230 ] 2231 }); 2232 } 2233 } 2234 }; 2235 function countBytes(heartbeatsCache) { 2236 return base64urlEncodeWithoutPadding(JSON.stringify({ version: 2, heartbeats: heartbeatsCache })).length; 2237 } 2238 function registerCoreComponents(variant) { 2239 _registerComponent(new Component("platform-logger", (container) => new PlatformLoggerServiceImpl(container), "PRIVATE")); 2240 _registerComponent(new Component("heartbeat", (container) => new HeartbeatServiceImpl(container), "PRIVATE")); 2241 registerVersion(name$o, version$1, variant); 2242 registerVersion(name$o, version$1, "esm2017"); 2243 registerVersion("fire-js", ""); 2244 } 2245 registerCoreComponents(""); 2246 2247
vendor: 145 bytes, lines 2247-2252
2247// node_modules/firebase/app/dist/index.esm.js 2248 var name2 = "firebase"; 2249 var version2 = "9.9.4"; 2250 registerVersion(name2, version2, "app"); 2251 2252
vendor: 19,135 bytes, lines 2252-2782
2252// node_modules/@firebase/installations/dist/esm/index.esm2017.js 2253 var name3 = "@firebase/installations"; 2254 var version3 = "0.5.12"; 2255 var PENDING_TIMEOUT_MS = 1e4; 2256 var PACKAGE_VERSION = `w:${version3}`; 2257 var INTERNAL_AUTH_VERSION = "FIS_v2"; 2258 var INSTALLATIONS_API_URL = "https://firebaseinstallations.googleapis.com/v1"; 2259 var TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1e3; 2260 var SERVICE = "installations"; 2261 var SERVICE_NAME = "Installations"; 2262 var ERROR_DESCRIPTION_MAP = { 2263 ["missing-app-config-values"]: 'Missing App configuration value: "{$valueName}"', 2264 ["not-registered"]: "Firebase Installation is not registered.", 2265 ["installation-not-found"]: "Firebase Installation not found.", 2266 ["request-failed"]: '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"', 2267 ["app-offline"]: "Could not process request. Application offline.", 2268 ["delete-pending-registration"]: "Can't delete installation while there is a pending registration request." 2269 }; 2270 var ERROR_FACTORY2 = new ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP); 2271 function isServerError(error2) { 2272 return error2 instanceof FirebaseError && error2.code.includes("request-failed"); 2273 } 2274 function getInstallationsEndpoint({ projectId }) { 2275 return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`; 2276 } 2277 function extractAuthTokenInfoFromResponse(response) { 2278 return { 2279 token: response.token, 2280 requestStatus: 2, 2281 expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn), 2282 creationTime: Date.now() 2283 }; 2284 } 2285 async function getErrorFromResponse(requestName, response) { 2286 const responseJson = await response.json(); 2287 const errorData = responseJson.error; 2288 return ERROR_FACTORY2.create("request-failed", { 2289 requestName, 2290 serverCode: errorData.code, 2291 serverMessage: errorData.message, 2292 serverStatus: errorData.status 2293 }); 2294 } 2295 function getHeaders({ apiKey }) { 2296 return new Headers({ 2297 "Content-Type": "application/json", 2298 Accept: "application/json", 2299 "x-goog-api-key": apiKey 2300 }); 2301 } 2302 function getHeadersWithAuth(appConfig, { refreshToken }) { 2303 const headers = getHeaders(appConfig); 2304 headers.append("Authorization", getAuthorizationHeader(refreshToken)); 2305 return headers; 2306 } 2307 async function retryIfServerError(fn) { 2308 const result = await fn(); 2309 if (result.status >= 500 && result.status < 600) { 2310 return fn(); 2311 } 2312 return result; 2313 } 2314 function getExpiresInFromResponseExpiresIn(responseExpiresIn) { 2315 return Number(responseExpiresIn.replace("s", "000")); 2316 } 2317 function getAuthorizationHeader(refreshToken) { 2318 return `${INTERNAL_AUTH_VERSION} ${refreshToken}`; 2319 } 2320 async function createInstallationRequest({ appConfig, heartbeatServiceProvider }, { fid }) { 2321 const endpoint = getInstallationsEndpoint(appConfig); 2322 const headers = getHeaders(appConfig); 2323 const heartbeatService = heartbeatServiceProvider.getImmediate({ 2324 optional: true 2325 }); 2326 if (heartbeatService) { 2327 const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader(); 2328 if (heartbeatsHeader) { 2329 headers.append("x-firebase-client", heartbeatsHeader); 2330 } 2331 } 2332 const body = { 2333 fid, 2334 authVersion: INTERNAL_AUTH_VERSION, 2335 appId: appConfig.appId, 2336 sdkVersion: PACKAGE_VERSION 2337 }; 2338 const request = { 2339 method: "POST", 2340 headers, 2341 body: JSON.stringify(body) 2342 }; 2343 const response = await retryIfServerError(() => fetch(endpoint, request)); 2344 if (response.ok) { 2345 const responseValue = await response.json(); 2346 const registeredInstallationEntry = { 2347 fid: responseValue.fid || fid, 2348 registrationStatus: 2, 2349 refreshToken: responseValue.refreshToken, 2350 authToken: extractAuthTokenInfoFromResponse(responseValue.authToken) 2351 }; 2352 return registeredInstallationEntry; 2353 } else { 2354 throw await getErrorFromResponse("Create Installation", response); 2355 } 2356 } 2357 function sleep(ms) { 2358 return new Promise((resolve) => { 2359 setTimeout(resolve, ms); 2360 }); 2361 } 2362 function bufferToBase64UrlSafe(array) { 2363 const b64 = btoa(String.fromCharCode(...array)); 2364 return b64.replace(/\+/g, "-").replace(/\//g, "_"); 2365 } 2366 var VALID_FID_PATTERN = /^[cdef][\w-]{21}$/; 2367 var INVALID_FID = ""; 2368 function generateFid() { 2369 try { 2370 const fidByteArray = new Uint8Array(17); 2371 const crypto = self.crypto || self.msCrypto; 2372 crypto.getRandomValues(fidByteArray); 2373 fidByteArray[0] = 112 + fidByteArray[0] % 16; 2374 const fid = encode(fidByteArray); 2375 return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID; 2376 } catch (_a) { 2377 return INVALID_FID; 2378 } 2379 } 2380 function encode(fidByteArray) { 2381 const b64String = bufferToBase64UrlSafe(fidByteArray); 2382 return b64String.substr(0, 22); 2383 } 2384 function getKey(appConfig) { 2385 return `${appConfig.appName}!${appConfig.appId}`; 2386 } 2387 var fidChangeCallbacks = /* @__PURE__ */ new Map(); 2388 function fidChanged(appConfig, fid) { 2389 const key = getKey(appConfig); 2390 callFidChangeCallbacks(key, fid); 2391 broadcastFidChange(key, fid); 2392 } 2393 function callFidChangeCallbacks(key, fid) { 2394 const callbacks = fidChangeCallbacks.get(key); 2395 if (!callbacks) { 2396 return; 2397 } 2398 for (const callback of callbacks) { 2399 callback(fid); 2400 } 2401 } 2402 function broadcastFidChange(key, fid) { 2403 const channel = getBroadcastChannel(); 2404 if (channel) { 2405 channel.postMessage({ key, fid }); 2406 } 2407 closeBroadcastChannel(); 2408 } 2409 var broadcastChannel = null; 2410 function getBroadcastChannel() { 2411 if (!broadcastChannel && "BroadcastChannel" in self) { 2412 broadcastChannel = new BroadcastChannel("[Firebase] FID Change"); 2413 broadcastChannel.onmessage = (e) => { 2414 callFidChangeCallbacks(e.data.key, e.data.fid); 2415 }; 2416 } 2417 return broadcastChannel; 2418 } 2419 function closeBroadcastChannel() { 2420 if (fidChangeCallbacks.size === 0 && broadcastChannel) { 2421 broadcastChannel.close(); 2422 broadcastChannel = null; 2423 } 2424 } 2425 var DATABASE_NAME = "firebase-installations-database"; 2426 var DATABASE_VERSION = 1; 2427 var OBJECT_STORE_NAME = "firebase-installations-store"; 2428 var dbPromise2 = null; 2429 function getDbPromise2() { 2430 if (!dbPromise2) { 2431 dbPromise2 = openDB(DATABASE_NAME, DATABASE_VERSION, { 2432 upgrade: (db2, oldVersion) => { 2433 switch (oldVersion) { 2434 case 0: 2435 db2.createObjectStore(OBJECT_STORE_NAME); 2436 } 2437 } 2438 }); 2439 } 2440 return dbPromise2; 2441 } 2442 async function set(appConfig, value) { 2443 const key = getKey(appConfig); 2444 const db2 = await getDbPromise2(); 2445 const tx = db2.transaction(OBJECT_STORE_NAME, "readwrite"); 2446 const objectStore = tx.objectStore(OBJECT_STORE_NAME); 2447 const oldValue = await objectStore.get(key); 2448 await objectStore.put(value, key); 2449 await tx.done; 2450 if (!oldValue || oldValue.fid !== value.fid) { 2451 fidChanged(appConfig, value.fid); 2452 } 2453 return value; 2454 } 2455 async function remove(appConfig) { 2456 const key = getKey(appConfig); 2457 const db2 = await getDbPromise2(); 2458 const tx = db2.transaction(OBJECT_STORE_NAME, "readwrite"); 2459 await tx.objectStore(OBJECT_STORE_NAME).delete(key); 2460 await tx.done; 2461 } 2462 async function update(appConfig, updateFn) { 2463 const key = getKey(appConfig); 2464 const db2 = await getDbPromise2(); 2465 const tx = db2.transaction(OBJECT_STORE_NAME, "readwrite"); 2466 const store = tx.objectStore(OBJECT_STORE_NAME); 2467 const oldValue = await store.get(key); 2468 const newValue = updateFn(oldValue); 2469 if (newValue === void 0) { 2470 await store.delete(key); 2471 } else { 2472 await store.put(newValue, key); 2473 } 2474 await tx.done; 2475 if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) { 2476 fidChanged(appConfig, newValue.fid); 2477 } 2478 return newValue; 2479 } 2480 async function getInstallationEntry(installations) { 2481 let registrationPromise; 2482 const installationEntry = await update(installations.appConfig, (oldEntry) => { 2483 const installationEntry2 = updateOrCreateInstallationEntry(oldEntry); 2484 const entryWithPromise = triggerRegistrationIfNecessary(installations, installationEntry2); 2485 registrationPromise = entryWithPromise.registrationPromise; 2486 return entryWithPromise.installationEntry; 2487 }); 2488 if (installationEntry.fid === INVALID_FID) { 2489 return { installationEntry: await registrationPromise }; 2490 } 2491 return { 2492 installationEntry, 2493 registrationPromise 2494 }; 2495 } 2496 function updateOrCreateInstallationEntry(oldEntry) { 2497 const entry = oldEntry || { 2498 fid: generateFid(), 2499 registrationStatus: 0 2500 }; 2501 return clearTimedOutRequest(entry); 2502 } 2503 function triggerRegistrationIfNecessary(installations, installationEntry) { 2504 if (installationEntry.registrationStatus === 0) { 2505 if (!navigator.onLine) { 2506 const registrationPromiseWithError = Promise.reject(ERROR_FACTORY2.create("app-offline")); 2507 return { 2508 installationEntry, 2509 registrationPromise: registrationPromiseWithError 2510 }; 2511 } 2512 const inProgressEntry = { 2513 fid: installationEntry.fid, 2514 registrationStatus: 1, 2515 registrationTime: Date.now() 2516 }; 2517 const registrationPromise = registerInstallation(installations, inProgressEntry); 2518 return { installationEntry: inProgressEntry, registrationPromise }; 2519 } else if (installationEntry.registrationStatus === 1) { 2520 return { 2521 installationEntry, 2522 registrationPromise: waitUntilFidRegistration(installations) 2523 }; 2524 } else { 2525 return { installationEntry }; 2526 } 2527 } 2528 async function registerInstallation(installations, installationEntry) { 2529 try { 2530 const registeredInstallationEntry = await createInstallationRequest(installations, installationEntry); 2531 return set(installations.appConfig, registeredInstallationEntry); 2532 } catch (e) { 2533 if (isServerError(e) && e.customData.serverCode === 409) { 2534 await remove(installations.appConfig); 2535 } else { 2536 await set(installations.appConfig, { 2537 fid: installationEntry.fid, 2538 registrationStatus: 0 2539 }); 2540 } 2541 throw e; 2542 } 2543 } 2544 async function waitUntilFidRegistration(installations) { 2545 let entry = await updateInstallationRequest(installations.appConfig); 2546 while (entry.registrationStatus === 1) { 2547 await sleep(100); 2548 entry = await updateInstallationRequest(installations.appConfig); 2549 } 2550 if (entry.registrationStatus === 0) { 2551 const { installationEntry, registrationPromise } = await getInstallationEntry(installations); 2552 if (registrationPromise) { 2553 return registrationPromise; 2554 } else { 2555 return installationEntry; 2556 } 2557 } 2558 return entry; 2559 } 2560 function updateInstallationRequest(appConfig) { 2561 return update(appConfig, (oldEntry) => { 2562 if (!oldEntry) { 2563 throw ERROR_FACTORY2.create("installation-not-found"); 2564 } 2565 return clearTimedOutRequest(oldEntry); 2566 }); 2567 } 2568 function clearTimedOutRequest(entry) { 2569 if (hasInstallationRequestTimedOut(entry)) { 2570 return { 2571 fid: entry.fid, 2572 registrationStatus: 0 2573 }; 2574 } 2575 return entry; 2576 } 2577 function hasInstallationRequestTimedOut(installationEntry) { 2578 return installationEntry.registrationStatus === 1 && installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now(); 2579 } 2580 async function generateAuthTokenRequest({ appConfig, heartbeatServiceProvider }, installationEntry) { 2581 const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry); 2582 const headers = getHeadersWithAuth(appConfig, installationEntry); 2583 const heartbeatService = heartbeatServiceProvider.getImmediate({ 2584 optional: true 2585 }); 2586 if (heartbeatService) { 2587 const heartbeatsHeader = await heartbeatService.getHeartbeatsHeader(); 2588 if (heartbeatsHeader) { 2589 headers.append("x-firebase-client", heartbeatsHeader); 2590 } 2591 } 2592 const body = { 2593 installation: { 2594 sdkVersion: PACKAGE_VERSION, 2595 appId: appConfig.appId 2596 } 2597 }; 2598 const request = { 2599 method: "POST", 2600 headers, 2601 body: JSON.stringify(body) 2602 }; 2603 const response = await retryIfServerError(() => fetch(endpoint, request)); 2604 if (response.ok) { 2605 const responseValue = await response.json(); 2606 const completedAuthToken = extractAuthTokenInfoFromResponse(responseValue); 2607 return completedAuthToken; 2608 } else { 2609 throw await getErrorFromResponse("Generate Auth Token", response); 2610 } 2611 } 2612 function getGenerateAuthTokenEndpoint(appConfig, { fid }) { 2613 return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`; 2614 } 2615 async function refreshAuthToken(installations, forceRefresh = false) { 2616 let tokenPromise; 2617 const entry = await update(installations.appConfig, (oldEntry) => { 2618 if (!isEntryRegistered(oldEntry)) { 2619 throw ERROR_FACTORY2.create("not-registered"); 2620 } 2621 const oldAuthToken = oldEntry.authToken; 2622 if (!forceRefresh && isAuthTokenValid(oldAuthToken)) { 2623 return oldEntry; 2624 } else if (oldAuthToken.requestStatus === 1) { 2625 tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh); 2626 return oldEntry; 2627 } else { 2628 if (!navigator.onLine) { 2629 throw ERROR_FACTORY2.create("app-offline"); 2630 } 2631 const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry); 2632 tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry); 2633 return inProgressEntry; 2634 } 2635 }); 2636 const authToken = tokenPromise ? await tokenPromise : entry.authToken; 2637 return authToken; 2638 } 2639 async function waitUntilAuthTokenRequest(installations, forceRefresh) { 2640 let entry = await updateAuthTokenRequest(installations.appConfig); 2641 while (entry.authToken.requestStatus === 1) { 2642 await sleep(100); 2643 entry = await updateAuthTokenRequest(installations.appConfig); 2644 } 2645 const authToken = entry.authToken; 2646 if (authToken.requestStatus === 0) { 2647 return refreshAuthToken(installations, forceRefresh); 2648 } else { 2649 return authToken; 2650 } 2651 } 2652 function updateAuthTokenRequest(appConfig) { 2653 return update(appConfig, (oldEntry) => { 2654 if (!isEntryRegistered(oldEntry)) { 2655 throw ERROR_FACTORY2.create("not-registered"); 2656 } 2657 const oldAuthToken = oldEntry.authToken; 2658 if (hasAuthTokenRequestTimedOut(oldAuthToken)) { 2659 return Object.assign(Object.assign({}, oldEntry), { authToken: { requestStatus: 0 } }); 2660 } 2661 return oldEntry; 2662 }); 2663 } 2664 async function fetchAuthTokenFromServer(installations, installationEntry) { 2665 try { 2666 const authToken = await generateAuthTokenRequest(installations, installationEntry); 2667 const updatedInstallationEntry = Object.assign(Object.assign({}, installationEntry), { authToken }); 2668 await set(installations.appConfig, updatedInstallationEntry); 2669 return authToken; 2670 } catch (e) { 2671 if (isServerError(e) && (e.customData.serverCode === 401 || e.customData.serverCode === 404)) { 2672 await remove(installations.appConfig); 2673 } else { 2674 const updatedInstallationEntry = Object.assign(Object.assign({}, installationEntry), { authToken: { requestStatus: 0 } }); 2675 await set(installations.appConfig, updatedInstallationEntry); 2676 } 2677 throw e; 2678 } 2679 } 2680 function isEntryRegistered(installationEntry) { 2681 return installationEntry !== void 0 && installationEntry.registrationStatus === 2; 2682 } 2683 function isAuthTokenValid(authToken) { 2684 return authToken.requestStatus === 2 && !isAuthTokenExpired(authToken); 2685 } 2686 function isAuthTokenExpired(authToken) { 2687 const now = Date.now(); 2688 return now < authToken.creationTime || authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER; 2689 } 2690 function makeAuthTokenRequestInProgressEntry(oldEntry) { 2691 const inProgressAuthToken = { 2692 requestStatus: 1, 2693 requestTime: Date.now() 2694 }; 2695 return Object.assign(Object.assign({}, oldEntry), { authToken: inProgressAuthToken }); 2696 } 2697 function hasAuthTokenRequestTimedOut(authToken) { 2698 return authToken.requestStatus === 1 && authToken.requestTime + PENDING_TIMEOUT_MS < Date.now(); 2699 } 2700 async function getId(installations) { 2701 const installationsImpl = installations; 2702 const { installationEntry, registrationPromise } = await getInstallationEntry(installationsImpl); 2703 if (registrationPromise) { 2704 registrationPromise.catch(console.error); 2705 } else { 2706 refreshAuthToken(installationsImpl).catch(console.error); 2707 } 2708 return installationEntry.fid; 2709 } 2710 async function getToken(installations, forceRefresh = false) { 2711 const installationsImpl = installations; 2712 await completeInstallationRegistration(installationsImpl); 2713 const authToken = await refreshAuthToken(installationsImpl, forceRefresh); 2714 return authToken.token; 2715 } 2716 async function completeInstallationRegistration(installations) { 2717 const { registrationPromise } = await getInstallationEntry(installations); 2718 if (registrationPromise) { 2719 await registrationPromise; 2720 } 2721 } 2722 function extractAppConfig(app2) { 2723 if (!app2 || !app2.options) { 2724 throw getMissingValueError("App Configuration"); 2725 } 2726 if (!app2.name) { 2727 throw getMissingValueError("App Name"); 2728 } 2729 const configKeys = [ 2730 "projectId", 2731 "apiKey", 2732 "appId" 2733 ]; 2734 for (const keyName of configKeys) { 2735 if (!app2.options[keyName]) { 2736 throw getMissingValueError(keyName); 2737 } 2738 } 2739 return { 2740 appName: app2.name, 2741 projectId: app2.options.projectId, 2742 apiKey: app2.options.apiKey, 2743 appId: app2.options.appId 2744 }; 2745 } 2746 function getMissingValueError(valueName) { 2747 return ERROR_FACTORY2.create("missing-app-config-values", { 2748 valueName 2749 }); 2750 } 2751 var INSTALLATIONS_NAME = "installations"; 2752 var INSTALLATIONS_NAME_INTERNAL = "installations-internal"; 2753 var publicFactory = (container) => { 2754 const app2 = container.getProvider("app").getImmediate(); 2755 const appConfig = extractAppConfig(app2); 2756 const heartbeatServiceProvider = _getProvider(app2, "heartbeat"); 2757 const installationsImpl = { 2758 app: app2, 2759 appConfig, 2760 heartbeatServiceProvider, 2761 _delete: () => Promise.resolve() 2762 }; 2763 return installationsImpl; 2764 }; 2765 var internalFactory = (container) => { 2766 const app2 = container.getProvider("app").getImmediate(); 2767 const installations = _getProvider(app2, INSTALLATIONS_NAME).getImmediate(); 2768 const installationsInternal = { 2769 getId: () => getId(installations), 2770 getToken: (forceRefresh) => getToken(installations, forceRefresh) 2771 }; 2772 return installationsInternal; 2773 }; 2774 function registerInstallations() { 2775 _registerComponent(new Component(INSTALLATIONS_NAME, publicFactory, "PUBLIC")); 2776 _registerComponent(new Component(INSTALLATIONS_NAME_INTERNAL, internalFactory, "PRIVATE")); 2777 } 2778 registerInstallations(); 2779 registerVersion(name3, version3); 2780 registerVersion(name3, version3, "esm2017"); 2781 2782
vendor: 19,684 bytes, lines 2782-3231
2782// node_modules/@firebase/analytics/dist/esm/index.esm2017.js 2783 var ANALYTICS_TYPE = "analytics"; 2784 var GA_FID_KEY = "firebase_id"; 2785 var ORIGIN_KEY = "origin"; 2786 var FETCH_TIMEOUT_MILLIS = 60 * 1e3; 2787 var DYNAMIC_CONFIG_URL = "https://firebase.googleapis.com/v1alpha/projects/-/apps/{app-id}/webConfig"; 2788 var GTAG_URL = "https://www.googletagmanager.com/gtag/js"; 2789 var logger2 = new Logger("@firebase/analytics"); 2790 function promiseAllSettled(promises) { 2791 return Promise.all(promises.map((promise) => promise.catch((e) => e))); 2792 } 2793 function insertScriptTag(dataLayerName2, measurementId) { 2794 const script = document.createElement("script"); 2795 script.src = `${GTAG_URL}?l=${dataLayerName2}&id=${measurementId}`; 2796 script.async = true; 2797 document.head.appendChild(script); 2798 } 2799 function getOrCreateDataLayer(dataLayerName2) { 2800 let dataLayer = []; 2801 if (Array.isArray(window[dataLayerName2])) { 2802 dataLayer = window[dataLayerName2]; 2803 } else { 2804 window[dataLayerName2] = dataLayer; 2805 } 2806 return dataLayer; 2807 } 2808 async function gtagOnConfig(gtagCore, initializationPromisesMap2, dynamicConfigPromisesList2, measurementIdToAppId2, measurementId, gtagParams) { 2809 const correspondingAppId = measurementIdToAppId2[measurementId]; 2810 try { 2811 if (correspondingAppId) { 2812 await initializationPromisesMap2[correspondingAppId]; 2813 } else { 2814 const dynamicConfigResults = await promiseAllSettled(dynamicConfigPromisesList2); 2815 const foundConfig = dynamicConfigResults.find((config) => config.measurementId === measurementId); 2816 if (foundConfig) { 2817 await initializationPromisesMap2[foundConfig.appId]; 2818 } 2819 } 2820 } catch (e) { 2821 logger2.error(e); 2822 } 2823 gtagCore("config", measurementId, gtagParams); 2824 } 2825 async function gtagOnEvent(gtagCore, initializationPromisesMap2, dynamicConfigPromisesList2, measurementId, gtagParams) { 2826 try { 2827 let initializationPromisesToWaitFor = []; 2828 if (gtagParams && gtagParams["send_to"]) { 2829 let gaSendToList = gtagParams["send_to"]; 2830 if (!Array.isArray(gaSendToList)) { 2831 gaSendToList = [gaSendToList]; 2832 } 2833 const dynamicConfigResults = await promiseAllSettled(dynamicConfigPromisesList2); 2834 for (const sendToId of gaSendToList) { 2835 const foundConfig = dynamicConfigResults.find((config) => config.measurementId === sendToId); 2836 const initializationPromise = foundConfig && initializationPromisesMap2[foundConfig.appId]; 2837 if (initializationPromise) { 2838 initializationPromisesToWaitFor.push(initializationPromise); 2839 } else { 2840 initializationPromisesToWaitFor = []; 2841 break; 2842 } 2843 } 2844 } 2845 if (initializationPromisesToWaitFor.length === 0) { 2846 initializationPromisesToWaitFor = Object.values(initializationPromisesMap2); 2847 } 2848 await Promise.all(initializationPromisesToWaitFor); 2849 gtagCore("event", measurementId, gtagParams || {}); 2850 } catch (e) { 2851 logger2.error(e); 2852 } 2853 } 2854 function wrapGtag(gtagCore, initializationPromisesMap2, dynamicConfigPromisesList2, measurementIdToAppId2) { 2855 async function gtagWrapper(command, idOrNameOrParams, gtagParams) { 2856 try { 2857 if (command === "event") { 2858 await gtagOnEvent(gtagCore, initializationPromisesMap2, dynamicConfigPromisesList2, idOrNameOrParams, gtagParams); 2859 } else if (command === "config") { 2860 await gtagOnConfig(gtagCore, initializationPromisesMap2, dynamicConfigPromisesList2, measurementIdToAppId2, idOrNameOrParams, gtagParams); 2861 } else if (command === "consent") { 2862 gtagCore("consent", "update", gtagParams); 2863 } else { 2864 gtagCore("set", idOrNameOrParams); 2865 } 2866 } catch (e) { 2867 logger2.error(e); 2868 } 2869 } 2870 return gtagWrapper; 2871 } 2872 function wrapOrCreateGtag(initializationPromisesMap2, dynamicConfigPromisesList2, measurementIdToAppId2, dataLayerName2, gtagFunctionName) { 2873 let gtagCore = function(..._args) { 2874 window[dataLayerName2].push(arguments); 2875 }; 2876 if (window[gtagFunctionName] && typeof window[gtagFunctionName] === "function") { 2877 gtagCore = window[gtagFunctionName]; 2878 } 2879 window[gtagFunctionName] = wrapGtag(gtagCore, initializationPromisesMap2, dynamicConfigPromisesList2, measurementIdToAppId2); 2880 return { 2881 gtagCore, 2882 wrappedGtag: window[gtagFunctionName] 2883 }; 2884 } 2885 function findGtagScriptOnPage() { 2886 const scriptTags = window.document.getElementsByTagName("script"); 2887 for (const tag of Object.values(scriptTags)) { 2888 if (tag.src && tag.src.includes(GTAG_URL)) { 2889 return tag; 2890 } 2891 } 2892 return null; 2893 } 2894 var ERRORS2 = { 2895 ["already-exists"]: "A Firebase Analytics instance with the appId {$id} already exists. Only one Firebase Analytics instance can be created for each appId.", 2896 ["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-intialized instance.", 2897 ["already-initialized-settings"]: "Firebase Analytics has already been initialized.settings() must be called before initializing any Analytics instanceor it will have no effect.", 2898 ["interop-component-reg-failed"]: "Firebase Analytics Interop Component failed to instantiate: {$reason}", 2899 ["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}", 2900 ["indexeddb-unavailable"]: "IndexedDB unavailable or restricted in this environment. Wrap initialization of analytics in analytics.isSupported() to prevent initialization in unsupported environments. Details: {$errorInfo}", 2901 ["fetch-throttle"]: "The config fetch request timed out while in an exponential backoff state. Unix timestamp in milliseconds when fetch request throttling ends: {$throttleEndTimeMillis}.", 2902 ["config-fetch-failed"]: "Dynamic config fetch failed: [{$httpStatus}] {$responseMessage}", 2903 ["no-api-key"]: 'The "apiKey" field is empty in the local Firebase config. Firebase Analytics requires this field tocontain a valid API key.', 2904 ["no-app-id"]: 'The "appId" field is empty in the local Firebase config. Firebase Analytics requires this field tocontain a valid app ID.' 2905 }; 2906 var ERROR_FACTORY3 = new ErrorFactory("analytics", "Analytics", ERRORS2); 2907 var LONG_RETRY_FACTOR = 30; 2908 var BASE_INTERVAL_MILLIS = 1e3; 2909 var RetryData = class { 2910 constructor(throttleMetadata = {}, intervalMillis = BASE_INTERVAL_MILLIS) { 2911 this.throttleMetadata = throttleMetadata; 2912 this.intervalMillis = intervalMillis; 2913 } 2914 getThrottleMetadata(appId) { 2915 return this.throttleMetadata[appId]; 2916 } 2917 setThrottleMetadata(appId, metadata) { 2918 this.throttleMetadata[appId] = metadata; 2919 } 2920 deleteThrottleMetadata(appId) { 2921 delete this.throttleMetadata[appId]; 2922 } 2923 }; 2924 var defaultRetryData = new RetryData(); 2925 function getHeaders2(apiKey) { 2926 return new Headers({ 2927 Accept: "application/json", 2928 "x-goog-api-key": apiKey 2929 }); 2930 } 2931 async function fetchDynamicConfig(appFields) { 2932 var _a; 2933 const { appId, apiKey } = appFields; 2934 const request = { 2935 method: "GET", 2936 headers: getHeaders2(apiKey) 2937 }; 2938 const appUrl = DYNAMIC_CONFIG_URL.replace("{app-id}", appId); 2939 const response = await fetch(appUrl, request); 2940 if (response.status !== 200 && response.status !== 304) { 2941 let errorMessage = ""; 2942 try { 2943 const jsonResponse = await response.json(); 2944 if ((_a = jsonResponse.error) === null || _a === void 0 ? void 0 : _a.message) { 2945 errorMessage = jsonResponse.error.message; 2946 } 2947 } catch (_ignored) { 2948 } 2949 throw ERROR_FACTORY3.create("config-fetch-failed", { 2950 httpStatus: response.status, 2951 responseMessage: errorMessage 2952 }); 2953 } 2954 return response.json(); 2955 } 2956 async function fetchDynamicConfigWithRetry(app2, retryData = defaultRetryData, timeoutMillis) { 2957 const { appId, apiKey, measurementId } = app2.options; 2958 if (!appId) { 2959 throw ERROR_FACTORY3.create("no-app-id"); 2960 } 2961 if (!apiKey) { 2962 if (measurementId) { 2963 return { 2964 measurementId, 2965 appId 2966 }; 2967 } 2968 throw ERROR_FACTORY3.create("no-api-key"); 2969 } 2970 const throttleMetadata = retryData.getThrottleMetadata(appId) || { 2971 backoffCount: 0, 2972 throttleEndTimeMillis: Date.now() 2973 }; 2974 const signal = new AnalyticsAbortSignal(); 2975 setTimeout(async () => { 2976 signal.abort(); 2977 }, timeoutMillis !== void 0 ? timeoutMillis : FETCH_TIMEOUT_MILLIS); 2978 return attemptFetchDynamicConfigWithRetry({ appId, apiKey, measurementId }, throttleMetadata, signal, retryData); 2979 } 2980 async function attemptFetchDynamicConfigWithRetry(appFields, { throttleEndTimeMillis, backoffCount }, signal, retryData = defaultRetryData) { 2981 var _a, _b; 2982 const { appId, measurementId } = appFields; 2983 try { 2984 await setAbortableTimeout(signal, throttleEndTimeMillis); 2985 } catch (e) { 2986 if (measurementId) { 2987 logger2.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. [${(_a = e) === null || _a === void 0 ? void 0 : _a.message}]`); 2988 return { appId, measurementId }; 2989 } 2990 throw e; 2991 } 2992 try { 2993 const response = await fetchDynamicConfig(appFields); 2994 retryData.deleteThrottleMetadata(appId); 2995 return response; 2996 } catch (e) { 2997 const error2 = e; 2998 if (!isRetriableError(error2)) { 2999 retryData.deleteThrottleMetadata(appId); 3000 if (measurementId) { 3001 logger2.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. [${error2 === null || error2 === void 0 ? void 0 : error2.message}]`); 3002 return { appId, measurementId }; 3003 } else { 3004 throw e; 3005 } 3006 } 3007 const backoffMillis = Number((_b = error2 === null || error2 === void 0 ? void 0 : error2.customData) === null || _b === void 0 ? void 0 : _b.httpStatus) === 503 ? calculateBackoffMillis(backoffCount, retryData.intervalMillis, LONG_RETRY_FACTOR) : calculateBackoffMillis(backoffCount, retryData.intervalMillis); 3008 const throttleMetadata = { 3009 throttleEndTimeMillis: Date.now() + backoffMillis, 3010 backoffCount: backoffCount + 1 3011 }; 3012 retryData.setThrottleMetadata(appId, throttleMetadata); 3013 logger2.debug(`Calling attemptFetch again in ${backoffMillis} millis`); 3014 return attemptFetchDynamicConfigWithRetry(appFields, throttleMetadata, signal, retryData); 3015 } 3016 } 3017 function setAbortableTimeout(signal, throttleEndTimeMillis) { 3018 return new Promise((resolve, reject) => { 3019 const backoffMillis = Math.max(throttleEndTimeMillis - Date.now(), 0); 3020 const timeout = setTimeout(resolve, backoffMillis); 3021 signal.addEventListener(() => { 3022 clearTimeout(timeout); 3023 reject(ERROR_FACTORY3.create("fetch-throttle", { 3024 throttleEndTimeMillis 3025 })); 3026 }); 3027 }); 3028 } 3029 function isRetriableError(e) { 3030 if (!(e instanceof FirebaseError) || !e.customData) { 3031 return false; 3032 } 3033 const httpStatus = Number(e.customData["httpStatus"]); 3034 return httpStatus === 429 || httpStatus === 500 || httpStatus === 503 || httpStatus === 504; 3035 } 3036 var AnalyticsAbortSignal = class { 3037 constructor() { 3038 this.listeners = []; 3039 } 3040 addEventListener(listener) { 3041 this.listeners.push(listener); 3042 } 3043 abort() { 3044 this.listeners.forEach((listener) => listener()); 3045 } 3046 }; 3047 var defaultEventParametersForInit; 3048 async function logEvent$1(gtagFunction, initializationPromise, eventName, eventParams, options) { 3049 if (options && options.global) { 3050 gtagFunction("event", eventName, eventParams); 3051 return; 3052 } else { 3053 const measurementId = await initializationPromise; 3054 const params = Object.assign(Object.assign({}, eventParams), { "send_to": measurementId }); 3055 gtagFunction("event", eventName, params); 3056 } 3057 } 3058 var defaultConsentSettingsForInit; 3059 function _setConsentDefaultForInit(consentSettings) { 3060 defaultConsentSettingsForInit = consentSettings; 3061 } 3062 function _setDefaultEventParametersForInit(customParams) { 3063 defaultEventParametersForInit = customParams; 3064 } 3065 async function validateIndexedDB() { 3066 var _a; 3067 if (!isIndexedDBAvailable()) { 3068 logger2.warn(ERROR_FACTORY3.create("indexeddb-unavailable", { 3069 errorInfo: "IndexedDB is not available in this environment." 3070 }).message); 3071 return false; 3072 } else { 3073 try { 3074 await validateIndexedDBOpenable(); 3075 } catch (e) { 3076 logger2.warn(ERROR_FACTORY3.create("indexeddb-unavailable", { 3077 errorInfo: (_a = e) === null || _a === void 0 ? void 0 : _a.toString() 3078 }).message); 3079 return false; 3080 } 3081 } 3082 return true; 3083 } 3084 async function _initializeAnalytics(app2, dynamicConfigPromisesList2, measurementIdToAppId2, installations, gtagCore, dataLayerName2, options) { 3085 var _a; 3086 const dynamicConfigPromise = fetchDynamicConfigWithRetry(app2); 3087 dynamicConfigPromise.then((config) => { 3088 measurementIdToAppId2[config.measurementId] = config.appId; 3089 if (app2.options.measurementId && config.measurementId !== app2.options.measurementId) { 3090 logger2.warn(`The measurement ID in the local Firebase config (${app2.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.`); 3091 } 3092 }).catch((e) => logger2.error(e)); 3093 dynamicConfigPromisesList2.push(dynamicConfigPromise); 3094 const fidPromise = validateIndexedDB().then((envIsValid) => { 3095 if (envIsValid) { 3096 return installations.getId(); 3097 } else { 3098 return void 0; 3099 } 3100 }); 3101 const [dynamicConfig, fid] = await Promise.all([ 3102 dynamicConfigPromise, 3103 fidPromise 3104 ]); 3105 if (!findGtagScriptOnPage()) { 3106 insertScriptTag(dataLayerName2, dynamicConfig.measurementId); 3107 } 3108 if (defaultConsentSettingsForInit) { 3109 gtagCore("consent", "default", defaultConsentSettingsForInit); 3110 _setConsentDefaultForInit(void 0); 3111 } 3112 gtagCore("js", new Date()); 3113 const configProperties = (_a = options === null || options === void 0 ? void 0 : options.config) !== null && _a !== void 0 ? _a : {}; 3114 configProperties[ORIGIN_KEY] = "firebase"; 3115 configProperties.update = true; 3116 if (fid != null) { 3117 configProperties[GA_FID_KEY] = fid; 3118 } 3119 gtagCore("config", dynamicConfig.measurementId, configProperties); 3120 if (defaultEventParametersForInit) { 3121 gtagCore("set", defaultEventParametersForInit); 3122 _setDefaultEventParametersForInit(void 0); 3123 } 3124 return dynamicConfig.measurementId; 3125 } 3126 var AnalyticsService = class { 3127 constructor(app2) { 3128 this.app = app2; 3129 } 3130 _delete() { 3131 delete initializationPromisesMap[this.app.options.appId]; 3132 return Promise.resolve(); 3133 } 3134 }; 3135 var initializationPromisesMap = {}; 3136 var dynamicConfigPromisesList = []; 3137 var measurementIdToAppId = {}; 3138 var dataLayerName = "dataLayer"; 3139 var gtagName = "gtag"; 3140 var gtagCoreFunction; 3141 var wrappedGtagFunction; 3142 var globalInitDone = false; 3143 function warnOnBrowserContextMismatch() { 3144 const mismatchedEnvMessages = []; 3145 if (isBrowserExtension()) { 3146 mismatchedEnvMessages.push("This is a browser extension environment."); 3147 } 3148 if (!areCookiesEnabled()) { 3149 mismatchedEnvMessages.push("Cookies are not available."); 3150 } 3151 if (mismatchedEnvMessages.length > 0) { 3152 const details = mismatchedEnvMessages.map((message, index) => `(${index + 1}) ${message}`).join(" "); 3153 const err = ERROR_FACTORY3.create("invalid-analytics-context", { 3154 errorInfo: details 3155 }); 3156 logger2.warn(err.message); 3157 } 3158 } 3159 function factory(app2, installations, options) { 3160 warnOnBrowserContextMismatch(); 3161 const appId = app2.options.appId; 3162 if (!appId) { 3163 throw ERROR_FACTORY3.create("no-app-id"); 3164 } 3165 if (!app2.options.apiKey) { 3166 if (app2.options.measurementId) { 3167 logger2.warn(`The "apiKey" field is empty in the local Firebase config. This is needed to fetch the latest measurement ID for this Firebase app. Falling back to the measurement ID ${app2.options.measurementId} provided in the "measurementId" field in the local Firebase config.`); 3168 } else { 3169 throw ERROR_FACTORY3.create("no-api-key"); 3170 } 3171 } 3172 if (initializationPromisesMap[appId] != null) { 3173 throw ERROR_FACTORY3.create("already-exists", { 3174 id: appId 3175 }); 3176 } 3177 if (!globalInitDone) { 3178 getOrCreateDataLayer(dataLayerName); 3179 const { wrappedGtag, gtagCore } = wrapOrCreateGtag(initializationPromisesMap, dynamicConfigPromisesList, measurementIdToAppId, dataLayerName, gtagName); 3180 wrappedGtagFunction = wrappedGtag; 3181 gtagCoreFunction = gtagCore; 3182 globalInitDone = true; 3183 } 3184 initializationPromisesMap[appId] = _initializeAnalytics(app2, dynamicConfigPromisesList, measurementIdToAppId, installations, gtagCoreFunction, dataLayerName, options); 3185 const analyticsInstance = new AnalyticsService(app2); 3186 return analyticsInstance; 3187 } 3188 function initializeAnalytics(app2, options = {}) { 3189 const analyticsProvider = _getProvider(app2, ANALYTICS_TYPE); 3190 if (analyticsProvider.isInitialized()) { 3191 const existingInstance = analyticsProvider.getImmediate(); 3192 if (deepEqual(options, analyticsProvider.getOptions())) { 3193 return existingInstance; 3194 } else { 3195 throw ERROR_FACTORY3.create("already-initialized"); 3196 } 3197 } 3198 const analyticsInstance = analyticsProvider.initialize({ options }); 3199 return analyticsInstance; 3200 } 3201 function logEvent(analyticsInstance, eventName, eventParams, options) { 3202 analyticsInstance = getModularInstance(analyticsInstance); 3203 logEvent$1(wrappedGtagFunction, initializationPromisesMap[analyticsInstance.app.options.appId], eventName, eventParams, options).catch((e) => logger2.error(e)); 3204 } 3205 var name4 = "@firebase/analytics"; 3206 var version4 = "0.8.0"; 3207 function registerAnalytics() { 3208 _registerComponent(new Component(ANALYTICS_TYPE, (container, { options: analyticsOptions }) => { 3209 const app2 = container.getProvider("app").getImmediate(); 3210 const installations = container.getProvider("installations-internal").getImmediate(); 3211 return factory(app2, installations, analyticsOptions); 3212 }, "PUBLIC")); 3213 _registerComponent(new Component("analytics-internal", internalFactory2, "PRIVATE")); 3214 registerVersion(name4, version4); 3215 registerVersion(name4, version4, "esm2017"); 3216 function internalFactory2(container) { 3217 try { 3218 const analytics2 = container.getProvider(ANALYTICS_TYPE).getImmediate(); 3219 return { 3220 logEvent: (eventName, eventParams, options) => logEvent(analytics2, eventName, eventParams, options) 3221 }; 3222 } catch (e) { 3223 throw ERROR_FACTORY3.create("interop-component-reg-failed", { 3224 reason: e 3225 }); 3226 } 3227 } 3228 } 3229 registerAnalytics(); 3230 3231
vendor: 587 bytes, lines 3231-3261
3231// node_modules/tslib/modules/index.js 3232 var import_tslib = __toESM(require_tslib(), 1); 3233 var { 3234 __extends, 3235 __assign, 3236 __rest, 3237 __decorate, 3238 __param, 3239 __metadata, 3240 __awaiter, 3241 __generator, 3242 __exportStar, 3243 __createBinding, 3244 __values, 3245 __read, 3246 __spread, 3247 __spreadArrays, 3248 __spreadArray, 3249 __await, 3250 __asyncGenerator, 3251 __asyncDelegator, 3252 __asyncValues, 3253 __makeTemplateObject, 3254 __importStar, 3255 __importDefault, 3256 __classPrivateFieldGet, 3257 __classPrivateFieldSet, 3258 __classPrivateFieldIn 3259 } = import_tslib.default; 3260 3261
vendor: 109,777 bytes, lines 3261-6346
3261// node_modules/@firebase/auth/dist/esm2017/index-6bd8d405.js 3262 function _prodErrorMap() { 3263 return { 3264 ["dependent-sdk-initialized-before-auth"]: "Another Firebase SDK was initialized and is trying to use Auth before Auth is initialized. Please be sure to call `initializeAuth` or `getAuth` before starting any other Firebase SDK." 3265 }; 3266 } 3267 var prodErrorMap = _prodErrorMap; 3268 var _DEFAULT_AUTH_ERROR_FACTORY = new ErrorFactory("auth", "Firebase", _prodErrorMap()); 3269 var logClient = new Logger("@firebase/auth"); 3270 function _logError(msg, ...args) { 3271 if (logClient.logLevel <= LogLevel.ERROR) { 3272 logClient.error(`Auth (${SDK_VERSION}): ${msg}`, ...args); 3273 } 3274 } 3275 function _fail(authOrCode, ...rest) { 3276 throw createErrorInternal(authOrCode, ...rest); 3277 } 3278 function _createError(authOrCode, ...rest) { 3279 return createErrorInternal(authOrCode, ...rest); 3280 } 3281 function _errorWithCustomMessage(auth2, code, message) { 3282 const errorMap = Object.assign(Object.assign({}, prodErrorMap()), { [code]: message }); 3283 const factory2 = new ErrorFactory("auth", "Firebase", errorMap); 3284 return factory2.create(code, { 3285 appName: auth2.name 3286 }); 3287 } 3288 function createErrorInternal(authOrCode, ...rest) { 3289 if (typeof authOrCode !== "string") { 3290 const code = rest[0]; 3291 const fullParams = [...rest.slice(1)]; 3292 if (fullParams[0]) { 3293 fullParams[0].appName = authOrCode.name; 3294 } 3295 return authOrCode._errorFactory.create(code, ...fullParams); 3296 } 3297 return _DEFAULT_AUTH_ERROR_FACTORY.create(authOrCode, ...rest); 3298 } 3299 function _assert(assertion, authOrCode, ...rest) { 3300 if (!assertion) { 3301 throw createErrorInternal(authOrCode, ...rest); 3302 } 3303 } 3304 function debugFail(failure) { 3305 const message = `INTERNAL ASSERTION FAILED: ` + failure; 3306 _logError(message); 3307 throw new Error(message); 3308 } 3309 function debugAssert(assertion, message) { 3310 if (!assertion) { 3311 debugFail(message); 3312 } 3313 } 3314 var instanceCache = /* @__PURE__ */ new Map(); 3315 function _getInstance(cls) { 3316 debugAssert(cls instanceof Function, "Expected a class definition"); 3317 let instance = instanceCache.get(cls); 3318 if (instance) { 3319 debugAssert(instance instanceof cls, "Instance stored in cache mismatched with class"); 3320 return instance; 3321 } 3322 instance = new cls(); 3323 instanceCache.set(cls, instance); 3324 return instance; 3325 } 3326 function initializeAuth(app2, deps) { 3327 const provider = _getProvider(app2, "auth"); 3328 if (provider.isInitialized()) { 3329 const auth3 = provider.getImmediate(); 3330 const initialOptions = provider.getOptions(); 3331 if (deepEqual(initialOptions, deps !== null && deps !== void 0 ? deps : {})) { 3332 return auth3; 3333 } else { 3334 _fail(auth3, "already-initialized"); 3335 } 3336 } 3337 const auth2 = provider.initialize({ options: deps }); 3338 return auth2; 3339 } 3340 function _initializeAuthInstance(auth2, deps) { 3341 const persistence = (deps === null || deps === void 0 ? void 0 : deps.persistence) || []; 3342 const hierarchy = (Array.isArray(persistence) ? persistence : [persistence]).map(_getInstance); 3343 if (deps === null || deps === void 0 ? void 0 : deps.errorMap) { 3344 auth2._updateErrorMap(deps.errorMap); 3345 } 3346 auth2._initializeWithPersistence(hierarchy, deps === null || deps === void 0 ? void 0 : deps.popupRedirectResolver); 3347 } 3348 function _isHttpOrHttps() { 3349 return _getCurrentScheme() === "http:" || _getCurrentScheme() === "https:"; 3350 } 3351 function _getCurrentScheme() { 3352 var _a; 3353 return typeof self !== "undefined" && ((_a = self.location) === null || _a === void 0 ? void 0 : _a.protocol) || null; 3354 } 3355 function _isOnline() { 3356 if (typeof navigator !== "undefined" && navigator && "onLine" in navigator && typeof navigator.onLine === "boolean" && (_isHttpOrHttps() || isBrowserExtension() || "connection" in navigator)) { 3357 return navigator.onLine; 3358 } 3359 return true; 3360 } 3361 function _getUserLanguage() { 3362 if (typeof navigator === "undefined") { 3363 return null; 3364 } 3365 const navigatorLanguage = navigator; 3366 return navigatorLanguage.languages && navigatorLanguage.languages[0] || navigatorLanguage.language || null; 3367 } 3368 var Delay = class { 3369 constructor(shortDelay, longDelay) { 3370 this.shortDelay = shortDelay; 3371 this.longDelay = longDelay; 3372 debugAssert(longDelay > shortDelay, "Short delay should be less than long delay!"); 3373 this.isMobile = isMobileCordova() || isReactNative(); 3374 } 3375 get() { 3376 if (!_isOnline()) { 3377 return Math.min(5e3, this.shortDelay); 3378 } 3379 return this.isMobile ? this.longDelay : this.shortDelay; 3380 } 3381 }; 3382 function _emulatorUrl(config, path) { 3383 debugAssert(config.emulator, "Emulator should always be set here"); 3384 const { url } = config.emulator; 3385 if (!path) { 3386 return url; 3387 } 3388 return `${url}${path.startsWith("/") ? path.slice(1) : path}`; 3389 } 3390 var FetchProvider = class { 3391 static initialize(fetchImpl, headersImpl, responseImpl) { 3392 this.fetchImpl = fetchImpl; 3393 if (headersImpl) { 3394 this.headersImpl = headersImpl; 3395 } 3396 if (responseImpl) { 3397 this.responseImpl = responseImpl; 3398 } 3399 } 3400 static fetch() { 3401 if (this.fetchImpl) { 3402 return this.fetchImpl; 3403 } 3404 if (typeof self !== "undefined" && "fetch" in self) { 3405 return self.fetch; 3406 } 3407 debugFail("Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill"); 3408 } 3409 static headers() { 3410 if (this.headersImpl) { 3411 return this.headersImpl; 3412 } 3413 if (typeof self !== "undefined" && "Headers" in self) { 3414 return self.Headers; 3415 } 3416 debugFail("Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill"); 3417 } 3418 static response() { 3419 if (this.responseImpl) { 3420 return this.responseImpl; 3421 } 3422 if (typeof self !== "undefined" && "Response" in self) { 3423 return self.Response; 3424 } 3425 debugFail("Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill"); 3426 } 3427 }; 3428 var SERVER_ERROR_MAP = { 3429 ["CREDENTIAL_MISMATCH"]: "custom-token-mismatch", 3430 ["MISSING_CUSTOM_TOKEN"]: "internal-error", 3431 ["INVALID_IDENTIFIER"]: "invalid-email", 3432 ["MISSING_CONTINUE_URI"]: "internal-error", 3433 ["INVALID_PASSWORD"]: "wrong-password", 3434 ["MISSING_PASSWORD"]: "internal-error", 3435 ["EMAIL_EXISTS"]: "email-already-in-use", 3436 ["PASSWORD_LOGIN_DISABLED"]: "operation-not-allowed", 3437 ["INVALID_IDP_RESPONSE"]: "invalid-credential", 3438 ["INVALID_PENDING_TOKEN"]: "invalid-credential", 3439 ["FEDERATED_USER_ID_ALREADY_LINKED"]: "credential-already-in-use", 3440 ["MISSING_REQ_TYPE"]: "internal-error", 3441 ["EMAIL_NOT_FOUND"]: "user-not-found", 3442 ["RESET_PASSWORD_EXCEED_LIMIT"]: "too-many-requests", 3443 ["EXPIRED_OOB_CODE"]: "expired-action-code", 3444 ["INVALID_OOB_CODE"]: "invalid-action-code", 3445 ["MISSING_OOB_CODE"]: "internal-error", 3446 ["CREDENTIAL_TOO_OLD_LOGIN_AGAIN"]: "requires-recent-login", 3447 ["INVALID_ID_TOKEN"]: "invalid-user-token", 3448 ["TOKEN_EXPIRED"]: "user-token-expired", 3449 ["USER_NOT_FOUND"]: "user-token-expired", 3450 ["TOO_MANY_ATTEMPTS_TRY_LATER"]: "too-many-requests", 3451 ["INVALID_CODE"]: "invalid-verification-code", 3452 ["INVALID_SESSION_INFO"]: "invalid-verification-id", 3453 ["INVALID_TEMPORARY_PROOF"]: "invalid-credential", 3454 ["MISSING_SESSION_INFO"]: "missing-verification-id", 3455 ["SESSION_EXPIRED"]: "code-expired", 3456 ["MISSING_ANDROID_PACKAGE_NAME"]: "missing-android-pkg-name", 3457 ["UNAUTHORIZED_DOMAIN"]: "unauthorized-continue-uri", 3458 ["INVALID_OAUTH_CLIENT_ID"]: "invalid-oauth-client-id", 3459 ["ADMIN_ONLY_OPERATION"]: "admin-restricted-operation", 3460 ["INVALID_MFA_PENDING_CREDENTIAL"]: "invalid-multi-factor-session", 3461 ["MFA_ENROLLMENT_NOT_FOUND"]: "multi-factor-info-not-found", 3462 ["MISSING_MFA_ENROLLMENT_ID"]: "missing-multi-factor-info", 3463 ["MISSING_MFA_PENDING_CREDENTIAL"]: "missing-multi-factor-session", 3464 ["SECOND_FACTOR_EXISTS"]: "second-factor-already-in-use", 3465 ["SECOND_FACTOR_LIMIT_EXCEEDED"]: "maximum-second-factor-count-exceeded", 3466 ["BLOCKING_FUNCTION_ERROR_RESPONSE"]: "internal-error" 3467 }; 3468 var DEFAULT_API_TIMEOUT_MS = new Delay(3e4, 6e4); 3469 function _addTidIfNecessary(auth2, request) { 3470 if (auth2.tenantId && !request.tenantId) { 3471 return Object.assign(Object.assign({}, request), { tenantId: auth2.tenantId }); 3472 } 3473 return request; 3474 } 3475 async function _performApiRequest(auth2, method, path, request, customErrorMap = {}) { 3476 return _performFetchWithErrorHandling(auth2, customErrorMap, async () => { 3477 let body = {}; 3478 let params = {}; 3479 if (request) { 3480 if (method === "GET") { 3481 params = request; 3482 } else { 3483 body = { 3484 body: JSON.stringify(request) 3485 }; 3486 } 3487 } 3488 const query = querystring(Object.assign({ key: auth2.config.apiKey }, params)).slice(1); 3489 const headers = await auth2._getAdditionalHeaders(); 3490 headers["Content-Type"] = "application/json"; 3491 if (auth2.languageCode) { 3492 headers["X-Firebase-Locale"] = auth2.languageCode; 3493 } 3494 return FetchProvider.fetch()(_getFinalTarget(auth2, auth2.config.apiHost, path, query), Object.assign({ 3495 method, 3496 headers, 3497 referrerPolicy: "no-referrer" 3498 }, body)); 3499 }); 3500 } 3501 async function _performFetchWithErrorHandling(auth2, customErrorMap, fetchFn) { 3502 auth2._canInitEmulator = false; 3503 const errorMap = Object.assign(Object.assign({}, SERVER_ERROR_MAP), customErrorMap); 3504 try { 3505 const networkTimeout = new NetworkTimeout(auth2); 3506 const response = await Promise.race([ 3507 fetchFn(), 3508 networkTimeout.promise 3509 ]); 3510 networkTimeout.clearNetworkTimeout(); 3511 const json = await response.json(); 3512 if ("needConfirmation" in json) { 3513 throw _makeTaggedError(auth2, "account-exists-with-different-credential", json); 3514 } 3515 if (response.ok && !("errorMessage" in json)) { 3516 return json; 3517 } else { 3518 const errorMessage = response.ok ? json.errorMessage : json.error.message; 3519 const [serverErrorCode, serverErrorMessage] = errorMessage.split(" : "); 3520 if (serverErrorCode === "FEDERATED_USER_ID_ALREADY_LINKED") { 3521 throw _makeTaggedError(auth2, "credential-already-in-use", json); 3522 } else if (serverErrorCode === "EMAIL_EXISTS") { 3523 throw _makeTaggedError(auth2, "email-already-in-use", json); 3524 } else if (serverErrorCode === "USER_DISABLED") { 3525 throw _makeTaggedError(auth2, "user-disabled", json); 3526 } 3527 const authError = errorMap[serverErrorCode] || serverErrorCode.toLowerCase().replace(/[_\s]+/g, "-"); 3528 if (serverErrorMessage) { 3529 throw _errorWithCustomMessage(auth2, authError, serverErrorMessage); 3530 } else { 3531 _fail(auth2, authError); 3532 } 3533 } 3534 } catch (e) { 3535 if (e instanceof FirebaseError) { 3536 throw e; 3537 } 3538 _fail(auth2, "network-request-failed"); 3539 } 3540 } 3541 async function _performSignInRequest(auth2, method, path, request, customErrorMap = {}) { 3542 const serverResponse = await _performApiRequest(auth2, method, path, request, customErrorMap); 3543 if ("mfaPendingCredential" in serverResponse) { 3544 _fail(auth2, "multi-factor-auth-required", { 3545 _serverResponse: serverResponse 3546 }); 3547 } 3548 return serverResponse; 3549 } 3550 function _getFinalTarget(auth2, host, path, query) { 3551 const base = `${host}${path}?${query}`; 3552 if (!auth2.config.emulator) { 3553 return `${auth2.config.apiScheme}://${base}`; 3554 } 3555 return _emulatorUrl(auth2.config, base); 3556 } 3557 var NetworkTimeout = class { 3558 constructor(auth2) { 3559 this.auth = auth2; 3560 this.timer = null; 3561 this.promise = new Promise((_, reject) => { 3562 this.timer = setTimeout(() => { 3563 return reject(_createError(this.auth, "network-request-failed")); 3564 }, DEFAULT_API_TIMEOUT_MS.get()); 3565 }); 3566 } 3567 clearNetworkTimeout() { 3568 clearTimeout(this.timer); 3569 } 3570 }; 3571 function _makeTaggedError(auth2, code, response) { 3572 const errorParams = { 3573 appName: auth2.name 3574 }; 3575 if (response.email) { 3576 errorParams.email = response.email; 3577 } 3578 if (response.phoneNumber) { 3579 errorParams.phoneNumber = response.phoneNumber; 3580 } 3581 const error2 = _createError(auth2, code, errorParams); 3582 error2.customData._tokenResponse = response; 3583 return error2; 3584 } 3585 async function deleteAccount(auth2, request) { 3586 return _performApiRequest(auth2, "POST", "/v1/accounts:delete", request); 3587 } 3588 async function getAccountInfo(auth2, request) { 3589 return _performApiRequest(auth2, "POST", "/v1/accounts:lookup", request); 3590 } 3591 function utcTimestampToDateString(utcTimestamp) { 3592 if (!utcTimestamp) { 3593 return void 0; 3594 } 3595 try { 3596 const date = new Date(Number(utcTimestamp)); 3597 if (!isNaN(date.getTime())) { 3598 return date.toUTCString(); 3599 } 3600 } catch (e) { 3601 } 3602 return void 0; 3603 } 3604 async function getIdTokenResult(user, forceRefresh = false) { 3605 const userInternal = getModularInstance(user); 3606 const token = await userInternal.getIdToken(forceRefresh); 3607 const claims = _parseToken(token); 3608 _assert(claims && claims.exp && claims.auth_time && claims.iat, userInternal.auth, "internal-error"); 3609 const firebase = typeof claims.firebase === "object" ? claims.firebase : void 0; 3610 const signInProvider = firebase === null || firebase === void 0 ? void 0 : firebase["sign_in_provider"]; 3611 return { 3612 claims, 3613 token, 3614 authTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.auth_time)), 3615 issuedAtTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.iat)), 3616 expirationTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.exp)), 3617 signInProvider: signInProvider || null, 3618 signInSecondFactor: (firebase === null || firebase === void 0 ? void 0 : firebase["sign_in_second_factor"]) || null 3619 }; 3620 } 3621 function secondsStringToMilliseconds(seconds) { 3622 return Number(seconds) * 1e3; 3623 } 3624 function _parseToken(token) { 3625 var _a; 3626 const [algorithm, payload, signature] = token.split("."); 3627 if (algorithm === void 0 || payload === void 0 || signature === void 0) { 3628 _logError("JWT malformed, contained fewer than 3 sections"); 3629 return null; 3630 } 3631 try { 3632 const decoded = base64Decode(payload); 3633 if (!decoded) { 3634 _logError("Failed to decode base64 JWT payload"); 3635 return null; 3636 } 3637 return JSON.parse(decoded); 3638 } catch (e) { 3639 _logError("Caught error parsing JWT payload as JSON", (_a = e) === null || _a === void 0 ? void 0 : _a.toString()); 3640 return null; 3641 } 3642 } 3643 function _tokenExpiresIn(token) { 3644 const parsedToken = _parseToken(token); 3645 _assert(parsedToken, "internal-error"); 3646 _assert(typeof parsedToken.exp !== "undefined", "internal-error"); 3647 _assert(typeof parsedToken.iat !== "undefined", "internal-error"); 3648 return Number(parsedToken.exp) - Number(parsedToken.iat); 3649 } 3650 async function _logoutIfInvalidated(user, promise, bypassAuthState = false) { 3651 if (bypassAuthState) { 3652 return promise; 3653 } 3654 try { 3655 return await promise; 3656 } catch (e) { 3657 if (e instanceof FirebaseError && isUserInvalidated(e)) { 3658 if (user.auth.currentUser === user) { 3659 await user.auth.signOut(); 3660 } 3661 } 3662 throw e; 3663 } 3664 } 3665 function isUserInvalidated({ code }) { 3666 return code === `auth/${"user-disabled"}` || code === `auth/${"user-token-expired"}`; 3667 } 3668 var ProactiveRefresh = class { 3669 constructor(user) { 3670 this.user = user; 3671 this.isRunning = false; 3672 this.timerId = null; 3673 this.errorBackoff = 3e4; 3674 } 3675 _start() { 3676 if (this.isRunning) { 3677 return; 3678 } 3679 this.isRunning = true; 3680 this.schedule(); 3681 } 3682 _stop() { 3683 if (!this.isRunning) { 3684 return; 3685 } 3686 this.isRunning = false; 3687 if (this.timerId !== null) { 3688 clearTimeout(this.timerId); 3689 } 3690 } 3691 getInterval(wasError) { 3692 var _a; 3693 if (wasError) { 3694 const interval = this.errorBackoff; 3695 this.errorBackoff = Math.min(this.errorBackoff * 2, 96e4); 3696 return interval; 3697 } else { 3698 this.errorBackoff = 3e4; 3699 const expTime = (_a = this.user.stsTokenManager.expirationTime) !== null && _a !== void 0 ? _a : 0; 3700 const interval = expTime - Date.now() - 3e5; 3701 return Math.max(0, interval); 3702 } 3703 } 3704 schedule(wasError = false) { 3705 if (!this.isRunning) { 3706 return; 3707 } 3708 const interval = this.getInterval(wasError); 3709 this.timerId = setTimeout(async () => { 3710 await this.iteration(); 3711 }, interval); 3712 } 3713 async iteration() { 3714 var _a; 3715 try { 3716 await this.user.getIdToken(true); 3717 } catch (e) { 3718 if (((_a = e) === null || _a === void 0 ? void 0 : _a.code) === `auth/${"network-request-failed"}`) { 3719 this.schedule(true); 3720 } 3721 return; 3722 } 3723 this.schedule(); 3724 } 3725 }; 3726 var UserMetadata = class { 3727 constructor(createdAt, lastLoginAt) { 3728 this.createdAt = createdAt; 3729 this.lastLoginAt = lastLoginAt; 3730 this._initializeTime(); 3731 } 3732 _initializeTime() { 3733 this.lastSignInTime = utcTimestampToDateString(this.lastLoginAt); 3734 this.creationTime = utcTimestampToDateString(this.createdAt); 3735 } 3736 _copy(metadata) { 3737 this.createdAt = metadata.createdAt; 3738 this.lastLoginAt = metadata.lastLoginAt; 3739 this._initializeTime(); 3740 } 3741 toJSON() { 3742 return { 3743 createdAt: this.createdAt, 3744 lastLoginAt: this.lastLoginAt 3745 }; 3746 } 3747 }; 3748 async function _reloadWithoutSaving(user) { 3749 var _a; 3750 const auth2 = user.auth; 3751 const idToken = await user.getIdToken(); 3752 const response = await _logoutIfInvalidated(user, getAccountInfo(auth2, { idToken })); 3753 _assert(response === null || response === void 0 ? void 0 : response.users.length, auth2, "internal-error"); 3754 const coreAccount = response.users[0]; 3755 user._notifyReloadListener(coreAccount); 3756 const newProviderData = ((_a = coreAccount.providerUserInfo) === null || _a === void 0 ? void 0 : _a.length) ? extractProviderData(coreAccount.providerUserInfo) : []; 3757 const providerData = mergeProviderData(user.providerData, newProviderData); 3758 const oldIsAnonymous = user.isAnonymous; 3759 const newIsAnonymous = !(user.email && coreAccount.passwordHash) && !(providerData === null || providerData === void 0 ? void 0 : providerData.length); 3760 const isAnonymous = !oldIsAnonymous ? false : newIsAnonymous; 3761 const updates = { 3762 uid: coreAccount.localId, 3763 displayName: coreAccount.displayName || null, 3764 photoURL: coreAccount.photoUrl || null, 3765 email: coreAccount.email || null, 3766 emailVerified: coreAccount.emailVerified || false, 3767 phoneNumber: coreAccount.phoneNumber || null, 3768 tenantId: coreAccount.tenantId || null, 3769 providerData, 3770 metadata: new UserMetadata(coreAccount.createdAt, coreAccount.lastLoginAt), 3771 isAnonymous 3772 }; 3773 Object.assign(user, updates); 3774 } 3775 async function reload(user) { 3776 const userInternal = getModularInstance(user); 3777 await _reloadWithoutSaving(userInternal); 3778 await userInternal.auth._persistUserIfCurrent(userInternal); 3779 userInternal.auth._notifyListenersIfCurrent(userInternal); 3780 } 3781 function mergeProviderData(original, newData) { 3782 const deduped = original.filter((o) => !newData.some((n) => n.providerId === o.providerId)); 3783 return [...deduped, ...newData]; 3784 } 3785 function extractProviderData(providers) { 3786 return providers.map((_a) => { 3787 var { providerId } = _a, provider = __rest(_a, ["providerId"]); 3788 return { 3789 providerId, 3790 uid: provider.rawId || "", 3791 displayName: provider.displayName || null, 3792 email: provider.email || null, 3793 phoneNumber: provider.phoneNumber || null, 3794 photoURL: provider.photoUrl || null 3795 }; 3796 }); 3797 } 3798 async function requestStsToken(auth2, refreshToken) { 3799 const response = await _performFetchWithErrorHandling(auth2, {}, async () => { 3800 const body = querystring({ 3801 "grant_type": "refresh_token", 3802 "refresh_token": refreshToken 3803 }).slice(1); 3804 const { tokenApiHost, apiKey } = auth2.config; 3805 const url = _getFinalTarget(auth2, tokenApiHost, "/v1/token", `key=${apiKey}`); 3806 const headers = await auth2._getAdditionalHeaders(); 3807 headers["Content-Type"] = "application/x-www-form-urlencoded"; 3808 return FetchProvider.fetch()(url, { 3809 method: "POST", 3810 headers, 3811 body 3812 }); 3813 }); 3814 return { 3815 accessToken: response.access_token, 3816 expiresIn: response.expires_in, 3817 refreshToken: response.refresh_token 3818 }; 3819 } 3820 var StsTokenManager = class { 3821 constructor() { 3822 this.refreshToken = null; 3823 this.accessToken = null; 3824 this.expirationTime = null; 3825 } 3826 get isExpired() { 3827 return !this.expirationTime || Date.now() > this.expirationTime - 3e4; 3828 } 3829 updateFromServerResponse(response) { 3830 _assert(response.idToken, "internal-error"); 3831 _assert(typeof response.idToken !== "undefined", "internal-error"); 3832 _assert(typeof response.refreshToken !== "undefined", "internal-error"); 3833 const expiresIn = "expiresIn" in response && typeof response.expiresIn !== "undefined" ? Number(response.expiresIn) : _tokenExpiresIn(response.idToken); 3834 this.updateTokensAndExpiration(response.idToken, response.refreshToken, expiresIn); 3835 } 3836 async getToken(auth2, forceRefresh = false) { 3837 _assert(!this.accessToken || this.refreshToken, auth2, "user-token-expired"); 3838 if (!forceRefresh && this.accessToken && !this.isExpired) { 3839 return this.accessToken; 3840 } 3841 if (this.refreshToken) { 3842 await this.refresh(auth2, this.refreshToken); 3843 return this.accessToken; 3844 } 3845 return null; 3846 } 3847 clearRefreshToken() { 3848 this.refreshToken = null; 3849 } 3850 async refresh(auth2, oldToken) { 3851 const { accessToken, refreshToken, expiresIn } = await requestStsToken(auth2, oldToken); 3852 this.updateTokensAndExpiration(accessToken, refreshToken, Number(expiresIn)); 3853 } 3854 updateTokensAndExpiration(accessToken, refreshToken, expiresInSec) { 3855 this.refreshToken = refreshToken || null; 3856 this.accessToken = accessToken || null; 3857 this.expirationTime = Date.now() + expiresInSec * 1e3; 3858 } 3859 static fromJSON(appName, object) { 3860 const { refreshToken, accessToken, expirationTime } = object; 3861 const manager = new StsTokenManager(); 3862 if (refreshToken) { 3863 _assert(typeof refreshToken === "string", "internal-error", { 3864 appName 3865 }); 3866 manager.refreshToken = refreshToken; 3867 } 3868 if (accessToken) { 3869 _assert(typeof accessToken === "string", "internal-error", { 3870 appName 3871 }); 3872 manager.accessToken = accessToken; 3873 } 3874 if (expirationTime) { 3875 _assert(typeof expirationTime === "number", "internal-error", { 3876 appName 3877 }); 3878 manager.expirationTime = expirationTime; 3879 } 3880 return manager; 3881 } 3882 toJSON() { 3883 return { 3884 refreshToken: this.refreshToken, 3885 accessToken: this.accessToken, 3886 expirationTime: this.expirationTime 3887 }; 3888 } 3889 _assign(stsTokenManager) { 3890 this.accessToken = stsTokenManager.accessToken; 3891 this.refreshToken = stsTokenManager.refreshToken; 3892 this.expirationTime = stsTokenManager.expirationTime; 3893 } 3894 _clone() { 3895 return Object.assign(new StsTokenManager(), this.toJSON()); 3896 } 3897 _performRefresh() { 3898 return debugFail("not implemented"); 3899 } 3900 }; 3901 function assertStringOrUndefined(assertion, appName) { 3902 _assert(typeof assertion === "string" || typeof assertion === "undefined", "internal-error", { appName }); 3903 } 3904 var UserImpl = class { 3905 constructor(_a) { 3906 var { uid, auth: auth2, stsTokenManager } = _a, opt = __rest(_a, ["uid", "auth", "stsTokenManager"]); 3907 this.providerId = "firebase"; 3908 this.proactiveRefresh = new ProactiveRefresh(this); 3909 this.reloadUserInfo = null; 3910 this.reloadListener = null; 3911 this.uid = uid; 3912 this.auth = auth2; 3913 this.stsTokenManager = stsTokenManager; 3914 this.accessToken = stsTokenManager.accessToken; 3915 this.displayName = opt.displayName || null; 3916 this.email = opt.email || null; 3917 this.emailVerified = opt.emailVerified || false; 3918 this.phoneNumber = opt.phoneNumber || null; 3919 this.photoURL = opt.photoURL || null; 3920 this.isAnonymous = opt.isAnonymous || false; 3921 this.tenantId = opt.tenantId || null; 3922 this.providerData = opt.providerData ? [...opt.providerData] : []; 3923 this.metadata = new UserMetadata(opt.createdAt || void 0, opt.lastLoginAt || void 0); 3924 } 3925 async getIdToken(forceRefresh) { 3926 const accessToken = await _logoutIfInvalidated(this, this.stsTokenManager.getToken(this.auth, forceRefresh)); 3927 _assert(accessToken, this.auth, "internal-error"); 3928 if (this.accessToken !== accessToken) { 3929 this.accessToken = accessToken; 3930 await this.auth._persistUserIfCurrent(this); 3931 this.auth._notifyListenersIfCurrent(this); 3932 } 3933 return accessToken; 3934 } 3935 getIdTokenResult(forceRefresh) { 3936 return getIdTokenResult(this, forceRefresh); 3937 } 3938 reload() { 3939 return reload(this); 3940 } 3941 _assign(user) { 3942 if (this === user) { 3943 return; 3944 } 3945 _assert(this.uid === user.uid, this.auth, "internal-error"); 3946 this.displayName = user.displayName; 3947 this.photoURL = user.photoURL; 3948 this.email = user.email; 3949 this.emailVerified = user.emailVerified; 3950 this.phoneNumber = user.phoneNumber; 3951 this.isAnonymous = user.isAnonymous; 3952 this.tenantId = user.tenantId; 3953 this.providerData = user.providerData.map((userInfo) => Object.assign({}, userInfo)); 3954 this.metadata._copy(user.metadata); 3955 this.stsTokenManager._assign(user.stsTokenManager); 3956 } 3957 _clone(auth2) { 3958 return new UserImpl(Object.assign(Object.assign({}, this), { auth: auth2, stsTokenManager: this.stsTokenManager._clone() })); 3959 } 3960 _onReload(callback) { 3961 _assert(!this.reloadListener, this.auth, "internal-error"); 3962 this.reloadListener = callback; 3963 if (this.reloadUserInfo) { 3964 this._notifyReloadListener(this.reloadUserInfo); 3965 this.reloadUserInfo = null; 3966 } 3967 } 3968 _notifyReloadListener(userInfo) { 3969 if (this.reloadListener) { 3970 this.reloadListener(userInfo); 3971 } else { 3972 this.reloadUserInfo = userInfo; 3973 } 3974 } 3975 _startProactiveRefresh() { 3976 this.proactiveRefresh._start(); 3977 } 3978 _stopProactiveRefresh() { 3979 this.proactiveRefresh._stop(); 3980 } 3981 async _updateTokensIfNecessary(response, reload2 = false) { 3982 let tokensRefreshed = false; 3983 if (response.idToken && response.idToken !== this.stsTokenManager.accessToken) { 3984 this.stsTokenManager.updateFromServerResponse(response); 3985 tokensRefreshed = true; 3986 } 3987 if (reload2) { 3988 await _reloadWithoutSaving(this); 3989 } 3990 await this.auth._persistUserIfCurrent(this); 3991 if (tokensRefreshed) { 3992 this.auth._notifyListenersIfCurrent(this); 3993 } 3994 } 3995 async delete() { 3996 const idToken = await this.getIdToken(); 3997 await _logoutIfInvalidated(this, deleteAccount(this.auth, { idToken })); 3998 this.stsTokenManager.clearRefreshToken(); 3999 return this.auth.signOut(); 4000 } 4001 toJSON() { 4002 return Object.assign(Object.assign({ 4003 uid: this.uid, 4004 email: this.email || void 0, 4005 emailVerified: this.emailVerified, 4006 displayName: this.displayName || void 0, 4007 isAnonymous: this.isAnonymous, 4008 photoURL: this.photoURL || void 0, 4009 phoneNumber: this.phoneNumber || void 0, 4010 tenantId: this.tenantId || void 0, 4011 providerData: this.providerData.map((userInfo) => Object.assign({}, userInfo)), 4012 stsTokenManager: this.stsTokenManager.toJSON(), 4013 _redirectEventId: this._redirectEventId 4014 }, this.metadata.toJSON()), { 4015 apiKey: this.auth.config.apiKey, 4016 appName: this.auth.name 4017 }); 4018 } 4019 get refreshToken() { 4020 return this.stsTokenManager.refreshToken || ""; 4021 } 4022 static _fromJSON(auth2, object) { 4023 var _a, _b, _c, _d, _e, _f, _g, _h; 4024 const displayName = (_a = object.displayName) !== null && _a !== void 0 ? _a : void 0; 4025 const email = (_b = object.email) !== null && _b !== void 0 ? _b : void 0; 4026 const phoneNumber = (_c = object.phoneNumber) !== null && _c !== void 0 ? _c : void 0; 4027 const photoURL = (_d = object.photoURL) !== null && _d !== void 0 ? _d : void 0; 4028 const tenantId = (_e = object.tenantId) !== null && _e !== void 0 ? _e : void 0; 4029 const _redirectEventId = (_f = object._redirectEventId) !== null && _f !== void 0 ? _f : void 0; 4030 const createdAt = (_g = object.createdAt) !== null && _g !== void 0 ? _g : void 0; 4031 const lastLoginAt = (_h = object.lastLoginAt) !== null && _h !== void 0 ? _h : void 0; 4032 const { uid, emailVerified, isAnonymous, providerData, stsTokenManager: plainObjectTokenManager } = object; 4033 _assert(uid && plainObjectTokenManager, auth2, "internal-error"); 4034 const stsTokenManager = StsTokenManager.fromJSON(this.name, plainObjectTokenManager); 4035 _assert(typeof uid === "string", auth2, "internal-error"); 4036 assertStringOrUndefined(displayName, auth2.name); 4037 assertStringOrUndefined(email, auth2.name); 4038 _assert(typeof emailVerified === "boolean", auth2, "internal-error"); 4039 _assert(typeof isAnonymous === "boolean", auth2, "internal-error"); 4040 assertStringOrUndefined(phoneNumber, auth2.name); 4041 assertStringOrUndefined(photoURL, auth2.name); 4042 assertStringOrUndefined(tenantId, auth2.name); 4043 assertStringOrUndefined(_redirectEventId, auth2.name); 4044 assertStringOrUndefined(createdAt, auth2.name); 4045 assertStringOrUndefined(lastLoginAt, auth2.name); 4046 const user = new UserImpl({ 4047 uid, 4048 auth: auth2, 4049 email, 4050 emailVerified, 4051 displayName, 4052 isAnonymous, 4053 photoURL, 4054 phoneNumber, 4055 tenantId, 4056 stsTokenManager, 4057 createdAt, 4058 lastLoginAt 4059 }); 4060 if (providerData && Array.isArray(providerData)) { 4061 user.providerData = providerData.map((userInfo) => Object.assign({}, userInfo)); 4062 } 4063 if (_redirectEventId) { 4064 user._redirectEventId = _redirectEventId; 4065 } 4066 return user; 4067 } 4068 static async _fromIdTokenResponse(auth2, idTokenResponse, isAnonymous = false) { 4069 const stsTokenManager = new StsTokenManager(); 4070 stsTokenManager.updateFromServerResponse(idTokenResponse); 4071 const user = new UserImpl({ 4072 uid: idTokenResponse.localId, 4073 auth: auth2, 4074 stsTokenManager, 4075 isAnonymous 4076 }); 4077 await _reloadWithoutSaving(user); 4078 return user; 4079 } 4080 }; 4081 var InMemoryPersistence = class { 4082 constructor() { 4083 this.type = "NONE"; 4084 this.storage = {}; 4085 } 4086 async _isAvailable() { 4087 return true; 4088 } 4089 async _set(key, value) { 4090 this.storage[key] = value; 4091 } 4092 async _get(key) { 4093 const value = this.storage[key]; 4094 return value === void 0 ? null : value; 4095 } 4096 async _remove(key) { 4097 delete this.storage[key]; 4098 } 4099 _addListener(_key, _listener) { 4100 return; 4101 } 4102 _removeListener(_key, _listener) { 4103 return; 4104 } 4105 }; 4106 InMemoryPersistence.type = "NONE"; 4107 var inMemoryPersistence = InMemoryPersistence; 4108 function _persistenceKeyName(key, apiKey, appName) { 4109 return `${"firebase"}:${key}:${apiKey}:${appName}`; 4110 } 4111 var PersistenceUserManager = class { 4112 constructor(persistence, auth2, userKey) { 4113 this.persistence = persistence; 4114 this.auth = auth2; 4115 this.userKey = userKey; 4116 const { config, name: name7 } = this.auth; 4117 this.fullUserKey = _persistenceKeyName(this.userKey, config.apiKey, name7); 4118 this.fullPersistenceKey = _persistenceKeyName("persistence", config.apiKey, name7); 4119 this.boundEventHandler = auth2._onStorageEvent.bind(auth2); 4120 this.persistence._addListener(this.fullUserKey, this.boundEventHandler); 4121 } 4122 setCurrentUser(user) { 4123 return this.persistence._set(this.fullUserKey, user.toJSON()); 4124 } 4125 async getCurrentUser() { 4126 const blob = await this.persistence._get(this.fullUserKey); 4127 return blob ? UserImpl._fromJSON(this.auth, blob) : null; 4128 } 4129 removeCurrentUser() { 4130 return this.persistence._remove(this.fullUserKey); 4131 } 4132 savePersistenceForRedirect() { 4133 return this.persistence._set(this.fullPersistenceKey, this.persistence.type); 4134 } 4135 async setPersistence(newPersistence) { 4136 if (this.persistence === newPersistence) { 4137 return; 4138 } 4139 const currentUser = await this.getCurrentUser(); 4140 await this.removeCurrentUser(); 4141 this.persistence = newPersistence; 4142 if (currentUser) { 4143 return this.setCurrentUser(currentUser); 4144 } 4145 } 4146 delete() { 4147 this.persistence._removeListener(this.fullUserKey, this.boundEventHandler); 4148 } 4149 static async create(auth2, persistenceHierarchy, userKey = "authUser") { 4150 if (!persistenceHierarchy.length) { 4151 return new PersistenceUserManager(_getInstance(inMemoryPersistence), auth2, userKey); 4152 } 4153 const availablePersistences = (await Promise.all(persistenceHierarchy.map(async (persistence) => { 4154 if (await persistence._isAvailable()) { 4155 return persistence; 4156 } 4157 return void 0; 4158 }))).filter((persistence) => persistence); 4159 let selectedPersistence = availablePersistences[0] || _getInstance(inMemoryPersistence); 4160 const key = _persistenceKeyName(userKey, auth2.config.apiKey, auth2.name); 4161 let userToMigrate = null; 4162 for (const persistence of persistenceHierarchy) { 4163 try { 4164 const blob = await persistence._get(key); 4165 if (blob) { 4166 const user = UserImpl._fromJSON(auth2, blob); 4167 if (persistence !== selectedPersistence) { 4168 userToMigrate = user; 4169 } 4170 selectedPersistence = persistence; 4171 break; 4172 } 4173 } catch (_a) { 4174 } 4175 } 4176 const migrationHierarchy = availablePersistences.filter((p) => p._shouldAllowMigration); 4177 if (!selectedPersistence._shouldAllowMigration || !migrationHierarchy.length) { 4178 return new PersistenceUserManager(selectedPersistence, auth2, userKey); 4179 } 4180 selectedPersistence = migrationHierarchy[0]; 4181 if (userToMigrate) { 4182 await selectedPersistence._set(key, userToMigrate.toJSON()); 4183 } 4184 await Promise.all(persistenceHierarchy.map(async (persistence) => { 4185 if (persistence !== selectedPersistence) { 4186 try { 4187 await persistence._remove(key); 4188 } catch (_a) { 4189 } 4190 } 4191 })); 4192 return new PersistenceUserManager(selectedPersistence, auth2, userKey); 4193 } 4194 }; 4195 function _getBrowserName(userAgent) { 4196 const ua = userAgent.toLowerCase(); 4197 if (ua.includes("opera/") || ua.includes("opr/") || ua.includes("opios/")) { 4198 return "Opera"; 4199 } else if (_isIEMobile(ua)) { 4200 return "IEMobile"; 4201 } else if (ua.includes("msie") || ua.includes("trident/")) { 4202 return "IE"; 4203 } else if (ua.includes("edge/")) { 4204 return "Edge"; 4205 } else if (_isFirefox(ua)) { 4206 return "Firefox"; 4207 } else if (ua.includes("silk/")) { 4208 return "Silk"; 4209 } else if (_isBlackBerry(ua)) { 4210 return "Blackberry"; 4211 } else if (_isWebOS(ua)) { 4212 return "Webos"; 4213 } else if (_isSafari(ua)) { 4214 return "Safari"; 4215 } else if ((ua.includes("chrome/") || _isChromeIOS(ua)) && !ua.includes("edge/")) { 4216 return "Chrome"; 4217 } else if (_isAndroid(ua)) { 4218 return "Android"; 4219 } else { 4220 const re = /([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/; 4221 const matches = userAgent.match(re); 4222 if ((matches === null || matches === void 0 ? void 0 : matches.length) === 2) { 4223 return matches[1]; 4224 } 4225 } 4226 return "Other"; 4227 } 4228 function _isFirefox(ua = getUA()) { 4229 return /firefox\//i.test(ua); 4230 } 4231 function _isSafari(userAgent = getUA()) { 4232 const ua = userAgent.toLowerCase(); 4233 return ua.includes("safari/") && !ua.includes("chrome/") && !ua.includes("crios/") && !ua.includes("android"); 4234 } 4235 function _isChromeIOS(ua = getUA()) { 4236 return /crios\//i.test(ua); 4237 } 4238 function _isIEMobile(ua = getUA()) { 4239 return /iemobile/i.test(ua); 4240 } 4241 function _isAndroid(ua = getUA()) { 4242 return /android/i.test(ua); 4243 } 4244 function _isBlackBerry(ua = getUA()) { 4245 return /blackberry/i.test(ua); 4246 } 4247 function _isWebOS(ua = getUA()) { 4248 return /webos/i.test(ua); 4249 } 4250 function _isIOS(ua = getUA()) { 4251 return /iphone|ipad|ipod/i.test(ua) || /macintosh/i.test(ua) && /mobile/i.test(ua); 4252 } 4253 function _isIE10() { 4254 return isIE() && document.documentMode === 10; 4255 } 4256 function _isMobileBrowser(ua = getUA()) { 4257 return _isIOS(ua) || _isAndroid(ua) || _isWebOS(ua) || _isBlackBerry(ua) || /windows phone/i.test(ua) || _isIEMobile(ua); 4258 } 4259 function _isIframe() { 4260 try { 4261 return !!(window && window !== window.top); 4262 } catch (e) { 4263 return false; 4264 } 4265 } 4266 function _getClientVersion(clientPlatform, frameworks = []) { 4267 let reportedPlatform; 4268 switch (clientPlatform) { 4269 case "Browser": 4270 reportedPlatform = _getBrowserName(getUA()); 4271 break; 4272 case "Worker": 4273 reportedPlatform = `${_getBrowserName(getUA())}-${clientPlatform}`; 4274 break; 4275 default: 4276 reportedPlatform = clientPlatform; 4277 } 4278 const reportedFrameworks = frameworks.length ? frameworks.join(",") : "FirebaseCore-web"; 4279 return `${reportedPlatform}/${"JsCore"}/${SDK_VERSION}/${reportedFrameworks}`; 4280 } 4281 var AuthMiddlewareQueue = class { 4282 constructor(auth2) { 4283 this.auth = auth2; 4284 this.queue = []; 4285 } 4286 pushCallback(callback, onAbort) { 4287 const wrappedCallback = (user) => new Promise((resolve, reject) => { 4288 try { 4289 const result = callback(user); 4290 resolve(result); 4291 } catch (e) { 4292 reject(e); 4293 } 4294 }); 4295 wrappedCallback.onAbort = onAbort; 4296 this.queue.push(wrappedCallback); 4297 const index = this.queue.length - 1; 4298 return () => { 4299 this.queue[index] = () => Promise.resolve(); 4300 }; 4301 } 4302 async runMiddleware(nextUser) { 4303 var _a; 4304 if (this.auth.currentUser === nextUser) { 4305 return; 4306 } 4307 const onAbortStack = []; 4308 try { 4309 for (const beforeStateCallback of this.queue) { 4310 await beforeStateCallback(nextUser); 4311 if (beforeStateCallback.onAbort) { 4312 onAbortStack.push(beforeStateCallback.onAbort); 4313 } 4314 } 4315 } catch (e) { 4316 onAbortStack.reverse(); 4317 for (const onAbort of onAbortStack) { 4318 try { 4319 onAbort(); 4320 } catch (_) { 4321 } 4322 } 4323 throw this.auth._errorFactory.create("login-blocked", { 4324 originalMessage: (_a = e) === null || _a === void 0 ? void 0 : _a.message 4325 }); 4326 } 4327 } 4328 }; 4329 var AuthImpl = class { 4330 constructor(app2, heartbeatServiceProvider, config) { 4331 this.app = app2; 4332 this.heartbeatServiceProvider = heartbeatServiceProvider; 4333 this.config = config; 4334 this.currentUser = null; 4335 this.emulatorConfig = null; 4336 this.operations = Promise.resolve(); 4337 this.authStateSubscription = new Subscription(this); 4338 this.idTokenSubscription = new Subscription(this); 4339 this.beforeStateQueue = new AuthMiddlewareQueue(this); 4340 this.redirectUser = null; 4341 this.isProactiveRefreshEnabled = false; 4342 this._canInitEmulator = true; 4343 this._isInitialized = false; 4344 this._deleted = false; 4345 this._initializationPromise = null; 4346 this._popupRedirectResolver = null; 4347 this._errorFactory = _DEFAULT_AUTH_ERROR_FACTORY; 4348 this.lastNotifiedUid = void 0; 4349 this.languageCode = null; 4350 this.tenantId = null; 4351 this.settings = { appVerificationDisabledForTesting: false }; 4352 this.frameworks = []; 4353 this.name = app2.name; 4354 this.clientVersion = config.sdkClientVersion; 4355 } 4356 _initializeWithPersistence(persistenceHierarchy, popupRedirectResolver) { 4357 if (popupRedirectResolver) { 4358 this._popupRedirectResolver = _getInstance(popupRedirectResolver); 4359 } 4360 this._initializationPromise = this.queue(async () => { 4361 var _a, _b; 4362 if (this._deleted) { 4363 return; 4364 } 4365 this.persistenceManager = await PersistenceUserManager.create(this, persistenceHierarchy); 4366 if (this._deleted) { 4367 return; 4368 } 4369 if ((_a = this._popupRedirectResolver) === null || _a === void 0 ? void 0 : _a._shouldInitProactively) { 4370 try { 4371 await this._popupRedirectResolver._initialize(this); 4372 } catch (e) { 4373 } 4374 } 4375 await this.initializeCurrentUser(popupRedirectResolver); 4376 this.lastNotifiedUid = ((_b = this.currentUser) === null || _b === void 0 ? void 0 : _b.uid) || null; 4377 if (this._deleted) { 4378 return; 4379 } 4380 this._isInitialized = true; 4381 }); 4382 return this._initializationPromise; 4383 } 4384 async _onStorageEvent() { 4385 if (this._deleted) { 4386 return; 4387 } 4388 const user = await this.assertedPersistence.getCurrentUser(); 4389 if (!this.currentUser && !user) { 4390 return; 4391 } 4392 if (this.currentUser && user && this.currentUser.uid === user.uid) { 4393 this._currentUser._assign(user); 4394 await this.currentUser.getIdToken(); 4395 return; 4396 } 4397 await this._updateCurrentUser(user, true); 4398 } 4399 async initializeCurrentUser(popupRedirectResolver) { 4400 var _a; 4401 const previouslyStoredUser = await this.assertedPersistence.getCurrentUser(); 4402 let futureCurrentUser = previouslyStoredUser; 4403 let needsTocheckMiddleware = false; 4404 if (popupRedirectResolver && this.config.authDomain) { 4405 await this.getOrInitRedirectPersistenceManager(); 4406 const redirectUserEventId = (_a = this.redirectUser) === null || _a === void 0 ? void 0 : _a._redirectEventId; 4407 const storedUserEventId = futureCurrentUser === null || futureCurrentUser === void 0 ? void 0 : futureCurrentUser._redirectEventId; 4408 const result = await this.tryRedirectSignIn(popupRedirectResolver); 4409 if ((!redirectUserEventId || redirectUserEventId === storedUserEventId) && (result === null || result === void 0 ? void 0 : result.user)) { 4410 futureCurrentUser = result.user; 4411 needsTocheckMiddleware = true; 4412 } 4413 } 4414 if (!futureCurrentUser) { 4415 return this.directlySetCurrentUser(null); 4416 } 4417 if (!futureCurrentUser._redirectEventId) { 4418 if (needsTocheckMiddleware) { 4419 try { 4420 await this.beforeStateQueue.runMiddleware(futureCurrentUser); 4421 } catch (e) { 4422 futureCurrentUser = previouslyStoredUser; 4423 this._popupRedirectResolver._overrideRedirectResult(this, () => Promise.reject(e)); 4424 } 4425 } 4426 if (futureCurrentUser) { 4427 return this.reloadAndSetCurrentUserOrClear(futureCurrentUser); 4428 } else { 4429 return this.directlySetCurrentUser(null); 4430 } 4431 } 4432 _assert(this._popupRedirectResolver, this, "argument-error"); 4433 await this.getOrInitRedirectPersistenceManager(); 4434 if (this.redirectUser && this.redirectUser._redirectEventId === futureCurrentUser._redirectEventId) { 4435 return this.directlySetCurrentUser(futureCurrentUser); 4436 } 4437 return this.reloadAndSetCurrentUserOrClear(futureCurrentUser); 4438 } 4439 async tryRedirectSignIn(redirectResolver) { 4440 let result = null; 4441 try { 4442 result = await this._popupRedirectResolver._completeRedirectFn(this, redirectResolver, true); 4443 } catch (e) { 4444 await this._setRedirectUser(null); 4445 } 4446 return result; 4447 } 4448 async reloadAndSetCurrentUserOrClear(user) { 4449 var _a; 4450 try { 4451 await _reloadWithoutSaving(user); 4452 } catch (e) { 4453 if (((_a = e) === null || _a === void 0 ? void 0 : _a.code) !== `auth/${"network-request-failed"}`) { 4454 return this.directlySetCurrentUser(null); 4455 } 4456 } 4457 return this.directlySetCurrentUser(user); 4458 } 4459 useDeviceLanguage() { 4460 this.languageCode = _getUserLanguage(); 4461 } 4462 async _delete() { 4463 this._deleted = true; 4464 } 4465 async updateCurrentUser(userExtern) { 4466 const user = userExtern ? getModularInstance(userExtern) : null; 4467 if (user) { 4468 _assert(user.auth.config.apiKey === this.config.apiKey, this, "invalid-user-token"); 4469 } 4470 return this._updateCurrentUser(user && user._clone(this)); 4471 } 4472 async _updateCurrentUser(user, skipBeforeStateCallbacks = false) { 4473 if (this._deleted) { 4474 return; 4475 } 4476 if (user) { 4477 _assert(this.tenantId === user.tenantId, this, "tenant-id-mismatch"); 4478 } 4479 if (!skipBeforeStateCallbacks) { 4480 await this.beforeStateQueue.runMiddleware(user); 4481 } 4482 return this.queue(async () => { 4483 await this.directlySetCurrentUser(user); 4484 this.notifyAuthListeners(); 4485 }); 4486 } 4487 async signOut() { 4488 await this.beforeStateQueue.runMiddleware(null); 4489 if (this.redirectPersistenceManager || this._popupRedirectResolver) { 4490 await this._setRedirectUser(null); 4491 } 4492 return this._updateCurrentUser(null, true); 4493 } 4494 setPersistence(persistence) { 4495 return this.queue(async () => { 4496 await this.assertedPersistence.setPersistence(_getInstance(persistence)); 4497 }); 4498 } 4499 _getPersistence() { 4500 return this.assertedPersistence.persistence.type; 4501 } 4502 _updateErrorMap(errorMap) { 4503 this._errorFactory = new ErrorFactory("auth", "Firebase", errorMap()); 4504 } 4505 onAuthStateChanged(nextOrObserver, error2, completed) { 4506 return this.registerStateListener(this.authStateSubscription, nextOrObserver, error2, completed); 4507 } 4508 beforeAuthStateChanged(callback, onAbort) { 4509 return this.beforeStateQueue.pushCallback(callback, onAbort); 4510 } 4511 onIdTokenChanged(nextOrObserver, error2, completed) { 4512 return this.registerStateListener(this.idTokenSubscription, nextOrObserver, error2, completed); 4513 } 4514 toJSON() { 4515 var _a; 4516 return { 4517 apiKey: this.config.apiKey, 4518 authDomain: this.config.authDomain, 4519 appName: this.name, 4520 currentUser: (_a = this._currentUser) === null || _a === void 0 ? void 0 : _a.toJSON() 4521 }; 4522 } 4523 async _setRedirectUser(user, popupRedirectResolver) { 4524 const redirectManager = await this.getOrInitRedirectPersistenceManager(popupRedirectResolver); 4525 return user === null ? redirectManager.removeCurrentUser() : redirectManager.setCurrentUser(user); 4526 } 4527 async getOrInitRedirectPersistenceManager(popupRedirectResolver) { 4528 if (!this.redirectPersistenceManager) { 4529 const resolver = popupRedirectResolver && _getInstance(popupRedirectResolver) || this._popupRedirectResolver; 4530 _assert(resolver, this, "argument-error"); 4531 this.redirectPersistenceManager = await PersistenceUserManager.create(this, [_getInstance(resolver._redirectPersistence)], "redirectUser"); 4532 this.redirectUser = await this.redirectPersistenceManager.getCurrentUser(); 4533 } 4534 return this.redirectPersistenceManager; 4535 } 4536 async _redirectUserForId(id) { 4537 var _a, _b; 4538 if (this._isInitialized) { 4539 await this.queue(async () => { 4540 }); 4541 } 4542 if (((_a = this._currentUser) === null || _a === void 0 ? void 0 : _a._redirectEventId) === id) { 4543 return this._currentUser; 4544 } 4545 if (((_b = this.redirectUser) === null || _b === void 0 ? void 0 : _b._redirectEventId) === id) { 4546 return this.redirectUser; 4547 } 4548 return null; 4549 } 4550 async _persistUserIfCurrent(user) { 4551 if (user === this.currentUser) { 4552 return this.queue(async () => this.directlySetCurrentUser(user)); 4553 } 4554 } 4555 _notifyListenersIfCurrent(user) { 4556 if (user === this.currentUser) { 4557 this.notifyAuthListeners(); 4558 } 4559 } 4560 _key() { 4561 return `${this.config.authDomain}:${this.config.apiKey}:${this.name}`; 4562 } 4563 _startProactiveRefresh() { 4564 this.isProactiveRefreshEnabled = true; 4565 if (this.currentUser) { 4566 this._currentUser._startProactiveRefresh(); 4567 } 4568 } 4569 _stopProactiveRefresh() { 4570 this.isProactiveRefreshEnabled = false; 4571 if (this.currentUser) { 4572 this._currentUser._stopProactiveRefresh(); 4573 } 4574 } 4575 get _currentUser() { 4576 return this.currentUser; 4577 } 4578 notifyAuthListeners() { 4579 var _a, _b; 4580 if (!this._isInitialized) { 4581 return; 4582 } 4583 this.idTokenSubscription.next(this.currentUser); 4584 const currentUid = (_b = (_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.uid) !== null && _b !== void 0 ? _b : null; 4585 if (this.lastNotifiedUid !== currentUid) { 4586 this.lastNotifiedUid = currentUid; 4587 this.authStateSubscription.next(this.currentUser); 4588 } 4589 } 4590 registerStateListener(subscription, nextOrObserver, error2, completed) { 4591 if (this._deleted) { 4592 return () => { 4593 }; 4594 } 4595 const cb = typeof nextOrObserver === "function" ? nextOrObserver : nextOrObserver.next.bind(nextOrObserver); 4596 const promise = this._isInitialized ? Promise.resolve() : this._initializationPromise; 4597 _assert(promise, this, "internal-error"); 4598 promise.then(() => cb(this.currentUser)); 4599 if (typeof nextOrObserver === "function") { 4600 return subscription.addObserver(nextOrObserver, error2, completed); 4601 } else { 4602 return subscription.addObserver(nextOrObserver); 4603 } 4604 } 4605 async directlySetCurrentUser(user) { 4606 if (this.currentUser && this.currentUser !== user) { 4607 this._currentUser._stopProactiveRefresh(); 4608 } 4609 if (user && this.isProactiveRefreshEnabled) { 4610 user._startProactiveRefresh(); 4611 } 4612 this.currentUser = user; 4613 if (user) { 4614 await this.assertedPersistence.setCurrentUser(user); 4615 } else { 4616 await this.assertedPersistence.removeCurrentUser(); 4617 } 4618 } 4619 queue(action) { 4620 this.operations = this.operations.then(action, action); 4621 return this.operations; 4622 } 4623 get assertedPersistence() { 4624 _assert(this.persistenceManager, this, "internal-error"); 4625 return this.persistenceManager; 4626 } 4627 _logFramework(framework) { 4628 if (!framework || this.frameworks.includes(framework)) { 4629 return; 4630 } 4631 this.frameworks.push(framework); 4632 this.frameworks.sort(); 4633 this.clientVersion = _getClientVersion(this.config.clientPlatform, this._getFrameworks()); 4634 } 4635 _getFrameworks() { 4636 return this.frameworks; 4637 } 4638 async _getAdditionalHeaders() { 4639 var _a; 4640 const headers = { 4641 ["X-Client-Version"]: this.clientVersion 4642 }; 4643 if (this.app.options.appId) { 4644 headers["X-Firebase-gmpid"] = this.app.options.appId; 4645 } 4646 const heartbeatsHeader = await ((_a = this.heartbeatServiceProvider.getImmediate({ 4647 optional: true 4648 })) === null || _a === void 0 ? void 0 : _a.getHeartbeatsHeader()); 4649 if (heartbeatsHeader) { 4650 headers["X-Firebase-Client"] = heartbeatsHeader; 4651 } 4652 return headers; 4653 } 4654 }; 4655 function _castAuth(auth2) { 4656 return getModularInstance(auth2); 4657 } 4658 var Subscription = class { 4659 constructor(auth2) { 4660 this.auth = auth2; 4661 this.observer = null; 4662 this.addObserver = createSubscribe((observer) => this.observer = observer); 4663 } 4664 get next() { 4665 _assert(this.observer, this.auth, "internal-error"); 4666 return this.observer.next.bind(this.observer); 4667 } 4668 }; 4669 var AuthCredential = class { 4670 constructor(providerId, signInMethod) { 4671 this.providerId = providerId; 4672 this.signInMethod = signInMethod; 4673 } 4674 toJSON() { 4675 return debugFail("not implemented"); 4676 } 4677 _getIdTokenResponse(_auth) { 4678 return debugFail("not implemented"); 4679 } 4680 _linkToIdToken(_auth, _idToken) { 4681 return debugFail("not implemented"); 4682 } 4683 _getReauthenticationResolver(_auth) { 4684 return debugFail("not implemented"); 4685 } 4686 }; 4687 async function updateEmailPassword(auth2, request) { 4688 return _performApiRequest(auth2, "POST", "/v1/accounts:update", request); 4689 } 4690 async function signInWithPassword(auth2, request) { 4691 return _performSignInRequest(auth2, "POST", "/v1/accounts:signInWithPassword", _addTidIfNecessary(auth2, request)); 4692 } 4693 async function signInWithEmailLink$1(auth2, request) { 4694 return _performSignInRequest(auth2, "POST", "/v1/accounts:signInWithEmailLink", _addTidIfNecessary(auth2, request)); 4695 } 4696 async function signInWithEmailLinkForLinking(auth2, request) { 4697 return _performSignInRequest(auth2, "POST", "/v1/accounts:signInWithEmailLink", _addTidIfNecessary(auth2, request)); 4698 } 4699 var EmailAuthCredential = class extends AuthCredential { 4700 constructor(_email, _password, signInMethod, _tenantId = null) { 4701 super("password", signInMethod); 4702 this._email = _email; 4703 this._password = _password; 4704 this._tenantId = _tenantId; 4705 } 4706 static _fromEmailAndPassword(email, password) { 4707 return new EmailAuthCredential(email, password, "password"); 4708 } 4709 static _fromEmailAndCode(email, oobCode, tenantId = null) { 4710 return new EmailAuthCredential(email, oobCode, "emailLink", tenantId); 4711 } 4712 toJSON() { 4713 return { 4714 email: this._email, 4715 password: this._password, 4716 signInMethod: this.signInMethod, 4717 tenantId: this._tenantId 4718 }; 4719 } 4720 static fromJSON(json) { 4721 const obj = typeof json === "string" ? JSON.parse(json) : json; 4722 if ((obj === null || obj === void 0 ? void 0 : obj.email) && (obj === null || obj === void 0 ? void 0 : obj.password)) { 4723 if (obj.signInMethod === "password") { 4724 return this._fromEmailAndPassword(obj.email, obj.password); 4725 } else if (obj.signInMethod === "emailLink") { 4726 return this._fromEmailAndCode(obj.email, obj.password, obj.tenantId); 4727 } 4728 } 4729 return null; 4730 } 4731 async _getIdTokenResponse(auth2) { 4732 switch (this.signInMethod) { 4733 case "password": 4734 return signInWithPassword(auth2, { 4735 returnSecureToken: true, 4736 email: this._email, 4737 password: this._password 4738 }); 4739 case "emailLink": 4740 return signInWithEmailLink$1(auth2, { 4741 email: this._email, 4742 oobCode: this._password 4743 }); 4744 default: 4745 _fail(auth2, "internal-error"); 4746 } 4747 } 4748 async _linkToIdToken(auth2, idToken) { 4749 switch (this.signInMethod) { 4750 case "password": 4751 return updateEmailPassword(auth2, { 4752 idToken, 4753 returnSecureToken: true, 4754 email: this._email, 4755 password: this._password 4756 }); 4757 case "emailLink": 4758 return signInWithEmailLinkForLinking(auth2, { 4759 idToken, 4760 email: this._email, 4761 oobCode: this._password 4762 }); 4763 default: 4764 _fail(auth2, "internal-error"); 4765 } 4766 } 4767 _getReauthenticationResolver(auth2) { 4768 return this._getIdTokenResponse(auth2); 4769 } 4770 }; 4771 async function signInWithIdp(auth2, request) { 4772 return _performSignInRequest(auth2, "POST", "/v1/accounts:signInWithIdp", _addTidIfNecessary(auth2, request)); 4773 } 4774 var IDP_REQUEST_URI$1 = "http://localhost"; 4775 var OAuthCredential = class extends AuthCredential { 4776 constructor() { 4777 super(...arguments); 4778 this.pendingToken = null; 4779 } 4780 static _fromParams(params) { 4781 const cred = new OAuthCredential(params.providerId, params.signInMethod); 4782 if (params.idToken || params.accessToken) { 4783 if (params.idToken) { 4784 cred.idToken = params.idToken; 4785 } 4786 if (params.accessToken) { 4787 cred.accessToken = params.accessToken; 4788 } 4789 if (params.nonce && !params.pendingToken) { 4790 cred.nonce = params.nonce; 4791 } 4792 if (params.pendingToken) { 4793 cred.pendingToken = params.pendingToken; 4794 } 4795 } else if (params.oauthToken && params.oauthTokenSecret) { 4796 cred.accessToken = params.oauthToken; 4797 cred.secret = params.oauthTokenSecret; 4798 } else { 4799 _fail("argument-error"); 4800 } 4801 return cred; 4802 } 4803 toJSON() { 4804 return { 4805 idToken: this.idToken, 4806 accessToken: this.accessToken, 4807 secret: this.secret, 4808 nonce: this.nonce, 4809 pendingToken: this.pendingToken, 4810 providerId: this.providerId, 4811 signInMethod: this.signInMethod 4812 }; 4813 } 4814 static fromJSON(json) { 4815 const obj = typeof json === "string" ? JSON.parse(json) : json; 4816 const { providerId, signInMethod } = obj, rest = __rest(obj, ["providerId", "signInMethod"]); 4817 if (!providerId || !signInMethod) { 4818 return null; 4819 } 4820 const cred = new OAuthCredential(providerId, signInMethod); 4821 cred.idToken = rest.idToken || void 0; 4822 cred.accessToken = rest.accessToken || void 0; 4823 cred.secret = rest.secret; 4824 cred.nonce = rest.nonce; 4825 cred.pendingToken = rest.pendingToken || null; 4826 return cred; 4827 } 4828 _getIdTokenResponse(auth2) { 4829 const request = this.buildRequest(); 4830 return signInWithIdp(auth2, request); 4831 } 4832 _linkToIdToken(auth2, idToken) { 4833 const request = this.buildRequest(); 4834 request.idToken = idToken; 4835 return signInWithIdp(auth2, request); 4836 } 4837 _getReauthenticationResolver(auth2) { 4838 const request = this.buildRequest(); 4839 request.autoCreate = false; 4840 return signInWithIdp(auth2, request); 4841 } 4842 buildRequest() { 4843 const request = { 4844 requestUri: IDP_REQUEST_URI$1, 4845 returnSecureToken: true 4846 }; 4847 if (this.pendingToken) { 4848 request.pendingToken = this.pendingToken; 4849 } else { 4850 const postBody = {}; 4851 if (this.idToken) { 4852 postBody["id_token"] = this.idToken; 4853 } 4854 if (this.accessToken) { 4855 postBody["access_token"] = this.accessToken; 4856 } 4857 if (this.secret) { 4858 postBody["oauth_token_secret"] = this.secret; 4859 } 4860 postBody["providerId"] = this.providerId; 4861 if (this.nonce && !this.pendingToken) { 4862 postBody["nonce"] = this.nonce; 4863 } 4864 request.postBody = querystring(postBody); 4865 } 4866 return request; 4867 } 4868 }; 4869 async function sendPhoneVerificationCode(auth2, request) { 4870 return _performApiRequest(auth2, "POST", "/v1/accounts:sendVerificationCode", _addTidIfNecessary(auth2, request)); 4871 } 4872 async function signInWithPhoneNumber$1(auth2, request) { 4873 return _performSignInRequest(auth2, "POST", "/v1/accounts:signInWithPhoneNumber", _addTidIfNecessary(auth2, request)); 4874 } 4875 async function linkWithPhoneNumber$1(auth2, request) { 4876 const response = await _performSignInRequest(auth2, "POST", "/v1/accounts:signInWithPhoneNumber", _addTidIfNecessary(auth2, request)); 4877 if (response.temporaryProof) { 4878 throw _makeTaggedError(auth2, "account-exists-with-different-credential", response); 4879 } 4880 return response; 4881 } 4882 var VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_ = { 4883 ["USER_NOT_FOUND"]: "user-not-found" 4884 }; 4885 async function verifyPhoneNumberForExisting(auth2, request) { 4886 const apiRequest = Object.assign(Object.assign({}, request), { operation: "REAUTH" }); 4887 return _performSignInRequest(auth2, "POST", "/v1/accounts:signInWithPhoneNumber", _addTidIfNecessary(auth2, apiRequest), VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_); 4888 } 4889 var PhoneAuthCredential = class extends AuthCredential { 4890 constructor(params) { 4891 super("phone", "phone"); 4892 this.params = params; 4893 } 4894 static _fromVerification(verificationId, verificationCode) { 4895 return new PhoneAuthCredential({ verificationId, verificationCode }); 4896 } 4897 static _fromTokenResponse(phoneNumber, temporaryProof) { 4898 return new PhoneAuthCredential({ phoneNumber, temporaryProof }); 4899 } 4900 _getIdTokenResponse(auth2) { 4901 return signInWithPhoneNumber$1(auth2, this._makeVerificationRequest()); 4902 } 4903 _linkToIdToken(auth2, idToken) { 4904 return linkWithPhoneNumber$1(auth2, Object.assign({ idToken }, this._makeVerificationRequest())); 4905 } 4906 _getReauthenticationResolver(auth2) { 4907 return verifyPhoneNumberForExisting(auth2, this._makeVerificationRequest()); 4908 } 4909 _makeVerificationRequest() { 4910 const { temporaryProof, phoneNumber, verificationId, verificationCode } = this.params; 4911 if (temporaryProof && phoneNumber) { 4912 return { temporaryProof, phoneNumber }; 4913 } 4914 return { 4915 sessionInfo: verificationId, 4916 code: verificationCode 4917 }; 4918 } 4919 toJSON() { 4920 const obj = { 4921 providerId: this.providerId 4922 }; 4923 if (this.params.phoneNumber) { 4924 obj.phoneNumber = this.params.phoneNumber; 4925 } 4926 if (this.params.temporaryProof) { 4927 obj.temporaryProof = this.params.temporaryProof; 4928 } 4929 if (this.params.verificationCode) { 4930 obj.verificationCode = this.params.verificationCode; 4931 } 4932 if (this.params.verificationId) { 4933 obj.verificationId = this.params.verificationId; 4934 } 4935 return obj; 4936 } 4937 static fromJSON(json) { 4938 if (typeof json === "string") { 4939 json = JSON.parse(json); 4940 } 4941 const { verificationId, verificationCode, phoneNumber, temporaryProof } = json; 4942 if (!verificationCode && !verificationId && !phoneNumber && !temporaryProof) { 4943 return null; 4944 } 4945 return new PhoneAuthCredential({ 4946 verificationId, 4947 verificationCode, 4948 phoneNumber, 4949 temporaryProof 4950 }); 4951 } 4952 }; 4953 function parseMode(mode) { 4954 switch (mode) { 4955 case "recoverEmail": 4956 return "RECOVER_EMAIL"; 4957 case "resetPassword": 4958 return "PASSWORD_RESET"; 4959 case "signIn": 4960 return "EMAIL_SIGNIN"; 4961 case "verifyEmail": 4962 return "VERIFY_EMAIL"; 4963 case "verifyAndChangeEmail": 4964 return "VERIFY_AND_CHANGE_EMAIL"; 4965 case "revertSecondFactorAddition": 4966 return "REVERT_SECOND_FACTOR_ADDITION"; 4967 default: 4968 return null; 4969 } 4970 } 4971 function parseDeepLink(url) { 4972 const link = querystringDecode(extractQuerystring(url))["link"]; 4973 const doubleDeepLink = link ? querystringDecode(extractQuerystring(link))["deep_link_id"] : null; 4974 const iOSDeepLink = querystringDecode(extractQuerystring(url))["deep_link_id"]; 4975 const iOSDoubleDeepLink = iOSDeepLink ? querystringDecode(extractQuerystring(iOSDeepLink))["link"] : null; 4976 return iOSDoubleDeepLink || iOSDeepLink || doubleDeepLink || link || url; 4977 } 4978 var ActionCodeURL = class { 4979 constructor(actionLink) { 4980 var _a, _b, _c, _d, _e, _f; 4981 const searchParams = querystringDecode(extractQuerystring(actionLink)); 4982 const apiKey = (_a = searchParams["apiKey"]) !== null && _a !== void 0 ? _a : null; 4983 const code = (_b = searchParams["oobCode"]) !== null && _b !== void 0 ? _b : null; 4984 const operation = parseMode((_c = searchParams["mode"]) !== null && _c !== void 0 ? _c : null); 4985 _assert(apiKey && code && operation, "argument-error"); 4986 this.apiKey = apiKey; 4987 this.operation = operation; 4988 this.code = code; 4989 this.continueUrl = (_d = searchParams["continueUrl"]) !== null && _d !== void 0 ? _d : null; 4990 this.languageCode = (_e = searchParams["languageCode"]) !== null && _e !== void 0 ? _e : null; 4991 this.tenantId = (_f = searchParams["tenantId"]) !== null && _f !== void 0 ? _f : null; 4992 } 4993 static parseLink(link) { 4994 const actionLink = parseDeepLink(link); 4995 try { 4996 return new ActionCodeURL(actionLink); 4997 } catch (_a) { 4998 return null; 4999 } 5000 } 5001 }; 5002 var EmailAuthProvider = class { 5003 constructor() { 5004 this.providerId = EmailAuthProvider.PROVIDER_ID; 5005 } 5006 static credential(email, password) { 5007 return EmailAuthCredential._fromEmailAndPassword(email, password); 5008 } 5009 static credentialWithLink(email, emailLink) { 5010 const actionCodeUrl = ActionCodeURL.parseLink(emailLink); 5011 _assert(actionCodeUrl, "argument-error"); 5012 return EmailAuthCredential._fromEmailAndCode(email, actionCodeUrl.code, actionCodeUrl.tenantId); 5013 } 5014 }; 5015 EmailAuthProvider.PROVIDER_ID = "password"; 5016 EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD = "password"; 5017 EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD = "emailLink"; 5018 var FederatedAuthProvider = class { 5019 constructor(providerId) { 5020 this.providerId = providerId; 5021 this.defaultLanguageCode = null; 5022 this.customParameters = {}; 5023 } 5024 setDefaultLanguage(languageCode) { 5025 this.defaultLanguageCode = languageCode; 5026 } 5027 setCustomParameters(customOAuthParameters) { 5028 this.customParameters = customOAuthParameters; 5029 return this; 5030 } 5031 getCustomParameters() { 5032 return this.customParameters; 5033 } 5034 }; 5035 var BaseOAuthProvider = class extends FederatedAuthProvider { 5036 constructor() { 5037 super(...arguments); 5038 this.scopes = []; 5039 } 5040 addScope(scope) { 5041 if (!this.scopes.includes(scope)) { 5042 this.scopes.push(scope); 5043 } 5044 return this; 5045 } 5046 getScopes() { 5047 return [...this.scopes]; 5048 } 5049 }; 5050 var FacebookAuthProvider = class extends BaseOAuthProvider { 5051 constructor() { 5052 super("facebook.com"); 5053 } 5054 static credential(accessToken) { 5055 return OAuthCredential._fromParams({ 5056 providerId: FacebookAuthProvider.PROVIDER_ID, 5057 signInMethod: FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD, 5058 accessToken 5059 }); 5060 } 5061 static credentialFromResult(userCredential) { 5062 return FacebookAuthProvider.credentialFromTaggedObject(userCredential); 5063 } 5064 static credentialFromError(error2) { 5065 return FacebookAuthProvider.credentialFromTaggedObject(error2.customData || {}); 5066 } 5067 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) { 5068 if (!tokenResponse || !("oauthAccessToken" in tokenResponse)) { 5069 return null; 5070 } 5071 if (!tokenResponse.oauthAccessToken) { 5072 return null; 5073 } 5074 try { 5075 return FacebookAuthProvider.credential(tokenResponse.oauthAccessToken); 5076 } catch (_a) { 5077 return null; 5078 } 5079 } 5080 }; 5081 FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD = "facebook.com"; 5082 FacebookAuthProvider.PROVIDER_ID = "facebook.com"; 5083 var GoogleAuthProvider = class extends BaseOAuthProvider { 5084 constructor() { 5085 super("google.com"); 5086 this.addScope("profile"); 5087 } 5088 static credential(idToken, accessToken) { 5089 return OAuthCredential._fromParams({ 5090 providerId: GoogleAuthProvider.PROVIDER_ID, 5091 signInMethod: GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD, 5092 idToken, 5093 accessToken 5094 }); 5095 } 5096 static credentialFromResult(userCredential) { 5097 return GoogleAuthProvider.credentialFromTaggedObject(userCredential); 5098 } 5099 static credentialFromError(error2) { 5100 return GoogleAuthProvider.credentialFromTaggedObject(error2.customData || {}); 5101 } 5102 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) { 5103 if (!tokenResponse) { 5104 return null; 5105 } 5106 const { oauthIdToken, oauthAccessToken } = tokenResponse; 5107 if (!oauthIdToken && !oauthAccessToken) { 5108 return null; 5109 } 5110 try { 5111 return GoogleAuthProvider.credential(oauthIdToken, oauthAccessToken); 5112 } catch (_a) { 5113 return null; 5114 } 5115 } 5116 }; 5117 GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD = "google.com"; 5118 GoogleAuthProvider.PROVIDER_ID = "google.com"; 5119 var GithubAuthProvider = class extends BaseOAuthProvider { 5120 constructor() { 5121 super("github.com"); 5122 } 5123 static credential(accessToken) { 5124 return OAuthCredential._fromParams({ 5125 providerId: GithubAuthProvider.PROVIDER_ID, 5126 signInMethod: GithubAuthProvider.GITHUB_SIGN_IN_METHOD, 5127 accessToken 5128 }); 5129 } 5130 static credentialFromResult(userCredential) { 5131 return GithubAuthProvider.credentialFromTaggedObject(userCredential); 5132 } 5133 static credentialFromError(error2) { 5134 return GithubAuthProvider.credentialFromTaggedObject(error2.customData || {}); 5135 } 5136 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) { 5137 if (!tokenResponse || !("oauthAccessToken" in tokenResponse)) { 5138 return null; 5139 } 5140 if (!tokenResponse.oauthAccessToken) { 5141 return null; 5142 } 5143 try { 5144 return GithubAuthProvider.credential(tokenResponse.oauthAccessToken); 5145 } catch (_a) { 5146 return null; 5147 } 5148 } 5149 }; 5150 GithubAuthProvider.GITHUB_SIGN_IN_METHOD = "github.com"; 5151 GithubAuthProvider.PROVIDER_ID = "github.com"; 5152 var TwitterAuthProvider = class extends BaseOAuthProvider { 5153 constructor() { 5154 super("twitter.com"); 5155 } 5156 static credential(token, secret) { 5157 return OAuthCredential._fromParams({ 5158 providerId: TwitterAuthProvider.PROVIDER_ID, 5159 signInMethod: TwitterAuthProvider.TWITTER_SIGN_IN_METHOD, 5160 oauthToken: token, 5161 oauthTokenSecret: secret 5162 }); 5163 } 5164 static credentialFromResult(userCredential) { 5165 return TwitterAuthProvider.credentialFromTaggedObject(userCredential); 5166 } 5167 static credentialFromError(error2) { 5168 return TwitterAuthProvider.credentialFromTaggedObject(error2.customData || {}); 5169 } 5170 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) { 5171 if (!tokenResponse) { 5172 return null; 5173 } 5174 const { oauthAccessToken, oauthTokenSecret } = tokenResponse; 5175 if (!oauthAccessToken || !oauthTokenSecret) { 5176 return null; 5177 } 5178 try { 5179 return TwitterAuthProvider.credential(oauthAccessToken, oauthTokenSecret); 5180 } catch (_a) { 5181 return null; 5182 } 5183 } 5184 }; 5185 TwitterAuthProvider.TWITTER_SIGN_IN_METHOD = "twitter.com"; 5186 TwitterAuthProvider.PROVIDER_ID = "twitter.com"; 5187 var UserCredentialImpl = class { 5188 constructor(params) { 5189 this.user = params.user; 5190 this.providerId = params.providerId; 5191 this._tokenResponse = params._tokenResponse; 5192 this.operationType = params.operationType; 5193 } 5194 static async _fromIdTokenResponse(auth2, operationType, idTokenResponse, isAnonymous = false) { 5195 const user = await UserImpl._fromIdTokenResponse(auth2, idTokenResponse, isAnonymous); 5196 const providerId = providerIdForResponse(idTokenResponse); 5197 const userCred = new UserCredentialImpl({ 5198 user, 5199 providerId, 5200 _tokenResponse: idTokenResponse, 5201 operationType 5202 }); 5203 return userCred; 5204 } 5205 static async _forOperation(user, operationType, response) { 5206 await user._updateTokensIfNecessary(response, true); 5207 const providerId = providerIdForResponse(response); 5208 return new UserCredentialImpl({ 5209 user, 5210 providerId, 5211 _tokenResponse: response, 5212 operationType 5213 }); 5214 } 5215 }; 5216 function providerIdForResponse(response) { 5217 if (response.providerId) { 5218 return response.providerId; 5219 } 5220 if ("phoneNumber" in response) { 5221 return "phone"; 5222 } 5223 return null; 5224 } 5225 var MultiFactorError = class extends FirebaseError { 5226 constructor(auth2, error2, operationType, user) { 5227 var _a; 5228 super(error2.code, error2.message); 5229 this.operationType = operationType; 5230 this.user = user; 5231 Object.setPrototypeOf(this, MultiFactorError.prototype); 5232 this.customData = { 5233 appName: auth2.name, 5234 tenantId: (_a = auth2.tenantId) !== null && _a !== void 0 ? _a : void 0, 5235 _serverResponse: error2.customData._serverResponse, 5236 operationType 5237 }; 5238 } 5239 static _fromErrorAndOperation(auth2, error2, operationType, user) { 5240 return new MultiFactorError(auth2, error2, operationType, user); 5241 } 5242 }; 5243 function _processCredentialSavingMfaContextIfNecessary(auth2, operationType, credential, user) { 5244 const idTokenProvider = operationType === "reauthenticate" ? credential._getReauthenticationResolver(auth2) : credential._getIdTokenResponse(auth2); 5245 return idTokenProvider.catch((error2) => { 5246 if (error2.code === `auth/${"multi-factor-auth-required"}`) { 5247 throw MultiFactorError._fromErrorAndOperation(auth2, error2, operationType, user); 5248 } 5249 throw error2; 5250 }); 5251 } 5252 async function _link$1(user, credential, bypassAuthState = false) { 5253 const response = await _logoutIfInvalidated(user, credential._linkToIdToken(user.auth, await user.getIdToken()), bypassAuthState); 5254 return UserCredentialImpl._forOperation(user, "link", response); 5255 } 5256 async function _reauthenticate(user, credential, bypassAuthState = false) { 5257 var _a; 5258 const { auth: auth2 } = user; 5259 const operationType = "reauthenticate"; 5260 try { 5261 const response = await _logoutIfInvalidated(user, _processCredentialSavingMfaContextIfNecessary(auth2, operationType, credential, user), bypassAuthState); 5262 _assert(response.idToken, auth2, "internal-error"); 5263 const parsed = _parseToken(response.idToken); 5264 _assert(parsed, auth2, "internal-error"); 5265 const { sub: localId } = parsed; 5266 _assert(user.uid === localId, auth2, "user-mismatch"); 5267 return UserCredentialImpl._forOperation(user, operationType, response); 5268 } catch (e) { 5269 if (((_a = e) === null || _a === void 0 ? void 0 : _a.code) === `auth/${"user-not-found"}`) { 5270 _fail(auth2, "user-mismatch"); 5271 } 5272 throw e; 5273 } 5274 } 5275 async function _signInWithCredential(auth2, credential, bypassAuthState = false) { 5276 const operationType = "signIn"; 5277 const response = await _processCredentialSavingMfaContextIfNecessary(auth2, operationType, credential); 5278 const userCredential = await UserCredentialImpl._fromIdTokenResponse(auth2, operationType, response); 5279 if (!bypassAuthState) { 5280 await auth2._updateCurrentUser(userCredential.user); 5281 } 5282 return userCredential; 5283 } 5284 function onAuthStateChanged(auth2, nextOrObserver, error2, completed) { 5285 return getModularInstance(auth2).onAuthStateChanged(nextOrObserver, error2, completed); 5286 } 5287 function startEnrollPhoneMfa(auth2, request) { 5288 return _performApiRequest(auth2, "POST", "/v2/accounts/mfaEnrollment:start", _addTidIfNecessary(auth2, request)); 5289 } 5290 function finalizeEnrollPhoneMfa(auth2, request) { 5291 return _performApiRequest(auth2, "POST", "/v2/accounts/mfaEnrollment:finalize", _addTidIfNecessary(auth2, request)); 5292 } 5293 var STORAGE_AVAILABLE_KEY = "__sak"; 5294 var BrowserPersistenceClass = class { 5295 constructor(storageRetriever, type) { 5296 this.storageRetriever = storageRetriever; 5297 this.type = type; 5298 } 5299 _isAvailable() { 5300 try { 5301 if (!this.storage) { 5302 return Promise.resolve(false); 5303 } 5304 this.storage.setItem(STORAGE_AVAILABLE_KEY, "1"); 5305 this.storage.removeItem(STORAGE_AVAILABLE_KEY); 5306 return Promise.resolve(true); 5307 } catch (_a) { 5308 return Promise.resolve(false); 5309 } 5310 } 5311 _set(key, value) { 5312 this.storage.setItem(key, JSON.stringify(value)); 5313 return Promise.resolve(); 5314 } 5315 _get(key) { 5316 const json = this.storage.getItem(key); 5317 return Promise.resolve(json ? JSON.parse(json) : null); 5318 } 5319 _remove(key) { 5320 this.storage.removeItem(key); 5321 return Promise.resolve(); 5322 } 5323 get storage() { 5324 return this.storageRetriever(); 5325 } 5326 }; 5327 function _iframeCannotSyncWebStorage() { 5328 const ua = getUA(); 5329 return _isSafari(ua) || _isIOS(ua); 5330 } 5331 var _POLLING_INTERVAL_MS$1 = 1e3; 5332 var IE10_LOCAL_STORAGE_SYNC_DELAY = 10; 5333 var BrowserLocalPersistence = class extends BrowserPersistenceClass { 5334 constructor() { 5335 super(() => window.localStorage, "LOCAL"); 5336 this.boundEventHandler = (event, poll) => this.onStorageEvent(event, poll); 5337 this.listeners = {}; 5338 this.localCache = {}; 5339 this.pollTimer = null; 5340 this.safariLocalStorageNotSynced = _iframeCannotSyncWebStorage() && _isIframe(); 5341 this.fallbackToPolling = _isMobileBrowser(); 5342 this._shouldAllowMigration = true; 5343 } 5344 forAllChangedKeys(cb) { 5345 for (const key of Object.keys(this.listeners)) { 5346 const newValue = this.storage.getItem(key); 5347 const oldValue = this.localCache[key]; 5348 if (newValue !== oldValue) { 5349 cb(key, oldValue, newValue); 5350 } 5351 } 5352 } 5353 onStorageEvent(event, poll = false) { 5354 if (!event.key) { 5355 this.forAllChangedKeys((key2, _oldValue, newValue) => { 5356 this.notifyListeners(key2, newValue); 5357 }); 5358 return; 5359 } 5360 const key = event.key; 5361 if (poll) { 5362 this.detachListener(); 5363 } else { 5364 this.stopPolling(); 5365 } 5366 if (this.safariLocalStorageNotSynced) { 5367 const storedValue2 = this.storage.getItem(key); 5368 if (event.newValue !== storedValue2) { 5369 if (event.newValue !== null) { 5370 this.storage.setItem(key, event.newValue); 5371 } else { 5372 this.storage.removeItem(key); 5373 } 5374 } else if (this.localCache[key] === event.newValue && !poll) { 5375 return; 5376 } 5377 } 5378 const triggerListeners = () => { 5379 const storedValue2 = this.storage.getItem(key); 5380 if (!poll && this.localCache[key] === storedValue2) { 5381 return; 5382 } 5383 this.notifyListeners(key, storedValue2); 5384 }; 5385 const storedValue = this.storage.getItem(key); 5386 if (_isIE10() && storedValue !== event.newValue && event.newValue !== event.oldValue) { 5387 setTimeout(triggerListeners, IE10_LOCAL_STORAGE_SYNC_DELAY); 5388 } else { 5389 triggerListeners(); 5390 } 5391 } 5392 notifyListeners(key, value) { 5393 this.localCache[key] = value; 5394 const listeners = this.listeners[key]; 5395 if (listeners) { 5396 for (const listener of Array.from(listeners)) { 5397 listener(value ? JSON.parse(value) : value); 5398 } 5399 } 5400 } 5401 startPolling() { 5402 this.stopPolling(); 5403 this.pollTimer = setInterval(() => { 5404 this.forAllChangedKeys((key, oldValue, newValue) => { 5405 this.onStorageEvent(new StorageEvent("storage", { 5406 key, 5407 oldValue, 5408 newValue 5409 }), true); 5410 }); 5411 }, _POLLING_INTERVAL_MS$1); 5412 } 5413 stopPolling() { 5414 if (this.pollTimer) { 5415 clearInterval(this.pollTimer); 5416 this.pollTimer = null; 5417 } 5418 } 5419 attachListener() { 5420 window.addEventListener("storage", this.boundEventHandler); 5421 } 5422 detachListener() { 5423 window.removeEventListener("storage", this.boundEventHandler); 5424 } 5425 _addListener(key, listener) { 5426 if (Object.keys(this.listeners).length === 0) { 5427 if (this.fallbackToPolling) { 5428 this.startPolling(); 5429 } else { 5430 this.attachListener(); 5431 } 5432 } 5433 if (!this.listeners[key]) { 5434 this.listeners[key] = /* @__PURE__ */ new Set(); 5435 this.localCache[key] = this.storage.getItem(key); 5436 } 5437 this.listeners[key].add(listener); 5438 } 5439 _removeListener(key, listener) { 5440 if (this.listeners[key]) { 5441 this.listeners[key].delete(listener); 5442 if (this.listeners[key].size === 0) { 5443 delete this.listeners[key]; 5444 } 5445 } 5446 if (Object.keys(this.listeners).length === 0) { 5447 this.detachListener(); 5448 this.stopPolling(); 5449 } 5450 } 5451 async _set(key, value) { 5452 await super._set(key, value); 5453 this.localCache[key] = JSON.stringify(value); 5454 } 5455 async _get(key) { 5456 const value = await super._get(key); 5457 this.localCache[key] = JSON.stringify(value); 5458 return value; 5459 } 5460 async _remove(key) { 5461 await super._remove(key); 5462 delete this.localCache[key]; 5463 } 5464 }; 5465 BrowserLocalPersistence.type = "LOCAL"; 5466 var browserLocalPersistence = BrowserLocalPersistence; 5467 var BrowserSessionPersistence = class extends BrowserPersistenceClass { 5468 constructor() { 5469 super(() => window.sessionStorage, "SESSION"); 5470 } 5471 _addListener(_key, _listener) { 5472 return; 5473 } 5474 _removeListener(_key, _listener) { 5475 return; 5476 } 5477 }; 5478 BrowserSessionPersistence.type = "SESSION"; 5479 var browserSessionPersistence = BrowserSessionPersistence; 5480 function _allSettled(promises) { 5481 return Promise.all(promises.map(async (promise) => { 5482 try { 5483 const value = await promise; 5484 return { 5485 fulfilled: true, 5486 value 5487 }; 5488 } catch (reason) { 5489 return { 5490 fulfilled: false, 5491 reason 5492 }; 5493 } 5494 })); 5495 } 5496 var Receiver = class { 5497 constructor(eventTarget) { 5498 this.eventTarget = eventTarget; 5499 this.handlersMap = {}; 5500 this.boundEventHandler = this.handleEvent.bind(this); 5501 } 5502 static _getInstance(eventTarget) { 5503 const existingInstance = this.receivers.find((receiver) => receiver.isListeningto(eventTarget)); 5504 if (existingInstance) { 5505 return existingInstance; 5506 } 5507 const newInstance = new Receiver(eventTarget); 5508 this.receivers.push(newInstance); 5509 return newInstance; 5510 } 5511 isListeningto(eventTarget) { 5512 return this.eventTarget === eventTarget; 5513 } 5514 async handleEvent(event) { 5515 const messageEvent = event; 5516 const { eventId, eventType, data } = messageEvent.data; 5517 const handlers = this.handlersMap[eventType]; 5518 if (!(handlers === null || handlers === void 0 ? void 0 : handlers.size)) { 5519 return; 5520 } 5521 messageEvent.ports[0].postMessage({ 5522 status: "ack", 5523 eventId, 5524 eventType 5525 }); 5526 const promises = Array.from(handlers).map(async (handler) => handler(messageEvent.origin, data)); 5527 const response = await _allSettled(promises); 5528 messageEvent.ports[0].postMessage({ 5529 status: "done", 5530 eventId, 5531 eventType, 5532 response 5533 }); 5534 } 5535 _subscribe(eventType, eventHandler) { 5536 if (Object.keys(this.handlersMap).length === 0) { 5537 this.eventTarget.addEventListener("message", this.boundEventHandler); 5538 } 5539 if (!this.handlersMap[eventType]) { 5540 this.handlersMap[eventType] = /* @__PURE__ */ new Set(); 5541 } 5542 this.handlersMap[eventType].add(eventHandler); 5543 } 5544 _unsubscribe(eventType, eventHandler) { 5545 if (this.handlersMap[eventType] && eventHandler) { 5546 this.handlersMap[eventType].delete(eventHandler); 5547 } 5548 if (!eventHandler || this.handlersMap[eventType].size === 0) { 5549 delete this.handlersMap[eventType]; 5550 } 5551 if (Object.keys(this.handlersMap).length === 0) { 5552 this.eventTarget.removeEventListener("message", this.boundEventHandler); 5553 } 5554 } 5555 }; 5556 Receiver.receivers = []; 5557 function _generateEventId(prefix = "", digits = 10) { 5558 let random = ""; 5559 for (let i = 0; i < digits; i++) { 5560 random += Math.floor(Math.random() * 10); 5561 } 5562 return prefix + random; 5563 } 5564 var Sender = class { 5565 constructor(target) { 5566 this.target = target; 5567 this.handlers = /* @__PURE__ */ new Set(); 5568 } 5569 removeMessageHandler(handler) { 5570 if (handler.messageChannel) { 5571 handler.messageChannel.port1.removeEventListener("message", handler.onMessage); 5572 handler.messageChannel.port1.close(); 5573 } 5574 this.handlers.delete(handler); 5575 } 5576 async _send(eventType, data, timeout = 50) { 5577 const messageChannel = typeof MessageChannel !== "undefined" ? new MessageChannel() : null; 5578 if (!messageChannel) { 5579 throw new Error("connection_unavailable"); 5580 } 5581 let completionTimer; 5582 let handler; 5583 return new Promise((resolve, reject) => { 5584 const eventId = _generateEventId("", 20); 5585 messageChannel.port1.start(); 5586 const ackTimer = setTimeout(() => { 5587 reject(new Error("unsupported_event")); 5588 }, timeout); 5589 handler = { 5590 messageChannel, 5591 onMessage(event) { 5592 const messageEvent = event; 5593 if (messageEvent.data.eventId !== eventId) { 5594 return; 5595 } 5596 switch (messageEvent.data.status) { 5597 case "ack": 5598 clearTimeout(ackTimer); 5599 completionTimer = setTimeout(() => { 5600 reject(new Error("timeout")); 5601 }, 3e3); 5602 break; 5603 case "done": 5604 clearTimeout(completionTimer); 5605 resolve(messageEvent.data.response); 5606 break; 5607 default: 5608 clearTimeout(ackTimer); 5609 clearTimeout(completionTimer); 5610 reject(new Error("invalid_response")); 5611 break; 5612 } 5613 } 5614 }; 5615 this.handlers.add(handler); 5616 messageChannel.port1.addEventListener("message", handler.onMessage); 5617 this.target.postMessage({ 5618 eventType, 5619 eventId, 5620 data 5621 }, [messageChannel.port2]); 5622 }).finally(() => { 5623 if (handler) { 5624 this.removeMessageHandler(handler); 5625 } 5626 }); 5627 } 5628 }; 5629 function _window() { 5630 return window; 5631 } 5632 function _isWorker() { 5633 return typeof _window()["WorkerGlobalScope"] !== "undefined" && typeof _window()["importScripts"] === "function"; 5634 } 5635 async function _getActiveServiceWorker() { 5636 if (!(navigator === null || navigator === void 0 ? void 0 : navigator.serviceWorker)) { 5637 return null; 5638 } 5639 try { 5640 const registration = await navigator.serviceWorker.ready; 5641 return registration.active; 5642 } catch (_a) { 5643 return null; 5644 } 5645 } 5646 function _getServiceWorkerController() { 5647 var _a; 5648 return ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.serviceWorker) === null || _a === void 0 ? void 0 : _a.controller) || null; 5649 } 5650 function _getWorkerGlobalScope() { 5651 return _isWorker() ? self : null; 5652 } 5653 var DB_NAME2 = "firebaseLocalStorageDb"; 5654 var DB_VERSION2 = 1; 5655 var DB_OBJECTSTORE_NAME = "firebaseLocalStorage"; 5656 var DB_DATA_KEYPATH = "fbase_key"; 5657 var DBPromise = class { 5658 constructor(request) { 5659 this.request = request; 5660 } 5661 toPromise() { 5662 return new Promise((resolve, reject) => { 5663 this.request.addEventListener("success", () => { 5664 resolve(this.request.result); 5665 }); 5666 this.request.addEventListener("error", () => { 5667 reject(this.request.error); 5668 }); 5669 }); 5670 } 5671 }; 5672 function getObjectStore(db2, isReadWrite) { 5673 return db2.transaction([DB_OBJECTSTORE_NAME], isReadWrite ? "readwrite" : "readonly").objectStore(DB_OBJECTSTORE_NAME); 5674 } 5675 function _deleteDatabase() { 5676 const request = indexedDB.deleteDatabase(DB_NAME2); 5677 return new DBPromise(request).toPromise(); 5678 } 5679 function _openDatabase() { 5680 const request = indexedDB.open(DB_NAME2, DB_VERSION2); 5681 return new Promise((resolve, reject) => { 5682 request.addEventListener("error", () => { 5683 reject(request.error); 5684 }); 5685 request.addEventListener("upgradeneeded", () => { 5686 const db2 = request.result; 5687 try { 5688 db2.createObjectStore(DB_OBJECTSTORE_NAME, { keyPath: DB_DATA_KEYPATH }); 5689 } catch (e) { 5690 reject(e); 5691 } 5692 }); 5693 request.addEventListener("success", async () => { 5694 const db2 = request.result; 5695 if (!db2.objectStoreNames.contains(DB_OBJECTSTORE_NAME)) { 5696 db2.close(); 5697 await _deleteDatabase(); 5698 resolve(await _openDatabase()); 5699 } else { 5700 resolve(db2); 5701 } 5702 }); 5703 }); 5704 } 5705 async function _putObject(db2, key, value) { 5706 const request = getObjectStore(db2, true).put({ 5707 [DB_DATA_KEYPATH]: key, 5708 value 5709 }); 5710 return new DBPromise(request).toPromise(); 5711 } 5712 async function getObject(db2, key) { 5713 const request = getObjectStore(db2, false).get(key); 5714 const data = await new DBPromise(request).toPromise(); 5715 return data === void 0 ? null : data.value; 5716 } 5717 function _deleteObject(db2, key) { 5718 const request = getObjectStore(db2, true).delete(key); 5719 return new DBPromise(request).toPromise(); 5720 } 5721 var _POLLING_INTERVAL_MS = 800; 5722 var _TRANSACTION_RETRY_COUNT = 3; 5723 var IndexedDBLocalPersistence = class { 5724 constructor() { 5725 this.type = "LOCAL"; 5726 this._shouldAllowMigration = true; 5727 this.listeners = {}; 5728 this.localCache = {}; 5729 this.pollTimer = null; 5730 this.pendingWrites = 0; 5731 this.receiver = null; 5732 this.sender = null; 5733 this.serviceWorkerReceiverAvailable = false; 5734 this.activeServiceWorker = null; 5735 this._workerInitializationPromise = this.initializeServiceWorkerMessaging().then(() => { 5736 }, () => { 5737 }); 5738 } 5739 async _openDb() { 5740 if (this.db) { 5741 return this.db; 5742 } 5743 this.db = await _openDatabase(); 5744 return this.db; 5745 } 5746 async _withRetries(op) { 5747 let numAttempts = 0; 5748 while (true) { 5749 try { 5750 const db2 = await this._openDb(); 5751 return await op(db2); 5752 } catch (e) { 5753 if (numAttempts++ > _TRANSACTION_RETRY_COUNT) { 5754 throw e; 5755 } 5756 if (this.db) { 5757 this.db.close(); 5758 this.db = void 0; 5759 } 5760 } 5761 } 5762 } 5763 async initializeServiceWorkerMessaging() { 5764 return _isWorker() ? this.initializeReceiver() : this.initializeSender(); 5765 } 5766 async initializeReceiver() { 5767 this.receiver = Receiver._getInstance(_getWorkerGlobalScope()); 5768 this.receiver._subscribe("keyChanged", async (_origin, data) => { 5769 const keys = await this._poll(); 5770 return { 5771 keyProcessed: keys.includes(data.key) 5772 }; 5773 }); 5774 this.receiver._subscribe("ping", async (_origin, _data) => { 5775 return ["keyChanged"]; 5776 }); 5777 } 5778 async initializeSender() { 5779 var _a, _b; 5780 this.activeServiceWorker = await _getActiveServiceWorker(); 5781 if (!this.activeServiceWorker) { 5782 return; 5783 } 5784 this.sender = new Sender(this.activeServiceWorker); 5785 const results = await this.sender._send("ping", {}, 800); 5786 if (!results) { 5787 return; 5788 } 5789 if (((_a = results[0]) === null || _a === void 0 ? void 0 : _a.fulfilled) && ((_b = results[0]) === null || _b === void 0 ? void 0 : _b.value.includes("keyChanged"))) { 5790 this.serviceWorkerReceiverAvailable = true; 5791 } 5792 } 5793 async notifyServiceWorker(key) { 5794 if (!this.sender || !this.activeServiceWorker || _getServiceWorkerController() !== this.activeServiceWorker) { 5795 return; 5796 } 5797 try { 5798 await this.sender._send("keyChanged", { key }, this.serviceWorkerReceiverAvailable ? 800 : 50); 5799 } catch (_a) { 5800 } 5801 } 5802 async _isAvailable() { 5803 try { 5804 if (!indexedDB) { 5805 return false; 5806 } 5807 const db2 = await _openDatabase(); 5808 await _putObject(db2, STORAGE_AVAILABLE_KEY, "1"); 5809 await _deleteObject(db2, STORAGE_AVAILABLE_KEY); 5810 return true; 5811 } catch (_a) { 5812 } 5813 return false; 5814 } 5815 async _withPendingWrite(write) { 5816 this.pendingWrites++; 5817 try { 5818 await write(); 5819 } finally { 5820 this.pendingWrites--; 5821 } 5822 } 5823 async _set(key, value) { 5824 return this._withPendingWrite(async () => { 5825 await this._withRetries((db2) => _putObject(db2, key, value)); 5826 this.localCache[key] = value; 5827 return this.notifyServiceWorker(key); 5828 }); 5829 } 5830 async _get(key) { 5831 const obj = await this._withRetries((db2) => getObject(db2, key)); 5832 this.localCache[key] = obj; 5833 return obj; 5834 } 5835 async _remove(key) { 5836 return this._withPendingWrite(async () => { 5837 await this._withRetries((db2) => _deleteObject(db2, key)); 5838 delete this.localCache[key]; 5839 return this.notifyServiceWorker(key); 5840 }); 5841 } 5842 async _poll() { 5843 const result = await this._withRetries((db2) => { 5844 const getAllRequest = getObjectStore(db2, false).getAll(); 5845 return new DBPromise(getAllRequest).toPromise(); 5846 }); 5847 if (!result) { 5848 return []; 5849 } 5850 if (this.pendingWrites !== 0) { 5851 return []; 5852 } 5853 const keys = []; 5854 const keysInResult = /* @__PURE__ */ new Set(); 5855 for (const { fbase_key: key, value } of result) { 5856 keysInResult.add(key); 5857 if (JSON.stringify(this.localCache[key]) !== JSON.stringify(value)) { 5858 this.notifyListeners(key, value); 5859 keys.push(key); 5860 } 5861 } 5862 for (const localKey of Object.keys(this.localCache)) { 5863 if (this.localCache[localKey] && !keysInResult.has(localKey)) { 5864 this.notifyListeners(localKey, null); 5865 keys.push(localKey); 5866 } 5867 } 5868 return keys; 5869 } 5870 notifyListeners(key, newValue) { 5871 this.localCache[key] = newValue; 5872 const listeners = this.listeners[key]; 5873 if (listeners) { 5874 for (const listener of Array.from(listeners)) { 5875 listener(newValue); 5876 } 5877 } 5878 } 5879 startPolling() { 5880 this.stopPolling(); 5881 this.pollTimer = setInterval(async () => this._poll(), _POLLING_INTERVAL_MS); 5882 } 5883 stopPolling() { 5884 if (this.pollTimer) { 5885 clearInterval(this.pollTimer); 5886 this.pollTimer = null; 5887 } 5888 } 5889 _addListener(key, listener) { 5890 if (Object.keys(this.listeners).length === 0) { 5891 this.startPolling(); 5892 } 5893 if (!this.listeners[key]) { 5894 this.listeners[key] = /* @__PURE__ */ new Set(); 5895 void this._get(key); 5896 } 5897 this.listeners[key].add(listener); 5898 } 5899 _removeListener(key, listener) { 5900 if (this.listeners[key]) { 5901 this.listeners[key].delete(listener); 5902 if (this.listeners[key].size === 0) { 5903 delete this.listeners[key]; 5904 } 5905 } 5906 if (Object.keys(this.listeners).length === 0) { 5907 this.stopPolling(); 5908 } 5909 } 5910 }; 5911 IndexedDBLocalPersistence.type = "LOCAL"; 5912 var indexedDBLocalPersistence = IndexedDBLocalPersistence; 5913 function startSignInPhoneMfa(auth2, request) { 5914 return _performApiRequest(auth2, "POST", "/v2/accounts/mfaSignIn:start", _addTidIfNecessary(auth2, request)); 5915 } 5916 function finalizeSignInPhoneMfa(auth2, request) { 5917 return _performApiRequest(auth2, "POST", "/v2/accounts/mfaSignIn:finalize", _addTidIfNecessary(auth2, request)); 5918 } 5919 function _generateCallbackName(prefix) { 5920 return `__${prefix}${Math.floor(Math.random() * 1e6)}`; 5921 } 5922 var _JSLOAD_CALLBACK = _generateCallbackName("rcb"); 5923 var NETWORK_TIMEOUT_DELAY = new Delay(3e4, 6e4); 5924 var RECAPTCHA_VERIFIER_TYPE = "recaptcha"; 5925 async function _verifyPhoneNumber(auth2, options, verifier) { 5926 var _a; 5927 const recaptchaToken = await verifier.verify(); 5928 try { 5929 _assert(typeof recaptchaToken === "string", auth2, "argument-error"); 5930 _assert(verifier.type === RECAPTCHA_VERIFIER_TYPE, auth2, "argument-error"); 5931 let phoneInfoOptions; 5932 if (typeof options === "string") { 5933 phoneInfoOptions = { 5934 phoneNumber: options 5935 }; 5936 } else { 5937 phoneInfoOptions = options; 5938 } 5939 if ("session" in phoneInfoOptions) { 5940 const session = phoneInfoOptions.session; 5941 if ("phoneNumber" in phoneInfoOptions) { 5942 _assert(session.type === "enroll", auth2, "internal-error"); 5943 const response = await startEnrollPhoneMfa(auth2, { 5944 idToken: session.credential, 5945 phoneEnrollmentInfo: { 5946 phoneNumber: phoneInfoOptions.phoneNumber, 5947 recaptchaToken 5948 } 5949 }); 5950 return response.phoneSessionInfo.sessionInfo; 5951 } else { 5952 _assert(session.type === "signin", auth2, "internal-error"); 5953 const mfaEnrollmentId = ((_a = phoneInfoOptions.multiFactorHint) === null || _a === void 0 ? void 0 : _a.uid) || phoneInfoOptions.multiFactorUid; 5954 _assert(mfaEnrollmentId, auth2, "missing-multi-factor-info"); 5955 const response = await startSignInPhoneMfa(auth2, { 5956 mfaPendingCredential: session.credential, 5957 mfaEnrollmentId, 5958 phoneSignInInfo: { 5959 recaptchaToken 5960 } 5961 }); 5962 return response.phoneResponseInfo.sessionInfo; 5963 } 5964 } else { 5965 const { sessionInfo } = await sendPhoneVerificationCode(auth2, { 5966 phoneNumber: phoneInfoOptions.phoneNumber, 5967 recaptchaToken 5968 }); 5969 return sessionInfo; 5970 } 5971 } finally { 5972 verifier._reset(); 5973 } 5974 } 5975 var PhoneAuthProvider = class { 5976 constructor(auth2) { 5977 this.providerId = PhoneAuthProvider.PROVIDER_ID; 5978 this.auth = _castAuth(auth2); 5979 } 5980 verifyPhoneNumber(phoneOptions, applicationVerifier) { 5981 return _verifyPhoneNumber(this.auth, phoneOptions, getModularInstance(applicationVerifier)); 5982 } 5983 static credential(verificationId, verificationCode) { 5984 return PhoneAuthCredential._fromVerification(verificationId, verificationCode); 5985 } 5986 static credentialFromResult(userCredential) { 5987 const credential = userCredential; 5988 return PhoneAuthProvider.credentialFromTaggedObject(credential); 5989 } 5990 static credentialFromError(error2) { 5991 return PhoneAuthProvider.credentialFromTaggedObject(error2.customData || {}); 5992 } 5993 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) { 5994 if (!tokenResponse) { 5995 return null; 5996 } 5997 const { phoneNumber, temporaryProof } = tokenResponse; 5998 if (phoneNumber && temporaryProof) { 5999 return PhoneAuthCredential._fromTokenResponse(phoneNumber, temporaryProof); 6000 } 6001 return null; 6002 } 6003 }; 6004 PhoneAuthProvider.PROVIDER_ID = "phone"; 6005 PhoneAuthProvider.PHONE_SIGN_IN_METHOD = "phone"; 6006 var IdpCredential = class extends AuthCredential { 6007 constructor(params) { 6008 super("custom", "custom"); 6009 this.params = params; 6010 } 6011 _getIdTokenResponse(auth2) { 6012 return signInWithIdp(auth2, this._buildIdpRequest()); 6013 } 6014 _linkToIdToken(auth2, idToken) { 6015 return signInWithIdp(auth2, this._buildIdpRequest(idToken)); 6016 } 6017 _getReauthenticationResolver(auth2) { 6018 return signInWithIdp(auth2, this._buildIdpRequest()); 6019 } 6020 _buildIdpRequest(idToken) { 6021 const request = { 6022 requestUri: this.params.requestUri, 6023 sessionId: this.params.sessionId, 6024 postBody: this.params.postBody, 6025 tenantId: this.params.tenantId, 6026 pendingToken: this.params.pendingToken, 6027 returnSecureToken: true, 6028 returnIdpCredential: true 6029 }; 6030 if (idToken) { 6031 request.idToken = idToken; 6032 } 6033 return request; 6034 } 6035 }; 6036 function _signIn(params) { 6037 return _signInWithCredential(params.auth, new IdpCredential(params), params.bypassAuthState); 6038 } 6039 function _reauth(params) { 6040 const { auth: auth2, user } = params; 6041 _assert(user, auth2, "internal-error"); 6042 return _reauthenticate(user, new IdpCredential(params), params.bypassAuthState); 6043 } 6044 async function _link(params) { 6045 const { auth: auth2, user } = params; 6046 _assert(user, auth2, "internal-error"); 6047 return _link$1(user, new IdpCredential(params), params.bypassAuthState); 6048 } 6049 var AbstractPopupRedirectOperation = class { 6050 constructor(auth2, filter, resolver, user, bypassAuthState = false) { 6051 this.auth = auth2; 6052 this.resolver = resolver; 6053 this.user = user; 6054 this.bypassAuthState = bypassAuthState; 6055 this.pendingPromise = null; 6056 this.eventManager = null; 6057 this.filter = Array.isArray(filter) ? filter : [filter]; 6058 } 6059 execute() { 6060 return new Promise(async (resolve, reject) => { 6061 this.pendingPromise = { resolve, reject }; 6062 try { 6063 this.eventManager = await this.resolver._initialize(this.auth); 6064 await this.onExecution(); 6065 this.eventManager.registerConsumer(this); 6066 } catch (e) { 6067 this.reject(e); 6068 } 6069 }); 6070 } 6071 async onAuthEvent(event) { 6072 const { urlResponse, sessionId, postBody, tenantId, error: error2, type } = event; 6073 if (error2) { 6074 this.reject(error2); 6075 return; 6076 } 6077 const params = { 6078 auth: this.auth, 6079 requestUri: urlResponse, 6080 sessionId, 6081 tenantId: tenantId || void 0, 6082 postBody: postBody || void 0, 6083 user: this.user, 6084 bypassAuthState: this.bypassAuthState 6085 }; 6086 try { 6087 this.resolve(await this.getIdpTask(type)(params)); 6088 } catch (e) { 6089 this.reject(e); 6090 } 6091 } 6092 onError(error2) { 6093 this.reject(error2); 6094 } 6095 getIdpTask(type) { 6096 switch (type) { 6097 case "signInViaPopup": 6098 case "signInViaRedirect": 6099 return _signIn; 6100 case "linkViaPopup": 6101 case "linkViaRedirect": 6102 return _link; 6103 case "reauthViaPopup": 6104 case "reauthViaRedirect": 6105 return _reauth; 6106 default: 6107 _fail(this.auth, "internal-error"); 6108 } 6109 } 6110 resolve(cred) { 6111 debugAssert(this.pendingPromise, "Pending promise was never set"); 6112 this.pendingPromise.resolve(cred); 6113 this.unregisterAndCleanUp(); 6114 } 6115 reject(error2) { 6116 debugAssert(this.pendingPromise, "Pending promise was never set"); 6117 this.pendingPromise.reject(error2); 6118 this.unregisterAndCleanUp(); 6119 } 6120 unregisterAndCleanUp() { 6121 if (this.eventManager) { 6122 this.eventManager.unregisterConsumer(this); 6123 } 6124 this.pendingPromise = null; 6125 this.cleanUp(); 6126 } 6127 }; 6128 var _POLL_WINDOW_CLOSE_TIMEOUT = new Delay(2e3, 1e4); 6129 var PopupOperation = class extends AbstractPopupRedirectOperation { 6130 constructor(auth2, filter, provider, resolver, user) { 6131 super(auth2, filter, resolver, user); 6132 this.provider = provider; 6133 this.authWindow = null; 6134 this.pollId = null; 6135 if (PopupOperation.currentPopupAction) { 6136 PopupOperation.currentPopupAction.cancel(); 6137 } 6138 PopupOperation.currentPopupAction = this; 6139 } 6140 async executeNotNull() { 6141 const result = await this.execute(); 6142 _assert(result, this.auth, "internal-error"); 6143 return result; 6144 } 6145 async onExecution() { 6146 debugAssert(this.filter.length === 1, "Popup operations only handle one event"); 6147 const eventId = _generateEventId(); 6148 this.authWindow = await this.resolver._openPopup(this.auth, this.provider, this.filter[0], eventId); 6149 this.authWindow.associatedEvent = eventId; 6150 this.resolver._originValidation(this.auth).catch((e) => { 6151 this.reject(e); 6152 }); 6153 this.resolver._isIframeWebStorageSupported(this.auth, (isSupported) => { 6154 if (!isSupported) { 6155 this.reject(_createError(this.auth, "web-storage-unsupported")); 6156 } 6157 }); 6158 this.pollUserCancellation(); 6159 } 6160 get eventId() { 6161 var _a; 6162 return ((_a = this.authWindow) === null || _a === void 0 ? void 0 : _a.associatedEvent) || null; 6163 } 6164 cancel() { 6165 this.reject(_createError(this.auth, "cancelled-popup-request")); 6166 } 6167 cleanUp() { 6168 if (this.authWindow) { 6169 this.authWindow.close(); 6170 } 6171 if (this.pollId) { 6172 window.clearTimeout(this.pollId); 6173 } 6174 this.authWindow = null; 6175 this.pollId = null; 6176 PopupOperation.currentPopupAction = null; 6177 } 6178 pollUserCancellation() { 6179 const poll = () => { 6180 var _a, _b; 6181 if ((_b = (_a = this.authWindow) === null || _a === void 0 ? void 0 : _a.window) === null || _b === void 0 ? void 0 : _b.closed) { 6182 this.pollId = window.setTimeout(() => { 6183 this.pollId = null; 6184 this.reject(_createError(this.auth, "popup-closed-by-user")); 6185 }, 2e3); 6186 return; 6187 } 6188 this.pollId = window.setTimeout(poll, _POLL_WINDOW_CLOSE_TIMEOUT.get()); 6189 }; 6190 poll(); 6191 } 6192 }; 6193 PopupOperation.currentPopupAction = null; 6194 var EVENT_DUPLICATION_CACHE_DURATION_MS = 10 * 60 * 1e3; 6195 var NETWORK_TIMEOUT = new Delay(3e4, 6e4); 6196 var PING_TIMEOUT = new Delay(5e3, 15e3); 6197 var MultiFactorAssertionImpl = class { 6198 constructor(factorId) { 6199 this.factorId = factorId; 6200 } 6201 _process(auth2, session, displayName) { 6202 switch (session.type) { 6203 case "enroll": 6204 return this._finalizeEnroll(auth2, session.credential, displayName); 6205 case "signin": 6206 return this._finalizeSignIn(auth2, session.credential); 6207 default: 6208 return debugFail("unexpected MultiFactorSessionType"); 6209 } 6210 } 6211 }; 6212 var PhoneMultiFactorAssertionImpl = class extends MultiFactorAssertionImpl { 6213 constructor(credential) { 6214 super("phone"); 6215 this.credential = credential; 6216 } 6217 static _fromCredential(credential) { 6218 return new PhoneMultiFactorAssertionImpl(credential); 6219 } 6220 _finalizeEnroll(auth2, idToken, displayName) { 6221 return finalizeEnrollPhoneMfa(auth2, { 6222 idToken, 6223 displayName, 6224 phoneVerificationInfo: this.credential._makeVerificationRequest() 6225 }); 6226 } 6227 _finalizeSignIn(auth2, mfaPendingCredential) { 6228 return finalizeSignInPhoneMfa(auth2, { 6229 mfaPendingCredential, 6230 phoneVerificationInfo: this.credential._makeVerificationRequest() 6231 }); 6232 } 6233 }; 6234 var PhoneMultiFactorGenerator = class { 6235 constructor() { 6236 } 6237 static assertion(credential) { 6238 return PhoneMultiFactorAssertionImpl._fromCredential(credential); 6239 } 6240 }; 6241 PhoneMultiFactorGenerator.FACTOR_ID = "phone"; 6242 var name5 = "@firebase/auth"; 6243 var version5 = "0.20.6"; 6244 var AuthInterop = class { 6245 constructor(auth2) { 6246 this.auth = auth2; 6247 this.internalListeners = /* @__PURE__ */ new Map(); 6248 } 6249 getUid() { 6250 var _a; 6251 this.assertAuthConfigured(); 6252 return ((_a = this.auth.currentUser) === null || _a === void 0 ? void 0 : _a.uid) || null; 6253 } 6254 async getToken(forceRefresh) { 6255 this.assertAuthConfigured(); 6256 await this.auth._initializationPromise; 6257 if (!this.auth.currentUser) { 6258 return null; 6259 } 6260 const accessToken = await this.auth.currentUser.getIdToken(forceRefresh); 6261 return { accessToken }; 6262 } 6263 addAuthTokenListener(listener) { 6264 this.assertAuthConfigured(); 6265 if (this.internalListeners.has(listener)) { 6266 return; 6267 } 6268 const unsubscribe = this.auth.onIdTokenChanged((user) => { 6269 var _a; 6270 listener(((_a = user) === null || _a === void 0 ? void 0 : _a.stsTokenManager.accessToken) || null); 6271 }); 6272 this.internalListeners.set(listener, unsubscribe); 6273 this.updateProactiveRefresh(); 6274 } 6275 removeAuthTokenListener(listener) { 6276 this.assertAuthConfigured(); 6277 const unsubscribe = this.internalListeners.get(listener); 6278 if (!unsubscribe) { 6279 return; 6280 } 6281 this.internalListeners.delete(listener); 6282 unsubscribe(); 6283 this.updateProactiveRefresh(); 6284 } 6285 assertAuthConfigured() { 6286 _assert(this.auth._initializationPromise, "dependent-sdk-initialized-before-auth"); 6287 } 6288 updateProactiveRefresh() { 6289 if (this.internalListeners.size > 0) { 6290 this.auth._startProactiveRefresh(); 6291 } else { 6292 this.auth._stopProactiveRefresh(); 6293 } 6294 } 6295 }; 6296 function getVersionForPlatform(clientPlatform) { 6297 switch (clientPlatform) { 6298 case "Node": 6299 return "node"; 6300 case "ReactNative": 6301 return "rn"; 6302 case "Worker": 6303 return "webworker"; 6304 case "Cordova": 6305 return "cordova"; 6306 default: 6307 return void 0; 6308 } 6309 } 6310 function registerAuth(clientPlatform) { 6311 _registerComponent(new Component("auth", (container, { options: deps }) => { 6312 const app2 = container.getProvider("app").getImmediate(); 6313 const heartbeatServiceProvider = container.getProvider("heartbeat"); 6314 const { apiKey, authDomain } = app2.options; 6315 return ((app3, heartbeatServiceProvider2) => { 6316 _assert(apiKey && !apiKey.includes(":"), "invalid-api-key", { appName: app3.name }); 6317 _assert(!(authDomain === null || authDomain === void 0 ? void 0 : authDomain.includes(":")), "argument-error", { 6318 appName: app3.name 6319 }); 6320 const config = { 6321 apiKey, 6322 authDomain, 6323 clientPlatform, 6324 apiHost: "identitytoolkit.googleapis.com", 6325 tokenApiHost: "securetoken.googleapis.com", 6326 apiScheme: "https", 6327 sdkClientVersion: _getClientVersion(clientPlatform) 6328 }; 6329 const authInstance = new AuthImpl(app3, heartbeatServiceProvider2, config); 6330 _initializeAuthInstance(authInstance, deps); 6331 return authInstance; 6332 })(app2, heartbeatServiceProvider); 6333 }, "PUBLIC").setInstantiationMode("EXPLICIT").setInstanceCreatedCallback((container, _instanceIdentifier, _instance) => { 6334 const authInternalProvider = container.getProvider("auth-internal"); 6335 authInternalProvider.initialize(); 6336 })); 6337 _registerComponent(new Component("auth-internal", (container) => { 6338 const auth2 = _castAuth(container.getProvider("auth").getImmediate()); 6339 return ((auth3) => new AuthInterop(auth3))(auth2); 6340 }, "PRIVATE").setInstantiationMode("EXPLICIT")); 6341 registerVersion(name5, version5, getVersionForPlatform(clientPlatform)); 6342 registerVersion(name5, version5, "esm2017"); 6343 } 6344 registerAuth("Browser"); 6345 6346
vendor: 246,541 bytes, lines 6346-13028
6346// node_modules/@firebase/database/dist/index.esm2017.js 6347 var name6 = "@firebase/database"; 6348 var version6 = "0.13.6"; 6349 var SDK_VERSION2 = ""; 6350 function setSDKVersion(version7) { 6351 SDK_VERSION2 = version7; 6352 } 6353 var DOMStorageWrapper = class { 6354 constructor(domStorage_) { 6355 this.domStorage_ = domStorage_; 6356 this.prefix_ = "firebase:"; 6357 } 6358 set(key, value) { 6359 if (value == null) { 6360 this.domStorage_.removeItem(this.prefixedName_(key)); 6361 } else { 6362 this.domStorage_.setItem(this.prefixedName_(key), stringify(value)); 6363 } 6364 } 6365 get(key) { 6366 const storedVal = this.domStorage_.getItem(this.prefixedName_(key)); 6367 if (storedVal == null) { 6368 return null; 6369 } else { 6370 return jsonEval(storedVal); 6371 } 6372 } 6373 remove(key) { 6374 this.domStorage_.removeItem(this.prefixedName_(key)); 6375 } 6376 prefixedName_(name7) { 6377 return this.prefix_ + name7; 6378 } 6379 toString() { 6380 return this.domStorage_.toString(); 6381 } 6382 }; 6383 var MemoryStorage = class { 6384 constructor() { 6385 this.cache_ = {}; 6386 this.isInMemoryStorage = true; 6387 } 6388 set(key, value) { 6389 if (value == null) { 6390 delete this.cache_[key]; 6391 } else { 6392 this.cache_[key] = value; 6393 } 6394 } 6395 get(key) { 6396 if (contains(this.cache_, key)) { 6397 return this.cache_[key]; 6398 } 6399 return null; 6400 } 6401 remove(key) { 6402 delete this.cache_[key]; 6403 } 6404 }; 6405 var createStoragefor = function(domStorageName) { 6406 try { 6407 if (typeof window !== "undefined" && typeof window[domStorageName] !== "undefined") { 6408 const domStorage = window[domStorageName]; 6409 domStorage.setItem("firebase:sentinel", "cache"); 6410 domStorage.removeItem("firebase:sentinel"); 6411 return new DOMStorageWrapper(domStorage); 6412 } 6413 } catch (e) { 6414 } 6415 return new MemoryStorage(); 6416 }; 6417 var PersistentStorage = createStoragefor("localStorage"); 6418 var SessionStorage = createStoragefor("sessionStorage"); 6419 var logClient2 = new Logger("@firebase/database"); 6420 var LUIDGenerator = function() { 6421 let id = 1; 6422 return function() { 6423 return id++; 6424 }; 6425 }(); 6426 var sha1 = function(str) { 6427 const utf8Bytes = stringToByteArray(str); 6428 const sha12 = new Sha1(); 6429 sha12.update(utf8Bytes); 6430 const sha1Bytes = sha12.digest(); 6431 return base64.encodeByteArray(sha1Bytes); 6432 }; 6433 var buildLogMessage_ = function(...varArgs) { 6434 let message = ""; 6435 for (let i = 0; i < varArgs.length; i++) { 6436 const arg = varArgs[i]; 6437 if (Array.isArray(arg) || arg && typeof arg === "object" && typeof arg.length === "number") { 6438 message += buildLogMessage_.apply(null, arg); 6439 } else if (typeof arg === "object") { 6440 message += stringify(arg); 6441 } else { 6442 message += arg; 6443 } 6444 message += " "; 6445 } 6446 return message; 6447 }; 6448 var logger3 = null; 6449 var firstLog_ = true; 6450 var enableLogging$1 = function(logger_, persistent) { 6451 assert(!persistent || logger_ === true || logger_ === false, "Can't turn on custom loggers persistently."); 6452 if (logger_ === true) { 6453 logClient2.logLevel = LogLevel.VERBOSE; 6454 logger3 = logClient2.log.bind(logClient2); 6455 if (persistent) { 6456 SessionStorage.set("logging_enabled", true); 6457 } 6458 } else if (typeof logger_ === "function") { 6459 logger3 = logger_; 6460 } else { 6461 logger3 = null; 6462 SessionStorage.remove("logging_enabled"); 6463 } 6464 }; 6465 var log = function(...varArgs) { 6466 if (firstLog_ === true) { 6467 firstLog_ = false; 6468 if (logger3 === null && SessionStorage.get("logging_enabled") === true) { 6469 enableLogging$1(true); 6470 } 6471 } 6472 if (logger3) { 6473 const message = buildLogMessage_.apply(null, varArgs); 6474 logger3(message); 6475 } 6476 }; 6477 var logWrapper = function(prefix) { 6478 return function(...varArgs) { 6479 log(prefix, ...varArgs); 6480 }; 6481 }; 6482 var error = function(...varArgs) { 6483 const message = "FIREBASE INTERNAL ERROR: " + buildLogMessage_(...varArgs); 6484 logClient2.error(message); 6485 }; 6486 var fatal = function(...varArgs) { 6487 const message = `FIREBASE FATAL ERROR: ${buildLogMessage_(...varArgs)}`; 6488 logClient2.error(message); 6489 throw new Error(message); 6490 }; 6491 var warn = function(...varArgs) { 6492 const message = "FIREBASE WARNING: " + buildLogMessage_(...varArgs); 6493 logClient2.warn(message); 6494 }; 6495 var warnIfPageIsSecure = function() { 6496 if (typeof window !== "undefined" && window.location && window.location.protocol && window.location.protocol.indexOf("https:") !== -1) { 6497 warn("Insecure Firebase access from a secure page. Please use https in calls to new Firebase()."); 6498 } 6499 }; 6500 var isInvalidJSONNumber = function(data) { 6501 return typeof data === "number" && (data !== data || data === Number.POSITIVE_INFINITY || data === Number.NEGATIVE_INFINITY); 6502 }; 6503 var executeWhenDOMReady = function(fn) { 6504 if (isNodeSdk() || document.readyState === "complete") { 6505 fn(); 6506 } else { 6507 let called = false; 6508 const wrappedFn = function() { 6509 if (!document.body) { 6510 setTimeout(wrappedFn, Math.floor(10)); 6511 return; 6512 } 6513 if (!called) { 6514 called = true; 6515 fn(); 6516 } 6517 }; 6518 if (document.addEventListener) { 6519 document.addEventListener("DOMContentLoaded", wrappedFn, false); 6520 window.addEventListener("load", wrappedFn, false); 6521 } else if (document.attachEvent) { 6522 document.attachEvent("onreadystatechange", () => { 6523 if (document.readyState === "complete") { 6524 wrappedFn(); 6525 } 6526 }); 6527 window.attachEvent("onload", wrappedFn); 6528 } 6529 } 6530 }; 6531 var MIN_NAME = "[MIN_NAME]"; 6532 var MAX_NAME = "[MAX_NAME]"; 6533 var nameCompare = function(a, b) { 6534 if (a === b) { 6535 return 0; 6536 } else if (a === MIN_NAME || b === MAX_NAME) { 6537 return -1; 6538 } else if (b === MIN_NAME || a === MAX_NAME) { 6539 return 1; 6540 } else { 6541 const aAsInt = tryParseInt(a), bAsInt = tryParseInt(b); 6542 if (aAsInt !== null) { 6543 if (bAsInt !== null) { 6544 return aAsInt - bAsInt === 0 ? a.length - b.length : aAsInt - bAsInt; 6545 } else { 6546 return -1; 6547 } 6548 } else if (bAsInt !== null) { 6549 return 1; 6550 } else { 6551 return a < b ? -1 : 1; 6552 } 6553 } 6554 }; 6555 var stringCompare = function(a, b) { 6556 if (a === b) { 6557 return 0; 6558 } else if (a < b) { 6559 return -1; 6560 } else { 6561 return 1; 6562 } 6563 }; 6564 var requireKey = function(key, obj) { 6565 if (obj && key in obj) { 6566 return obj[key]; 6567 } else { 6568 throw new Error("Missing required key (" + key + ") in object: " + stringify(obj)); 6569 } 6570 }; 6571 var ObjectToUniqueKey = function(obj) { 6572 if (typeof obj !== "object" || obj === null) { 6573 return stringify(obj); 6574 } 6575 const keys = []; 6576 for (const k in obj) { 6577 keys.push(k); 6578 } 6579 keys.sort(); 6580 let key = "{"; 6581 for (let i = 0; i < keys.length; i++) { 6582 if (i !== 0) { 6583 key += ","; 6584 } 6585 key += stringify(keys[i]); 6586 key += ":"; 6587 key += ObjectToUniqueKey(obj[keys[i]]); 6588 } 6589 key += "}"; 6590 return key; 6591 }; 6592 var splitStringBySize = function(str, segsize) { 6593 const len = str.length; 6594 if (len <= segsize) { 6595 return [str]; 6596 } 6597 const dataSegs = []; 6598 for (let c = 0; c < len; c += segsize) { 6599 if (c + segsize > len) { 6600 dataSegs.push(str.substring(c, len)); 6601 } else { 6602 dataSegs.push(str.substring(c, c + segsize)); 6603 } 6604 } 6605 return dataSegs; 6606 }; 6607 function each(obj, fn) { 6608 for (const key in obj) { 6609 if (obj.hasOwnProperty(key)) { 6610 fn(key, obj[key]); 6611 } 6612 } 6613 } 6614 var doubleToIEEE754String = function(v) { 6615 assert(!isInvalidJSONNumber(v), "Invalid JSON number"); 6616 const ebits = 11, fbits = 52; 6617 const bias = (1 << ebits - 1) - 1; 6618 let s, e, f, ln, i; 6619 if (v === 0) { 6620 e = 0; 6621 f = 0; 6622 s = 1 / v === -Infinity ? 1 : 0; 6623 } else { 6624 s = v < 0; 6625 v = Math.abs(v); 6626 if (v >= Math.pow(2, 1 - bias)) { 6627 ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias); 6628 e = ln + bias; 6629 f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits)); 6630 } else { 6631 e = 0; 6632 f = Math.round(v / Math.pow(2, 1 - bias - fbits)); 6633 } 6634 } 6635 const bits = []; 6636 for (i = fbits; i; i -= 1) { 6637 bits.push(f % 2 ? 1 : 0); 6638 f = Math.floor(f / 2); 6639 } 6640 for (i = ebits; i; i -= 1) { 6641 bits.push(e % 2 ? 1 : 0); 6642 e = Math.floor(e / 2); 6643 } 6644 bits.push(s ? 1 : 0); 6645 bits.reverse(); 6646 const str = bits.join(""); 6647 let hexByteString = ""; 6648 for (i = 0; i < 64; i += 8) { 6649 let hexByte = parseInt(str.substr(i, 8), 2).toString(16); 6650 if (hexByte.length === 1) { 6651 hexByte = "0" + hexByte; 6652 } 6653 hexByteString = hexByteString + hexByte; 6654 } 6655 return hexByteString.toLowerCase(); 6656 }; 6657 var isChromeExtensionContentScript = function() { 6658 return !!(typeof window === "object" && window["chrome"] && window["chrome"]["extension"] && !/^chrome/.test(window.location.href)); 6659 }; 6660 var isWindowsStoreApp = function() { 6661 return typeof Windows === "object" && typeof Windows.UI === "object"; 6662 }; 6663 var INTEGER_REGEXP_ = new RegExp("^-?(0*)\\d{1,10}$"); 6664 var INTEGER_32_MIN = -2147483648; 6665 var INTEGER_32_MAX = 2147483647; 6666 var tryParseInt = function(str) { 6667 if (INTEGER_REGEXP_.test(str)) { 6668 const intVal = Number(str); 6669 if (intVal >= INTEGER_32_MIN && intVal <= INTEGER_32_MAX) { 6670 return intVal; 6671 } 6672 } 6673 return null; 6674 }; 6675 var exceptionGuard = function(fn) { 6676 try { 6677 fn(); 6678 } catch (e) { 6679 setTimeout(() => { 6680 const stack = e.stack || ""; 6681 warn("Exception was thrown by user callback.", stack); 6682 throw e; 6683 }, Math.floor(0)); 6684 } 6685 }; 6686 var beingCrawled = function() { 6687 const userAgent = typeof window === "object" && window["navigator"] && window["navigator"]["userAgent"] || ""; 6688 return userAgent.search(/googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i) >= 0; 6689 }; 6690 var setTimeoutNonBlocking = function(fn, time) { 6691 const timeout = setTimeout(fn, time); 6692 if (typeof timeout === "number" && typeof Deno !== "undefined" && Deno["unrefTimer"]) { 6693 Deno.unrefTimer(timeout); 6694 } else if (typeof timeout === "object" && timeout["unref"]) { 6695 timeout["unref"](); 6696 } 6697 return timeout; 6698 }; 6699 var AppCheckTokenProvider = class { 6700 constructor(appName_, appCheckProvider) { 6701 this.appName_ = appName_; 6702 this.appCheckProvider = appCheckProvider; 6703 this.appCheck = appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.getImmediate({ optional: true }); 6704 if (!this.appCheck) { 6705 appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.get().then((appCheck) => this.appCheck = appCheck); 6706 } 6707 } 6708 getToken(forceRefresh) { 6709 if (!this.appCheck) { 6710 return new Promise((resolve, reject) => { 6711 setTimeout(() => { 6712 if (this.appCheck) { 6713 this.getToken(forceRefresh).then(resolve, reject); 6714 } else { 6715 resolve(null); 6716 } 6717 }, 0); 6718 }); 6719 } 6720 return this.appCheck.getToken(forceRefresh); 6721 } 6722 addTokenChangeListener(listener) { 6723 var _a; 6724 (_a = this.appCheckProvider) === null || _a === void 0 ? void 0 : _a.get().then((appCheck) => appCheck.addTokenListener(listener)); 6725 } 6726 notifyForInvalidToken() { 6727 warn(`Provided AppCheck credentials for the app named "${this.appName_}" are invalid. This usually indicates your app was not initialized correctly.`); 6728 } 6729 }; 6730 var FirebaseAuthTokenProvider = class { 6731 constructor(appName_, firebaseOptions_, authProvider_) { 6732 this.appName_ = appName_; 6733 this.firebaseOptions_ = firebaseOptions_; 6734 this.authProvider_ = authProvider_; 6735 this.auth_ = null; 6736 this.auth_ = authProvider_.getImmediate({ optional: true }); 6737 if (!this.auth_) { 6738 authProvider_.onInit((auth2) => this.auth_ = auth2); 6739 } 6740 } 6741 getToken(forceRefresh) { 6742 if (!this.auth_) { 6743 return new Promise((resolve, reject) => { 6744 setTimeout(() => { 6745 if (this.auth_) { 6746 this.getToken(forceRefresh).then(resolve, reject); 6747 } else { 6748 resolve(null); 6749 } 6750 }, 0); 6751 }); 6752 } 6753 return this.auth_.getToken(forceRefresh).catch((error2) => { 6754 if (error2 && error2.code === "auth/token-not-initialized") { 6755 log("Got auth/token-not-initialized error. Treating as null token."); 6756 return null; 6757 } else { 6758 return Promise.reject(error2); 6759 } 6760 }); 6761 } 6762 addTokenChangeListener(listener) { 6763 if (this.auth_) { 6764 this.auth_.addAuthTokenListener(listener); 6765 } else { 6766 this.authProvider_.get().then((auth2) => auth2.addAuthTokenListener(listener)); 6767 } 6768 } 6769 removeTokenChangeListener(listener) { 6770 this.authProvider_.get().then((auth2) => auth2.removeAuthTokenListener(listener)); 6771 } 6772 notifyForInvalidToken() { 6773 let errorMessage = 'Provided authentication credentials for the app named "' + this.appName_ + '" are invalid. This usually indicates your app was not initialized correctly. '; 6774 if ("credential" in this.firebaseOptions_) { 6775 errorMessage += 'Make sure the "credential" property provided to initializeApp() is authorized to access the specified "databaseURL" and is from the correct project.'; 6776 } else if ("serviceAccount" in this.firebaseOptions_) { 6777 errorMessage += 'Make sure the "serviceAccount" property provided to initializeApp() is authorized to access the specified "databaseURL" and is from the correct project.'; 6778 } else { 6779 errorMessage += 'Make sure the "apiKey" and "databaseURL" properties provided to initializeApp() match the values provided for your app at https://console.firebase.google.com/.'; 6780 } 6781 warn(errorMessage); 6782 } 6783 }; 6784 var EmulatorTokenProvider = class { 6785 constructor(accessToken) { 6786 this.accessToken = accessToken; 6787 } 6788 getToken(forceRefresh) { 6789 return Promise.resolve({ 6790 accessToken: this.accessToken 6791 }); 6792 } 6793 addTokenChangeListener(listener) { 6794 listener(this.accessToken); 6795 } 6796 removeTokenChangeListener(listener) { 6797 } 6798 notifyForInvalidToken() { 6799 } 6800 }; 6801 EmulatorTokenProvider.OWNER = "owner"; 6802 var PROTOCOL_VERSION = "5"; 6803 var VERSION_PARAM = "v"; 6804 var TRANSPORT_SESSION_PARAM = "s"; 6805 var REFERER_PARAM = "r"; 6806 var FORGE_REF = "f"; 6807 var FORGE_DOMAIN_RE = /(console\.firebase|firebase-console-\w+\.corp|firebase\.corp)\.google\.com/; 6808 var LAST_SESSION_PARAM = "ls"; 6809 var APPLICATION_ID_PARAM = "p"; 6810 var APP_CHECK_TOKEN_PARAM = "ac"; 6811 var WEBSOCKET = "websocket"; 6812 var LONG_POLLING = "long_polling"; 6813 var RepoInfo = class { 6814 constructor(host, secure, namespace, webSocketOnly, nodeAdmin = false, persistenceKey = "", includeNamespaceInQueryParams = false) { 6815 this.secure = secure; 6816 this.namespace = namespace; 6817 this.webSocketOnly = webSocketOnly; 6818 this.nodeAdmin = nodeAdmin; 6819 this.persistenceKey = persistenceKey; 6820 this.includeNamespaceInQueryParams = includeNamespaceInQueryParams; 6821 this._host = host.toLowerCase(); 6822 this._domain = this._host.substr(this._host.indexOf(".") + 1); 6823 this.internalHost = PersistentStorage.get("host:" + host) || this._host; 6824 } 6825 isCacheableHost() { 6826 return this.internalHost.substr(0, 2) === "s-"; 6827 } 6828 isCustomHost() { 6829 return this._domain !== "firebaseio.com" && this._domain !== "firebaseio-demo.com"; 6830 } 6831 get host() { 6832 return this._host; 6833 } 6834 set host(newHost) { 6835 if (newHost !== this.internalHost) { 6836 this.internalHost = newHost; 6837 if (this.isCacheableHost()) { 6838 PersistentStorage.set("host:" + this._host, this.internalHost); 6839 } 6840 } 6841 } 6842 toString() { 6843 let str = this.toURLString(); 6844 if (this.persistenceKey) { 6845 str += "<" + this.persistenceKey + ">"; 6846 } 6847 return str; 6848 } 6849 toURLString() { 6850 const protocol = this.secure ? "https://" : "http://"; 6851 const query = this.includeNamespaceInQueryParams ? `?ns=${this.namespace}` : ""; 6852 return `${protocol}${this.host}/${query}`; 6853 } 6854 }; 6855 function repoInfoNeedsQueryParam(repoInfo) { 6856 return repoInfo.host !== repoInfo.internalHost || repoInfo.isCustomHost() || repoInfo.includeNamespaceInQueryParams; 6857 } 6858 function repoInfoConnectionURL(repoInfo, type, params) { 6859 assert(typeof type === "string", "typeof type must == string"); 6860 assert(typeof params === "object", "typeof params must == object"); 6861 let connURL; 6862 if (type === WEBSOCKET) { 6863 connURL = (repoInfo.secure ? "wss://" : "ws://") + repoInfo.internalHost + "/.ws?"; 6864 } else if (type === LONG_POLLING) { 6865 connURL = (repoInfo.secure ? "https://" : "http://") + repoInfo.internalHost + "/.lp?"; 6866 } else { 6867 throw new Error("Unknown connection type: " + type); 6868 } 6869 if (repoInfoNeedsQueryParam(repoInfo)) { 6870 params["ns"] = repoInfo.namespace; 6871 } 6872 const pairs = []; 6873 each(params, (key, value) => { 6874 pairs.push(key + "=" + value); 6875 }); 6876 return connURL + pairs.join("&"); 6877 } 6878 var StatsCollection = class { 6879 constructor() { 6880 this.counters_ = {}; 6881 } 6882 incrementCounter(name7, amount = 1) { 6883 if (!contains(this.counters_, name7)) { 6884 this.counters_[name7] = 0; 6885 } 6886 this.counters_[name7] += amount; 6887 } 6888 get() { 6889 return deepCopy(this.counters_); 6890 } 6891 }; 6892 var collections = {}; 6893 var reporters = {}; 6894 function statsManagerGetCollection(repoInfo) { 6895 const hashString = repoInfo.toString(); 6896 if (!collections[hashString]) { 6897 collections[hashString] = new StatsCollection(); 6898 } 6899 return collections[hashString]; 6900 } 6901 function statsManagerGetOrCreateReporter(repoInfo, creatorFunction) { 6902 const hashString = repoInfo.toString(); 6903 if (!reporters[hashString]) { 6904 reporters[hashString] = creatorFunction(); 6905 } 6906 return reporters[hashString]; 6907 } 6908 var PacketReceiver = class { 6909 constructor(onMessage_) { 6910 this.onMessage_ = onMessage_; 6911 this.pendingResponses = []; 6912 this.currentResponseNum = 0; 6913 this.closeAfterResponse = -1; 6914 this.onClose = null; 6915 } 6916 closeAfter(responseNum, callback) { 6917 this.closeAfterResponse = responseNum; 6918 this.onClose = callback; 6919 if (this.closeAfterResponse < this.currentResponseNum) { 6920 this.onClose(); 6921 this.onClose = null; 6922 } 6923 } 6924 handleResponse(requestNum, data) { 6925 this.pendingResponses[requestNum] = data; 6926 while (this.pendingResponses[this.currentResponseNum]) { 6927 const toProcess = this.pendingResponses[this.currentResponseNum]; 6928 delete this.pendingResponses[this.currentResponseNum]; 6929 for (let i = 0; i < toProcess.length; ++i) { 6930 if (toProcess[i]) { 6931 exceptionGuard(() => { 6932 this.onMessage_(toProcess[i]); 6933 }); 6934 } 6935 } 6936 if (this.currentResponseNum === this.closeAfterResponse) { 6937 if (this.onClose) { 6938 this.onClose(); 6939 this.onClose = null; 6940 } 6941 break; 6942 } 6943 this.currentResponseNum++; 6944 } 6945 } 6946 }; 6947 var FIREBASE_LONGPOLL_START_PARAM = "start"; 6948 var FIREBASE_LONGPOLL_CLOSE_COMMAND = "close"; 6949 var FIREBASE_LONGPOLL_COMMAND_CB_NAME = "pLPCommand"; 6950 var FIREBASE_LONGPOLL_DATA_CB_NAME = "pRTLPCB"; 6951 var FIREBASE_LONGPOLL_ID_PARAM = "id"; 6952 var FIREBASE_LONGPOLL_PW_PARAM = "pw"; 6953 var FIREBASE_LONGPOLL_SERIAL_PARAM = "ser"; 6954 var FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = "cb"; 6955 var FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = "seg"; 6956 var FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = "ts"; 6957 var FIREBASE_LONGPOLL_DATA_PARAM = "d"; 6958 var FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = "dframe"; 6959 var MAX_URL_DATA_SIZE = 1870; 6960 var SEG_HEADER_SIZE = 30; 6961 var MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE; 6962 var KEEPALIVE_REQUEST_INTERVAL = 25e3; 6963 var LP_CONNECT_TIMEOUT = 3e4; 6964 var BrowserPollConnection = class { 6965 constructor(connId, repoInfo, applicationId, appCheckToken, authToken, transportSessionId, lastSessionId) { 6966 this.connId = connId; 6967 this.repoInfo = repoInfo; 6968 this.applicationId = applicationId; 6969 this.appCheckToken = appCheckToken; 6970 this.authToken = authToken; 6971 this.transportSessionId = transportSessionId; 6972 this.lastSessionId = lastSessionId; 6973 this.bytesSent = 0; 6974 this.bytesReceived = 0; 6975 this.everConnected_ = false; 6976 this.log_ = logWrapper(connId); 6977 this.stats_ = statsManagerGetCollection(repoInfo); 6978 this.urlFn = (params) => { 6979 if (this.appCheckToken) { 6980 params[APP_CHECK_TOKEN_PARAM] = this.appCheckToken; 6981 } 6982 return repoInfoConnectionURL(repoInfo, LONG_POLLING, params); 6983 }; 6984 } 6985 open(onMessage, onDisconnect) { 6986 this.curSegmentNum = 0; 6987 this.onDisconnect_ = onDisconnect; 6988 this.myPacketOrderer = new PacketReceiver(onMessage); 6989 this.isClosed_ = false; 6990 this.connectTimeoutTimer_ = setTimeout(() => { 6991 this.log_("Timed out trying to connect."); 6992 this.onClosed_(); 6993 this.connectTimeoutTimer_ = null; 6994 }, Math.floor(LP_CONNECT_TIMEOUT)); 6995 executeWhenDOMReady(() => { 6996 if (this.isClosed_) { 6997 return; 6998 } 6999 this.scriptTagHolder = new FirebaseIFrameScriptHolder((...args) => { 7000 const [command, arg1, arg2, arg3, arg4] = args; 7001 this.incrementIncomingBytes_(args); 7002 if (!this.scriptTagHolder) { 7003 return; 7004 } 7005 if (this.connectTimeoutTimer_) { 7006 clearTimeout(this.connectTimeoutTimer_); 7007 this.connectTimeoutTimer_ = null; 7008 } 7009 this.everConnected_ = true; 7010 if (command === FIREBASE_LONGPOLL_START_PARAM) { 7011 this.id = arg1; 7012 this.password = arg2; 7013 } else if (command === FIREBASE_LONGPOLL_CLOSE_COMMAND) { 7014 if (arg1) { 7015 this.scriptTagHolder.sendNewPolls = false; 7016 this.myPacketOrderer.closeAfter(arg1, () => { 7017 this.onClosed_(); 7018 }); 7019 } else { 7020 this.onClosed_(); 7021 } 7022 } else { 7023 throw new Error("Unrecognized command received: " + command); 7024 } 7025 }, (...args) => { 7026 const [pN, data] = args; 7027 this.incrementIncomingBytes_(args); 7028 this.myPacketOrderer.handleResponse(pN, data); 7029 }, () => { 7030 this.onClosed_(); 7031 }, this.urlFn); 7032 const urlParams = {}; 7033 urlParams[FIREBASE_LONGPOLL_START_PARAM] = "t"; 7034 urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(Math.random() * 1e8); 7035 if (this.scriptTagHolder.uniqueCallbackIdentifier) { 7036 urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] = this.scriptTagHolder.uniqueCallbackIdentifier; 7037 } 7038 urlParams[VERSION_PARAM] = PROTOCOL_VERSION; 7039 if (this.transportSessionId) { 7040 urlParams[TRANSPORT_SESSION_PARAM] = this.transportSessionId; 7041 } 7042 if (this.lastSessionId) { 7043 urlParams[LAST_SESSION_PARAM] = this.lastSessionId; 7044 } 7045 if (this.applicationId) { 7046 urlParams[APPLICATION_ID_PARAM] = this.applicationId; 7047 } 7048 if (this.appCheckToken) { 7049 urlParams[APP_CHECK_TOKEN_PARAM] = this.appCheckToken; 7050 } 7051 if (typeof location !== "undefined" && location.hostname && FORGE_DOMAIN_RE.test(location.hostname)) { 7052 urlParams[REFERER_PARAM] = FORGE_REF; 7053 } 7054 const connectURL = this.urlFn(urlParams); 7055 this.log_("Connecting via long-poll to " + connectURL); 7056 this.scriptTagHolder.addTag(connectURL, () => { 7057 }); 7058 }); 7059 } 7060 start() { 7061 this.scriptTagHolder.startLongPoll(this.id, this.password); 7062 this.addDisconnectPingFrame(this.id, this.password); 7063 } 7064 static forceAllow() { 7065 BrowserPollConnection.forceAllow_ = true; 7066 } 7067 static forceDisallow() { 7068 BrowserPollConnection.forceDisallow_ = true; 7069 } 7070 static isAvailable() { 7071 if (isNodeSdk()) { 7072 return false; 7073 } else if (BrowserPollConnection.forceAllow_) { 7074 return true; 7075 } else { 7076 return !BrowserPollConnection.forceDisallow_ && typeof document !== "undefined" && document.createElement != null && !isChromeExtensionContentScript() && !isWindowsStoreApp(); 7077 } 7078 } 7079 markConnectionHealthy() { 7080 } 7081 shutdown_() { 7082 this.isClosed_ = true; 7083 if (this.scriptTagHolder) { 7084 this.scriptTagHolder.close(); 7085 this.scriptTagHolder = null; 7086 } 7087 if (this.myDisconnFrame) { 7088 document.body.removeChild(this.myDisconnFrame); 7089 this.myDisconnFrame = null; 7090 } 7091 if (this.connectTimeoutTimer_) { 7092 clearTimeout(this.connectTimeoutTimer_); 7093 this.connectTimeoutTimer_ = null; 7094 } 7095 } 7096 onClosed_() { 7097 if (!this.isClosed_) { 7098 this.log_("Longpoll is closing itself"); 7099 this.shutdown_(); 7100 if (this.onDisconnect_) { 7101 this.onDisconnect_(this.everConnected_); 7102 this.onDisconnect_ = null; 7103 } 7104 } 7105 } 7106 close() { 7107 if (!this.isClosed_) { 7108 this.log_("Longpoll is being closed."); 7109 this.shutdown_(); 7110 } 7111 } 7112 send(data) { 7113 const dataStr = stringify(data); 7114 this.bytesSent += dataStr.length; 7115 this.stats_.incrementCounter("bytes_sent", dataStr.length); 7116 const base64data = base64Encode(dataStr); 7117 const dataSegs = splitStringBySize(base64data, MAX_PAYLOAD_SIZE); 7118 for (let i = 0; i < dataSegs.length; i++) { 7119 this.scriptTagHolder.enqueueSegment(this.curSegmentNum, dataSegs.length, dataSegs[i]); 7120 this.curSegmentNum++; 7121 } 7122 } 7123 addDisconnectPingFrame(id, pw) { 7124 if (isNodeSdk()) { 7125 return; 7126 } 7127 this.myDisconnFrame = document.createElement("iframe"); 7128 const urlParams = {}; 7129 urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM] = "t"; 7130 urlParams[FIREBASE_LONGPOLL_ID_PARAM] = id; 7131 urlParams[FIREBASE_LONGPOLL_PW_PARAM] = pw; 7132 this.myDisconnFrame.src = this.urlFn(urlParams); 7133 this.myDisconnFrame.style.display = "none"; 7134 document.body.appendChild(this.myDisconnFrame); 7135 } 7136 incrementIncomingBytes_(args) { 7137 const bytesReceived = stringify(args).length; 7138 this.bytesReceived += bytesReceived; 7139 this.stats_.incrementCounter("bytes_received", bytesReceived); 7140 } 7141 }; 7142 var FirebaseIFrameScriptHolder = class { 7143 constructor(commandCB, onMessageCB, onDisconnect, urlFn) { 7144 this.onDisconnect = onDisconnect; 7145 this.urlFn = urlFn; 7146 this.outstandingRequests = /* @__PURE__ */ new Set(); 7147 this.pendingSegs = []; 7148 this.currentSerial = Math.floor(Math.random() * 1e8); 7149 this.sendNewPolls = true; 7150 if (!isNodeSdk()) { 7151 this.uniqueCallbackIdentifier = LUIDGenerator(); 7152 window[FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier] = commandCB; 7153 window[FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier] = onMessageCB; 7154 this.myIFrame = FirebaseIFrameScriptHolder.createIFrame_(); 7155 let script = ""; 7156 if (this.myIFrame.src && this.myIFrame.src.substr(0, "javascript:".length) === "javascript:") { 7157 const currentDomain = document.domain; 7158 script = '<script>document.domain="' + currentDomain + '";<\/script>'; 7159 } 7160 const iframeContents = "<html><body>" + script + "</body></html>"; 7161 try { 7162 this.myIFrame.doc.open(); 7163 this.myIFrame.doc.write(iframeContents); 7164 this.myIFrame.doc.close(); 7165 } catch (e) { 7166 log("frame writing exception"); 7167 if (e.stack) { 7168 log(e.stack); 7169 } 7170 log(e); 7171 } 7172 } else { 7173 this.commandCB = commandCB; 7174 this.onMessageCB = onMessageCB; 7175 } 7176 } 7177 static createIFrame_() { 7178 const iframe = document.createElement("iframe"); 7179 iframe.style.display = "none"; 7180 if (document.body) { 7181 document.body.appendChild(iframe); 7182 try { 7183 const a = iframe.contentWindow.document; 7184 if (!a) { 7185 log("No IE domain setting required"); 7186 } 7187 } catch (e) { 7188 const domain = document.domain; 7189 iframe.src = "javascript:void((function(){document.open();document.domain='" + domain + "';document.close();})())"; 7190 } 7191 } else { 7192 throw "Document body has not initialized. Wait to initialize Firebase until after the document is ready."; 7193 } 7194 if (iframe.contentDocument) { 7195 iframe.doc = iframe.contentDocument; 7196 } else if (iframe.contentWindow) { 7197 iframe.doc = iframe.contentWindow.document; 7198 } else if (iframe.document) { 7199 iframe.doc = iframe.document; 7200 } 7201 return iframe; 7202 } 7203 close() { 7204 this.alive = false; 7205 if (this.myIFrame) { 7206 this.myIFrame.doc.body.innerHTML = ""; 7207 setTimeout(() => { 7208 if (this.myIFrame !== null) { 7209 document.body.removeChild(this.myIFrame); 7210 this.myIFrame = null; 7211 } 7212 }, Math.floor(0)); 7213 } 7214 const onDisconnect = this.onDisconnect; 7215 if (onDisconnect) { 7216 this.onDisconnect = null; 7217 onDisconnect(); 7218 } 7219 } 7220 startLongPoll(id, pw) { 7221 this.myID = id; 7222 this.myPW = pw; 7223 this.alive = true; 7224 while (this.newRequest_()) { 7225 } 7226 } 7227 newRequest_() { 7228 if (this.alive && this.sendNewPolls && this.outstandingRequests.size < (this.pendingSegs.length > 0 ? 2 : 1)) { 7229 this.currentSerial++; 7230 const urlParams = {}; 7231 urlParams[FIREBASE_LONGPOLL_ID_PARAM] = this.myID; 7232 urlParams[FIREBASE_LONGPOLL_PW_PARAM] = this.myPW; 7233 urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = this.currentSerial; 7234 let theURL = this.urlFn(urlParams); 7235 let curDataString = ""; 7236 let i = 0; 7237 while (this.pendingSegs.length > 0) { 7238 const nextSeg = this.pendingSegs[0]; 7239 if (nextSeg.d.length + SEG_HEADER_SIZE + curDataString.length <= MAX_URL_DATA_SIZE) { 7240 const theSeg = this.pendingSegs.shift(); 7241 curDataString = curDataString + "&" + FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM + i + "=" + theSeg.seg + "&" + FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET + i + "=" + theSeg.ts + "&" + FIREBASE_LONGPOLL_DATA_PARAM + i + "=" + theSeg.d; 7242 i++; 7243 } else { 7244 break; 7245 } 7246 } 7247 theURL = theURL + curDataString; 7248 this.addLongPollTag_(theURL, this.currentSerial); 7249 return true; 7250 } else { 7251 return false; 7252 } 7253 } 7254 enqueueSegment(segnum, totalsegs, data) { 7255 this.pendingSegs.push({ seg: segnum, ts: totalsegs, d: data }); 7256 if (this.alive) { 7257 this.newRequest_(); 7258 } 7259 } 7260 addLongPollTag_(url, serial) { 7261 this.outstandingRequests.add(serial); 7262 const doNewRequest = () => { 7263 this.outstandingRequests.delete(serial); 7264 this.newRequest_(); 7265 }; 7266 const keepaliveTimeout = setTimeout(doNewRequest, Math.floor(KEEPALIVE_REQUEST_INTERVAL)); 7267 const readyStateCB = () => { 7268 clearTimeout(keepaliveTimeout); 7269 doNewRequest(); 7270 }; 7271 this.addTag(url, readyStateCB); 7272 } 7273 addTag(url, loadCB) { 7274 if (isNodeSdk()) { 7275 this.doNodeLongPoll(url, loadCB); 7276 } else { 7277 setTimeout(() => { 7278 try { 7279 if (!this.sendNewPolls) { 7280 return; 7281 } 7282 const newScript = this.myIFrame.doc.createElement("script"); 7283 newScript.type = "text/javascript"; 7284 newScript.async = true; 7285 newScript.src = url; 7286 newScript.onload = newScript.onreadystatechange = function() { 7287 const rstate = newScript.readyState; 7288 if (!rstate || rstate === "loaded" || rstate === "complete") { 7289 newScript.onload = newScript.onreadystatechange = null; 7290 if (newScript.parentNode) { 7291 newScript.parentNode.removeChild(newScript); 7292 } 7293 loadCB(); 7294 } 7295 }; 7296 newScript.onerror = () => { 7297 log("Long-poll script failed to load: " + url); 7298 this.sendNewPolls = false; 7299 this.close(); 7300 }; 7301 this.myIFrame.doc.body.appendChild(newScript); 7302 } catch (e) { 7303 } 7304 }, Math.floor(1)); 7305 } 7306 } 7307 }; 7308 var WEBSOCKET_MAX_FRAME_SIZE = 16384; 7309 var WEBSOCKET_KEEPALIVE_INTERVAL = 45e3; 7310 var WebSocketImpl = null; 7311 if (typeof MozWebSocket !== "undefined") { 7312 WebSocketImpl = MozWebSocket; 7313 } else if (typeof WebSocket !== "undefined") { 7314 WebSocketImpl = WebSocket; 7315 } 7316 var WebSocketConnection = class { 7317 constructor(connId, repoInfo, applicationId, appCheckToken, authToken, transportSessionId, lastSessionId) { 7318 this.connId = connId; 7319 this.applicationId = applicationId; 7320 this.appCheckToken = appCheckToken; 7321 this.authToken = authToken; 7322 this.keepaliveTimer = null; 7323 this.frames = null; 7324 this.totalFrames = 0; 7325 this.bytesSent = 0; 7326 this.bytesReceived = 0; 7327 this.log_ = logWrapper(this.connId); 7328 this.stats_ = statsManagerGetCollection(repoInfo); 7329 this.connURL = WebSocketConnection.connectionURL_(repoInfo, transportSessionId, lastSessionId, appCheckToken, applicationId); 7330 this.nodeAdmin = repoInfo.nodeAdmin; 7331 } 7332 static connectionURL_(repoInfo, transportSessionId, lastSessionId, appCheckToken, applicationId) { 7333 const urlParams = {}; 7334 urlParams[VERSION_PARAM] = PROTOCOL_VERSION; 7335 if (!isNodeSdk() && typeof location !== "undefined" && location.hostname && FORGE_DOMAIN_RE.test(location.hostname)) { 7336 urlParams[REFERER_PARAM] = FORGE_REF; 7337 } 7338 if (transportSessionId) { 7339 urlParams[TRANSPORT_SESSION_PARAM] = transportSessionId; 7340 } 7341 if (lastSessionId) { 7342 urlParams[LAST_SESSION_PARAM] = lastSessionId; 7343 } 7344 if (appCheckToken) { 7345 urlParams[APP_CHECK_TOKEN_PARAM] = appCheckToken; 7346 } 7347 if (applicationId) { 7348 urlParams[APPLICATION_ID_PARAM] = applicationId; 7349 } 7350 return repoInfoConnectionURL(repoInfo, WEBSOCKET, urlParams); 7351 } 7352 open(onMessage, onDisconnect) { 7353 this.onDisconnect = onDisconnect; 7354 this.onMessage = onMessage; 7355 this.log_("Websocket connecting to " + this.connURL); 7356 this.everConnected_ = false; 7357 PersistentStorage.set("previous_websocket_failure", true); 7358 try { 7359 let options; 7360 if (isNodeSdk()) { 7361 const device = this.nodeAdmin ? "AdminNode" : "Node"; 7362 options = { 7363 headers: { 7364 "User-Agent": `Firebase/${PROTOCOL_VERSION}/${SDK_VERSION2}/${process.platform}/${device}`, 7365 "X-Firebase-GMPID": this.applicationId || "" 7366 } 7367 }; 7368 if (this.authToken) { 7369 options.headers["Authorization"] = `Bearer ${this.authToken}`; 7370 } 7371 if (this.appCheckToken) { 7372 options.headers["X-Firebase-AppCheck"] = this.appCheckToken; 7373 } 7374 const env = process["env"]; 7375 const proxy = this.connURL.indexOf("wss://") === 0 ? env["HTTPS_PROXY"] || env["https_proxy"] : env["HTTP_PROXY"] || env["http_proxy"]; 7376 if (proxy) { 7377 options["proxy"] = { origin: proxy }; 7378 } 7379 } 7380 this.mySock = new WebSocketImpl(this.connURL, [], options); 7381 } catch (e) { 7382 this.log_("Error instantiating WebSocket."); 7383 const error2 = e.message || e.data; 7384 if (error2) { 7385 this.log_(error2); 7386 } 7387 this.onClosed_(); 7388 return; 7389 } 7390 this.mySock.onopen = () => { 7391 this.log_("Websocket connected."); 7392 this.everConnected_ = true; 7393 }; 7394 this.mySock.onclose = () => { 7395 this.log_("Websocket connection was disconnected."); 7396 this.mySock = null; 7397 this.onClosed_(); 7398 }; 7399 this.mySock.onmessage = (m) => { 7400 this.handleIncomingFrame(m); 7401 }; 7402 this.mySock.onerror = (e) => { 7403 this.log_("WebSocket error. Closing connection."); 7404 const error2 = e.message || e.data; 7405 if (error2) { 7406 this.log_(error2); 7407 } 7408 this.onClosed_(); 7409 }; 7410 } 7411 start() { 7412 } 7413 static forceDisallow() { 7414 WebSocketConnection.forceDisallow_ = true; 7415 } 7416 static isAvailable() { 7417 let isOldAndroid = false; 7418 if (typeof navigator !== "undefined" && navigator.userAgent) { 7419 const oldAndroidRegex = /Android ([0-9]{0,}\.[0-9]{0,})/; 7420 const oldAndroidMatch = navigator.userAgent.match(oldAndroidRegex); 7421 if (oldAndroidMatch && oldAndroidMatch.length > 1) { 7422 if (parseFloat(oldAndroidMatch[1]) < 4.4) { 7423 isOldAndroid = true; 7424 } 7425 } 7426 } 7427 return !isOldAndroid && WebSocketImpl !== null && !WebSocketConnection.forceDisallow_; 7428 } 7429 static previouslyFailed() { 7430 return PersistentStorage.isInMemoryStorage || PersistentStorage.get("previous_websocket_failure") === true; 7431 } 7432 markConnectionHealthy() { 7433 PersistentStorage.remove("previous_websocket_failure"); 7434 } 7435 appendFrame_(data) { 7436 this.frames.push(data); 7437 if (this.frames.length === this.totalFrames) { 7438 const fullMess = this.frames.join(""); 7439 this.frames = null; 7440 const jsonMess = jsonEval(fullMess); 7441 this.onMessage(jsonMess); 7442 } 7443 } 7444 handleNewFrameCount_(frameCount) { 7445 this.totalFrames = frameCount; 7446 this.frames = []; 7447 } 7448 extractFrameCount_(data) { 7449 assert(this.frames === null, "We already have a frame buffer"); 7450 if (data.length <= 6) { 7451 const frameCount = Number(data); 7452 if (!isNaN(frameCount)) { 7453 this.handleNewFrameCount_(frameCount); 7454 return null; 7455 } 7456 } 7457 this.handleNewFrameCount_(1); 7458 return data; 7459 } 7460 handleIncomingFrame(mess) { 7461 if (this.mySock === null) { 7462 return; 7463 } 7464 const data = mess["data"]; 7465 this.bytesReceived += data.length; 7466 this.stats_.incrementCounter("bytes_received", data.length); 7467 this.resetKeepAlive(); 7468 if (this.frames !== null) { 7469 this.appendFrame_(data); 7470 } else { 7471 const remainingData = this.extractFrameCount_(data); 7472 if (remainingData !== null) { 7473 this.appendFrame_(remainingData); 7474 } 7475 } 7476 } 7477 send(data) { 7478 this.resetKeepAlive(); 7479 const dataStr = stringify(data); 7480 this.bytesSent += dataStr.length; 7481 this.stats_.incrementCounter("bytes_sent", dataStr.length); 7482 const dataSegs = splitStringBySize(dataStr, WEBSOCKET_MAX_FRAME_SIZE); 7483 if (dataSegs.length > 1) { 7484 this.sendString_(String(dataSegs.length)); 7485 } 7486 for (let i = 0; i < dataSegs.length; i++) { 7487 this.sendString_(dataSegs[i]); 7488 } 7489 } 7490 shutdown_() { 7491 this.isClosed_ = true; 7492 if (this.keepaliveTimer) { 7493 clearInterval(this.keepaliveTimer); 7494 this.keepaliveTimer = null; 7495 } 7496 if (this.mySock) { 7497 this.mySock.close(); 7498 this.mySock = null; 7499 } 7500 } 7501 onClosed_() { 7502 if (!this.isClosed_) { 7503 this.log_("WebSocket is closing itself"); 7504 this.shutdown_(); 7505 if (this.onDisconnect) { 7506 this.onDisconnect(this.everConnected_); 7507 this.onDisconnect = null; 7508 } 7509 } 7510 } 7511 close() { 7512 if (!this.isClosed_) { 7513 this.log_("WebSocket is being closed"); 7514 this.shutdown_(); 7515 } 7516 } 7517 resetKeepAlive() { 7518 clearInterval(this.keepaliveTimer); 7519 this.keepaliveTimer = setInterval(() => { 7520 if (this.mySock) { 7521 this.sendString_("0"); 7522 } 7523 this.resetKeepAlive(); 7524 }, Math.floor(WEBSOCKET_KEEPALIVE_INTERVAL)); 7525 } 7526 sendString_(str) { 7527 try { 7528 this.mySock.send(str); 7529 } catch (e) { 7530 this.log_("Exception thrown from WebSocket.send():", e.message || e.data, "Closing connection."); 7531 setTimeout(this.onClosed_.bind(this), 0); 7532 } 7533 } 7534 }; 7535 WebSocketConnection.responsesRequiredToBeHealthy = 2; 7536 WebSocketConnection.healthyTimeout = 3e4; 7537 var TransportManager = class { 7538 constructor(repoInfo) { 7539 this.initTransports_(repoInfo); 7540 } 7541 static get ALL_TRANSPORTS() { 7542 return [BrowserPollConnection, WebSocketConnection]; 7543 } 7544 static get IS_TRANSPORT_INITIALIZED() { 7545 return this.globalTransportInitialized_; 7546 } 7547 initTransports_(repoInfo) { 7548 const isWebSocketsAvailable = WebSocketConnection && WebSocketConnection["isAvailable"](); 7549 let isSkipPollConnection = isWebSocketsAvailable && !WebSocketConnection.previouslyFailed(); 7550 if (repoInfo.webSocketOnly) { 7551 if (!isWebSocketsAvailable) { 7552 warn("wss:// URL used, but browser isn't known to support websockets. Trying anyway."); 7553 } 7554 isSkipPollConnection = true; 7555 } 7556 if (isSkipPollConnection) { 7557 this.transports_ = [WebSocketConnection]; 7558 } else { 7559 const transports = this.transports_ = []; 7560 for (const transport of TransportManager.ALL_TRANSPORTS) { 7561 if (transport && transport["isAvailable"]()) { 7562 transports.push(transport); 7563 } 7564 } 7565 TransportManager.globalTransportInitialized_ = true; 7566 } 7567 } 7568 initialTransport() { 7569 if (this.transports_.length > 0) { 7570 return this.transports_[0]; 7571 } else { 7572 throw new Error("No transports available"); 7573 } 7574 } 7575 upgradeTransport() { 7576 if (this.transports_.length > 1) { 7577 return this.transports_[1]; 7578 } else { 7579 return null; 7580 } 7581 } 7582 }; 7583 TransportManager.globalTransportInitialized_ = false; 7584 var UPGRADE_TIMEOUT = 6e4; 7585 var DELAY_BEFORE_SENDING_EXTRA_REQUESTS = 5e3; 7586 var BYTES_SENT_HEALTHY_OVERRIDE = 10 * 1024; 7587 var BYTES_RECEIVED_HEALTHY_OVERRIDE = 100 * 1024; 7588 var MESSAGE_TYPE = "t"; 7589 var MESSAGE_DATA = "d"; 7590 var CONTROL_SHUTDOWN = "s"; 7591 var CONTROL_RESET = "r"; 7592 var CONTROL_ERROR = "e"; 7593 var CONTROL_PONG = "o"; 7594 var SWITCH_ACK = "a"; 7595 var END_TRANSMISSION = "n"; 7596 var PING = "p"; 7597 var SERVER_HELLO = "h"; 7598 var Connection = class { 7599 constructor(id, repoInfo_, applicationId_, appCheckToken_, authToken_, onMessage_, onReady_, onDisconnect_, onKill_, lastSessionId) { 7600 this.id = id; 7601 this.repoInfo_ = repoInfo_; 7602 this.applicationId_ = applicationId_; 7603 this.appCheckToken_ = appCheckToken_; 7604 this.authToken_ = authToken_; 7605 this.onMessage_ = onMessage_; 7606 this.onReady_ = onReady_; 7607 this.onDisconnect_ = onDisconnect_; 7608 this.onKill_ = onKill_; 7609 this.lastSessionId = lastSessionId; 7610 this.connectionCount = 0; 7611 this.pendingDataMessages = []; 7612 this.state_ = 0; 7613 this.log_ = logWrapper("c:" + this.id + ":"); 7614 this.transportManager_ = new TransportManager(repoInfo_); 7615 this.log_("Connection created"); 7616 this.start_(); 7617 } 7618 start_() { 7619 const conn = this.transportManager_.initialTransport(); 7620 this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_, this.applicationId_, this.appCheckToken_, this.authToken_, null, this.lastSessionId); 7621 this.primaryResponsesRequired_ = conn["responsesRequiredToBeHealthy"] || 0; 7622 const onMessageReceived = this.connReceiver_(this.conn_); 7623 const onConnectionLost = this.disconnReceiver_(this.conn_); 7624 this.tx_ = this.conn_; 7625 this.rx_ = this.conn_; 7626 this.secondaryConn_ = null; 7627 this.isHealthy_ = false; 7628 setTimeout(() => { 7629 this.conn_ && this.conn_.open(onMessageReceived, onConnectionLost); 7630 }, Math.floor(0)); 7631 const healthyTimeoutMS = conn["healthyTimeout"] || 0; 7632 if (healthyTimeoutMS > 0) { 7633 this.healthyTimeout_ = setTimeoutNonBlocking(() => { 7634 this.healthyTimeout_ = null; 7635 if (!this.isHealthy_) { 7636 if (this.conn_ && this.conn_.bytesReceived > BYTES_RECEIVED_HEALTHY_OVERRIDE) { 7637 this.log_("Connection exceeded healthy timeout but has received " + this.conn_.bytesReceived + " bytes. Marking connection healthy."); 7638 this.isHealthy_ = true; 7639 this.conn_.markConnectionHealthy(); 7640 } else if (this.conn_ && this.conn_.bytesSent > BYTES_SENT_HEALTHY_OVERRIDE) { 7641 this.log_("Connection exceeded healthy timeout but has sent " + this.conn_.bytesSent + " bytes. Leaving connection alive."); 7642 } else { 7643 this.log_("Closing unhealthy connection after timeout."); 7644 this.close(); 7645 } 7646 } 7647 }, Math.floor(healthyTimeoutMS)); 7648 } 7649 } 7650 nextTransportId_() { 7651 return "c:" + this.id + ":" + this.connectionCount++; 7652 } 7653 disconnReceiver_(conn) { 7654 return (everConnected) => { 7655 if (conn === this.conn_) { 7656 this.onConnectionLost_(everConnected); 7657 } else if (conn === this.secondaryConn_) { 7658 this.log_("Secondary connection lost."); 7659 this.onSecondaryConnectionLost_(); 7660 } else { 7661 this.log_("closing an old connection"); 7662 } 7663 }; 7664 } 7665 connReceiver_(conn) { 7666 return (message) => { 7667 if (this.state_ !== 2) { 7668 if (conn === this.rx_) { 7669 this.onPrimaryMessageReceived_(message); 7670 } else if (conn === this.secondaryConn_) { 7671 this.onSecondaryMessageReceived_(message); 7672 } else { 7673 this.log_("message on old connection"); 7674 } 7675 } 7676 }; 7677 } 7678 sendRequest(dataMsg) { 7679 const msg = { t: "d", d: dataMsg }; 7680 this.sendData_(msg); 7681 } 7682 tryCleanupConnection() { 7683 if (this.tx_ === this.secondaryConn_ && this.rx_ === this.secondaryConn_) { 7684 this.log_("cleaning up and promoting a connection: " + this.secondaryConn_.connId); 7685 this.conn_ = this.secondaryConn_; 7686 this.secondaryConn_ = null; 7687 } 7688 } 7689 onSecondaryControl_(controlData) { 7690 if (MESSAGE_TYPE in controlData) { 7691 const cmd = controlData[MESSAGE_TYPE]; 7692 if (cmd === SWITCH_ACK) { 7693 this.upgradeIfSecondaryHealthy_(); 7694 } else if (cmd === CONTROL_RESET) { 7695 this.log_("Got a reset on secondary, closing it"); 7696 this.secondaryConn_.close(); 7697 if (this.tx_ === this.secondaryConn_ || this.rx_ === this.secondaryConn_) { 7698 this.close(); 7699 } 7700 } else if (cmd === CONTROL_PONG) { 7701 this.log_("got pong on secondary."); 7702 this.secondaryResponsesRequired_--; 7703 this.upgradeIfSecondaryHealthy_(); 7704 } 7705 } 7706 } 7707 onSecondaryMessageReceived_(parsedData) { 7708 const layer = requireKey("t", parsedData); 7709 const data = requireKey("d", parsedData); 7710 if (layer === "c") { 7711 this.onSecondaryControl_(data); 7712 } else if (layer === "d") { 7713 this.pendingDataMessages.push(data); 7714 } else { 7715 throw new Error("Unknown protocol layer: " + layer); 7716 } 7717 } 7718 upgradeIfSecondaryHealthy_() { 7719 if (this.secondaryResponsesRequired_ <= 0) { 7720 this.log_("Secondary connection is healthy."); 7721 this.isHealthy_ = true; 7722 this.secondaryConn_.markConnectionHealthy(); 7723 this.proceedWithUpgrade_(); 7724 } else { 7725 this.log_("sending ping on secondary."); 7726 this.secondaryConn_.send({ t: "c", d: { t: PING, d: {} } }); 7727 } 7728 } 7729 proceedWithUpgrade_() { 7730 this.secondaryConn_.start(); 7731 this.log_("sending client ack on secondary"); 7732 this.secondaryConn_.send({ t: "c", d: { t: SWITCH_ACK, d: {} } }); 7733 this.log_("Ending transmission on primary"); 7734 this.conn_.send({ t: "c", d: { t: END_TRANSMISSION, d: {} } }); 7735 this.tx_ = this.secondaryConn_; 7736 this.tryCleanupConnection(); 7737 } 7738 onPrimaryMessageReceived_(parsedData) { 7739 const layer = requireKey("t", parsedData); 7740 const data = requireKey("d", parsedData); 7741 if (layer === "c") { 7742 this.onControl_(data); 7743 } else if (layer === "d") { 7744 this.onDataMessage_(data); 7745 } 7746 } 7747 onDataMessage_(message) { 7748 this.onPrimaryResponse_(); 7749 this.onMessage_(message); 7750 } 7751 onPrimaryResponse_() { 7752 if (!this.isHealthy_) { 7753 this.primaryResponsesRequired_--; 7754 if (this.primaryResponsesRequired_ <= 0) { 7755 this.log_("Primary connection is healthy."); 7756 this.isHealthy_ = true; 7757 this.conn_.markConnectionHealthy(); 7758 } 7759 } 7760 } 7761 onControl_(controlData) { 7762 const cmd = requireKey(MESSAGE_TYPE, controlData); 7763 if (MESSAGE_DATA in controlData) { 7764 const payload = controlData[MESSAGE_DATA]; 7765 if (cmd === SERVER_HELLO) { 7766 this.onHandshake_(payload); 7767 } else if (cmd === END_TRANSMISSION) { 7768 this.log_("recvd end transmission on primary"); 7769 this.rx_ = this.secondaryConn_; 7770 for (let i = 0; i < this.pendingDataMessages.length; ++i) { 7771 this.onDataMessage_(this.pendingDataMessages[i]); 7772 } 7773 this.pendingDataMessages = []; 7774 this.tryCleanupConnection(); 7775 } else if (cmd === CONTROL_SHUTDOWN) { 7776 this.onConnectionShutdown_(payload); 7777 } else if (cmd === CONTROL_RESET) { 7778 this.onReset_(payload); 7779 } else if (cmd === CONTROL_ERROR) { 7780 error("Server Error: " + payload); 7781 } else if (cmd === CONTROL_PONG) { 7782 this.log_("got pong on primary."); 7783 this.onPrimaryResponse_(); 7784 this.sendPingOnPrimaryIfNecessary_(); 7785 } else { 7786 error("Unknown control packet command: " + cmd); 7787 } 7788 } 7789 } 7790 onHandshake_(handshake) { 7791 const timestamp = handshake.ts; 7792 const version7 = handshake.v; 7793 const host = handshake.h; 7794 this.sessionId = handshake.s; 7795 this.repoInfo_.host = host; 7796 if (this.state_ === 0) { 7797 this.conn_.start(); 7798 this.onConnectionEstablished_(this.conn_, timestamp); 7799 if (PROTOCOL_VERSION !== version7) { 7800 warn("Protocol version mismatch detected"); 7801 } 7802 this.tryStartUpgrade_(); 7803 } 7804 } 7805 tryStartUpgrade_() { 7806 const conn = this.transportManager_.upgradeTransport(); 7807 if (conn) { 7808 this.startUpgrade_(conn); 7809 } 7810 } 7811 startUpgrade_(conn) { 7812 this.secondaryConn_ = new conn(this.nextTransportId_(), this.repoInfo_, this.applicationId_, this.appCheckToken_, this.authToken_, this.sessionId); 7813 this.secondaryResponsesRequired_ = conn["responsesRequiredToBeHealthy"] || 0; 7814 const onMessage = this.connReceiver_(this.secondaryConn_); 7815 const onDisconnect = this.disconnReceiver_(this.secondaryConn_); 7816 this.secondaryConn_.open(onMessage, onDisconnect); 7817 setTimeoutNonBlocking(() => { 7818 if (this.secondaryConn_) { 7819 this.log_("Timed out trying to upgrade."); 7820 this.secondaryConn_.close(); 7821 } 7822 }, Math.floor(UPGRADE_TIMEOUT)); 7823 } 7824 onReset_(host) { 7825 this.log_("Reset packet received. New host: " + host); 7826 this.repoInfo_.host = host; 7827 if (this.state_ === 1) { 7828 this.close(); 7829 } else { 7830 this.closeConnections_(); 7831 this.start_(); 7832 } 7833 } 7834 onConnectionEstablished_(conn, timestamp) { 7835 this.log_("Realtime connection established."); 7836 this.conn_ = conn; 7837 this.state_ = 1; 7838 if (this.onReady_) { 7839 this.onReady_(timestamp, this.sessionId); 7840 this.onReady_ = null; 7841 } 7842 if (this.primaryResponsesRequired_ === 0) { 7843 this.log_("Primary connection is healthy."); 7844 this.isHealthy_ = true; 7845 } else { 7846 setTimeoutNonBlocking(() => { 7847 this.sendPingOnPrimaryIfNecessary_(); 7848 }, Math.floor(DELAY_BEFORE_SENDING_EXTRA_REQUESTS)); 7849 } 7850 } 7851 sendPingOnPrimaryIfNecessary_() { 7852 if (!this.isHealthy_ && this.state_ === 1) { 7853 this.log_("sending ping on primary."); 7854 this.sendData_({ t: "c", d: { t: PING, d: {} } }); 7855 } 7856 } 7857 onSecondaryConnectionLost_() { 7858 const conn = this.secondaryConn_; 7859 this.secondaryConn_ = null; 7860 if (this.tx_ === conn || this.rx_ === conn) { 7861 this.close(); 7862 } 7863 } 7864 onConnectionLost_(everConnected) { 7865 this.conn_ = null; 7866 if (!everConnected && this.state_ === 0) { 7867 this.log_("Realtime connection failed."); 7868 if (this.repoInfo_.isCacheableHost()) { 7869 PersistentStorage.remove("host:" + this.repoInfo_.host); 7870 this.repoInfo_.internalHost = this.repoInfo_.host; 7871 } 7872 } else if (this.state_ === 1) { 7873 this.log_("Realtime connection lost."); 7874 } 7875 this.close(); 7876 } 7877 onConnectionShutdown_(reason) { 7878 this.log_("Connection shutdown command received. Shutting down..."); 7879 if (this.onKill_) { 7880 this.onKill_(reason); 7881 this.onKill_ = null; 7882 } 7883 this.onDisconnect_ = null; 7884 this.close(); 7885 } 7886 sendData_(data) { 7887 if (this.state_ !== 1) { 7888 throw "Connection is not connected"; 7889 } else { 7890 this.tx_.send(data); 7891 } 7892 } 7893 close() { 7894 if (this.state_ !== 2) { 7895 this.log_("Closing realtime connection."); 7896 this.state_ = 2; 7897 this.closeConnections_(); 7898 if (this.onDisconnect_) { 7899 this.onDisconnect_(); 7900 this.onDisconnect_ = null; 7901 } 7902 } 7903 } 7904 closeConnections_() { 7905 this.log_("Shutting down all connections"); 7906 if (this.conn_) { 7907 this.conn_.close(); 7908 this.conn_ = null; 7909 } 7910 if (this.secondaryConn_) { 7911 this.secondaryConn_.close(); 7912 this.secondaryConn_ = null; 7913 } 7914 if (this.healthyTimeout_) { 7915 clearTimeout(this.healthyTimeout_); 7916 this.healthyTimeout_ = null; 7917 } 7918 } 7919 }; 7920 var ServerActions = class { 7921 put(pathString, data, onComplete, hash) { 7922 } 7923 merge(pathString, data, onComplete, hash) { 7924 } 7925 refreshAuthToken(token) { 7926 } 7927 refreshAppCheckToken(token) { 7928 } 7929 onDisconnectPut(pathString, data, onComplete) { 7930 } 7931 onDisconnectMerge(pathString, data, onComplete) { 7932 } 7933 onDisconnectCancel(pathString, onComplete) { 7934 } 7935 reportStats(stats) { 7936 } 7937 }; 7938 var EventEmitter = class { 7939 constructor(allowedEvents_) { 7940 this.allowedEvents_ = allowedEvents_; 7941 this.listeners_ = {}; 7942 assert(Array.isArray(allowedEvents_) && allowedEvents_.length > 0, "Requires a non-empty array"); 7943 } 7944 trigger(eventType, ...varArgs) { 7945 if (Array.isArray(this.listeners_[eventType])) { 7946 const listeners = [...this.listeners_[eventType]]; 7947 for (let i = 0; i < listeners.length; i++) { 7948 listeners[i].callback.apply(listeners[i].context, varArgs); 7949 } 7950 } 7951 } 7952 on(eventType, callback, context) { 7953 this.validateEventType_(eventType); 7954 this.listeners_[eventType] = this.listeners_[eventType] || []; 7955 this.listeners_[eventType].push({ callback, context }); 7956 const eventData = this.getInitialEvent(eventType); 7957 if (eventData) { 7958 callback.apply(context, eventData); 7959 } 7960 } 7961 off(eventType, callback, context) { 7962 this.validateEventType_(eventType); 7963 const listeners = this.listeners_[eventType] || []; 7964 for (let i = 0; i < listeners.length; i++) { 7965 if (listeners[i].callback === callback && (!context || context === listeners[i].context)) { 7966 listeners.splice(i, 1); 7967 return; 7968 } 7969 } 7970 } 7971 validateEventType_(eventType) { 7972 assert(this.allowedEvents_.find((et) => { 7973 return et === eventType; 7974 }), "Unknown event: " + eventType); 7975 } 7976 }; 7977 var OnlineMonitor = class extends EventEmitter { 7978 constructor() { 7979 super(["online"]); 7980 this.online_ = true; 7981 if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined" && !isMobileCordova()) { 7982 window.addEventListener("online", () => { 7983 if (!this.online_) { 7984 this.online_ = true; 7985 this.trigger("online", true); 7986 } 7987 }, false); 7988 window.addEventListener("offline", () => { 7989 if (this.online_) { 7990 this.online_ = false; 7991 this.trigger("online", false); 7992 } 7993 }, false); 7994 } 7995 } 7996 static getInstance() { 7997 return new OnlineMonitor(); 7998 } 7999 getInitialEvent(eventType) { 8000 assert(eventType === "online", "Unknown event type: " + eventType); 8001 return [this.online_]; 8002 } 8003 currentlyOnline() { 8004 return this.online_; 8005 } 8006 }; 8007 var MAX_PATH_DEPTH = 32; 8008 var MAX_PATH_LENGTH_BYTES = 768; 8009 var Path = class { 8010 constructor(pathOrString, pieceNum) { 8011 if (pieceNum === void 0) { 8012 this.pieces_ = pathOrString.split("/"); 8013 let copyTo = 0; 8014 for (let i = 0; i < this.pieces_.length; i++) { 8015 if (this.pieces_[i].length > 0) { 8016 this.pieces_[copyTo] = this.pieces_[i]; 8017 copyTo++; 8018 } 8019 } 8020 this.pieces_.length = copyTo; 8021 this.pieceNum_ = 0; 8022 } else { 8023 this.pieces_ = pathOrString; 8024 this.pieceNum_ = pieceNum; 8025 } 8026 } 8027 toString() { 8028 let pathString = ""; 8029 for (let i = this.pieceNum_; i < this.pieces_.length; i++) { 8030 if (this.pieces_[i] !== "") { 8031 pathString += "/" + this.pieces_[i]; 8032 } 8033 } 8034 return pathString || "/"; 8035 } 8036 }; 8037 function newEmptyPath() { 8038 return new Path(""); 8039 } 8040 function pathGetFront(path) { 8041 if (path.pieceNum_ >= path.pieces_.length) { 8042 return null; 8043 } 8044 return path.pieces_[path.pieceNum_]; 8045 } 8046 function pathGetLength(path) { 8047 return path.pieces_.length - path.pieceNum_; 8048 } 8049 function pathPopFront(path) { 8050 let pieceNum = path.pieceNum_; 8051 if (pieceNum < path.pieces_.length) { 8052 pieceNum++; 8053 } 8054 return new Path(path.pieces_, pieceNum); 8055 } 8056 function pathGetBack(path) { 8057 if (path.pieceNum_ < path.pieces_.length) { 8058 return path.pieces_[path.pieces_.length - 1]; 8059 } 8060 return null; 8061 } 8062 function pathToUrlEncodedString(path) { 8063 let pathString = ""; 8064 for (let i = path.pieceNum_; i < path.pieces_.length; i++) { 8065 if (path.pieces_[i] !== "") { 8066 pathString += "/" + encodeURIComponent(String(path.pieces_[i])); 8067 } 8068 } 8069 return pathString || "/"; 8070 } 8071 function pathSlice(path, begin = 0) { 8072 return path.pieces_.slice(path.pieceNum_ + begin); 8073 } 8074 function pathParent(path) { 8075 if (path.pieceNum_ >= path.pieces_.length) { 8076 return null; 8077 } 8078 const pieces = []; 8079 for (let i = path.pieceNum_; i < path.pieces_.length - 1; i++) { 8080 pieces.push(path.pieces_[i]); 8081 } 8082 return new Path(pieces, 0); 8083 } 8084 function pathChild(path, childPathObj) { 8085 const pieces = []; 8086 for (let i = path.pieceNum_; i < path.pieces_.length; i++) { 8087 pieces.push(path.pieces_[i]); 8088 } 8089 if (childPathObj instanceof Path) { 8090 for (let i = childPathObj.pieceNum_; i < childPathObj.pieces_.length; i++) { 8091 pieces.push(childPathObj.pieces_[i]); 8092 } 8093 } else { 8094 const childPieces = childPathObj.split("/"); 8095 for (let i = 0; i < childPieces.length; i++) { 8096 if (childPieces[i].length > 0) { 8097 pieces.push(childPieces[i]); 8098 } 8099 } 8100 } 8101 return new Path(pieces, 0); 8102 } 8103 function pathIsEmpty(path) { 8104 return path.pieceNum_ >= path.pieces_.length; 8105 } 8106 function newRelativePath(outerPath, innerPath) { 8107 const outer = pathGetFront(outerPath), inner = pathGetFront(innerPath); 8108 if (outer === null) { 8109 return innerPath; 8110 } else if (outer === inner) { 8111 return newRelativePath(pathPopFront(outerPath), pathPopFront(innerPath)); 8112 } else { 8113 throw new Error("INTERNAL ERROR: innerPath (" + innerPath + ") is not within outerPath (" + outerPath + ")"); 8114 } 8115 } 8116 function pathEquals(path, other) { 8117 if (pathGetLength(path) !== pathGetLength(other)) { 8118 return false; 8119 } 8120 for (let i = path.pieceNum_, j = other.pieceNum_; i <= path.pieces_.length; i++, j++) { 8121 if (path.pieces_[i] !== other.pieces_[j]) { 8122 return false; 8123 } 8124 } 8125 return true; 8126 } 8127 function pathContains(path, other) { 8128 let i = path.pieceNum_; 8129 let j = other.pieceNum_; 8130 if (pathGetLength(path) > pathGetLength(other)) { 8131 return false; 8132 } 8133 while (i < path.pieces_.length) { 8134 if (path.pieces_[i] !== other.pieces_[j]) { 8135 return false; 8136 } 8137 ++i; 8138 ++j; 8139 } 8140 return true; 8141 } 8142 var ValidationPath = class { 8143 constructor(path, errorPrefix_) { 8144 this.errorPrefix_ = errorPrefix_; 8145 this.parts_ = pathSlice(path, 0); 8146 this.byteLength_ = Math.max(1, this.parts_.length); 8147 for (let i = 0; i < this.parts_.length; i++) { 8148 this.byteLength_ += stringLength(this.parts_[i]); 8149 } 8150 validationPathCheckValid(this); 8151 } 8152 }; 8153 function validationPathPush(validationPath, child) { 8154 if (validationPath.parts_.length > 0) { 8155 validationPath.byteLength_ += 1; 8156 } 8157 validationPath.parts_.push(child); 8158 validationPath.byteLength_ += stringLength(child); 8159 validationPathCheckValid(validationPath); 8160 } 8161 function validationPathPop(validationPath) { 8162 const last = validationPath.parts_.pop(); 8163 validationPath.byteLength_ -= stringLength(last); 8164 if (validationPath.parts_.length > 0) { 8165 validationPath.byteLength_ -= 1; 8166 } 8167 } 8168 function validationPathCheckValid(validationPath) { 8169 if (validationPath.byteLength_ > MAX_PATH_LENGTH_BYTES) { 8170 throw new Error(validationPath.errorPrefix_ + "has a key path longer than " + MAX_PATH_LENGTH_BYTES + " bytes (" + validationPath.byteLength_ + ")."); 8171 } 8172 if (validationPath.parts_.length > MAX_PATH_DEPTH) { 8173 throw new Error(validationPath.errorPrefix_ + "path specified exceeds the maximum depth that can be written (" + MAX_PATH_DEPTH + ") or object contains a cycle " + validationPathToErrorString(validationPath)); 8174 } 8175 } 8176 function validationPathToErrorString(validationPath) { 8177 if (validationPath.parts_.length === 0) { 8178 return ""; 8179 } 8180 return "in property '" + validationPath.parts_.join(".") + "'"; 8181 } 8182 var VisibilityMonitor = class extends EventEmitter { 8183 constructor() { 8184 super(["visible"]); 8185 let hidden; 8186 let visibilityChange; 8187 if (typeof document !== "undefined" && typeof document.addEventListener !== "undefined") { 8188 if (typeof document["hidden"] !== "undefined") { 8189 visibilityChange = "visibilitychange"; 8190 hidden = "hidden"; 8191 } else if (typeof document["mozHidden"] !== "undefined") { 8192 visibilityChange = "mozvisibilitychange"; 8193 hidden = "mozHidden"; 8194 } else if (typeof document["msHidden"] !== "undefined") { 8195 visibilityChange = "msvisibilitychange"; 8196 hidden = "msHidden"; 8197 } else if (typeof document["webkitHidden"] !== "undefined") { 8198 visibilityChange = "webkitvisibilitychange"; 8199 hidden = "webkitHidden"; 8200 } 8201 } 8202 this.visible_ = true; 8203 if (visibilityChange) { 8204 document.addEventListener(visibilityChange, () => { 8205 const visible = !document[hidden]; 8206 if (visible !== this.visible_) { 8207 this.visible_ = visible; 8208 this.trigger("visible", visible); 8209 } 8210 }, false); 8211 } 8212 } 8213 static getInstance() { 8214 return new VisibilityMonitor(); 8215 } 8216 getInitialEvent(eventType) { 8217 assert(eventType === "visible", "Unknown event type: " + eventType); 8218 return [this.visible_]; 8219 } 8220 }; 8221 var RECONNECT_MIN_DELAY = 1e3; 8222 var RECONNECT_MAX_DELAY_DEFAULT = 60 * 5 * 1e3; 8223 var RECONNECT_MAX_DELAY_FOR_ADMINS = 30 * 1e3; 8224 var RECONNECT_DELAY_MULTIPLIER = 1.3; 8225 var RECONNECT_DELAY_RESET_TIMEOUT = 3e4; 8226 var SERVER_KILL_INTERRUPT_REASON = "server_kill"; 8227 var INVALID_TOKEN_THRESHOLD = 3; 8228 var PersistentConnection = class extends ServerActions { 8229 constructor(repoInfo_, applicationId_, onDataUpdate_, onConnectStatus_, onServerInfoUpdate_, authTokenProvider_, appCheckTokenProvider_, authOverride_) { 8230 super(); 8231 this.repoInfo_ = repoInfo_; 8232 this.applicationId_ = applicationId_; 8233 this.onDataUpdate_ = onDataUpdate_; 8234 this.onConnectStatus_ = onConnectStatus_; 8235 this.onServerInfoUpdate_ = onServerInfoUpdate_; 8236 this.authTokenProvider_ = authTokenProvider_; 8237 this.appCheckTokenProvider_ = appCheckTokenProvider_; 8238 this.authOverride_ = authOverride_; 8239 this.id = PersistentConnection.nextPersistentConnectionId_++; 8240 this.log_ = logWrapper("p:" + this.id + ":"); 8241 this.interruptReasons_ = {}; 8242 this.listens = /* @__PURE__ */ new Map(); 8243 this.outstandingPuts_ = []; 8244 this.outstandingGets_ = []; 8245 this.outstandingPutCount_ = 0; 8246 this.outstandingGetCount_ = 0; 8247 this.onDisconnectRequestQueue_ = []; 8248 this.connected_ = false; 8249 this.reconnectDelay_ = RECONNECT_MIN_DELAY; 8250 this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_DEFAULT; 8251 this.securityDebugCallback_ = null; 8252 this.lastSessionId = null; 8253 this.establishConnectionTimer_ = null; 8254 this.visible_ = false; 8255 this.requestCBHash_ = {}; 8256 this.requestNumber_ = 0; 8257 this.realtime_ = null; 8258 this.authToken_ = null; 8259 this.appCheckToken_ = null; 8260 this.forceTokenRefresh_ = false; 8261 this.invalidAuthTokenCount_ = 0; 8262 this.invalidAppCheckTokenCount_ = 0; 8263 this.firstConnection_ = true; 8264 this.lastConnectionAttemptTime_ = null; 8265 this.lastConnectionEstablishedTime_ = null; 8266 if (authOverride_ && !isNodeSdk()) { 8267 throw new Error("Auth override specified in options, but not supported on non Node.js platforms"); 8268 } 8269 VisibilityMonitor.getInstance().on("visible", this.onVisible_, this); 8270 if (repoInfo_.host.indexOf("fblocal") === -1) { 8271 OnlineMonitor.getInstance().on("online", this.onOnline_, this); 8272 } 8273 } 8274 sendRequest(action, body, onResponse) { 8275 const curReqNum = ++this.requestNumber_; 8276 const msg = { r: curReqNum, a: action, b: body }; 8277 this.log_(stringify(msg)); 8278 assert(this.connected_, "sendRequest call when we're not connected not allowed."); 8279 this.realtime_.sendRequest(msg); 8280 if (onResponse) { 8281 this.requestCBHash_[curReqNum] = onResponse; 8282 } 8283 } 8284 get(query) { 8285 this.initConnection_(); 8286 const deferred = new Deferred(); 8287 const request = { 8288 p: query._path.toString(), 8289 q: query._queryObject 8290 }; 8291 const outstandingGet = { 8292 action: "g", 8293 request, 8294 onComplete: (message) => { 8295 const payload = message["d"]; 8296 if (message["s"] === "ok") { 8297 deferred.resolve(payload); 8298 } else { 8299 deferred.reject(payload); 8300 } 8301 } 8302 }; 8303 this.outstandingGets_.push(outstandingGet); 8304 this.outstandingGetCount_++; 8305 const index = this.outstandingGets_.length - 1; 8306 if (this.connected_) { 8307 this.sendGet_(index); 8308 } 8309 return deferred.promise; 8310 } 8311 listen(query, currentHashFn, tag, onComplete) { 8312 this.initConnection_(); 8313 const queryId = query._queryIdentifier; 8314 const pathString = query._path.toString(); 8315 this.log_("Listen called for " + pathString + " " + queryId); 8316 if (!this.listens.has(pathString)) { 8317 this.listens.set(pathString, /* @__PURE__ */ new Map()); 8318 } 8319 assert(query._queryParams.isDefault() || !query._queryParams.loadsAllData(), "listen() called for non-default but complete query"); 8320 assert(!this.listens.get(pathString).has(queryId), `listen() called twice for same path/queryId.`); 8321 const listenSpec = { 8322 onComplete, 8323 hashFn: currentHashFn, 8324 query, 8325 tag 8326 }; 8327 this.listens.get(pathString).set(queryId, listenSpec); 8328 if (this.connected_) { 8329 this.sendListen_(listenSpec); 8330 } 8331 } 8332 sendGet_(index) { 8333 const get = this.outstandingGets_[index]; 8334 this.sendRequest("g", get.request, (message) => { 8335 delete this.outstandingGets_[index]; 8336 this.outstandingGetCount_--; 8337 if (this.outstandingGetCount_ === 0) { 8338 this.outstandingGets_ = []; 8339 } 8340 if (get.onComplete) { 8341 get.onComplete(message); 8342 } 8343 }); 8344 } 8345 sendListen_(listenSpec) { 8346 const query = listenSpec.query; 8347 const pathString = query._path.toString(); 8348 const queryId = query._queryIdentifier; 8349 this.log_("Listen on " + pathString + " for " + queryId); 8350 const req = { p: pathString }; 8351 const action = "q"; 8352 if (listenSpec.tag) { 8353 req["q"] = query._queryObject; 8354 req["t"] = listenSpec.tag; 8355 } 8356 req["h"] = listenSpec.hashFn(); 8357 this.sendRequest(action, req, (message) => { 8358 const payload = message["d"]; 8359 const status = message["s"]; 8360 PersistentConnection.warnOnListenWarnings_(payload, query); 8361 const currentListenSpec = this.listens.get(pathString) && this.listens.get(pathString).get(queryId); 8362 if (currentListenSpec === listenSpec) { 8363 this.log_("listen response", message); 8364 if (status !== "ok") { 8365 this.removeListen_(pathString, queryId); 8366 } 8367 if (listenSpec.onComplete) { 8368 listenSpec.onComplete(status, payload); 8369 } 8370 } 8371 }); 8372 } 8373 static warnOnListenWarnings_(payload, query) { 8374 if (payload && typeof payload === "object" && contains(payload, "w")) { 8375 const warnings = safeGet(payload, "w"); 8376 if (Array.isArray(warnings) && ~warnings.indexOf("no_index")) { 8377 const indexSpec = '".indexOn": "' + query._queryParams.getIndex().toString() + '"'; 8378 const indexPath = query._path.toString(); 8379 warn(`Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ${indexSpec} at ${indexPath} to your security rules for better performance.`); 8380 } 8381 } 8382 } 8383 refreshAuthToken(token) { 8384 this.authToken_ = token; 8385 this.log_("Auth token refreshed"); 8386 if (this.authToken_) { 8387 this.tryAuth(); 8388 } else { 8389 if (this.connected_) { 8390 this.sendRequest("unauth", {}, () => { 8391 }); 8392 } 8393 } 8394 this.reduceReconnectDelayIfAdminCredential_(token); 8395 } 8396 reduceReconnectDelayIfAdminCredential_(credential) { 8397 const isFirebaseSecret = credential && credential.length === 40; 8398 if (isFirebaseSecret || isAdmin(credential)) { 8399 this.log_("Admin auth credential detected. Reducing max reconnect time."); 8400 this.maxReconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS; 8401 } 8402 } 8403 refreshAppCheckToken(token) { 8404 this.appCheckToken_ = token; 8405 this.log_("App check token refreshed"); 8406 if (this.appCheckToken_) { 8407 this.tryAppCheck(); 8408 } else { 8409 if (this.connected_) { 8410 this.sendRequest("unappeck", {}, () => { 8411 }); 8412 } 8413 } 8414 } 8415 tryAuth() { 8416 if (this.connected_ && this.authToken_) { 8417 const token = this.authToken_; 8418 const authMethod = isValidFormat(token) ? "auth" : "gauth"; 8419 const requestData = { cred: token }; 8420 if (this.authOverride_ === null) { 8421 requestData["noauth"] = true; 8422 } else if (typeof this.authOverride_ === "object") { 8423 requestData["authvar"] = this.authOverride_; 8424 } 8425 this.sendRequest(authMethod, requestData, (res) => { 8426 const status = res["s"]; 8427 const data = res["d"] || "error"; 8428 if (this.authToken_ === token) { 8429 if (status === "ok") { 8430 this.invalidAuthTokenCount_ = 0; 8431 } else { 8432 this.onAuthRevoked_(status, data); 8433 } 8434 } 8435 }); 8436 } 8437 } 8438 tryAppCheck() { 8439 if (this.connected_ && this.appCheckToken_) { 8440 this.sendRequest("appcheck", { "token": this.appCheckToken_ }, (res) => { 8441 const status = res["s"]; 8442 const data = res["d"] || "error"; 8443 if (status === "ok") { 8444 this.invalidAppCheckTokenCount_ = 0; 8445 } else { 8446 this.onAppCheckRevoked_(status, data); 8447 } 8448 }); 8449 } 8450 } 8451 unlisten(query, tag) { 8452 const pathString = query._path.toString(); 8453 const queryId = query._queryIdentifier; 8454 this.log_("Unlisten called for " + pathString + " " + queryId); 8455 assert(query._queryParams.isDefault() || !query._queryParams.loadsAllData(), "unlisten() called for non-default but complete query"); 8456 const listen = this.removeListen_(pathString, queryId); 8457 if (listen && this.connected_) { 8458 this.sendUnlisten_(pathString, queryId, query._queryObject, tag); 8459 } 8460 } 8461 sendUnlisten_(pathString, queryId, queryObj, tag) { 8462 this.log_("Unlisten on " + pathString + " for " + queryId); 8463 const req = { p: pathString }; 8464 const action = "n"; 8465 if (tag) { 8466 req["q"] = queryObj; 8467 req["t"] = tag; 8468 } 8469 this.sendRequest(action, req); 8470 } 8471 onDisconnectPut(pathString, data, onComplete) { 8472 this.initConnection_(); 8473 if (this.connected_) { 8474 this.sendOnDisconnect_("o", pathString, data, onComplete); 8475 } else { 8476 this.onDisconnectRequestQueue_.push({ 8477 pathString, 8478 action: "o", 8479 data, 8480 onComplete 8481 }); 8482 } 8483 } 8484 onDisconnectMerge(pathString, data, onComplete) { 8485 this.initConnection_(); 8486 if (this.connected_) { 8487 this.sendOnDisconnect_("om", pathString, data, onComplete); 8488 } else { 8489 this.onDisconnectRequestQueue_.push({ 8490 pathString, 8491 action: "om", 8492 data, 8493 onComplete 8494 }); 8495 } 8496 } 8497 onDisconnectCancel(pathString, onComplete) { 8498 this.initConnection_(); 8499 if (this.connected_) { 8500 this.sendOnDisconnect_("oc", pathString, null, onComplete); 8501 } else { 8502 this.onDisconnectRequestQueue_.push({ 8503 pathString, 8504 action: "oc", 8505 data: null, 8506 onComplete 8507 }); 8508 } 8509 } 8510 sendOnDisconnect_(action, pathString, data, onComplete) { 8511 const request = { p: pathString, d: data }; 8512 this.log_("onDisconnect " + action, request); 8513 this.sendRequest(action, request, (response) => { 8514 if (onComplete) { 8515 setTimeout(() => { 8516 onComplete(response["s"], response["d"]); 8517 }, Math.floor(0)); 8518 } 8519 }); 8520 } 8521 put(pathString, data, onComplete, hash) { 8522 this.putInternal("p", pathString, data, onComplete, hash); 8523 } 8524 merge(pathString, data, onComplete, hash) { 8525 this.putInternal("m", pathString, data, onComplete, hash); 8526 } 8527 putInternal(action, pathString, data, onComplete, hash) { 8528 this.initConnection_(); 8529 const request = { 8530 p: pathString, 8531 d: data 8532 }; 8533 if (hash !== void 0) { 8534 request["h"] = hash; 8535 } 8536 this.outstandingPuts_.push({ 8537 action, 8538 request, 8539 onComplete 8540 }); 8541 this.outstandingPutCount_++; 8542 const index = this.outstandingPuts_.length - 1; 8543 if (this.connected_) { 8544 this.sendPut_(index); 8545 } else { 8546 this.log_("Buffering put: " + pathString); 8547 } 8548 } 8549 sendPut_(index) { 8550 const action = this.outstandingPuts_[index].action; 8551 const request = this.outstandingPuts_[index].request; 8552 const onComplete = this.outstandingPuts_[index].onComplete; 8553 this.outstandingPuts_[index].queued = this.connected_; 8554 this.sendRequest(action, request, (message) => { 8555 this.log_(action + " response", message); 8556 delete this.outstandingPuts_[index]; 8557 this.outstandingPutCount_--; 8558 if (this.outstandingPutCount_ === 0) { 8559 this.outstandingPuts_ = []; 8560 } 8561 if (onComplete) { 8562 onComplete(message["s"], message["d"]); 8563 } 8564 }); 8565 } 8566 reportStats(stats) { 8567 if (this.connected_) { 8568 const request = { c: stats }; 8569 this.log_("reportStats", request); 8570 this.sendRequest("s", request, (result) => { 8571 const status = result["s"]; 8572 if (status !== "ok") { 8573 const errorReason = result["d"]; 8574 this.log_("reportStats", "Error sending stats: " + errorReason); 8575 } 8576 }); 8577 } 8578 } 8579 onDataMessage_(message) { 8580 if ("r" in message) { 8581 this.log_("from server: " + stringify(message)); 8582 const reqNum = message["r"]; 8583 const onResponse = this.requestCBHash_[reqNum]; 8584 if (onResponse) { 8585 delete this.requestCBHash_[reqNum]; 8586 onResponse(message["b"]); 8587 } 8588 } else if ("error" in message) { 8589 throw "A server-side error has occurred: " + message["error"]; 8590 } else if ("a" in message) { 8591 this.onDataPush_(message["a"], message["b"]); 8592 } 8593 } 8594 onDataPush_(action, body) { 8595 this.log_("handleServerMessage", action, body); 8596 if (action === "d") { 8597 this.onDataUpdate_(body["p"], body["d"], false, body["t"]); 8598 } else if (action === "m") { 8599 this.onDataUpdate_(body["p"], body["d"], true, body["t"]); 8600 } else if (action === "c") { 8601 this.onListenRevoked_(body["p"], body["q"]); 8602 } else if (action === "ac") { 8603 this.onAuthRevoked_(body["s"], body["d"]); 8604 } else if (action === "apc") { 8605 this.onAppCheckRevoked_(body["s"], body["d"]); 8606 } else if (action === "sd") { 8607 this.onSecurityDebugPacket_(body); 8608 } else { 8609 error("Unrecognized action received from server: " + stringify(action) + "\nAre you using the latest client?"); 8610 } 8611 } 8612 onReady_(timestamp, sessionId) { 8613 this.log_("connection ready"); 8614 this.connected_ = true; 8615 this.lastConnectionEstablishedTime_ = new Date().getTime(); 8616 this.handleTimestamp_(timestamp); 8617 this.lastSessionId = sessionId; 8618 if (this.firstConnection_) { 8619 this.sendConnectStats_(); 8620 } 8621 this.restoreState_(); 8622 this.firstConnection_ = false; 8623 this.onConnectStatus_(true); 8624 } 8625 scheduleConnect_(timeout) { 8626 assert(!this.realtime_, "Scheduling a connect when we're already connected/ing?"); 8627 if (this.establishConnectionTimer_) { 8628 clearTimeout(this.establishConnectionTimer_); 8629 } 8630 this.establishConnectionTimer_ = setTimeout(() => { 8631 this.establishConnectionTimer_ = null; 8632 this.establishConnection_(); 8633 }, Math.floor(timeout)); 8634 } 8635 initConnection_() { 8636 if (!this.realtime_ && this.firstConnection_) { 8637 this.scheduleConnect_(0); 8638 } 8639 } 8640 onVisible_(visible) { 8641 if (visible && !this.visible_ && this.reconnectDelay_ === this.maxReconnectDelay_) { 8642 this.log_("Window became visible. Reducing delay."); 8643 this.reconnectDelay_ = RECONNECT_MIN_DELAY; 8644 if (!this.realtime_) { 8645 this.scheduleConnect_(0); 8646 } 8647 } 8648 this.visible_ = visible; 8649 } 8650 onOnline_(online) { 8651 if (online) { 8652 this.log_("Browser went online."); 8653 this.reconnectDelay_ = RECONNECT_MIN_DELAY; 8654 if (!this.realtime_) { 8655 this.scheduleConnect_(0); 8656 } 8657 } else { 8658 this.log_("Browser went offline. Killing connection."); 8659 if (this.realtime_) { 8660 this.realtime_.close(); 8661 } 8662 } 8663 } 8664 onRealtimeDisconnect_() { 8665 this.log_("data client disconnected"); 8666 this.connected_ = false; 8667 this.realtime_ = null; 8668 this.cancelSentTransactions_(); 8669 this.requestCBHash_ = {}; 8670 if (this.shouldReconnect_()) { 8671 if (!this.visible_) { 8672 this.log_("Window isn't visible. Delaying reconnect."); 8673 this.reconnectDelay_ = this.maxReconnectDelay_; 8674 this.lastConnectionAttemptTime_ = new Date().getTime(); 8675 } else if (this.lastConnectionEstablishedTime_) { 8676 const timeSinceLastConnectSucceeded = new Date().getTime() - this.lastConnectionEstablishedTime_; 8677 if (timeSinceLastConnectSucceeded > RECONNECT_DELAY_RESET_TIMEOUT) { 8678 this.reconnectDelay_ = RECONNECT_MIN_DELAY; 8679 } 8680 this.lastConnectionEstablishedTime_ = null; 8681 } 8682 const timeSinceLastConnectAttempt = new Date().getTime() - this.lastConnectionAttemptTime_; 8683 let reconnectDelay = Math.max(0, this.reconnectDelay_ - timeSinceLastConnectAttempt); 8684 reconnectDelay = Math.random() * reconnectDelay; 8685 this.log_("Trying to reconnect in " + reconnectDelay + "ms"); 8686 this.scheduleConnect_(reconnectDelay); 8687 this.reconnectDelay_ = Math.min(this.maxReconnectDelay_, this.reconnectDelay_ * RECONNECT_DELAY_MULTIPLIER); 8688 } 8689 this.onConnectStatus_(false); 8690 } 8691 async establishConnection_() { 8692 if (this.shouldReconnect_()) { 8693 this.log_("Making a connection attempt"); 8694 this.lastConnectionAttemptTime_ = new Date().getTime(); 8695 this.lastConnectionEstablishedTime_ = null; 8696 const onDataMessage = this.onDataMessage_.bind(this); 8697 const onReady = this.onReady_.bind(this); 8698 const onDisconnect = this.onRealtimeDisconnect_.bind(this); 8699 const connId = this.id + ":" + PersistentConnection.nextConnectionId_++; 8700 const lastSessionId = this.lastSessionId; 8701 let canceled = false; 8702 let connection = null; 8703 const closeFn = function() { 8704 if (connection) { 8705 connection.close(); 8706 } else { 8707 canceled = true; 8708 onDisconnect(); 8709 } 8710 }; 8711 const sendRequestFn = function(msg) { 8712 assert(connection, "sendRequest call when we're not connected not allowed."); 8713 connection.sendRequest(msg); 8714 }; 8715 this.realtime_ = { 8716 close: closeFn, 8717 sendRequest: sendRequestFn 8718 }; 8719 const forceRefresh = this.forceTokenRefresh_; 8720 this.forceTokenRefresh_ = false; 8721 try { 8722 const [authToken, appCheckToken] = await Promise.all([ 8723 this.authTokenProvider_.getToken(forceRefresh), 8724 this.appCheckTokenProvider_.getToken(forceRefresh) 8725 ]); 8726 if (!canceled) { 8727 log("getToken() completed. Creating connection."); 8728 this.authToken_ = authToken && authToken.accessToken; 8729 this.appCheckToken_ = appCheckToken && appCheckToken.token; 8730 connection = new Connection(connId, this.repoInfo_, this.applicationId_, this.appCheckToken_, this.authToken_, onDataMessage, onReady, onDisconnect, (reason) => { 8731 warn(reason + " (" + this.repoInfo_.toString() + ")"); 8732 this.interrupt(SERVER_KILL_INTERRUPT_REASON); 8733 }, lastSessionId); 8734 } else { 8735 log("getToken() completed but was canceled"); 8736 } 8737 } catch (error2) { 8738 this.log_("Failed to get token: " + error2); 8739 if (!canceled) { 8740 if (this.repoInfo_.nodeAdmin) { 8741 warn(error2); 8742 } 8743 closeFn(); 8744 } 8745 } 8746 } 8747 } 8748 interrupt(reason) { 8749 log("Interrupting connection for reason: " + reason); 8750 this.interruptReasons_[reason] = true; 8751 if (this.realtime_) { 8752 this.realtime_.close(); 8753 } else { 8754 if (this.establishConnectionTimer_) { 8755 clearTimeout(this.establishConnectionTimer_); 8756 this.establishConnectionTimer_ = null; 8757 } 8758 if (this.connected_) { 8759 this.onRealtimeDisconnect_(); 8760 } 8761 } 8762 } 8763 resume(reason) { 8764 log("Resuming connection for reason: " + reason); 8765 delete this.interruptReasons_[reason]; 8766 if (isEmpty(this.interruptReasons_)) { 8767 this.reconnectDelay_ = RECONNECT_MIN_DELAY; 8768 if (!this.realtime_) { 8769 this.scheduleConnect_(0); 8770 } 8771 } 8772 } 8773 handleTimestamp_(timestamp) { 8774 const delta = timestamp - new Date().getTime(); 8775 this.onServerInfoUpdate_({ serverTimeOffset: delta }); 8776 } 8777 cancelSentTransactions_() { 8778 for (let i = 0; i < this.outstandingPuts_.length; i++) { 8779 const put = this.outstandingPuts_[i]; 8780 if (put && "h" in put.request && put.queued) { 8781 if (put.onComplete) { 8782 put.onComplete("disconnect"); 8783 } 8784 delete this.outstandingPuts_[i]; 8785 this.outstandingPutCount_--; 8786 } 8787 } 8788 if (this.outstandingPutCount_ === 0) { 8789 this.outstandingPuts_ = []; 8790 } 8791 } 8792 onListenRevoked_(pathString, query) { 8793 let queryId; 8794 if (!query) { 8795 queryId = "default"; 8796 } else { 8797 queryId = query.map((q) => ObjectToUniqueKey(q)).join("$"); 8798 } 8799 const listen = this.removeListen_(pathString, queryId); 8800 if (listen && listen.onComplete) { 8801 listen.onComplete("permission_denied"); 8802 } 8803 } 8804 removeListen_(pathString, queryId) { 8805 const normalizedPathString = new Path(pathString).toString(); 8806 let listen; 8807 if (this.listens.has(normalizedPathString)) { 8808 const map2 = this.listens.get(normalizedPathString); 8809 listen = map2.get(queryId); 8810 map2.delete(queryId); 8811 if (map2.size === 0) { 8812 this.listens.delete(normalizedPathString); 8813 } 8814 } else { 8815 listen = void 0; 8816 } 8817 return listen; 8818 } 8819 onAuthRevoked_(statusCode, explanation) { 8820 log("Auth token revoked: " + statusCode + "/" + explanation); 8821 this.authToken_ = null; 8822 this.forceTokenRefresh_ = true; 8823 this.realtime_.close(); 8824 if (statusCode === "invalid_token" || statusCode === "permission_denied") { 8825 this.invalidAuthTokenCount_++; 8826 if (this.invalidAuthTokenCount_ >= INVALID_TOKEN_THRESHOLD) { 8827 this.reconnectDelay_ = RECONNECT_MAX_DELAY_FOR_ADMINS; 8828 this.authTokenProvider_.notifyForInvalidToken(); 8829 } 8830 } 8831 } 8832 onAppCheckRevoked_(statusCode, explanation) { 8833 log("App check token revoked: " + statusCode + "/" + explanation); 8834 this.appCheckToken_ = null; 8835 this.forceTokenRefresh_ = true; 8836 if (statusCode === "invalid_token" || statusCode === "permission_denied") { 8837 this.invalidAppCheckTokenCount_++; 8838 if (this.invalidAppCheckTokenCount_ >= INVALID_TOKEN_THRESHOLD) { 8839 this.appCheckTokenProvider_.notifyForInvalidToken(); 8840 } 8841 } 8842 } 8843 onSecurityDebugPacket_(body) { 8844 if (this.securityDebugCallback_) { 8845 this.securityDebugCallback_(body); 8846 } else { 8847 if ("msg" in body) { 8848 console.log("FIREBASE: " + body["msg"].replace("\n", "\nFIREBASE: ")); 8849 } 8850 } 8851 } 8852 restoreState_() { 8853 this.tryAuth(); 8854 this.tryAppCheck(); 8855 for (const queries of this.listens.values()) { 8856 for (const listenSpec of queries.values()) { 8857 this.sendListen_(listenSpec); 8858 } 8859 } 8860 for (let i = 0; i < this.outstandingPuts_.length; i++) { 8861 if (this.outstandingPuts_[i]) { 8862 this.sendPut_(i); 8863 } 8864 } 8865 while (this.onDisconnectRequestQueue_.length) { 8866 const request = this.onDisconnectRequestQueue_.shift(); 8867 this.sendOnDisconnect_(request.action, request.pathString, request.data, request.onComplete); 8868 } 8869 for (let i = 0; i < this.outstandingGets_.length; i++) { 8870 if (this.outstandingGets_[i]) { 8871 this.sendGet_(i); 8872 } 8873 } 8874 } 8875 sendConnectStats_() { 8876 const stats = {}; 8877 let clientName = "js"; 8878 if (isNodeSdk()) { 8879 if (this.repoInfo_.nodeAdmin) { 8880 clientName = "admin_node"; 8881 } else { 8882 clientName = "node"; 8883 } 8884 } 8885 stats["sdk." + clientName + "." + SDK_VERSION2.replace(/\./g, "-")] = 1; 8886 if (isMobileCordova()) { 8887 stats["framework.cordova"] = 1; 8888 } else if (isReactNative()) { 8889 stats["framework.reactnative"] = 1; 8890 } 8891 this.reportStats(stats); 8892 } 8893 shouldReconnect_() { 8894 const online = OnlineMonitor.getInstance().currentlyOnline(); 8895 return isEmpty(this.interruptReasons_) && online; 8896 } 8897 }; 8898 PersistentConnection.nextPersistentConnectionId_ = 0; 8899 PersistentConnection.nextConnectionId_ = 0; 8900 var NamedNode = class { 8901 constructor(name7, node) { 8902 this.name = name7; 8903 this.node = node; 8904 } 8905 static Wrap(name7, node) { 8906 return new NamedNode(name7, node); 8907 } 8908 }; 8909 var Index = class { 8910 getCompare() { 8911 return this.compare.bind(this); 8912 } 8913 indexedValueChanged(oldNode, newNode) { 8914 const oldWrapped = new NamedNode(MIN_NAME, oldNode); 8915 const newWrapped = new NamedNode(MIN_NAME, newNode); 8916 return this.compare(oldWrapped, newWrapped) !== 0; 8917 } 8918 minPost() { 8919 return NamedNode.MIN; 8920 } 8921 }; 8922 var __EMPTY_NODE; 8923 var KeyIndex = class extends Index { 8924 static get __EMPTY_NODE() { 8925 return __EMPTY_NODE; 8926 } 8927 static set __EMPTY_NODE(val) { 8928 __EMPTY_NODE = val; 8929 } 8930 compare(a, b) { 8931 return nameCompare(a.name, b.name); 8932 } 8933 isDefinedOn(node) { 8934 throw assertionError("KeyIndex.isDefinedOn not expected to be called."); 8935 } 8936 indexedValueChanged(oldNode, newNode) { 8937 return false; 8938 } 8939 minPost() { 8940 return NamedNode.MIN; 8941 } 8942 maxPost() { 8943 return new NamedNode(MAX_NAME, __EMPTY_NODE); 8944 } 8945 makePost(indexValue, name7) { 8946 assert(typeof indexValue === "string", "KeyIndex indexValue must always be a string."); 8947 return new NamedNode(indexValue, __EMPTY_NODE); 8948 } 8949 toString() { 8950 return ".key"; 8951 } 8952 }; 8953 var KEY_INDEX = new KeyIndex(); 8954 var SortedMapIterator = class { 8955 constructor(node, startKey, comparator, isReverse_, resultGenerator_ = null) { 8956 this.isReverse_ = isReverse_; 8957 this.resultGenerator_ = resultGenerator_; 8958 this.nodeStack_ = []; 8959 let cmp = 1; 8960 while (!node.isEmpty()) { 8961 node = node; 8962 cmp = startKey ? comparator(node.key, startKey) : 1; 8963 if (isReverse_) { 8964 cmp *= -1; 8965 } 8966 if (cmp < 0) { 8967 if (this.isReverse_) { 8968 node = node.left; 8969 } else { 8970 node = node.right; 8971 } 8972 } else if (cmp === 0) { 8973 this.nodeStack_.push(node); 8974 break; 8975 } else { 8976 this.nodeStack_.push(node); 8977 if (this.isReverse_) { 8978 node = node.right; 8979 } else { 8980 node = node.left; 8981 } 8982 } 8983 } 8984 } 8985 getNext() { 8986 if (this.nodeStack_.length === 0) { 8987 return null; 8988 } 8989 let node = this.nodeStack_.pop(); 8990 let result; 8991 if (this.resultGenerator_) { 8992 result = this.resultGenerator_(node.key, node.value); 8993 } else { 8994 result = { key: node.key, value: node.value }; 8995 } 8996 if (this.isReverse_) { 8997 node = node.left; 8998 while (!node.isEmpty()) { 8999 this.nodeStack_.push(node); 9000 node = node.right; 9001 } 9002 } else { 9003 node = node.right; 9004 while (!node.isEmpty()) { 9005 this.nodeStack_.push(node); 9006 node = node.left; 9007 } 9008 } 9009 return result; 9010 } 9011 hasNext() { 9012 return this.nodeStack_.length > 0; 9013 } 9014 peek() { 9015 if (this.nodeStack_.length === 0) { 9016 return null; 9017 } 9018 const node = this.nodeStack_[this.nodeStack_.length - 1]; 9019 if (this.resultGenerator_) { 9020 return this.resultGenerator_(node.key, node.value); 9021 } else { 9022 return { key: node.key, value: node.value }; 9023 } 9024 } 9025 }; 9026 var LLRBNode = class { 9027 constructor(key, value, color, left, right) { 9028 this.key = key; 9029 this.value = value; 9030 this.color = color != null ? color : LLRBNode.RED; 9031 this.left = left != null ? left : SortedMap.EMPTY_NODE; 9032 this.right = right != null ? right : SortedMap.EMPTY_NODE; 9033 } 9034 copy(key, value, color, left, right) { 9035 return new LLRBNode(key != null ? key : this.key, value != null ? value : this.value, color != null ? color : this.color, left != null ? left : this.left, right != null ? right : this.right); 9036 } 9037 count() { 9038 return this.left.count() + 1 + this.right.count(); 9039 } 9040 isEmpty() { 9041 return false; 9042 } 9043 inorderTraversal(action) { 9044 return this.left.inorderTraversal(action) || !!action(this.key, this.value) || this.right.inorderTraversal(action); 9045 } 9046 reverseTraversal(action) { 9047 return this.right.reverseTraversal(action) || action(this.key, this.value) || this.left.reverseTraversal(action); 9048 } 9049 min_() { 9050 if (this.left.isEmpty()) { 9051 return this; 9052 } else { 9053 return this.left.min_(); 9054 } 9055 } 9056 minKey() { 9057 return this.min_().key; 9058 } 9059 maxKey() { 9060 if (this.right.isEmpty()) { 9061 return this.key; 9062 } else { 9063 return this.right.maxKey(); 9064 } 9065 } 9066 insert(key, value, comparator) { 9067 let n = this; 9068 const cmp = comparator(key, n.key); 9069 if (cmp < 0) { 9070 n = n.copy(null, null, null, n.left.insert(key, value, comparator), null); 9071 } else if (cmp === 0) { 9072 n = n.copy(null, value, null, null, null); 9073 } else { 9074 n = n.copy(null, null, null, null, n.right.insert(key, value, comparator)); 9075 } 9076 return n.fixUp_(); 9077 } 9078 removeMin_() { 9079 if (this.left.isEmpty()) { 9080 return SortedMap.EMPTY_NODE; 9081 } 9082 let n = this; 9083 if (!n.left.isRed_() && !n.left.left.isRed_()) { 9084 n = n.moveRedLeft_(); 9085 } 9086 n = n.copy(null, null, null, n.left.removeMin_(), null); 9087 return n.fixUp_(); 9088 } 9089 remove(key, comparator) { 9090 let n, smallest; 9091 n = this; 9092 if (comparator(key, n.key) < 0) { 9093 if (!n.left.isEmpty() && !n.left.isRed_() && !n.left.left.isRed_()) { 9094 n = n.moveRedLeft_(); 9095 } 9096 n = n.copy(null, null, null, n.left.remove(key, comparator), null); 9097 } else { 9098 if (n.left.isRed_()) { 9099 n = n.rotateRight_(); 9100 } 9101 if (!n.right.isEmpty() && !n.right.isRed_() && !n.right.left.isRed_()) { 9102 n = n.moveRedRight_(); 9103 } 9104 if (comparator(key, n.key) === 0) { 9105 if (n.right.isEmpty()) { 9106 return SortedMap.EMPTY_NODE; 9107 } else { 9108 smallest = n.right.min_(); 9109 n = n.copy(smallest.key, smallest.value, null, null, n.right.removeMin_()); 9110 } 9111 } 9112 n = n.copy(null, null, null, null, n.right.remove(key, comparator)); 9113 } 9114 return n.fixUp_(); 9115 } 9116 isRed_() { 9117 return this.color; 9118 } 9119 fixUp_() { 9120 let n = this; 9121 if (n.right.isRed_() && !n.left.isRed_()) { 9122 n = n.rotateLeft_(); 9123 } 9124 if (n.left.isRed_() && n.left.left.isRed_()) { 9125 n = n.rotateRight_(); 9126 } 9127 if (n.left.isRed_() && n.right.isRed_()) { 9128 n = n.colorFlip_(); 9129 } 9130 return n; 9131 } 9132 moveRedLeft_() { 9133 let n = this.colorFlip_(); 9134 if (n.right.left.isRed_()) { 9135 n = n.copy(null, null, null, null, n.right.rotateRight_()); 9136 n = n.rotateLeft_(); 9137 n = n.colorFlip_(); 9138 } 9139 return n; 9140 } 9141 moveRedRight_() { 9142 let n = this.colorFlip_(); 9143 if (n.left.left.isRed_()) { 9144 n = n.rotateRight_(); 9145 n = n.colorFlip_(); 9146 } 9147 return n; 9148 } 9149 rotateLeft_() { 9150 const nl = this.copy(null, null, LLRBNode.RED, null, this.right.left); 9151 return this.right.copy(null, null, this.color, nl, null); 9152 } 9153 rotateRight_() { 9154 const nr = this.copy(null, null, LLRBNode.RED, this.left.right, null); 9155 return this.left.copy(null, null, this.color, null, nr); 9156 } 9157 colorFlip_() { 9158 const left = this.left.copy(null, null, !this.left.color, null, null); 9159 const right = this.right.copy(null, null, !this.right.color, null, null); 9160 return this.copy(null, null, !this.color, left, right); 9161 } 9162 checkMaxDepth_() { 9163 const blackDepth = this.check_(); 9164 return Math.pow(2, blackDepth) <= this.count() + 1; 9165 } 9166 check_() { 9167 if (this.isRed_() && this.left.isRed_()) { 9168 throw new Error("Red node has red child(" + this.key + "," + this.value + ")"); 9169 } 9170 if (this.right.isRed_()) { 9171 throw new Error("Right child of (" + this.key + "," + this.value + ") is red"); 9172 } 9173 const blackDepth = this.left.check_(); 9174 if (blackDepth !== this.right.check_()) { 9175 throw new Error("Black depths differ"); 9176 } else { 9177 return blackDepth + (this.isRed_() ? 0 : 1); 9178 } 9179 } 9180 }; 9181 LLRBNode.RED = true; 9182 LLRBNode.BLACK = false; 9183 var LLRBEmptyNode = class { 9184 copy(key, value, color, left, right) { 9185 return this; 9186 } 9187 insert(key, value, comparator) { 9188 return new LLRBNode(key, value, null); 9189 } 9190 remove(key, comparator) { 9191 return this; 9192 } 9193 count() { 9194 return 0; 9195 } 9196 isEmpty() { 9197 return true; 9198 } 9199 inorderTraversal(action) { 9200 return false; 9201 } 9202 reverseTraversal(action) { 9203 return false; 9204 } 9205 minKey() { 9206 return null; 9207 } 9208 maxKey() { 9209 return null; 9210 } 9211 check_() { 9212 return 0; 9213 } 9214 isRed_() { 9215 return false; 9216 } 9217 }; 9218 var SortedMap = class { 9219 constructor(comparator_, root_ = SortedMap.EMPTY_NODE) { 9220 this.comparator_ = comparator_; 9221 this.root_ = root_; 9222 } 9223 insert(key, value) { 9224 return new SortedMap(this.comparator_, this.root_.insert(key, value, this.comparator_).copy(null, null, LLRBNode.BLACK, null, null)); 9225 } 9226 remove(key) { 9227 return new SortedMap(this.comparator_, this.root_.remove(key, this.comparator_).copy(null, null, LLRBNode.BLACK, null, null)); 9228 } 9229 get(key) { 9230 let cmp; 9231 let node = this.root_; 9232 while (!node.isEmpty()) { 9233 cmp = this.comparator_(key, node.key); 9234 if (cmp === 0) { 9235 return node.value; 9236 } else if (cmp < 0) { 9237 node = node.left; 9238 } else if (cmp > 0) { 9239 node = node.right; 9240 } 9241 } 9242 return null; 9243 } 9244 getPredecessorKey(key) { 9245 let cmp, node = this.root_, rightParent = null; 9246 while (!node.isEmpty()) { 9247 cmp = this.comparator_(key, node.key); 9248 if (cmp === 0) { 9249 if (!node.left.isEmpty()) { 9250 node = node.left; 9251 while (!node.right.isEmpty()) { 9252 node = node.right; 9253 } 9254 return node.key; 9255 } else if (rightParent) { 9256 return rightParent.key; 9257 } else { 9258 return null; 9259 } 9260 } else if (cmp < 0) { 9261 node = node.left; 9262 } else if (cmp > 0) { 9263 rightParent = node; 9264 node = node.right; 9265 } 9266 } 9267 throw new Error("Attempted to find predecessor key for a nonexistent key. What gives?"); 9268 } 9269 isEmpty() { 9270 return this.root_.isEmpty(); 9271 } 9272 count() { 9273 return this.root_.count(); 9274 } 9275 minKey() { 9276 return this.root_.minKey(); 9277 } 9278 maxKey() { 9279 return this.root_.maxKey(); 9280 } 9281 inorderTraversal(action) { 9282 return this.root_.inorderTraversal(action); 9283 } 9284 reverseTraversal(action) { 9285 return this.root_.reverseTraversal(action); 9286 } 9287 getIterator(resultGenerator) { 9288 return new SortedMapIterator(this.root_, null, this.comparator_, false, resultGenerator); 9289 } 9290 getIteratorFrom(key, resultGenerator) { 9291 return new SortedMapIterator(this.root_, key, this.comparator_, false, resultGenerator); 9292 } 9293 getReverseIteratorFrom(key, resultGenerator) { 9294 return new SortedMapIterator(this.root_, key, this.comparator_, true, resultGenerator); 9295 } 9296 getReverseIterator(resultGenerator) { 9297 return new SortedMapIterator(this.root_, null, this.comparator_, true, resultGenerator); 9298 } 9299 }; 9300 SortedMap.EMPTY_NODE = new LLRBEmptyNode(); 9301 function NAME_ONLY_COMPARATOR(left, right) { 9302 return nameCompare(left.name, right.name); 9303 } 9304 function NAME_COMPARATOR(left, right) { 9305 return nameCompare(left, right); 9306 } 9307 var MAX_NODE$2; 9308 function setMaxNode$1(val) { 9309 MAX_NODE$2 = val; 9310 } 9311 var priorityHashText = function(priority) { 9312 if (typeof priority === "number") { 9313 return "number:" + doubleToIEEE754String(priority); 9314 } else { 9315 return "string:" + priority; 9316 } 9317 }; 9318 var validatePriorityNode = function(priorityNode) { 9319 if (priorityNode.isLeafNode()) { 9320 const val = priorityNode.val(); 9321 assert(typeof val === "string" || typeof val === "number" || typeof val === "object" && contains(val, ".sv"), "Priority must be a string or number."); 9322 } else { 9323 assert(priorityNode === MAX_NODE$2 || priorityNode.isEmpty(), "priority of unexpected type."); 9324 } 9325 assert(priorityNode === MAX_NODE$2 || priorityNode.getPriority().isEmpty(), "Priority nodes can't have a priority of their own."); 9326 }; 9327 var __childrenNodeConstructor; 9328 var LeafNode = class { 9329 constructor(value_, priorityNode_ = LeafNode.__childrenNodeConstructor.EMPTY_NODE) { 9330 this.value_ = value_; 9331 this.priorityNode_ = priorityNode_; 9332 this.lazyHash_ = null; 9333 assert(this.value_ !== void 0 && this.value_ !== null, "LeafNode shouldn't be created with null/undefined value."); 9334 validatePriorityNode(this.priorityNode_); 9335 } 9336 static set __childrenNodeConstructor(val) { 9337 __childrenNodeConstructor = val; 9338 } 9339 static get __childrenNodeConstructor() { 9340 return __childrenNodeConstructor; 9341 } 9342 isLeafNode() { 9343 return true; 9344 } 9345 getPriority() { 9346 return this.priorityNode_; 9347 } 9348 updatePriority(newPriorityNode) { 9349 return new LeafNode(this.value_, newPriorityNode); 9350 } 9351 getImmediateChild(childName) { 9352 if (childName === ".priority") { 9353 return this.priorityNode_; 9354 } else { 9355 return LeafNode.__childrenNodeConstructor.EMPTY_NODE; 9356 } 9357 } 9358 getChild(path) { 9359 if (pathIsEmpty(path)) { 9360 return this; 9361 } else if (pathGetFront(path) === ".priority") { 9362 return this.priorityNode_; 9363 } else { 9364 return LeafNode.__childrenNodeConstructor.EMPTY_NODE; 9365 } 9366 } 9367 hasChild() { 9368 return false; 9369 } 9370 getPredecessorChildName(childName, childNode) { 9371 return null; 9372 } 9373 updateImmediateChild(childName, newChildNode) { 9374 if (childName === ".priority") { 9375 return this.updatePriority(newChildNode); 9376 } else if (newChildNode.isEmpty() && childName !== ".priority") { 9377 return this; 9378 } else { 9379 return LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateImmediateChild(childName, newChildNode).updatePriority(this.priorityNode_); 9380 } 9381 } 9382 updateChild(path, newChildNode) { 9383 const front = pathGetFront(path); 9384 if (front === null) { 9385 return newChildNode; 9386 } else if (newChildNode.isEmpty() && front !== ".priority") { 9387 return this; 9388 } else { 9389 assert(front !== ".priority" || pathGetLength(path) === 1, ".priority must be the last token in a path"); 9390 return this.updateImmediateChild(front, LeafNode.__childrenNodeConstructor.EMPTY_NODE.updateChild(pathPopFront(path), newChildNode)); 9391 } 9392 } 9393 isEmpty() { 9394 return false; 9395 } 9396 numChildren() { 9397 return 0; 9398 } 9399 forEachChild(index, action) { 9400 return false; 9401 } 9402 val(exportFormat) { 9403 if (exportFormat && !this.getPriority().isEmpty()) { 9404 return { 9405 ".value": this.getValue(), 9406 ".priority": this.getPriority().val() 9407 }; 9408 } else { 9409 return this.getValue(); 9410 } 9411 } 9412 hash() { 9413 if (this.lazyHash_ === null) { 9414 let toHash = ""; 9415 if (!this.priorityNode_.isEmpty()) { 9416 toHash += "priority:" + priorityHashText(this.priorityNode_.val()) + ":"; 9417 } 9418 const type = typeof this.value_; 9419 toHash += type + ":"; 9420 if (type === "number") { 9421 toHash += doubleToIEEE754String(this.value_); 9422 } else { 9423 toHash += this.value_; 9424 } 9425 this.lazyHash_ = sha1(toHash); 9426 } 9427 return this.lazyHash_; 9428 } 9429 getValue() { 9430 return this.value_; 9431 } 9432 compareTo(other) { 9433 if (other === LeafNode.__childrenNodeConstructor.EMPTY_NODE) { 9434 return 1; 9435 } else if (other instanceof LeafNode.__childrenNodeConstructor) { 9436 return -1; 9437 } else { 9438 assert(other.isLeafNode(), "Unknown node type"); 9439 return this.compareToLeafNode_(other); 9440 } 9441 } 9442 compareToLeafNode_(otherLeaf) { 9443 const otherLeafType = typeof otherLeaf.value_; 9444 const thisLeafType = typeof this.value_; 9445 const otherIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(otherLeafType); 9446 const thisIndex = LeafNode.VALUE_TYPE_ORDER.indexOf(thisLeafType); 9447 assert(otherIndex >= 0, "Unknown leaf type: " + otherLeafType); 9448 assert(thisIndex >= 0, "Unknown leaf type: " + thisLeafType); 9449 if (otherIndex === thisIndex) { 9450 if (thisLeafType === "object") { 9451 return 0; 9452 } else { 9453 if (this.value_ < otherLeaf.value_) { 9454 return -1; 9455 } else if (this.value_ === otherLeaf.value_) { 9456 return 0; 9457 } else { 9458 return 1; 9459 } 9460 } 9461 } else { 9462 return thisIndex - otherIndex; 9463 } 9464 } 9465 withIndex() { 9466 return this; 9467 } 9468 isIndexed() { 9469 return true; 9470 } 9471 equals(other) { 9472 if (other === this) { 9473 return true; 9474 } else if (other.isLeafNode()) { 9475 const otherLeaf = other; 9476 return this.value_ === otherLeaf.value_ && this.priorityNode_.equals(otherLeaf.priorityNode_); 9477 } else { 9478 return false; 9479 } 9480 } 9481 }; 9482 LeafNode.VALUE_TYPE_ORDER = ["object", "boolean", "number", "string"]; 9483 var nodeFromJSON$1; 9484 var MAX_NODE$1; 9485 function setNodeFromJSON(val) { 9486 nodeFromJSON$1 = val; 9487 } 9488 function setMaxNode(val) { 9489 MAX_NODE$1 = val; 9490 } 9491 var PriorityIndex = class extends Index { 9492 compare(a, b) { 9493 const aPriority = a.node.getPriority(); 9494 const bPriority = b.node.getPriority(); 9495 const indexCmp = aPriority.compareTo(bPriority); 9496 if (indexCmp === 0) { 9497 return nameCompare(a.name, b.name); 9498 } else { 9499 return indexCmp; 9500 } 9501 } 9502 isDefinedOn(node) { 9503 return !node.getPriority().isEmpty(); 9504 } 9505 indexedValueChanged(oldNode, newNode) { 9506 return !oldNode.getPriority().equals(newNode.getPriority()); 9507 } 9508 minPost() { 9509 return NamedNode.MIN; 9510 } 9511 maxPost() { 9512 return new NamedNode(MAX_NAME, new LeafNode("[PRIORITY-POST]", MAX_NODE$1)); 9513 } 9514 makePost(indexValue, name7) { 9515 const priorityNode = nodeFromJSON$1(indexValue); 9516 return new NamedNode(name7, new LeafNode("[PRIORITY-POST]", priorityNode)); 9517 } 9518 toString() { 9519 return ".priority"; 9520 } 9521 }; 9522 var PRIORITY_INDEX = new PriorityIndex(); 9523 var LOG_2 = Math.log(2); 9524 var Base12Num = class { 9525 constructor(length) { 9526 const logBase2 = (num) => parseInt(Math.log(num) / LOG_2, 10); 9527 const bitMask = (bits) => parseInt(Array(bits + 1).join("1"), 2); 9528 this.count = logBase2(length + 1); 9529 this.current_ = this.count - 1; 9530 const mask = bitMask(this.count); 9531 this.bits_ = length + 1 & mask; 9532 } 9533 nextBitIsOne() { 9534 const result = !(this.bits_ & 1 << this.current_); 9535 this.current_--; 9536 return result; 9537 } 9538 }; 9539 var buildChildSet = function(childList, cmp, keyFn, mapSortFn) { 9540 childList.sort(cmp); 9541 const buildBalancedTree = function(low, high) { 9542 const length = high - low; 9543 let namedNode; 9544 let key; 9545 if (length === 0) { 9546 return null; 9547 } else if (length === 1) { 9548 namedNode = childList[low]; 9549 key = keyFn ? keyFn(namedNode) : namedNode; 9550 return new LLRBNode(key, namedNode.node, LLRBNode.BLACK, null, null); 9551 } else { 9552 const middle = parseInt(length / 2, 10) + low; 9553 const left = buildBalancedTree(low, middle); 9554 const right = buildBalancedTree(middle + 1, high); 9555 namedNode = childList[middle]; 9556 key = keyFn ? keyFn(namedNode) : namedNode; 9557 return new LLRBNode(key, namedNode.node, LLRBNode.BLACK, left, right); 9558 } 9559 }; 9560 const buildFrom12Array = function(base122) { 9561 let node = null; 9562 let root2 = null; 9563 let index = childList.length; 9564 const buildPennant = function(chunkSize, color) { 9565 const low = index - chunkSize; 9566 const high = index; 9567 index -= chunkSize; 9568 const childTree = buildBalancedTree(low + 1, high); 9569 const namedNode = childList[low]; 9570 const key = keyFn ? keyFn(namedNode) : namedNode; 9571 attachPennant(new LLRBNode(key, namedNode.node, color, null, childTree)); 9572 }; 9573 const attachPennant = function(pennant) { 9574 if (node) { 9575 node.left = pennant; 9576 node = pennant; 9577 } else { 9578 root2 = pennant; 9579 node = pennant; 9580 } 9581 }; 9582 for (let i = 0; i < base122.count; ++i) { 9583 const isOne = base122.nextBitIsOne(); 9584 const chunkSize = Math.pow(2, base122.count - (i + 1)); 9585 if (isOne) { 9586 buildPennant(chunkSize, LLRBNode.BLACK); 9587 } else { 9588 buildPennant(chunkSize, LLRBNode.BLACK); 9589 buildPennant(chunkSize, LLRBNode.RED); 9590 } 9591 } 9592 return root2; 9593 }; 9594 const base12 = new Base12Num(childList.length); 9595 const root = buildFrom12Array(base12); 9596 return new SortedMap(mapSortFn || cmp, root); 9597 }; 9598 var _defaultIndexMap; 9599 var fallbackObject = {}; 9600 var IndexMap = class { 9601 constructor(indexes_, indexSet_) { 9602 this.indexes_ = indexes_; 9603 this.indexSet_ = indexSet_; 9604 } 9605 static get Default() { 9606 assert(fallbackObject && PRIORITY_INDEX, "ChildrenNode.ts has not been loaded"); 9607 _defaultIndexMap = _defaultIndexMap || new IndexMap({ ".priority": fallbackObject }, { ".priority": PRIORITY_INDEX }); 9608 return _defaultIndexMap; 9609 } 9610 get(indexKey) { 9611 const sortedMap = safeGet(this.indexes_, indexKey); 9612 if (!sortedMap) { 9613 throw new Error("No index defined for " + indexKey); 9614 } 9615 if (sortedMap instanceof SortedMap) { 9616 return sortedMap; 9617 } else { 9618 return null; 9619 } 9620 } 9621 hasIndex(indexDefinition) { 9622 return contains(this.indexSet_, indexDefinition.toString()); 9623 } 9624 addIndex(indexDefinition, existingChildren) { 9625 assert(indexDefinition !== KEY_INDEX, "KeyIndex always exists and isn't meant to be added to the IndexMap."); 9626 const childList = []; 9627 let sawIndexedValue = false; 9628 const iter = existingChildren.getIterator(NamedNode.Wrap); 9629 let next = iter.getNext(); 9630 while (next) { 9631 sawIndexedValue = sawIndexedValue || indexDefinition.isDefinedOn(next.node); 9632 childList.push(next); 9633 next = iter.getNext(); 9634 } 9635 let newIndex; 9636 if (sawIndexedValue) { 9637 newIndex = buildChildSet(childList, indexDefinition.getCompare()); 9638 } else { 9639 newIndex = fallbackObject; 9640 } 9641 const indexName = indexDefinition.toString(); 9642 const newIndexSet = Object.assign({}, this.indexSet_); 9643 newIndexSet[indexName] = indexDefinition; 9644 const newIndexes = Object.assign({}, this.indexes_); 9645 newIndexes[indexName] = newIndex; 9646 return new IndexMap(newIndexes, newIndexSet); 9647 } 9648 addToIndexes(namedNode, existingChildren) { 9649 const newIndexes = map(this.indexes_, (indexedChildren, indexName) => { 9650 const index = safeGet(this.indexSet_, indexName); 9651 assert(index, "Missing index implementation for " + indexName); 9652 if (indexedChildren === fallbackObject) { 9653 if (index.isDefinedOn(namedNode.node)) { 9654 const childList = []; 9655 const iter = existingChildren.getIterator(NamedNode.Wrap); 9656 let next = iter.getNext(); 9657 while (next) { 9658 if (next.name !== namedNode.name) { 9659 childList.push(next); 9660 } 9661 next = iter.getNext(); 9662 } 9663 childList.push(namedNode); 9664 return buildChildSet(childList, index.getCompare()); 9665 } else { 9666 return fallbackObject; 9667 } 9668 } else { 9669 const existingSnap = existingChildren.get(namedNode.name); 9670 let newChildren = indexedChildren; 9671 if (existingSnap) { 9672 newChildren = newChildren.remove(new NamedNode(namedNode.name, existingSnap)); 9673 } 9674 return newChildren.insert(namedNode, namedNode.node); 9675 } 9676 }); 9677 return new IndexMap(newIndexes, this.indexSet_); 9678 } 9679 removeFromIndexes(namedNode, existingChildren) { 9680 const newIndexes = map(this.indexes_, (indexedChildren) => { 9681 if (indexedChildren === fallbackObject) { 9682 return indexedChildren; 9683 } else { 9684 const existingSnap = existingChildren.get(namedNode.name); 9685 if (existingSnap) { 9686 return indexedChildren.remove(new NamedNode(namedNode.name, existingSnap)); 9687 } else { 9688 return indexedChildren; 9689 } 9690 } 9691 }); 9692 return new IndexMap(newIndexes, this.indexSet_); 9693 } 9694 }; 9695 var EMPTY_NODE; 9696 var ChildrenNode = class { 9697 constructor(children_, priorityNode_, indexMap_) { 9698 this.children_ = children_; 9699 this.priorityNode_ = priorityNode_; 9700 this.indexMap_ = indexMap_; 9701 this.lazyHash_ = null; 9702 if (this.priorityNode_) { 9703 validatePriorityNode(this.priorityNode_); 9704 } 9705 if (this.children_.isEmpty()) { 9706 assert(!this.priorityNode_ || this.priorityNode_.isEmpty(), "An empty node cannot have a priority"); 9707 } 9708 } 9709 static get EMPTY_NODE() { 9710 return EMPTY_NODE || (EMPTY_NODE = new ChildrenNode(new SortedMap(NAME_COMPARATOR), null, IndexMap.Default)); 9711 } 9712 isLeafNode() { 9713 return false; 9714 } 9715 getPriority() { 9716 return this.priorityNode_ || EMPTY_NODE; 9717 } 9718 updatePriority(newPriorityNode) { 9719 if (this.children_.isEmpty()) { 9720 return this; 9721 } else { 9722 return new ChildrenNode(this.children_, newPriorityNode, this.indexMap_); 9723 } 9724 } 9725 getImmediateChild(childName) { 9726 if (childName === ".priority") { 9727 return this.getPriority(); 9728 } else { 9729 const child = this.children_.get(childName); 9730 return child === null ? EMPTY_NODE : child; 9731 } 9732 } 9733 getChild(path) { 9734 const front = pathGetFront(path); 9735 if (front === null) { 9736 return this; 9737 } 9738 return this.getImmediateChild(front).getChild(pathPopFront(path)); 9739 } 9740 hasChild(childName) { 9741 return this.children_.get(childName) !== null; 9742 } 9743 updateImmediateChild(childName, newChildNode) { 9744 assert(newChildNode, "We should always be passing snapshot nodes"); 9745 if (childName === ".priority") { 9746 return this.updatePriority(newChildNode); 9747 } else { 9748 const namedNode = new NamedNode(childName, newChildNode); 9749 let newChildren, newIndexMap; 9750 if (newChildNode.isEmpty()) { 9751 newChildren = this.children_.remove(childName); 9752 newIndexMap = this.indexMap_.removeFromIndexes(namedNode, this.children_); 9753 } else { 9754 newChildren = this.children_.insert(childName, newChildNode); 9755 newIndexMap = this.indexMap_.addToIndexes(namedNode, this.children_); 9756 } 9757 const newPriority = newChildren.isEmpty() ? EMPTY_NODE : this.priorityNode_; 9758 return new ChildrenNode(newChildren, newPriority, newIndexMap); 9759 } 9760 } 9761 updateChild(path, newChildNode) { 9762 const front = pathGetFront(path); 9763 if (front === null) { 9764 return newChildNode; 9765 } else { 9766 assert(pathGetFront(path) !== ".priority" || pathGetLength(path) === 1, ".priority must be the last token in a path"); 9767 const newImmediateChild = this.getImmediateChild(front).updateChild(pathPopFront(path), newChildNode); 9768 return this.updateImmediateChild(front, newImmediateChild); 9769 } 9770 } 9771 isEmpty() { 9772 return this.children_.isEmpty(); 9773 } 9774 numChildren() { 9775 return this.children_.count(); 9776 } 9777 val(exportFormat) { 9778 if (this.isEmpty()) { 9779 return null; 9780 } 9781 const obj = {}; 9782 let numKeys = 0, maxKey = 0, allIntegerKeys = true; 9783 this.forEachChild(PRIORITY_INDEX, (key, childNode) => { 9784 obj[key] = childNode.val(exportFormat); 9785 numKeys++; 9786 if (allIntegerKeys && ChildrenNode.INTEGER_REGEXP_.test(key)) { 9787 maxKey = Math.max(maxKey, Number(key)); 9788 } else { 9789 allIntegerKeys = false; 9790 } 9791 }); 9792 if (!exportFormat && allIntegerKeys && maxKey < 2 * numKeys) { 9793 const array = []; 9794 for (const key in obj) { 9795 array[key] = obj[key]; 9796 } 9797 return array; 9798 } else { 9799 if (exportFormat && !this.getPriority().isEmpty()) { 9800 obj[".priority"] = this.getPriority().val(); 9801 } 9802 return obj; 9803 } 9804 } 9805 hash() { 9806 if (this.lazyHash_ === null) { 9807 let toHash = ""; 9808 if (!this.getPriority().isEmpty()) { 9809 toHash += "priority:" + priorityHashText(this.getPriority().val()) + ":"; 9810 } 9811 this.forEachChild(PRIORITY_INDEX, (key, childNode) => { 9812 const childHash = childNode.hash(); 9813 if (childHash !== "") { 9814 toHash += ":" + key + ":" + childHash; 9815 } 9816 }); 9817 this.lazyHash_ = toHash === "" ? "" : sha1(toHash); 9818 } 9819 return this.lazyHash_; 9820 } 9821 getPredecessorChildName(childName, childNode, index) { 9822 const idx = this.resolveIndex_(index); 9823 if (idx) { 9824 const predecessor = idx.getPredecessorKey(new NamedNode(childName, childNode)); 9825 return predecessor ? predecessor.name : null; 9826 } else { 9827 return this.children_.getPredecessorKey(childName); 9828 } 9829 } 9830 getFirstChildName(indexDefinition) { 9831 const idx = this.resolveIndex_(indexDefinition); 9832 if (idx) { 9833 const minKey = idx.minKey(); 9834 return minKey && minKey.name; 9835 } else { 9836 return this.children_.minKey(); 9837 } 9838 } 9839 getFirstChild(indexDefinition) { 9840 const minKey = this.getFirstChildName(indexDefinition); 9841 if (minKey) { 9842 return new NamedNode(minKey, this.children_.get(minKey)); 9843 } else { 9844 return null; 9845 } 9846 } 9847 getLastChildName(indexDefinition) { 9848 const idx = this.resolveIndex_(indexDefinition); 9849 if (idx) { 9850 const maxKey = idx.maxKey(); 9851 return maxKey && maxKey.name; 9852 } else { 9853 return this.children_.maxKey(); 9854 } 9855 } 9856 getLastChild(indexDefinition) { 9857 const maxKey = this.getLastChildName(indexDefinition); 9858 if (maxKey) { 9859 return new NamedNode(maxKey, this.children_.get(maxKey)); 9860 } else { 9861 return null; 9862 } 9863 } 9864 forEachChild(index, action) { 9865 const idx = this.resolveIndex_(index); 9866 if (idx) { 9867 return idx.inorderTraversal((wrappedNode) => { 9868 return action(wrappedNode.name, wrappedNode.node); 9869 }); 9870 } else { 9871 return this.children_.inorderTraversal(action); 9872 } 9873 } 9874 getIterator(indexDefinition) { 9875 return this.getIteratorFrom(indexDefinition.minPost(), indexDefinition); 9876 } 9877 getIteratorFrom(startPost, indexDefinition) { 9878 const idx = this.resolveIndex_(indexDefinition); 9879 if (idx) { 9880 return idx.getIteratorFrom(startPost, (key) => key); 9881 } else { 9882 const iterator = this.children_.getIteratorFrom(startPost.name, NamedNode.Wrap); 9883 let next = iterator.peek(); 9884 while (next != null && indexDefinition.compare(next, startPost) < 0) { 9885 iterator.getNext(); 9886 next = iterator.peek(); 9887 } 9888 return iterator; 9889 } 9890 } 9891 getReverseIterator(indexDefinition) { 9892 return this.getReverseIteratorFrom(indexDefinition.maxPost(), indexDefinition); 9893 } 9894 getReverseIteratorFrom(endPost, indexDefinition) { 9895 const idx = this.resolveIndex_(indexDefinition); 9896 if (idx) { 9897 return idx.getReverseIteratorFrom(endPost, (key) => { 9898 return key; 9899 }); 9900 } else { 9901 const iterator = this.children_.getReverseIteratorFrom(endPost.name, NamedNode.Wrap); 9902 let next = iterator.peek(); 9903 while (next != null && indexDefinition.compare(next, endPost) > 0) { 9904 iterator.getNext(); 9905 next = iterator.peek(); 9906 } 9907 return iterator; 9908 } 9909 } 9910 compareTo(other) { 9911 if (this.isEmpty()) { 9912 if (other.isEmpty()) { 9913 return 0; 9914 } else { 9915 return -1; 9916 } 9917 } else if (other.isLeafNode() || other.isEmpty()) { 9918 return 1; 9919 } else if (other === MAX_NODE) { 9920 return -1; 9921 } else { 9922 return 0; 9923 } 9924 } 9925 withIndex(indexDefinition) { 9926 if (indexDefinition === KEY_INDEX || this.indexMap_.hasIndex(indexDefinition)) { 9927 return this; 9928 } else { 9929 const newIndexMap = this.indexMap_.addIndex(indexDefinition, this.children_); 9930 return new ChildrenNode(this.children_, this.priorityNode_, newIndexMap); 9931 } 9932 } 9933 isIndexed(index) { 9934 return index === KEY_INDEX || this.indexMap_.hasIndex(index); 9935 } 9936 equals(other) { 9937 if (other === this) { 9938 return true; 9939 } else if (other.isLeafNode()) { 9940 return false; 9941 } else { 9942 const otherChildrenNode = other; 9943 if (!this.getPriority().equals(otherChildrenNode.getPriority())) { 9944 return false; 9945 } else if (this.children_.count() === otherChildrenNode.children_.count()) { 9946 const thisIter = this.getIterator(PRIORITY_INDEX); 9947 const otherIter = otherChildrenNode.getIterator(PRIORITY_INDEX); 9948 let thisCurrent = thisIter.getNext(); 9949 let otherCurrent = otherIter.getNext(); 9950 while (thisCurrent && otherCurrent) { 9951 if (thisCurrent.name !== otherCurrent.name || !thisCurrent.node.equals(otherCurrent.node)) { 9952 return false; 9953 } 9954 thisCurrent = thisIter.getNext(); 9955 otherCurrent = otherIter.getNext(); 9956 } 9957 return thisCurrent === null && otherCurrent === null; 9958 } else { 9959 return false; 9960 } 9961 } 9962 } 9963 resolveIndex_(indexDefinition) { 9964 if (indexDefinition === KEY_INDEX) { 9965 return null; 9966 } else { 9967 return this.indexMap_.get(indexDefinition.toString()); 9968 } 9969 } 9970 }; 9971 ChildrenNode.INTEGER_REGEXP_ = /^(0|[1-9]\d*)$/; 9972 var MaxNode = class extends ChildrenNode { 9973 constructor() { 9974 super(new SortedMap(NAME_COMPARATOR), ChildrenNode.EMPTY_NODE, IndexMap.Default); 9975 } 9976 compareTo(other) { 9977 if (other === this) { 9978 return 0; 9979 } else { 9980 return 1; 9981 } 9982 } 9983 equals(other) { 9984 return other === this; 9985 } 9986 getPriority() { 9987 return this; 9988 } 9989 getImmediateChild(childName) { 9990 return ChildrenNode.EMPTY_NODE; 9991 } 9992 isEmpty() { 9993 return false; 9994 } 9995 }; 9996 var MAX_NODE = new MaxNode(); 9997 Object.defineProperties(NamedNode, { 9998 MIN: { 9999 value: new NamedNode(MIN_NAME, ChildrenNode.EMPTY_NODE) 10000 }, 10001 MAX: { 10002 value: new NamedNode(MAX_NAME, MAX_NODE) 10003 } 10004 }); 10005 KeyIndex.__EMPTY_NODE = ChildrenNode.EMPTY_NODE; 10006 LeafNode.__childrenNodeConstructor = ChildrenNode; 10007 setMaxNode$1(MAX_NODE); 10008 setMaxNode(MAX_NODE); 10009 var USE_HINZE = true; 10010 function nodeFromJSON(json, priority = null) { 10011 if (json === null) { 10012 return ChildrenNode.EMPTY_NODE; 10013 } 10014 if (typeof json === "object" && ".priority" in json) { 10015 priority = json[".priority"]; 10016 } 10017 assert(priority === null || typeof priority === "string" || typeof priority === "number" || typeof priority === "object" && ".sv" in priority, "Invalid priority type found: " + typeof priority); 10018 if (typeof json === "object" && ".value" in json && json[".value"] !== null) { 10019 json = json[".value"]; 10020 } 10021 if (typeof json !== "object" || ".sv" in json) { 10022 const jsonLeaf = json; 10023 return new LeafNode(jsonLeaf, nodeFromJSON(priority)); 10024 } 10025 if (!(json instanceof Array) && USE_HINZE) { 10026 const children = []; 10027 let childrenHavePriority = false; 10028 const hinzeJsonObj = json; 10029 each(hinzeJsonObj, (key, child) => { 10030 if (key.substring(0, 1) !== ".") { 10031 const childNode = nodeFromJSON(child); 10032 if (!childNode.isEmpty()) { 10033 childrenHavePriority = childrenHavePriority || !childNode.getPriority().isEmpty(); 10034 children.push(new NamedNode(key, childNode)); 10035 } 10036 } 10037 }); 10038 if (children.length === 0) { 10039 return ChildrenNode.EMPTY_NODE; 10040 } 10041 const childSet = buildChildSet(children, NAME_ONLY_COMPARATOR, (namedNode) => namedNode.name, NAME_COMPARATOR); 10042 if (childrenHavePriority) { 10043 const sortedChildSet = buildChildSet(children, PRIORITY_INDEX.getCompare()); 10044 return new ChildrenNode(childSet, nodeFromJSON(priority), new IndexMap({ ".priority": sortedChildSet }, { ".priority": PRIORITY_INDEX })); 10045 } else { 10046 return new ChildrenNode(childSet, nodeFromJSON(priority), IndexMap.Default); 10047 } 10048 } else { 10049 let node = ChildrenNode.EMPTY_NODE; 10050 each(json, (key, childData) => { 10051 if (contains(json, key)) { 10052 if (key.substring(0, 1) !== ".") { 10053 const childNode = nodeFromJSON(childData); 10054 if (childNode.isLeafNode() || !childNode.isEmpty()) { 10055 node = node.updateImmediateChild(key, childNode); 10056 } 10057 } 10058 } 10059 }); 10060 return node.updatePriority(nodeFromJSON(priority)); 10061 } 10062 } 10063 setNodeFromJSON(nodeFromJSON); 10064 var PathIndex = class extends Index { 10065 constructor(indexPath_) { 10066 super(); 10067 this.indexPath_ = indexPath_; 10068 assert(!pathIsEmpty(indexPath_) && pathGetFront(indexPath_) !== ".priority", "Can't create PathIndex with empty path or .priority key"); 10069 } 10070 extractChild(snap) { 10071 return snap.getChild(this.indexPath_); 10072 } 10073 isDefinedOn(node) { 10074 return !node.getChild(this.indexPath_).isEmpty(); 10075 } 10076 compare(a, b) { 10077 const aChild = this.extractChild(a.node); 10078 const bChild = this.extractChild(b.node); 10079 const indexCmp = aChild.compareTo(bChild); 10080 if (indexCmp === 0) { 10081 return nameCompare(a.name, b.name); 10082 } else { 10083 return indexCmp; 10084 } 10085 } 10086 makePost(indexValue, name7) { 10087 const valueNode = nodeFromJSON(indexValue); 10088 const node = ChildrenNode.EMPTY_NODE.updateChild(this.indexPath_, valueNode); 10089 return new NamedNode(name7, node); 10090 } 10091 maxPost() { 10092 const node = ChildrenNode.EMPTY_NODE.updateChild(this.indexPath_, MAX_NODE); 10093 return new NamedNode(MAX_NAME, node); 10094 } 10095 toString() { 10096 return pathSlice(this.indexPath_, 0).join("/"); 10097 } 10098 }; 10099 var ValueIndex = class extends Index { 10100 compare(a, b) { 10101 const indexCmp = a.node.compareTo(b.node); 10102 if (indexCmp === 0) { 10103 return nameCompare(a.name, b.name); 10104 } else { 10105 return indexCmp; 10106 } 10107 } 10108 isDefinedOn(node) { 10109 return true; 10110 } 10111 indexedValueChanged(oldNode, newNode) { 10112 return !oldNode.equals(newNode); 10113 } 10114 minPost() { 10115 return NamedNode.MIN; 10116 } 10117 maxPost() { 10118 return NamedNode.MAX; 10119 } 10120 makePost(indexValue, name7) { 10121 const valueNode = nodeFromJSON(indexValue); 10122 return new NamedNode(name7, valueNode); 10123 } 10124 toString() { 10125 return ".value"; 10126 } 10127 }; 10128 var VALUE_INDEX = new ValueIndex(); 10129 var PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; 10130 var nextPushId = function() { 10131 let lastPushTime = 0; 10132 const lastRandChars = []; 10133 return function(now) { 10134 const duplicateTime = now === lastPushTime; 10135 lastPushTime = now; 10136 let i; 10137 const timeStampChars = new Array(8); 10138 for (i = 7; i >= 0; i--) { 10139 timeStampChars[i] = PUSH_CHARS.charAt(now % 64); 10140 now = Math.floor(now / 64); 10141 } 10142 assert(now === 0, "Cannot push at time == 0"); 10143 let id = timeStampChars.join(""); 10144 if (!duplicateTime) { 10145 for (i = 0; i < 12; i++) { 10146 lastRandChars[i] = Math.floor(Math.random() * 64); 10147 } 10148 } else { 10149 for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) { 10150 lastRandChars[i] = 0; 10151 } 10152 lastRandChars[i]++; 10153 } 10154 for (i = 0; i < 12; i++) { 10155 id += PUSH_CHARS.charAt(lastRandChars[i]); 10156 } 10157 assert(id.length === 20, "nextPushId: Length should be 20."); 10158 return id; 10159 }; 10160 }(); 10161 function changeValue(snapshotNode) { 10162 return { type: "value", snapshotNode }; 10163 } 10164 function changeChildAdded(childName, snapshotNode) { 10165 return { type: "child_added", snapshotNode, childName }; 10166 } 10167 function changeChildRemoved(childName, snapshotNode) { 10168 return { type: "child_removed", snapshotNode, childName }; 10169 } 10170 function changeChildChanged(childName, snapshotNode, oldSnap) { 10171 return { 10172 type: "child_changed", 10173 snapshotNode, 10174 childName, 10175 oldSnap 10176 }; 10177 } 10178 function changeChildMoved(childName, snapshotNode) { 10179 return { type: "child_moved", snapshotNode, childName }; 10180 } 10181 var QueryParams = class { 10182 constructor() { 10183 this.limitSet_ = false; 10184 this.startSet_ = false; 10185 this.startNameSet_ = false; 10186 this.startAfterSet_ = false; 10187 this.endSet_ = false; 10188 this.endNameSet_ = false; 10189 this.endBeforeSet_ = false; 10190 this.limit_ = 0; 10191 this.viewFrom_ = ""; 10192 this.indexStartValue_ = null; 10193 this.indexStartName_ = ""; 10194 this.indexEndValue_ = null; 10195 this.indexEndName_ = ""; 10196 this.index_ = PRIORITY_INDEX; 10197 } 10198 hasStart() { 10199 return this.startSet_; 10200 } 10201 hasStartAfter() { 10202 return this.startAfterSet_; 10203 } 10204 hasEndBefore() { 10205 return this.endBeforeSet_; 10206 } 10207 isViewFromLeft() { 10208 if (this.viewFrom_ === "") { 10209 return this.startSet_; 10210 } else { 10211 return this.viewFrom_ === "l"; 10212 } 10213 } 10214 getIndexStartValue() { 10215 assert(this.startSet_, "Only valid if start has been set"); 10216 return this.indexStartValue_; 10217 } 10218 getIndexStartName() { 10219 assert(this.startSet_, "Only valid if start has been set"); 10220 if (this.startNameSet_) { 10221 return this.indexStartName_; 10222 } else { 10223 return MIN_NAME; 10224 } 10225 } 10226 hasEnd() { 10227 return this.endSet_; 10228 } 10229 getIndexEndValue() { 10230 assert(this.endSet_, "Only valid if end has been set"); 10231 return this.indexEndValue_; 10232 } 10233 getIndexEndName() { 10234 assert(this.endSet_, "Only valid if end has been set"); 10235 if (this.endNameSet_) { 10236 return this.indexEndName_; 10237 } else { 10238 return MAX_NAME; 10239 } 10240 } 10241 hasLimit() { 10242 return this.limitSet_; 10243 } 10244 hasAnchoredLimit() { 10245 return this.limitSet_ && this.viewFrom_ !== ""; 10246 } 10247 getLimit() { 10248 assert(this.limitSet_, "Only valid if limit has been set"); 10249 return this.limit_; 10250 } 10251 getIndex() { 10252 return this.index_; 10253 } 10254 loadsAllData() { 10255 return !(this.startSet_ || this.endSet_ || this.limitSet_); 10256 } 10257 isDefault() { 10258 return this.loadsAllData() && this.index_ === PRIORITY_INDEX; 10259 } 10260 copy() { 10261 const copy = new QueryParams(); 10262 copy.limitSet_ = this.limitSet_; 10263 copy.limit_ = this.limit_; 10264 copy.startSet_ = this.startSet_; 10265 copy.indexStartValue_ = this.indexStartValue_; 10266 copy.startNameSet_ = this.startNameSet_; 10267 copy.indexStartName_ = this.indexStartName_; 10268 copy.endSet_ = this.endSet_; 10269 copy.indexEndValue_ = this.indexEndValue_; 10270 copy.endNameSet_ = this.endNameSet_; 10271 copy.indexEndName_ = this.indexEndName_; 10272 copy.index_ = this.index_; 10273 copy.viewFrom_ = this.viewFrom_; 10274 return copy; 10275 } 10276 }; 10277 function queryParamsToRestQueryStringParameters(queryParams) { 10278 const qs = {}; 10279 if (queryParams.isDefault()) { 10280 return qs; 10281 } 10282 let orderBy; 10283 if (queryParams.index_ === PRIORITY_INDEX) { 10284 orderBy = "$priority"; 10285 } else if (queryParams.index_ === VALUE_INDEX) { 10286 orderBy = "$value"; 10287 } else if (queryParams.index_ === KEY_INDEX) { 10288 orderBy = "$key"; 10289 } else { 10290 assert(queryParams.index_ instanceof PathIndex, "Unrecognized index type!"); 10291 orderBy = queryParams.index_.toString(); 10292 } 10293 qs["orderBy"] = stringify(orderBy); 10294 if (queryParams.startSet_) { 10295 qs["startAt"] = stringify(queryParams.indexStartValue_); 10296 if (queryParams.startNameSet_) { 10297 qs["startAt"] += "," + stringify(queryParams.indexStartName_); 10298 } 10299 } 10300 if (queryParams.endSet_) { 10301 qs["endAt"] = stringify(queryParams.indexEndValue_); 10302 if (queryParams.endNameSet_) { 10303 qs["endAt"] += "," + stringify(queryParams.indexEndName_); 10304 } 10305 } 10306 if (queryParams.limitSet_) { 10307 if (queryParams.isViewFromLeft()) { 10308 qs["limitToFirst"] = queryParams.limit_; 10309 } else { 10310 qs["limitToLast"] = queryParams.limit_; 10311 } 10312 } 10313 return qs; 10314 } 10315 function queryParamsGetQueryObject(queryParams) { 10316 const obj = {}; 10317 if (queryParams.startSet_) { 10318 obj["sp"] = queryParams.indexStartValue_; 10319 if (queryParams.startNameSet_) { 10320 obj["sn"] = queryParams.indexStartName_; 10321 } 10322 } 10323 if (queryParams.endSet_) { 10324 obj["ep"] = queryParams.indexEndValue_; 10325 if (queryParams.endNameSet_) { 10326 obj["en"] = queryParams.indexEndName_; 10327 } 10328 } 10329 if (queryParams.limitSet_) { 10330 obj["l"] = queryParams.limit_; 10331 let viewFrom = queryParams.viewFrom_; 10332 if (viewFrom === "") { 10333 if (queryParams.isViewFromLeft()) { 10334 viewFrom = "l"; 10335 } else { 10336 viewFrom = "r"; 10337 } 10338 } 10339 obj["vf"] = viewFrom; 10340 } 10341 if (queryParams.index_ !== PRIORITY_INDEX) { 10342 obj["i"] = queryParams.index_.toString(); 10343 } 10344 return obj; 10345 } 10346 var ReadonlyRestClient = class extends ServerActions { 10347 constructor(repoInfo_, onDataUpdate_, authTokenProvider_, appCheckTokenProvider_) { 10348 super(); 10349 this.repoInfo_ = repoInfo_; 10350 this.onDataUpdate_ = onDataUpdate_; 10351 this.authTokenProvider_ = authTokenProvider_; 10352 this.appCheckTokenProvider_ = appCheckTokenProvider_; 10353 this.log_ = logWrapper("p:rest:"); 10354 this.listens_ = {}; 10355 } 10356 reportStats(stats) { 10357 throw new Error("Method not implemented."); 10358 } 10359 static getListenId_(query, tag) { 10360 if (tag !== void 0) { 10361 return "tag$" + tag; 10362 } else { 10363 assert(query._queryParams.isDefault(), "should have a tag if it's not a default query."); 10364 return query._path.toString(); 10365 } 10366 } 10367 listen(query, currentHashFn, tag, onComplete) { 10368 const pathString = query._path.toString(); 10369 this.log_("Listen called for " + pathString + " " + query._queryIdentifier); 10370 const listenId = ReadonlyRestClient.getListenId_(query, tag); 10371 const thisListen = {}; 10372 this.listens_[listenId] = thisListen; 10373 const queryStringParameters = queryParamsToRestQueryStringParameters(query._queryParams); 10374 this.restRequest_(pathString + ".json", queryStringParameters, (error2, result) => { 10375 let data = result; 10376 if (error2 === 404) { 10377 data = null; 10378 error2 = null; 10379 } 10380 if (error2 === null) { 10381 this.onDataUpdate_(pathString, data, false, tag); 10382 } 10383 if (safeGet(this.listens_, listenId) === thisListen) { 10384 let status; 10385 if (!error2) { 10386 status = "ok"; 10387 } else if (error2 === 401) { 10388 status = "permission_denied"; 10389 } else { 10390 status = "rest_error:" + error2; 10391 } 10392 onComplete(status, null); 10393 } 10394 }); 10395 } 10396 unlisten(query, tag) { 10397 const listenId = ReadonlyRestClient.getListenId_(query, tag); 10398 delete this.listens_[listenId]; 10399 } 10400 get(query) { 10401 const queryStringParameters = queryParamsToRestQueryStringParameters(query._queryParams); 10402 const pathString = query._path.toString(); 10403 const deferred = new Deferred(); 10404 this.restRequest_(pathString + ".json", queryStringParameters, (error2, result) => { 10405 let data = result; 10406 if (error2 === 404) { 10407 data = null; 10408 error2 = null; 10409 } 10410 if (error2 === null) { 10411 this.onDataUpdate_(pathString, data, false, null); 10412 deferred.resolve(data); 10413 } else { 10414 deferred.reject(new Error(data)); 10415 } 10416 }); 10417 return deferred.promise; 10418 } 10419 refreshAuthToken(token) { 10420 } 10421 restRequest_(pathString, queryStringParameters = {}, callback) { 10422 queryStringParameters["format"] = "export"; 10423 return Promise.all([ 10424 this.authTokenProvider_.getToken(false), 10425 this.appCheckTokenProvider_.getToken(false) 10426 ]).then(([authToken, appCheckToken]) => { 10427 if (authToken && authToken.accessToken) { 10428 queryStringParameters["auth"] = authToken.accessToken; 10429 } 10430 if (appCheckToken && appCheckToken.token) { 10431 queryStringParameters["ac"] = appCheckToken.token; 10432 } 10433 const url = (this.repoInfo_.secure ? "https://" : "http://") + this.repoInfo_.host + pathString + "?ns=" + this.repoInfo_.namespace + querystring(queryStringParameters); 10434 this.log_("Sending REST request for " + url); 10435 const xhr = new XMLHttpRequest(); 10436 xhr.onreadystatechange = () => { 10437 if (callback && xhr.readyState === 4) { 10438 this.log_("REST Response for " + url + " received. status:", xhr.status, "response:", xhr.responseText); 10439 let res = null; 10440 if (xhr.status >= 200 && xhr.status < 300) { 10441 try { 10442 res = jsonEval(xhr.responseText); 10443 } catch (e) { 10444 warn("Failed to parse JSON response for " + url + ": " + xhr.responseText); 10445 } 10446 callback(null, res); 10447 } else { 10448 if (xhr.status !== 401 && xhr.status !== 404) { 10449 warn("Got unsuccessful REST response for " + url + " Status: " + xhr.status); 10450 } 10451 callback(xhr.status); 10452 } 10453 callback = null; 10454 } 10455 }; 10456 xhr.open("GET", url, true); 10457 xhr.send(); 10458 }); 10459 } 10460 }; 10461 var SnapshotHolder = class { 10462 constructor() { 10463 this.rootNode_ = ChildrenNode.EMPTY_NODE; 10464 } 10465 getNode(path) { 10466 return this.rootNode_.getChild(path); 10467 } 10468 updateSnapshot(path, newSnapshotNode) { 10469 this.rootNode_ = this.rootNode_.updateChild(path, newSnapshotNode); 10470 } 10471 }; 10472 function newSparseSnapshotTree() { 10473 return { 10474 value: null, 10475 children: /* @__PURE__ */ new Map() 10476 }; 10477 } 10478 function sparseSnapshotTreeRemember(sparseSnapshotTree, path, data) { 10479 if (pathIsEmpty(path)) { 10480 sparseSnapshotTree.value = data; 10481 sparseSnapshotTree.children.clear(); 10482 } else if (sparseSnapshotTree.value !== null) { 10483 sparseSnapshotTree.value = sparseSnapshotTree.value.updateChild(path, data); 10484 } else { 10485 const childKey = pathGetFront(path); 10486 if (!sparseSnapshotTree.children.has(childKey)) { 10487 sparseSnapshotTree.children.set(childKey, newSparseSnapshotTree()); 10488 } 10489 const child = sparseSnapshotTree.children.get(childKey); 10490 path = pathPopFront(path); 10491 sparseSnapshotTreeRemember(child, path, data); 10492 } 10493 } 10494 function sparseSnapshotTreeForEachTree(sparseSnapshotTree, prefixPath, func) { 10495 if (sparseSnapshotTree.value !== null) { 10496 func(prefixPath, sparseSnapshotTree.value); 10497 } else { 10498 sparseSnapshotTreeForEachChild(sparseSnapshotTree, (key, tree) => { 10499 const path = new Path(prefixPath.toString() + "/" + key); 10500 sparseSnapshotTreeForEachTree(tree, path, func); 10501 }); 10502 } 10503 } 10504 function sparseSnapshotTreeForEachChild(sparseSnapshotTree, func) { 10505 sparseSnapshotTree.children.forEach((tree, key) => { 10506 func(key, tree); 10507 }); 10508 } 10509 var StatsListener = class { 10510 constructor(collection_) { 10511 this.collection_ = collection_; 10512 this.last_ = null; 10513 } 10514 get() { 10515 const newStats = this.collection_.get(); 10516 const delta = Object.assign({}, newStats); 10517 if (this.last_) { 10518 each(this.last_, (stat, value) => { 10519 delta[stat] = delta[stat] - value; 10520 }); 10521 } 10522 this.last_ = newStats; 10523 return delta; 10524 } 10525 }; 10526 var FIRST_STATS_MIN_TIME = 10 * 1e3; 10527 var FIRST_STATS_MAX_TIME = 30 * 1e3; 10528 var REPORT_STATS_INTERVAL = 5 * 60 * 1e3; 10529 var StatsReporter = class { 10530 constructor(collection, server_) { 10531 this.server_ = server_; 10532 this.statsToReport_ = {}; 10533 this.statsListener_ = new StatsListener(collection); 10534 const timeout = FIRST_STATS_MIN_TIME + (FIRST_STATS_MAX_TIME - FIRST_STATS_MIN_TIME) * Math.random(); 10535 setTimeoutNonBlocking(this.reportStats_.bind(this), Math.floor(timeout)); 10536 } 10537 reportStats_() { 10538 const stats = this.statsListener_.get(); 10539 const reportedStats = {}; 10540 let haveStatsToReport = false; 10541 each(stats, (stat, value) => { 10542 if (value > 0 && contains(this.statsToReport_, stat)) { 10543 reportedStats[stat] = value; 10544 haveStatsToReport = true; 10545 } 10546 }); 10547 if (haveStatsToReport) { 10548 this.server_.reportStats(reportedStats); 10549 } 10550 setTimeoutNonBlocking(this.reportStats_.bind(this), Math.floor(Math.random() * 2 * REPORT_STATS_INTERVAL)); 10551 } 10552 }; 10553 var OperationType2; 10554 (function(OperationType3) { 10555 OperationType3[OperationType3["OVERWRITE"] = 0] = "OVERWRITE"; 10556 OperationType3[OperationType3["MERGE"] = 1] = "MERGE"; 10557 OperationType3[OperationType3["ACK_USER_WRITE"] = 2] = "ACK_USER_WRITE"; 10558 OperationType3[OperationType3["LISTEN_COMPLETE"] = 3] = "LISTEN_COMPLETE"; 10559 })(OperationType2 || (OperationType2 = {})); 10560 function newOperationSourceUser() { 10561 return { 10562 fromUser: true, 10563 fromServer: false, 10564 queryId: null, 10565 tagged: false 10566 }; 10567 } 10568 function newOperationSourceServer() { 10569 return { 10570 fromUser: false, 10571 fromServer: true, 10572 queryId: null, 10573 tagged: false 10574 }; 10575 } 10576 function newOperationSourceServerTaggedQuery(queryId) { 10577 return { 10578 fromUser: false, 10579 fromServer: true, 10580 queryId, 10581 tagged: true 10582 }; 10583 } 10584 var AckUserWrite = class { 10585 constructor(path, affectedTree, revert) { 10586 this.path = path; 10587 this.affectedTree = affectedTree; 10588 this.revert = revert; 10589 this.type = OperationType2.ACK_USER_WRITE; 10590 this.source = newOperationSourceUser(); 10591 } 10592 operationForChild(childName) { 10593 if (!pathIsEmpty(this.path)) { 10594 assert(pathGetFront(this.path) === childName, "operationForChild called for unrelated child."); 10595 return new AckUserWrite(pathPopFront(this.path), this.affectedTree, this.revert); 10596 } else if (this.affectedTree.value != null) { 10597 assert(this.affectedTree.children.isEmpty(), "affectedTree should not have overlapping affected paths."); 10598 return this; 10599 } else { 10600 const childTree = this.affectedTree.subtree(new Path(childName)); 10601 return new AckUserWrite(newEmptyPath(), childTree, this.revert); 10602 } 10603 } 10604 }; 10605 var Overwrite = class { 10606 constructor(source, path, snap) { 10607 this.source = source; 10608 this.path = path; 10609 this.snap = snap; 10610 this.type = OperationType2.OVERWRITE; 10611 } 10612 operationForChild(childName) { 10613 if (pathIsEmpty(this.path)) { 10614 return new Overwrite(this.source, newEmptyPath(), this.snap.getImmediateChild(childName)); 10615 } else { 10616 return new Overwrite(this.source, pathPopFront(this.path), this.snap); 10617 } 10618 } 10619 }; 10620 var Merge = class { 10621 constructor(source, path, children) { 10622 this.source = source; 10623 this.path = path; 10624 this.children = children; 10625 this.type = OperationType2.MERGE; 10626 } 10627 operationForChild(childName) { 10628 if (pathIsEmpty(this.path)) { 10629 const childTree = this.children.subtree(new Path(childName)); 10630 if (childTree.isEmpty()) { 10631 return null; 10632 } else if (childTree.value) { 10633 return new Overwrite(this.source, newEmptyPath(), childTree.value); 10634 } else { 10635 return new Merge(this.source, newEmptyPath(), childTree); 10636 } 10637 } else { 10638 assert(pathGetFront(this.path) === childName, "Can't get a merge for a child not on the path of the operation"); 10639 return new Merge(this.source, pathPopFront(this.path), this.children); 10640 } 10641 } 10642 toString() { 10643 return "Operation(" + this.path + ": " + this.source.toString() + " merge: " + this.children.toString() + ")"; 10644 } 10645 }; 10646 var CacheNode = class { 10647 constructor(node_, fullyInitialized_, filtered_) { 10648 this.node_ = node_; 10649 this.fullyInitialized_ = fullyInitialized_; 10650 this.filtered_ = filtered_; 10651 } 10652 isFullyInitialized() { 10653 return this.fullyInitialized_; 10654 } 10655 isFiltered() { 10656 return this.filtered_; 10657 } 10658 isCompleteForPath(path) { 10659 if (pathIsEmpty(path)) { 10660 return this.isFullyInitialized() && !this.filtered_; 10661 } 10662 const childKey = pathGetFront(path); 10663 return this.isCompleteForChild(childKey); 10664 } 10665 isCompleteForChild(key) { 10666 return this.isFullyInitialized() && !this.filtered_ || this.node_.hasChild(key); 10667 } 10668 getNode() { 10669 return this.node_; 10670 } 10671 }; 10672 function eventGeneratorGenerateEventsForChanges(eventGenerator, changes, eventCache, eventRegistrations) { 10673 const events = []; 10674 const moves = []; 10675 changes.forEach((change) => { 10676 if (change.type === "child_changed" && eventGenerator.index_.indexedValueChanged(change.oldSnap, change.snapshotNode)) { 10677 moves.push(changeChildMoved(change.childName, change.snapshotNode)); 10678 } 10679 }); 10680 eventGeneratorGenerateEventsForType(eventGenerator, events, "child_removed", changes, eventRegistrations, eventCache); 10681 eventGeneratorGenerateEventsForType(eventGenerator, events, "child_added", changes, eventRegistrations, eventCache); 10682 eventGeneratorGenerateEventsForType(eventGenerator, events, "child_moved", moves, eventRegistrations, eventCache); 10683 eventGeneratorGenerateEventsForType(eventGenerator, events, "child_changed", changes, eventRegistrations, eventCache); 10684 eventGeneratorGenerateEventsForType(eventGenerator, events, "value", changes, eventRegistrations, eventCache); 10685 return events; 10686 } 10687 function eventGeneratorGenerateEventsForType(eventGenerator, events, eventType, changes, registrations, eventCache) { 10688 const filteredChanges = changes.filter((change) => change.type === eventType); 10689 filteredChanges.sort((a, b) => eventGeneratorCompareChanges(eventGenerator, a, b)); 10690 filteredChanges.forEach((change) => { 10691 const materializedChange = eventGeneratorMaterializeSingleChange(eventGenerator, change, eventCache); 10692 registrations.forEach((registration) => { 10693 if (registration.respondsTo(change.type)) { 10694 events.push(registration.createEvent(materializedChange, eventGenerator.query_)); 10695 } 10696 }); 10697 }); 10698 } 10699 function eventGeneratorMaterializeSingleChange(eventGenerator, change, eventCache) { 10700 if (change.type === "value" || change.type === "child_removed") { 10701 return change; 10702 } else { 10703 change.prevName = eventCache.getPredecessorChildName(change.childName, change.snapshotNode, eventGenerator.index_); 10704 return change; 10705 } 10706 } 10707 function eventGeneratorCompareChanges(eventGenerator, a, b) { 10708 if (a.childName == null || b.childName == null) { 10709 throw assertionError("Should only compare child_ events."); 10710 } 10711 const aWrapped = new NamedNode(a.childName, a.snapshotNode); 10712 const bWrapped = new NamedNode(b.childName, b.snapshotNode); 10713 return eventGenerator.index_.compare(aWrapped, bWrapped); 10714 } 10715 function newViewCache(eventCache, serverCache) { 10716 return { eventCache, serverCache }; 10717 } 10718 function viewCacheUpdateEventSnap(viewCache, eventSnap, complete, filtered) { 10719 return newViewCache(new CacheNode(eventSnap, complete, filtered), viewCache.serverCache); 10720 } 10721 function viewCacheUpdateServerSnap(viewCache, serverSnap, complete, filtered) { 10722 return newViewCache(viewCache.eventCache, new CacheNode(serverSnap, complete, filtered)); 10723 } 10724 function viewCacheGetCompleteEventSnap(viewCache) { 10725 return viewCache.eventCache.isFullyInitialized() ? viewCache.eventCache.getNode() : null; 10726 } 10727 function viewCacheGetCompleteServerSnap(viewCache) { 10728 return viewCache.serverCache.isFullyInitialized() ? viewCache.serverCache.getNode() : null; 10729 } 10730 var emptyChildrenSingleton; 10731 var EmptyChildren = () => { 10732 if (!emptyChildrenSingleton) { 10733 emptyChildrenSingleton = new SortedMap(stringCompare); 10734 } 10735 return emptyChildrenSingleton; 10736 }; 10737 var ImmutableTree = class { 10738 constructor(value, children = EmptyChildren()) { 10739 this.value = value; 10740 this.children = children; 10741 } 10742 static fromObject(obj) { 10743 let tree = new ImmutableTree(null); 10744 each(obj, (childPath, childSnap) => { 10745 tree = tree.set(new Path(childPath), childSnap); 10746 }); 10747 return tree; 10748 } 10749 isEmpty() { 10750 return this.value === null && this.children.isEmpty(); 10751 } 10752 findRootMostMatchingPathAndValue(relativePath, predicate) { 10753 if (this.value != null && predicate(this.value)) { 10754 return { path: newEmptyPath(), value: this.value }; 10755 } else { 10756 if (pathIsEmpty(relativePath)) { 10757 return null; 10758 } else { 10759 const front = pathGetFront(relativePath); 10760 const child = this.children.get(front); 10761 if (child !== null) { 10762 const childExistingPathAndValue = child.findRootMostMatchingPathAndValue(pathPopFront(relativePath), predicate); 10763 if (childExistingPathAndValue != null) { 10764 const fullPath = pathChild(new Path(front), childExistingPathAndValue.path); 10765 return { path: fullPath, value: childExistingPathAndValue.value }; 10766 } else { 10767 return null; 10768 } 10769 } else { 10770 return null; 10771 } 10772 } 10773 } 10774 } 10775 findRootMostValueAndPath(relativePath) { 10776 return this.findRootMostMatchingPathAndValue(relativePath, () => true); 10777 } 10778 subtree(relativePath) { 10779 if (pathIsEmpty(relativePath)) { 10780 return this; 10781 } else { 10782 const front = pathGetFront(relativePath); 10783 const childTree = this.children.get(front); 10784 if (childTree !== null) { 10785 return childTree.subtree(pathPopFront(relativePath)); 10786 } else { 10787 return new ImmutableTree(null); 10788 } 10789 } 10790 } 10791 set(relativePath, toSet) { 10792 if (pathIsEmpty(relativePath)) { 10793 return new ImmutableTree(toSet, this.children); 10794 } else { 10795 const front = pathGetFront(relativePath); 10796 const child = this.children.get(front) || new ImmutableTree(null); 10797 const newChild = child.set(pathPopFront(relativePath), toSet); 10798 const newChildren = this.children.insert(front, newChild); 10799 return new ImmutableTree(this.value, newChildren); 10800 } 10801 } 10802 remove(relativePath) { 10803 if (pathIsEmpty(relativePath)) { 10804 if (this.children.isEmpty()) { 10805 return new ImmutableTree(null); 10806 } else { 10807 return new ImmutableTree(null, this.children); 10808 } 10809 } else { 10810 const front = pathGetFront(relativePath); 10811 const child = this.children.get(front); 10812 if (child) { 10813 const newChild = child.remove(pathPopFront(relativePath)); 10814 let newChildren; 10815 if (newChild.isEmpty()) { 10816 newChildren = this.children.remove(front); 10817 } else { 10818 newChildren = this.children.insert(front, newChild); 10819 } 10820 if (this.value === null && newChildren.isEmpty()) { 10821 return new ImmutableTree(null); 10822 } else { 10823 return new ImmutableTree(this.value, newChildren); 10824 } 10825 } else { 10826 return this; 10827 } 10828 } 10829 } 10830 get(relativePath) { 10831 if (pathIsEmpty(relativePath)) { 10832 return this.value; 10833 } else { 10834 const front = pathGetFront(relativePath); 10835 const child = this.children.get(front); 10836 if (child) { 10837 return child.get(pathPopFront(relativePath)); 10838 } else { 10839 return null; 10840 } 10841 } 10842 } 10843 setTree(relativePath, newTree) { 10844 if (pathIsEmpty(relativePath)) { 10845 return newTree; 10846 } else { 10847 const front = pathGetFront(relativePath); 10848 const child = this.children.get(front) || new ImmutableTree(null); 10849 const newChild = child.setTree(pathPopFront(relativePath), newTree); 10850 let newChildren; 10851 if (newChild.isEmpty()) { 10852 newChildren = this.children.remove(front); 10853 } else { 10854 newChildren = this.children.insert(front, newChild); 10855 } 10856 return new ImmutableTree(this.value, newChildren); 10857 } 10858 } 10859 fold(fn) { 10860 return this.fold_(newEmptyPath(), fn); 10861 } 10862 fold_(pathSoFar, fn) { 10863 const accum = {}; 10864 this.children.inorderTraversal((childKey, childTree) => { 10865 accum[childKey] = childTree.fold_(pathChild(pathSoFar, childKey), fn); 10866 }); 10867 return fn(pathSoFar, this.value, accum); 10868 } 10869 findOnPath(path, f) { 10870 return this.findOnPath_(path, newEmptyPath(), f); 10871 } 10872 findOnPath_(pathToFollow, pathSoFar, f) { 10873 const result = this.value ? f(pathSoFar, this.value) : false; 10874 if (result) { 10875 return result; 10876 } else { 10877 if (pathIsEmpty(pathToFollow)) { 10878 return null; 10879 } else { 10880 const front = pathGetFront(pathToFollow); 10881 const nextChild = this.children.get(front); 10882 if (nextChild) { 10883 return nextChild.findOnPath_(pathPopFront(pathToFollow), pathChild(pathSoFar, front), f); 10884 } else { 10885 return null; 10886 } 10887 } 10888 } 10889 } 10890 foreachOnPath(path, f) { 10891 return this.foreachOnPath_(path, newEmptyPath(), f); 10892 } 10893 foreachOnPath_(pathToFollow, currentRelativePath, f) { 10894 if (pathIsEmpty(pathToFollow)) { 10895 return this; 10896 } else { 10897 if (this.value) { 10898 f(currentRelativePath, this.value); 10899 } 10900 const front = pathGetFront(pathToFollow); 10901 const nextChild = this.children.get(front); 10902 if (nextChild) { 10903 return nextChild.foreachOnPath_(pathPopFront(pathToFollow), pathChild(currentRelativePath, front), f); 10904 } else { 10905 return new ImmutableTree(null); 10906 } 10907 } 10908 } 10909 foreach(f) { 10910 this.foreach_(newEmptyPath(), f); 10911 } 10912 foreach_(currentRelativePath, f) { 10913 this.children.inorderTraversal((childName, childTree) => { 10914 childTree.foreach_(pathChild(currentRelativePath, childName), f); 10915 }); 10916 if (this.value) { 10917 f(currentRelativePath, this.value); 10918 } 10919 } 10920 foreachChild(f) { 10921 this.children.inorderTraversal((childName, childTree) => { 10922 if (childTree.value) { 10923 f(childName, childTree.value); 10924 } 10925 }); 10926 } 10927 }; 10928 var CompoundWrite = class { 10929 constructor(writeTree_) { 10930 this.writeTree_ = writeTree_; 10931 } 10932 static empty() { 10933 return new CompoundWrite(new ImmutableTree(null)); 10934 } 10935 }; 10936 function compoundWriteAddWrite(compoundWrite, path, node) { 10937 if (pathIsEmpty(path)) { 10938 return new CompoundWrite(new ImmutableTree(node)); 10939 } else { 10940 const rootmost = compoundWrite.writeTree_.findRootMostValueAndPath(path); 10941 if (rootmost != null) { 10942 const rootMostPath = rootmost.path; 10943 let value = rootmost.value; 10944 const relativePath = newRelativePath(rootMostPath, path); 10945 value = value.updateChild(relativePath, node); 10946 return new CompoundWrite(compoundWrite.writeTree_.set(rootMostPath, value)); 10947 } else { 10948 const subtree = new ImmutableTree(node); 10949 const newWriteTree2 = compoundWrite.writeTree_.setTree(path, subtree); 10950 return new CompoundWrite(newWriteTree2); 10951 } 10952 } 10953 } 10954 function compoundWriteAddWrites(compoundWrite, path, updates) { 10955 let newWrite = compoundWrite; 10956 each(updates, (childKey, node) => { 10957 newWrite = compoundWriteAddWrite(newWrite, pathChild(path, childKey), node); 10958 }); 10959 return newWrite; 10960 } 10961 function compoundWriteRemoveWrite(compoundWrite, path) { 10962 if (pathIsEmpty(path)) { 10963 return CompoundWrite.empty(); 10964 } else { 10965 const newWriteTree2 = compoundWrite.writeTree_.setTree(path, new ImmutableTree(null)); 10966 return new CompoundWrite(newWriteTree2); 10967 } 10968 } 10969 function compoundWriteHasCompleteWrite(compoundWrite, path) { 10970 return compoundWriteGetCompleteNode(compoundWrite, path) != null; 10971 } 10972 function compoundWriteGetCompleteNode(compoundWrite, path) { 10973 const rootmost = compoundWrite.writeTree_.findRootMostValueAndPath(path); 10974 if (rootmost != null) { 10975 return compoundWrite.writeTree_.get(rootmost.path).getChild(newRelativePath(rootmost.path, path)); 10976 } else { 10977 return null; 10978 } 10979 } 10980 function compoundWriteGetCompleteChildren(compoundWrite) { 10981 const children = []; 10982 const node = compoundWrite.writeTree_.value; 10983 if (node != null) { 10984 if (!node.isLeafNode()) { 10985 node.forEachChild(PRIORITY_INDEX, (childName, childNode) => { 10986 children.push(new NamedNode(childName, childNode)); 10987 }); 10988 } 10989 } else { 10990 compoundWrite.writeTree_.children.inorderTraversal((childName, childTree) => { 10991 if (childTree.value != null) { 10992 children.push(new NamedNode(childName, childTree.value)); 10993 } 10994 }); 10995 } 10996 return children; 10997 } 10998 function compoundWriteChildCompoundWrite(compoundWrite, path) { 10999 if (pathIsEmpty(path)) { 11000 return compoundWrite; 11001 } else { 11002 const shadowingNode = compoundWriteGetCompleteNode(compoundWrite, path); 11003 if (shadowingNode != null) { 11004 return new CompoundWrite(new ImmutableTree(shadowingNode)); 11005 } else { 11006 return new CompoundWrite(compoundWrite.writeTree_.subtree(path)); 11007 } 11008 } 11009 } 11010 function compoundWriteIsEmpty(compoundWrite) { 11011 return compoundWrite.writeTree_.isEmpty(); 11012 } 11013 function compoundWriteApply(compoundWrite, node) { 11014 return applySubtreeWrite(newEmptyPath(), compoundWrite.writeTree_, node); 11015 } 11016 function applySubtreeWrite(relativePath, writeTree, node) { 11017 if (writeTree.value != null) { 11018 return node.updateChild(relativePath, writeTree.value); 11019 } else { 11020 let priorityWrite = null; 11021 writeTree.children.inorderTraversal((childKey, childTree) => { 11022 if (childKey === ".priority") { 11023 assert(childTree.value !== null, "Priority writes must always be leaf nodes"); 11024 priorityWrite = childTree.value; 11025 } else { 11026 node = applySubtreeWrite(pathChild(relativePath, childKey), childTree, node); 11027 } 11028 }); 11029 if (!node.getChild(relativePath).isEmpty() && priorityWrite !== null) { 11030 node = node.updateChild(pathChild(relativePath, ".priority"), priorityWrite); 11031 } 11032 return node; 11033 } 11034 } 11035 function writeTreeChildWrites(writeTree, path) { 11036 return newWriteTreeRef(path, writeTree); 11037 } 11038 function writeTreeAddOverwrite(writeTree, path, snap, writeId, visible) { 11039 assert(writeId > writeTree.lastWriteId, "Stacking an older write on top of newer ones"); 11040 if (visible === void 0) { 11041 visible = true; 11042 } 11043 writeTree.allWrites.push({ 11044 path, 11045 snap, 11046 writeId, 11047 visible 11048 }); 11049 if (visible) { 11050 writeTree.visibleWrites = compoundWriteAddWrite(writeTree.visibleWrites, path, snap); 11051 } 11052 writeTree.lastWriteId = writeId; 11053 } 11054 function writeTreeGetWrite(writeTree, writeId) { 11055 for (let i = 0; i < writeTree.allWrites.length; i++) { 11056 const record = writeTree.allWrites[i]; 11057 if (record.writeId === writeId) { 11058 return record; 11059 } 11060 } 11061 return null; 11062 } 11063 function writeTreeRemoveWrite(writeTree, writeId) { 11064 const idx = writeTree.allWrites.findIndex((s) => { 11065 return s.writeId === writeId; 11066 }); 11067 assert(idx >= 0, "removeWrite called with nonexistent writeId."); 11068 const writeToRemove = writeTree.allWrites[idx]; 11069 writeTree.allWrites.splice(idx, 1); 11070 let removedWriteWasVisible = writeToRemove.visible; 11071 let removedWriteOverlapsWithOtherWrites = false; 11072 let i = writeTree.allWrites.length - 1; 11073 while (removedWriteWasVisible && i >= 0) { 11074 const currentWrite = writeTree.allWrites[i]; 11075 if (currentWrite.visible) { 11076 if (i >= idx && writeTreeRecordContainsPath_(currentWrite, writeToRemove.path)) { 11077 removedWriteWasVisible = false; 11078 } else if (pathContains(writeToRemove.path, currentWrite.path)) { 11079 removedWriteOverlapsWithOtherWrites = true; 11080 } 11081 } 11082 i--; 11083 } 11084 if (!removedWriteWasVisible) { 11085 return false; 11086 } else if (removedWriteOverlapsWithOtherWrites) { 11087 writeTreeResetTree_(writeTree); 11088 return true; 11089 } else { 11090 if (writeToRemove.snap) { 11091 writeTree.visibleWrites = compoundWriteRemoveWrite(writeTree.visibleWrites, writeToRemove.path); 11092 } else { 11093 const children = writeToRemove.children; 11094 each(children, (childName) => { 11095 writeTree.visibleWrites = compoundWriteRemoveWrite(writeTree.visibleWrites, pathChild(writeToRemove.path, childName)); 11096 }); 11097 } 11098 return true; 11099 } 11100 } 11101 function writeTreeRecordContainsPath_(writeRecord, path) { 11102 if (writeRecord.snap) { 11103 return pathContains(writeRecord.path, path); 11104 } else { 11105 for (const childName in writeRecord.children) { 11106 if (writeRecord.children.hasOwnProperty(childName) && pathContains(pathChild(writeRecord.path, childName), path)) { 11107 return true; 11108 } 11109 } 11110 return false; 11111 } 11112 } 11113 function writeTreeResetTree_(writeTree) { 11114 writeTree.visibleWrites = writeTreeLayerTree_(writeTree.allWrites, writeTreeDefaultFilter_, newEmptyPath()); 11115 if (writeTree.allWrites.length > 0) { 11116 writeTree.lastWriteId = writeTree.allWrites[writeTree.allWrites.length - 1].writeId; 11117 } else { 11118 writeTree.lastWriteId = -1; 11119 } 11120 } 11121 function writeTreeDefaultFilter_(write) { 11122 return write.visible; 11123 } 11124 function writeTreeLayerTree_(writes, filter, treeRoot) { 11125 let compoundWrite = CompoundWrite.empty(); 11126 for (let i = 0; i < writes.length; ++i) { 11127 const write = writes[i]; 11128 if (filter(write)) { 11129 const writePath = write.path; 11130 let relativePath; 11131 if (write.snap) { 11132 if (pathContains(treeRoot, writePath)) { 11133 relativePath = newRelativePath(treeRoot, writePath); 11134 compoundWrite = compoundWriteAddWrite(compoundWrite, relativePath, write.snap); 11135 } else if (pathContains(writePath, treeRoot)) { 11136 relativePath = newRelativePath(writePath, treeRoot); 11137 compoundWrite = compoundWriteAddWrite(compoundWrite, newEmptyPath(), write.snap.getChild(relativePath)); 11138 } else 11139 ; 11140 } else if (write.children) { 11141 if (pathContains(treeRoot, writePath)) { 11142 relativePath = newRelativePath(treeRoot, writePath); 11143 compoundWrite = compoundWriteAddWrites(compoundWrite, relativePath, write.children); 11144 } else if (pathContains(writePath, treeRoot)) { 11145 relativePath = newRelativePath(writePath, treeRoot); 11146 if (pathIsEmpty(relativePath)) { 11147 compoundWrite = compoundWriteAddWrites(compoundWrite, newEmptyPath(), write.children); 11148 } else { 11149 const child = safeGet(write.children, pathGetFront(relativePath)); 11150 if (child) { 11151 const deepNode = child.getChild(pathPopFront(relativePath)); 11152 compoundWrite = compoundWriteAddWrite(compoundWrite, newEmptyPath(), deepNode); 11153 } 11154 } 11155 } else 11156 ; 11157 } else { 11158 throw assertionError("WriteRecord should have .snap or .children"); 11159 } 11160 } 11161 } 11162 return compoundWrite; 11163 } 11164 function writeTreeCalcCompleteEventCache(writeTree, treePath, completeServerCache, writeIdsToExclude, includeHiddenWrites) { 11165 if (!writeIdsToExclude && !includeHiddenWrites) { 11166 const shadowingNode = compoundWriteGetCompleteNode(writeTree.visibleWrites, treePath); 11167 if (shadowingNode != null) { 11168 return shadowingNode; 11169 } else { 11170 const subMerge = compoundWriteChildCompoundWrite(writeTree.visibleWrites, treePath); 11171 if (compoundWriteIsEmpty(subMerge)) { 11172 return completeServerCache; 11173 } else if (completeServerCache == null && !compoundWriteHasCompleteWrite(subMerge, newEmptyPath())) { 11174 return null; 11175 } else { 11176 const layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE; 11177 return compoundWriteApply(subMerge, layeredCache); 11178 } 11179 } 11180 } else { 11181 const merge = compoundWriteChildCompoundWrite(writeTree.visibleWrites, treePath); 11182 if (!includeHiddenWrites && compoundWriteIsEmpty(merge)) { 11183 return completeServerCache; 11184 } else { 11185 if (!includeHiddenWrites && completeServerCache == null && !compoundWriteHasCompleteWrite(merge, newEmptyPath())) { 11186 return null; 11187 } else { 11188 const filter = function(write) { 11189 return (write.visible || includeHiddenWrites) && (!writeIdsToExclude || !~writeIdsToExclude.indexOf(write.writeId)) && (pathContains(write.path, treePath) || pathContains(treePath, write.path)); 11190 }; 11191 const mergeAtPath = writeTreeLayerTree_(writeTree.allWrites, filter, treePath); 11192 const layeredCache = completeServerCache || ChildrenNode.EMPTY_NODE; 11193 return compoundWriteApply(mergeAtPath, layeredCache); 11194 } 11195 } 11196 } 11197 } 11198 function writeTreeCalcCompleteEventChildren(writeTree, treePath, completeServerChildren) { 11199 let completeChildren = ChildrenNode.EMPTY_NODE; 11200 const topLevelSet = compoundWriteGetCompleteNode(writeTree.visibleWrites, treePath); 11201 if (topLevelSet) { 11202 if (!topLevelSet.isLeafNode()) { 11203 topLevelSet.forEachChild(PRIORITY_INDEX, (childName, childSnap) => { 11204 completeChildren = completeChildren.updateImmediateChild(childName, childSnap); 11205 }); 11206 } 11207 return completeChildren; 11208 } else if (completeServerChildren) { 11209 const merge = compoundWriteChildCompoundWrite(writeTree.visibleWrites, treePath); 11210 completeServerChildren.forEachChild(PRIORITY_INDEX, (childName, childNode) => { 11211 const node = compoundWriteApply(compoundWriteChildCompoundWrite(merge, new Path(childName)), childNode); 11212 completeChildren = completeChildren.updateImmediateChild(childName, node); 11213 }); 11214 compoundWriteGetCompleteChildren(merge).forEach((namedNode) => { 11215 completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node); 11216 }); 11217 return completeChildren; 11218 } else { 11219 const merge = compoundWriteChildCompoundWrite(writeTree.visibleWrites, treePath); 11220 compoundWriteGetCompleteChildren(merge).forEach((namedNode) => { 11221 completeChildren = completeChildren.updateImmediateChild(namedNode.name, namedNode.node); 11222 }); 11223 return completeChildren; 11224 } 11225 } 11226 function writeTreeCalcEventCacheAfterServerOverwrite(writeTree, treePath, childPath, existingEventSnap, existingServerSnap) { 11227 assert(existingEventSnap || existingServerSnap, "Either existingEventSnap or existingServerSnap must exist"); 11228 const path = pathChild(treePath, childPath); 11229 if (compoundWriteHasCompleteWrite(writeTree.visibleWrites, path)) { 11230 return null; 11231 } else { 11232 const childMerge = compoundWriteChildCompoundWrite(writeTree.visibleWrites, path); 11233 if (compoundWriteIsEmpty(childMerge)) { 11234 return existingServerSnap.getChild(childPath); 11235 } else { 11236 return compoundWriteApply(childMerge, existingServerSnap.getChild(childPath)); 11237 } 11238 } 11239 } 11240 function writeTreeCalcCompleteChild(writeTree, treePath, childKey, existingServerSnap) { 11241 const path = pathChild(treePath, childKey); 11242 const shadowingNode = compoundWriteGetCompleteNode(writeTree.visibleWrites, path); 11243 if (shadowingNode != null) { 11244 return shadowingNode; 11245 } else { 11246 if (existingServerSnap.isCompleteForChild(childKey)) { 11247 const childMerge = compoundWriteChildCompoundWrite(writeTree.visibleWrites, path); 11248 return compoundWriteApply(childMerge, existingServerSnap.getNode().getImmediateChild(childKey)); 11249 } else { 11250 return null; 11251 } 11252 } 11253 } 11254 function writeTreeShadowingWrite(writeTree, path) { 11255 return compoundWriteGetCompleteNode(writeTree.visibleWrites, path); 11256 } 11257 function writeTreeCalcIndexedSlice(writeTree, treePath, completeServerData, startPost, count, reverse, index) { 11258 let toIterate; 11259 const merge = compoundWriteChildCompoundWrite(writeTree.visibleWrites, treePath); 11260 const shadowingNode = compoundWriteGetCompleteNode(merge, newEmptyPath()); 11261 if (shadowingNode != null) { 11262 toIterate = shadowingNode; 11263 } else if (completeServerData != null) { 11264 toIterate = compoundWriteApply(merge, completeServerData); 11265 } else { 11266 return []; 11267 } 11268 toIterate = toIterate.withIndex(index); 11269 if (!toIterate.isEmpty() && !toIterate.isLeafNode()) { 11270 const nodes = []; 11271 const cmp = index.getCompare(); 11272 const iter = reverse ? toIterate.getReverseIteratorFrom(startPost, index) : toIterate.getIteratorFrom(startPost, index); 11273 let next = iter.getNext(); 11274 while (next && nodes.length < count) { 11275 if (cmp(next, startPost) !== 0) { 11276 nodes.push(next); 11277 } 11278 next = iter.getNext(); 11279 } 11280 return nodes; 11281 } else { 11282 return []; 11283 } 11284 } 11285 function newWriteTree() { 11286 return { 11287 visibleWrites: CompoundWrite.empty(), 11288 allWrites: [], 11289 lastWriteId: -1 11290 }; 11291 } 11292 function writeTreeRefCalcCompleteEventCache(writeTreeRef, completeServerCache, writeIdsToExclude, includeHiddenWrites) { 11293 return writeTreeCalcCompleteEventCache(writeTreeRef.writeTree, writeTreeRef.treePath, completeServerCache, writeIdsToExclude, includeHiddenWrites); 11294 } 11295 function writeTreeRefCalcCompleteEventChildren(writeTreeRef, completeServerChildren) { 11296 return writeTreeCalcCompleteEventChildren(writeTreeRef.writeTree, writeTreeRef.treePath, completeServerChildren); 11297 } 11298 function writeTreeRefCalcEventCacheAfterServerOverwrite(writeTreeRef, path, existingEventSnap, existingServerSnap) { 11299 return writeTreeCalcEventCacheAfterServerOverwrite(writeTreeRef.writeTree, writeTreeRef.treePath, path, existingEventSnap, existingServerSnap); 11300 } 11301 function writeTreeRefShadowingWrite(writeTreeRef, path) { 11302 return writeTreeShadowingWrite(writeTreeRef.writeTree, pathChild(writeTreeRef.treePath, path)); 11303 } 11304 function writeTreeRefCalcIndexedSlice(writeTreeRef, completeServerData, startPost, count, reverse, index) { 11305 return writeTreeCalcIndexedSlice(writeTreeRef.writeTree, writeTreeRef.treePath, completeServerData, startPost, count, reverse, index); 11306 } 11307 function writeTreeRefCalcCompleteChild(writeTreeRef, childKey, existingServerCache) { 11308 return writeTreeCalcCompleteChild(writeTreeRef.writeTree, writeTreeRef.treePath, childKey, existingServerCache); 11309 } 11310 function writeTreeRefChild(writeTreeRef, childName) { 11311 return newWriteTreeRef(pathChild(writeTreeRef.treePath, childName), writeTreeRef.writeTree); 11312 } 11313 function newWriteTreeRef(path, writeTree) { 11314 return { 11315 treePath: path, 11316 writeTree 11317 }; 11318 } 11319 var ChildChangeAccumulator = class { 11320 constructor() { 11321 this.changeMap = /* @__PURE__ */ new Map(); 11322 } 11323 trackChildChange(change) { 11324 const type = change.type; 11325 const childKey = change.childName; 11326 assert(type === "child_added" || type === "child_changed" || type === "child_removed", "Only child changes supported for tracking"); 11327 assert(childKey !== ".priority", "Only non-priority child changes can be tracked."); 11328 const oldChange = this.changeMap.get(childKey); 11329 if (oldChange) { 11330 const oldType = oldChange.type; 11331 if (type === "child_added" && oldType === "child_removed") { 11332 this.changeMap.set(childKey, changeChildChanged(childKey, change.snapshotNode, oldChange.snapshotNode)); 11333 } else if (type === "child_removed" && oldType === "child_added") { 11334 this.changeMap.delete(childKey); 11335 } else if (type === "child_removed" && oldType === "child_changed") { 11336 this.changeMap.set(childKey, changeChildRemoved(childKey, oldChange.oldSnap)); 11337 } else if (type === "child_changed" && oldType === "child_added") { 11338 this.changeMap.set(childKey, changeChildAdded(childKey, change.snapshotNode)); 11339 } else if (type === "child_changed" && oldType === "child_changed") { 11340 this.changeMap.set(childKey, changeChildChanged(childKey, change.snapshotNode, oldChange.oldSnap)); 11341 } else { 11342 throw assertionError("Illegal combination of changes: " + change + " occurred after " + oldChange); 11343 } 11344 } else { 11345 this.changeMap.set(childKey, change); 11346 } 11347 } 11348 getChanges() { 11349 return Array.from(this.changeMap.values()); 11350 } 11351 }; 11352 var NoCompleteChildSource_ = class { 11353 getCompleteChild(childKey) { 11354 return null; 11355 } 11356 getChildAfterChild(index, child, reverse) { 11357 return null; 11358 } 11359 }; 11360 var NO_COMPLETE_CHILD_SOURCE = new NoCompleteChildSource_(); 11361 var WriteTreeCompleteChildSource = class { 11362 constructor(writes_, viewCache_, optCompleteServerCache_ = null) { 11363 this.writes_ = writes_; 11364 this.viewCache_ = viewCache_; 11365 this.optCompleteServerCache_ = optCompleteServerCache_; 11366 } 11367 getCompleteChild(childKey) { 11368 const node = this.viewCache_.eventCache; 11369 if (node.isCompleteForChild(childKey)) { 11370 return node.getNode().getImmediateChild(childKey); 11371 } else { 11372 const serverNode = this.optCompleteServerCache_ != null ? new CacheNode(this.optCompleteServerCache_, true, false) : this.viewCache_.serverCache; 11373 return writeTreeRefCalcCompleteChild(this.writes_, childKey, serverNode); 11374 } 11375 } 11376 getChildAfterChild(index, child, reverse) { 11377 const completeServerData = this.optCompleteServerCache_ != null ? this.optCompleteServerCache_ : viewCacheGetCompleteServerSnap(this.viewCache_); 11378 const nodes = writeTreeRefCalcIndexedSlice(this.writes_, completeServerData, child, 1, reverse, index); 11379 if (nodes.length === 0) { 11380 return null; 11381 } else { 11382 return nodes[0]; 11383 } 11384 } 11385 }; 11386 function viewProcessorAssertIndexed(viewProcessor, viewCache) { 11387 assert(viewCache.eventCache.getNode().isIndexed(viewProcessor.filter.getIndex()), "Event snap not indexed"); 11388 assert(viewCache.serverCache.getNode().isIndexed(viewProcessor.filter.getIndex()), "Server snap not indexed"); 11389 } 11390 function viewProcessorApplyOperation(viewProcessor, oldViewCache, operation, writesCache, completeCache) { 11391 const accumulator = new ChildChangeAccumulator(); 11392 let newViewCache2, filterServerNode; 11393 if (operation.type === OperationType2.OVERWRITE) { 11394 const overwrite = operation; 11395 if (overwrite.source.fromUser) { 11396 newViewCache2 = viewProcessorApplyUserOverwrite(viewProcessor, oldViewCache, overwrite.path, overwrite.snap, writesCache, completeCache, accumulator); 11397 } else { 11398 assert(overwrite.source.fromServer, "Unknown source."); 11399 filterServerNode = overwrite.source.tagged || oldViewCache.serverCache.isFiltered() && !pathIsEmpty(overwrite.path); 11400 newViewCache2 = viewProcessorApplyServerOverwrite(viewProcessor, oldViewCache, overwrite.path, overwrite.snap, writesCache, completeCache, filterServerNode, accumulator); 11401 } 11402 } else if (operation.type === OperationType2.MERGE) { 11403 const merge = operation; 11404 if (merge.source.fromUser) { 11405 newViewCache2 = viewProcessorApplyUserMerge(viewProcessor, oldViewCache, merge.path, merge.children, writesCache, completeCache, accumulator); 11406 } else { 11407 assert(merge.source.fromServer, "Unknown source."); 11408 filterServerNode = merge.source.tagged || oldViewCache.serverCache.isFiltered(); 11409 newViewCache2 = viewProcessorApplyServerMerge(viewProcessor, oldViewCache, merge.path, merge.children, writesCache, completeCache, filterServerNode, accumulator); 11410 } 11411 } else if (operation.type === OperationType2.ACK_USER_WRITE) { 11412 const ackUserWrite = operation; 11413 if (!ackUserWrite.revert) { 11414 newViewCache2 = viewProcessorAckUserWrite(viewProcessor, oldViewCache, ackUserWrite.path, ackUserWrite.affectedTree, writesCache, completeCache, accumulator); 11415 } else { 11416 newViewCache2 = viewProcessorRevertUserWrite(viewProcessor, oldViewCache, ackUserWrite.path, writesCache, completeCache, accumulator); 11417 } 11418 } else if (operation.type === OperationType2.LISTEN_COMPLETE) { 11419 newViewCache2 = viewProcessorListenComplete(viewProcessor, oldViewCache, operation.path, writesCache, accumulator); 11420 } else { 11421 throw assertionError("Unknown operation type: " + operation.type); 11422 } 11423 const changes = accumulator.getChanges(); 11424 viewProcessorMaybeAddValueEvent(oldViewCache, newViewCache2, changes); 11425 return { viewCache: newViewCache2, changes }; 11426 } 11427 function viewProcessorMaybeAddValueEvent(oldViewCache, newViewCache2, accumulator) { 11428 const eventSnap = newViewCache2.eventCache; 11429 if (eventSnap.isFullyInitialized()) { 11430 const isLeafOrEmpty = eventSnap.getNode().isLeafNode() || eventSnap.getNode().isEmpty(); 11431 const oldCompleteSnap = viewCacheGetCompleteEventSnap(oldViewCache); 11432 if (accumulator.length > 0 || !oldViewCache.eventCache.isFullyInitialized() || isLeafOrEmpty && !eventSnap.getNode().equals(oldCompleteSnap) || !eventSnap.getNode().getPriority().equals(oldCompleteSnap.getPriority())) { 11433 accumulator.push(changeValue(viewCacheGetCompleteEventSnap(newViewCache2))); 11434 } 11435 } 11436 } 11437 function viewProcessorGenerateEventCacheAfterServerEvent(viewProcessor, viewCache, changePath, writesCache, source, accumulator) { 11438 const oldEventSnap = viewCache.eventCache; 11439 if (writeTreeRefShadowingWrite(writesCache, changePath) != null) { 11440 return viewCache; 11441 } else { 11442 let newEventCache, serverNode; 11443 if (pathIsEmpty(changePath)) { 11444 assert(viewCache.serverCache.isFullyInitialized(), "If change path is empty, we must have complete server data"); 11445 if (viewCache.serverCache.isFiltered()) { 11446 const serverCache = viewCacheGetCompleteServerSnap(viewCache); 11447 const completeChildren = serverCache instanceof ChildrenNode ? serverCache : ChildrenNode.EMPTY_NODE; 11448 const completeEventChildren = writeTreeRefCalcCompleteEventChildren(writesCache, completeChildren); 11449 newEventCache = viewProcessor.filter.updateFullNode(viewCache.eventCache.getNode(), completeEventChildren, accumulator); 11450 } else { 11451 const completeNode = writeTreeRefCalcCompleteEventCache(writesCache, viewCacheGetCompleteServerSnap(viewCache)); 11452 newEventCache = viewProcessor.filter.updateFullNode(viewCache.eventCache.getNode(), completeNode, accumulator); 11453 } 11454 } else { 11455 const childKey = pathGetFront(changePath); 11456 if (childKey === ".priority") { 11457 assert(pathGetLength(changePath) === 1, "Can't have a priority with additional path components"); 11458 const oldEventNode = oldEventSnap.getNode(); 11459 serverNode = viewCache.serverCache.getNode(); 11460 const updatedPriority = writeTreeRefCalcEventCacheAfterServerOverwrite(writesCache, changePath, oldEventNode, serverNode); 11461 if (updatedPriority != null) { 11462 newEventCache = viewProcessor.filter.updatePriority(oldEventNode, updatedPriority); 11463 } else { 11464 newEventCache = oldEventSnap.getNode(); 11465 } 11466 } else { 11467 const childChangePath = pathPopFront(changePath); 11468 let newEventChild; 11469 if (oldEventSnap.isCompleteForChild(childKey)) { 11470 serverNode = viewCache.serverCache.getNode(); 11471 const eventChildUpdate = writeTreeRefCalcEventCacheAfterServerOverwrite(writesCache, changePath, oldEventSnap.getNode(), serverNode); 11472 if (eventChildUpdate != null) { 11473 newEventChild = oldEventSnap.getNode().getImmediateChild(childKey).updateChild(childChangePath, eventChildUpdate); 11474 } else { 11475 newEventChild = oldEventSnap.getNode().getImmediateChild(childKey); 11476 } 11477 } else { 11478 newEventChild = writeTreeRefCalcCompleteChild(writesCache, childKey, viewCache.serverCache); 11479 } 11480 if (newEventChild != null) { 11481 newEventCache = viewProcessor.filter.updateChild(oldEventSnap.getNode(), childKey, newEventChild, childChangePath, source, accumulator); 11482 } else { 11483 newEventCache = oldEventSnap.getNode(); 11484 } 11485 } 11486 } 11487 return viewCacheUpdateEventSnap(viewCache, newEventCache, oldEventSnap.isFullyInitialized() || pathIsEmpty(changePath), viewProcessor.filter.filtersNodes()); 11488 } 11489 } 11490 function viewProcessorApplyServerOverwrite(viewProcessor, oldViewCache, changePath, changedSnap, writesCache, completeCache, filterServerNode, accumulator) { 11491 const oldServerSnap = oldViewCache.serverCache; 11492 let newServerCache; 11493 const serverFilter = filterServerNode ? viewProcessor.filter : viewProcessor.filter.getIndexedFilter(); 11494 if (pathIsEmpty(changePath)) { 11495 newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), changedSnap, null); 11496 } else if (serverFilter.filtersNodes() && !oldServerSnap.isFiltered()) { 11497 const newServerNode = oldServerSnap.getNode().updateChild(changePath, changedSnap); 11498 newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), newServerNode, null); 11499 } else { 11500 const childKey = pathGetFront(changePath); 11501 if (!oldServerSnap.isCompleteForPath(changePath) && pathGetLength(changePath) > 1) { 11502 return oldViewCache; 11503 } 11504 const childChangePath = pathPopFront(changePath); 11505 const childNode = oldServerSnap.getNode().getImmediateChild(childKey); 11506 const newChildNode = childNode.updateChild(childChangePath, changedSnap); 11507 if (childKey === ".priority") { 11508 newServerCache = serverFilter.updatePriority(oldServerSnap.getNode(), newChildNode); 11509 } else { 11510 newServerCache = serverFilter.updateChild(oldServerSnap.getNode(), childKey, newChildNode, childChangePath, NO_COMPLETE_CHILD_SOURCE, null); 11511 } 11512 } 11513 const newViewCache2 = viewCacheUpdateServerSnap(oldViewCache, newServerCache, oldServerSnap.isFullyInitialized() || pathIsEmpty(changePath), serverFilter.filtersNodes()); 11514 const source = new WriteTreeCompleteChildSource(writesCache, newViewCache2, completeCache); 11515 return viewProcessorGenerateEventCacheAfterServerEvent(viewProcessor, newViewCache2, changePath, writesCache, source, accumulator); 11516 } 11517 function viewProcessorApplyUserOverwrite(viewProcessor, oldViewCache, changePath, changedSnap, writesCache, completeCache, accumulator) { 11518 const oldEventSnap = oldViewCache.eventCache; 11519 let newViewCache2, newEventCache; 11520 const source = new WriteTreeCompleteChildSource(writesCache, oldViewCache, completeCache); 11521 if (pathIsEmpty(changePath)) { 11522 newEventCache = viewProcessor.filter.updateFullNode(oldViewCache.eventCache.getNode(), changedSnap, accumulator); 11523 newViewCache2 = viewCacheUpdateEventSnap(oldViewCache, newEventCache, true, viewProcessor.filter.filtersNodes()); 11524 } else { 11525 const childKey = pathGetFront(changePath); 11526 if (childKey === ".priority") { 11527 newEventCache = viewProcessor.filter.updatePriority(oldViewCache.eventCache.getNode(), changedSnap); 11528 newViewCache2 = viewCacheUpdateEventSnap(oldViewCache, newEventCache, oldEventSnap.isFullyInitialized(), oldEventSnap.isFiltered()); 11529 } else { 11530 const childChangePath = pathPopFront(changePath); 11531 const oldChild = oldEventSnap.getNode().getImmediateChild(childKey); 11532 let newChild; 11533 if (pathIsEmpty(childChangePath)) { 11534 newChild = changedSnap; 11535 } else { 11536 const childNode = source.getCompleteChild(childKey); 11537 if (childNode != null) { 11538 if (pathGetBack(childChangePath) === ".priority" && childNode.getChild(pathParent(childChangePath)).isEmpty()) { 11539 newChild = childNode; 11540 } else { 11541 newChild = childNode.updateChild(childChangePath, changedSnap); 11542 } 11543 } else { 11544 newChild = ChildrenNode.EMPTY_NODE; 11545 } 11546 } 11547 if (!oldChild.equals(newChild)) { 11548 const newEventSnap = viewProcessor.filter.updateChild(oldEventSnap.getNode(), childKey, newChild, childChangePath, source, accumulator); 11549 newViewCache2 = viewCacheUpdateEventSnap(oldViewCache, newEventSnap, oldEventSnap.isFullyInitialized(), viewProcessor.filter.filtersNodes()); 11550 } else { 11551 newViewCache2 = oldViewCache; 11552 } 11553 } 11554 } 11555 return newViewCache2; 11556 } 11557 function viewProcessorCacheHasChild(viewCache, childKey) { 11558 return viewCache.eventCache.isCompleteForChild(childKey); 11559 } 11560 function viewProcessorApplyUserMerge(viewProcessor, viewCache, path, changedChildren, writesCache, serverCache, accumulator) { 11561 let curViewCache = viewCache; 11562 changedChildren.foreach((relativePath, childNode) => { 11563 const writePath = pathChild(path, relativePath); 11564 if (viewProcessorCacheHasChild(viewCache, pathGetFront(writePath))) { 11565 curViewCache = viewProcessorApplyUserOverwrite(viewProcessor, curViewCache, writePath, childNode, writesCache, serverCache, accumulator); 11566 } 11567 }); 11568 changedChildren.foreach((relativePath, childNode) => { 11569 const writePath = pathChild(path, relativePath); 11570 if (!viewProcessorCacheHasChild(viewCache, pathGetFront(writePath))) { 11571 curViewCache = viewProcessorApplyUserOverwrite(viewProcessor, curViewCache, writePath, childNode, writesCache, serverCache, accumulator); 11572 } 11573 }); 11574 return curViewCache; 11575 } 11576 function viewProcessorApplyMerge(viewProcessor, node, merge) { 11577 merge.foreach((relativePath, childNode) => { 11578 node = node.updateChild(relativePath, childNode); 11579 }); 11580 return node; 11581 } 11582 function viewProcessorApplyServerMerge(viewProcessor, viewCache, path, changedChildren, writesCache, serverCache, filterServerNode, accumulator) { 11583 if (viewCache.serverCache.getNode().isEmpty() && !viewCache.serverCache.isFullyInitialized()) { 11584 return viewCache; 11585 } 11586 let curViewCache = viewCache; 11587 let viewMergeTree; 11588 if (pathIsEmpty(path)) { 11589 viewMergeTree = changedChildren; 11590 } else { 11591 viewMergeTree = new ImmutableTree(null).setTree(path, changedChildren); 11592 } 11593 const serverNode = viewCache.serverCache.getNode(); 11594 viewMergeTree.children.inorderTraversal((childKey, childTree) => { 11595 if (serverNode.hasChild(childKey)) { 11596 const serverChild = viewCache.serverCache.getNode().getImmediateChild(childKey); 11597 const newChild = viewProcessorApplyMerge(viewProcessor, serverChild, childTree); 11598 curViewCache = viewProcessorApplyServerOverwrite(viewProcessor, curViewCache, new Path(childKey), newChild, writesCache, serverCache, filterServerNode, accumulator); 11599 } 11600 }); 11601 viewMergeTree.children.inorderTraversal((childKey, childMergeTree) => { 11602 const isUnknownDeepMerge = !viewCache.serverCache.isCompleteForChild(childKey) && childMergeTree.value === null; 11603 if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) { 11604 const serverChild = viewCache.serverCache.getNode().getImmediateChild(childKey); 11605 const newChild = viewProcessorApplyMerge(viewProcessor, serverChild, childMergeTree); 11606 curViewCache = viewProcessorApplyServerOverwrite(viewProcessor, curViewCache, new Path(childKey), newChild, writesCache, serverCache, filterServerNode, accumulator); 11607 } 11608 }); 11609 return curViewCache; 11610 } 11611 function viewProcessorAckUserWrite(viewProcessor, viewCache, ackPath, affectedTree, writesCache, completeCache, accumulator) { 11612 if (writeTreeRefShadowingWrite(writesCache, ackPath) != null) { 11613 return viewCache; 11614 } 11615 const filterServerNode = viewCache.serverCache.isFiltered(); 11616 const serverCache = viewCache.serverCache; 11617 if (affectedTree.value != null) { 11618 if (pathIsEmpty(ackPath) && serverCache.isFullyInitialized() || serverCache.isCompleteForPath(ackPath)) { 11619 return viewProcessorApplyServerOverwrite(viewProcessor, viewCache, ackPath, serverCache.getNode().getChild(ackPath), writesCache, completeCache, filterServerNode, accumulator); 11620 } else if (pathIsEmpty(ackPath)) { 11621 let changedChildren = new ImmutableTree(null); 11622 serverCache.getNode().forEachChild(KEY_INDEX, (name7, node) => { 11623 changedChildren = changedChildren.set(new Path(name7), node); 11624 }); 11625 return viewProcessorApplyServerMerge(viewProcessor, viewCache, ackPath, changedChildren, writesCache, completeCache, filterServerNode, accumulator); 11626 } else { 11627 return viewCache; 11628 } 11629 } else { 11630 let changedChildren = new ImmutableTree(null); 11631 affectedTree.foreach((mergePath, value) => { 11632 const serverCachePath = pathChild(ackPath, mergePath); 11633 if (serverCache.isCompleteForPath(serverCachePath)) { 11634 changedChildren = changedChildren.set(mergePath, serverCache.getNode().getChild(serverCachePath)); 11635 } 11636 }); 11637 return viewProcessorApplyServerMerge(viewProcessor, viewCache, ackPath, changedChildren, writesCache, completeCache, filterServerNode, accumulator); 11638 } 11639 } 11640 function viewProcessorListenComplete(viewProcessor, viewCache, path, writesCache, accumulator) { 11641 const oldServerNode = viewCache.serverCache; 11642 const newViewCache2 = viewCacheUpdateServerSnap(viewCache, oldServerNode.getNode(), oldServerNode.isFullyInitialized() || pathIsEmpty(path), oldServerNode.isFiltered()); 11643 return viewProcessorGenerateEventCacheAfterServerEvent(viewProcessor, newViewCache2, path, writesCache, NO_COMPLETE_CHILD_SOURCE, accumulator); 11644 } 11645 function viewProcessorRevertUserWrite(viewProcessor, viewCache, path, writesCache, completeServerCache, accumulator) { 11646 let complete; 11647 if (writeTreeRefShadowingWrite(writesCache, path) != null) { 11648 return viewCache; 11649 } else { 11650 const source = new WriteTreeCompleteChildSource(writesCache, viewCache, completeServerCache); 11651 const oldEventCache = viewCache.eventCache.getNode(); 11652 let newEventCache; 11653 if (pathIsEmpty(path) || pathGetFront(path) === ".priority") { 11654 let newNode; 11655 if (viewCache.serverCache.isFullyInitialized()) { 11656 newNode = writeTreeRefCalcCompleteEventCache(writesCache, viewCacheGetCompleteServerSnap(viewCache)); 11657 } else { 11658 const serverChildren = viewCache.serverCache.getNode(); 11659 assert(serverChildren instanceof ChildrenNode, "serverChildren would be complete if leaf node"); 11660 newNode = writeTreeRefCalcCompleteEventChildren(writesCache, serverChildren); 11661 } 11662 newNode = newNode; 11663 newEventCache = viewProcessor.filter.updateFullNode(oldEventCache, newNode, accumulator); 11664 } else { 11665 const childKey = pathGetFront(path); 11666 let newChild = writeTreeRefCalcCompleteChild(writesCache, childKey, viewCache.serverCache); 11667 if (newChild == null && viewCache.serverCache.isCompleteForChild(childKey)) { 11668 newChild = oldEventCache.getImmediateChild(childKey); 11669 } 11670 if (newChild != null) { 11671 newEventCache = viewProcessor.filter.updateChild(oldEventCache, childKey, newChild, pathPopFront(path), source, accumulator); 11672 } else if (viewCache.eventCache.getNode().hasChild(childKey)) { 11673 newEventCache = viewProcessor.filter.updateChild(oldEventCache, childKey, ChildrenNode.EMPTY_NODE, pathPopFront(path), source, accumulator); 11674 } else { 11675 newEventCache = oldEventCache; 11676 } 11677 if (newEventCache.isEmpty() && viewCache.serverCache.isFullyInitialized()) { 11678 complete = writeTreeRefCalcCompleteEventCache(writesCache, viewCacheGetCompleteServerSnap(viewCache)); 11679 if (complete.isLeafNode()) { 11680 newEventCache = viewProcessor.filter.updateFullNode(newEventCache, complete, accumulator); 11681 } 11682 } 11683 } 11684 complete = viewCache.serverCache.isFullyInitialized() || writeTreeRefShadowingWrite(writesCache, newEmptyPath()) != null; 11685 return viewCacheUpdateEventSnap(viewCache, newEventCache, complete, viewProcessor.filter.filtersNodes()); 11686 } 11687 } 11688 function viewGetCompleteServerCache(view, path) { 11689 const cache = viewCacheGetCompleteServerSnap(view.viewCache_); 11690 if (cache) { 11691 if (view.query._queryParams.loadsAllData() || !pathIsEmpty(path) && !cache.getImmediateChild(pathGetFront(path)).isEmpty()) { 11692 return cache.getChild(path); 11693 } 11694 } 11695 return null; 11696 } 11697 function viewApplyOperation(view, operation, writesCache, completeServerCache) { 11698 if (operation.type === OperationType2.MERGE && operation.source.queryId !== null) { 11699 assert(viewCacheGetCompleteServerSnap(view.viewCache_), "We should always have a full cache before handling merges"); 11700 assert(viewCacheGetCompleteEventSnap(view.viewCache_), "Missing event cache, even though we have a server cache"); 11701 } 11702 const oldViewCache = view.viewCache_; 11703 const result = viewProcessorApplyOperation(view.processor_, oldViewCache, operation, writesCache, completeServerCache); 11704 viewProcessorAssertIndexed(view.processor_, result.viewCache); 11705 assert(result.viewCache.serverCache.isFullyInitialized() || !oldViewCache.serverCache.isFullyInitialized(), "Once a server snap is complete, it should never go back"); 11706 view.viewCache_ = result.viewCache; 11707 return viewGenerateEventsForChanges_(view, result.changes, result.viewCache.eventCache.getNode(), null); 11708 } 11709 function viewGenerateEventsForChanges_(view, changes, eventCache, eventRegistration) { 11710 const registrations = eventRegistration ? [eventRegistration] : view.eventRegistrations_; 11711 return eventGeneratorGenerateEventsForChanges(view.eventGenerator_, changes, eventCache, registrations); 11712 } 11713 var referenceConstructor$1; 11714 function syncPointSetReferenceConstructor(val) { 11715 assert(!referenceConstructor$1, "__referenceConstructor has already been defined"); 11716 referenceConstructor$1 = val; 11717 } 11718 function syncPointApplyOperation(syncPoint, operation, writesCache, optCompleteServerCache) { 11719 const queryId = operation.source.queryId; 11720 if (queryId !== null) { 11721 const view = syncPoint.views.get(queryId); 11722 assert(view != null, "SyncTree gave us an op for an invalid query."); 11723 return viewApplyOperation(view, operation, writesCache, optCompleteServerCache); 11724 } else { 11725 let events = []; 11726 for (const view of syncPoint.views.values()) { 11727 events = events.concat(viewApplyOperation(view, operation, writesCache, optCompleteServerCache)); 11728 } 11729 return events; 11730 } 11731 } 11732 function syncPointGetCompleteServerCache(syncPoint, path) { 11733 let serverCache = null; 11734 for (const view of syncPoint.views.values()) { 11735 serverCache = serverCache || viewGetCompleteServerCache(view, path); 11736 } 11737 return serverCache; 11738 } 11739 var referenceConstructor; 11740 function syncTreeSetReferenceConstructor(val) { 11741 assert(!referenceConstructor, "__referenceConstructor has already been defined"); 11742 referenceConstructor = val; 11743 } 11744 var SyncTree = class { 11745 constructor(listenProvider_) { 11746 this.listenProvider_ = listenProvider_; 11747 this.syncPointTree_ = new ImmutableTree(null); 11748 this.pendingWriteTree_ = newWriteTree(); 11749 this.tagToQueryMap = /* @__PURE__ */ new Map(); 11750 this.queryToTagMap = /* @__PURE__ */ new Map(); 11751 } 11752 }; 11753 function syncTreeApplyUserOverwrite(syncTree, path, newData, writeId, visible) { 11754 writeTreeAddOverwrite(syncTree.pendingWriteTree_, path, newData, writeId, visible); 11755 if (!visible) { 11756 return []; 11757 } else { 11758 return syncTreeApplyOperationToSyncPoints_(syncTree, new Overwrite(newOperationSourceUser(), path, newData)); 11759 } 11760 } 11761 function syncTreeAckUserWrite(syncTree, writeId, revert = false) { 11762 const write = writeTreeGetWrite(syncTree.pendingWriteTree_, writeId); 11763 const needToReevaluate = writeTreeRemoveWrite(syncTree.pendingWriteTree_, writeId); 11764 if (!needToReevaluate) { 11765 return []; 11766 } else { 11767 let affectedTree = new ImmutableTree(null); 11768 if (write.snap != null) { 11769 affectedTree = affectedTree.set(newEmptyPath(), true); 11770 } else { 11771 each(write.children, (pathString) => { 11772 affectedTree = affectedTree.set(new Path(pathString), true); 11773 }); 11774 } 11775 return syncTreeApplyOperationToSyncPoints_(syncTree, new AckUserWrite(write.path, affectedTree, revert)); 11776 } 11777 } 11778 function syncTreeApplyServerOverwrite(syncTree, path, newData) { 11779 return syncTreeApplyOperationToSyncPoints_(syncTree, new Overwrite(newOperationSourceServer(), path, newData)); 11780 } 11781 function syncTreeApplyServerMerge(syncTree, path, changedChildren) { 11782 const changeTree = ImmutableTree.fromObject(changedChildren); 11783 return syncTreeApplyOperationToSyncPoints_(syncTree, new Merge(newOperationSourceServer(), path, changeTree)); 11784 } 11785 function syncTreeApplyTaggedQueryOverwrite(syncTree, path, snap, tag) { 11786 const queryKey = syncTreeQueryKeyForTag_(syncTree, tag); 11787 if (queryKey != null) { 11788 const r = syncTreeParseQueryKey_(queryKey); 11789 const queryPath = r.path, queryId = r.queryId; 11790 const relativePath = newRelativePath(queryPath, path); 11791 const op = new Overwrite(newOperationSourceServerTaggedQuery(queryId), relativePath, snap); 11792 return syncTreeApplyTaggedOperation_(syncTree, queryPath, op); 11793 } else { 11794 return []; 11795 } 11796 } 11797 function syncTreeApplyTaggedQueryMerge(syncTree, path, changedChildren, tag) { 11798 const queryKey = syncTreeQueryKeyForTag_(syncTree, tag); 11799 if (queryKey) { 11800 const r = syncTreeParseQueryKey_(queryKey); 11801 const queryPath = r.path, queryId = r.queryId; 11802 const relativePath = newRelativePath(queryPath, path); 11803 const changeTree = ImmutableTree.fromObject(changedChildren); 11804 const op = new Merge(newOperationSourceServerTaggedQuery(queryId), relativePath, changeTree); 11805 return syncTreeApplyTaggedOperation_(syncTree, queryPath, op); 11806 } else { 11807 return []; 11808 } 11809 } 11810 function syncTreeCalcCompleteEventCache(syncTree, path, writeIdsToExclude) { 11811 const includeHiddenSets = true; 11812 const writeTree = syncTree.pendingWriteTree_; 11813 const serverCache = syncTree.syncPointTree_.findOnPath(path, (pathSoFar, syncPoint) => { 11814 const relativePath = newRelativePath(pathSoFar, path); 11815 const serverCache2 = syncPointGetCompleteServerCache(syncPoint, relativePath); 11816 if (serverCache2) { 11817 return serverCache2; 11818 } 11819 }); 11820 return writeTreeCalcCompleteEventCache(writeTree, path, serverCache, writeIdsToExclude, includeHiddenSets); 11821 } 11822 function syncTreeApplyOperationToSyncPoints_(syncTree, operation) { 11823 return syncTreeApplyOperationHelper_(operation, syncTree.syncPointTree_, null, writeTreeChildWrites(syncTree.pendingWriteTree_, newEmptyPath())); 11824 } 11825 function syncTreeApplyOperationHelper_(operation, syncPointTree, serverCache, writesCache) { 11826 if (pathIsEmpty(operation.path)) { 11827 return syncTreeApplyOperationDescendantsHelper_(operation, syncPointTree, serverCache, writesCache); 11828 } else { 11829 const syncPoint = syncPointTree.get(newEmptyPath()); 11830 if (serverCache == null && syncPoint != null) { 11831 serverCache = syncPointGetCompleteServerCache(syncPoint, newEmptyPath()); 11832 } 11833 let events = []; 11834 const childName = pathGetFront(operation.path); 11835 const childOperation = operation.operationForChild(childName); 11836 const childTree = syncPointTree.children.get(childName); 11837 if (childTree && childOperation) { 11838 const childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null; 11839 const childWritesCache = writeTreeRefChild(writesCache, childName); 11840 events = events.concat(syncTreeApplyOperationHelper_(childOperation, childTree, childServerCache, childWritesCache)); 11841 } 11842 if (syncPoint) { 11843 events = events.concat(syncPointApplyOperation(syncPoint, operation, writesCache, serverCache)); 11844 } 11845 return events; 11846 } 11847 } 11848 function syncTreeApplyOperationDescendantsHelper_(operation, syncPointTree, serverCache, writesCache) { 11849 const syncPoint = syncPointTree.get(newEmptyPath()); 11850 if (serverCache == null && syncPoint != null) { 11851 serverCache = syncPointGetCompleteServerCache(syncPoint, newEmptyPath()); 11852 } 11853 let events = []; 11854 syncPointTree.children.inorderTraversal((childName, childTree) => { 11855 const childServerCache = serverCache ? serverCache.getImmediateChild(childName) : null; 11856 const childWritesCache = writeTreeRefChild(writesCache, childName); 11857 const childOperation = operation.operationForChild(childName); 11858 if (childOperation) { 11859 events = events.concat(syncTreeApplyOperationDescendantsHelper_(childOperation, childTree, childServerCache, childWritesCache)); 11860 } 11861 }); 11862 if (syncPoint) { 11863 events = events.concat(syncPointApplyOperation(syncPoint, operation, writesCache, serverCache)); 11864 } 11865 return events; 11866 } 11867 function syncTreeQueryKeyForTag_(syncTree, tag) { 11868 return syncTree.tagToQueryMap.get(tag); 11869 } 11870 function syncTreeParseQueryKey_(queryKey) { 11871 const splitIndex = queryKey.indexOf("$"); 11872 assert(splitIndex !== -1 && splitIndex < queryKey.length - 1, "Bad queryKey."); 11873 return { 11874 queryId: queryKey.substr(splitIndex + 1), 11875 path: new Path(queryKey.substr(0, splitIndex)) 11876 }; 11877 } 11878 function syncTreeApplyTaggedOperation_(syncTree, queryPath, operation) { 11879 const syncPoint = syncTree.syncPointTree_.get(queryPath); 11880 assert(syncPoint, "Missing sync point for query tag that we're tracking"); 11881 const writesCache = writeTreeChildWrites(syncTree.pendingWriteTree_, queryPath); 11882 return syncPointApplyOperation(syncPoint, operation, writesCache, null); 11883 } 11884 var ExistingValueProvider = class { 11885 constructor(node_) { 11886 this.node_ = node_; 11887 } 11888 getImmediateChild(childName) { 11889 const child = this.node_.getImmediateChild(childName); 11890 return new ExistingValueProvider(child); 11891 } 11892 node() { 11893 return this.node_; 11894 } 11895 }; 11896 var DeferredValueProvider = class { 11897 constructor(syncTree, path) { 11898 this.syncTree_ = syncTree; 11899 this.path_ = path; 11900 } 11901 getImmediateChild(childName) { 11902 const childPath = pathChild(this.path_, childName); 11903 return new DeferredValueProvider(this.syncTree_, childPath); 11904 } 11905 node() { 11906 return syncTreeCalcCompleteEventCache(this.syncTree_, this.path_); 11907 } 11908 }; 11909 var generateWithValues = function(values) { 11910 values = values || {}; 11911 values["timestamp"] = values["timestamp"] || new Date().getTime(); 11912 return values; 11913 }; 11914 var resolveDeferredLeafValue = function(value, existingVal, serverValues) { 11915 if (!value || typeof value !== "object") { 11916 return value; 11917 } 11918 assert(".sv" in value, "Unexpected leaf node or priority contents"); 11919 if (typeof value[".sv"] === "string") { 11920 return resolveScalarDeferredValue(value[".sv"], existingVal, serverValues); 11921 } else if (typeof value[".sv"] === "object") { 11922 return resolveComplexDeferredValue(value[".sv"], existingVal); 11923 } else { 11924 assert(false, "Unexpected server value: " + JSON.stringify(value, null, 2)); 11925 } 11926 }; 11927 var resolveScalarDeferredValue = function(op, existing, serverValues) { 11928 switch (op) { 11929 case "timestamp": 11930 return serverValues["timestamp"]; 11931 default: 11932 assert(false, "Unexpected server value: " + op); 11933 } 11934 }; 11935 var resolveComplexDeferredValue = function(op, existing, unused) { 11936 if (!op.hasOwnProperty("increment")) { 11937 assert(false, "Unexpected server value: " + JSON.stringify(op, null, 2)); 11938 } 11939 const delta = op["increment"]; 11940 if (typeof delta !== "number") { 11941 assert(false, "Unexpected increment value: " + delta); 11942 } 11943 const existingNode = existing.node(); 11944 assert(existingNode !== null && typeof existingNode !== "undefined", "Expected ChildrenNode.EMPTY_NODE for nulls"); 11945 if (!existingNode.isLeafNode()) { 11946 return delta; 11947 } 11948 const leaf = existingNode; 11949 const existingVal = leaf.getValue(); 11950 if (typeof existingVal !== "number") { 11951 return delta; 11952 } 11953 return existingVal + delta; 11954 }; 11955 var resolveDeferredValueTree = function(path, node, syncTree, serverValues) { 11956 return resolveDeferredValue(node, new DeferredValueProvider(syncTree, path), serverValues); 11957 }; 11958 var resolveDeferredValueSnapshot = function(node, existing, serverValues) { 11959 return resolveDeferredValue(node, new ExistingValueProvider(existing), serverValues); 11960 }; 11961 function resolveDeferredValue(node, existingVal, serverValues) { 11962 const rawPri = node.getPriority().val(); 11963 const priority = resolveDeferredLeafValue(rawPri, existingVal.getImmediateChild(".priority"), serverValues); 11964 let newNode; 11965 if (node.isLeafNode()) { 11966 const leafNode = node; 11967 const value = resolveDeferredLeafValue(leafNode.getValue(), existingVal, serverValues); 11968 if (value !== leafNode.getValue() || priority !== leafNode.getPriority().val()) { 11969 return new LeafNode(value, nodeFromJSON(priority)); 11970 } else { 11971 return node; 11972 } 11973 } else { 11974 const childrenNode = node; 11975 newNode = childrenNode; 11976 if (priority !== childrenNode.getPriority().val()) { 11977 newNode = newNode.updatePriority(new LeafNode(priority)); 11978 } 11979 childrenNode.forEachChild(PRIORITY_INDEX, (childName, childNode) => { 11980 const newChildNode = resolveDeferredValue(childNode, existingVal.getImmediateChild(childName), serverValues); 11981 if (newChildNode !== childNode) { 11982 newNode = newNode.updateImmediateChild(childName, newChildNode); 11983 } 11984 }); 11985 return newNode; 11986 } 11987 } 11988 var Tree = class { 11989 constructor(name7 = "", parent = null, node = { children: {}, childCount: 0 }) { 11990 this.name = name7; 11991 this.parent = parent; 11992 this.node = node; 11993 } 11994 }; 11995 function treeSubTree(tree, pathObj) { 11996 let path = pathObj instanceof Path ? pathObj : new Path(pathObj); 11997 let child = tree, next = pathGetFront(path); 11998 while (next !== null) { 11999 const childNode = safeGet(child.node.children, next) || { 12000 children: {}, 12001 childCount: 0 12002 }; 12003 child = new Tree(next, child, childNode); 12004 path = pathPopFront(path); 12005 next = pathGetFront(path); 12006 } 12007 return child; 12008 } 12009 function treeGetValue(tree) { 12010 return tree.node.value; 12011 } 12012 function treeSetValue(tree, value) { 12013 tree.node.value = value; 12014 treeUpdateParents(tree); 12015 } 12016 function treeHasChildren(tree) { 12017 return tree.node.childCount > 0; 12018 } 12019 function treeIsEmpty(tree) { 12020 return treeGetValue(tree) === void 0 && !treeHasChildren(tree); 12021 } 12022 function treeForEachChild(tree, action) { 12023 each(tree.node.children, (child, childTree) => { 12024 action(new Tree(child, tree, childTree)); 12025 }); 12026 } 12027 function treeForEachDescendant(tree, action, includeSelf, childrenFirst) { 12028 if (includeSelf && !childrenFirst) { 12029 action(tree); 12030 } 12031 treeForEachChild(tree, (child) => { 12032 treeForEachDescendant(child, action, true, childrenFirst); 12033 }); 12034 if (includeSelf && childrenFirst) { 12035 action(tree); 12036 } 12037 } 12038 function treeForEachAncestor(tree, action, includeSelf) { 12039 let node = includeSelf ? tree : tree.parent; 12040 while (node !== null) { 12041 if (action(node)) { 12042 return true; 12043 } 12044 node = node.parent; 12045 } 12046 return false; 12047 } 12048 function treeGetPath(tree) { 12049 return new Path(tree.parent === null ? tree.name : treeGetPath(tree.parent) + "/" + tree.name); 12050 } 12051 function treeUpdateParents(tree) { 12052 if (tree.parent !== null) { 12053 treeUpdateChild(tree.parent, tree.name, tree); 12054 } 12055 } 12056 function treeUpdateChild(tree, childName, child) { 12057 const childEmpty = treeIsEmpty(child); 12058 const childExists = contains(tree.node.children, childName); 12059 if (childEmpty && childExists) { 12060 delete tree.node.children[childName]; 12061 tree.node.childCount--; 12062 treeUpdateParents(tree); 12063 } else if (!childEmpty && !childExists) { 12064 tree.node.children[childName] = child.node; 12065 tree.node.childCount++; 12066 treeUpdateParents(tree); 12067 } 12068 } 12069 var INVALID_KEY_REGEX_ = /[\[\].#$\/\u0000-\u001F\u007F]/; 12070 var INVALID_PATH_REGEX_ = /[\[\].#$\u0000-\u001F\u007F]/; 12071 var MAX_LEAF_SIZE_ = 10 * 1024 * 1024; 12072 var isValidKey2 = function(key) { 12073 return typeof key === "string" && key.length !== 0 && !INVALID_KEY_REGEX_.test(key); 12074 }; 12075 var isValidPathString = function(pathString) { 12076 return typeof pathString === "string" && pathString.length !== 0 && !INVALID_PATH_REGEX_.test(pathString); 12077 }; 12078 var isValidRootPathString = function(pathString) { 12079 if (pathString) { 12080 pathString = pathString.replace(/^\/*\.info(\/|$)/, "/"); 12081 } 12082 return isValidPathString(pathString); 12083 }; 12084 var validateFirebaseData = function(errorPrefix2, data, path_) { 12085 const path = path_ instanceof Path ? new ValidationPath(path_, errorPrefix2) : path_; 12086 if (data === void 0) { 12087 throw new Error(errorPrefix2 + "contains undefined " + validationPathToErrorString(path)); 12088 } 12089 if (typeof data === "function") { 12090 throw new Error(errorPrefix2 + "contains a function " + validationPathToErrorString(path) + " with contents = " + data.toString()); 12091 } 12092 if (isInvalidJSONNumber(data)) { 12093 throw new Error(errorPrefix2 + "contains " + data.toString() + " " + validationPathToErrorString(path)); 12094 } 12095 if (typeof data === "string" && data.length > MAX_LEAF_SIZE_ / 3 && stringLength(data) > MAX_LEAF_SIZE_) { 12096 throw new Error(errorPrefix2 + "contains a string greater than " + MAX_LEAF_SIZE_ + " utf8 bytes " + validationPathToErrorString(path) + " ('" + data.substring(0, 50) + "...')"); 12097 } 12098 if (data && typeof data === "object") { 12099 let hasDotValue = false; 12100 let hasActualChild = false; 12101 each(data, (key, value) => { 12102 if (key === ".value") { 12103 hasDotValue = true; 12104 } else if (key !== ".priority" && key !== ".sv") { 12105 hasActualChild = true; 12106 if (!isValidKey2(key)) { 12107 throw new Error(errorPrefix2 + " contains an invalid key (" + key + ") " + validationPathToErrorString(path) + `. Keys must be non-empty strings and can't contain ".", "#", "$", "/", "[", or "]"`); 12108 } 12109 } 12110 validationPathPush(path, key); 12111 validateFirebaseData(errorPrefix2, value, path); 12112 validationPathPop(path); 12113 }); 12114 if (hasDotValue && hasActualChild) { 12115 throw new Error(errorPrefix2 + ' contains ".value" child ' + validationPathToErrorString(path) + " in addition to actual children."); 12116 } 12117 } 12118 }; 12119 var validateUrl = function(fnName, parsedUrl) { 12120 const pathString = parsedUrl.path.toString(); 12121 if (!(typeof parsedUrl.repoInfo.host === "string") || parsedUrl.repoInfo.host.length === 0 || !isValidKey2(parsedUrl.repoInfo.namespace) && parsedUrl.repoInfo.host.split(":")[0] !== "localhost" || pathString.length !== 0 && !isValidRootPathString(pathString)) { 12122 throw new Error(errorPrefix(fnName, "url") + `must be a valid firebase URL and the path can't contain ".", "#", "$", "[", or "]".`); 12123 } 12124 }; 12125 var EventQueue = class { 12126 constructor() { 12127 this.eventLists_ = []; 12128 this.recursionDepth_ = 0; 12129 } 12130 }; 12131 function eventQueueQueueEvents(eventQueue, eventDataList) { 12132 let currList = null; 12133 for (let i = 0; i < eventDataList.length; i++) { 12134 const data = eventDataList[i]; 12135 const path = data.getPath(); 12136 if (currList !== null && !pathEquals(path, currList.path)) { 12137 eventQueue.eventLists_.push(currList); 12138 currList = null; 12139 } 12140 if (currList === null) { 12141 currList = { events: [], path }; 12142 } 12143 currList.events.push(data); 12144 } 12145 if (currList) { 12146 eventQueue.eventLists_.push(currList); 12147 } 12148 } 12149 function eventQueueRaiseEventsForChangedPath(eventQueue, changedPath, eventDataList) { 12150 eventQueueQueueEvents(eventQueue, eventDataList); 12151 eventQueueRaiseQueuedEventsMatchingPredicate(eventQueue, (eventPath) => pathContains(eventPath, changedPath) || pathContains(changedPath, eventPath)); 12152 } 12153 function eventQueueRaiseQueuedEventsMatchingPredicate(eventQueue, predicate) { 12154 eventQueue.recursionDepth_++; 12155 let sentAll = true; 12156 for (let i = 0; i < eventQueue.eventLists_.length; i++) { 12157 const eventList = eventQueue.eventLists_[i]; 12158 if (eventList) { 12159 const eventPath = eventList.path; 12160 if (predicate(eventPath)) { 12161 eventListRaise(eventQueue.eventLists_[i]); 12162 eventQueue.eventLists_[i] = null; 12163 } else { 12164 sentAll = false; 12165 } 12166 } 12167 } 12168 if (sentAll) { 12169 eventQueue.eventLists_ = []; 12170 } 12171 eventQueue.recursionDepth_--; 12172 } 12173 function eventListRaise(eventList) { 12174 for (let i = 0; i < eventList.events.length; i++) { 12175 const eventData = eventList.events[i]; 12176 if (eventData !== null) { 12177 eventList.events[i] = null; 12178 const eventFn = eventData.getEventRunner(); 12179 if (logger3) { 12180 log("event: " + eventData.toString()); 12181 } 12182 exceptionGuard(eventFn); 12183 } 12184 } 12185 } 12186 var INTERRUPT_REASON = "repo_interrupt"; 12187 var MAX_TRANSACTION_RETRIES = 25; 12188 var Repo = class { 12189 constructor(repoInfo_, forceRestClient_, authTokenProvider_, appCheckProvider_) { 12190 this.repoInfo_ = repoInfo_; 12191 this.forceRestClient_ = forceRestClient_; 12192 this.authTokenProvider_ = authTokenProvider_; 12193 this.appCheckProvider_ = appCheckProvider_; 12194 this.dataUpdateCount = 0; 12195 this.statsListener_ = null; 12196 this.eventQueue_ = new EventQueue(); 12197 this.nextWriteId_ = 1; 12198 this.interceptServerDataCallback_ = null; 12199 this.onDisconnect_ = newSparseSnapshotTree(); 12200 this.transactionQueueTree_ = new Tree(); 12201 this.persistentConnection_ = null; 12202 this.key = this.repoInfo_.toURLString(); 12203 } 12204 toString() { 12205 return (this.repoInfo_.secure ? "https://" : "http://") + this.repoInfo_.host; 12206 } 12207 }; 12208 function repoStart(repo, appId, authOverride) { 12209 repo.stats_ = statsManagerGetCollection(repo.repoInfo_); 12210 if (repo.forceRestClient_ || beingCrawled()) { 12211 repo.server_ = new ReadonlyRestClient(repo.repoInfo_, (pathString, data, isMerge, tag) => { 12212 repoOnDataUpdate(repo, pathString, data, isMerge, tag); 12213 }, repo.authTokenProvider_, repo.appCheckProvider_); 12214 setTimeout(() => repoOnConnectStatus(repo, true), 0); 12215 } else { 12216 if (typeof authOverride !== "undefined" && authOverride !== null) { 12217 if (typeof authOverride !== "object") { 12218 throw new Error("Only objects are supported for option databaseAuthVariableOverride"); 12219 } 12220 try { 12221 stringify(authOverride); 12222 } catch (e) { 12223 throw new Error("Invalid authOverride provided: " + e); 12224 } 12225 } 12226 repo.persistentConnection_ = new PersistentConnection(repo.repoInfo_, appId, (pathString, data, isMerge, tag) => { 12227 repoOnDataUpdate(repo, pathString, data, isMerge, tag); 12228 }, (connectStatus) => { 12229 repoOnConnectStatus(repo, connectStatus); 12230 }, (updates) => { 12231 repoOnServerInfoUpdate(repo, updates); 12232 }, repo.authTokenProvider_, repo.appCheckProvider_, authOverride); 12233 repo.server_ = repo.persistentConnection_; 12234 } 12235 repo.authTokenProvider_.addTokenChangeListener((token) => { 12236 repo.server_.refreshAuthToken(token); 12237 }); 12238 repo.appCheckProvider_.addTokenChangeListener((result) => { 12239 repo.server_.refreshAppCheckToken(result.token); 12240 }); 12241 repo.statsReporter_ = statsManagerGetOrCreateReporter(repo.repoInfo_, () => new StatsReporter(repo.stats_, repo.server_)); 12242 repo.infoData_ = new SnapshotHolder(); 12243 repo.infoSyncTree_ = new SyncTree({ 12244 startListening: (query, tag, currentHashFn, onComplete) => { 12245 let infoEvents = []; 12246 const node = repo.infoData_.getNode(query._path); 12247 if (!node.isEmpty()) { 12248 infoEvents = syncTreeApplyServerOverwrite(repo.infoSyncTree_, query._path, node); 12249 setTimeout(() => { 12250 onComplete("ok"); 12251 }, 0); 12252 } 12253 return infoEvents; 12254 }, 12255 stopListening: () => { 12256 } 12257 }); 12258 repoUpdateInfo(repo, "connected", false); 12259 repo.serverSyncTree_ = new SyncTree({ 12260 startListening: (query, tag, currentHashFn, onComplete) => { 12261 repo.server_.listen(query, currentHashFn, tag, (status, data) => { 12262 const events = onComplete(status, data); 12263 eventQueueRaiseEventsForChangedPath(repo.eventQueue_, query._path, events); 12264 }); 12265 return []; 12266 }, 12267 stopListening: (query, tag) => { 12268 repo.server_.unlisten(query, tag); 12269 } 12270 }); 12271 } 12272 function repoServerTime(repo) { 12273 const offsetNode = repo.infoData_.getNode(new Path(".info/serverTimeOffset")); 12274 const offset = offsetNode.val() || 0; 12275 return new Date().getTime() + offset; 12276 } 12277 function repoGenerateServerValues(repo) { 12278 return generateWithValues({ 12279 timestamp: repoServerTime(repo) 12280 }); 12281 } 12282 function repoOnDataUpdate(repo, pathString, data, isMerge, tag) { 12283 repo.dataUpdateCount++; 12284 const path = new Path(pathString); 12285 data = repo.interceptServerDataCallback_ ? repo.interceptServerDataCallback_(pathString, data) : data; 12286 let events = []; 12287 if (tag) { 12288 if (isMerge) { 12289 const taggedChildren = map(data, (raw) => nodeFromJSON(raw)); 12290 events = syncTreeApplyTaggedQueryMerge(repo.serverSyncTree_, path, taggedChildren, tag); 12291 } else { 12292 const taggedSnap = nodeFromJSON(data); 12293 events = syncTreeApplyTaggedQueryOverwrite(repo.serverSyncTree_, path, taggedSnap, tag); 12294 } 12295 } else if (isMerge) { 12296 const changedChildren = map(data, (raw) => nodeFromJSON(raw)); 12297 events = syncTreeApplyServerMerge(repo.serverSyncTree_, path, changedChildren); 12298 } else { 12299 const snap = nodeFromJSON(data); 12300 events = syncTreeApplyServerOverwrite(repo.serverSyncTree_, path, snap); 12301 } 12302 let affectedPath = path; 12303 if (events.length > 0) { 12304 affectedPath = repoRerunTransactions(repo, path); 12305 } 12306 eventQueueRaiseEventsForChangedPath(repo.eventQueue_, affectedPath, events); 12307 } 12308 function repoOnConnectStatus(repo, connectStatus) { 12309 repoUpdateInfo(repo, "connected", connectStatus); 12310 if (connectStatus === false) { 12311 repoRunOnDisconnectEvents(repo); 12312 } 12313 } 12314 function repoOnServerInfoUpdate(repo, updates) { 12315 each(updates, (key, value) => { 12316 repoUpdateInfo(repo, key, value); 12317 }); 12318 } 12319 function repoUpdateInfo(repo, pathString, value) { 12320 const path = new Path("/.info/" + pathString); 12321 const newNode = nodeFromJSON(value); 12322 repo.infoData_.updateSnapshot(path, newNode); 12323 const events = syncTreeApplyServerOverwrite(repo.infoSyncTree_, path, newNode); 12324 eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events); 12325 } 12326 function repoGetNextWriteId(repo) { 12327 return repo.nextWriteId_++; 12328 } 12329 function repoRunOnDisconnectEvents(repo) { 12330 repoLog(repo, "onDisconnectEvents"); 12331 const serverValues = repoGenerateServerValues(repo); 12332 const resolvedOnDisconnectTree = newSparseSnapshotTree(); 12333 sparseSnapshotTreeForEachTree(repo.onDisconnect_, newEmptyPath(), (path, node) => { 12334 const resolved = resolveDeferredValueTree(path, node, repo.serverSyncTree_, serverValues); 12335 sparseSnapshotTreeRemember(resolvedOnDisconnectTree, path, resolved); 12336 }); 12337 let events = []; 12338 sparseSnapshotTreeForEachTree(resolvedOnDisconnectTree, newEmptyPath(), (path, snap) => { 12339 events = events.concat(syncTreeApplyServerOverwrite(repo.serverSyncTree_, path, snap)); 12340 const affectedPath = repoAbortTransactions(repo, path); 12341 repoRerunTransactions(repo, affectedPath); 12342 }); 12343 repo.onDisconnect_ = newSparseSnapshotTree(); 12344 eventQueueRaiseEventsForChangedPath(repo.eventQueue_, newEmptyPath(), events); 12345 } 12346 function repoInterrupt(repo) { 12347 if (repo.persistentConnection_) { 12348 repo.persistentConnection_.interrupt(INTERRUPT_REASON); 12349 } 12350 } 12351 function repoLog(repo, ...varArgs) { 12352 let prefix = ""; 12353 if (repo.persistentConnection_) { 12354 prefix = repo.persistentConnection_.id + ":"; 12355 } 12356 log(prefix, ...varArgs); 12357 } 12358 function repoGetLatestState(repo, path, excludeSets) { 12359 return syncTreeCalcCompleteEventCache(repo.serverSyncTree_, path, excludeSets) || ChildrenNode.EMPTY_NODE; 12360 } 12361 function repoSendReadyTransactions(repo, node = repo.transactionQueueTree_) { 12362 if (!node) { 12363 repoPruneCompletedTransactionsBelowNode(repo, node); 12364 } 12365 if (treeGetValue(node)) { 12366 const queue = repoBuildTransactionQueue(repo, node); 12367 assert(queue.length > 0, "Sending zero length transaction queue"); 12368 const allRun = queue.every((transaction) => transaction.status === 0); 12369 if (allRun) { 12370 repoSendTransactionQueue(repo, treeGetPath(node), queue); 12371 } 12372 } else if (treeHasChildren(node)) { 12373 treeForEachChild(node, (childNode) => { 12374 repoSendReadyTransactions(repo, childNode); 12375 }); 12376 } 12377 } 12378 function repoSendTransactionQueue(repo, path, queue) { 12379 const setsToIgnore = queue.map((txn) => { 12380 return txn.currentWriteId; 12381 }); 12382 const latestState = repoGetLatestState(repo, path, setsToIgnore); 12383 let snapToSend = latestState; 12384 const latestHash = latestState.hash(); 12385 for (let i = 0; i < queue.length; i++) { 12386 const txn = queue[i]; 12387 assert(txn.status === 0, "tryToSendTransactionQueue_: items in queue should all be run."); 12388 txn.status = 1; 12389 txn.retryCount++; 12390 const relativePath = newRelativePath(path, txn.path); 12391 snapToSend = snapToSend.updateChild(relativePath, txn.currentOutputSnapshotRaw); 12392 } 12393 const dataToSend = snapToSend.val(true); 12394 const pathToSend = path; 12395 repo.server_.put(pathToSend.toString(), dataToSend, (status) => { 12396 repoLog(repo, "transaction put response", { 12397 path: pathToSend.toString(), 12398 status 12399 }); 12400 let events = []; 12401 if (status === "ok") { 12402 const callbacks = []; 12403 for (let i = 0; i < queue.length; i++) { 12404 queue[i].status = 2; 12405 events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId)); 12406 if (queue[i].onComplete) { 12407 callbacks.push(() => queue[i].onComplete(null, true, queue[i].currentOutputSnapshotResolved)); 12408 } 12409 queue[i].unwatcher(); 12410 } 12411 repoPruneCompletedTransactionsBelowNode(repo, treeSubTree(repo.transactionQueueTree_, path)); 12412 repoSendReadyTransactions(repo, repo.transactionQueueTree_); 12413 eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events); 12414 for (let i = 0; i < callbacks.length; i++) { 12415 exceptionGuard(callbacks[i]); 12416 } 12417 } else { 12418 if (status === "datastale") { 12419 for (let i = 0; i < queue.length; i++) { 12420 if (queue[i].status === 3) { 12421 queue[i].status = 4; 12422 } else { 12423 queue[i].status = 0; 12424 } 12425 } 12426 } else { 12427 warn("transaction at " + pathToSend.toString() + " failed: " + status); 12428 for (let i = 0; i < queue.length; i++) { 12429 queue[i].status = 4; 12430 queue[i].abortReason = status; 12431 } 12432 } 12433 repoRerunTransactions(repo, path); 12434 } 12435 }, latestHash); 12436 } 12437 function repoRerunTransactions(repo, changedPath) { 12438 const rootMostTransactionNode = repoGetAncestorTransactionNode(repo, changedPath); 12439 const path = treeGetPath(rootMostTransactionNode); 12440 const queue = repoBuildTransactionQueue(repo, rootMostTransactionNode); 12441 repoRerunTransactionQueue(repo, queue, path); 12442 return path; 12443 } 12444 function repoRerunTransactionQueue(repo, queue, path) { 12445 if (queue.length === 0) { 12446 return; 12447 } 12448 const callbacks = []; 12449 let events = []; 12450 const txnsToRerun = queue.filter((q) => { 12451 return q.status === 0; 12452 }); 12453 const setsToIgnore = txnsToRerun.map((q) => { 12454 return q.currentWriteId; 12455 }); 12456 for (let i = 0; i < queue.length; i++) { 12457 const transaction = queue[i]; 12458 const relativePath = newRelativePath(path, transaction.path); 12459 let abortTransaction = false, abortReason; 12460 assert(relativePath !== null, "rerunTransactionsUnderNode_: relativePath should not be null."); 12461 if (transaction.status === 4) { 12462 abortTransaction = true; 12463 abortReason = transaction.abortReason; 12464 events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true)); 12465 } else if (transaction.status === 0) { 12466 if (transaction.retryCount >= MAX_TRANSACTION_RETRIES) { 12467 abortTransaction = true; 12468 abortReason = "maxretry"; 12469 events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true)); 12470 } else { 12471 const currentNode = repoGetLatestState(repo, transaction.path, setsToIgnore); 12472 transaction.currentInputSnapshot = currentNode; 12473 const newData = queue[i].update(currentNode.val()); 12474 if (newData !== void 0) { 12475 validateFirebaseData("transaction failed: Data returned ", newData, transaction.path); 12476 let newDataNode = nodeFromJSON(newData); 12477 const hasExplicitPriority = typeof newData === "object" && newData != null && contains(newData, ".priority"); 12478 if (!hasExplicitPriority) { 12479 newDataNode = newDataNode.updatePriority(currentNode.getPriority()); 12480 } 12481 const oldWriteId = transaction.currentWriteId; 12482 const serverValues = repoGenerateServerValues(repo); 12483 const newNodeResolved = resolveDeferredValueSnapshot(newDataNode, currentNode, serverValues); 12484 transaction.currentOutputSnapshotRaw = newDataNode; 12485 transaction.currentOutputSnapshotResolved = newNodeResolved; 12486 transaction.currentWriteId = repoGetNextWriteId(repo); 12487 setsToIgnore.splice(setsToIgnore.indexOf(oldWriteId), 1); 12488 events = events.concat(syncTreeApplyUserOverwrite(repo.serverSyncTree_, transaction.path, newNodeResolved, transaction.currentWriteId, transaction.applyLocally)); 12489 events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, oldWriteId, true)); 12490 } else { 12491 abortTransaction = true; 12492 abortReason = "nodata"; 12493 events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, transaction.currentWriteId, true)); 12494 } 12495 } 12496 } 12497 eventQueueRaiseEventsForChangedPath(repo.eventQueue_, path, events); 12498 events = []; 12499 if (abortTransaction) { 12500 queue[i].status = 2; 12501 (function(unwatcher) { 12502 setTimeout(unwatcher, Math.floor(0)); 12503 })(queue[i].unwatcher); 12504 if (queue[i].onComplete) { 12505 if (abortReason === "nodata") { 12506 callbacks.push(() => queue[i].onComplete(null, false, queue[i].currentInputSnapshot)); 12507 } else { 12508 callbacks.push(() => queue[i].onComplete(new Error(abortReason), false, null)); 12509 } 12510 } 12511 } 12512 } 12513 repoPruneCompletedTransactionsBelowNode(repo, repo.transactionQueueTree_); 12514 for (let i = 0; i < callbacks.length; i++) { 12515 exceptionGuard(callbacks[i]); 12516 } 12517 repoSendReadyTransactions(repo, repo.transactionQueueTree_); 12518 } 12519 function repoGetAncestorTransactionNode(repo, path) { 12520 let front; 12521 let transactionNode = repo.transactionQueueTree_; 12522 front = pathGetFront(path); 12523 while (front !== null && treeGetValue(transactionNode) === void 0) { 12524 transactionNode = treeSubTree(transactionNode, front); 12525 path = pathPopFront(path); 12526 front = pathGetFront(path); 12527 } 12528 return transactionNode; 12529 } 12530 function repoBuildTransactionQueue(repo, transactionNode) { 12531 const transactionQueue = []; 12532 repoAggregateTransactionQueuesForNode(repo, transactionNode, transactionQueue); 12533 transactionQueue.sort((a, b) => a.order - b.order); 12534 return transactionQueue; 12535 } 12536 function repoAggregateTransactionQueuesForNode(repo, node, queue) { 12537 const nodeQueue = treeGetValue(node); 12538 if (nodeQueue) { 12539 for (let i = 0; i < nodeQueue.length; i++) { 12540 queue.push(nodeQueue[i]); 12541 } 12542 } 12543 treeForEachChild(node, (child) => { 12544 repoAggregateTransactionQueuesForNode(repo, child, queue); 12545 }); 12546 } 12547 function repoPruneCompletedTransactionsBelowNode(repo, node) { 12548 const queue = treeGetValue(node); 12549 if (queue) { 12550 let to = 0; 12551 for (let from = 0; from < queue.length; from++) { 12552 if (queue[from].status !== 2) { 12553 queue[to] = queue[from]; 12554 to++; 12555 } 12556 } 12557 queue.length = to; 12558 treeSetValue(node, queue.length > 0 ? queue : void 0); 12559 } 12560 treeForEachChild(node, (childNode) => { 12561 repoPruneCompletedTransactionsBelowNode(repo, childNode); 12562 }); 12563 } 12564 function repoAbortTransactions(repo, path) { 12565 const affectedPath = treeGetPath(repoGetAncestorTransactionNode(repo, path)); 12566 const transactionNode = treeSubTree(repo.transactionQueueTree_, path); 12567 treeForEachAncestor(transactionNode, (node) => { 12568 repoAbortTransactionsOnNode(repo, node); 12569 }); 12570 repoAbortTransactionsOnNode(repo, transactionNode); 12571 treeForEachDescendant(transactionNode, (node) => { 12572 repoAbortTransactionsOnNode(repo, node); 12573 }); 12574 return affectedPath; 12575 } 12576 function repoAbortTransactionsOnNode(repo, node) { 12577 const queue = treeGetValue(node); 12578 if (queue) { 12579 const callbacks = []; 12580 let events = []; 12581 let lastSent = -1; 12582 for (let i = 0; i < queue.length; i++) { 12583 if (queue[i].status === 3) 12584 ; 12585 else if (queue[i].status === 1) { 12586 assert(lastSent === i - 1, "All SENT items should be at beginning of queue."); 12587 lastSent = i; 12588 queue[i].status = 3; 12589 queue[i].abortReason = "set"; 12590 } else { 12591 assert(queue[i].status === 0, "Unexpected transaction status in abort"); 12592 queue[i].unwatcher(); 12593 events = events.concat(syncTreeAckUserWrite(repo.serverSyncTree_, queue[i].currentWriteId, true)); 12594 if (queue[i].onComplete) { 12595 callbacks.push(queue[i].onComplete.bind(null, new Error("set"), false, null)); 12596 } 12597 } 12598 } 12599 if (lastSent === -1) { 12600 treeSetValue(node, void 0); 12601 } else { 12602 queue.length = lastSent + 1; 12603 } 12604 eventQueueRaiseEventsForChangedPath(repo.eventQueue_, treeGetPath(node), events); 12605 for (let i = 0; i < callbacks.length; i++) { 12606 exceptionGuard(callbacks[i]); 12607 } 12608 } 12609 } 12610 function decodePath(pathString) { 12611 let pathStringDecoded = ""; 12612 const pieces = pathString.split("/"); 12613 for (let i = 0; i < pieces.length; i++) { 12614 if (pieces[i].length > 0) { 12615 let piece = pieces[i]; 12616 try { 12617 piece = decodeURIComponent(piece.replace(/\+/g, " ")); 12618 } catch (e) { 12619 } 12620 pathStringDecoded += "/" + piece; 12621 } 12622 } 12623 return pathStringDecoded; 12624 } 12625 function decodeQuery(queryString) { 12626 const results = {}; 12627 if (queryString.charAt(0) === "?") { 12628 queryString = queryString.substring(1); 12629 } 12630 for (const segment of queryString.split("&")) { 12631 if (segment.length === 0) { 12632 continue; 12633 } 12634 const kv = segment.split("="); 12635 if (kv.length === 2) { 12636 results[decodeURIComponent(kv[0])] = decodeURIComponent(kv[1]); 12637 } else { 12638 warn(`Invalid query segment '${segment}' in query '${queryString}'`); 12639 } 12640 } 12641 return results; 12642 } 12643 var parseRepoInfo = function(dataURL, nodeAdmin) { 12644 const parsedUrl = parseDatabaseURL(dataURL), namespace = parsedUrl.namespace; 12645 if (parsedUrl.domain === "firebase.com") { 12646 fatal(parsedUrl.host + " is no longer supported. Please use <YOUR FIREBASE>.firebaseio.com instead"); 12647 } 12648 if ((!namespace || namespace === "undefined") && parsedUrl.domain !== "localhost") { 12649 fatal("Cannot parse Firebase url. Please use https://<YOUR FIREBASE>.firebaseio.com"); 12650 } 12651 if (!parsedUrl.secure) { 12652 warnIfPageIsSecure(); 12653 } 12654 const webSocketOnly = parsedUrl.scheme === "ws" || parsedUrl.scheme === "wss"; 12655 return { 12656 repoInfo: new RepoInfo(parsedUrl.host, parsedUrl.secure, namespace, webSocketOnly, nodeAdmin, "", namespace !== parsedUrl.subdomain), 12657 path: new Path(parsedUrl.pathString) 12658 }; 12659 }; 12660 var parseDatabaseURL = function(dataURL) { 12661 let host = "", domain = "", subdomain = "", pathString = "", namespace = ""; 12662 let secure = true, scheme = "https", port = 443; 12663 if (typeof dataURL === "string") { 12664 let colonInd = dataURL.indexOf("//"); 12665 if (colonInd >= 0) { 12666 scheme = dataURL.substring(0, colonInd - 1); 12667 dataURL = dataURL.substring(colonInd + 2); 12668 } 12669 let slashInd = dataURL.indexOf("/"); 12670 if (slashInd === -1) { 12671 slashInd = dataURL.length; 12672 } 12673 let questionMarkInd = dataURL.indexOf("?"); 12674 if (questionMarkInd === -1) { 12675 questionMarkInd = dataURL.length; 12676 } 12677 host = dataURL.substring(0, Math.min(slashInd, questionMarkInd)); 12678 if (slashInd < questionMarkInd) { 12679 pathString = decodePath(dataURL.substring(slashInd, questionMarkInd)); 12680 } 12681 const queryParams = decodeQuery(dataURL.substring(Math.min(dataURL.length, questionMarkInd))); 12682 colonInd = host.indexOf(":"); 12683 if (colonInd >= 0) { 12684 secure = scheme === "https" || scheme === "wss"; 12685 port = parseInt(host.substring(colonInd + 1), 10); 12686 } else { 12687 colonInd = host.length; 12688 } 12689 const hostWithoutPort = host.slice(0, colonInd); 12690 if (hostWithoutPort.toLowerCase() === "localhost") { 12691 domain = "localhost"; 12692 } else if (hostWithoutPort.split(".").length <= 2) { 12693 domain = hostWithoutPort; 12694 } else { 12695 const dotInd = host.indexOf("."); 12696 subdomain = host.substring(0, dotInd).toLowerCase(); 12697 domain = host.substring(dotInd + 1); 12698 namespace = subdomain; 12699 } 12700 if ("ns" in queryParams) { 12701 namespace = queryParams["ns"]; 12702 } 12703 } 12704 return { 12705 host, 12706 port, 12707 domain, 12708 subdomain, 12709 secure, 12710 scheme, 12711 pathString, 12712 namespace 12713 }; 12714 }; 12715 var QueryImpl = class { 12716 constructor(_repo, _path, _queryParams, _orderByCalled) { 12717 this._repo = _repo; 12718 this._path = _path; 12719 this._queryParams = _queryParams; 12720 this._orderByCalled = _orderByCalled; 12721 } 12722 get key() { 12723 if (pathIsEmpty(this._path)) { 12724 return null; 12725 } else { 12726 return pathGetBack(this._path); 12727 } 12728 } 12729 get ref() { 12730 return new ReferenceImpl(this._repo, this._path); 12731 } 12732 get _queryIdentifier() { 12733 const obj = queryParamsGetQueryObject(this._queryParams); 12734 const id = ObjectToUniqueKey(obj); 12735 return id === "{}" ? "default" : id; 12736 } 12737 get _queryObject() { 12738 return queryParamsGetQueryObject(this._queryParams); 12739 } 12740 isEqual(other) { 12741 other = getModularInstance(other); 12742 if (!(other instanceof QueryImpl)) { 12743 return false; 12744 } 12745 const sameRepo = this._repo === other._repo; 12746 const samePath = pathEquals(this._path, other._path); 12747 const sameQueryIdentifier = this._queryIdentifier === other._queryIdentifier; 12748 return sameRepo && samePath && sameQueryIdentifier; 12749 } 12750 toJSON() { 12751 return this.toString(); 12752 } 12753 toString() { 12754 return this._repo.toString() + pathToUrlEncodedString(this._path); 12755 } 12756 }; 12757 var ReferenceImpl = class extends QueryImpl { 12758 constructor(repo, path) { 12759 super(repo, path, new QueryParams(), false); 12760 } 12761 get parent() { 12762 const parentPath = pathParent(this._path); 12763 return parentPath === null ? null : new ReferenceImpl(this._repo, parentPath); 12764 } 12765 get root() { 12766 let ref = this; 12767 while (ref.parent !== null) { 12768 ref = ref.parent; 12769 } 12770 return ref; 12771 } 12772 }; 12773 syncPointSetReferenceConstructor(ReferenceImpl); 12774 syncTreeSetReferenceConstructor(ReferenceImpl); 12775 var FIREBASE_DATABASE_EMULATOR_HOST_VAR = "FIREBASE_DATABASE_EMULATOR_HOST"; 12776 var repos = {}; 12777 var useRestClient = false; 12778 function repoManagerDatabaseFromApp(app2, authProvider, appCheckProvider, url, nodeAdmin) { 12779 let dbUrl = url || app2.options.databaseURL; 12780 if (dbUrl === void 0) { 12781 if (!app2.options.projectId) { 12782 fatal("Can't determine Firebase Database URL. Be sure to include a Project ID when calling firebase.initializeApp()."); 12783 } 12784 log("Using default host for project ", app2.options.projectId); 12785 dbUrl = `${app2.options.projectId}-default-rtdb.firebaseio.com`; 12786 } 12787 let parsedUrl = parseRepoInfo(dbUrl, nodeAdmin); 12788 let repoInfo = parsedUrl.repoInfo; 12789 let isEmulator; 12790 let dbEmulatorHost = void 0; 12791 if (typeof process !== "undefined" && process.env) { 12792 dbEmulatorHost = process.env[FIREBASE_DATABASE_EMULATOR_HOST_VAR]; 12793 } 12794 if (dbEmulatorHost) { 12795 isEmulator = true; 12796 dbUrl = `http://${dbEmulatorHost}?ns=${repoInfo.namespace}`; 12797 parsedUrl = parseRepoInfo(dbUrl, nodeAdmin); 12798 repoInfo = parsedUrl.repoInfo; 12799 } else { 12800 isEmulator = !parsedUrl.repoInfo.secure; 12801 } 12802 const authTokenProvider = nodeAdmin && isEmulator ? new EmulatorTokenProvider(EmulatorTokenProvider.OWNER) : new FirebaseAuthTokenProvider(app2.name, app2.options, authProvider); 12803 validateUrl("Invalid Firebase Database URL", parsedUrl); 12804 if (!pathIsEmpty(parsedUrl.path)) { 12805 fatal("Database URL must point to the root of a Firebase Database (not including a child path)."); 12806 } 12807 const repo = repoManagerCreateRepo(repoInfo, app2, authTokenProvider, new AppCheckTokenProvider(app2.name, appCheckProvider)); 12808 return new Database(repo, app2); 12809 } 12810 function repoManagerDeleteRepo(repo, appName) { 12811 const appRepos = repos[appName]; 12812 if (!appRepos || appRepos[repo.key] !== repo) { 12813 fatal(`Database ${appName}(${repo.repoInfo_}) has already been deleted.`); 12814 } 12815 repoInterrupt(repo); 12816 delete appRepos[repo.key]; 12817 } 12818 function repoManagerCreateRepo(repoInfo, app2, authTokenProvider, appCheckProvider) { 12819 let appRepos = repos[app2.name]; 12820 if (!appRepos) { 12821 appRepos = {}; 12822 repos[app2.name] = appRepos; 12823 } 12824 let repo = appRepos[repoInfo.toURLString()]; 12825 if (repo) { 12826 fatal("Database initialized multiple times. Please make sure the format of the database URL matches with each database() call."); 12827 } 12828 repo = new Repo(repoInfo, useRestClient, authTokenProvider, appCheckProvider); 12829 appRepos[repoInfo.toURLString()] = repo; 12830 return repo; 12831 } 12832 var Database = class { 12833 constructor(_repoInternal, app2) { 12834 this._repoInternal = _repoInternal; 12835 this.app = app2; 12836 this["type"] = "database"; 12837 this._instanceStarted = false; 12838 } 12839 get _repo() { 12840 if (!this._instanceStarted) { 12841 repoStart(this._repoInternal, this.app.options.appId, this.app.options["databaseAuthVariableOverride"]); 12842 this._instanceStarted = true; 12843 } 12844 return this._repoInternal; 12845 } 12846 get _root() { 12847 if (!this._rootInternal) { 12848 this._rootInternal = new ReferenceImpl(this._repo, newEmptyPath()); 12849 } 12850 return this._rootInternal; 12851 } 12852 _delete() { 12853 if (this._rootInternal !== null) { 12854 repoManagerDeleteRepo(this._repo, this.app.name); 12855 this._repoInternal = null; 12856 this._rootInternal = null; 12857 } 12858 return Promise.resolve(); 12859 } 12860 _checkNotDeleted(apiName) { 12861 if (this._rootInternal === null) { 12862 fatal("Cannot call " + apiName + " on a deleted database."); 12863 } 12864 } 12865 }; 12866 function getDatabase(app2 = getApp(), url) { 12867 return _getProvider(app2, "database").getImmediate({ 12868 identifier: url 12869 }); 12870 } 12871 function registerDatabase(variant) { 12872 setSDKVersion(SDK_VERSION); 12873 _registerComponent(new Component("database", (container, { instanceIdentifier: url }) => { 12874 const app2 = container.getProvider("app").getImmediate(); 12875 const authProvider = container.getProvider("auth-internal"); 12876 const appCheckProvider = container.getProvider("app-check-internal"); 12877 return repoManagerDatabaseFromApp(app2, authProvider, appCheckProvider, url); 12878 }, "PUBLIC").setMultipleInstances(true)); 12879 registerVersion(name6, version6, variant); 12880 registerVersion(name6, version6, "esm2017"); 12881 } 12882 PersistentConnection.prototype.simpleListen = function(pathString, onComplete) { 12883 this.sendRequest("q", { p: pathString }, onComplete); 12884 }; 12885 PersistentConnection.prototype.echo = function(data, onEcho) { 12886 this.sendRequest("echo", { d: data }, onEcho); 12887 }; 12888 registerDatabase(); 12889 12890 // <stdin> 12891 var firebaseConfig = { 12892 apiKey: "AIzaSyB3UbePjjc0Q5-G6uYnWntG9mdKQBL9d6w", 12893 authDomain: "auth.iolingjapan.org", 12894 databaseURL: "https://application-ef043.firebaseio.com", 12895 projectId: "application-ef043", 12896 storageBucket: "application-ef043.appspot.com", 12897 messagingSenderId: "205884223458", 12898 appId: "1:205884223458:web:38aa6379161011c78e13bb", 12899 measurementId: "G-835927SH9F" 12900 }; 12901 var app = initializeApp(firebaseConfig); 12902 var analytics = initializeAnalytics(app); 12903 var auth = initializeAuth(app, { 12904 persistence: [ 12905 indexedDBLocalPersistence, 12906 browserLocalPersistence, 12907 browserSessionPersistence 12908 ] 12909 }); 12910 var db = getDatabase(app); 12911 var navbarlogin = document.getElementById("navbarlogin"); 12912 if (navbarlogin) { 12913 navbarlogin.addEventListener("click", (e) => { 12914 onAuthStateChanged(auth, (user) => { 12915 if (user) { 12916 location.href = "/account/"; 12917 } else { 12918 location.href = "/login/"; 12919 } 12920 }); 12921 }); 12922 } 12923 var logout = () => { 12924 onAuthStateChanged(auth, (user) => { 12925 auth.signOut().then(() => { 12926 console.log("\u30ED\u30B0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F"); 12927 }).catch((error2) => { 12928 console.log(`\u30ED\u30B0\u30A2\u30A6\u30C8\u6642\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F (${error2})`); 12929 }); 12930 }); 12931 }; 12932})(); 12933/** 12934 * @license 12935 * Copyright 2017 Google LLC 12936 * 12937 * Licensed under the Apache License, Version 2.0 (the "License"); 12938 * you may not use this file except in compliance with the License. 12939 * You may obtain a copy of the License at 12940 * 12941 * http://www.apache.org/licenses/LICENSE-2.0 12942 * 12943 * Unless required by applicable law or agreed to in writing, software 12944 * distributed under the License is distributed on an "AS IS" BASIS, 12945 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12946 * See the License for the specific language governing permissions and 12947 * limitations under the License. 12948 */ 12949/** 12950 * @license 12951 * Copyright 2019 Google LLC 12952 * 12953 * Licensed under the Apache License, Version 2.0 (the "License"); 12954 * you may not use this file except in compliance with the License. 12955 * You may obtain a copy of the License at 12956 * 12957 * http://www.apache.org/licenses/LICENSE-2.0 12958 * 12959 * Unless required by applicable law or agreed to in writing, software 12960 * distributed under the License is distributed on an "AS IS" BASIS, 12961 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12962 * See the License for the specific language governing permissions and 12963 * limitations under the License. 12964 */ 12965/** 12966 * @license 12967 * Copyright 2020 Google LLC 12968 * 12969 * Licensed under the Apache License, Version 2.0 (the "License"); 12970 * you may not use this file except in compliance with the License. 12971 * You may obtain a copy of the License at 12972 * 12973 * http://www.apache.org/licenses/LICENSE-2.0 12974 * 12975 * Unless required by applicable law or agreed to in writing, software 12976 * distributed under the License is distributed on an "AS IS" BASIS, 12977 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12978 * See the License for the specific language governing permissions and 12979 * limitations under the License. 12980 */ 12981/** 12982 * @license 12983 * Copyright 2020 Google LLC. 12984 * 12985 * Licensed under the Apache License, Version 2.0 (the "License"); 12986 * you may not use this file except in compliance with the License. 12987 * You may obtain a copy of the License at 12988 * 12989 * http://www.apache.org/licenses/LICENSE-2.0 12990 * 12991 * Unless required by applicable law or agreed to in writing, software 12992 * distributed under the License is distributed on an "AS IS" BASIS, 12993 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12994 * See the License for the specific language governing permissions and 12995 * limitations under the License. 12996 */ 12997/** 12998 * @license 12999 * Copyright 2021 Google LLC 13000 * 13001 * Licensed under the Apache License, Version 2.0 (the "License"); 13002 * you may not use this file except in compliance with the License. 13003 * You may obtain a copy of the License at 13004 * 13005 * http://www.apache.org/licenses/LICENSE-2.0 13006 * 13007 * Unless required by applicable law or agreed to in writing, software 13008 * distributed under the License is distributed on an "AS IS" BASIS, 13009 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13010 * See the License for the specific language governing permissions and 13011 * limitations under the License. 13012 */ 13013/** 13014 * @license 13015 * Copyright 2022 Google LLC 13016 * 13017 * Licensed under the Apache License, Version 2.0 (the "License"); 13018 * you may not use this file except in compliance with the License. 13019 * You may obtain a copy of the License at 13020 * 13021 * http://www.apache.org/licenses/LICENSE-2.0 13022 * 13023 * Unless required by applicable law or agreed to in writing, software 13024 * distributed under the License is distributed on an "AS IS" BASIS, 13025 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13026 * See the License for the specific language governing permissions and 13027 * limitations under the License. 13028 */
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.