var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name4 in all) __defProp(target, name4, { get: all[name4], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // client/src/index.ts var src_exports = {}; __export(src_exports, { AdriftBareClient: () => AdriftBareClient, Connection: () => Connection, DevWsTransport: () => DevWsTransport, RTCTransport: () => RTCTransport, SignalFirebase: () => SignalFirebase_exports, downloadShortcut: () => downloadShortcut }); module.exports = __toCommonJS(src_exports); // node_modules/.pnpm/uuid@9.0.0/node_modules/uuid/dist/esm-browser/rng.js var getRandomValues; var rnds8 = new Uint8Array(16); function rng() { if (!getRandomValues) { getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); if (!getRandomValues) { throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported"); } } return getRandomValues(rnds8); } // node_modules/.pnpm/uuid@9.0.0/node_modules/uuid/dist/esm-browser/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); } function unsafeStringify(arr, offset = 0) { return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); } // node_modules/.pnpm/uuid@9.0.0/node_modules/uuid/dist/esm-browser/native.js var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto); var native_default = { randomUUID }; // node_modules/.pnpm/uuid@9.0.0/node_modules/uuid/dist/esm-browser/v4.js function v4(options, buf, offset) { if (native_default.randomUUID && !buf && !options) { return native_default.randomUUID(); } options = options || {}; const rnds = options.random || (options.rng || rng)(); rnds[6] = rnds[6] & 15 | 64; rnds[8] = rnds[8] & 63 | 128; if (buf) { offset = offset || 0; for (let i = 0; i < 16; ++i) { buf[offset + i] = rnds[i]; } return buf; } return unsafeStringify(rnds); } var v4_default = v4; // node_modules/.pnpm/file+bare-client-custom/node_modules/bare-client-custom/dist/index.js var WebSocket2 = globalThis.WebSocket; var Request = globalThis.Request; var Response2 = globalThis.Response; var WebSocketFields = { prototype: { send: WebSocket2.prototype.send }, CLOSED: WebSocket2.CLOSED, CLOSING: WebSocket2.CLOSING, CONNECTING: WebSocket2.CONNECTING, OPEN: WebSocket2.OPEN }; var statusEmpty = [101, 204, 205, 304]; var Client = class { }; var RemoteClient = class extends Client { callbacks = {}; uid = v4_default(); constructor() { super(); if (!("ServiceWorkerGlobalScope" in self)) { throw new TypeError("Attempt to construct RemoteClient from outside a service worker"); } addEventListener("message", (event) => { if (event.data.__remote_target === this.uid) { const callback = this.callbacks[event.data.__remote_id]; callback(event.data.__remote_value); } }); } async send(message, id) { const clients = await self.clients.matchAll(); if (clients.length < 1) throw new Error("no available clients"); for (const client of clients) { client.postMessage({ __remote_target: this.uid, __remote_id: id, __remote_value: message }); } } async sendWithResponse(message) { const id = v4_default(); return new Promise((resolve) => { this.callbacks[id] = resolve; this.send(message, id); }); } connect(remote, protocols, getRequestHeaders, onMeta, onReadyState) { return new WebSocket2(""); } async request(method, requestHeaders, body, remote, cache, duplex, signal) { const response = await this.sendWithResponse({ type: "request", options: { method, requestHeaders, body, remote: remote.toString() } }); const result = new Response2(statusEmpty.includes(response.status) ? void 0 : response.body, { status: response.status, statusText: response.statusText ?? void 0, headers: new Headers(response.headers) }); result.rawHeaders = response.headers; result.rawResponse = response; return result; } }; var getRealReadyState = Object.getOwnPropertyDescriptor(WebSocket2.prototype, "readyState").get; self.BCC_VERSION = "1.2.1"; console.warn("BCC_VERSION: " + self.BCC_VERSION); function setBareClientImplementation(implementation) { self.gBareClientImplementation = implementation; } if ("ServiceWorkerGlobalScope" in self) { setBareClientImplementation(new RemoteClient()); } else { let parent = self; console.log("attempting to find an implementation"); for (let i = 0; i < 10; i++) { try { parent = parent.parent; if (parent && parent["gBareClientImplementation"]) { console.warn("found implementation on parent"); setBareClientImplementation(parent["gBareClientImplementation"]); break; } } catch (e) { console.log("could not find implementation"); break; } } } // protocol/src/Transport.ts var Transport = class { constructor(onopen, onclose) { this.onopen = onopen; this.onclose = onclose; } ondata = () => { }; }; // protocol/src/index.ts var C2SRequestTypes = { HTTPRequestStart: 0, HTTPRequestChunk: 1, HTTPRequestEnd: 2, WSOpen: 3, WSClose: 4, WSSendText: 5, WSSendBinary: 6 }; var S2CRequestTypes = { HTTPResponseStart: 0, HTTPResponseChunk: 1, HTTPResponseEnd: 2, WSOpen: 3, WSClose: 4, WSTextStart: 5, WSBinaryStart: 6, WSDataChunk: 7, WSDataEnd: 8, WSError: 9 }; var MAX_CHUNK_SIZE = 12 * 1024; var S2C_HELLO_OK = ":3"; var C2S_HELLO = "haiii "; var S2C_HELLO_ERR = ":< "; var PROTOCOL_VERSION = "3.0"; // client/src/AdriftClient.ts var NULL_BODY_STATUSES = [101, 103, 204, 205, 304]; function createBodyStream(body, arrayBufferImpl) { if (body === null || typeof body === "undefined") return null; if (typeof body === "string") { body = new TextEncoder().encode(body); } if (window.ArrayBuffer.isView(body)) { body = body.buffer.slice( body.byteOffset, body.byteOffset + body.byteLength ); } if (body instanceof window.ArrayBuffer) { if (body.byteLength == 0) { return null; } let remaining = body; return new ReadableStream({ type: "bytes", pull: (controller) => { if (remaining.byteLength <= 0) { return controller.close(); } const current = remaining.slice(0, MAX_CHUNK_SIZE); remaining = remaining.slice(MAX_CHUNK_SIZE); controller.enqueue(new Uint8Array(current)); } }); } if (body instanceof FormData) { throw new Error("formdata todo"); } const transformer = () => new TransformStream({ transform: async (chunk, controller) => { if (typeof chunk === "string") { chunk = new TextEncoder().encode(chunk); } if (chunk instanceof Blob) { chunk = await chunk.arrayBuffer(); } if (window.ArrayBuffer.isView(chunk)) { chunk = chunk.buffer.slice( chunk.byteOffset, chunk.byteOffset + chunk.byteLength ); } if (!(chunk instanceof window.ArrayBuffer)) { console.error({ chunk }); throw new Error("Invalid type read from body stream: " + chunk); } let current = null; let remaining = chunk; do { current = remaining.slice(0, MAX_CHUNK_SIZE); remaining = remaining.slice(MAX_CHUNK_SIZE); controller.enqueue(new Uint8Array(current)); } while (remaining.byteLength > 0); } }); if (body instanceof ReadableStream) { return body.pipeThrough(transformer()); } if (body instanceof Blob) { return body.stream().pipeThrough(transformer()); } throw new Error("Unexpected body type: " + body); } var AdriftBareClient = class extends Client { constructor(connection) { super(); this.connection = connection; } async request(method, requestHeaders, body, remote, cache, duplex, signal, arrayBufferImpl) { const bodyStream = createBodyStream(body, arrayBufferImpl); let { payload, body: respRawBody } = await this.connection.httprequest( { method, requestHeaders, remote }, bodyStream ); const headers = new Headers(); for (const [header, values] of Object.entries(payload.headers)) { for (const value of values) { headers.append(header, value); } } let respBody = respRawBody; if (respBody.byteLength == 0 || NULL_BODY_STATUSES.includes(payload.status)) { respBody = null; } return new Response(respBody, { status: payload.status, statusText: payload.statusText, headers }); } connect(remote, protocols, getRequestHeaders, onMeta, onReadyState, webSocketImpl, arrayBufferImpl) { const ws = new webSocketImpl("wss:null", protocols); let initalCloseHappened = false; ws.addEventListener("close", (e) => { if (!initalCloseHappened) { onReadyState(WebSocket.CONNECTING); e.stopImmediatePropagation(); initalCloseHappened = true; } }); let initialErrorHappened = false; ws.addEventListener("error", (e) => { if (!initialErrorHappened) { onReadyState(WebSocket.CONNECTING); e.stopImmediatePropagation(); initialErrorHappened = true; } }); let { send, close } = this.connection.wsconnect( remote, protocols, (protocol) => { onReadyState(WebSocket.OPEN); ws.__defineGetter__("protocol", () => { return protocol; }); ws.dispatchEvent(new Event("open")); }, (code, reason, wasClean) => { onReadyState(WebSocket.CLOSED); ws.dispatchEvent(new CloseEvent("close", { code, reason, wasClean })); }, async (stream, isBinary) => { let data = await new Response( stream ).arrayBuffer(); data.__proto__ = arrayBufferImpl.prototype; if (!isBinary) { try { data = new TextDecoder().decode(); } catch (e) { console.error(e); return; } } ws.dispatchEvent(new MessageEvent("message", { data })); }, (message) => { console.log({ message }); ws.dispatchEvent(new ErrorEvent("error", { message })); }, arrayBufferImpl ); ws.send = (data) => { send(data); }; ws.close = (code, reason) => { close(code, reason); onReadyState(WebSocket.CLOSING); }; return ws; } }; // client/src/Connection.ts ReadableStream.prototype[Symbol.asyncIterator] = async function* () { const reader = this.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) return; yield value; } } finally { reader.releaseLock(); } }; var Connection = class _Connection { constructor(transport) { this.transport = transport; this.initialized = false; this.requestCallbacks = {}; this.openRequestStreams = {}; this.openingSockets = {}; this.openSockets = {}; this.wsMsgStreams = {}; this.counter = 0; transport.ondata = _Connection.uninitializedError; } static uninitializedError() { throw new Error("Connection not initialized"); } async initialize() { const onDataPromise = () => { return new Promise((res) => { this.transport.ondata = res; }); }; this.transport.send(new TextEncoder().encode(C2S_HELLO + PROTOCOL_VERSION)); const msg = await onDataPromise(); const msgText = new TextDecoder().decode(msg); if (msgText === S2C_HELLO_OK) { this.transport.ondata = this.ondata.bind(this); this.initialized = true; } else if (msgText.startsWith(S2C_HELLO_ERR)) { const expectedVersion = msgText.slice(S2C_HELLO_ERR.length); throw new Error( `We are running protocol version ${PROTOCOL_VERSION}, but server expected ${expectedVersion}` ); } else { throw new Error("Unexpected server hello response"); } } nextSeq() { return ++this.counter; } ondata(data) { if (!this.initialized) return; let cursor = 0; const view = new DataView(data); let requestID = view.getUint16(cursor); cursor += 2; let requestType = view.getUint8(cursor); cursor += 1; const msgText = () => new TextDecoder().decode(data.slice(cursor)); const msgJSON = () => JSON.parse(msgText()); switch (requestType) { case S2CRequestTypes.HTTPResponseStart: const payload = msgJSON(); const stream = new ReadableStream({ start: (controller) => { this.openRequestStreams[requestID] = controller; }, pull: (controller) => { }, cancel: () => { } }); this.requestCallbacks[requestID]({ payload, body: stream }); delete this.requestCallbacks[requestID]; break; case S2CRequestTypes.HTTPResponseChunk: this.openRequestStreams[requestID]?.enqueue( new Uint8Array(data.slice(cursor)) ); break; case S2CRequestTypes.HTTPResponseEnd: this.openRequestStreams[requestID]?.close(); delete this.openRequestStreams[requestID]; break; case S2CRequestTypes.WSOpen: { const socketMeta = this.openingSockets[requestID]; if (!socketMeta) return; const payload2 = msgJSON(); delete this.openingSockets[requestID]; this.openSockets[requestID] = socketMeta; setTimeout(() => socketMeta.onopen(payload2.protocol)); break; } case S2CRequestTypes.WSBinaryStart: case S2CRequestTypes.WSTextStart: { const socketMeta = this.openSockets[requestID]; if (!socketMeta) return; const stream2 = new ReadableStream({ start: (controller) => { this.wsMsgStreams[requestID] = controller; }, pull: (constroller) => { }, cancel: () => { } }); setTimeout( () => socketMeta.onmessage( stream2, requestType === S2CRequestTypes.WSBinaryStart ? true : requestType === S2CRequestTypes.WSTextStart ? false : (() => { throw new Error("unreachable"); })() ) ); break; } case S2CRequestTypes.WSDataChunk: { const stream2 = this.wsMsgStreams[requestID]; stream2?.enqueue(new Uint8Array(data.slice(cursor))); break; } case S2CRequestTypes.WSDataEnd: { const stream2 = this.wsMsgStreams[requestID]; stream2?.close(); break; } case S2CRequestTypes.WSClose: { const socketMeta = this.openingSockets[requestID] || this.openSockets[requestID]; if (!socketMeta) return; const payload2 = msgJSON(); setTimeout( () => socketMeta.onclose( payload2.code || 1005, payload2.reason || "", "wasClean" in payload2 ? Boolean(payload2.wasClean) : false ) ); delete this.openingSockets[requestID]; delete this.openSockets[requestID]; break; } case S2CRequestTypes.WSError: { const socketMeta = this.openingSockets[requestID] || this.openSockets[requestID]; if (!socketMeta) return; const payload2 = msgJSON(); setTimeout(() => socketMeta.onerror(payload2.message)); break; } default: break; } } async send(requestID, type, data) { if (!this.initialized) { _Connection.uninitializedError(); } let header = new window.ArrayBuffer(2 + 1); let view = new DataView(header); let cursor = 0; view.setUint16(cursor, requestID); cursor += 2; view.setUint8(cursor, type); cursor += 1; let buf = header; if (data) { buf = await new Blob([header, data]).arrayBuffer(); } this.transport.send(buf); } httprequest(data, body) { if (!this.initialized) { _Connection.uninitializedError(); } const payload = { ...data, hasBody: Boolean(body) }; let json = JSON.stringify(payload); return new Promise(async (resolve) => { let seq = this.nextSeq(); this.requestCallbacks[seq] = resolve; await this.send(seq, C2SRequestTypes.HTTPRequestStart, new Blob([json])); if (payload.hasBody) { for await (const chunk of body) { await this.send( seq, C2SRequestTypes.HTTPRequestChunk, new Uint8Array(chunk) ); } await this.send(seq, C2SRequestTypes.HTTPRequestEnd); } }); } wsconnect(url, protocols, onopen, onclose, onmessage, onerror, arrayBufferImpl) { if (!this.initialized) { _Connection.uninitializedError(); } const payload = { url: url.toString(), protocols }; const payloadJSON = JSON.stringify(payload); let seq = this.nextSeq(); const closeWithError = () => onclose(1006, "", false); this.send( seq, C2SRequestTypes.WSOpen, new TextEncoder().encode(payloadJSON) ).catch((e) => { console.error(e); closeWithError(); }); this.openingSockets[seq] = { onopen, onmessage, onclose, onerror }; return { send: (data) => { if (!this.openSockets[seq]) { throw new Error("send on closed socket"); } const cleanup = (e) => { console.error(e); delete this.openSockets[seq]; }; if (typeof data === "string") { this.send( seq, C2SRequestTypes.WSSendText, new TextEncoder().encode(data) ).catch(cleanup); return; } if (data instanceof arrayBufferImpl) { this.send(seq, C2SRequestTypes.WSSendBinary, data).catch(cleanup); return; } if (arrayBufferImpl.isView(data)) { this.send( seq, C2SRequestTypes.WSSendBinary, data.buffer.slice( data.byteOffset, data.byteOffset + data.byteLength ) ).catch(cleanup); return; } console.error({ data }); throw new Error("Unexpected type passed to send"); }, close: (code, reason) => { const payload2 = { code, reason }; const payloadJSON2 = JSON.stringify(payload2); this.send( seq, C2SRequestTypes.WSClose, new TextEncoder().encode(payloadJSON2) ).catch((e) => { console.error(e); }); delete this.openSockets[seq]; } }; } }; // client/src/DevWsTransport.ts var DevWsTransport = class extends Transport { constructor(onopen, onclose) { super(onopen, onclose); this.ws = new WebSocket("ws://localhost:3000/dev-ws"); this.ws.binaryType = "arraybuffer"; this.ws.onopen = onopen; this.ws.onclose = onclose; this.ws.onmessage = this.onmessage.bind(this); } onmessage(msg) { if (msg.data instanceof window.ArrayBuffer) { this.ondata(msg.data); return; } } send(data) { this.ws.send(data); } close() { this.ws.close(); } }; // client/src/RTCTransport.ts var rtcConf = { iceServers: [ { urls: "stun:stun.l.google.com:19302" } ] }; var RTCTransport = class extends Transport { constructor(onopen, onclose, onconnectionstatechange, onsignalingstatechange, onicegatheringstatechange) { super(onopen, onclose); this.onopen = onopen; this.onclose = onclose; this.onconnectionstatechange = onconnectionstatechange; this.onsignalingstatechange = onsignalingstatechange; this.onicegatheringstatechange = onicegatheringstatechange; this.peer = new RTCPeerConnection(rtcConf); this.peer.onconnectionstatechange = onconnectionstatechange; this.peer.onsignalingstatechange = onsignalingstatechange; this.peer.oniceconnectionstatechange = (event) => { console.log("ICE connection state:", this.peer.iceConnectionState); if (this.peer.iceConnectionState == "disconnected" || this.peer.iceConnectionState == "failed") { console.log("disconnected"); onclose(); } }; this.peer.onicegatheringstatechange = onicegatheringstatechange; this.dataChannel = this.peer.createDataChannel("host-server"); this.dataChannel.onopen = onopen; this.dataChannel.binaryType = "arraybuffer"; this.dataChannel.onclose = onclose; this.dataChannel.onmessage = async (event) => { let buf = event.data; this.ondata(buf); }; } send(data) { this.dataChannel.send(data); } close() { this.dataChannel.close(); } async createOffer() { const localCandidates = []; let readyPromise = new Promise((resolve, reject) => { this.peer.onicecandidate = async (event) => { if (event.candidate) { localCandidates.push(event.candidate); return; } resolve({ offer, localCandidates }); }; }); const offer = await this.peer.createOffer(); await this.peer.setLocalDescription(offer); return readyPromise; } async answer(answer, candidates) { await this.peer.setRemoteDescription(answer); for (let candidate of candidates) { await this.peer.addIceCandidate(candidate); } } }; // client/src/SignalFirebase.ts var SignalFirebase_exports = {}; __export(SignalFirebase_exports, { signalAccount: () => signalAccount, signalSwarm: () => signalSwarm }); // node_modules/.pnpm/@firebase+util@1.9.3/node_modules/@firebase/util/dist/index.esm2017.js var CONSTANTS = { /** * @define {boolean} Whether this is the client Node.js SDK. */ NODE_CLIENT: false, /** * @define {boolean} Whether this is the Admin Node.js SDK. */ NODE_ADMIN: false, /** * Firebase SDK Version */ SDK_VERSION: "${JSCORE_VERSION}" }; var assert = function(assertion, message) { if (!assertion) { throw assertionError(message); } }; var assertionError = function(message) { return new Error("Firebase Database (" + CONSTANTS.SDK_VERSION + ") INTERNAL ASSERT FAILED: " + message); }; var stringToByteArray$1 = function(str) { const out = []; let p = 0; for (let i = 0; i < str.length; i++) { let c = str.charCodeAt(i); if (c < 128) { out[p++] = c; } else if (c < 2048) { out[p++] = c >> 6 | 192; out[p++] = c & 63 | 128; } else if ((c & 64512) === 55296 && i + 1 < str.length && (str.charCodeAt(i + 1) & 64512) === 56320) { c = 65536 + ((c & 1023) << 10) + (str.charCodeAt(++i) & 1023); out[p++] = c >> 18 | 240; out[p++] = c >> 12 & 63 | 128; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } else { out[p++] = c >> 12 | 224; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } } return out; }; var byteArrayToString = function(bytes) { const out = []; let pos = 0, c = 0; while (pos < bytes.length) { const c1 = bytes[pos++]; if (c1 < 128) { out[c++] = String.fromCharCode(c1); } else if (c1 > 191 && c1 < 224) { const c2 = bytes[pos++]; out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); } else if (c1 > 239 && c1 < 365) { const c2 = bytes[pos++]; const c3 = bytes[pos++]; const c4 = bytes[pos++]; const u = ((c1 & 7) << 18 | (c2 & 63) << 12 | (c3 & 63) << 6 | c4 & 63) - 65536; out[c++] = String.fromCharCode(55296 + (u >> 10)); out[c++] = String.fromCharCode(56320 + (u & 1023)); } else { const c2 = bytes[pos++]; const c3 = bytes[pos++]; out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63); } } return out.join(""); }; var base64 = { /** * Maps bytes to characters. */ byteToCharMap_: null, /** * Maps characters to bytes. */ charToByteMap_: null, /** * Maps bytes to websafe characters. * @private */ byteToCharMapWebSafe_: null, /** * Maps websafe characters to bytes. * @private */ charToByteMapWebSafe_: null, /** * Our default alphabet, shared between * ENCODED_VALS and ENCODED_VALS_WEBSAFE */ ENCODED_VALS_BASE: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", /** * Our default alphabet. Value 64 (=) is special; it means "nothing." */ get ENCODED_VALS() { return this.ENCODED_VALS_BASE + "+/="; }, /** * Our websafe alphabet. */ get ENCODED_VALS_WEBSAFE() { return this.ENCODED_VALS_BASE + "-_."; }, /** * Whether this browser supports the atob and btoa functions. This extension * started at Mozilla but is now implemented by many browsers. We use the * ASSUME_* variables to avoid pulling in the full useragent detection library * but still allowing the standard per-browser compilations. * */ HAS_NATIVE_SUPPORT: typeof atob === "function", /** * Base64-encode an array of bytes. * * @param input An array of bytes (numbers with * value in [0, 255]) to encode. * @param webSafe Boolean indicating we should use the * alternative alphabet. * @return The base64 encoded string. */ encodeByteArray(input, webSafe) { if (!Array.isArray(input)) { throw Error("encodeByteArray takes an array as a parameter"); } this.init_(); const byteToCharMap = webSafe ? this.byteToCharMapWebSafe_ : this.byteToCharMap_; const output = []; for (let i = 0; i < input.length; i += 3) { const byte1 = input[i]; const haveByte2 = i + 1 < input.length; const byte2 = haveByte2 ? input[i + 1] : 0; const haveByte3 = i + 2 < input.length; const byte3 = haveByte3 ? input[i + 2] : 0; const outByte1 = byte1 >> 2; const outByte2 = (byte1 & 3) << 4 | byte2 >> 4; let outByte3 = (byte2 & 15) << 2 | byte3 >> 6; let outByte4 = byte3 & 63; if (!haveByte3) { outByte4 = 64; if (!haveByte2) { outByte3 = 64; } } output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]); } return output.join(""); }, /** * Base64-encode a string. * * @param input A string to encode. * @param webSafe If true, we should use the * alternative alphabet. * @return The base64 encoded string. */ encodeString(input, webSafe) { if (this.HAS_NATIVE_SUPPORT && !webSafe) { return btoa(input); } return this.encodeByteArray(stringToByteArray$1(input), webSafe); }, /** * Base64-decode a string. * * @param input to decode. * @param webSafe True if we should use the * alternative alphabet. * @return string representing the decoded value. */ decodeString(input, webSafe) { if (this.HAS_NATIVE_SUPPORT && !webSafe) { return atob(input); } return byteArrayToString(this.decodeStringToByteArray(input, webSafe)); }, /** * Base64-decode a string. * * In base-64 decoding, groups of four characters are converted into three * bytes. If the encoder did not apply padding, the input length may not * be a multiple of 4. * * In this case, the last group will have fewer than 4 characters, and * padding will be inferred. If the group has one or two characters, it decodes * to one byte. If the group has three characters, it decodes to two bytes. * * @param input Input to decode. * @param webSafe True if we should use the web-safe alphabet. * @return bytes representing the decoded value. */ decodeStringToByteArray(input, webSafe) { this.init_(); const charToByteMap = webSafe ? this.charToByteMapWebSafe_ : this.charToByteMap_; const output = []; for (let i = 0; i < input.length; ) { const byte1 = charToByteMap[input.charAt(i++)]; const haveByte2 = i < input.length; const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0; ++i; const haveByte3 = i < input.length; const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64; ++i; const haveByte4 = i < input.length; const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64; ++i; if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) { throw new DecodeBase64StringError(); } const outByte1 = byte1 << 2 | byte2 >> 4; output.push(outByte1); if (byte3 !== 64) { const outByte2 = byte2 << 4 & 240 | byte3 >> 2; output.push(outByte2); if (byte4 !== 64) { const outByte3 = byte3 << 6 & 192 | byte4; output.push(outByte3); } } } return output; }, /** * Lazy static initialization function. Called before * accessing any of the static map variables. * @private */ init_() { if (!this.byteToCharMap_) { this.byteToCharMap_ = {}; this.charToByteMap_ = {}; this.byteToCharMapWebSafe_ = {}; this.charToByteMapWebSafe_ = {}; for (let i = 0; i < this.ENCODED_VALS.length; i++) { this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i); this.charToByteMap_[this.byteToCharMap_[i]] = i; this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i); this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i; if (i >= this.ENCODED_VALS_BASE.length) { this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i; this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i; } } } } }; var DecodeBase64StringError = class extends Error { constructor() { super(...arguments); this.name = "DecodeBase64StringError"; } }; var base64Encode = function(str) { const utf8Bytes = stringToByteArray$1(str); return base64.encodeByteArray(utf8Bytes, true); }; var base64urlEncodeWithoutPadding = function(str) { return base64Encode(str).replace(/\./g, ""); }; var base64Decode = function(str) { try { return base64.decodeString(str, true); } catch (e) { console.error("base64Decode failed: ", e); } return null; }; function deepCopy(value) { return deepExtend(void 0, value); } function deepExtend(target, source) { if (!(source instanceof Object)) { return source; } switch (source.constructor) { case Date: const dateValue = source; return new Date(dateValue.getTime()); case Object: if (target === void 0) { target = {}; } break; case Array: target = []; break; default: return source; } for (const prop in source) { if (!source.hasOwnProperty(prop) || !isValidKey(prop)) { continue; } target[prop] = deepExtend(target[prop], source[prop]); } return target; } function isValidKey(key) { return key !== "__proto__"; } function getGlobal() { if (typeof self !== "undefined") { return self; } if (typeof window !== "undefined") { return window; } if (typeof global !== "undefined") { return global; } throw new Error("Unable to locate global object."); } var getDefaultsFromGlobal = () => getGlobal().__FIREBASE_DEFAULTS__; var getDefaultsFromEnvVariable = () => { if (typeof process === "undefined" || typeof process.env === "undefined") { return; } const defaultsJsonString = process.env.__FIREBASE_DEFAULTS__; if (defaultsJsonString) { return JSON.parse(defaultsJsonString); } }; var getDefaultsFromCookie = () => { if (typeof document === "undefined") { return; } let match; try { match = document.cookie.match(/__FIREBASE_DEFAULTS__=([^;]+)/); } catch (e) { return; } const decoded = match && base64Decode(match[1]); return decoded && JSON.parse(decoded); }; var getDefaults = () => { try { return getDefaultsFromGlobal() || getDefaultsFromEnvVariable() || getDefaultsFromCookie(); } catch (e) { console.info(`Unable to get __FIREBASE_DEFAULTS__ due to: ${e}`); return; } }; var getDefaultEmulatorHost = (productName) => { var _a, _b; return (_b = (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.emulatorHosts) === null || _b === void 0 ? void 0 : _b[productName]; }; var getDefaultEmulatorHostnameAndPort = (productName) => { const host = getDefaultEmulatorHost(productName); if (!host) { return void 0; } const separatorIndex = host.lastIndexOf(":"); if (separatorIndex <= 0 || separatorIndex + 1 === host.length) { throw new Error(`Invalid host ${host} with no separate hostname and port!`); } const port = parseInt(host.substring(separatorIndex + 1), 10); if (host[0] === "[") { return [host.substring(1, separatorIndex - 1), port]; } else { return [host.substring(0, separatorIndex), port]; } }; var getDefaultAppConfig = () => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a.config; }; var getExperimentalSetting = (name4) => { var _a; return (_a = getDefaults()) === null || _a === void 0 ? void 0 : _a[`_${name4}`]; }; var Deferred = class { constructor() { this.reject = () => { }; this.resolve = () => { }; this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; }); } /** * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback * and returns a node-style callback which will resolve or reject the Deferred's promise. */ wrapCallback(callback) { return (error2, value) => { if (error2) { this.reject(error2); } else { this.resolve(value); } if (typeof callback === "function") { this.promise.catch(() => { }); if (callback.length === 1) { callback(error2); } else { callback(error2, value); } } }; } }; function createMockUserToken(token, projectId) { if (token.uid) { throw new Error('The "uid" field is no longer supported by mockUserToken. Please use "sub" instead for Firebase Auth User ID.'); } const header = { alg: "none", type: "JWT" }; const project = projectId || "demo-project"; const iat = token.iat || 0; const sub = token.sub || token.user_id; if (!sub) { throw new Error("mockUserToken must contain 'sub' or 'user_id' field!"); } const payload = Object.assign({ // Set all required fields to decent defaults iss: `https://securetoken.google.com/${project}`, aud: project, iat, exp: iat + 3600, auth_time: iat, sub, user_id: sub, firebase: { sign_in_provider: "custom", identities: {} } }, token); const signature = ""; return [ base64urlEncodeWithoutPadding(JSON.stringify(header)), base64urlEncodeWithoutPadding(JSON.stringify(payload)), signature ].join("."); } function getUA() { if (typeof navigator !== "undefined" && typeof navigator["userAgent"] === "string") { return navigator["userAgent"]; } else { return ""; } } function isMobileCordova() { return typeof window !== "undefined" && // @ts-ignore Setting up an broadly applicable index signature for Window // just to deal with this case would probably be a bad idea. !!(window["cordova"] || window["phonegap"] || window["PhoneGap"]) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA()); } function isBrowserExtension() { const runtime = typeof chrome === "object" ? chrome.runtime : typeof browser === "object" ? browser.runtime : void 0; return typeof runtime === "object" && runtime.id !== void 0; } function isReactNative() { return typeof navigator === "object" && navigator["product"] === "ReactNative"; } function isIE() { const ua = getUA(); return ua.indexOf("MSIE ") >= 0 || ua.indexOf("Trident/") >= 0; } function isNodeSdk() { return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true; } function isIndexedDBAvailable() { try { return typeof indexedDB === "object"; } catch (e) { return false; } } function validateIndexedDBOpenable() { return new Promise((resolve, reject) => { try { let preExist = true; const DB_CHECK_NAME = "validate-browser-context-for-indexeddb-analytics-module"; const request = self.indexedDB.open(DB_CHECK_NAME); request.onsuccess = () => { request.result.close(); if (!preExist) { self.indexedDB.deleteDatabase(DB_CHECK_NAME); } resolve(true); }; request.onupgradeneeded = () => { preExist = false; }; request.onerror = () => { var _a; reject(((_a = request.error) === null || _a === void 0 ? void 0 : _a.message) || ""); }; } catch (error2) { reject(error2); } }); } var ERROR_NAME = "FirebaseError"; var FirebaseError = class _FirebaseError extends Error { constructor(code, message, customData) { super(message); this.code = code; this.customData = customData; this.name = ERROR_NAME; Object.setPrototypeOf(this, _FirebaseError.prototype); if (Error.captureStackTrace) { Error.captureStackTrace(this, ErrorFactory.prototype.create); } } }; var ErrorFactory = class { constructor(service, serviceName, errors) { this.service = service; this.serviceName = serviceName; this.errors = errors; } create(code, ...data) { const customData = data[0] || {}; const fullCode = `${this.service}/${code}`; const template = this.errors[code]; const message = template ? replaceTemplate(template, customData) : "Error"; const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`; const error2 = new FirebaseError(fullCode, fullMessage, customData); return error2; } }; function replaceTemplate(template, data) { return template.replace(PATTERN, (_, key) => { const value = data[key]; return value != null ? String(value) : `<${key}?>`; }); } var PATTERN = /\{\$([^}]+)}/g; function jsonEval(str) { return JSON.parse(str); } function stringify(data) { return JSON.stringify(data); } var decode = function(token) { let header = {}, claims = {}, data = {}, signature = ""; try { const parts = token.split("."); header = jsonEval(base64Decode(parts[0]) || ""); claims = jsonEval(base64Decode(parts[1]) || ""); signature = parts[2]; data = claims["d"] || {}; delete claims["d"]; } catch (e) { } return { header, claims, data, signature }; }; var isValidFormat = function(token) { const decoded = decode(token), claims = decoded.claims; return !!claims && typeof claims === "object" && claims.hasOwnProperty("iat"); }; var isAdmin = function(token) { const claims = decode(token).claims; return typeof claims === "object" && claims["admin"] === true; }; function contains(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } function safeGet(obj, key) { if (Object.prototype.hasOwnProperty.call(obj, key)) { return obj[key]; } else { return void 0; } } function isEmpty(obj) { for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { return false; } } return true; } function map(obj, fn, contextObj) { const res = {}; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { res[key] = fn.call(contextObj, obj[key], key, obj); } } return res; } function deepEqual(a, b) { if (a === b) { return true; } const aKeys = Object.keys(a); const bKeys = Object.keys(b); for (const k of aKeys) { if (!bKeys.includes(k)) { return false; } const aProp = a[k]; const bProp = b[k]; if (isObject(aProp) && isObject(bProp)) { if (!deepEqual(aProp, bProp)) { return false; } } else if (aProp !== bProp) { return false; } } for (const k of bKeys) { if (!aKeys.includes(k)) { return false; } } return true; } function isObject(thing) { return thing !== null && typeof thing === "object"; } function querystring(querystringParams) { const params = []; for (const [key, value] of Object.entries(querystringParams)) { if (Array.isArray(value)) { value.forEach((arrayVal) => { params.push(encodeURIComponent(key) + "=" + encodeURIComponent(arrayVal)); }); } else { params.push(encodeURIComponent(key) + "=" + encodeURIComponent(value)); } } return params.length ? "&" + params.join("&") : ""; } function querystringDecode(querystring2) { const obj = {}; const tokens = querystring2.replace(/^\?/, "").split("&"); tokens.forEach((token) => { if (token) { const [key, value] = token.split("="); obj[decodeURIComponent(key)] = decodeURIComponent(value); } }); return obj; } function extractQuerystring(url) { const queryStart = url.indexOf("?"); if (!queryStart) { return ""; } const fragmentStart = url.indexOf("#", queryStart); return url.substring(queryStart, fragmentStart > 0 ? fragmentStart : void 0); } var Sha1 = class { constructor() { this.chain_ = []; this.buf_ = []; this.W_ = []; this.pad_ = []; this.inbuf_ = 0; this.total_ = 0; this.blockSize = 512 / 8; this.pad_[0] = 128; for (let i = 1; i < this.blockSize; ++i) { this.pad_[i] = 0; } this.reset(); } reset() { this.chain_[0] = 1732584193; this.chain_[1] = 4023233417; this.chain_[2] = 2562383102; this.chain_[3] = 271733878; this.chain_[4] = 3285377520; this.inbuf_ = 0; this.total_ = 0; } /** * Internal compress helper function. * @param buf Block to compress. * @param offset Offset of the block in the buffer. * @private */ compress_(buf, offset) { if (!offset) { offset = 0; } const W = this.W_; if (typeof buf === "string") { for (let i = 0; i < 16; i++) { W[i] = buf.charCodeAt(offset) << 24 | buf.charCodeAt(offset + 1) << 16 | buf.charCodeAt(offset + 2) << 8 | buf.charCodeAt(offset + 3); offset += 4; } } else { for (let i = 0; i < 16; i++) { W[i] = buf[offset] << 24 | buf[offset + 1] << 16 | buf[offset + 2] << 8 | buf[offset + 3]; offset += 4; } } for (let i = 16; i < 80; i++) { const t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; W[i] = (t << 1 | t >>> 31) & 4294967295; } let a = this.chain_[0]; let b = this.chain_[1]; let c = this.chain_[2]; let d = this.chain_[3]; let e = this.chain_[4]; let f, k; for (let i = 0; i < 80; i++) { if (i < 40) { if (i < 20) { f = d ^ b & (c ^ d); k = 1518500249; } else { f = b ^ c ^ d; k = 1859775393; } } else { if (i < 60) { f = b & c | d & (b | c); k = 2400959708; } else { f = b ^ c ^ d; k = 3395469782; } } const t = (a << 5 | a >>> 27) + f + e + k + W[i] & 4294967295; e = d; d = c; c = (b << 30 | b >>> 2) & 4294967295; b = a; a = t; } this.chain_[0] = this.chain_[0] + a & 4294967295; this.chain_[1] = this.chain_[1] + b & 4294967295; this.chain_[2] = this.chain_[2] + c & 4294967295; this.chain_[3] = this.chain_[3] + d & 4294967295; this.chain_[4] = this.chain_[4] + e & 4294967295; } update(bytes, length) { if (bytes == null) { return; } if (length === void 0) { length = bytes.length; } const lengthMinusBlock = length - this.blockSize; let n = 0; const buf = this.buf_; let inbuf = this.inbuf_; while (n < length) { if (inbuf === 0) { while (n <= lengthMinusBlock) { this.compress_(bytes, n); n += this.blockSize; } } if (typeof bytes === "string") { while (n < length) { buf[inbuf] = bytes.charCodeAt(n); ++inbuf; ++n; if (inbuf === this.blockSize) { this.compress_(buf); inbuf = 0; break; } } } else { while (n < length) { buf[inbuf] = bytes[n]; ++inbuf; ++n; if (inbuf === this.blockSize) { this.compress_(buf); inbuf = 0; break; } } } } this.inbuf_ = inbuf; this.total_ += length; } /** @override */ digest() { const digest = []; let totalBits = this.total_ * 8; if (this.inbuf_ < 56) { this.update(this.pad_, 56 - this.inbuf_); } else { this.update(this.pad_, this.blockSize - (this.inbuf_ - 56)); } for (let i = this.blockSize - 1; i >= 56; i--) { this.buf_[i] = totalBits & 255; totalBits /= 256; } this.compress_(this.buf_); let n = 0; for (let i = 0; i < 5; i++) { for (let j = 24; j >= 0; j -= 8) { digest[n] = this.chain_[i] >> j & 255; ++n; } } return digest; } }; function createSubscribe(executor, onNoObservers) { const proxy = new ObserverProxy(executor, onNoObservers); return proxy.subscribe.bind(proxy); } var ObserverProxy = class { /** * @param executor Function which can make calls to a single Observer * as a proxy. * @param onNoObservers Callback when count of Observers goes to zero. */ constructor(executor, onNoObservers) { this.observers = []; this.unsubscribes = []; this.observerCount = 0; this.task = Promise.resolve(); this.finalized = false; this.onNoObservers = onNoObservers; this.task.then(() => { executor(this); }).catch((e) => { this.error(e); }); } next(value) { this.forEachObserver((observer) => { observer.next(value); }); } error(error2) { this.forEachObserver((observer) => { observer.error(error2); }); this.close(error2); } complete() { this.forEachObserver((observer) => { observer.complete(); }); this.close(); } /** * Subscribe function that can be used to add an Observer to the fan-out list. * * - We require that no event is sent to a subscriber sychronously to their * call to subscribe(). */ subscribe(nextOrObserver, error2, complete) { let observer; if (nextOrObserver === void 0 && error2 === void 0 && complete === void 0) { throw new Error("Missing Observer."); } if (implementsAnyMethods(nextOrObserver, [ "next", "error", "complete" ])) { observer = nextOrObserver; } else { observer = { next: nextOrObserver, error: error2, complete }; } if (observer.next === void 0) { observer.next = noop; } if (observer.error === void 0) { observer.error = noop; } if (observer.complete === void 0) { observer.complete = noop; } const unsub = this.unsubscribeOne.bind(this, this.observers.length); if (this.finalized) { this.task.then(() => { try { if (this.finalError) { observer.error(this.finalError); } else { observer.complete(); } } catch (e) { } return; }); } this.observers.push(observer); return unsub; } // Unsubscribe is synchronous - we guarantee that no events are sent to // any unsubscribed Observer. unsubscribeOne(i) { if (this.observers === void 0 || this.observers[i] === void 0) { return; } delete this.observers[i]; this.observerCount -= 1; if (this.observerCount === 0 && this.onNoObservers !== void 0) { this.onNoObservers(this); } } forEachObserver(fn) { if (this.finalized) { return; } for (let i = 0; i < this.observers.length; i++) { this.sendOne(i, fn); } } // Call the Observer via one of it's callback function. We are careful to // confirm that the observe has not been unsubscribed since this asynchronous // function had been queued. sendOne(i, fn) { this.task.then(() => { if (this.observers !== void 0 && this.observers[i] !== void 0) { try { fn(this.observers[i]); } catch (e) { if (typeof console !== "undefined" && console.error) { console.error(e); } } } }); } close(err) { if (this.finalized) { return; } this.finalized = true; if (err !== void 0) { this.finalError = err; } this.task.then(() => { this.observers = void 0; this.onNoObservers = void 0; }); } }; function implementsAnyMethods(obj, methods) { if (typeof obj !== "object" || obj === null) { return false; } for (const method of methods) { if (method in obj && typeof obj[method] === "function") { return true; } } return false; } function noop() { } function errorPrefix(fnName, argName) { return `${fnName} failed: ${argName} argument `; } var stringToByteArray = function(str) { const out = []; let p = 0; for (let i = 0; i < str.length; i++) { let c = str.charCodeAt(i); if (c >= 55296 && c <= 56319) { const high = c - 55296; i++; assert(i < str.length, "Surrogate pair missing trail surrogate."); const low = str.charCodeAt(i) - 56320; c = 65536 + (high << 10) + low; } if (c < 128) { out[p++] = c; } else if (c < 2048) { out[p++] = c >> 6 | 192; out[p++] = c & 63 | 128; } else if (c < 65536) { out[p++] = c >> 12 | 224; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } else { out[p++] = c >> 18 | 240; out[p++] = c >> 12 & 63 | 128; out[p++] = c >> 6 & 63 | 128; out[p++] = c & 63 | 128; } } return out; }; var stringLength = function(str) { let p = 0; for (let i = 0; i < str.length; i++) { const c = str.charCodeAt(i); if (c < 128) { p++; } else if (c < 2048) { p += 2; } else if (c >= 55296 && c <= 56319) { p += 4; i++; } else { p += 3; } } return p; }; var MAX_VALUE_MILLIS = 4 * 60 * 60 * 1e3; function getModularInstance(service) { if (service && service._delegate) { return service._delegate; } else { return service; } } // node_modules/.pnpm/@firebase+component@0.6.4/node_modules/@firebase/component/dist/esm/index.esm2017.js var Component = class { /** * * @param name The public service name, e.g. app, auth, firestore, database * @param instanceFactory Service factory responsible for creating the public interface * @param type whether the service provided by the component is public or private */ constructor(name4, instanceFactory, type) { this.name = name4; this.instanceFactory = instanceFactory; this.type = type; this.multipleInstances = false; this.serviceProps = {}; this.instantiationMode = "LAZY"; this.onInstanceCreated = null; } setInstantiationMode(mode) { this.instantiationMode = mode; return this; } setMultipleInstances(multipleInstances) { this.multipleInstances = multipleInstances; return this; } setServiceProps(props) { this.serviceProps = props; return this; } setInstanceCreatedCallback(callback) { this.onInstanceCreated = callback; return this; } }; var DEFAULT_ENTRY_NAME = "[DEFAULT]"; var Provider = class { constructor(name4, container) { this.name = name4; this.container = container; this.component = null; this.instances = /* @__PURE__ */ new Map(); this.instancesDeferred = /* @__PURE__ */ new Map(); this.instancesOptions = /* @__PURE__ */ new Map(); this.onInitCallbacks = /* @__PURE__ */ new Map(); } /** * @param identifier A provider can provide mulitple instances of a service * if this.component.multipleInstances is true. */ get(identifier) { const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier); if (!this.instancesDeferred.has(normalizedIdentifier)) { const deferred = new Deferred(); this.instancesDeferred.set(normalizedIdentifier, deferred); if (this.isInitialized(normalizedIdentifier) || this.shouldAutoInitialize()) { try { const instance = this.getOrInitializeService({ instanceIdentifier: normalizedIdentifier }); if (instance) { deferred.resolve(instance); } } catch (e) { } } } return this.instancesDeferred.get(normalizedIdentifier).promise; } getImmediate(options) { var _a; const normalizedIdentifier = this.normalizeInstanceIdentifier(options === null || options === void 0 ? void 0 : options.identifier); const optional = (_a = options === null || options === void 0 ? void 0 : options.optional) !== null && _a !== void 0 ? _a : false; if (this.isInitialized(normalizedIdentifier) || this.shouldAutoInitialize()) { try { return this.getOrInitializeService({ instanceIdentifier: normalizedIdentifier }); } catch (e) { if (optional) { return null; } else { throw e; } } } else { if (optional) { return null; } else { throw Error(`Service ${this.name} is not available`); } } } getComponent() { return this.component; } setComponent(component) { if (component.name !== this.name) { throw Error(`Mismatching Component ${component.name} for Provider ${this.name}.`); } if (this.component) { throw Error(`Component for ${this.name} has already been provided`); } this.component = component; if (!this.shouldAutoInitialize()) { return; } if (isComponentEager(component)) { try { this.getOrInitializeService({ instanceIdentifier: DEFAULT_ENTRY_NAME }); } catch (e) { } } for (const [instanceIdentifier, instanceDeferred] of this.instancesDeferred.entries()) { const normalizedIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier); try { const instance = this.getOrInitializeService({ instanceIdentifier: normalizedIdentifier }); instanceDeferred.resolve(instance); } catch (e) { } } } clearInstance(identifier = DEFAULT_ENTRY_NAME) { this.instancesDeferred.delete(identifier); this.instancesOptions.delete(identifier); this.instances.delete(identifier); } // app.delete() will call this method on every provider to delete the services // TODO: should we mark the provider as deleted? async delete() { const services = Array.from(this.instances.values()); await Promise.all([ ...services.filter((service) => "INTERNAL" in service).map((service) => service.INTERNAL.delete()), ...services.filter((service) => "_delete" in service).map((service) => service._delete()) ]); } isComponentSet() { return this.component != null; } isInitialized(identifier = DEFAULT_ENTRY_NAME) { return this.instances.has(identifier); } getOptions(identifier = DEFAULT_ENTRY_NAME) { return this.instancesOptions.get(identifier) || {}; } initialize(opts = {}) { const { options = {} } = opts; const normalizedIdentifier = this.normalizeInstanceIdentifier(opts.instanceIdentifier); if (this.isInitialized(normalizedIdentifier)) { throw Error(`${this.name}(${normalizedIdentifier}) has already been initialized`); } if (!this.isComponentSet()) { throw Error(`Component ${this.name} has not been registered yet`); } const instance = this.getOrInitializeService({ instanceIdentifier: normalizedIdentifier, options }); for (const [instanceIdentifier, instanceDeferred] of this.instancesDeferred.entries()) { const normalizedDeferredIdentifier = this.normalizeInstanceIdentifier(instanceIdentifier); if (normalizedIdentifier === normalizedDeferredIdentifier) { instanceDeferred.resolve(instance); } } return instance; } /** * * @param callback - a function that will be invoked after the provider has been initialized by calling provider.initialize(). * The function is invoked SYNCHRONOUSLY, so it should not execute any longrunning tasks in order to not block the program. * * @param identifier An optional instance identifier * @returns a function to unregister the callback */ onInit(callback, identifier) { var _a; const normalizedIdentifier = this.normalizeInstanceIdentifier(identifier); const existingCallbacks = (_a = this.onInitCallbacks.get(normalizedIdentifier)) !== null && _a !== void 0 ? _a : /* @__PURE__ */ new Set(); existingCallbacks.add(callback); this.onInitCallbacks.set(normalizedIdentifier, existingCallbacks); const existingInstance = this.instances.get(normalizedIdentifier); if (existingInstance) { callback(existingInstance, normalizedIdentifier); } return () => { existingCallbacks.delete(callback); }; } /** * Invoke onInit callbacks synchronously * @param instance the service instance` */ invokeOnInitCallbacks(instance, identifier) { const callbacks = this.onInitCallbacks.get(identifier); if (!callbacks) { return; } for (const callback of callbacks) { try { callback(instance, identifier); } catch (_a) { } } } getOrInitializeService({ instanceIdentifier, options = {} }) { let instance = this.instances.get(instanceIdentifier); if (!instance && this.component) { instance = this.component.instanceFactory(this.container, { instanceIdentifier: normalizeIdentifierForFactory(instanceIdentifier), options }); this.instances.set(instanceIdentifier, instance); this.instancesOptions.set(instanceIdentifier, options); this.invokeOnInitCallbacks(instance, instanceIdentifier); if (this.component.onInstanceCreated) { try { this.component.onInstanceCreated(this.container, instanceIdentifier, instance); } catch (_a) { } } } return instance || null; } normalizeInstanceIdentifier(identifier = DEFAULT_ENTRY_NAME) { if (this.component) { return this.component.multipleInstances ? identifier : DEFAULT_ENTRY_NAME; } else { return identifier; } } shouldAutoInitialize() { return !!this.component && this.component.instantiationMode !== "EXPLICIT"; } }; function normalizeIdentifierForFactory(identifier) { return identifier === DEFAULT_ENTRY_NAME ? void 0 : identifier; } function isComponentEager(component) { return component.instantiationMode === "EAGER"; } var ComponentContainer = class { constructor(name4) { this.name = name4; this.providers = /* @__PURE__ */ new Map(); } /** * * @param component Component being added * @param overwrite When a component with the same name has already been registered, * if overwrite is true: overwrite the existing component with the new component and create a new * provider with the new component. It can be useful in tests where you want to use different mocks * for different tests. * if overwrite is false: throw an exception */ addComponent(component) { const provider = this.getProvider(component.name); if (provider.isComponentSet()) { throw new Error(`Component ${component.name} has already been registered with ${this.name}`); } provider.setComponent(component); } addOrOverwriteComponent(component) { const provider = this.getProvider(component.name); if (provider.isComponentSet()) { this.providers.delete(component.name); } this.addComponent(component); } /** * getProvider provides a type safe interface where it can only be called with a field name * present in NameServiceMapping interface. * * Firebase SDKs providing services should extend NameServiceMapping interface to register * themselves. */ getProvider(name4) { if (this.providers.has(name4)) { return this.providers.get(name4); } const provider = new Provider(name4, this); this.providers.set(name4, provider); return provider; } getProviders() { return Array.from(this.providers.values()); } }; // node_modules/.pnpm/@firebase+logger@0.4.0/node_modules/@firebase/logger/dist/esm/index.esm2017.js var instances = []; var LogLevel; (function(LogLevel2) { LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG"; LogLevel2[LogLevel2["VERBOSE"] = 1] = "VERBOSE"; LogLevel2[LogLevel2["INFO"] = 2] = "INFO"; LogLevel2[LogLevel2["WARN"] = 3] = "WARN"; LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR"; LogLevel2[LogLevel2["SILENT"] = 5] = "SILENT"; })(LogLevel || (LogLevel = {})); var levelStringToEnum = { "debug": LogLevel.DEBUG, "verbose": LogLevel.VERBOSE, "info": LogLevel.INFO, "warn": LogLevel.WARN, "error": LogLevel.ERROR, "silent": LogLevel.SILENT }; var defaultLogLevel = LogLevel.INFO; var ConsoleMethod = { [LogLevel.DEBUG]: "log", [LogLevel.VERBOSE]: "log", [LogLevel.INFO]: "info", [LogLevel.WARN]: "warn", [LogLevel.ERROR]: "error" }; var defaultLogHandler = (instance, logType, ...args) => { if (logType < instance.logLevel) { return; } const now = (/* @__PURE__ */ new Date()).toISOString(); const method = ConsoleMethod[logType]; if (method) { console[method](`[${now}] ${instance.name}:`, ...args); } else { throw new Error(`Attempted to log a message with an invalid logType (value: ${logType})`); } }; var Logger = class { /** * Gives you an instance of a Logger to capture messages according to * Firebase's logging scheme. * * @param name The name that the logs will be associated with */ constructor(name4) { this.name = name4; this._logLevel = defaultLogLevel; this._logHandler = defaultLogHandler; this._userLogHandler = null; instances.push(this); } get logLevel() { return this._logLevel; } set logLevel(val) { if (!(val in LogLevel)) { throw new TypeError(`Invalid value "${val}" assigned to \`logLevel\``); } this._logLevel = val; } // Workaround for setter/getter having to be the same type. setLogLevel(val) { this._logLevel = typeof val === "string" ? levelStringToEnum[val] : val; } get logHandler() { return this._logHandler; } set logHandler(val) { if (typeof val !== "function") { throw new TypeError("Value assigned to `logHandler` must be a function"); } this._logHandler = val; } get userLogHandler() { return this._userLogHandler; } set userLogHandler(val) { this._userLogHandler = val; } /** * The functions below are all based on the `console` interface */ debug(...args) { this._userLogHandler && this._userLogHandler(this, LogLevel.DEBUG, ...args); this._logHandler(this, LogLevel.DEBUG, ...args); } log(...args) { this._userLogHandler && this._userLogHandler(this, LogLevel.VERBOSE, ...args); this._logHandler(this, LogLevel.VERBOSE, ...args); } info(...args) { this._userLogHandler && this._userLogHandler(this, LogLevel.INFO, ...args); this._logHandler(this, LogLevel.INFO, ...args); } warn(...args) { this._userLogHandler && this._userLogHandler(this, LogLevel.WARN, ...args); this._logHandler(this, LogLevel.WARN, ...args); } error(...args) { this._userLogHandler && this._userLogHandler(this, LogLevel.ERROR, ...args); this._logHandler(this, LogLevel.ERROR, ...args); } }; // node_modules/.pnpm/idb@7.1.1/node_modules/idb/build/wrap-idb-value.js var instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c); var idbProxyableTypes; var cursorAdvanceMethods; function getIdbProxyableTypes() { return idbProxyableTypes || (idbProxyableTypes = [ IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction ]); } function getCursorAdvanceMethods() { return cursorAdvanceMethods || (cursorAdvanceMethods = [ IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey ]); } var cursorRequestMap = /* @__PURE__ */ new WeakMap(); var transactionDoneMap = /* @__PURE__ */ new WeakMap(); var transactionStoreNamesMap = /* @__PURE__ */ new WeakMap(); var transformCache = /* @__PURE__ */ new WeakMap(); var reverseTransformCache = /* @__PURE__ */ new WeakMap(); function promisifyRequest(request) { const promise = new Promise((resolve, reject) => { const unlisten = () => { request.removeEventListener("success", success); request.removeEventListener("error", error2); }; const success = () => { resolve(wrap(request.result)); unlisten(); }; const error2 = () => { reject(request.error); unlisten(); }; request.addEventListener("success", success); request.addEventListener("error", error2); }); promise.then((value) => { if (value instanceof IDBCursor) { cursorRequestMap.set(value, request); } }).catch(() => { }); reverseTransformCache.set(promise, request); return promise; } function cacheDonePromiseForTransaction(tx) { if (transactionDoneMap.has(tx)) return; const done = new Promise((resolve, reject) => { const unlisten = () => { tx.removeEventListener("complete", complete); tx.removeEventListener("error", error2); tx.removeEventListener("abort", error2); }; const complete = () => { resolve(); unlisten(); }; const error2 = () => { reject(tx.error || new DOMException("AbortError", "AbortError")); unlisten(); }; tx.addEventListener("complete", complete); tx.addEventListener("error", error2); tx.addEventListener("abort", error2); }); transactionDoneMap.set(tx, done); } var idbProxyTraps = { get(target, prop, receiver) { if (target instanceof IDBTransaction) { if (prop === "done") return transactionDoneMap.get(target); if (prop === "objectStoreNames") { return target.objectStoreNames || transactionStoreNamesMap.get(target); } if (prop === "store") { return receiver.objectStoreNames[1] ? void 0 : receiver.objectStore(receiver.objectStoreNames[0]); } } return wrap(target[prop]); }, set(target, prop, value) { target[prop] = value; return true; }, has(target, prop) { if (target instanceof IDBTransaction && (prop === "done" || prop === "store")) { return true; } return prop in target; } }; function replaceTraps(callback) { idbProxyTraps = callback(idbProxyTraps); } function wrapFunction(func) { if (func === IDBDatabase.prototype.transaction && !("objectStoreNames" in IDBTransaction.prototype)) { return function(storeNames, ...args) { const tx = func.call(unwrap(this), storeNames, ...args); transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]); return wrap(tx); }; } if (getCursorAdvanceMethods().includes(func)) { return function(...args) { func.apply(unwrap(this), args); return wrap(cursorRequestMap.get(this)); }; } return function(...args) { return wrap(func.apply(unwrap(this), args)); }; } function transformCachableValue(value) { if (typeof value === "function") return wrapFunction(value); if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value); if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps); return value; } function wrap(value) { if (value instanceof IDBRequest) return promisifyRequest(value); if (transformCache.has(value)) return transformCache.get(value); const newValue = transformCachableValue(value); if (newValue !== value) { transformCache.set(value, newValue); reverseTransformCache.set(newValue, value); } return newValue; } var unwrap = (value) => reverseTransformCache.get(value); // node_modules/.pnpm/idb@7.1.1/node_modules/idb/build/index.js function openDB(name4, version4, { blocked, upgrade, blocking, terminated } = {}) { const request = indexedDB.open(name4, version4); const openPromise = wrap(request); if (upgrade) { request.addEventListener("upgradeneeded", (event) => { upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event); }); } if (blocked) { request.addEventListener("blocked", (event) => blocked( // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405 event.oldVersion, event.newVersion, event )); } openPromise.then((db) => { if (terminated) db.addEventListener("close", () => terminated()); if (blocking) { db.addEventListener("versionchange", (event) => blocking(event.oldVersion, event.newVersion, event)); } }).catch(() => { }); return openPromise; } var readMethods = ["get", "getKey", "getAll", "getAllKeys", "count"]; var writeMethods = ["put", "add", "delete", "clear"]; var cachedMethods = /* @__PURE__ */ new Map(); function getMethod(target, prop) { if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === "string")) { return; } if (cachedMethods.get(prop)) return cachedMethods.get(prop); const targetFuncName = prop.replace(/FromIndex$/, ""); const useIndex = prop !== targetFuncName; const isWrite = writeMethods.includes(targetFuncName); if ( // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge. !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName)) ) { return; } const method = async function(storeName, ...args) { const tx = this.transaction(storeName, isWrite ? "readwrite" : "readonly"); let target2 = tx.store; if (useIndex) target2 = target2.index(args.shift()); return (await Promise.all([ target2[targetFuncName](...args), isWrite && tx.done ]))[0]; }; cachedMethods.set(prop, method); return method; } replaceTraps((oldTraps) => ({ ...oldTraps, get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver), has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop) })); // node_modules/.pnpm/@firebase+app@0.9.15/node_modules/@firebase/app/dist/esm/index.esm2017.js var PlatformLoggerServiceImpl = class { constructor(container) { this.container = container; } // In initial implementation, this will be called by installations on // auth token refresh, and installations will send this string. getPlatformInfoString() { const providers = this.container.getProviders(); return providers.map((provider) => { if (isVersionServiceProvider(provider)) { const service = provider.getImmediate(); return `${service.library}/${service.version}`; } else { return null; } }).filter((logString) => logString).join(" "); } }; function isVersionServiceProvider(provider) { const component = provider.getComponent(); return (component === null || component === void 0 ? void 0 : component.type) === "VERSION"; } var name$o = "@firebase/app"; var version$1 = "0.9.15"; var logger = new Logger("@firebase/app"); var name$n = "@firebase/app-compat"; var name$m = "@firebase/analytics-compat"; var name$l = "@firebase/analytics"; var name$k = "@firebase/app-check-compat"; var name$j = "@firebase/app-check"; var name$i = "@firebase/auth"; var name$h = "@firebase/auth-compat"; var name$g = "@firebase/database"; var name$f = "@firebase/database-compat"; var name$e = "@firebase/functions"; var name$d = "@firebase/functions-compat"; var name$c = "@firebase/installations"; var name$b = "@firebase/installations-compat"; var name$a = "@firebase/messaging"; var name$9 = "@firebase/messaging-compat"; var name$8 = "@firebase/performance"; var name$7 = "@firebase/performance-compat"; var name$6 = "@firebase/remote-config"; var name$5 = "@firebase/remote-config-compat"; var name$4 = "@firebase/storage"; var name$3 = "@firebase/storage-compat"; var name$2 = "@firebase/firestore"; var name$1 = "@firebase/firestore-compat"; var name = "firebase"; var version = "10.1.0"; var DEFAULT_ENTRY_NAME2 = "[DEFAULT]"; var PLATFORM_LOG_STRING = { [name$o]: "fire-core", [name$n]: "fire-core-compat", [name$l]: "fire-analytics", [name$m]: "fire-analytics-compat", [name$j]: "fire-app-check", [name$k]: "fire-app-check-compat", [name$i]: "fire-auth", [name$h]: "fire-auth-compat", [name$g]: "fire-rtdb", [name$f]: "fire-rtdb-compat", [name$e]: "fire-fn", [name$d]: "fire-fn-compat", [name$c]: "fire-iid", [name$b]: "fire-iid-compat", [name$a]: "fire-fcm", [name$9]: "fire-fcm-compat", [name$8]: "fire-perf", [name$7]: "fire-perf-compat", [name$6]: "fire-rc", [name$5]: "fire-rc-compat", [name$4]: "fire-gcs", [name$3]: "fire-gcs-compat", [name$2]: "fire-fst", [name$1]: "fire-fst-compat", "fire-js": "fire-js", [name]: "fire-js-all" }; var _apps = /* @__PURE__ */ new Map(); var _components = /* @__PURE__ */ new Map(); function _addComponent(app, component) { try { app.container.addComponent(component); } catch (e) { logger.debug(`Component ${component.name} failed to register with FirebaseApp ${app.name}`, e); } } function _registerComponent(component) { const componentName = component.name; if (_components.has(componentName)) { logger.debug(`There were multiple attempts to register component ${componentName}.`); return false; } _components.set(componentName, component); for (const app of _apps.values()) { _addComponent(app, component); } return true; } function _getProvider(app, name4) { const heartbeatController = app.container.getProvider("heartbeat").getImmediate({ optional: true }); if (heartbeatController) { void heartbeatController.triggerHeartbeat(); } return app.container.getProvider(name4); } var ERRORS = { [ "no-app" /* AppError.NO_APP */ ]: "No Firebase App '{$appName}' has been created - call initializeApp() first", [ "bad-app-name" /* AppError.BAD_APP_NAME */ ]: "Illegal App name: '{$appName}", [ "duplicate-app" /* AppError.DUPLICATE_APP */ ]: "Firebase App named '{$appName}' already exists with different options or config", [ "app-deleted" /* AppError.APP_DELETED */ ]: "Firebase App named '{$appName}' already deleted", [ "no-options" /* AppError.NO_OPTIONS */ ]: "Need to provide options, when not being deployed to hosting via source.", [ "invalid-app-argument" /* AppError.INVALID_APP_ARGUMENT */ ]: "firebase.{$appName}() takes either no argument or a Firebase App instance.", [ "invalid-log-argument" /* AppError.INVALID_LOG_ARGUMENT */ ]: "First argument to `onLog` must be null or a function.", [ "idb-open" /* AppError.IDB_OPEN */ ]: "Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.", [ "idb-get" /* AppError.IDB_GET */ ]: "Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.", [ "idb-set" /* AppError.IDB_WRITE */ ]: "Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.", [ "idb-delete" /* AppError.IDB_DELETE */ ]: "Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}." }; var ERROR_FACTORY = new ErrorFactory("app", "Firebase", ERRORS); var FirebaseAppImpl = class { constructor(options, config, container) { this._isDeleted = false; this._options = Object.assign({}, options); this._config = Object.assign({}, config); this._name = config.name; this._automaticDataCollectionEnabled = config.automaticDataCollectionEnabled; this._container = container; this.container.addComponent(new Component( "app", () => this, "PUBLIC" /* ComponentType.PUBLIC */ )); } get automaticDataCollectionEnabled() { this.checkDestroyed(); return this._automaticDataCollectionEnabled; } set automaticDataCollectionEnabled(val) { this.checkDestroyed(); this._automaticDataCollectionEnabled = val; } get name() { this.checkDestroyed(); return this._name; } get options() { this.checkDestroyed(); return this._options; } get config() { this.checkDestroyed(); return this._config; } get container() { return this._container; } get isDeleted() { return this._isDeleted; } set isDeleted(val) { this._isDeleted = val; } /** * This function will throw an Error if the App has already been deleted - * use before performing API actions on the App. */ checkDestroyed() { if (this.isDeleted) { throw ERROR_FACTORY.create("app-deleted", { appName: this._name }); } } }; var SDK_VERSION = version; function initializeApp(_options, rawConfig = {}) { let options = _options; if (typeof rawConfig !== "object") { const name5 = rawConfig; rawConfig = { name: name5 }; } const config = Object.assign({ name: DEFAULT_ENTRY_NAME2, automaticDataCollectionEnabled: false }, rawConfig); const name4 = config.name; if (typeof name4 !== "string" || !name4) { throw ERROR_FACTORY.create("bad-app-name", { appName: String(name4) }); } options || (options = getDefaultAppConfig()); if (!options) { throw ERROR_FACTORY.create( "no-options" /* AppError.NO_OPTIONS */ ); } const existingApp = _apps.get(name4); if (existingApp) { if (deepEqual(options, existingApp.options) && deepEqual(config, existingApp.config)) { return existingApp; } else { throw ERROR_FACTORY.create("duplicate-app", { appName: name4 }); } } const container = new ComponentContainer(name4); for (const component of _components.values()) { container.addComponent(component); } const newApp = new FirebaseAppImpl(options, config, container); _apps.set(name4, newApp); return newApp; } function getApp(name4 = DEFAULT_ENTRY_NAME2) { const app = _apps.get(name4); if (!app && name4 === DEFAULT_ENTRY_NAME2 && getDefaultAppConfig()) { return initializeApp(); } if (!app) { throw ERROR_FACTORY.create("no-app", { appName: name4 }); } return app; } function registerVersion(libraryKeyOrName, version4, variant) { var _a; let library = (_a = PLATFORM_LOG_STRING[libraryKeyOrName]) !== null && _a !== void 0 ? _a : libraryKeyOrName; if (variant) { library += `-${variant}`; } const libraryMismatch = library.match(/\s|\//); const versionMismatch = version4.match(/\s|\//); if (libraryMismatch || versionMismatch) { const warning = [ `Unable to register library "${library}" with version "${version4}":` ]; if (libraryMismatch) { warning.push(`library name "${library}" contains illegal characters (whitespace or "/")`); } if (libraryMismatch && versionMismatch) { warning.push("and"); } if (versionMismatch) { warning.push(`version name "${version4}" contains illegal characters (whitespace or "/")`); } logger.warn(warning.join(" ")); return; } _registerComponent(new Component( `${library}-version`, () => ({ library, version: version4 }), "VERSION" /* ComponentType.VERSION */ )); } var DB_NAME = "firebase-heartbeat-database"; var DB_VERSION = 1; var STORE_NAME = "firebase-heartbeat-store"; var dbPromise = null; function getDbPromise() { if (!dbPromise) { dbPromise = openDB(DB_NAME, DB_VERSION, { upgrade: (db, oldVersion) => { switch (oldVersion) { case 0: db.createObjectStore(STORE_NAME); } } }).catch((e) => { throw ERROR_FACTORY.create("idb-open", { originalErrorMessage: e.message }); }); } return dbPromise; } async function readHeartbeatsFromIndexedDB(app) { try { const db = await getDbPromise(); const result = await db.transaction(STORE_NAME).objectStore(STORE_NAME).get(computeKey(app)); return result; } catch (e) { if (e instanceof FirebaseError) { logger.warn(e.message); } else { const idbGetError = ERROR_FACTORY.create("idb-get", { originalErrorMessage: e === null || e === void 0 ? void 0 : e.message }); logger.warn(idbGetError.message); } } } async function writeHeartbeatsToIndexedDB(app, heartbeatObject) { try { const db = await getDbPromise(); const tx = db.transaction(STORE_NAME, "readwrite"); const objectStore = tx.objectStore(STORE_NAME); await objectStore.put(heartbeatObject, computeKey(app)); await tx.done; } catch (e) { if (e instanceof FirebaseError) { logger.warn(e.message); } else { const idbGetError = ERROR_FACTORY.create("idb-set", { originalErrorMessage: e === null || e === void 0 ? void 0 : e.message }); logger.warn(idbGetError.message); } } } function computeKey(app) { return `${app.name}!${app.options.appId}`; } var MAX_HEADER_BYTES = 1024; var STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1e3; var HeartbeatServiceImpl = class { constructor(container) { this.container = container; this._heartbeatsCache = null; const app = this.container.getProvider("app").getImmediate(); this._storage = new HeartbeatStorageImpl(app); this._heartbeatsCachePromise = this._storage.read().then((result) => { this._heartbeatsCache = result; return result; }); } /** * Called to report a heartbeat. The function will generate * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it * to IndexedDB. * Note that we only store one heartbeat per day. So if a heartbeat for today is * already logged, subsequent calls to this function in the same day will be ignored. */ async triggerHeartbeat() { const platformLogger = this.container.getProvider("platform-logger").getImmediate(); const agent = platformLogger.getPlatformInfoString(); const date = getUTCDateString(); if (this._heartbeatsCache === null) { this._heartbeatsCache = await this._heartbeatsCachePromise; } if (this._heartbeatsCache.lastSentHeartbeatDate === date || this._heartbeatsCache.heartbeats.some((singleDateHeartbeat) => singleDateHeartbeat.date === date)) { return; } else { this._heartbeatsCache.heartbeats.push({ date, agent }); } this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter((singleDateHeartbeat) => { const hbTimestamp = new Date(singleDateHeartbeat.date).valueOf(); const now = Date.now(); return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS; }); return this._storage.overwrite(this._heartbeatsCache); } /** * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly. * It also clears all heartbeats from memory as well as in IndexedDB. * * NOTE: Consuming product SDKs should not send the header if this method * returns an empty string. */ async getHeartbeatsHeader() { if (this._heartbeatsCache === null) { await this._heartbeatsCachePromise; } if (this._heartbeatsCache === null || this._heartbeatsCache.heartbeats.length === 0) { return ""; } const date = getUTCDateString(); const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats); const headerString = base64urlEncodeWithoutPadding(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend })); this._heartbeatsCache.lastSentHeartbeatDate = date; if (unsentEntries.length > 0) { this._heartbeatsCache.heartbeats = unsentEntries; await this._storage.overwrite(this._heartbeatsCache); } else { this._heartbeatsCache.heartbeats = []; void this._storage.overwrite(this._heartbeatsCache); } return headerString; } }; function getUTCDateString() { const today = /* @__PURE__ */ new Date(); return today.toISOString().substring(0, 10); } function extractHeartbeatsForHeader(heartbeatsCache, maxSize = MAX_HEADER_BYTES) { const heartbeatsToSend = []; let unsentEntries = heartbeatsCache.slice(); for (const singleDateHeartbeat of heartbeatsCache) { const heartbeatEntry = heartbeatsToSend.find((hb) => hb.agent === singleDateHeartbeat.agent); if (!heartbeatEntry) { heartbeatsToSend.push({ agent: singleDateHeartbeat.agent, dates: [singleDateHeartbeat.date] }); if (countBytes(heartbeatsToSend) > maxSize) { heartbeatsToSend.pop(); break; } } else { heartbeatEntry.dates.push(singleDateHeartbeat.date); if (countBytes(heartbeatsToSend) > maxSize) { heartbeatEntry.dates.pop(); break; } } unsentEntries = unsentEntries.slice(1); } return { heartbeatsToSend, unsentEntries }; } var HeartbeatStorageImpl = class { constructor(app) { this.app = app; this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck(); } async runIndexedDBEnvironmentCheck() { if (!isIndexedDBAvailable()) { return false; } else { return validateIndexedDBOpenable().then(() => true).catch(() => false); } } /** * Read all heartbeats. */ async read() { const canUseIndexedDB = await this._canUseIndexedDBPromise; if (!canUseIndexedDB) { return { heartbeats: [] }; } else { const idbHeartbeatObject = await readHeartbeatsFromIndexedDB(this.app); return idbHeartbeatObject || { heartbeats: [] }; } } // overwrite the storage with the provided heartbeats async overwrite(heartbeatsObject) { var _a; const canUseIndexedDB = await this._canUseIndexedDBPromise; if (!canUseIndexedDB) { return; } else { const existingHeartbeatsObject = await this.read(); return writeHeartbeatsToIndexedDB(this.app, { lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate, heartbeats: heartbeatsObject.heartbeats }); } } // add heartbeats async add(heartbeatsObject) { var _a; const canUseIndexedDB = await this._canUseIndexedDBPromise; if (!canUseIndexedDB) { return; } else { const existingHeartbeatsObject = await this.read(); return writeHeartbeatsToIndexedDB(this.app, { lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate, heartbeats: [ ...existingHeartbeatsObject.heartbeats, ...heartbeatsObject.heartbeats ] }); } } }; function countBytes(heartbeatsCache) { return base64urlEncodeWithoutPadding( // heartbeatsCache wrapper properties JSON.stringify({ version: 2, heartbeats: heartbeatsCache }) ).length; } function registerCoreComponents(variant) { _registerComponent(new Component( "platform-logger", (container) => new PlatformLoggerServiceImpl(container), "PRIVATE" /* ComponentType.PRIVATE */ )); _registerComponent(new Component( "heartbeat", (container) => new HeartbeatServiceImpl(container), "PRIVATE" /* ComponentType.PRIVATE */ )); registerVersion(name$o, version$1, variant); registerVersion(name$o, version$1, "esm2017"); registerVersion("fire-js", ""); } registerCoreComponents(""); // node_modules/.pnpm/@firebase+database@1.0.1/node_modules/@firebase/database/dist/index.esm2017.js var name2 = "@firebase/database"; var version2 = "1.0.1"; var SDK_VERSION2 = ""; function setSDKVersion(version4) { SDK_VERSION2 = version4; } var DOMStorageWrapper = class { /** * @param domStorage_ - The underlying storage object (e.g. localStorage or sessionStorage) */ constructor(domStorage_) { this.domStorage_ = domStorage_; this.prefix_ = "firebase:"; } /** * @param key - The key to save the value under * @param value - The value being stored, or null to remove the key. */ set(key, value) { if (value == null) { this.domStorage_.removeItem(this.prefixedName_(key)); } else { this.domStorage_.setItem(this.prefixedName_(key), stringify(value)); } } /** * @returns The value that was stored under this key, or null */ get(key) { const storedVal = this.domStorage_.getItem(this.prefixedName_(key)); if (storedVal == null) { return null; } else { return jsonEval(storedVal); } } remove(key) { this.domStorage_.removeItem(this.prefixedName_(key)); } prefixedName_(name4) { return this.prefix_ + name4; } toString() { return this.domStorage_.toString(); } }; var MemoryStorage = class { constructor() { this.cache_ = {}; this.isInMemoryStorage = true; } set(key, value) { if (value == null) { delete this.cache_[key]; } else { this.cache_[key] = value; } } get(key) { if (contains(this.cache_, key)) { return this.cache_[key]; } return null; } remove(key) { delete this.cache_[key]; } }; var createStoragefor = function(domStorageName) { try { if (typeof window !== "undefined" && typeof window[domStorageName] !== "undefined") { const domStorage = window[domStorageName]; domStorage.setItem("firebase:sentinel", "cache"); domStorage.removeItem("firebase:sentinel"); return new DOMStorageWrapper(domStorage); } } catch (e) { } return new MemoryStorage(); }; var PersistentStorage = createStoragefor("localStorage"); var SessionStorage = createStoragefor("sessionStorage"); var logClient = new Logger("@firebase/database"); var LUIDGenerator = function() { let id = 1; return function() { return id++; }; }(); var sha1 = function(str) { const utf8Bytes = stringToByteArray(str); const sha12 = new Sha1(); sha12.update(utf8Bytes); const sha1Bytes = sha12.digest(); return base64.encodeByteArray(sha1Bytes); }; var buildLogMessage_ = function(...varArgs) { let message = ""; for (let i = 0; i < varArgs.length; i++) { const arg = varArgs[i]; if (Array.isArray(arg) || arg && typeof arg === "object" && // eslint-disable-next-line @typescript-eslint/no-explicit-any typeof arg.length === "number") { message += buildLogMessage_.apply(null, arg); } else if (typeof arg === "object") { message += stringify(arg); } else { message += arg; } message += " "; } return message; }; var logger2 = null; var firstLog_ = true; var enableLogging$1 = function(logger_, persistent) { assert(!persistent || logger_ === true || logger_ === false, "Can't turn on custom loggers persistently."); if (logger_ === true) { logClient.logLevel = LogLevel.VERBOSE; logger2 = logClient.log.bind(logClient); if (persistent) { SessionStorage.set("logging_enabled", true); } } else if (typeof logger_ === "function") { logger2 = logger_; } else { logger2 = null; SessionStorage.remove("logging_enabled"); } }; var log = function(...varArgs) { if (firstLog_ === true) { firstLog_ = false; if (logger2 === null && SessionStorage.get("logging_enabled") === true) { enableLogging$1(true); } } if (logger2) { const message = buildLogMessage_.apply(null, varArgs); logger2(message); } }; var logWrapper = function(prefix) { return function(...varArgs) { log(prefix, ...varArgs); }; }; var error = function(...varArgs) { const message = "FIREBASE INTERNAL ERROR: " + buildLogMessage_(...varArgs); logClient.error(message); }; var fatal = function(...varArgs) { const message = `FIREBASE FATAL ERROR: ${buildLogMessage_(...varArgs)}`; logClient.error(message); throw new Error(message); }; var warn = function(...varArgs) { const message = "FIREBASE WARNING: " + buildLogMessage_(...varArgs); logClient.warn(message); }; var warnIfPageIsSecure = function() { if (typeof window !== "undefined" && window.location && window.location.protocol && window.location.protocol.indexOf("https:") !== -1) { warn("Insecure Firebase access from a secure page. Please use https in calls to new Firebase()."); } }; var isInvalidJSONNumber = function(data) { return typeof data === "number" && (data !== data || // NaN data === Number.POSITIVE_INFINITY || data === Number.NEGATIVE_INFINITY); }; var executeWhenDOMReady = function(fn) { if (isNodeSdk() || document.readyState === "complete") { fn(); } else { let called = false; const wrappedFn = function() { if (!document.body) { setTimeout(wrappedFn, Math.floor(10)); return; } if (!called) { called = true; fn(); } }; if (document.addEventListener) { document.addEventListener("DOMContentLoaded", wrappedFn, false); window.addEventListener("load", wrappedFn, false); } else if (document.attachEvent) { document.attachEvent("onreadystatechange", () => { if (document.readyState === "complete") { wrappedFn(); } }); window.attachEvent("onload", wrappedFn); } } }; var MIN_NAME = "[MIN_NAME]"; var MAX_NAME = "[MAX_NAME]"; var nameCompare = function(a, b) { if (a === b) { return 0; } else if (a === MIN_NAME || b === MAX_NAME) { return -1; } else if (b === MIN_NAME || a === MAX_NAME) { return 1; } else { const aAsInt = tryParseInt(a), bAsInt = tryParseInt(b); if (aAsInt !== null) { if (bAsInt !== null) { return aAsInt - bAsInt === 0 ? a.length - b.length : aAsInt - bAsInt; } else { return -1; } } else if (bAsInt !== null) { return 1; } else { return a < b ? -1 : 1; } } }; var stringCompare = function(a, b) { if (a === b) { return 0; } else if (a < b) { return -1; } else { return 1; } }; var requireKey = function(key, obj) { if (obj && key in obj) { return obj[key]; } else { throw new Error("Missing required key (" + key + ") in object: " + stringify(obj)); } }; var ObjectToUniqueKey = function(obj) { if (typeof obj !== "object" || obj === null) { return stringify(obj); } const keys = []; for (const k in obj) { keys.push(k); } keys.sort(); let key = "{"; for (let i = 0; i < keys.length; i++) { if (i !== 0) { key += ","; } key += stringify(keys[i]); key += ":"; key += ObjectToUniqueKey(obj[keys[i]]); } key += "}"; return key; }; var splitStringBySize = function(str, segsize) { const len = str.length; if (len <= segsize) { return [str]; } const dataSegs = []; for (let c = 0; c < len; c += segsize) { if (c + segsize > len) { dataSegs.push(str.substring(c, len)); } else { dataSegs.push(str.substring(c, c + segsize)); } } return dataSegs; }; function each(obj, fn) { for (const key in obj) { if (obj.hasOwnProperty(key)) { fn(key, obj[key]); } } } var doubleToIEEE754String = function(v) { assert(!isInvalidJSONNumber(v), "Invalid JSON number"); const ebits = 11, fbits = 52; const bias = (1 << ebits - 1) - 1; let s, e, f, ln, i; if (v === 0) { e = 0; f = 0; s = 1 / v === -Infinity ? 1 : 0; } else { s = v < 0; v = Math.abs(v); if (v >= Math.pow(2, 1 - bias)) { ln = Math.min(Math.floor(Math.log(v) / Math.LN2), bias); e = ln + bias; f = Math.round(v * Math.pow(2, fbits - ln) - Math.pow(2, fbits)); } else { e = 0; f = Math.round(v / Math.pow(2, 1 - bias - fbits)); } } const bits = []; for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = Math.floor(f / 2); } for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = Math.floor(e / 2); } bits.push(s ? 1 : 0); bits.reverse(); const str = bits.join(""); let hexByteString = ""; for (i = 0; i < 64; i += 8) { let hexByte = parseInt(str.substr(i, 8), 2).toString(16); if (hexByte.length === 1) { hexByte = "0" + hexByte; } hexByteString = hexByteString + hexByte; } return hexByteString.toLowerCase(); }; var isChromeExtensionContentScript = function() { return !!(typeof window === "object" && window["chrome"] && window["chrome"]["extension"] && !/^chrome/.test(window.location.href)); }; var isWindowsStoreApp = function() { return typeof Windows === "object" && typeof Windows.UI === "object"; }; function errorForServerCode(code, query) { let reason = "Unknown Error"; if (code === "too_big") { reason = "The data requested exceeds the maximum size that can be accessed with a single request."; } else if (code === "permission_denied") { reason = "Client doesn't have permission to access the desired data."; } else if (code === "unavailable") { reason = "The service is unavailable"; } const error2 = new Error(code + " at " + query._path.toString() + ": " + reason); error2.code = code.toUpperCase(); return error2; } var INTEGER_REGEXP_ = new RegExp("^-?(0*)\\d{1,10}$"); var INTEGER_32_MIN = -2147483648; var INTEGER_32_MAX = 2147483647; var tryParseInt = function(str) { if (INTEGER_REGEXP_.test(str)) { const intVal = Number(str); if (intVal >= INTEGER_32_MIN && intVal <= INTEGER_32_MAX) { return intVal; } } return null; }; var exceptionGuard = function(fn) { try { fn(); } catch (e) { setTimeout(() => { const stack = e.stack || ""; warn("Exception was thrown by user callback.", stack); throw e; }, Math.floor(0)); } }; var beingCrawled = function() { const userAgent = typeof window === "object" && window["navigator"] && window["navigator"]["userAgent"] || ""; return userAgent.search(/googlebot|google webmaster tools|bingbot|yahoo! slurp|baiduspider|yandexbot|duckduckbot/i) >= 0; }; var setTimeoutNonBlocking = function(fn, time) { const timeout = setTimeout(fn, time); if (typeof timeout === "number" && // @ts-ignore Is only defined in Deno environments. typeof Deno !== "undefined" && // @ts-ignore Deno and unrefTimer are only defined in Deno environments. Deno["unrefTimer"]) { Deno.unrefTimer(timeout); } else if (typeof timeout === "object" && timeout["unref"]) { timeout["unref"](); } return timeout; }; var AppCheckTokenProvider = class { constructor(appName_, appCheckProvider) { this.appName_ = appName_; this.appCheckProvider = appCheckProvider; this.appCheck = appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.getImmediate({ optional: true }); if (!this.appCheck) { appCheckProvider === null || appCheckProvider === void 0 ? void 0 : appCheckProvider.get().then((appCheck) => this.appCheck = appCheck); } } getToken(forceRefresh) { if (!this.appCheck) { return new Promise((resolve, reject) => { setTimeout(() => { if (this.appCheck) { this.getToken(forceRefresh).then(resolve, reject); } else { resolve(null); } }, 0); }); } return this.appCheck.getToken(forceRefresh); } addTokenChangeListener(listener) { var _a; (_a = this.appCheckProvider) === null || _a === void 0 ? void 0 : _a.get().then((appCheck) => appCheck.addTokenListener(listener)); } notifyForInvalidToken() { warn(`Provided AppCheck credentials for the app named "${this.appName_}" are invalid. This usually indicates your app was not initialized correctly.`); } }; var FirebaseAuthTokenProvider = class { constructor(appName_, firebaseOptions_, authProvider_) { this.appName_ = appName_; this.firebaseOptions_ = firebaseOptions_; this.authProvider_ = authProvider_; this.auth_ = null; this.auth_ = authProvider_.getImmediate({ optional: true }); if (!this.auth_) { authProvider_.onInit((auth) => this.auth_ = auth); } } getToken(forceRefresh) { if (!this.auth_) { return new Promise((resolve, reject) => { setTimeout(() => { if (this.auth_) { this.getToken(forceRefresh).then(resolve, reject); } else { resolve(null); } }, 0); }); } return this.auth_.getToken(forceRefresh).catch((error2) => { if (error2 && error2.code === "auth/token-not-initialized") { log("Got auth/token-not-initialized error. Treating as null token."); return null; } else { return Promise.reject(error2); } }); } addTokenChangeListener(listener) { if (this.auth_) { this.auth_.addAuthTokenListener(listener); } else { this.authProvider_.get().then((auth) => auth.addAuthTokenListener(listener)); } } removeTokenChangeListener(listener) { this.authProvider_.get().then((auth) => auth.removeAuthTokenListener(listener)); } notifyForInvalidToken() { let errorMessage = 'Provided authentication credentials for the app named "' + this.appName_ + '" are invalid. This usually indicates your app was not initialized correctly. '; if ("credential" in this.firebaseOptions_) { errorMessage += 'Make sure the "credential" property provided to initializeApp() is authorized to access the specified "databaseURL" and is from the correct project.'; } else if ("serviceAccount" in this.firebaseOptions_) { errorMessage += 'Make sure the "serviceAccount" property provided to initializeApp() is authorized to access the specified "databaseURL" and is from the correct project.'; } else { errorMessage += 'Make sure the "apiKey" and "databaseURL" properties provided to initializeApp() match the values provided for your app at https://console.firebase.google.com/.'; } warn(errorMessage); } }; var EmulatorTokenProvider = class { constructor(accessToken) { this.accessToken = accessToken; } getToken(forceRefresh) { return Promise.resolve({ accessToken: this.accessToken }); } addTokenChangeListener(listener) { listener(this.accessToken); } removeTokenChangeListener(listener) { } notifyForInvalidToken() { } }; EmulatorTokenProvider.OWNER = "owner"; var PROTOCOL_VERSION2 = "5"; var VERSION_PARAM = "v"; var TRANSPORT_SESSION_PARAM = "s"; var REFERER_PARAM = "r"; var FORGE_REF = "f"; var FORGE_DOMAIN_RE = /(console\.firebase|firebase-console-\w+\.corp|firebase\.corp)\.google\.com/; var LAST_SESSION_PARAM = "ls"; var APPLICATION_ID_PARAM = "p"; var APP_CHECK_TOKEN_PARAM = "ac"; var WEBSOCKET = "websocket"; var LONG_POLLING = "long_polling"; var RepoInfo = class { /** * @param host - Hostname portion of the url for the repo * @param secure - Whether or not this repo is accessed over ssl * @param namespace - The namespace represented by the repo * @param webSocketOnly - Whether to prefer websockets over all other transports (used by Nest). * @param nodeAdmin - Whether this instance uses Admin SDK credentials * @param persistenceKey - Override the default session persistence storage key */ constructor(host, secure, namespace, webSocketOnly, nodeAdmin = false, persistenceKey = "", includeNamespaceInQueryParams = false, isUsingEmulator = false) { this.secure = secure; this.namespace = namespace; this.webSocketOnly = webSocketOnly; this.nodeAdmin = nodeAdmin; this.persistenceKey = persistenceKey; this.includeNamespaceInQueryParams = includeNamespaceInQueryParams; this.isUsingEmulator = isUsingEmulator; this._host = host.toLowerCase(); this._domain = this._host.substr(this._host.indexOf(".") + 1); this.internalHost = PersistentStorage.get("host:" + host) || this._host; } isCacheableHost() { return this.internalHost.substr(0, 2) === "s-"; } isCustomHost() { return this._domain !== "firebaseio.com" && this._domain !== "firebaseio-demo.com"; } get host() { return this._host; } set host(newHost) { if (newHost !== this.internalHost) { this.internalHost = newHost; if (this.isCacheableHost()) { PersistentStorage.set("host:" + this._host, this.internalHost); } } } toString() { let str = this.toURLString(); if (this.persistenceKey) { str += "<" + this.persistenceKey + ">"; } return str; } toURLString() { const protocol = this.secure ? "https://" : "http://"; const query = this.includeNamespaceInQueryParams ? `?ns=${this.namespace}` : ""; return `${protocol}${this.host}/${query}`; } }; function repoInfoNeedsQueryParam(repoInfo) { return repoInfo.host !== repoInfo.internalHost || repoInfo.isCustomHost() || repoInfo.includeNamespaceInQueryParams; } function repoInfoConnectionURL(repoInfo, type, params) { assert(typeof type === "string", "typeof type must == string"); assert(typeof params === "object", "typeof params must == object"); let connURL; if (type === WEBSOCKET) { connURL = (repoInfo.secure ? "wss://" : "ws://") + repoInfo.internalHost + "/.ws?"; } else if (type === LONG_POLLING) { connURL = (repoInfo.secure ? "https://" : "http://") + repoInfo.internalHost + "/.lp?"; } else { throw new Error("Unknown connection type: " + type); } if (repoInfoNeedsQueryParam(repoInfo)) { params["ns"] = repoInfo.namespace; } const pairs = []; each(params, (key, value) => { pairs.push(key + "=" + value); }); return connURL + pairs.join("&"); } var StatsCollection = class { constructor() { this.counters_ = {}; } incrementCounter(name4, amount = 1) { if (!contains(this.counters_, name4)) { this.counters_[name4] = 0; } this.counters_[name4] += amount; } get() { return deepCopy(this.counters_); } }; var collections = {}; var reporters = {}; function statsManagerGetCollection(repoInfo) { const hashString = repoInfo.toString(); if (!collections[hashString]) { collections[hashString] = new StatsCollection(); } return collections[hashString]; } function statsManagerGetOrCreateReporter(repoInfo, creatorFunction) { const hashString = repoInfo.toString(); if (!reporters[hashString]) { reporters[hashString] = creatorFunction(); } return reporters[hashString]; } var PacketReceiver = class { /** * @param onMessage_ */ constructor(onMessage_) { this.onMessage_ = onMessage_; this.pendingResponses = []; this.currentResponseNum = 0; this.closeAfterResponse = -1; this.onClose = null; } closeAfter(responseNum, callback) { this.closeAfterResponse = responseNum; this.onClose = callback; if (this.closeAfterResponse < this.currentResponseNum) { this.onClose(); this.onClose = null; } } /** * Each message from the server comes with a response number, and an array of data. The responseNumber * allows us to ensure that we process them in the right order, since we can't be guaranteed that all * browsers will respond in the same order as the requests we sent */ handleResponse(requestNum, data) { this.pendingResponses[requestNum] = data; while (this.pendingResponses[this.currentResponseNum]) { const toProcess = this.pendingResponses[this.currentResponseNum]; delete this.pendingResponses[this.currentResponseNum]; for (let i = 0; i < toProcess.length; ++i) { if (toProcess[i]) { exceptionGuard(() => { this.onMessage_(toProcess[i]); }); } } if (this.currentResponseNum === this.closeAfterResponse) { if (this.onClose) { this.onClose(); this.onClose = null; } break; } this.currentResponseNum++; } } }; var FIREBASE_LONGPOLL_START_PARAM = "start"; var FIREBASE_LONGPOLL_CLOSE_COMMAND = "close"; var FIREBASE_LONGPOLL_COMMAND_CB_NAME = "pLPCommand"; var FIREBASE_LONGPOLL_DATA_CB_NAME = "pRTLPCB"; var FIREBASE_LONGPOLL_ID_PARAM = "id"; var FIREBASE_LONGPOLL_PW_PARAM = "pw"; var FIREBASE_LONGPOLL_SERIAL_PARAM = "ser"; var FIREBASE_LONGPOLL_CALLBACK_ID_PARAM = "cb"; var FIREBASE_LONGPOLL_SEGMENT_NUM_PARAM = "seg"; var FIREBASE_LONGPOLL_SEGMENTS_IN_PACKET = "ts"; var FIREBASE_LONGPOLL_DATA_PARAM = "d"; var FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM = "dframe"; var MAX_URL_DATA_SIZE = 1870; var SEG_HEADER_SIZE = 30; var MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE; var KEEPALIVE_REQUEST_INTERVAL = 25e3; var LP_CONNECT_TIMEOUT = 3e4; var BrowserPollConnection = class _BrowserPollConnection { /** * @param connId An identifier for this connection, used for logging * @param repoInfo The info for the endpoint to send data to. * @param applicationId The Firebase App ID for this project. * @param appCheckToken The AppCheck token for this client. * @param authToken The AuthToken to use for this connection. * @param transportSessionId Optional transportSessionid if we are * reconnecting for an existing transport session * @param lastSessionId Optional lastSessionId if the PersistentConnection has * already created a connection previously */ constructor(connId, repoInfo, applicationId, appCheckToken, authToken, transportSessionId, lastSessionId) { this.connId = connId; this.repoInfo = repoInfo; this.applicationId = applicationId; this.appCheckToken = appCheckToken; this.authToken = authToken; this.transportSessionId = transportSessionId; this.lastSessionId = lastSessionId; this.bytesSent = 0; this.bytesReceived = 0; this.everConnected_ = false; this.log_ = logWrapper(connId); this.stats_ = statsManagerGetCollection(repoInfo); this.urlFn = (params) => { if (this.appCheckToken) { params[APP_CHECK_TOKEN_PARAM] = this.appCheckToken; } return repoInfoConnectionURL(repoInfo, LONG_POLLING, params); }; } /** * @param onMessage - Callback when messages arrive * @param onDisconnect - Callback with connection lost. */ open(onMessage, onDisconnect) { this.curSegmentNum = 0; this.onDisconnect_ = onDisconnect; this.myPacketOrderer = new PacketReceiver(onMessage); this.isClosed_ = false; this.connectTimeoutTimer_ = setTimeout(() => { this.log_("Timed out trying to connect."); this.onClosed_(); this.connectTimeoutTimer_ = null; }, Math.floor(LP_CONNECT_TIMEOUT)); executeWhenDOMReady(() => { if (this.isClosed_) { return; } this.scriptTagHolder = new FirebaseIFrameScriptHolder((...args) => { const [command, arg1, arg2, arg3, arg4] = args; this.incrementIncomingBytes_(args); if (!this.scriptTagHolder) { return; } if (this.connectTimeoutTimer_) { clearTimeout(this.connectTimeoutTimer_); this.connectTimeoutTimer_ = null; } this.everConnected_ = true; if (command === FIREBASE_LONGPOLL_START_PARAM) { this.id = arg1; this.password = arg2; } else if (command === FIREBASE_LONGPOLL_CLOSE_COMMAND) { if (arg1) { this.scriptTagHolder.sendNewPolls = false; this.myPacketOrderer.closeAfter(arg1, () => { this.onClosed_(); }); } else { this.onClosed_(); } } else { throw new Error("Unrecognized command received: " + command); } }, (...args) => { const [pN, data] = args; this.incrementIncomingBytes_(args); this.myPacketOrderer.handleResponse(pN, data); }, () => { this.onClosed_(); }, this.urlFn); const urlParams = {}; urlParams[FIREBASE_LONGPOLL_START_PARAM] = "t"; urlParams[FIREBASE_LONGPOLL_SERIAL_PARAM] = Math.floor(Math.random() * 1e8); if (this.scriptTagHolder.uniqueCallbackIdentifier) { urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] = this.scriptTagHolder.uniqueCallbackIdentifier; } urlParams[VERSION_PARAM] = PROTOCOL_VERSION2; if (this.transportSessionId) { urlParams[TRANSPORT_SESSION_PARAM] = this.transportSessionId; } if (this.lastSessionId) { urlParams[LAST_SESSION_PARAM] = this.lastSessionId; } if (this.applicationId) { urlParams[APPLICATION_ID_PARAM] = this.applicationId; } if (this.appCheckToken) { urlParams[APP_CHECK_TOKEN_PARAM] = this.appCheckToken; } if (typeof location !== "undefined" && location.hostname && FORGE_DOMAIN_RE.test(location.hostname)) { urlParams[REFERER_PARAM] = FORGE_REF; } const connectURL = this.urlFn(urlParams); this.log_("Connecting via long-poll to " + connectURL); this.scriptTagHolder.addTag(connectURL, () => { }); }); } /** * Call this when a handshake has completed successfully and we want to consider the connection established */ start() { this.scriptTagHolder.startLongPoll(this.id, this.password); this.addDisconnectPingFrame(this.id, this.password); } /** * Forces long polling to be considered as a potential transport */ static forceAllow() { _BrowserPollConnection.forceAllow_ = true; } /** * Forces longpolling to not be considered as a potential transport */ static forceDisallow() { _BrowserPollConnection.forceDisallow_ = true; } // Static method, use string literal so it can be accessed in a generic way static isAvailable() { if (isNodeSdk()) { return false; } else if (_BrowserPollConnection.forceAllow_) { return true; } else { return !_BrowserPollConnection.forceDisallow_ && typeof document !== "undefined" && document.createElement != null && !isChromeExtensionContentScript() && !isWindowsStoreApp(); } } /** * No-op for polling */ markConnectionHealthy() { } /** * Stops polling and cleans up the iframe */ shutdown_() { this.isClosed_ = true; if (this.scriptTagHolder) { this.scriptTagHolder.close(); this.scriptTagHolder = null; } if (this.myDisconnFrame) { document.body.removeChild(this.myDisconnFrame); this.myDisconnFrame = null; } if (this.connectTimeoutTimer_) { clearTimeout(this.connectTimeoutTimer_); this.connectTimeoutTimer_ = null; } } /** * Triggered when this transport is closed */ onClosed_() { if (!this.isClosed_) { this.log_("Longpoll is closing itself"); this.shutdown_(); if (this.onDisconnect_) { this.onDisconnect_(this.everConnected_); this.onDisconnect_ = null; } } } /** * External-facing close handler. RealTime has requested we shut down. Kill our connection and tell the server * that we've left. */ close() { if (!this.isClosed_) { this.log_("Longpoll is being closed."); this.shutdown_(); } } /** * Send the JSON object down to the server. It will need to be stringified, base64 encoded, and then * broken into chunks (since URLs have a small maximum length). * @param data - The JSON data to transmit. */ send(data) { const dataStr = stringify(data); this.bytesSent += dataStr.length; this.stats_.incrementCounter("bytes_sent", dataStr.length); const base64data = base64Encode(dataStr); const dataSegs = splitStringBySize(base64data, MAX_PAYLOAD_SIZE); for (let i = 0; i < dataSegs.length; i++) { this.scriptTagHolder.enqueueSegment(this.curSegmentNum, dataSegs.length, dataSegs[i]); this.curSegmentNum++; } } /** * This is how we notify the server that we're leaving. * We aren't able to send requests with DHTML on a window close event, but we can * trigger XHR requests in some browsers (everything but Opera basically). */ addDisconnectPingFrame(id, pw) { if (isNodeSdk()) { return; } this.myDisconnFrame = document.createElement("iframe"); const urlParams = {}; urlParams[FIREBASE_LONGPOLL_DISCONN_FRAME_REQUEST_PARAM] = "t"; urlParams[FIREBASE_LONGPOLL_ID_PARAM] = id; urlParams[FIREBASE_LONGPOLL_PW_PARAM] = pw; this.myDisconnFrame.src = this.urlFn(urlParams); this.myDisconnFrame.style.display = "none"; document.body.appendChild(this.myDisconnFrame); } /** * Used to track the bytes received by this client */ incrementIncomingBytes_(args) { const bytesReceived = stringify(args).length; this.bytesReceived += bytesReceived; this.stats_.incrementCounter("bytes_received", bytesReceived); } }; var FirebaseIFrameScriptHolder = class _FirebaseIFrameScriptHolder { /** * @param commandCB - The callback to be called when control commands are recevied from the server. * @param onMessageCB - The callback to be triggered when responses arrive from the server. * @param onDisconnect - The callback to be triggered when this tag holder is closed * @param urlFn - A function that provides the URL of the endpoint to send data to. */ constructor(commandCB, onMessageCB, onDisconnect, urlFn) { this.onDisconnect = onDisconnect; this.urlFn = urlFn; this.outstandingRequests = /* @__PURE__ */ new Set(); this.pendingSegs = []; this.currentSerial = Math.floor(Math.random() * 1e8); this.sendNewPolls = true; if (!isNodeSdk()) { this.uniqueCallbackIdentifier = LUIDGenerator(); window[FIREBASE_LONGPOLL_COMMAND_CB_NAME + this.uniqueCallbackIdentifier] = commandCB; window[FIREBASE_LONGPOLL_DATA_CB_NAME + this.uniqueCallbackIdentifier] = onMessageCB; this.myIFrame = _FirebaseIFrameScriptHolder.createIFrame_(); let script = ""; if (this.myIFrame.src && this.myIFrame.src.substr(0, "javascript:".length) === "javascript:") { const currentDomain = document.domain; script = '