Spaces:
Sleeping
Sleeping
| ; | |
| (() => { | |
| var __defProp = Object.defineProperty; | |
| var __export = (target, all) => { | |
| for (var name in all) | |
| __defProp(target, name, { get: all[name], enumerable: true }); | |
| }; | |
| // node_modules/engine.io-parser/build/esm/commons.js | |
| var PACKET_TYPES = /* @__PURE__ */ Object.create(null); | |
| PACKET_TYPES["open"] = "0"; | |
| PACKET_TYPES["close"] = "1"; | |
| PACKET_TYPES["ping"] = "2"; | |
| PACKET_TYPES["pong"] = "3"; | |
| PACKET_TYPES["message"] = "4"; | |
| PACKET_TYPES["upgrade"] = "5"; | |
| PACKET_TYPES["noop"] = "6"; | |
| var PACKET_TYPES_REVERSE = /* @__PURE__ */ Object.create(null); | |
| Object.keys(PACKET_TYPES).forEach((key) => { | |
| PACKET_TYPES_REVERSE[PACKET_TYPES[key]] = key; | |
| }); | |
| var ERROR_PACKET = { type: "error", data: "parser error" }; | |
| // node_modules/engine.io-parser/build/esm/encodePacket.browser.js | |
| var withNativeBlob = typeof Blob === "function" || typeof Blob !== "undefined" && Object.prototype.toString.call(Blob) === "[object BlobConstructor]"; | |
| var withNativeArrayBuffer = typeof ArrayBuffer === "function"; | |
| var isView = (obj) => { | |
| return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj && obj.buffer instanceof ArrayBuffer; | |
| }; | |
| var encodePacket = ({ type, data }, supportsBinary, callback) => { | |
| if (withNativeBlob && data instanceof Blob) { | |
| if (supportsBinary) { | |
| return callback(data); | |
| } else { | |
| return encodeBlobAsBase64(data, callback); | |
| } | |
| } else if (withNativeArrayBuffer && (data instanceof ArrayBuffer || isView(data))) { | |
| if (supportsBinary) { | |
| return callback(data); | |
| } else { | |
| return encodeBlobAsBase64(new Blob([data]), callback); | |
| } | |
| } | |
| return callback(PACKET_TYPES[type] + (data || "")); | |
| }; | |
| var encodeBlobAsBase64 = (data, callback) => { | |
| const fileReader = new FileReader(); | |
| fileReader.onload = function() { | |
| const content = fileReader.result.split(",")[1]; | |
| callback("b" + (content || "")); | |
| }; | |
| return fileReader.readAsDataURL(data); | |
| }; | |
| function toArray(data) { | |
| if (data instanceof Uint8Array) { | |
| return data; | |
| } else if (data instanceof ArrayBuffer) { | |
| return new Uint8Array(data); | |
| } else { | |
| return new Uint8Array(data.buffer, data.byteOffset, data.byteLength); | |
| } | |
| } | |
| var TEXT_ENCODER; | |
| function encodePacketToBinary(packet, callback) { | |
| if (withNativeBlob && packet.data instanceof Blob) { | |
| return packet.data.arrayBuffer().then(toArray).then(callback); | |
| } else if (withNativeArrayBuffer && (packet.data instanceof ArrayBuffer || isView(packet.data))) { | |
| return callback(toArray(packet.data)); | |
| } | |
| encodePacket(packet, false, (encoded) => { | |
| if (!TEXT_ENCODER) { | |
| TEXT_ENCODER = new TextEncoder(); | |
| } | |
| callback(TEXT_ENCODER.encode(encoded)); | |
| }); | |
| } | |
| // node_modules/engine.io-parser/build/esm/contrib/base64-arraybuffer.js | |
| var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
| var lookup = typeof Uint8Array === "undefined" ? [] : new Uint8Array(256); | |
| for (let i = 0; i < chars.length; i++) { | |
| lookup[chars.charCodeAt(i)] = i; | |
| } | |
| var decode = (base64) => { | |
| let bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4; | |
| if (base64[base64.length - 1] === "=") { | |
| bufferLength--; | |
| if (base64[base64.length - 2] === "=") { | |
| bufferLength--; | |
| } | |
| } | |
| const arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer); | |
| for (i = 0; i < len; i += 4) { | |
| encoded1 = lookup[base64.charCodeAt(i)]; | |
| encoded2 = lookup[base64.charCodeAt(i + 1)]; | |
| encoded3 = lookup[base64.charCodeAt(i + 2)]; | |
| encoded4 = lookup[base64.charCodeAt(i + 3)]; | |
| bytes[p++] = encoded1 << 2 | encoded2 >> 4; | |
| bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; | |
| bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; | |
| } | |
| return arraybuffer; | |
| }; | |
| // node_modules/engine.io-parser/build/esm/decodePacket.browser.js | |
| var withNativeArrayBuffer2 = typeof ArrayBuffer === "function"; | |
| var decodePacket = (encodedPacket, binaryType) => { | |
| if (typeof encodedPacket !== "string") { | |
| return { | |
| type: "message", | |
| data: mapBinary(encodedPacket, binaryType) | |
| }; | |
| } | |
| const type = encodedPacket.charAt(0); | |
| if (type === "b") { | |
| return { | |
| type: "message", | |
| data: decodeBase64Packet(encodedPacket.substring(1), binaryType) | |
| }; | |
| } | |
| const packetType = PACKET_TYPES_REVERSE[type]; | |
| if (!packetType) { | |
| return ERROR_PACKET; | |
| } | |
| return encodedPacket.length > 1 ? { | |
| type: PACKET_TYPES_REVERSE[type], | |
| data: encodedPacket.substring(1) | |
| } : { | |
| type: PACKET_TYPES_REVERSE[type] | |
| }; | |
| }; | |
| var decodeBase64Packet = (data, binaryType) => { | |
| if (withNativeArrayBuffer2) { | |
| const decoded = decode(data); | |
| return mapBinary(decoded, binaryType); | |
| } else { | |
| return { base64: true, data }; | |
| } | |
| }; | |
| var mapBinary = (data, binaryType) => { | |
| switch (binaryType) { | |
| case "blob": | |
| if (data instanceof Blob) { | |
| return data; | |
| } else { | |
| return new Blob([data]); | |
| } | |
| case "arraybuffer": | |
| default: | |
| if (data instanceof ArrayBuffer) { | |
| return data; | |
| } else { | |
| return data.buffer; | |
| } | |
| } | |
| }; | |
| // node_modules/engine.io-parser/build/esm/index.js | |
| var SEPARATOR = String.fromCharCode(30); | |
| var encodePayload = (packets, callback) => { | |
| const length = packets.length; | |
| const encodedPackets = new Array(length); | |
| let count = 0; | |
| packets.forEach((packet, i) => { | |
| encodePacket(packet, false, (encodedPacket) => { | |
| encodedPackets[i] = encodedPacket; | |
| if (++count === length) { | |
| callback(encodedPackets.join(SEPARATOR)); | |
| } | |
| }); | |
| }); | |
| }; | |
| var decodePayload = (encodedPayload, binaryType) => { | |
| const encodedPackets = encodedPayload.split(SEPARATOR); | |
| const packets = []; | |
| for (let i = 0; i < encodedPackets.length; i++) { | |
| const decodedPacket = decodePacket(encodedPackets[i], binaryType); | |
| packets.push(decodedPacket); | |
| if (decodedPacket.type === "error") { | |
| break; | |
| } | |
| } | |
| return packets; | |
| }; | |
| function createPacketEncoderStream() { | |
| return new TransformStream({ | |
| transform(packet, controller) { | |
| encodePacketToBinary(packet, (encodedPacket) => { | |
| const payloadLength = encodedPacket.length; | |
| let header; | |
| if (payloadLength < 126) { | |
| header = new Uint8Array(1); | |
| new DataView(header.buffer).setUint8(0, payloadLength); | |
| } else if (payloadLength < 65536) { | |
| header = new Uint8Array(3); | |
| const view = new DataView(header.buffer); | |
| view.setUint8(0, 126); | |
| view.setUint16(1, payloadLength); | |
| } else { | |
| header = new Uint8Array(9); | |
| const view = new DataView(header.buffer); | |
| view.setUint8(0, 127); | |
| view.setBigUint64(1, BigInt(payloadLength)); | |
| } | |
| if (packet.data && typeof packet.data !== "string") { | |
| header[0] |= 128; | |
| } | |
| controller.enqueue(header); | |
| controller.enqueue(encodedPacket); | |
| }); | |
| } | |
| }); | |
| } | |
| var TEXT_DECODER; | |
| function totalLength(chunks) { | |
| return chunks.reduce((acc, chunk) => acc + chunk.length, 0); | |
| } | |
| function concatChunks(chunks, size) { | |
| if (chunks[0].length === size) { | |
| return chunks.shift(); | |
| } | |
| const buffer = new Uint8Array(size); | |
| let j2 = 0; | |
| for (let i = 0; i < size; i++) { | |
| buffer[i] = chunks[0][j2++]; | |
| if (j2 === chunks[0].length) { | |
| chunks.shift(); | |
| j2 = 0; | |
| } | |
| } | |
| if (chunks.length && j2 < chunks[0].length) { | |
| chunks[0] = chunks[0].slice(j2); | |
| } | |
| return buffer; | |
| } | |
| function createPacketDecoderStream(maxPayload, binaryType) { | |
| if (!TEXT_DECODER) { | |
| TEXT_DECODER = new TextDecoder(); | |
| } | |
| const chunks = []; | |
| let state = 0; | |
| let expectedLength = -1; | |
| let isBinary2 = false; | |
| return new TransformStream({ | |
| transform(chunk, controller) { | |
| chunks.push(chunk); | |
| while (true) { | |
| if (state === 0) { | |
| if (totalLength(chunks) < 1) { | |
| break; | |
| } | |
| const header = concatChunks(chunks, 1); | |
| isBinary2 = (header[0] & 128) === 128; | |
| expectedLength = header[0] & 127; | |
| if (expectedLength < 126) { | |
| state = 3; | |
| } else if (expectedLength === 126) { | |
| state = 1; | |
| } else { | |
| state = 2; | |
| } | |
| } else if (state === 1) { | |
| if (totalLength(chunks) < 2) { | |
| break; | |
| } | |
| const headerArray = concatChunks(chunks, 2); | |
| expectedLength = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length).getUint16(0); | |
| state = 3; | |
| } else if (state === 2) { | |
| if (totalLength(chunks) < 8) { | |
| break; | |
| } | |
| const headerArray = concatChunks(chunks, 8); | |
| const view = new DataView(headerArray.buffer, headerArray.byteOffset, headerArray.length); | |
| const n = view.getUint32(0); | |
| if (n > Math.pow(2, 53 - 32) - 1) { | |
| controller.enqueue(ERROR_PACKET); | |
| break; | |
| } | |
| expectedLength = n * Math.pow(2, 32) + view.getUint32(4); | |
| state = 3; | |
| } else { | |
| if (totalLength(chunks) < expectedLength) { | |
| break; | |
| } | |
| const data = concatChunks(chunks, expectedLength); | |
| controller.enqueue(decodePacket(isBinary2 ? data : TEXT_DECODER.decode(data), binaryType)); | |
| state = 0; | |
| } | |
| if (expectedLength === 0 || expectedLength > maxPayload) { | |
| controller.enqueue(ERROR_PACKET); | |
| break; | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| var protocol = 4; | |
| // node_modules/@socket.io/component-emitter/lib/esm/index.js | |
| function Emitter(obj) { | |
| if (obj) return mixin(obj); | |
| } | |
| function mixin(obj) { | |
| for (var key in Emitter.prototype) { | |
| obj[key] = Emitter.prototype[key]; | |
| } | |
| return obj; | |
| } | |
| Emitter.prototype.on = Emitter.prototype.addEventListener = function(event, fn) { | |
| this._callbacks = this._callbacks || {}; | |
| (this._callbacks["$" + event] = this._callbacks["$" + event] || []).push(fn); | |
| return this; | |
| }; | |
| Emitter.prototype.once = function(event, fn) { | |
| function on2() { | |
| this.off(event, on2); | |
| fn.apply(this, arguments); | |
| } | |
| on2.fn = fn; | |
| this.on(event, on2); | |
| return this; | |
| }; | |
| Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function(event, fn) { | |
| this._callbacks = this._callbacks || {}; | |
| if (0 == arguments.length) { | |
| this._callbacks = {}; | |
| return this; | |
| } | |
| var callbacks = this._callbacks["$" + event]; | |
| if (!callbacks) return this; | |
| if (1 == arguments.length) { | |
| delete this._callbacks["$" + event]; | |
| return this; | |
| } | |
| var cb; | |
| for (var i = 0; i < callbacks.length; i++) { | |
| cb = callbacks[i]; | |
| if (cb === fn || cb.fn === fn) { | |
| callbacks.splice(i, 1); | |
| break; | |
| } | |
| } | |
| if (callbacks.length === 0) { | |
| delete this._callbacks["$" + event]; | |
| } | |
| return this; | |
| }; | |
| Emitter.prototype.emit = function(event) { | |
| this._callbacks = this._callbacks || {}; | |
| var args = new Array(arguments.length - 1), callbacks = this._callbacks["$" + event]; | |
| for (var i = 1; i < arguments.length; i++) { | |
| args[i - 1] = arguments[i]; | |
| } | |
| if (callbacks) { | |
| callbacks = callbacks.slice(0); | |
| for (var i = 0, len = callbacks.length; i < len; ++i) { | |
| callbacks[i].apply(this, args); | |
| } | |
| } | |
| return this; | |
| }; | |
| Emitter.prototype.emitReserved = Emitter.prototype.emit; | |
| Emitter.prototype.listeners = function(event) { | |
| this._callbacks = this._callbacks || {}; | |
| return this._callbacks["$" + event] || []; | |
| }; | |
| Emitter.prototype.hasListeners = function(event) { | |
| return !!this.listeners(event).length; | |
| }; | |
| // node_modules/engine.io-client/build/esm/globals.js | |
| var nextTick = (() => { | |
| const isPromiseAvailable = typeof Promise === "function" && typeof Promise.resolve === "function"; | |
| if (isPromiseAvailable) { | |
| return (cb) => Promise.resolve().then(cb); | |
| } else { | |
| return (cb, setTimeoutFn) => setTimeoutFn(cb, 0); | |
| } | |
| })(); | |
| var globalThisShim = (() => { | |
| if (typeof self !== "undefined") { | |
| return self; | |
| } else if (typeof window !== "undefined") { | |
| return window; | |
| } else { | |
| return Function("return this")(); | |
| } | |
| })(); | |
| var defaultBinaryType = "arraybuffer"; | |
| function createCookieJar() { | |
| } | |
| // node_modules/engine.io-client/build/esm/util.js | |
| function pick(obj, ...attr) { | |
| return attr.reduce((acc, k2) => { | |
| if (obj.hasOwnProperty(k2)) { | |
| acc[k2] = obj[k2]; | |
| } | |
| return acc; | |
| }, {}); | |
| } | |
| var NATIVE_SET_TIMEOUT = globalThisShim.setTimeout; | |
| var NATIVE_CLEAR_TIMEOUT = globalThisShim.clearTimeout; | |
| function installTimerFunctions(obj, opts) { | |
| if (opts.useNativeTimers) { | |
| obj.setTimeoutFn = NATIVE_SET_TIMEOUT.bind(globalThisShim); | |
| obj.clearTimeoutFn = NATIVE_CLEAR_TIMEOUT.bind(globalThisShim); | |
| } else { | |
| obj.setTimeoutFn = globalThisShim.setTimeout.bind(globalThisShim); | |
| obj.clearTimeoutFn = globalThisShim.clearTimeout.bind(globalThisShim); | |
| } | |
| } | |
| var BASE64_OVERHEAD = 1.33; | |
| function byteLength(obj) { | |
| if (typeof obj === "string") { | |
| return utf8Length(obj); | |
| } | |
| return Math.ceil((obj.byteLength || obj.size) * BASE64_OVERHEAD); | |
| } | |
| function utf8Length(str) { | |
| let c = 0, length = 0; | |
| for (let i = 0, l = str.length; i < l; i++) { | |
| c = str.charCodeAt(i); | |
| if (c < 128) { | |
| length += 1; | |
| } else if (c < 2048) { | |
| length += 2; | |
| } else if (c < 55296 || c >= 57344) { | |
| length += 3; | |
| } else { | |
| i++; | |
| length += 4; | |
| } | |
| } | |
| return length; | |
| } | |
| function randomString() { | |
| return Date.now().toString(36).substring(3) + Math.random().toString(36).substring(2, 5); | |
| } | |
| // node_modules/engine.io-client/build/esm/contrib/parseqs.js | |
| function encode(obj) { | |
| let str = ""; | |
| for (let i in obj) { | |
| if (obj.hasOwnProperty(i)) { | |
| if (str.length) | |
| str += "&"; | |
| str += encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]); | |
| } | |
| } | |
| return str; | |
| } | |
| function decode2(qs) { | |
| let qry = {}; | |
| let pairs = qs.split("&"); | |
| for (let i = 0, l = pairs.length; i < l; i++) { | |
| let pair = pairs[i].split("="); | |
| qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); | |
| } | |
| return qry; | |
| } | |
| // node_modules/engine.io-client/build/esm/transport.js | |
| var TransportError = class extends Error { | |
| constructor(reason, description, context) { | |
| super(reason); | |
| this.description = description; | |
| this.context = context; | |
| this.type = "TransportError"; | |
| } | |
| }; | |
| var Transport = class extends Emitter { | |
| /** | |
| * Transport abstract constructor. | |
| * | |
| * @param {Object} opts - options | |
| * @protected | |
| */ | |
| constructor(opts) { | |
| super(); | |
| this.writable = false; | |
| installTimerFunctions(this, opts); | |
| this.opts = opts; | |
| this.query = opts.query; | |
| this.socket = opts.socket; | |
| this.supportsBinary = !opts.forceBase64; | |
| } | |
| /** | |
| * Emits an error. | |
| * | |
| * @param {String} reason | |
| * @param description | |
| * @param context - the error context | |
| * @return {Transport} for chaining | |
| * @protected | |
| */ | |
| onError(reason, description, context) { | |
| super.emitReserved("error", new TransportError(reason, description, context)); | |
| return this; | |
| } | |
| /** | |
| * Opens the transport. | |
| */ | |
| open() { | |
| this.readyState = "opening"; | |
| this.doOpen(); | |
| return this; | |
| } | |
| /** | |
| * Closes the transport. | |
| */ | |
| close() { | |
| if (this.readyState === "opening" || this.readyState === "open") { | |
| this.doClose(); | |
| this.onClose(); | |
| } | |
| return this; | |
| } | |
| /** | |
| * Sends multiple packets. | |
| * | |
| * @param {Array} packets | |
| */ | |
| send(packets) { | |
| if (this.readyState === "open") { | |
| this.write(packets); | |
| } else { | |
| } | |
| } | |
| /** | |
| * Called upon open | |
| * | |
| * @protected | |
| */ | |
| onOpen() { | |
| this.readyState = "open"; | |
| this.writable = true; | |
| super.emitReserved("open"); | |
| } | |
| /** | |
| * Called with data. | |
| * | |
| * @param {String} data | |
| * @protected | |
| */ | |
| onData(data) { | |
| const packet = decodePacket(data, this.socket.binaryType); | |
| this.onPacket(packet); | |
| } | |
| /** | |
| * Called with a decoded packet. | |
| * | |
| * @protected | |
| */ | |
| onPacket(packet) { | |
| super.emitReserved("packet", packet); | |
| } | |
| /** | |
| * Called upon close. | |
| * | |
| * @protected | |
| */ | |
| onClose(details) { | |
| this.readyState = "closed"; | |
| super.emitReserved("close", details); | |
| } | |
| /** | |
| * Pauses the transport, in order not to lose packets during an upgrade. | |
| * | |
| * @param onPause | |
| */ | |
| pause(onPause) { | |
| } | |
| createUri(schema, query = {}) { | |
| return schema + "://" + this._hostname() + this._port() + this.opts.path + this._query(query); | |
| } | |
| _hostname() { | |
| const hostname = this.opts.hostname; | |
| return hostname.indexOf(":") === -1 ? hostname : "[" + hostname + "]"; | |
| } | |
| _port() { | |
| if (this.opts.port && (this.opts.secure && Number(this.opts.port !== 443) || !this.opts.secure && Number(this.opts.port) !== 80)) { | |
| return ":" + this.opts.port; | |
| } else { | |
| return ""; | |
| } | |
| } | |
| _query(query) { | |
| const encodedQuery = encode(query); | |
| return encodedQuery.length ? "?" + encodedQuery : ""; | |
| } | |
| }; | |
| // node_modules/engine.io-client/build/esm/transports/polling.js | |
| var Polling = class extends Transport { | |
| constructor() { | |
| super(...arguments); | |
| this._polling = false; | |
| } | |
| get name() { | |
| return "polling"; | |
| } | |
| /** | |
| * Opens the socket (triggers polling). We write a PING message to determine | |
| * when the transport is open. | |
| * | |
| * @protected | |
| */ | |
| doOpen() { | |
| this._poll(); | |
| } | |
| /** | |
| * Pauses polling. | |
| * | |
| * @param {Function} onPause - callback upon buffers are flushed and transport is paused | |
| * @package | |
| */ | |
| pause(onPause) { | |
| this.readyState = "pausing"; | |
| const pause = () => { | |
| this.readyState = "paused"; | |
| onPause(); | |
| }; | |
| if (this._polling || !this.writable) { | |
| let total = 0; | |
| if (this._polling) { | |
| total++; | |
| this.once("pollComplete", function() { | |
| --total || pause(); | |
| }); | |
| } | |
| if (!this.writable) { | |
| total++; | |
| this.once("drain", function() { | |
| --total || pause(); | |
| }); | |
| } | |
| } else { | |
| pause(); | |
| } | |
| } | |
| /** | |
| * Starts polling cycle. | |
| * | |
| * @private | |
| */ | |
| _poll() { | |
| this._polling = true; | |
| this.doPoll(); | |
| this.emitReserved("poll"); | |
| } | |
| /** | |
| * Overloads onData to detect payloads. | |
| * | |
| * @protected | |
| */ | |
| onData(data) { | |
| const callback = (packet) => { | |
| if ("opening" === this.readyState && packet.type === "open") { | |
| this.onOpen(); | |
| } | |
| if ("close" === packet.type) { | |
| this.onClose({ description: "transport closed by the server" }); | |
| return false; | |
| } | |
| this.onPacket(packet); | |
| }; | |
| decodePayload(data, this.socket.binaryType).forEach(callback); | |
| if ("closed" !== this.readyState) { | |
| this._polling = false; | |
| this.emitReserved("pollComplete"); | |
| if ("open" === this.readyState) { | |
| this._poll(); | |
| } else { | |
| } | |
| } | |
| } | |
| /** | |
| * For polling, send a close packet. | |
| * | |
| * @protected | |
| */ | |
| doClose() { | |
| const close = () => { | |
| this.write([{ type: "close" }]); | |
| }; | |
| if ("open" === this.readyState) { | |
| close(); | |
| } else { | |
| this.once("open", close); | |
| } | |
| } | |
| /** | |
| * Writes a packets payload. | |
| * | |
| * @param {Array} packets - data packets | |
| * @protected | |
| */ | |
| write(packets) { | |
| this.writable = false; | |
| encodePayload(packets, (data) => { | |
| this.doWrite(data, () => { | |
| this.writable = true; | |
| this.emitReserved("drain"); | |
| }); | |
| }); | |
| } | |
| /** | |
| * Generates uri for connection. | |
| * | |
| * @private | |
| */ | |
| uri() { | |
| const schema = this.opts.secure ? "https" : "http"; | |
| const query = this.query || {}; | |
| if (false !== this.opts.timestampRequests) { | |
| query[this.opts.timestampParam] = randomString(); | |
| } | |
| if (!this.supportsBinary && !query.sid) { | |
| query.b64 = 1; | |
| } | |
| return this.createUri(schema, query); | |
| } | |
| }; | |
| // node_modules/engine.io-client/build/esm/contrib/has-cors.js | |
| var value = false; | |
| try { | |
| value = typeof XMLHttpRequest !== "undefined" && "withCredentials" in new XMLHttpRequest(); | |
| } catch (err) { | |
| } | |
| var hasCORS = value; | |
| // node_modules/engine.io-client/build/esm/transports/polling-xhr.js | |
| function empty() { | |
| } | |
| var BaseXHR = class extends Polling { | |
| /** | |
| * XHR Polling constructor. | |
| * | |
| * @param {Object} opts | |
| * @package | |
| */ | |
| constructor(opts) { | |
| super(opts); | |
| if (typeof location !== "undefined") { | |
| const isSSL = "https:" === location.protocol; | |
| let port = location.port; | |
| if (!port) { | |
| port = isSSL ? "443" : "80"; | |
| } | |
| this.xd = typeof location !== "undefined" && opts.hostname !== location.hostname || port !== opts.port; | |
| } | |
| } | |
| /** | |
| * Sends data. | |
| * | |
| * @param {String} data to send. | |
| * @param {Function} called upon flush. | |
| * @private | |
| */ | |
| doWrite(data, fn) { | |
| const req = this.request({ | |
| method: "POST", | |
| data | |
| }); | |
| req.on("success", fn); | |
| req.on("error", (xhrStatus, context) => { | |
| this.onError("xhr post error", xhrStatus, context); | |
| }); | |
| } | |
| /** | |
| * Starts a poll cycle. | |
| * | |
| * @private | |
| */ | |
| doPoll() { | |
| const req = this.request(); | |
| req.on("data", this.onData.bind(this)); | |
| req.on("error", (xhrStatus, context) => { | |
| this.onError("xhr poll error", xhrStatus, context); | |
| }); | |
| this.pollXhr = req; | |
| } | |
| }; | |
| var Request = class _Request extends Emitter { | |
| /** | |
| * Request constructor | |
| * | |
| * @param {Object} options | |
| * @package | |
| */ | |
| constructor(createRequest, uri, opts) { | |
| super(); | |
| this.createRequest = createRequest; | |
| installTimerFunctions(this, opts); | |
| this._opts = opts; | |
| this._method = opts.method || "GET"; | |
| this._uri = uri; | |
| this._data = void 0 !== opts.data ? opts.data : null; | |
| this._create(); | |
| } | |
| /** | |
| * Creates the XHR object and sends the request. | |
| * | |
| * @private | |
| */ | |
| _create() { | |
| var _a; | |
| const opts = pick(this._opts, "agent", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "autoUnref"); | |
| opts.xdomain = !!this._opts.xd; | |
| const xhr = this._xhr = this.createRequest(opts); | |
| try { | |
| xhr.open(this._method, this._uri, true); | |
| try { | |
| if (this._opts.extraHeaders) { | |
| xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true); | |
| for (let i in this._opts.extraHeaders) { | |
| if (this._opts.extraHeaders.hasOwnProperty(i)) { | |
| xhr.setRequestHeader(i, this._opts.extraHeaders[i]); | |
| } | |
| } | |
| } | |
| } catch (e) { | |
| } | |
| if ("POST" === this._method) { | |
| try { | |
| xhr.setRequestHeader("Content-type", "text/plain;charset=UTF-8"); | |
| } catch (e) { | |
| } | |
| } | |
| try { | |
| xhr.setRequestHeader("Accept", "*/*"); | |
| } catch (e) { | |
| } | |
| (_a = this._opts.cookieJar) === null || _a === void 0 ? void 0 : _a.addCookies(xhr); | |
| if ("withCredentials" in xhr) { | |
| xhr.withCredentials = this._opts.withCredentials; | |
| } | |
| if (this._opts.requestTimeout) { | |
| xhr.timeout = this._opts.requestTimeout; | |
| } | |
| xhr.onreadystatechange = () => { | |
| var _a2; | |
| if (xhr.readyState === 3) { | |
| (_a2 = this._opts.cookieJar) === null || _a2 === void 0 ? void 0 : _a2.parseCookies( | |
| // @ts-ignore | |
| xhr.getResponseHeader("set-cookie") | |
| ); | |
| } | |
| if (4 !== xhr.readyState) | |
| return; | |
| if (200 === xhr.status || 1223 === xhr.status) { | |
| this._onLoad(); | |
| } else { | |
| this.setTimeoutFn(() => { | |
| this._onError(typeof xhr.status === "number" ? xhr.status : 0); | |
| }, 0); | |
| } | |
| }; | |
| xhr.send(this._data); | |
| } catch (e) { | |
| this.setTimeoutFn(() => { | |
| this._onError(e); | |
| }, 0); | |
| return; | |
| } | |
| if (typeof document !== "undefined") { | |
| this._index = _Request.requestsCount++; | |
| _Request.requests[this._index] = this; | |
| } | |
| } | |
| /** | |
| * Called upon error. | |
| * | |
| * @private | |
| */ | |
| _onError(err) { | |
| this.emitReserved("error", err, this._xhr); | |
| this._cleanup(true); | |
| } | |
| /** | |
| * Cleans up house. | |
| * | |
| * @private | |
| */ | |
| _cleanup(fromError) { | |
| if ("undefined" === typeof this._xhr || null === this._xhr) { | |
| return; | |
| } | |
| this._xhr.onreadystatechange = empty; | |
| if (fromError) { | |
| try { | |
| this._xhr.abort(); | |
| } catch (e) { | |
| } | |
| } | |
| if (typeof document !== "undefined") { | |
| delete _Request.requests[this._index]; | |
| } | |
| this._xhr = null; | |
| } | |
| /** | |
| * Called upon load. | |
| * | |
| * @private | |
| */ | |
| _onLoad() { | |
| const data = this._xhr.responseText; | |
| if (data !== null) { | |
| this.emitReserved("data", data); | |
| this.emitReserved("success"); | |
| this._cleanup(); | |
| } | |
| } | |
| /** | |
| * Aborts the request. | |
| * | |
| * @package | |
| */ | |
| abort() { | |
| this._cleanup(); | |
| } | |
| }; | |
| Request.requestsCount = 0; | |
| Request.requests = {}; | |
| if (typeof document !== "undefined") { | |
| if (typeof attachEvent === "function") { | |
| attachEvent("onunload", unloadHandler); | |
| } else if (typeof addEventListener === "function") { | |
| const terminationEvent = "onpagehide" in globalThisShim ? "pagehide" : "unload"; | |
| addEventListener(terminationEvent, unloadHandler, false); | |
| } | |
| } | |
| function unloadHandler() { | |
| for (let i in Request.requests) { | |
| if (Request.requests.hasOwnProperty(i)) { | |
| Request.requests[i].abort(); | |
| } | |
| } | |
| } | |
| var hasXHR2 = (function() { | |
| const xhr = newRequest({ | |
| xdomain: false | |
| }); | |
| return xhr && xhr.responseType !== null; | |
| })(); | |
| var XHR = class extends BaseXHR { | |
| constructor(opts) { | |
| super(opts); | |
| const forceBase64 = opts && opts.forceBase64; | |
| this.supportsBinary = hasXHR2 && !forceBase64; | |
| } | |
| request(opts = {}) { | |
| Object.assign(opts, { xd: this.xd }, this.opts); | |
| return new Request(newRequest, this.uri(), opts); | |
| } | |
| }; | |
| function newRequest(opts) { | |
| const xdomain = opts.xdomain; | |
| try { | |
| if ("undefined" !== typeof XMLHttpRequest && (!xdomain || hasCORS)) { | |
| return new XMLHttpRequest(); | |
| } | |
| } catch (e) { | |
| } | |
| if (!xdomain) { | |
| try { | |
| return new globalThisShim[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP"); | |
| } catch (e) { | |
| } | |
| } | |
| } | |
| // node_modules/engine.io-client/build/esm/transports/websocket.js | |
| var isReactNative = typeof navigator !== "undefined" && typeof navigator.product === "string" && navigator.product.toLowerCase() === "reactnative"; | |
| var BaseWS = class extends Transport { | |
| get name() { | |
| return "websocket"; | |
| } | |
| doOpen() { | |
| const uri = this.uri(); | |
| const protocols = this.opts.protocols; | |
| const opts = isReactNative ? {} : pick(this.opts, "agent", "perMessageDeflate", "pfx", "key", "passphrase", "cert", "ca", "ciphers", "rejectUnauthorized", "localAddress", "protocolVersion", "origin", "maxPayload", "family", "checkServerIdentity"); | |
| if (this.opts.extraHeaders) { | |
| opts.headers = this.opts.extraHeaders; | |
| } | |
| try { | |
| this.ws = this.createSocket(uri, protocols, opts); | |
| } catch (err) { | |
| return this.emitReserved("error", err); | |
| } | |
| this.ws.binaryType = this.socket.binaryType; | |
| this.addEventListeners(); | |
| } | |
| /** | |
| * Adds event listeners to the socket | |
| * | |
| * @private | |
| */ | |
| addEventListeners() { | |
| this.ws.onopen = () => { | |
| if (this.opts.autoUnref) { | |
| this.ws._socket.unref(); | |
| } | |
| this.onOpen(); | |
| }; | |
| this.ws.onclose = (closeEvent) => this.onClose({ | |
| description: "websocket connection closed", | |
| context: closeEvent | |
| }); | |
| this.ws.onmessage = (ev) => this.onData(ev.data); | |
| this.ws.onerror = (e) => this.onError("websocket error", e); | |
| } | |
| write(packets) { | |
| this.writable = false; | |
| for (let i = 0; i < packets.length; i++) { | |
| const packet = packets[i]; | |
| const lastPacket = i === packets.length - 1; | |
| encodePacket(packet, this.supportsBinary, (data) => { | |
| try { | |
| this.doWrite(packet, data); | |
| } catch (e) { | |
| } | |
| if (lastPacket) { | |
| nextTick(() => { | |
| this.writable = true; | |
| this.emitReserved("drain"); | |
| }, this.setTimeoutFn); | |
| } | |
| }); | |
| } | |
| } | |
| doClose() { | |
| if (typeof this.ws !== "undefined") { | |
| this.ws.onerror = () => { | |
| }; | |
| this.ws.close(); | |
| this.ws = null; | |
| } | |
| } | |
| /** | |
| * Generates uri for connection. | |
| * | |
| * @private | |
| */ | |
| uri() { | |
| const schema = this.opts.secure ? "wss" : "ws"; | |
| const query = this.query || {}; | |
| if (this.opts.timestampRequests) { | |
| query[this.opts.timestampParam] = randomString(); | |
| } | |
| if (!this.supportsBinary) { | |
| query.b64 = 1; | |
| } | |
| return this.createUri(schema, query); | |
| } | |
| }; | |
| var WebSocketCtor = globalThisShim.WebSocket || globalThisShim.MozWebSocket; | |
| var WS = class extends BaseWS { | |
| createSocket(uri, protocols, opts) { | |
| return !isReactNative ? protocols ? new WebSocketCtor(uri, protocols) : new WebSocketCtor(uri) : new WebSocketCtor(uri, protocols, opts); | |
| } | |
| doWrite(_packet, data) { | |
| this.ws.send(data); | |
| } | |
| }; | |
| // node_modules/engine.io-client/build/esm/transports/webtransport.js | |
| var WT = class extends Transport { | |
| get name() { | |
| return "webtransport"; | |
| } | |
| doOpen() { | |
| try { | |
| this._transport = new WebTransport(this.createUri("https"), this.opts.transportOptions[this.name]); | |
| } catch (err) { | |
| return this.emitReserved("error", err); | |
| } | |
| this._transport.closed.then(() => { | |
| this.onClose(); | |
| }).catch((err) => { | |
| this.onError("webtransport error", err); | |
| }); | |
| this._transport.ready.then(() => { | |
| this._transport.createBidirectionalStream().then((stream) => { | |
| const decoderStream = createPacketDecoderStream(Number.MAX_SAFE_INTEGER, this.socket.binaryType); | |
| const reader = stream.readable.pipeThrough(decoderStream).getReader(); | |
| const encoderStream = createPacketEncoderStream(); | |
| encoderStream.readable.pipeTo(stream.writable); | |
| this._writer = encoderStream.writable.getWriter(); | |
| const read = () => { | |
| reader.read().then(({ done, value: value2 }) => { | |
| if (done) { | |
| return; | |
| } | |
| this.onPacket(value2); | |
| read(); | |
| }).catch((err) => { | |
| }); | |
| }; | |
| read(); | |
| const packet = { type: "open" }; | |
| if (this.query.sid) { | |
| packet.data = `{"sid":"${this.query.sid}"}`; | |
| } | |
| this._writer.write(packet).then(() => this.onOpen()); | |
| }); | |
| }); | |
| } | |
| write(packets) { | |
| this.writable = false; | |
| for (let i = 0; i < packets.length; i++) { | |
| const packet = packets[i]; | |
| const lastPacket = i === packets.length - 1; | |
| this._writer.write(packet).then(() => { | |
| if (lastPacket) { | |
| nextTick(() => { | |
| this.writable = true; | |
| this.emitReserved("drain"); | |
| }, this.setTimeoutFn); | |
| } | |
| }); | |
| } | |
| } | |
| doClose() { | |
| var _a; | |
| (_a = this._transport) === null || _a === void 0 ? void 0 : _a.close(); | |
| } | |
| }; | |
| // node_modules/engine.io-client/build/esm/transports/index.js | |
| var transports = { | |
| websocket: WS, | |
| webtransport: WT, | |
| polling: XHR | |
| }; | |
| // node_modules/engine.io-client/build/esm/contrib/parseuri.js | |
| var re = /^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; | |
| var parts = [ | |
| "source", | |
| "protocol", | |
| "authority", | |
| "userInfo", | |
| "user", | |
| "password", | |
| "host", | |
| "port", | |
| "relative", | |
| "path", | |
| "directory", | |
| "file", | |
| "query", | |
| "anchor" | |
| ]; | |
| function parse(str) { | |
| if (str.length > 8e3) { | |
| throw "URI too long"; | |
| } | |
| const src = str, b2 = str.indexOf("["), e = str.indexOf("]"); | |
| if (b2 != -1 && e != -1) { | |
| str = str.substring(0, b2) + str.substring(b2, e).replace(/:/g, ";") + str.substring(e, str.length); | |
| } | |
| let m2 = re.exec(str || ""), uri = {}, i = 14; | |
| while (i--) { | |
| uri[parts[i]] = m2[i] || ""; | |
| } | |
| if (b2 != -1 && e != -1) { | |
| uri.source = src; | |
| uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ":"); | |
| uri.authority = uri.authority.replace("[", "").replace("]", "").replace(/;/g, ":"); | |
| uri.ipv6uri = true; | |
| } | |
| uri.pathNames = pathNames(uri, uri["path"]); | |
| uri.queryKey = queryKey(uri, uri["query"]); | |
| return uri; | |
| } | |
| function pathNames(obj, path) { | |
| const regx = /\/{2,9}/g, names = path.replace(regx, "/").split("/"); | |
| if (path.slice(0, 1) == "/" || path.length === 0) { | |
| names.splice(0, 1); | |
| } | |
| if (path.slice(-1) == "/") { | |
| names.splice(names.length - 1, 1); | |
| } | |
| return names; | |
| } | |
| function queryKey(uri, query) { | |
| const data = {}; | |
| query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function($0, $1, $2) { | |
| if ($1) { | |
| data[$1] = $2; | |
| } | |
| }); | |
| return data; | |
| } | |
| // node_modules/engine.io-client/build/esm/socket.js | |
| var withEventListeners = typeof addEventListener === "function" && typeof removeEventListener === "function"; | |
| var OFFLINE_EVENT_LISTENERS = []; | |
| if (withEventListeners) { | |
| addEventListener("offline", () => { | |
| OFFLINE_EVENT_LISTENERS.forEach((listener) => listener()); | |
| }, false); | |
| } | |
| var SocketWithoutUpgrade = class _SocketWithoutUpgrade extends Emitter { | |
| /** | |
| * Socket constructor. | |
| * | |
| * @param {String|Object} uri - uri or options | |
| * @param {Object} opts - options | |
| */ | |
| constructor(uri, opts) { | |
| super(); | |
| this.binaryType = defaultBinaryType; | |
| this.writeBuffer = []; | |
| this._prevBufferLen = 0; | |
| this._pingInterval = -1; | |
| this._pingTimeout = -1; | |
| this._maxPayload = -1; | |
| this._pingTimeoutTime = Infinity; | |
| if (uri && "object" === typeof uri) { | |
| opts = uri; | |
| uri = null; | |
| } | |
| if (uri) { | |
| const parsedUri = parse(uri); | |
| opts.hostname = parsedUri.host; | |
| opts.secure = parsedUri.protocol === "https" || parsedUri.protocol === "wss"; | |
| opts.port = parsedUri.port; | |
| if (parsedUri.query) | |
| opts.query = parsedUri.query; | |
| } else if (opts.host) { | |
| opts.hostname = parse(opts.host).host; | |
| } | |
| installTimerFunctions(this, opts); | |
| this.secure = null != opts.secure ? opts.secure : typeof location !== "undefined" && "https:" === location.protocol; | |
| if (opts.hostname && !opts.port) { | |
| opts.port = this.secure ? "443" : "80"; | |
| } | |
| this.hostname = opts.hostname || (typeof location !== "undefined" ? location.hostname : "localhost"); | |
| this.port = opts.port || (typeof location !== "undefined" && location.port ? location.port : this.secure ? "443" : "80"); | |
| this.transports = []; | |
| this._transportsByName = {}; | |
| opts.transports.forEach((t) => { | |
| const transportName = t.prototype.name; | |
| this.transports.push(transportName); | |
| this._transportsByName[transportName] = t; | |
| }); | |
| this.opts = Object.assign({ | |
| path: "/engine.io", | |
| agent: false, | |
| withCredentials: false, | |
| upgrade: true, | |
| timestampParam: "t", | |
| rememberUpgrade: false, | |
| addTrailingSlash: true, | |
| rejectUnauthorized: true, | |
| perMessageDeflate: { | |
| threshold: 1024 | |
| }, | |
| transportOptions: {}, | |
| closeOnBeforeunload: false | |
| }, opts); | |
| this.opts.path = this.opts.path.replace(/\/$/, "") + (this.opts.addTrailingSlash ? "/" : ""); | |
| if (typeof this.opts.query === "string") { | |
| this.opts.query = decode2(this.opts.query); | |
| } | |
| if (withEventListeners) { | |
| if (this.opts.closeOnBeforeunload) { | |
| this._beforeunloadEventListener = () => { | |
| if (this.transport) { | |
| this.transport.removeAllListeners(); | |
| this.transport.close(); | |
| } | |
| }; | |
| addEventListener("beforeunload", this._beforeunloadEventListener, false); | |
| } | |
| if (this.hostname !== "localhost") { | |
| this._offlineEventListener = () => { | |
| this._onClose("transport close", { | |
| description: "network connection lost" | |
| }); | |
| }; | |
| OFFLINE_EVENT_LISTENERS.push(this._offlineEventListener); | |
| } | |
| } | |
| if (this.opts.withCredentials) { | |
| this._cookieJar = createCookieJar(); | |
| } | |
| this._open(); | |
| } | |
| /** | |
| * Creates transport of the given type. | |
| * | |
| * @param {String} name - transport name | |
| * @return {Transport} | |
| * @private | |
| */ | |
| createTransport(name) { | |
| const query = Object.assign({}, this.opts.query); | |
| query.EIO = protocol; | |
| query.transport = name; | |
| if (this.id) | |
| query.sid = this.id; | |
| const opts = Object.assign({}, this.opts, { | |
| query, | |
| socket: this, | |
| hostname: this.hostname, | |
| secure: this.secure, | |
| port: this.port | |
| }, this.opts.transportOptions[name]); | |
| return new this._transportsByName[name](opts); | |
| } | |
| /** | |
| * Initializes transport to use and starts probe. | |
| * | |
| * @private | |
| */ | |
| _open() { | |
| if (this.transports.length === 0) { | |
| this.setTimeoutFn(() => { | |
| this.emitReserved("error", "No transports available"); | |
| }, 0); | |
| return; | |
| } | |
| const transportName = this.opts.rememberUpgrade && _SocketWithoutUpgrade.priorWebsocketSuccess && this.transports.indexOf("websocket") !== -1 ? "websocket" : this.transports[0]; | |
| this.readyState = "opening"; | |
| const transport = this.createTransport(transportName); | |
| transport.open(); | |
| this.setTransport(transport); | |
| } | |
| /** | |
| * Sets the current transport. Disables the existing one (if any). | |
| * | |
| * @private | |
| */ | |
| setTransport(transport) { | |
| if (this.transport) { | |
| this.transport.removeAllListeners(); | |
| } | |
| this.transport = transport; | |
| transport.on("drain", this._onDrain.bind(this)).on("packet", this._onPacket.bind(this)).on("error", this._onError.bind(this)).on("close", (reason) => this._onClose("transport close", reason)); | |
| } | |
| /** | |
| * Called when connection is deemed open. | |
| * | |
| * @private | |
| */ | |
| onOpen() { | |
| this.readyState = "open"; | |
| _SocketWithoutUpgrade.priorWebsocketSuccess = "websocket" === this.transport.name; | |
| this.emitReserved("open"); | |
| this.flush(); | |
| } | |
| /** | |
| * Handles a packet. | |
| * | |
| * @private | |
| */ | |
| _onPacket(packet) { | |
| if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { | |
| this.emitReserved("packet", packet); | |
| this.emitReserved("heartbeat"); | |
| switch (packet.type) { | |
| case "open": | |
| this.onHandshake(JSON.parse(packet.data)); | |
| break; | |
| case "ping": | |
| this._sendPacket("pong"); | |
| this.emitReserved("ping"); | |
| this.emitReserved("pong"); | |
| this._resetPingTimeout(); | |
| break; | |
| case "error": | |
| const err = new Error("server error"); | |
| err.code = packet.data; | |
| this._onError(err); | |
| break; | |
| case "message": | |
| this.emitReserved("data", packet.data); | |
| this.emitReserved("message", packet.data); | |
| break; | |
| } | |
| } else { | |
| } | |
| } | |
| /** | |
| * Called upon handshake completion. | |
| * | |
| * @param {Object} data - handshake obj | |
| * @private | |
| */ | |
| onHandshake(data) { | |
| this.emitReserved("handshake", data); | |
| this.id = data.sid; | |
| this.transport.query.sid = data.sid; | |
| this._pingInterval = data.pingInterval; | |
| this._pingTimeout = data.pingTimeout; | |
| this._maxPayload = data.maxPayload; | |
| this.onOpen(); | |
| if ("closed" === this.readyState) | |
| return; | |
| this._resetPingTimeout(); | |
| } | |
| /** | |
| * Sets and resets ping timeout timer based on server pings. | |
| * | |
| * @private | |
| */ | |
| _resetPingTimeout() { | |
| this.clearTimeoutFn(this._pingTimeoutTimer); | |
| const delay = this._pingInterval + this._pingTimeout; | |
| this._pingTimeoutTime = Date.now() + delay; | |
| this._pingTimeoutTimer = this.setTimeoutFn(() => { | |
| this._onClose("ping timeout"); | |
| }, delay); | |
| if (this.opts.autoUnref) { | |
| this._pingTimeoutTimer.unref(); | |
| } | |
| } | |
| /** | |
| * Called on `drain` event | |
| * | |
| * @private | |
| */ | |
| _onDrain() { | |
| this.writeBuffer.splice(0, this._prevBufferLen); | |
| this._prevBufferLen = 0; | |
| if (0 === this.writeBuffer.length) { | |
| this.emitReserved("drain"); | |
| } else { | |
| this.flush(); | |
| } | |
| } | |
| /** | |
| * Flush write buffers. | |
| * | |
| * @private | |
| */ | |
| flush() { | |
| if ("closed" !== this.readyState && this.transport.writable && !this.upgrading && this.writeBuffer.length) { | |
| const packets = this._getWritablePackets(); | |
| this.transport.send(packets); | |
| this._prevBufferLen = packets.length; | |
| this.emitReserved("flush"); | |
| } | |
| } | |
| /** | |
| * Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP | |
| * long-polling) | |
| * | |
| * @private | |
| */ | |
| _getWritablePackets() { | |
| const shouldCheckPayloadSize = this._maxPayload && this.transport.name === "polling" && this.writeBuffer.length > 1; | |
| if (!shouldCheckPayloadSize) { | |
| return this.writeBuffer; | |
| } | |
| let payloadSize = 1; | |
| for (let i = 0; i < this.writeBuffer.length; i++) { | |
| const data = this.writeBuffer[i].data; | |
| if (data) { | |
| payloadSize += byteLength(data); | |
| } | |
| if (i > 0 && payloadSize > this._maxPayload) { | |
| return this.writeBuffer.slice(0, i); | |
| } | |
| payloadSize += 2; | |
| } | |
| return this.writeBuffer; | |
| } | |
| /** | |
| * Checks whether the heartbeat timer has expired but the socket has not yet been notified. | |
| * | |
| * Note: this method is private for now because it does not really fit the WebSocket API, but if we put it in the | |
| * `write()` method then the message would not be buffered by the Socket.IO client. | |
| * | |
| * @return {boolean} | |
| * @private | |
| */ | |
| /* private */ | |
| _hasPingExpired() { | |
| if (!this._pingTimeoutTime) | |
| return true; | |
| const hasExpired = Date.now() > this._pingTimeoutTime; | |
| if (hasExpired) { | |
| this._pingTimeoutTime = 0; | |
| nextTick(() => { | |
| this._onClose("ping timeout"); | |
| }, this.setTimeoutFn); | |
| } | |
| return hasExpired; | |
| } | |
| /** | |
| * Sends a message. | |
| * | |
| * @param {String} msg - message. | |
| * @param {Object} options. | |
| * @param {Function} fn - callback function. | |
| * @return {Socket} for chaining. | |
| */ | |
| write(msg, options, fn) { | |
| this._sendPacket("message", msg, options, fn); | |
| return this; | |
| } | |
| /** | |
| * Sends a message. Alias of {@link Socket#write}. | |
| * | |
| * @param {String} msg - message. | |
| * @param {Object} options. | |
| * @param {Function} fn - callback function. | |
| * @return {Socket} for chaining. | |
| */ | |
| send(msg, options, fn) { | |
| this._sendPacket("message", msg, options, fn); | |
| return this; | |
| } | |
| /** | |
| * Sends a packet. | |
| * | |
| * @param {String} type: packet type. | |
| * @param {String} data. | |
| * @param {Object} options. | |
| * @param {Function} fn - callback function. | |
| * @private | |
| */ | |
| _sendPacket(type, data, options, fn) { | |
| if ("function" === typeof data) { | |
| fn = data; | |
| data = void 0; | |
| } | |
| if ("function" === typeof options) { | |
| fn = options; | |
| options = null; | |
| } | |
| if ("closing" === this.readyState || "closed" === this.readyState) { | |
| return; | |
| } | |
| options = options || {}; | |
| options.compress = false !== options.compress; | |
| const packet = { | |
| type, | |
| data, | |
| options | |
| }; | |
| this.emitReserved("packetCreate", packet); | |
| this.writeBuffer.push(packet); | |
| if (fn) | |
| this.once("flush", fn); | |
| this.flush(); | |
| } | |
| /** | |
| * Closes the connection. | |
| */ | |
| close() { | |
| const close = () => { | |
| this._onClose("forced close"); | |
| this.transport.close(); | |
| }; | |
| const cleanupAndClose = () => { | |
| this.off("upgrade", cleanupAndClose); | |
| this.off("upgradeError", cleanupAndClose); | |
| close(); | |
| }; | |
| const waitForUpgrade = () => { | |
| this.once("upgrade", cleanupAndClose); | |
| this.once("upgradeError", cleanupAndClose); | |
| }; | |
| if ("opening" === this.readyState || "open" === this.readyState) { | |
| this.readyState = "closing"; | |
| if (this.writeBuffer.length) { | |
| this.once("drain", () => { | |
| if (this.upgrading) { | |
| waitForUpgrade(); | |
| } else { | |
| close(); | |
| } | |
| }); | |
| } else if (this.upgrading) { | |
| waitForUpgrade(); | |
| } else { | |
| close(); | |
| } | |
| } | |
| return this; | |
| } | |
| /** | |
| * Called upon transport error | |
| * | |
| * @private | |
| */ | |
| _onError(err) { | |
| _SocketWithoutUpgrade.priorWebsocketSuccess = false; | |
| if (this.opts.tryAllTransports && this.transports.length > 1 && this.readyState === "opening") { | |
| this.transports.shift(); | |
| return this._open(); | |
| } | |
| this.emitReserved("error", err); | |
| this._onClose("transport error", err); | |
| } | |
| /** | |
| * Called upon transport close. | |
| * | |
| * @private | |
| */ | |
| _onClose(reason, description) { | |
| if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { | |
| this.clearTimeoutFn(this._pingTimeoutTimer); | |
| this.transport.removeAllListeners("close"); | |
| this.transport.close(); | |
| this.transport.removeAllListeners(); | |
| if (withEventListeners) { | |
| if (this._beforeunloadEventListener) { | |
| removeEventListener("beforeunload", this._beforeunloadEventListener, false); | |
| } | |
| if (this._offlineEventListener) { | |
| const i = OFFLINE_EVENT_LISTENERS.indexOf(this._offlineEventListener); | |
| if (i !== -1) { | |
| OFFLINE_EVENT_LISTENERS.splice(i, 1); | |
| } | |
| } | |
| } | |
| this.readyState = "closed"; | |
| this.id = null; | |
| this.emitReserved("close", reason, description); | |
| this.writeBuffer = []; | |
| this._prevBufferLen = 0; | |
| } | |
| } | |
| }; | |
| SocketWithoutUpgrade.protocol = protocol; | |
| var SocketWithUpgrade = class extends SocketWithoutUpgrade { | |
| constructor() { | |
| super(...arguments); | |
| this._upgrades = []; | |
| } | |
| onOpen() { | |
| super.onOpen(); | |
| if ("open" === this.readyState && this.opts.upgrade) { | |
| for (let i = 0; i < this._upgrades.length; i++) { | |
| this._probe(this._upgrades[i]); | |
| } | |
| } | |
| } | |
| /** | |
| * Probes a transport. | |
| * | |
| * @param {String} name - transport name | |
| * @private | |
| */ | |
| _probe(name) { | |
| let transport = this.createTransport(name); | |
| let failed = false; | |
| SocketWithoutUpgrade.priorWebsocketSuccess = false; | |
| const onTransportOpen = () => { | |
| if (failed) | |
| return; | |
| transport.send([{ type: "ping", data: "probe" }]); | |
| transport.once("packet", (msg) => { | |
| if (failed) | |
| return; | |
| if ("pong" === msg.type && "probe" === msg.data) { | |
| this.upgrading = true; | |
| this.emitReserved("upgrading", transport); | |
| if (!transport) | |
| return; | |
| SocketWithoutUpgrade.priorWebsocketSuccess = "websocket" === transport.name; | |
| this.transport.pause(() => { | |
| if (failed) | |
| return; | |
| if ("closed" === this.readyState) | |
| return; | |
| cleanup(); | |
| this.setTransport(transport); | |
| transport.send([{ type: "upgrade" }]); | |
| this.emitReserved("upgrade", transport); | |
| transport = null; | |
| this.upgrading = false; | |
| this.flush(); | |
| }); | |
| } else { | |
| const err = new Error("probe error"); | |
| err.transport = transport.name; | |
| this.emitReserved("upgradeError", err); | |
| } | |
| }); | |
| }; | |
| function freezeTransport() { | |
| if (failed) | |
| return; | |
| failed = true; | |
| cleanup(); | |
| transport.close(); | |
| transport = null; | |
| } | |
| const onerror = (err) => { | |
| const error = new Error("probe error: " + err); | |
| error.transport = transport.name; | |
| freezeTransport(); | |
| this.emitReserved("upgradeError", error); | |
| }; | |
| function onTransportClose() { | |
| onerror("transport closed"); | |
| } | |
| function onclose() { | |
| onerror("socket closed"); | |
| } | |
| function onupgrade(to) { | |
| if (transport && to.name !== transport.name) { | |
| freezeTransport(); | |
| } | |
| } | |
| const cleanup = () => { | |
| transport.removeListener("open", onTransportOpen); | |
| transport.removeListener("error", onerror); | |
| transport.removeListener("close", onTransportClose); | |
| this.off("close", onclose); | |
| this.off("upgrading", onupgrade); | |
| }; | |
| transport.once("open", onTransportOpen); | |
| transport.once("error", onerror); | |
| transport.once("close", onTransportClose); | |
| this.once("close", onclose); | |
| this.once("upgrading", onupgrade); | |
| if (this._upgrades.indexOf("webtransport") !== -1 && name !== "webtransport") { | |
| this.setTimeoutFn(() => { | |
| if (!failed) { | |
| transport.open(); | |
| } | |
| }, 200); | |
| } else { | |
| transport.open(); | |
| } | |
| } | |
| onHandshake(data) { | |
| this._upgrades = this._filterUpgrades(data.upgrades); | |
| super.onHandshake(data); | |
| } | |
| /** | |
| * Filters upgrades, returning only those matching client transports. | |
| * | |
| * @param {Array} upgrades - server upgrades | |
| * @private | |
| */ | |
| _filterUpgrades(upgrades) { | |
| const filteredUpgrades = []; | |
| for (let i = 0; i < upgrades.length; i++) { | |
| if (~this.transports.indexOf(upgrades[i])) | |
| filteredUpgrades.push(upgrades[i]); | |
| } | |
| return filteredUpgrades; | |
| } | |
| }; | |
| var Socket = class extends SocketWithUpgrade { | |
| constructor(uri, opts = {}) { | |
| const o = typeof uri === "object" ? uri : opts; | |
| if (!o.transports || o.transports && typeof o.transports[0] === "string") { | |
| o.transports = (o.transports || ["polling", "websocket", "webtransport"]).map((transportName) => transports[transportName]).filter((t) => !!t); | |
| } | |
| super(uri, o); | |
| } | |
| }; | |
| // node_modules/engine.io-client/build/esm/index.js | |
| var protocol2 = Socket.protocol; | |
| // node_modules/socket.io-client/build/esm/url.js | |
| function url(uri, path = "", loc) { | |
| let obj = uri; | |
| loc = loc || typeof location !== "undefined" && location; | |
| if (null == uri) | |
| uri = loc.protocol + "//" + loc.host; | |
| if (typeof uri === "string") { | |
| if ("/" === uri.charAt(0)) { | |
| if ("/" === uri.charAt(1)) { | |
| uri = loc.protocol + uri; | |
| } else { | |
| uri = loc.host + uri; | |
| } | |
| } | |
| if (!/^(https?|wss?):\/\//.test(uri)) { | |
| if ("undefined" !== typeof loc) { | |
| uri = loc.protocol + "//" + uri; | |
| } else { | |
| uri = "https://" + uri; | |
| } | |
| } | |
| obj = parse(uri); | |
| } | |
| if (!obj.port) { | |
| if (/^(http|ws)$/.test(obj.protocol)) { | |
| obj.port = "80"; | |
| } else if (/^(http|ws)s$/.test(obj.protocol)) { | |
| obj.port = "443"; | |
| } | |
| } | |
| obj.path = obj.path || "/"; | |
| const ipv6 = obj.host.indexOf(":") !== -1; | |
| const host = ipv6 ? "[" + obj.host + "]" : obj.host; | |
| obj.id = obj.protocol + "://" + host + ":" + obj.port + path; | |
| obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port); | |
| return obj; | |
| } | |
| // node_modules/socket.io-parser/build/esm/index.js | |
| var esm_exports = {}; | |
| __export(esm_exports, { | |
| Decoder: () => Decoder, | |
| Encoder: () => Encoder, | |
| PacketType: () => PacketType, | |
| protocol: () => protocol3 | |
| }); | |
| // node_modules/socket.io-parser/build/esm/is-binary.js | |
| var withNativeArrayBuffer3 = typeof ArrayBuffer === "function"; | |
| var isView2 = (obj) => { | |
| return typeof ArrayBuffer.isView === "function" ? ArrayBuffer.isView(obj) : obj.buffer instanceof ArrayBuffer; | |
| }; | |
| var toString = Object.prototype.toString; | |
| var withNativeBlob2 = typeof Blob === "function" || typeof Blob !== "undefined" && toString.call(Blob) === "[object BlobConstructor]"; | |
| var withNativeFile = typeof File === "function" || typeof File !== "undefined" && toString.call(File) === "[object FileConstructor]"; | |
| function isBinary(obj) { | |
| return withNativeArrayBuffer3 && (obj instanceof ArrayBuffer || isView2(obj)) || withNativeBlob2 && obj instanceof Blob || withNativeFile && obj instanceof File; | |
| } | |
| function hasBinary(obj, toJSON) { | |
| if (!obj || typeof obj !== "object") { | |
| return false; | |
| } | |
| if (Array.isArray(obj)) { | |
| for (let i = 0, l = obj.length; i < l; i++) { | |
| if (hasBinary(obj[i])) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| if (isBinary(obj)) { | |
| return true; | |
| } | |
| if (obj.toJSON && typeof obj.toJSON === "function" && arguments.length === 1) { | |
| return hasBinary(obj.toJSON(), true); | |
| } | |
| for (const key in obj) { | |
| if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| // node_modules/socket.io-parser/build/esm/binary.js | |
| function deconstructPacket(packet) { | |
| const buffers = []; | |
| const packetData = packet.data; | |
| const pack = packet; | |
| pack.data = _deconstructPacket(packetData, buffers); | |
| pack.attachments = buffers.length; | |
| return { packet: pack, buffers }; | |
| } | |
| function _deconstructPacket(data, buffers) { | |
| if (!data) | |
| return data; | |
| if (isBinary(data)) { | |
| const placeholder = { _placeholder: true, num: buffers.length }; | |
| buffers.push(data); | |
| return placeholder; | |
| } else if (Array.isArray(data)) { | |
| const newData = new Array(data.length); | |
| for (let i = 0; i < data.length; i++) { | |
| newData[i] = _deconstructPacket(data[i], buffers); | |
| } | |
| return newData; | |
| } else if (typeof data === "object" && !(data instanceof Date)) { | |
| const newData = {}; | |
| for (const key in data) { | |
| if (Object.prototype.hasOwnProperty.call(data, key)) { | |
| newData[key] = _deconstructPacket(data[key], buffers); | |
| } | |
| } | |
| return newData; | |
| } | |
| return data; | |
| } | |
| function reconstructPacket(packet, buffers) { | |
| packet.data = _reconstructPacket(packet.data, buffers); | |
| delete packet.attachments; | |
| return packet; | |
| } | |
| function _reconstructPacket(data, buffers) { | |
| if (!data) | |
| return data; | |
| if (data && data._placeholder === true) { | |
| const isIndexValid = typeof data.num === "number" && data.num >= 0 && data.num < buffers.length; | |
| if (isIndexValid) { | |
| return buffers[data.num]; | |
| } else { | |
| throw new Error("illegal attachments"); | |
| } | |
| } else if (Array.isArray(data)) { | |
| for (let i = 0; i < data.length; i++) { | |
| data[i] = _reconstructPacket(data[i], buffers); | |
| } | |
| } else if (typeof data === "object") { | |
| for (const key in data) { | |
| if (Object.prototype.hasOwnProperty.call(data, key)) { | |
| data[key] = _reconstructPacket(data[key], buffers); | |
| } | |
| } | |
| } | |
| return data; | |
| } | |
| // node_modules/socket.io-parser/build/esm/index.js | |
| var RESERVED_EVENTS = [ | |
| "connect", | |
| "connect_error", | |
| "disconnect", | |
| "disconnecting", | |
| "newListener", | |
| "removeListener" | |
| // used by the Node.js EventEmitter | |
| ]; | |
| var protocol3 = 5; | |
| var PacketType; | |
| (function(PacketType2) { | |
| PacketType2[PacketType2["CONNECT"] = 0] = "CONNECT"; | |
| PacketType2[PacketType2["DISCONNECT"] = 1] = "DISCONNECT"; | |
| PacketType2[PacketType2["EVENT"] = 2] = "EVENT"; | |
| PacketType2[PacketType2["ACK"] = 3] = "ACK"; | |
| PacketType2[PacketType2["CONNECT_ERROR"] = 4] = "CONNECT_ERROR"; | |
| PacketType2[PacketType2["BINARY_EVENT"] = 5] = "BINARY_EVENT"; | |
| PacketType2[PacketType2["BINARY_ACK"] = 6] = "BINARY_ACK"; | |
| })(PacketType || (PacketType = {})); | |
| var Encoder = class { | |
| /** | |
| * Encoder constructor | |
| * | |
| * @param {function} replacer - custom replacer to pass down to JSON.parse | |
| */ | |
| constructor(replacer) { | |
| this.replacer = replacer; | |
| } | |
| /** | |
| * Encode a packet as a single string if non-binary, or as a | |
| * buffer sequence, depending on packet type. | |
| * | |
| * @param {Object} obj - packet object | |
| */ | |
| encode(obj) { | |
| if (obj.type === PacketType.EVENT || obj.type === PacketType.ACK) { | |
| if (hasBinary(obj)) { | |
| return this.encodeAsBinary({ | |
| type: obj.type === PacketType.EVENT ? PacketType.BINARY_EVENT : PacketType.BINARY_ACK, | |
| nsp: obj.nsp, | |
| data: obj.data, | |
| id: obj.id | |
| }); | |
| } | |
| } | |
| return [this.encodeAsString(obj)]; | |
| } | |
| /** | |
| * Encode packet as string. | |
| */ | |
| encodeAsString(obj) { | |
| let str = "" + obj.type; | |
| if (obj.type === PacketType.BINARY_EVENT || obj.type === PacketType.BINARY_ACK) { | |
| str += obj.attachments + "-"; | |
| } | |
| if (obj.nsp && "/" !== obj.nsp) { | |
| str += obj.nsp + ","; | |
| } | |
| if (null != obj.id) { | |
| str += obj.id; | |
| } | |
| if (null != obj.data) { | |
| str += JSON.stringify(obj.data, this.replacer); | |
| } | |
| return str; | |
| } | |
| /** | |
| * Encode packet as 'buffer sequence' by removing blobs, and | |
| * deconstructing packet into object with placeholders and | |
| * a list of buffers. | |
| */ | |
| encodeAsBinary(obj) { | |
| const deconstruction = deconstructPacket(obj); | |
| const pack = this.encodeAsString(deconstruction.packet); | |
| const buffers = deconstruction.buffers; | |
| buffers.unshift(pack); | |
| return buffers; | |
| } | |
| }; | |
| function isObject(value2) { | |
| return Object.prototype.toString.call(value2) === "[object Object]"; | |
| } | |
| var Decoder = class _Decoder extends Emitter { | |
| /** | |
| * Decoder constructor | |
| * | |
| * @param {function} reviver - custom reviver to pass down to JSON.stringify | |
| */ | |
| constructor(reviver) { | |
| super(); | |
| this.reviver = reviver; | |
| } | |
| /** | |
| * Decodes an encoded packet string into packet JSON. | |
| * | |
| * @param {String} obj - encoded packet | |
| */ | |
| add(obj) { | |
| let packet; | |
| if (typeof obj === "string") { | |
| if (this.reconstructor) { | |
| throw new Error("got plaintext data when reconstructing a packet"); | |
| } | |
| packet = this.decodeString(obj); | |
| const isBinaryEvent = packet.type === PacketType.BINARY_EVENT; | |
| if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) { | |
| packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK; | |
| this.reconstructor = new BinaryReconstructor(packet); | |
| if (packet.attachments === 0) { | |
| super.emitReserved("decoded", packet); | |
| } | |
| } else { | |
| super.emitReserved("decoded", packet); | |
| } | |
| } else if (isBinary(obj) || obj.base64) { | |
| if (!this.reconstructor) { | |
| throw new Error("got binary data when not reconstructing a packet"); | |
| } else { | |
| packet = this.reconstructor.takeBinaryData(obj); | |
| if (packet) { | |
| this.reconstructor = null; | |
| super.emitReserved("decoded", packet); | |
| } | |
| } | |
| } else { | |
| throw new Error("Unknown type: " + obj); | |
| } | |
| } | |
| /** | |
| * Decode a packet String (JSON data) | |
| * | |
| * @param {String} str | |
| * @return {Object} packet | |
| */ | |
| decodeString(str) { | |
| let i = 0; | |
| const p = { | |
| type: Number(str.charAt(0)) | |
| }; | |
| if (PacketType[p.type] === void 0) { | |
| throw new Error("unknown packet type " + p.type); | |
| } | |
| if (p.type === PacketType.BINARY_EVENT || p.type === PacketType.BINARY_ACK) { | |
| const start = i + 1; | |
| while (str.charAt(++i) !== "-" && i != str.length) { | |
| } | |
| const buf = str.substring(start, i); | |
| if (buf != Number(buf) || str.charAt(i) !== "-") { | |
| throw new Error("Illegal attachments"); | |
| } | |
| p.attachments = Number(buf); | |
| } | |
| if ("/" === str.charAt(i + 1)) { | |
| const start = i + 1; | |
| while (++i) { | |
| const c = str.charAt(i); | |
| if ("," === c) | |
| break; | |
| if (i === str.length) | |
| break; | |
| } | |
| p.nsp = str.substring(start, i); | |
| } else { | |
| p.nsp = "/"; | |
| } | |
| const next = str.charAt(i + 1); | |
| if ("" !== next && Number(next) == next) { | |
| const start = i + 1; | |
| while (++i) { | |
| const c = str.charAt(i); | |
| if (null == c || Number(c) != c) { | |
| --i; | |
| break; | |
| } | |
| if (i === str.length) | |
| break; | |
| } | |
| p.id = Number(str.substring(start, i + 1)); | |
| } | |
| if (str.charAt(++i)) { | |
| const payload = this.tryParse(str.substr(i)); | |
| if (_Decoder.isPayloadValid(p.type, payload)) { | |
| p.data = payload; | |
| } else { | |
| throw new Error("invalid payload"); | |
| } | |
| } | |
| return p; | |
| } | |
| tryParse(str) { | |
| try { | |
| return JSON.parse(str, this.reviver); | |
| } catch (e) { | |
| return false; | |
| } | |
| } | |
| static isPayloadValid(type, payload) { | |
| switch (type) { | |
| case PacketType.CONNECT: | |
| return isObject(payload); | |
| case PacketType.DISCONNECT: | |
| return payload === void 0; | |
| case PacketType.CONNECT_ERROR: | |
| return typeof payload === "string" || isObject(payload); | |
| case PacketType.EVENT: | |
| case PacketType.BINARY_EVENT: | |
| return Array.isArray(payload) && (typeof payload[0] === "number" || typeof payload[0] === "string" && RESERVED_EVENTS.indexOf(payload[0]) === -1); | |
| case PacketType.ACK: | |
| case PacketType.BINARY_ACK: | |
| return Array.isArray(payload); | |
| } | |
| } | |
| /** | |
| * Deallocates a parser's resources | |
| */ | |
| destroy() { | |
| if (this.reconstructor) { | |
| this.reconstructor.finishedReconstruction(); | |
| this.reconstructor = null; | |
| } | |
| } | |
| }; | |
| var BinaryReconstructor = class { | |
| constructor(packet) { | |
| this.packet = packet; | |
| this.buffers = []; | |
| this.reconPack = packet; | |
| } | |
| /** | |
| * Method to be called when binary data received from connection | |
| * after a BINARY_EVENT packet. | |
| * | |
| * @param {Buffer | ArrayBuffer} binData - the raw binary data received | |
| * @return {null | Object} returns null if more binary data is expected or | |
| * a reconstructed packet object if all buffers have been received. | |
| */ | |
| takeBinaryData(binData) { | |
| this.buffers.push(binData); | |
| if (this.buffers.length === this.reconPack.attachments) { | |
| const packet = reconstructPacket(this.reconPack, this.buffers); | |
| this.finishedReconstruction(); | |
| return packet; | |
| } | |
| return null; | |
| } | |
| /** | |
| * Cleans up binary packet reconstruction variables. | |
| */ | |
| finishedReconstruction() { | |
| this.reconPack = null; | |
| this.buffers = []; | |
| } | |
| }; | |
| // node_modules/socket.io-client/build/esm/on.js | |
| function on(obj, ev, fn) { | |
| obj.on(ev, fn); | |
| return function subDestroy() { | |
| obj.off(ev, fn); | |
| }; | |
| } | |
| // node_modules/socket.io-client/build/esm/socket.js | |
| var RESERVED_EVENTS2 = Object.freeze({ | |
| connect: 1, | |
| connect_error: 1, | |
| disconnect: 1, | |
| disconnecting: 1, | |
| // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener | |
| newListener: 1, | |
| removeListener: 1 | |
| }); | |
| var Socket2 = class extends Emitter { | |
| /** | |
| * `Socket` constructor. | |
| */ | |
| constructor(io, nsp, opts) { | |
| super(); | |
| this.connected = false; | |
| this.recovered = false; | |
| this.receiveBuffer = []; | |
| this.sendBuffer = []; | |
| this._queue = []; | |
| this._queueSeq = 0; | |
| this.ids = 0; | |
| this.acks = {}; | |
| this.flags = {}; | |
| this.io = io; | |
| this.nsp = nsp; | |
| if (opts && opts.auth) { | |
| this.auth = opts.auth; | |
| } | |
| this._opts = Object.assign({}, opts); | |
| if (this.io._autoConnect) | |
| this.open(); | |
| } | |
| /** | |
| * Whether the socket is currently disconnected | |
| * | |
| * @example | |
| * const socket = io(); | |
| * | |
| * socket.on("connect", () => { | |
| * console.log(socket.disconnected); // false | |
| * }); | |
| * | |
| * socket.on("disconnect", () => { | |
| * console.log(socket.disconnected); // true | |
| * }); | |
| */ | |
| get disconnected() { | |
| return !this.connected; | |
| } | |
| /** | |
| * Subscribe to open, close and packet events | |
| * | |
| * @private | |
| */ | |
| subEvents() { | |
| if (this.subs) | |
| return; | |
| const io = this.io; | |
| this.subs = [ | |
| on(io, "open", this.onopen.bind(this)), | |
| on(io, "packet", this.onpacket.bind(this)), | |
| on(io, "error", this.onerror.bind(this)), | |
| on(io, "close", this.onclose.bind(this)) | |
| ]; | |
| } | |
| /** | |
| * Whether the Socket will try to reconnect when its Manager connects or reconnects. | |
| * | |
| * @example | |
| * const socket = io(); | |
| * | |
| * console.log(socket.active); // true | |
| * | |
| * socket.on("disconnect", (reason) => { | |
| * if (reason === "io server disconnect") { | |
| * // the disconnection was initiated by the server, you need to manually reconnect | |
| * console.log(socket.active); // false | |
| * } | |
| * // else the socket will automatically try to reconnect | |
| * console.log(socket.active); // true | |
| * }); | |
| */ | |
| get active() { | |
| return !!this.subs; | |
| } | |
| /** | |
| * "Opens" the socket. | |
| * | |
| * @example | |
| * const socket = io({ | |
| * autoConnect: false | |
| * }); | |
| * | |
| * socket.connect(); | |
| */ | |
| connect() { | |
| if (this.connected) | |
| return this; | |
| this.subEvents(); | |
| if (!this.io["_reconnecting"]) | |
| this.io.open(); | |
| if ("open" === this.io._readyState) | |
| this.onopen(); | |
| return this; | |
| } | |
| /** | |
| * Alias for {@link connect()}. | |
| */ | |
| open() { | |
| return this.connect(); | |
| } | |
| /** | |
| * Sends a `message` event. | |
| * | |
| * This method mimics the WebSocket.send() method. | |
| * | |
| * @see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send | |
| * | |
| * @example | |
| * socket.send("hello"); | |
| * | |
| * // this is equivalent to | |
| * socket.emit("message", "hello"); | |
| * | |
| * @return self | |
| */ | |
| send(...args) { | |
| args.unshift("message"); | |
| this.emit.apply(this, args); | |
| return this; | |
| } | |
| /** | |
| * Override `emit`. | |
| * If the event is in `events`, it's emitted normally. | |
| * | |
| * @example | |
| * socket.emit("hello", "world"); | |
| * | |
| * // all serializable datastructures are supported (no need to call JSON.stringify) | |
| * socket.emit("hello", 1, "2", { 3: ["4"], 5: Uint8Array.from([6]) }); | |
| * | |
| * // with an acknowledgement from the server | |
| * socket.emit("hello", "world", (val) => { | |
| * // ... | |
| * }); | |
| * | |
| * @return self | |
| */ | |
| emit(ev, ...args) { | |
| var _a, _b, _c; | |
| if (RESERVED_EVENTS2.hasOwnProperty(ev)) { | |
| throw new Error('"' + ev.toString() + '" is a reserved event name'); | |
| } | |
| args.unshift(ev); | |
| if (this._opts.retries && !this.flags.fromQueue && !this.flags.volatile) { | |
| this._addToQueue(args); | |
| return this; | |
| } | |
| const packet = { | |
| type: PacketType.EVENT, | |
| data: args | |
| }; | |
| packet.options = {}; | |
| packet.options.compress = this.flags.compress !== false; | |
| if ("function" === typeof args[args.length - 1]) { | |
| const id = this.ids++; | |
| const ack = args.pop(); | |
| this._registerAckCallback(id, ack); | |
| packet.id = id; | |
| } | |
| const isTransportWritable = (_b = (_a = this.io.engine) === null || _a === void 0 ? void 0 : _a.transport) === null || _b === void 0 ? void 0 : _b.writable; | |
| const isConnected = this.connected && !((_c = this.io.engine) === null || _c === void 0 ? void 0 : _c._hasPingExpired()); | |
| const discardPacket = this.flags.volatile && !isTransportWritable; | |
| if (discardPacket) { | |
| } else if (isConnected) { | |
| this.notifyOutgoingListeners(packet); | |
| this.packet(packet); | |
| } else { | |
| this.sendBuffer.push(packet); | |
| } | |
| this.flags = {}; | |
| return this; | |
| } | |
| /** | |
| * @private | |
| */ | |
| _registerAckCallback(id, ack) { | |
| var _a; | |
| const timeout = (_a = this.flags.timeout) !== null && _a !== void 0 ? _a : this._opts.ackTimeout; | |
| if (timeout === void 0) { | |
| this.acks[id] = ack; | |
| return; | |
| } | |
| const timer = this.io.setTimeoutFn(() => { | |
| delete this.acks[id]; | |
| for (let i = 0; i < this.sendBuffer.length; i++) { | |
| if (this.sendBuffer[i].id === id) { | |
| this.sendBuffer.splice(i, 1); | |
| } | |
| } | |
| ack.call(this, new Error("operation has timed out")); | |
| }, timeout); | |
| const fn = (...args) => { | |
| this.io.clearTimeoutFn(timer); | |
| ack.apply(this, args); | |
| }; | |
| fn.withError = true; | |
| this.acks[id] = fn; | |
| } | |
| /** | |
| * Emits an event and waits for an acknowledgement | |
| * | |
| * @example | |
| * // without timeout | |
| * const response = await socket.emitWithAck("hello", "world"); | |
| * | |
| * // with a specific timeout | |
| * try { | |
| * const response = await socket.timeout(1000).emitWithAck("hello", "world"); | |
| * } catch (err) { | |
| * // the server did not acknowledge the event in the given delay | |
| * } | |
| * | |
| * @return a Promise that will be fulfilled when the server acknowledges the event | |
| */ | |
| emitWithAck(ev, ...args) { | |
| return new Promise((resolve, reject) => { | |
| const fn = (arg1, arg2) => { | |
| return arg1 ? reject(arg1) : resolve(arg2); | |
| }; | |
| fn.withError = true; | |
| args.push(fn); | |
| this.emit(ev, ...args); | |
| }); | |
| } | |
| /** | |
| * Add the packet to the queue. | |
| * @param args | |
| * @private | |
| */ | |
| _addToQueue(args) { | |
| let ack; | |
| if (typeof args[args.length - 1] === "function") { | |
| ack = args.pop(); | |
| } | |
| const packet = { | |
| id: this._queueSeq++, | |
| tryCount: 0, | |
| pending: false, | |
| args, | |
| flags: Object.assign({ fromQueue: true }, this.flags) | |
| }; | |
| args.push((err, ...responseArgs) => { | |
| if (packet !== this._queue[0]) { | |
| return; | |
| } | |
| const hasError = err !== null; | |
| if (hasError) { | |
| if (packet.tryCount > this._opts.retries) { | |
| this._queue.shift(); | |
| if (ack) { | |
| ack(err); | |
| } | |
| } | |
| } else { | |
| this._queue.shift(); | |
| if (ack) { | |
| ack(null, ...responseArgs); | |
| } | |
| } | |
| packet.pending = false; | |
| return this._drainQueue(); | |
| }); | |
| this._queue.push(packet); | |
| this._drainQueue(); | |
| } | |
| /** | |
| * Send the first packet of the queue, and wait for an acknowledgement from the server. | |
| * @param force - whether to resend a packet that has not been acknowledged yet | |
| * | |
| * @private | |
| */ | |
| _drainQueue(force = false) { | |
| if (!this.connected || this._queue.length === 0) { | |
| return; | |
| } | |
| const packet = this._queue[0]; | |
| if (packet.pending && !force) { | |
| return; | |
| } | |
| packet.pending = true; | |
| packet.tryCount++; | |
| this.flags = packet.flags; | |
| this.emit.apply(this, packet.args); | |
| } | |
| /** | |
| * Sends a packet. | |
| * | |
| * @param packet | |
| * @private | |
| */ | |
| packet(packet) { | |
| packet.nsp = this.nsp; | |
| this.io._packet(packet); | |
| } | |
| /** | |
| * Called upon engine `open`. | |
| * | |
| * @private | |
| */ | |
| onopen() { | |
| if (typeof this.auth == "function") { | |
| this.auth((data) => { | |
| this._sendConnectPacket(data); | |
| }); | |
| } else { | |
| this._sendConnectPacket(this.auth); | |
| } | |
| } | |
| /** | |
| * Sends a CONNECT packet to initiate the Socket.IO session. | |
| * | |
| * @param data | |
| * @private | |
| */ | |
| _sendConnectPacket(data) { | |
| this.packet({ | |
| type: PacketType.CONNECT, | |
| data: this._pid ? Object.assign({ pid: this._pid, offset: this._lastOffset }, data) : data | |
| }); | |
| } | |
| /** | |
| * Called upon engine or manager `error`. | |
| * | |
| * @param err | |
| * @private | |
| */ | |
| onerror(err) { | |
| if (!this.connected) { | |
| this.emitReserved("connect_error", err); | |
| } | |
| } | |
| /** | |
| * Called upon engine `close`. | |
| * | |
| * @param reason | |
| * @param description | |
| * @private | |
| */ | |
| onclose(reason, description) { | |
| this.connected = false; | |
| delete this.id; | |
| this.emitReserved("disconnect", reason, description); | |
| this._clearAcks(); | |
| } | |
| /** | |
| * Clears the acknowledgement handlers upon disconnection, since the client will never receive an acknowledgement from | |
| * the server. | |
| * | |
| * @private | |
| */ | |
| _clearAcks() { | |
| Object.keys(this.acks).forEach((id) => { | |
| const isBuffered = this.sendBuffer.some((packet) => String(packet.id) === id); | |
| if (!isBuffered) { | |
| const ack = this.acks[id]; | |
| delete this.acks[id]; | |
| if (ack.withError) { | |
| ack.call(this, new Error("socket has been disconnected")); | |
| } | |
| } | |
| }); | |
| } | |
| /** | |
| * Called with socket packet. | |
| * | |
| * @param packet | |
| * @private | |
| */ | |
| onpacket(packet) { | |
| const sameNamespace = packet.nsp === this.nsp; | |
| if (!sameNamespace) | |
| return; | |
| switch (packet.type) { | |
| case PacketType.CONNECT: | |
| if (packet.data && packet.data.sid) { | |
| this.onconnect(packet.data.sid, packet.data.pid); | |
| } else { | |
| this.emitReserved("connect_error", new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)")); | |
| } | |
| break; | |
| case PacketType.EVENT: | |
| case PacketType.BINARY_EVENT: | |
| this.onevent(packet); | |
| break; | |
| case PacketType.ACK: | |
| case PacketType.BINARY_ACK: | |
| this.onack(packet); | |
| break; | |
| case PacketType.DISCONNECT: | |
| this.ondisconnect(); | |
| break; | |
| case PacketType.CONNECT_ERROR: | |
| this.destroy(); | |
| const err = new Error(packet.data.message); | |
| err.data = packet.data.data; | |
| this.emitReserved("connect_error", err); | |
| break; | |
| } | |
| } | |
| /** | |
| * Called upon a server event. | |
| * | |
| * @param packet | |
| * @private | |
| */ | |
| onevent(packet) { | |
| const args = packet.data || []; | |
| if (null != packet.id) { | |
| args.push(this.ack(packet.id)); | |
| } | |
| if (this.connected) { | |
| this.emitEvent(args); | |
| } else { | |
| this.receiveBuffer.push(Object.freeze(args)); | |
| } | |
| } | |
| emitEvent(args) { | |
| if (this._anyListeners && this._anyListeners.length) { | |
| const listeners = this._anyListeners.slice(); | |
| for (const listener of listeners) { | |
| listener.apply(this, args); | |
| } | |
| } | |
| super.emit.apply(this, args); | |
| if (this._pid && args.length && typeof args[args.length - 1] === "string") { | |
| this._lastOffset = args[args.length - 1]; | |
| } | |
| } | |
| /** | |
| * Produces an ack callback to emit with an event. | |
| * | |
| * @private | |
| */ | |
| ack(id) { | |
| const self2 = this; | |
| let sent = false; | |
| return function(...args) { | |
| if (sent) | |
| return; | |
| sent = true; | |
| self2.packet({ | |
| type: PacketType.ACK, | |
| id, | |
| data: args | |
| }); | |
| }; | |
| } | |
| /** | |
| * Called upon a server acknowledgement. | |
| * | |
| * @param packet | |
| * @private | |
| */ | |
| onack(packet) { | |
| const ack = this.acks[packet.id]; | |
| if (typeof ack !== "function") { | |
| return; | |
| } | |
| delete this.acks[packet.id]; | |
| if (ack.withError) { | |
| packet.data.unshift(null); | |
| } | |
| ack.apply(this, packet.data); | |
| } | |
| /** | |
| * Called upon server connect. | |
| * | |
| * @private | |
| */ | |
| onconnect(id, pid) { | |
| this.id = id; | |
| this.recovered = pid && this._pid === pid; | |
| this._pid = pid; | |
| this.connected = true; | |
| this.emitBuffered(); | |
| this.emitReserved("connect"); | |
| this._drainQueue(true); | |
| } | |
| /** | |
| * Emit buffered events (received and emitted). | |
| * | |
| * @private | |
| */ | |
| emitBuffered() { | |
| this.receiveBuffer.forEach((args) => this.emitEvent(args)); | |
| this.receiveBuffer = []; | |
| this.sendBuffer.forEach((packet) => { | |
| this.notifyOutgoingListeners(packet); | |
| this.packet(packet); | |
| }); | |
| this.sendBuffer = []; | |
| } | |
| /** | |
| * Called upon server disconnect. | |
| * | |
| * @private | |
| */ | |
| ondisconnect() { | |
| this.destroy(); | |
| this.onclose("io server disconnect"); | |
| } | |
| /** | |
| * Called upon forced client/server side disconnections, | |
| * this method ensures the manager stops tracking us and | |
| * that reconnections don't get triggered for this. | |
| * | |
| * @private | |
| */ | |
| destroy() { | |
| if (this.subs) { | |
| this.subs.forEach((subDestroy) => subDestroy()); | |
| this.subs = void 0; | |
| } | |
| this.io["_destroy"](this); | |
| } | |
| /** | |
| * Disconnects the socket manually. In that case, the socket will not try to reconnect. | |
| * | |
| * If this is the last active Socket instance of the {@link Manager}, the low-level connection will be closed. | |
| * | |
| * @example | |
| * const socket = io(); | |
| * | |
| * socket.on("disconnect", (reason) => { | |
| * // console.log(reason); prints "io client disconnect" | |
| * }); | |
| * | |
| * socket.disconnect(); | |
| * | |
| * @return self | |
| */ | |
| disconnect() { | |
| if (this.connected) { | |
| this.packet({ type: PacketType.DISCONNECT }); | |
| } | |
| this.destroy(); | |
| if (this.connected) { | |
| this.onclose("io client disconnect"); | |
| } | |
| return this; | |
| } | |
| /** | |
| * Alias for {@link disconnect()}. | |
| * | |
| * @return self | |
| */ | |
| close() { | |
| return this.disconnect(); | |
| } | |
| /** | |
| * Sets the compress flag. | |
| * | |
| * @example | |
| * socket.compress(false).emit("hello"); | |
| * | |
| * @param compress - if `true`, compresses the sending data | |
| * @return self | |
| */ | |
| compress(compress) { | |
| this.flags.compress = compress; | |
| return this; | |
| } | |
| /** | |
| * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not | |
| * ready to send messages. | |
| * | |
| * @example | |
| * socket.volatile.emit("hello"); // the server may or may not receive it | |
| * | |
| * @returns self | |
| */ | |
| get volatile() { | |
| this.flags.volatile = true; | |
| return this; | |
| } | |
| /** | |
| * Sets a modifier for a subsequent event emission that the callback will be called with an error when the | |
| * given number of milliseconds have elapsed without an acknowledgement from the server: | |
| * | |
| * @example | |
| * socket.timeout(5000).emit("my-event", (err) => { | |
| * if (err) { | |
| * // the server did not acknowledge the event in the given delay | |
| * } | |
| * }); | |
| * | |
| * @returns self | |
| */ | |
| timeout(timeout) { | |
| this.flags.timeout = timeout; | |
| return this; | |
| } | |
| /** | |
| * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the | |
| * callback. | |
| * | |
| * @example | |
| * socket.onAny((event, ...args) => { | |
| * console.log(`got ${event}`); | |
| * }); | |
| * | |
| * @param listener | |
| */ | |
| onAny(listener) { | |
| this._anyListeners = this._anyListeners || []; | |
| this._anyListeners.push(listener); | |
| return this; | |
| } | |
| /** | |
| * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the | |
| * callback. The listener is added to the beginning of the listeners array. | |
| * | |
| * @example | |
| * socket.prependAny((event, ...args) => { | |
| * console.log(`got event ${event}`); | |
| * }); | |
| * | |
| * @param listener | |
| */ | |
| prependAny(listener) { | |
| this._anyListeners = this._anyListeners || []; | |
| this._anyListeners.unshift(listener); | |
| return this; | |
| } | |
| /** | |
| * Removes the listener that will be fired when any event is emitted. | |
| * | |
| * @example | |
| * const catchAllListener = (event, ...args) => { | |
| * console.log(`got event ${event}`); | |
| * } | |
| * | |
| * socket.onAny(catchAllListener); | |
| * | |
| * // remove a specific listener | |
| * socket.offAny(catchAllListener); | |
| * | |
| * // or remove all listeners | |
| * socket.offAny(); | |
| * | |
| * @param listener | |
| */ | |
| offAny(listener) { | |
| if (!this._anyListeners) { | |
| return this; | |
| } | |
| if (listener) { | |
| const listeners = this._anyListeners; | |
| for (let i = 0; i < listeners.length; i++) { | |
| if (listener === listeners[i]) { | |
| listeners.splice(i, 1); | |
| return this; | |
| } | |
| } | |
| } else { | |
| this._anyListeners = []; | |
| } | |
| return this; | |
| } | |
| /** | |
| * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, | |
| * e.g. to remove listeners. | |
| */ | |
| listenersAny() { | |
| return this._anyListeners || []; | |
| } | |
| /** | |
| * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the | |
| * callback. | |
| * | |
| * Note: acknowledgements sent to the server are not included. | |
| * | |
| * @example | |
| * socket.onAnyOutgoing((event, ...args) => { | |
| * console.log(`sent event ${event}`); | |
| * }); | |
| * | |
| * @param listener | |
| */ | |
| onAnyOutgoing(listener) { | |
| this._anyOutgoingListeners = this._anyOutgoingListeners || []; | |
| this._anyOutgoingListeners.push(listener); | |
| return this; | |
| } | |
| /** | |
| * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the | |
| * callback. The listener is added to the beginning of the listeners array. | |
| * | |
| * Note: acknowledgements sent to the server are not included. | |
| * | |
| * @example | |
| * socket.prependAnyOutgoing((event, ...args) => { | |
| * console.log(`sent event ${event}`); | |
| * }); | |
| * | |
| * @param listener | |
| */ | |
| prependAnyOutgoing(listener) { | |
| this._anyOutgoingListeners = this._anyOutgoingListeners || []; | |
| this._anyOutgoingListeners.unshift(listener); | |
| return this; | |
| } | |
| /** | |
| * Removes the listener that will be fired when any event is emitted. | |
| * | |
| * @example | |
| * const catchAllListener = (event, ...args) => { | |
| * console.log(`sent event ${event}`); | |
| * } | |
| * | |
| * socket.onAnyOutgoing(catchAllListener); | |
| * | |
| * // remove a specific listener | |
| * socket.offAnyOutgoing(catchAllListener); | |
| * | |
| * // or remove all listeners | |
| * socket.offAnyOutgoing(); | |
| * | |
| * @param [listener] - the catch-all listener (optional) | |
| */ | |
| offAnyOutgoing(listener) { | |
| if (!this._anyOutgoingListeners) { | |
| return this; | |
| } | |
| if (listener) { | |
| const listeners = this._anyOutgoingListeners; | |
| for (let i = 0; i < listeners.length; i++) { | |
| if (listener === listeners[i]) { | |
| listeners.splice(i, 1); | |
| return this; | |
| } | |
| } | |
| } else { | |
| this._anyOutgoingListeners = []; | |
| } | |
| return this; | |
| } | |
| /** | |
| * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, | |
| * e.g. to remove listeners. | |
| */ | |
| listenersAnyOutgoing() { | |
| return this._anyOutgoingListeners || []; | |
| } | |
| /** | |
| * Notify the listeners for each packet sent | |
| * | |
| * @param packet | |
| * | |
| * @private | |
| */ | |
| notifyOutgoingListeners(packet) { | |
| if (this._anyOutgoingListeners && this._anyOutgoingListeners.length) { | |
| const listeners = this._anyOutgoingListeners.slice(); | |
| for (const listener of listeners) { | |
| listener.apply(this, packet.data); | |
| } | |
| } | |
| } | |
| }; | |
| // node_modules/socket.io-client/build/esm/contrib/backo2.js | |
| function Backoff(opts) { | |
| opts = opts || {}; | |
| this.ms = opts.min || 100; | |
| this.max = opts.max || 1e4; | |
| this.factor = opts.factor || 2; | |
| this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; | |
| this.attempts = 0; | |
| } | |
| Backoff.prototype.duration = function() { | |
| var ms = this.ms * Math.pow(this.factor, this.attempts++); | |
| if (this.jitter) { | |
| var rand = Math.random(); | |
| var deviation = Math.floor(rand * this.jitter * ms); | |
| ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; | |
| } | |
| return Math.min(ms, this.max) | 0; | |
| }; | |
| Backoff.prototype.reset = function() { | |
| this.attempts = 0; | |
| }; | |
| Backoff.prototype.setMin = function(min) { | |
| this.ms = min; | |
| }; | |
| Backoff.prototype.setMax = function(max) { | |
| this.max = max; | |
| }; | |
| Backoff.prototype.setJitter = function(jitter) { | |
| this.jitter = jitter; | |
| }; | |
| // node_modules/socket.io-client/build/esm/manager.js | |
| var Manager = class extends Emitter { | |
| constructor(uri, opts) { | |
| var _a; | |
| super(); | |
| this.nsps = {}; | |
| this.subs = []; | |
| if (uri && "object" === typeof uri) { | |
| opts = uri; | |
| uri = void 0; | |
| } | |
| opts = opts || {}; | |
| opts.path = opts.path || "/socket.io"; | |
| this.opts = opts; | |
| installTimerFunctions(this, opts); | |
| this.reconnection(opts.reconnection !== false); | |
| this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); | |
| this.reconnectionDelay(opts.reconnectionDelay || 1e3); | |
| this.reconnectionDelayMax(opts.reconnectionDelayMax || 5e3); | |
| this.randomizationFactor((_a = opts.randomizationFactor) !== null && _a !== void 0 ? _a : 0.5); | |
| this.backoff = new Backoff({ | |
| min: this.reconnectionDelay(), | |
| max: this.reconnectionDelayMax(), | |
| jitter: this.randomizationFactor() | |
| }); | |
| this.timeout(null == opts.timeout ? 2e4 : opts.timeout); | |
| this._readyState = "closed"; | |
| this.uri = uri; | |
| const _parser = opts.parser || esm_exports; | |
| this.encoder = new _parser.Encoder(); | |
| this.decoder = new _parser.Decoder(); | |
| this._autoConnect = opts.autoConnect !== false; | |
| if (this._autoConnect) | |
| this.open(); | |
| } | |
| reconnection(v2) { | |
| if (!arguments.length) | |
| return this._reconnection; | |
| this._reconnection = !!v2; | |
| if (!v2) { | |
| this.skipReconnect = true; | |
| } | |
| return this; | |
| } | |
| reconnectionAttempts(v2) { | |
| if (v2 === void 0) | |
| return this._reconnectionAttempts; | |
| this._reconnectionAttempts = v2; | |
| return this; | |
| } | |
| reconnectionDelay(v2) { | |
| var _a; | |
| if (v2 === void 0) | |
| return this._reconnectionDelay; | |
| this._reconnectionDelay = v2; | |
| (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v2); | |
| return this; | |
| } | |
| randomizationFactor(v2) { | |
| var _a; | |
| if (v2 === void 0) | |
| return this._randomizationFactor; | |
| this._randomizationFactor = v2; | |
| (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v2); | |
| return this; | |
| } | |
| reconnectionDelayMax(v2) { | |
| var _a; | |
| if (v2 === void 0) | |
| return this._reconnectionDelayMax; | |
| this._reconnectionDelayMax = v2; | |
| (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v2); | |
| return this; | |
| } | |
| timeout(v2) { | |
| if (!arguments.length) | |
| return this._timeout; | |
| this._timeout = v2; | |
| return this; | |
| } | |
| /** | |
| * Starts trying to reconnect if reconnection is enabled and we have not | |
| * started reconnecting yet | |
| * | |
| * @private | |
| */ | |
| maybeReconnectOnOpen() { | |
| if (!this._reconnecting && this._reconnection && this.backoff.attempts === 0) { | |
| this.reconnect(); | |
| } | |
| } | |
| /** | |
| * Sets the current transport `socket`. | |
| * | |
| * @param {Function} fn - optional, callback | |
| * @return self | |
| * @public | |
| */ | |
| open(fn) { | |
| if (~this._readyState.indexOf("open")) | |
| return this; | |
| this.engine = new Socket(this.uri, this.opts); | |
| const socket = this.engine; | |
| const self2 = this; | |
| this._readyState = "opening"; | |
| this.skipReconnect = false; | |
| const openSubDestroy = on(socket, "open", function() { | |
| self2.onopen(); | |
| fn && fn(); | |
| }); | |
| const onError = (err) => { | |
| this.cleanup(); | |
| this._readyState = "closed"; | |
| this.emitReserved("error", err); | |
| if (fn) { | |
| fn(err); | |
| } else { | |
| this.maybeReconnectOnOpen(); | |
| } | |
| }; | |
| const errorSub = on(socket, "error", onError); | |
| if (false !== this._timeout) { | |
| const timeout = this._timeout; | |
| const timer = this.setTimeoutFn(() => { | |
| openSubDestroy(); | |
| onError(new Error("timeout")); | |
| socket.close(); | |
| }, timeout); | |
| if (this.opts.autoUnref) { | |
| timer.unref(); | |
| } | |
| this.subs.push(() => { | |
| this.clearTimeoutFn(timer); | |
| }); | |
| } | |
| this.subs.push(openSubDestroy); | |
| this.subs.push(errorSub); | |
| return this; | |
| } | |
| /** | |
| * Alias for open() | |
| * | |
| * @return self | |
| * @public | |
| */ | |
| connect(fn) { | |
| return this.open(fn); | |
| } | |
| /** | |
| * Called upon transport open. | |
| * | |
| * @private | |
| */ | |
| onopen() { | |
| this.cleanup(); | |
| this._readyState = "open"; | |
| this.emitReserved("open"); | |
| const socket = this.engine; | |
| this.subs.push( | |
| on(socket, "ping", this.onping.bind(this)), | |
| on(socket, "data", this.ondata.bind(this)), | |
| on(socket, "error", this.onerror.bind(this)), | |
| on(socket, "close", this.onclose.bind(this)), | |
| // @ts-ignore | |
| on(this.decoder, "decoded", this.ondecoded.bind(this)) | |
| ); | |
| } | |
| /** | |
| * Called upon a ping. | |
| * | |
| * @private | |
| */ | |
| onping() { | |
| this.emitReserved("ping"); | |
| } | |
| /** | |
| * Called with data. | |
| * | |
| * @private | |
| */ | |
| ondata(data) { | |
| try { | |
| this.decoder.add(data); | |
| } catch (e) { | |
| this.onclose("parse error", e); | |
| } | |
| } | |
| /** | |
| * Called when parser fully decodes a packet. | |
| * | |
| * @private | |
| */ | |
| ondecoded(packet) { | |
| nextTick(() => { | |
| this.emitReserved("packet", packet); | |
| }, this.setTimeoutFn); | |
| } | |
| /** | |
| * Called upon socket error. | |
| * | |
| * @private | |
| */ | |
| onerror(err) { | |
| this.emitReserved("error", err); | |
| } | |
| /** | |
| * Creates a new socket for the given `nsp`. | |
| * | |
| * @return {Socket} | |
| * @public | |
| */ | |
| socket(nsp, opts) { | |
| let socket = this.nsps[nsp]; | |
| if (!socket) { | |
| socket = new Socket2(this, nsp, opts); | |
| this.nsps[nsp] = socket; | |
| } else if (this._autoConnect && !socket.active) { | |
| socket.connect(); | |
| } | |
| return socket; | |
| } | |
| /** | |
| * Called upon a socket close. | |
| * | |
| * @param socket | |
| * @private | |
| */ | |
| _destroy(socket) { | |
| const nsps = Object.keys(this.nsps); | |
| for (const nsp of nsps) { | |
| const socket2 = this.nsps[nsp]; | |
| if (socket2.active) { | |
| return; | |
| } | |
| } | |
| this._close(); | |
| } | |
| /** | |
| * Writes a packet. | |
| * | |
| * @param packet | |
| * @private | |
| */ | |
| _packet(packet) { | |
| const encodedPackets = this.encoder.encode(packet); | |
| for (let i = 0; i < encodedPackets.length; i++) { | |
| this.engine.write(encodedPackets[i], packet.options); | |
| } | |
| } | |
| /** | |
| * Clean up transport subscriptions and packet buffer. | |
| * | |
| * @private | |
| */ | |
| cleanup() { | |
| this.subs.forEach((subDestroy) => subDestroy()); | |
| this.subs.length = 0; | |
| this.decoder.destroy(); | |
| } | |
| /** | |
| * Close the current socket. | |
| * | |
| * @private | |
| */ | |
| _close() { | |
| this.skipReconnect = true; | |
| this._reconnecting = false; | |
| this.onclose("forced close"); | |
| } | |
| /** | |
| * Alias for close() | |
| * | |
| * @private | |
| */ | |
| disconnect() { | |
| return this._close(); | |
| } | |
| /** | |
| * Called when: | |
| * | |
| * - the low-level engine is closed | |
| * - the parser encountered a badly formatted packet | |
| * - all sockets are disconnected | |
| * | |
| * @private | |
| */ | |
| onclose(reason, description) { | |
| var _a; | |
| this.cleanup(); | |
| (_a = this.engine) === null || _a === void 0 ? void 0 : _a.close(); | |
| this.backoff.reset(); | |
| this._readyState = "closed"; | |
| this.emitReserved("close", reason, description); | |
| if (this._reconnection && !this.skipReconnect) { | |
| this.reconnect(); | |
| } | |
| } | |
| /** | |
| * Attempt a reconnection. | |
| * | |
| * @private | |
| */ | |
| reconnect() { | |
| if (this._reconnecting || this.skipReconnect) | |
| return this; | |
| const self2 = this; | |
| if (this.backoff.attempts >= this._reconnectionAttempts) { | |
| this.backoff.reset(); | |
| this.emitReserved("reconnect_failed"); | |
| this._reconnecting = false; | |
| } else { | |
| const delay = this.backoff.duration(); | |
| this._reconnecting = true; | |
| const timer = this.setTimeoutFn(() => { | |
| if (self2.skipReconnect) | |
| return; | |
| this.emitReserved("reconnect_attempt", self2.backoff.attempts); | |
| if (self2.skipReconnect) | |
| return; | |
| self2.open((err) => { | |
| if (err) { | |
| self2._reconnecting = false; | |
| self2.reconnect(); | |
| this.emitReserved("reconnect_error", err); | |
| } else { | |
| self2.onreconnect(); | |
| } | |
| }); | |
| }, delay); | |
| if (this.opts.autoUnref) { | |
| timer.unref(); | |
| } | |
| this.subs.push(() => { | |
| this.clearTimeoutFn(timer); | |
| }); | |
| } | |
| } | |
| /** | |
| * Called upon successful reconnect. | |
| * | |
| * @private | |
| */ | |
| onreconnect() { | |
| const attempt = this.backoff.attempts; | |
| this._reconnecting = false; | |
| this.backoff.reset(); | |
| this.emitReserved("reconnect", attempt); | |
| } | |
| }; | |
| // node_modules/socket.io-client/build/esm/index.js | |
| var cache = {}; | |
| function lookup2(uri, opts) { | |
| if (typeof uri === "object") { | |
| opts = uri; | |
| uri = void 0; | |
| } | |
| opts = opts || {}; | |
| const parsed = url(uri, opts.path || "/socket.io"); | |
| const source = parsed.source; | |
| const id = parsed.id; | |
| const path = parsed.path; | |
| const sameNamespace = cache[id] && path in cache[id]["nsps"]; | |
| const newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace; | |
| let io; | |
| if (newConnection) { | |
| io = new Manager(source, opts); | |
| } else { | |
| if (!cache[id]) { | |
| cache[id] = new Manager(source, opts); | |
| } | |
| io = cache[id]; | |
| } | |
| if (parsed.query && !opts.query) { | |
| opts.query = parsed.queryKey; | |
| } | |
| return io.socket(parsed.path, opts); | |
| } | |
| Object.assign(lookup2, { | |
| Manager, | |
| Socket: Socket2, | |
| io: lookup2, | |
| connect: lookup2 | |
| }); | |
| // node_modules/marked/lib/marked.esm.js | |
| function M() { | |
| return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null }; | |
| } | |
| var w = M(); | |
| function H(a3) { | |
| w = a3; | |
| } | |
| var C = { exec: () => null }; | |
| function h(a3, e = "") { | |
| let t = typeof a3 == "string" ? a3 : a3.source, n = { replace: (s, i) => { | |
| let r = typeof i == "string" ? i : i.source; | |
| return r = r.replace(m.caret, "$1"), t = t.replace(s, r), n; | |
| }, getRegex: () => new RegExp(t, e) }; | |
| return n; | |
| } | |
| var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceTabs: /^\t+/, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] /, listReplaceTask: /^\[[ xX]\] +/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, unescapeTest: /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (a3) => new RegExp(`^( {0,3}${a3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}#`), htmlBeginRegex: (a3) => new RegExp(`^ {0,${Math.min(3, a3 - 1)}}<(?:[a-z].*>|!--)`, "i") }; | |
| var xe = /^(?:[ \t]*(?:\n|$))+/; | |
| var be = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/; | |
| var Te = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/; | |
| var I = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/; | |
| var we = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/; | |
| var j = /(?:[*+-]|\d{1,9}[.)])/; | |
| var re2 = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/; | |
| var ie = h(re2).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex(); | |
| var ye = h(re2).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(); | |
| var F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/; | |
| var Re = /^[^\n]+/; | |
| var Q = /(?!\s*\])(?:\\.|[^\[\]\\])+/; | |
| var Se = h(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", Q).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(); | |
| var $e = h(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, j).getRegex(); | |
| var v = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul"; | |
| var U = /<!--(?:-?>|[\s\S]*?(?:-->|$))/; | |
| var _e = h("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", U).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); | |
| var oe = h(F).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex(); | |
| var Le = h(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", oe).getRegex(); | |
| var K = { blockquote: Le, code: be, def: Se, fences: Te, heading: we, hr: I, html: _e, lheading: ie, list: $e, newline: xe, paragraph: oe, table: C, text: Re }; | |
| var se = h("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex(); | |
| var ze = { ...K, lheading: ye, table: se, paragraph: h(F).replace("hr", I).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() }; | |
| var Me = { ...K, html: h(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", U).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: C, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: h(F).replace("hr", I).replace("heading", ` *#{1,6} *[^ | |
| ]`).replace("lheading", ie).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() }; | |
| var Pe = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/; | |
| var Ae = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/; | |
| var le = /^( {2,}|\\)\n(?!\s*$)/; | |
| var Ee = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/; | |
| var D = /[\p{P}\p{S}]/u; | |
| var X = /[\s\p{P}\p{S}]/u; | |
| var ae = /[^\s\p{P}\p{S}]/u; | |
| var Ce = h(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, X).getRegex(); | |
| var ce = /(?!~)[\p{P}\p{S}]/u; | |
| var Ie = /(?!~)[\s\p{P}\p{S}]/u; | |
| var Oe = /(?:[^\s\p{P}\p{S}]|~)/u; | |
| var Be = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g; | |
| var pe = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/; | |
| var qe = h(pe, "u").replace(/punct/g, D).getRegex(); | |
| var ve = h(pe, "u").replace(/punct/g, ce).getRegex(); | |
| var ue = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)"; | |
| var De = h(ue, "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, X).replace(/punct/g, D).getRegex(); | |
| var Ze = h(ue, "gu").replace(/notPunctSpace/g, Oe).replace(/punctSpace/g, Ie).replace(/punct/g, ce).getRegex(); | |
| var Ge = h("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, ae).replace(/punctSpace/g, X).replace(/punct/g, D).getRegex(); | |
| var He = h(/\\(punct)/, "gu").replace(/punct/g, D).getRegex(); | |
| var Ne = h(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(); | |
| var je = h(U).replace("(?:-->|$)", "-->").getRegex(); | |
| var Fe = h("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", je).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(); | |
| var q = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/; | |
| var Qe = h(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(); | |
| var he = h(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", Q).getRegex(); | |
| var ke = h(/^!?\[(ref)\](?:\[\])?/).replace("ref", Q).getRegex(); | |
| var Ue = h("reflink|nolink(?!\\()", "g").replace("reflink", he).replace("nolink", ke).getRegex(); | |
| var W = { _backpedal: C, anyPunctuation: He, autolink: Ne, blockSkip: Be, br: le, code: Ae, del: C, emStrongLDelim: qe, emStrongRDelimAst: De, emStrongRDelimUnd: Ge, escape: Pe, link: Qe, nolink: ke, punctuation: Ce, reflink: he, reflinkSearch: Ue, tag: Fe, text: Ee, url: C }; | |
| var Ke = { ...W, link: h(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: h(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() }; | |
| var N = { ...W, emStrongRDelimAst: Ze, emStrongLDelim: ve, url: h(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, "i").replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/, text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/ }; | |
| var Xe = { ...N, br: h(le).replace("{2,}", "*").getRegex(), text: h(N.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() }; | |
| var O = { normal: K, gfm: ze, pedantic: Me }; | |
| var P = { normal: W, gfm: N, breaks: Xe, pedantic: Ke }; | |
| var We = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }; | |
| var ge = (a3) => We[a3]; | |
| function R(a3, e) { | |
| if (e) { | |
| if (m.escapeTest.test(a3)) return a3.replace(m.escapeReplace, ge); | |
| } else if (m.escapeTestNoEncode.test(a3)) return a3.replace(m.escapeReplaceNoEncode, ge); | |
| return a3; | |
| } | |
| function J(a3) { | |
| try { | |
| a3 = encodeURI(a3).replace(m.percentDecode, "%"); | |
| } catch { | |
| return null; | |
| } | |
| return a3; | |
| } | |
| function V(a3, e) { | |
| let t = a3.replace(m.findPipe, (i, r, o) => { | |
| let l = false, c = r; | |
| for (; --c >= 0 && o[c] === "\\"; ) l = !l; | |
| return l ? "|" : " |"; | |
| }), n = t.split(m.splitPipe), s = 0; | |
| if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e); | |
| else for (; n.length < e; ) n.push(""); | |
| for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|"); | |
| return n; | |
| } | |
| function A(a3, e, t) { | |
| let n = a3.length; | |
| if (n === 0) return ""; | |
| let s = 0; | |
| for (; s < n; ) { | |
| let i = a3.charAt(n - s - 1); | |
| if (i === e && !t) s++; | |
| else if (i !== e && t) s++; | |
| else break; | |
| } | |
| return a3.slice(0, n - s); | |
| } | |
| function fe(a3, e) { | |
| if (a3.indexOf(e[1]) === -1) return -1; | |
| let t = 0; | |
| for (let n = 0; n < a3.length; n++) if (a3[n] === "\\") n++; | |
| else if (a3[n] === e[0]) t++; | |
| else if (a3[n] === e[1] && (t--, t < 0)) return n; | |
| return t > 0 ? -2 : -1; | |
| } | |
| function de(a3, e, t, n, s) { | |
| let i = e.href, r = e.title || null, o = a3[1].replace(s.other.outputLinkReplace, "$1"); | |
| n.state.inLink = true; | |
| let l = { type: a3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: i, title: r, text: o, tokens: n.inlineTokens(o) }; | |
| return n.state.inLink = false, l; | |
| } | |
| function Je(a3, e, t) { | |
| let n = a3.match(t.other.indentCodeCompensation); | |
| if (n === null) return e; | |
| let s = n[1]; | |
| return e.split(` | |
| `).map((i) => { | |
| let r = i.match(t.other.beginningSpace); | |
| if (r === null) return i; | |
| let [o] = r; | |
| return o.length >= s.length ? i.slice(s.length) : i; | |
| }).join(` | |
| `); | |
| } | |
| var S = class { | |
| options; | |
| rules; | |
| lexer; | |
| constructor(e) { | |
| this.options = e || w; | |
| } | |
| space(e) { | |
| let t = this.rules.block.newline.exec(e); | |
| if (t && t[0].length > 0) return { type: "space", raw: t[0] }; | |
| } | |
| code(e) { | |
| let t = this.rules.block.code.exec(e); | |
| if (t) { | |
| let n = t[0].replace(this.rules.other.codeRemoveIndent, ""); | |
| return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : A(n, ` | |
| `) }; | |
| } | |
| } | |
| fences(e) { | |
| let t = this.rules.block.fences.exec(e); | |
| if (t) { | |
| let n = t[0], s = Je(n, t[3] || "", this.rules); | |
| return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s }; | |
| } | |
| } | |
| heading(e) { | |
| let t = this.rules.block.heading.exec(e); | |
| if (t) { | |
| let n = t[2].trim(); | |
| if (this.rules.other.endingHash.test(n)) { | |
| let s = A(n, "#"); | |
| (this.options.pedantic || !s || this.rules.other.endingSpaceChar.test(s)) && (n = s.trim()); | |
| } | |
| return { type: "heading", raw: t[0], depth: t[1].length, text: n, tokens: this.lexer.inline(n) }; | |
| } | |
| } | |
| hr(e) { | |
| let t = this.rules.block.hr.exec(e); | |
| if (t) return { type: "hr", raw: A(t[0], ` | |
| `) }; | |
| } | |
| blockquote(e) { | |
| let t = this.rules.block.blockquote.exec(e); | |
| if (t) { | |
| let n = A(t[0], ` | |
| `).split(` | |
| `), s = "", i = "", r = []; | |
| for (; n.length > 0; ) { | |
| let o = false, l = [], c; | |
| for (c = 0; c < n.length; c++) if (this.rules.other.blockquoteStart.test(n[c])) l.push(n[c]), o = true; | |
| else if (!o) l.push(n[c]); | |
| else break; | |
| n = n.slice(c); | |
| let p = l.join(` | |
| `), u = p.replace(this.rules.other.blockquoteSetextReplace, ` | |
| $1`).replace(this.rules.other.blockquoteSetextReplace2, ""); | |
| s = s ? `${s} | |
| ${p}` : p, i = i ? `${i} | |
| ${u}` : u; | |
| let d = this.lexer.state.top; | |
| if (this.lexer.state.top = true, this.lexer.blockTokens(u, r, true), this.lexer.state.top = d, n.length === 0) break; | |
| let g = r.at(-1); | |
| if (g?.type === "code") break; | |
| if (g?.type === "blockquote") { | |
| let x = g, f = x.raw + ` | |
| ` + n.join(` | |
| `), y = this.blockquote(f); | |
| r[r.length - 1] = y, s = s.substring(0, s.length - x.raw.length) + y.raw, i = i.substring(0, i.length - x.text.length) + y.text; | |
| break; | |
| } else if (g?.type === "list") { | |
| let x = g, f = x.raw + ` | |
| ` + n.join(` | |
| `), y = this.list(f); | |
| r[r.length - 1] = y, s = s.substring(0, s.length - g.raw.length) + y.raw, i = i.substring(0, i.length - x.raw.length) + y.raw, n = f.substring(r.at(-1).raw.length).split(` | |
| `); | |
| continue; | |
| } | |
| } | |
| return { type: "blockquote", raw: s, tokens: r, text: i }; | |
| } | |
| } | |
| list(e) { | |
| let t = this.rules.block.list.exec(e); | |
| if (t) { | |
| let n = t[1].trim(), s = n.length > 1, i = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] }; | |
| n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]"); | |
| let r = this.rules.other.listItemRegex(n), o = false; | |
| for (; e; ) { | |
| let c = false, p = "", u = ""; | |
| if (!(t = r.exec(e)) || this.rules.block.hr.test(e)) break; | |
| p = t[0], e = e.substring(p.length); | |
| let d = t[2].split(` | |
| `, 1)[0].replace(this.rules.other.listReplaceTabs, (Z) => " ".repeat(3 * Z.length)), g = e.split(` | |
| `, 1)[0], x = !d.trim(), f = 0; | |
| if (this.options.pedantic ? (f = 2, u = d.trimStart()) : x ? f = t[1].length + 1 : (f = t[2].search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, u = d.slice(f), f += t[1].length), x && this.rules.other.blankLine.test(g) && (p += g + ` | |
| `, e = e.substring(g.length + 1), c = true), !c) { | |
| let Z = this.rules.other.nextBulletRegex(f), ee = this.rules.other.hrRegex(f), te = this.rules.other.fencesBeginRegex(f), ne = this.rules.other.headingBeginRegex(f), me = this.rules.other.htmlBeginRegex(f); | |
| for (; e; ) { | |
| let G = e.split(` | |
| `, 1)[0], E; | |
| if (g = G, this.options.pedantic ? (g = g.replace(this.rules.other.listReplaceNesting, " "), E = g) : E = g.replace(this.rules.other.tabCharGlobal, " "), te.test(g) || ne.test(g) || me.test(g) || Z.test(g) || ee.test(g)) break; | |
| if (E.search(this.rules.other.nonSpaceChar) >= f || !g.trim()) u += ` | |
| ` + E.slice(f); | |
| else { | |
| if (x || d.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || te.test(d) || ne.test(d) || ee.test(d)) break; | |
| u += ` | |
| ` + g; | |
| } | |
| !x && !g.trim() && (x = true), p += G + ` | |
| `, e = e.substring(G.length + 1), d = E.slice(f); | |
| } | |
| } | |
| i.loose || (o ? i.loose = true : this.rules.other.doubleBlankLine.test(p) && (o = true)); | |
| let y = null, Y; | |
| this.options.gfm && (y = this.rules.other.listIsTask.exec(u), y && (Y = y[0] !== "[ ] ", u = u.replace(this.rules.other.listReplaceTask, ""))), i.items.push({ type: "list_item", raw: p, task: !!y, checked: Y, loose: false, text: u, tokens: [] }), i.raw += p; | |
| } | |
| let l = i.items.at(-1); | |
| if (l) l.raw = l.raw.trimEnd(), l.text = l.text.trimEnd(); | |
| else return; | |
| i.raw = i.raw.trimEnd(); | |
| for (let c = 0; c < i.items.length; c++) if (this.lexer.state.top = false, i.items[c].tokens = this.lexer.blockTokens(i.items[c].text, []), !i.loose) { | |
| let p = i.items[c].tokens.filter((d) => d.type === "space"), u = p.length > 0 && p.some((d) => this.rules.other.anyLine.test(d.raw)); | |
| i.loose = u; | |
| } | |
| if (i.loose) for (let c = 0; c < i.items.length; c++) i.items[c].loose = true; | |
| return i; | |
| } | |
| } | |
| html(e) { | |
| let t = this.rules.block.html.exec(e); | |
| if (t) return { type: "html", block: true, raw: t[0], pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: t[0] }; | |
| } | |
| def(e) { | |
| let t = this.rules.block.def.exec(e); | |
| if (t) { | |
| let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), s = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3]; | |
| return { type: "def", tag: n, raw: t[0], href: s, title: i }; | |
| } | |
| } | |
| table(e) { | |
| let t = this.rules.block.table.exec(e); | |
| if (!t || !this.rules.other.tableDelimiter.test(t[2])) return; | |
| let n = V(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(` | |
| `) : [], r = { type: "table", raw: t[0], header: [], align: [], rows: [] }; | |
| if (n.length === s.length) { | |
| for (let o of s) this.rules.other.tableAlignRight.test(o) ? r.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? r.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? r.align.push("left") : r.align.push(null); | |
| for (let o = 0; o < n.length; o++) r.header.push({ text: n[o], tokens: this.lexer.inline(n[o]), header: true, align: r.align[o] }); | |
| for (let o of i) r.rows.push(V(o, r.header.length).map((l, c) => ({ text: l, tokens: this.lexer.inline(l), header: false, align: r.align[c] }))); | |
| return r; | |
| } | |
| } | |
| lheading(e) { | |
| let t = this.rules.block.lheading.exec(e); | |
| if (t) return { type: "heading", raw: t[0], depth: t[2].charAt(0) === "=" ? 1 : 2, text: t[1], tokens: this.lexer.inline(t[1]) }; | |
| } | |
| paragraph(e) { | |
| let t = this.rules.block.paragraph.exec(e); | |
| if (t) { | |
| let n = t[1].charAt(t[1].length - 1) === ` | |
| ` ? t[1].slice(0, -1) : t[1]; | |
| return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) }; | |
| } | |
| } | |
| text(e) { | |
| let t = this.rules.block.text.exec(e); | |
| if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) }; | |
| } | |
| escape(e) { | |
| let t = this.rules.inline.escape.exec(e); | |
| if (t) return { type: "escape", raw: t[0], text: t[1] }; | |
| } | |
| tag(e) { | |
| let t = this.rules.inline.tag.exec(e); | |
| if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] }; | |
| } | |
| link(e) { | |
| let t = this.rules.inline.link.exec(e); | |
| if (t) { | |
| let n = t[2].trim(); | |
| if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) { | |
| if (!this.rules.other.endAngleBracket.test(n)) return; | |
| let r = A(n.slice(0, -1), "\\"); | |
| if ((n.length - r.length) % 2 === 0) return; | |
| } else { | |
| let r = fe(t[2], "()"); | |
| if (r === -2) return; | |
| if (r > -1) { | |
| let l = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + r; | |
| t[2] = t[2].substring(0, r), t[0] = t[0].substring(0, l).trim(), t[3] = ""; | |
| } | |
| } | |
| let s = t[2], i = ""; | |
| if (this.options.pedantic) { | |
| let r = this.rules.other.pedanticHrefTitle.exec(s); | |
| r && (s = r[1], i = r[3]); | |
| } else i = t[3] ? t[3].slice(1, -1) : ""; | |
| return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), de(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules); | |
| } | |
| } | |
| reflink(e, t) { | |
| let n; | |
| if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) { | |
| let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t[s.toLowerCase()]; | |
| if (!i) { | |
| let r = n[0].charAt(0); | |
| return { type: "text", raw: r, text: r }; | |
| } | |
| return de(n, i, n[0], this.lexer, this.rules); | |
| } | |
| } | |
| emStrong(e, t, n = "") { | |
| let s = this.rules.inline.emStrongLDelim.exec(e); | |
| if (!s || s[3] && n.match(this.rules.other.unicodeAlphaNumeric)) return; | |
| if (!(s[1] || s[2] || "") || !n || this.rules.inline.punctuation.exec(n)) { | |
| let r = [...s[0]].length - 1, o, l, c = r, p = 0, u = s[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd; | |
| for (u.lastIndex = 0, t = t.slice(-1 * e.length + r); (s = u.exec(t)) != null; ) { | |
| if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue; | |
| if (l = [...o].length, s[3] || s[4]) { | |
| c += l; | |
| continue; | |
| } else if ((s[5] || s[6]) && r % 3 && !((r + l) % 3)) { | |
| p += l; | |
| continue; | |
| } | |
| if (c -= l, c > 0) continue; | |
| l = Math.min(l, l + c + p); | |
| let d = [...s[0]][0].length, g = e.slice(0, r + s.index + d + l); | |
| if (Math.min(r, l) % 2) { | |
| let f = g.slice(1, -1); | |
| return { type: "em", raw: g, text: f, tokens: this.lexer.inlineTokens(f) }; | |
| } | |
| let x = g.slice(2, -2); | |
| return { type: "strong", raw: g, text: x, tokens: this.lexer.inlineTokens(x) }; | |
| } | |
| } | |
| } | |
| codespan(e) { | |
| let t = this.rules.inline.code.exec(e); | |
| if (t) { | |
| let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), s = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n); | |
| return s && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n }; | |
| } | |
| } | |
| br(e) { | |
| let t = this.rules.inline.br.exec(e); | |
| if (t) return { type: "br", raw: t[0] }; | |
| } | |
| del(e) { | |
| let t = this.rules.inline.del.exec(e); | |
| if (t) return { type: "del", raw: t[0], text: t[2], tokens: this.lexer.inlineTokens(t[2]) }; | |
| } | |
| autolink(e) { | |
| let t = this.rules.inline.autolink.exec(e); | |
| if (t) { | |
| let n, s; | |
| return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] }; | |
| } | |
| } | |
| url(e) { | |
| let t; | |
| if (t = this.rules.inline.url.exec(e)) { | |
| let n, s; | |
| if (t[2] === "@") n = t[0], s = "mailto:" + n; | |
| else { | |
| let i; | |
| do | |
| i = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? ""; | |
| while (i !== t[0]); | |
| n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0]; | |
| } | |
| return { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] }; | |
| } | |
| } | |
| inlineText(e) { | |
| let t = this.rules.inline.text.exec(e); | |
| if (t) { | |
| let n = this.lexer.state.inRawBlock; | |
| return { type: "text", raw: t[0], text: t[0], escaped: n }; | |
| } | |
| } | |
| }; | |
| var b = class a { | |
| tokens; | |
| options; | |
| state; | |
| tokenizer; | |
| inlineQueue; | |
| constructor(e) { | |
| this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || w, this.options.tokenizer = this.options.tokenizer || new S(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true }; | |
| let t = { other: m, block: O.normal, inline: P.normal }; | |
| this.options.pedantic ? (t.block = O.pedantic, t.inline = P.pedantic) : this.options.gfm && (t.block = O.gfm, this.options.breaks ? t.inline = P.breaks : t.inline = P.gfm), this.tokenizer.rules = t; | |
| } | |
| static get rules() { | |
| return { block: O, inline: P }; | |
| } | |
| static lex(e, t) { | |
| return new a(t).lex(e); | |
| } | |
| static lexInline(e, t) { | |
| return new a(t).inlineTokens(e); | |
| } | |
| lex(e) { | |
| e = e.replace(m.carriageReturn, ` | |
| `), this.blockTokens(e, this.tokens); | |
| for (let t = 0; t < this.inlineQueue.length; t++) { | |
| let n = this.inlineQueue[t]; | |
| this.inlineTokens(n.src, n.tokens); | |
| } | |
| return this.inlineQueue = [], this.tokens; | |
| } | |
| blockTokens(e, t = [], n = false) { | |
| for (this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); e; ) { | |
| let s; | |
| if (this.options.extensions?.block?.some((r) => (s = r.call({ lexer: this }, e, t)) ? (e = e.substring(s.raw.length), t.push(s), true) : false)) continue; | |
| if (s = this.tokenizer.space(e)) { | |
| e = e.substring(s.raw.length); | |
| let r = t.at(-1); | |
| s.raw.length === 1 && r !== void 0 ? r.raw += ` | |
| ` : t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.code(e)) { | |
| e = e.substring(s.raw.length); | |
| let r = t.at(-1); | |
| r?.type === "paragraph" || r?.type === "text" ? (r.raw += ` | |
| ` + s.raw, r.text += ` | |
| ` + s.text, this.inlineQueue.at(-1).src = r.text) : t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.fences(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.heading(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.hr(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.blockquote(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.list(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.html(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.def(e)) { | |
| e = e.substring(s.raw.length); | |
| let r = t.at(-1); | |
| r?.type === "paragraph" || r?.type === "text" ? (r.raw += ` | |
| ` + s.raw, r.text += ` | |
| ` + s.raw, this.inlineQueue.at(-1).src = r.text) : this.tokens.links[s.tag] || (this.tokens.links[s.tag] = { href: s.href, title: s.title }); | |
| continue; | |
| } | |
| if (s = this.tokenizer.table(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| if (s = this.tokenizer.lheading(e)) { | |
| e = e.substring(s.raw.length), t.push(s); | |
| continue; | |
| } | |
| let i = e; | |
| if (this.options.extensions?.startBlock) { | |
| let r = 1 / 0, o = e.slice(1), l; | |
| this.options.extensions.startBlock.forEach((c) => { | |
| l = c.call({ lexer: this }, o), typeof l == "number" && l >= 0 && (r = Math.min(r, l)); | |
| }), r < 1 / 0 && r >= 0 && (i = e.substring(0, r + 1)); | |
| } | |
| if (this.state.top && (s = this.tokenizer.paragraph(i))) { | |
| let r = t.at(-1); | |
| n && r?.type === "paragraph" ? (r.raw += ` | |
| ` + s.raw, r.text += ` | |
| ` + s.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = r.text) : t.push(s), n = i.length !== e.length, e = e.substring(s.raw.length); | |
| continue; | |
| } | |
| if (s = this.tokenizer.text(e)) { | |
| e = e.substring(s.raw.length); | |
| let r = t.at(-1); | |
| r?.type === "text" ? (r.raw += ` | |
| ` + s.raw, r.text += ` | |
| ` + s.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = r.text) : t.push(s); | |
| continue; | |
| } | |
| if (e) { | |
| let r = "Infinite loop on byte: " + e.charCodeAt(0); | |
| if (this.options.silent) { | |
| console.error(r); | |
| break; | |
| } else throw new Error(r); | |
| } | |
| } | |
| return this.state.top = true, t; | |
| } | |
| inline(e, t = []) { | |
| return this.inlineQueue.push({ src: e, tokens: t }), t; | |
| } | |
| inlineTokens(e, t = []) { | |
| let n = e, s = null; | |
| if (this.tokens.links) { | |
| let o = Object.keys(this.tokens.links); | |
| if (o.length > 0) for (; (s = this.tokenizer.rules.inline.reflinkSearch.exec(n)) != null; ) o.includes(s[0].slice(s[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex)); | |
| } | |
| for (; (s = this.tokenizer.rules.inline.anyPunctuation.exec(n)) != null; ) n = n.slice(0, s.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); | |
| for (; (s = this.tokenizer.rules.inline.blockSkip.exec(n)) != null; ) n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); | |
| let i = false, r = ""; | |
| for (; e; ) { | |
| i || (r = ""), i = false; | |
| let o; | |
| if (this.options.extensions?.inline?.some((c) => (o = c.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue; | |
| if (o = this.tokenizer.escape(e)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.tag(e)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.link(e)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.reflink(e, this.tokens.links)) { | |
| e = e.substring(o.raw.length); | |
| let c = t.at(-1); | |
| o.type === "text" && c?.type === "text" ? (c.raw += o.raw, c.text += o.text) : t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.emStrong(e, n, r)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.codespan(e)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.br(e)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.del(e)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (o = this.tokenizer.autolink(e)) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| if (!this.state.inLink && (o = this.tokenizer.url(e))) { | |
| e = e.substring(o.raw.length), t.push(o); | |
| continue; | |
| } | |
| let l = e; | |
| if (this.options.extensions?.startInline) { | |
| let c = 1 / 0, p = e.slice(1), u; | |
| this.options.extensions.startInline.forEach((d) => { | |
| u = d.call({ lexer: this }, p), typeof u == "number" && u >= 0 && (c = Math.min(c, u)); | |
| }), c < 1 / 0 && c >= 0 && (l = e.substring(0, c + 1)); | |
| } | |
| if (o = this.tokenizer.inlineText(l)) { | |
| e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (r = o.raw.slice(-1)), i = true; | |
| let c = t.at(-1); | |
| c?.type === "text" ? (c.raw += o.raw, c.text += o.text) : t.push(o); | |
| continue; | |
| } | |
| if (e) { | |
| let c = "Infinite loop on byte: " + e.charCodeAt(0); | |
| if (this.options.silent) { | |
| console.error(c); | |
| break; | |
| } else throw new Error(c); | |
| } | |
| } | |
| return t; | |
| } | |
| }; | |
| var $ = class { | |
| options; | |
| parser; | |
| constructor(e) { | |
| this.options = e || w; | |
| } | |
| space(e) { | |
| return ""; | |
| } | |
| code({ text: e, lang: t, escaped: n }) { | |
| let s = (t || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + ` | |
| `; | |
| return s ? '<pre><code class="language-' + R(s) + '">' + (n ? i : R(i, true)) + `</code></pre> | |
| ` : "<pre><code>" + (n ? i : R(i, true)) + `</code></pre> | |
| `; | |
| } | |
| blockquote({ tokens: e }) { | |
| return `<blockquote> | |
| ${this.parser.parse(e)}</blockquote> | |
| `; | |
| } | |
| html({ text: e }) { | |
| return e; | |
| } | |
| heading({ tokens: e, depth: t }) { | |
| return `<h${t}>${this.parser.parseInline(e)}</h${t}> | |
| `; | |
| } | |
| hr(e) { | |
| return `<hr> | |
| `; | |
| } | |
| list(e) { | |
| let t = e.ordered, n = e.start, s = ""; | |
| for (let o = 0; o < e.items.length; o++) { | |
| let l = e.items[o]; | |
| s += this.listitem(l); | |
| } | |
| let i = t ? "ol" : "ul", r = t && n !== 1 ? ' start="' + n + '"' : ""; | |
| return "<" + i + r + `> | |
| ` + s + "</" + i + `> | |
| `; | |
| } | |
| listitem(e) { | |
| let t = ""; | |
| if (e.task) { | |
| let n = this.checkbox({ checked: !!e.checked }); | |
| e.loose ? e.tokens[0]?.type === "paragraph" ? (e.tokens[0].text = n + " " + e.tokens[0].text, e.tokens[0].tokens && e.tokens[0].tokens.length > 0 && e.tokens[0].tokens[0].type === "text" && (e.tokens[0].tokens[0].text = n + " " + R(e.tokens[0].tokens[0].text), e.tokens[0].tokens[0].escaped = true)) : e.tokens.unshift({ type: "text", raw: n + " ", text: n + " ", escaped: true }) : t += n + " "; | |
| } | |
| return t += this.parser.parse(e.tokens, !!e.loose), `<li>${t}</li> | |
| `; | |
| } | |
| checkbox({ checked: e }) { | |
| return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox">'; | |
| } | |
| paragraph({ tokens: e }) { | |
| return `<p>${this.parser.parseInline(e)}</p> | |
| `; | |
| } | |
| table(e) { | |
| let t = "", n = ""; | |
| for (let i = 0; i < e.header.length; i++) n += this.tablecell(e.header[i]); | |
| t += this.tablerow({ text: n }); | |
| let s = ""; | |
| for (let i = 0; i < e.rows.length; i++) { | |
| let r = e.rows[i]; | |
| n = ""; | |
| for (let o = 0; o < r.length; o++) n += this.tablecell(r[o]); | |
| s += this.tablerow({ text: n }); | |
| } | |
| return s && (s = `<tbody>${s}</tbody>`), `<table> | |
| <thead> | |
| ` + t + `</thead> | |
| ` + s + `</table> | |
| `; | |
| } | |
| tablerow({ text: e }) { | |
| return `<tr> | |
| ${e}</tr> | |
| `; | |
| } | |
| tablecell(e) { | |
| let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td"; | |
| return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}> | |
| `; | |
| } | |
| strong({ tokens: e }) { | |
| return `<strong>${this.parser.parseInline(e)}</strong>`; | |
| } | |
| em({ tokens: e }) { | |
| return `<em>${this.parser.parseInline(e)}</em>`; | |
| } | |
| codespan({ text: e }) { | |
| return `<code>${R(e, true)}</code>`; | |
| } | |
| br(e) { | |
| return "<br>"; | |
| } | |
| del({ tokens: e }) { | |
| return `<del>${this.parser.parseInline(e)}</del>`; | |
| } | |
| link({ href: e, title: t, tokens: n }) { | |
| let s = this.parser.parseInline(n), i = J(e); | |
| if (i === null) return s; | |
| e = i; | |
| let r = '<a href="' + e + '"'; | |
| return t && (r += ' title="' + R(t) + '"'), r += ">" + s + "</a>", r; | |
| } | |
| image({ href: e, title: t, text: n, tokens: s }) { | |
| s && (n = this.parser.parseInline(s, this.parser.textRenderer)); | |
| let i = J(e); | |
| if (i === null) return R(n); | |
| e = i; | |
| let r = `<img src="${e}" alt="${n}"`; | |
| return t && (r += ` title="${R(t)}"`), r += ">", r; | |
| } | |
| text(e) { | |
| return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : R(e.text); | |
| } | |
| }; | |
| var _ = class { | |
| strong({ text: e }) { | |
| return e; | |
| } | |
| em({ text: e }) { | |
| return e; | |
| } | |
| codespan({ text: e }) { | |
| return e; | |
| } | |
| del({ text: e }) { | |
| return e; | |
| } | |
| html({ text: e }) { | |
| return e; | |
| } | |
| text({ text: e }) { | |
| return e; | |
| } | |
| link({ text: e }) { | |
| return "" + e; | |
| } | |
| image({ text: e }) { | |
| return "" + e; | |
| } | |
| br() { | |
| return ""; | |
| } | |
| }; | |
| var T = class a2 { | |
| options; | |
| renderer; | |
| textRenderer; | |
| constructor(e) { | |
| this.options = e || w, this.options.renderer = this.options.renderer || new $(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new _(); | |
| } | |
| static parse(e, t) { | |
| return new a2(t).parse(e); | |
| } | |
| static parseInline(e, t) { | |
| return new a2(t).parseInline(e); | |
| } | |
| parse(e, t = true) { | |
| let n = ""; | |
| for (let s = 0; s < e.length; s++) { | |
| let i = e[s]; | |
| if (this.options.extensions?.renderers?.[i.type]) { | |
| let o = i, l = this.options.extensions.renderers[o.type].call({ parser: this }, o); | |
| if (l !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(o.type)) { | |
| n += l || ""; | |
| continue; | |
| } | |
| } | |
| let r = i; | |
| switch (r.type) { | |
| case "space": { | |
| n += this.renderer.space(r); | |
| continue; | |
| } | |
| case "hr": { | |
| n += this.renderer.hr(r); | |
| continue; | |
| } | |
| case "heading": { | |
| n += this.renderer.heading(r); | |
| continue; | |
| } | |
| case "code": { | |
| n += this.renderer.code(r); | |
| continue; | |
| } | |
| case "table": { | |
| n += this.renderer.table(r); | |
| continue; | |
| } | |
| case "blockquote": { | |
| n += this.renderer.blockquote(r); | |
| continue; | |
| } | |
| case "list": { | |
| n += this.renderer.list(r); | |
| continue; | |
| } | |
| case "html": { | |
| n += this.renderer.html(r); | |
| continue; | |
| } | |
| case "paragraph": { | |
| n += this.renderer.paragraph(r); | |
| continue; | |
| } | |
| case "text": { | |
| let o = r, l = this.renderer.text(o); | |
| for (; s + 1 < e.length && e[s + 1].type === "text"; ) o = e[++s], l += ` | |
| ` + this.renderer.text(o); | |
| t ? n += this.renderer.paragraph({ type: "paragraph", raw: l, text: l, tokens: [{ type: "text", raw: l, text: l, escaped: true }] }) : n += l; | |
| continue; | |
| } | |
| default: { | |
| let o = 'Token with "' + r.type + '" type was not found.'; | |
| if (this.options.silent) return console.error(o), ""; | |
| throw new Error(o); | |
| } | |
| } | |
| } | |
| return n; | |
| } | |
| parseInline(e, t = this.renderer) { | |
| let n = ""; | |
| for (let s = 0; s < e.length; s++) { | |
| let i = e[s]; | |
| if (this.options.extensions?.renderers?.[i.type]) { | |
| let o = this.options.extensions.renderers[i.type].call({ parser: this }, i); | |
| if (o !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(i.type)) { | |
| n += o || ""; | |
| continue; | |
| } | |
| } | |
| let r = i; | |
| switch (r.type) { | |
| case "escape": { | |
| n += t.text(r); | |
| break; | |
| } | |
| case "html": { | |
| n += t.html(r); | |
| break; | |
| } | |
| case "link": { | |
| n += t.link(r); | |
| break; | |
| } | |
| case "image": { | |
| n += t.image(r); | |
| break; | |
| } | |
| case "strong": { | |
| n += t.strong(r); | |
| break; | |
| } | |
| case "em": { | |
| n += t.em(r); | |
| break; | |
| } | |
| case "codespan": { | |
| n += t.codespan(r); | |
| break; | |
| } | |
| case "br": { | |
| n += t.br(r); | |
| break; | |
| } | |
| case "del": { | |
| n += t.del(r); | |
| break; | |
| } | |
| case "text": { | |
| n += t.text(r); | |
| break; | |
| } | |
| default: { | |
| let o = 'Token with "' + r.type + '" type was not found.'; | |
| if (this.options.silent) return console.error(o), ""; | |
| throw new Error(o); | |
| } | |
| } | |
| } | |
| return n; | |
| } | |
| }; | |
| var L = class { | |
| options; | |
| block; | |
| constructor(e) { | |
| this.options = e || w; | |
| } | |
| static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]); | |
| preprocess(e) { | |
| return e; | |
| } | |
| postprocess(e) { | |
| return e; | |
| } | |
| processAllTokens(e) { | |
| return e; | |
| } | |
| provideLexer() { | |
| return this.block ? b.lex : b.lexInline; | |
| } | |
| provideParser() { | |
| return this.block ? T.parse : T.parseInline; | |
| } | |
| }; | |
| var B = class { | |
| defaults = M(); | |
| options = this.setOptions; | |
| parse = this.parseMarkdown(true); | |
| parseInline = this.parseMarkdown(false); | |
| Parser = T; | |
| Renderer = $; | |
| TextRenderer = _; | |
| Lexer = b; | |
| Tokenizer = S; | |
| Hooks = L; | |
| constructor(...e) { | |
| this.use(...e); | |
| } | |
| walkTokens(e, t) { | |
| let n = []; | |
| for (let s of e) switch (n = n.concat(t.call(this, s)), s.type) { | |
| case "table": { | |
| let i = s; | |
| for (let r of i.header) n = n.concat(this.walkTokens(r.tokens, t)); | |
| for (let r of i.rows) for (let o of r) n = n.concat(this.walkTokens(o.tokens, t)); | |
| break; | |
| } | |
| case "list": { | |
| let i = s; | |
| n = n.concat(this.walkTokens(i.items, t)); | |
| break; | |
| } | |
| default: { | |
| let i = s; | |
| this.defaults.extensions?.childTokens?.[i.type] ? this.defaults.extensions.childTokens[i.type].forEach((r) => { | |
| let o = i[r].flat(1 / 0); | |
| n = n.concat(this.walkTokens(o, t)); | |
| }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t))); | |
| } | |
| } | |
| return n; | |
| } | |
| use(...e) { | |
| let t = this.defaults.extensions || { renderers: {}, childTokens: {} }; | |
| return e.forEach((n) => { | |
| let s = { ...n }; | |
| if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((i) => { | |
| if (!i.name) throw new Error("extension name required"); | |
| if ("renderer" in i) { | |
| let r = t.renderers[i.name]; | |
| r ? t.renderers[i.name] = function(...o) { | |
| let l = i.renderer.apply(this, o); | |
| return l === false && (l = r.apply(this, o)), l; | |
| } : t.renderers[i.name] = i.renderer; | |
| } | |
| if ("tokenizer" in i) { | |
| if (!i.level || i.level !== "block" && i.level !== "inline") throw new Error("extension level must be 'block' or 'inline'"); | |
| let r = t[i.level]; | |
| r ? r.unshift(i.tokenizer) : t[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t.startBlock ? t.startBlock.push(i.start) : t.startBlock = [i.start] : i.level === "inline" && (t.startInline ? t.startInline.push(i.start) : t.startInline = [i.start])); | |
| } | |
| "childTokens" in i && i.childTokens && (t.childTokens[i.name] = i.childTokens); | |
| }), s.extensions = t), n.renderer) { | |
| let i = this.defaults.renderer || new $(this.defaults); | |
| for (let r in n.renderer) { | |
| if (!(r in i)) throw new Error(`renderer '${r}' does not exist`); | |
| if (["options", "parser"].includes(r)) continue; | |
| let o = r, l = n.renderer[o], c = i[o]; | |
| i[o] = (...p) => { | |
| let u = l.apply(i, p); | |
| return u === false && (u = c.apply(i, p)), u || ""; | |
| }; | |
| } | |
| s.renderer = i; | |
| } | |
| if (n.tokenizer) { | |
| let i = this.defaults.tokenizer || new S(this.defaults); | |
| for (let r in n.tokenizer) { | |
| if (!(r in i)) throw new Error(`tokenizer '${r}' does not exist`); | |
| if (["options", "rules", "lexer"].includes(r)) continue; | |
| let o = r, l = n.tokenizer[o], c = i[o]; | |
| i[o] = (...p) => { | |
| let u = l.apply(i, p); | |
| return u === false && (u = c.apply(i, p)), u; | |
| }; | |
| } | |
| s.tokenizer = i; | |
| } | |
| if (n.hooks) { | |
| let i = this.defaults.hooks || new L(); | |
| for (let r in n.hooks) { | |
| if (!(r in i)) throw new Error(`hook '${r}' does not exist`); | |
| if (["options", "block"].includes(r)) continue; | |
| let o = r, l = n.hooks[o], c = i[o]; | |
| L.passThroughHooks.has(r) ? i[o] = (p) => { | |
| if (this.defaults.async) return Promise.resolve(l.call(i, p)).then((d) => c.call(i, d)); | |
| let u = l.call(i, p); | |
| return c.call(i, u); | |
| } : i[o] = (...p) => { | |
| let u = l.apply(i, p); | |
| return u === false && (u = c.apply(i, p)), u; | |
| }; | |
| } | |
| s.hooks = i; | |
| } | |
| if (n.walkTokens) { | |
| let i = this.defaults.walkTokens, r = n.walkTokens; | |
| s.walkTokens = function(o) { | |
| let l = []; | |
| return l.push(r.call(this, o)), i && (l = l.concat(i.call(this, o))), l; | |
| }; | |
| } | |
| this.defaults = { ...this.defaults, ...s }; | |
| }), this; | |
| } | |
| setOptions(e) { | |
| return this.defaults = { ...this.defaults, ...e }, this; | |
| } | |
| lexer(e, t) { | |
| return b.lex(e, t ?? this.defaults); | |
| } | |
| parser(e, t) { | |
| return T.parse(e, t ?? this.defaults); | |
| } | |
| parseMarkdown(e) { | |
| return (n, s) => { | |
| let i = { ...s }, r = { ...this.defaults, ...i }, o = this.onError(!!r.silent, !!r.async); | |
| if (this.defaults.async === true && i.async === false) return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.")); | |
| if (typeof n > "u" || n === null) return o(new Error("marked(): input parameter is undefined or null")); | |
| if (typeof n != "string") return o(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected")); | |
| r.hooks && (r.hooks.options = r, r.hooks.block = e); | |
| let l = r.hooks ? r.hooks.provideLexer() : e ? b.lex : b.lexInline, c = r.hooks ? r.hooks.provideParser() : e ? T.parse : T.parseInline; | |
| if (r.async) return Promise.resolve(r.hooks ? r.hooks.preprocess(n) : n).then((p) => l(p, r)).then((p) => r.hooks ? r.hooks.processAllTokens(p) : p).then((p) => r.walkTokens ? Promise.all(this.walkTokens(p, r.walkTokens)).then(() => p) : p).then((p) => c(p, r)).then((p) => r.hooks ? r.hooks.postprocess(p) : p).catch(o); | |
| try { | |
| r.hooks && (n = r.hooks.preprocess(n)); | |
| let p = l(n, r); | |
| r.hooks && (p = r.hooks.processAllTokens(p)), r.walkTokens && this.walkTokens(p, r.walkTokens); | |
| let u = c(p, r); | |
| return r.hooks && (u = r.hooks.postprocess(u)), u; | |
| } catch (p) { | |
| return o(p); | |
| } | |
| }; | |
| } | |
| onError(e, t) { | |
| return (n) => { | |
| if (n.message += ` | |
| Please report this to https://github.com/markedjs/marked.`, e) { | |
| let s = "<p>An error occurred:</p><pre>" + R(n.message + "", true) + "</pre>"; | |
| return t ? Promise.resolve(s) : s; | |
| } | |
| if (t) return Promise.reject(n); | |
| throw n; | |
| }; | |
| } | |
| }; | |
| var z = new B(); | |
| function k(a3, e) { | |
| return z.parse(a3, e); | |
| } | |
| k.options = k.setOptions = function(a3) { | |
| return z.setOptions(a3), k.defaults = z.defaults, H(k.defaults), k; | |
| }; | |
| k.getDefaults = M; | |
| k.defaults = w; | |
| k.use = function(...a3) { | |
| return z.use(...a3), k.defaults = z.defaults, H(k.defaults), k; | |
| }; | |
| k.walkTokens = function(a3, e) { | |
| return z.walkTokens(a3, e); | |
| }; | |
| k.parseInline = z.parseInline; | |
| k.Parser = T; | |
| k.parser = T.parse; | |
| k.Renderer = $; | |
| k.TextRenderer = _; | |
| k.Lexer = b; | |
| k.lexer = b.lex; | |
| k.Tokenizer = S; | |
| k.Hooks = L; | |
| k.parse = k; | |
| var Dt = k.options; | |
| var Zt = k.setOptions; | |
| var Gt = k.use; | |
| var Ht = k.walkTokens; | |
| var Nt = k.parseInline; | |
| var Ft = T.parse; | |
| var Qt = b.lex; | |
| // node_modules/dompurify/dist/purify.es.mjs | |
| var { | |
| entries, | |
| setPrototypeOf, | |
| isFrozen, | |
| getPrototypeOf, | |
| getOwnPropertyDescriptor | |
| } = Object; | |
| var { | |
| freeze, | |
| seal, | |
| create | |
| } = Object; | |
| var { | |
| apply, | |
| construct | |
| } = typeof Reflect !== "undefined" && Reflect; | |
| if (!freeze) { | |
| freeze = function freeze2(x) { | |
| return x; | |
| }; | |
| } | |
| if (!seal) { | |
| seal = function seal2(x) { | |
| return x; | |
| }; | |
| } | |
| if (!apply) { | |
| apply = function apply2(fun, thisValue, args) { | |
| return fun.apply(thisValue, args); | |
| }; | |
| } | |
| if (!construct) { | |
| construct = function construct2(Func, args) { | |
| return new Func(...args); | |
| }; | |
| } | |
| var arrayForEach = unapply(Array.prototype.forEach); | |
| var arrayLastIndexOf = unapply(Array.prototype.lastIndexOf); | |
| var arrayPop = unapply(Array.prototype.pop); | |
| var arrayPush = unapply(Array.prototype.push); | |
| var arraySplice = unapply(Array.prototype.splice); | |
| var stringToLowerCase = unapply(String.prototype.toLowerCase); | |
| var stringToString = unapply(String.prototype.toString); | |
| var stringMatch = unapply(String.prototype.match); | |
| var stringReplace = unapply(String.prototype.replace); | |
| var stringIndexOf = unapply(String.prototype.indexOf); | |
| var stringTrim = unapply(String.prototype.trim); | |
| var objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty); | |
| var regExpTest = unapply(RegExp.prototype.test); | |
| var typeErrorCreate = unconstruct(TypeError); | |
| function unapply(func) { | |
| return function(thisArg) { | |
| if (thisArg instanceof RegExp) { | |
| thisArg.lastIndex = 0; | |
| } | |
| for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | |
| args[_key - 1] = arguments[_key]; | |
| } | |
| return apply(func, thisArg, args); | |
| }; | |
| } | |
| function unconstruct(func) { | |
| return function() { | |
| for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | |
| args[_key2] = arguments[_key2]; | |
| } | |
| return construct(func, args); | |
| }; | |
| } | |
| function addToSet(set, array) { | |
| let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase; | |
| if (setPrototypeOf) { | |
| setPrototypeOf(set, null); | |
| } | |
| let l = array.length; | |
| while (l--) { | |
| let element = array[l]; | |
| if (typeof element === "string") { | |
| const lcElement = transformCaseFunc(element); | |
| if (lcElement !== element) { | |
| if (!isFrozen(array)) { | |
| array[l] = lcElement; | |
| } | |
| element = lcElement; | |
| } | |
| } | |
| set[element] = true; | |
| } | |
| return set; | |
| } | |
| function cleanArray(array) { | |
| for (let index = 0; index < array.length; index++) { | |
| const isPropertyExist = objectHasOwnProperty(array, index); | |
| if (!isPropertyExist) { | |
| array[index] = null; | |
| } | |
| } | |
| return array; | |
| } | |
| function clone(object) { | |
| const newObject = create(null); | |
| for (const [property, value2] of entries(object)) { | |
| const isPropertyExist = objectHasOwnProperty(object, property); | |
| if (isPropertyExist) { | |
| if (Array.isArray(value2)) { | |
| newObject[property] = cleanArray(value2); | |
| } else if (value2 && typeof value2 === "object" && value2.constructor === Object) { | |
| newObject[property] = clone(value2); | |
| } else { | |
| newObject[property] = value2; | |
| } | |
| } | |
| } | |
| return newObject; | |
| } | |
| function lookupGetter(object, prop) { | |
| while (object !== null) { | |
| const desc = getOwnPropertyDescriptor(object, prop); | |
| if (desc) { | |
| if (desc.get) { | |
| return unapply(desc.get); | |
| } | |
| if (typeof desc.value === "function") { | |
| return unapply(desc.value); | |
| } | |
| } | |
| object = getPrototypeOf(object); | |
| } | |
| function fallbackValue() { | |
| return null; | |
| } | |
| return fallbackValue; | |
| } | |
| var html$1 = freeze(["a", "abbr", "acronym", "address", "area", "article", "aside", "audio", "b", "bdi", "bdo", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "decorator", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "element", "em", "fieldset", "figcaption", "figure", "font", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "img", "input", "ins", "kbd", "label", "legend", "li", "main", "map", "mark", "marquee", "menu", "menuitem", "meter", "nav", "nobr", "ol", "optgroup", "option", "output", "p", "picture", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "section", "select", "shadow", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]); | |
| var svg$1 = freeze(["svg", "a", "altglyph", "altglyphdef", "altglyphitem", "animatecolor", "animatemotion", "animatetransform", "circle", "clippath", "defs", "desc", "ellipse", "filter", "font", "g", "glyph", "glyphref", "hkern", "image", "line", "lineargradient", "marker", "mask", "metadata", "mpath", "path", "pattern", "polygon", "polyline", "radialgradient", "rect", "stop", "style", "switch", "symbol", "text", "textpath", "title", "tref", "tspan", "view", "vkern"]); | |
| var svgFilters = freeze(["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence"]); | |
| var svgDisallowed = freeze(["animate", "color-profile", "cursor", "discard", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignobject", "hatch", "hatchpath", "mesh", "meshgradient", "meshpatch", "meshrow", "missing-glyph", "script", "set", "solidcolor", "unknown", "use"]); | |
| var mathMl$1 = freeze(["math", "menclose", "merror", "mfenced", "mfrac", "mglyph", "mi", "mlabeledtr", "mmultiscripts", "mn", "mo", "mover", "mpadded", "mphantom", "mroot", "mrow", "ms", "mspace", "msqrt", "mstyle", "msub", "msup", "msubsup", "mtable", "mtd", "mtext", "mtr", "munder", "munderover", "mprescripts"]); | |
| var mathMlDisallowed = freeze(["maction", "maligngroup", "malignmark", "mlongdiv", "mscarries", "mscarry", "msgroup", "mstack", "msline", "msrow", "semantics", "annotation", "annotation-xml", "mprescripts", "none"]); | |
| var text = freeze(["#text"]); | |
| var html = freeze(["accept", "action", "align", "alt", "autocapitalize", "autocomplete", "autopictureinpicture", "autoplay", "background", "bgcolor", "border", "capture", "cellpadding", "cellspacing", "checked", "cite", "class", "clear", "color", "cols", "colspan", "controls", "controlslist", "coords", "crossorigin", "datetime", "decoding", "default", "dir", "disabled", "disablepictureinpicture", "disableremoteplayback", "download", "draggable", "enctype", "enterkeyhint", "face", "for", "headers", "height", "hidden", "high", "href", "hreflang", "id", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading", "loop", "low", "max", "maxlength", "media", "method", "min", "minlength", "multiple", "muted", "name", "nonce", "noshade", "novalidate", "nowrap", "open", "optimum", "pattern", "placeholder", "playsinline", "popover", "popovertarget", "popovertargetaction", "poster", "preload", "pubdate", "radiogroup", "readonly", "rel", "required", "rev", "reversed", "role", "rows", "rowspan", "spellcheck", "scope", "selected", "shape", "size", "sizes", "span", "srclang", "start", "src", "srcset", "step", "style", "summary", "tabindex", "title", "translate", "type", "usemap", "valign", "value", "width", "wrap", "xmlns", "slot"]); | |
| var svg = freeze(["accent-height", "accumulate", "additive", "alignment-baseline", "amplitude", "ascent", "attributename", "attributetype", "azimuth", "basefrequency", "baseline-shift", "begin", "bias", "by", "class", "clip", "clippathunits", "clip-path", "clip-rule", "color", "color-interpolation", "color-interpolation-filters", "color-profile", "color-rendering", "cx", "cy", "d", "dx", "dy", "diffuseconstant", "direction", "display", "divisor", "dur", "edgemode", "elevation", "end", "exponent", "fill", "fill-opacity", "fill-rule", "filter", "filterunits", "flood-color", "flood-opacity", "font-family", "font-size", "font-size-adjust", "font-stretch", "font-style", "font-variant", "font-weight", "fx", "fy", "g1", "g2", "glyph-name", "glyphref", "gradientunits", "gradienttransform", "height", "href", "id", "image-rendering", "in", "in2", "intercept", "k", "k1", "k2", "k3", "k4", "kerning", "keypoints", "keysplines", "keytimes", "lang", "lengthadjust", "letter-spacing", "kernelmatrix", "kernelunitlength", "lighting-color", "local", "marker-end", "marker-mid", "marker-start", "markerheight", "markerunits", "markerwidth", "maskcontentunits", "maskunits", "max", "mask", "media", "method", "mode", "min", "name", "numoctaves", "offset", "operator", "opacity", "order", "orient", "orientation", "origin", "overflow", "paint-order", "path", "pathlength", "patterncontentunits", "patterntransform", "patternunits", "points", "preservealpha", "preserveaspectratio", "primitiveunits", "r", "rx", "ry", "radius", "refx", "refy", "repeatcount", "repeatdur", "restart", "result", "rotate", "scale", "seed", "shape-rendering", "slope", "specularconstant", "specularexponent", "spreadmethod", "startoffset", "stddeviation", "stitchtiles", "stop-color", "stop-opacity", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke", "stroke-width", "style", "surfacescale", "systemlanguage", "tabindex", "tablevalues", "targetx", "targety", "transform", "transform-origin", "text-anchor", "text-decoration", "text-rendering", "textlength", "type", "u1", "u2", "unicode", "values", "viewbox", "visibility", "version", "vert-adv-y", "vert-origin-x", "vert-origin-y", "width", "word-spacing", "wrap", "writing-mode", "xchannelselector", "ychannelselector", "x", "x1", "x2", "xmlns", "y", "y1", "y2", "z", "zoomandpan"]); | |
| var mathMl = freeze(["accent", "accentunder", "align", "bevelled", "close", "columnsalign", "columnlines", "columnspan", "denomalign", "depth", "dir", "display", "displaystyle", "encoding", "fence", "frame", "height", "href", "id", "largeop", "length", "linethickness", "lspace", "lquote", "mathbackground", "mathcolor", "mathsize", "mathvariant", "maxsize", "minsize", "movablelimits", "notation", "numalign", "open", "rowalign", "rowlines", "rowspacing", "rowspan", "rspace", "rquote", "scriptlevel", "scriptminsize", "scriptsizemultiplier", "selection", "separator", "separators", "stretchy", "subscriptshift", "supscriptshift", "symmetric", "voffset", "width", "xmlns"]); | |
| var xml = freeze(["xlink:href", "xml:id", "xlink:title", "xml:space", "xmlns:xlink"]); | |
| var MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); | |
| var ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); | |
| var TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); | |
| var DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); | |
| var ARIA_ATTR = seal(/^aria-[\-\w]+$/); | |
| var IS_ALLOWED_URI = seal( | |
| /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i | |
| // eslint-disable-line no-useless-escape | |
| ); | |
| var IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); | |
| var ATTR_WHITESPACE = seal( | |
| /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g | |
| // eslint-disable-line no-control-regex | |
| ); | |
| var DOCTYPE_NAME = seal(/^html$/i); | |
| var CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i); | |
| var EXPRESSIONS = /* @__PURE__ */ Object.freeze({ | |
| __proto__: null, | |
| ARIA_ATTR, | |
| ATTR_WHITESPACE, | |
| CUSTOM_ELEMENT, | |
| DATA_ATTR, | |
| DOCTYPE_NAME, | |
| ERB_EXPR, | |
| IS_ALLOWED_URI, | |
| IS_SCRIPT_OR_DATA, | |
| MUSTACHE_EXPR, | |
| TMPLIT_EXPR | |
| }); | |
| var NODE_TYPE = { | |
| element: 1, | |
| attribute: 2, | |
| text: 3, | |
| cdataSection: 4, | |
| entityReference: 5, | |
| // Deprecated | |
| entityNode: 6, | |
| // Deprecated | |
| progressingInstruction: 7, | |
| comment: 8, | |
| document: 9, | |
| documentType: 10, | |
| documentFragment: 11, | |
| notation: 12 | |
| // Deprecated | |
| }; | |
| var getGlobal = function getGlobal2() { | |
| return typeof window === "undefined" ? null : window; | |
| }; | |
| var _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTypes, purifyHostElement) { | |
| if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") { | |
| return null; | |
| } | |
| let suffix = null; | |
| const ATTR_NAME = "data-tt-policy-suffix"; | |
| if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { | |
| suffix = purifyHostElement.getAttribute(ATTR_NAME); | |
| } | |
| const policyName = "dompurify" + (suffix ? "#" + suffix : ""); | |
| try { | |
| return trustedTypes.createPolicy(policyName, { | |
| createHTML(html2) { | |
| return html2; | |
| }, | |
| createScriptURL(scriptUrl) { | |
| return scriptUrl; | |
| } | |
| }); | |
| } catch (_2) { | |
| console.warn("TrustedTypes policy " + policyName + " could not be created."); | |
| return null; | |
| } | |
| }; | |
| var _createHooksMap = function _createHooksMap2() { | |
| return { | |
| afterSanitizeAttributes: [], | |
| afterSanitizeElements: [], | |
| afterSanitizeShadowDOM: [], | |
| beforeSanitizeAttributes: [], | |
| beforeSanitizeElements: [], | |
| beforeSanitizeShadowDOM: [], | |
| uponSanitizeAttribute: [], | |
| uponSanitizeElement: [], | |
| uponSanitizeShadowNode: [] | |
| }; | |
| }; | |
| function createDOMPurify() { | |
| let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal(); | |
| const DOMPurify = (root) => createDOMPurify(root); | |
| DOMPurify.version = "3.2.6"; | |
| DOMPurify.removed = []; | |
| if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) { | |
| DOMPurify.isSupported = false; | |
| return DOMPurify; | |
| } | |
| let { | |
| document: document2 | |
| } = window2; | |
| const originalDocument = document2; | |
| const currentScript = originalDocument.currentScript; | |
| const { | |
| DocumentFragment, | |
| HTMLTemplateElement, | |
| Node, | |
| Element, | |
| NodeFilter, | |
| NamedNodeMap = window2.NamedNodeMap || window2.MozNamedAttrMap, | |
| HTMLFormElement, | |
| DOMParser, | |
| trustedTypes | |
| } = window2; | |
| const ElementPrototype = Element.prototype; | |
| const cloneNode = lookupGetter(ElementPrototype, "cloneNode"); | |
| const remove = lookupGetter(ElementPrototype, "remove"); | |
| const getNextSibling = lookupGetter(ElementPrototype, "nextSibling"); | |
| const getChildNodes = lookupGetter(ElementPrototype, "childNodes"); | |
| const getParentNode = lookupGetter(ElementPrototype, "parentNode"); | |
| if (typeof HTMLTemplateElement === "function") { | |
| const template = document2.createElement("template"); | |
| if (template.content && template.content.ownerDocument) { | |
| document2 = template.content.ownerDocument; | |
| } | |
| } | |
| let trustedTypesPolicy; | |
| let emptyHTML = ""; | |
| const { | |
| implementation, | |
| createNodeIterator, | |
| createDocumentFragment, | |
| getElementsByTagName | |
| } = document2; | |
| const { | |
| importNode | |
| } = originalDocument; | |
| let hooks = _createHooksMap(); | |
| DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0; | |
| const { | |
| MUSTACHE_EXPR: MUSTACHE_EXPR2, | |
| ERB_EXPR: ERB_EXPR2, | |
| TMPLIT_EXPR: TMPLIT_EXPR2, | |
| DATA_ATTR: DATA_ATTR2, | |
| ARIA_ATTR: ARIA_ATTR2, | |
| IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA2, | |
| ATTR_WHITESPACE: ATTR_WHITESPACE2, | |
| CUSTOM_ELEMENT: CUSTOM_ELEMENT2 | |
| } = EXPRESSIONS; | |
| let { | |
| IS_ALLOWED_URI: IS_ALLOWED_URI$1 | |
| } = EXPRESSIONS; | |
| let ALLOWED_TAGS = null; | |
| const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]); | |
| let ALLOWED_ATTR = null; | |
| const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]); | |
| let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, { | |
| tagNameCheck: { | |
| writable: true, | |
| configurable: false, | |
| enumerable: true, | |
| value: null | |
| }, | |
| attributeNameCheck: { | |
| writable: true, | |
| configurable: false, | |
| enumerable: true, | |
| value: null | |
| }, | |
| allowCustomizedBuiltInElements: { | |
| writable: true, | |
| configurable: false, | |
| enumerable: true, | |
| value: false | |
| } | |
| })); | |
| let FORBID_TAGS = null; | |
| let FORBID_ATTR = null; | |
| let ALLOW_ARIA_ATTR = true; | |
| let ALLOW_DATA_ATTR = true; | |
| let ALLOW_UNKNOWN_PROTOCOLS = false; | |
| let ALLOW_SELF_CLOSE_IN_ATTR = true; | |
| let SAFE_FOR_TEMPLATES = false; | |
| let SAFE_FOR_XML = true; | |
| let WHOLE_DOCUMENT = false; | |
| let SET_CONFIG = false; | |
| let FORCE_BODY = false; | |
| let RETURN_DOM = false; | |
| let RETURN_DOM_FRAGMENT = false; | |
| let RETURN_TRUSTED_TYPE = false; | |
| let SANITIZE_DOM = true; | |
| let SANITIZE_NAMED_PROPS = false; | |
| const SANITIZE_NAMED_PROPS_PREFIX = "user-content-"; | |
| let KEEP_CONTENT = true; | |
| let IN_PLACE = false; | |
| let USE_PROFILES = {}; | |
| let FORBID_CONTENTS = null; | |
| const DEFAULT_FORBID_CONTENTS = addToSet({}, ["annotation-xml", "audio", "colgroup", "desc", "foreignobject", "head", "iframe", "math", "mi", "mn", "mo", "ms", "mtext", "noembed", "noframes", "noscript", "plaintext", "script", "style", "svg", "template", "thead", "title", "video", "xmp"]); | |
| let DATA_URI_TAGS = null; | |
| const DEFAULT_DATA_URI_TAGS = addToSet({}, ["audio", "video", "img", "source", "image", "track"]); | |
| let URI_SAFE_ATTRIBUTES = null; | |
| const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ["alt", "class", "for", "id", "label", "name", "pattern", "placeholder", "role", "summary", "title", "value", "style", "xmlns"]); | |
| const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML"; | |
| const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; | |
| const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml"; | |
| let NAMESPACE = HTML_NAMESPACE; | |
| let IS_EMPTY_INPUT = false; | |
| let ALLOWED_NAMESPACES = null; | |
| const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString); | |
| let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ["mi", "mo", "mn", "ms", "mtext"]); | |
| let HTML_INTEGRATION_POINTS = addToSet({}, ["annotation-xml"]); | |
| const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ["title", "style", "font", "a", "script"]); | |
| let PARSER_MEDIA_TYPE = null; | |
| const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"]; | |
| const DEFAULT_PARSER_MEDIA_TYPE = "text/html"; | |
| let transformCaseFunc = null; | |
| let CONFIG = null; | |
| const formElement = document2.createElement("form"); | |
| const isRegexOrFunction = function isRegexOrFunction2(testValue) { | |
| return testValue instanceof RegExp || testValue instanceof Function; | |
| }; | |
| const _parseConfig = function _parseConfig2() { | |
| let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; | |
| if (CONFIG && CONFIG === cfg) { | |
| return; | |
| } | |
| if (!cfg || typeof cfg !== "object") { | |
| cfg = {}; | |
| } | |
| cfg = clone(cfg); | |
| PARSER_MEDIA_TYPE = // eslint-disable-next-line unicorn/prefer-includes | |
| SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE; | |
| transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase; | |
| ALLOWED_TAGS = objectHasOwnProperty(cfg, "ALLOWED_TAGS") ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS; | |
| ALLOWED_ATTR = objectHasOwnProperty(cfg, "ALLOWED_ATTR") ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR; | |
| ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, "ALLOWED_NAMESPACES") ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES; | |
| URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES; | |
| DATA_URI_TAGS = objectHasOwnProperty(cfg, "ADD_DATA_URI_TAGS") ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS; | |
| FORBID_CONTENTS = objectHasOwnProperty(cfg, "FORBID_CONTENTS") ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS; | |
| FORBID_TAGS = objectHasOwnProperty(cfg, "FORBID_TAGS") ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({}); | |
| FORBID_ATTR = objectHasOwnProperty(cfg, "FORBID_ATTR") ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({}); | |
| USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES : false; | |
| ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; | |
| ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; | |
| ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; | |
| ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; | |
| SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; | |
| SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; | |
| WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; | |
| RETURN_DOM = cfg.RETURN_DOM || false; | |
| RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; | |
| RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; | |
| FORCE_BODY = cfg.FORCE_BODY || false; | |
| SANITIZE_DOM = cfg.SANITIZE_DOM !== false; | |
| SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; | |
| KEEP_CONTENT = cfg.KEEP_CONTENT !== false; | |
| IN_PLACE = cfg.IN_PLACE || false; | |
| IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI; | |
| NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; | |
| MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS; | |
| HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS; | |
| CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {}; | |
| if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) { | |
| CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; | |
| } | |
| if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) { | |
| CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck; | |
| } | |
| if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === "boolean") { | |
| CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; | |
| } | |
| if (SAFE_FOR_TEMPLATES) { | |
| ALLOW_DATA_ATTR = false; | |
| } | |
| if (RETURN_DOM_FRAGMENT) { | |
| RETURN_DOM = true; | |
| } | |
| if (USE_PROFILES) { | |
| ALLOWED_TAGS = addToSet({}, text); | |
| ALLOWED_ATTR = []; | |
| if (USE_PROFILES.html === true) { | |
| addToSet(ALLOWED_TAGS, html$1); | |
| addToSet(ALLOWED_ATTR, html); | |
| } | |
| if (USE_PROFILES.svg === true) { | |
| addToSet(ALLOWED_TAGS, svg$1); | |
| addToSet(ALLOWED_ATTR, svg); | |
| addToSet(ALLOWED_ATTR, xml); | |
| } | |
| if (USE_PROFILES.svgFilters === true) { | |
| addToSet(ALLOWED_TAGS, svgFilters); | |
| addToSet(ALLOWED_ATTR, svg); | |
| addToSet(ALLOWED_ATTR, xml); | |
| } | |
| if (USE_PROFILES.mathMl === true) { | |
| addToSet(ALLOWED_TAGS, mathMl$1); | |
| addToSet(ALLOWED_ATTR, mathMl); | |
| addToSet(ALLOWED_ATTR, xml); | |
| } | |
| } | |
| if (cfg.ADD_TAGS) { | |
| if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { | |
| ALLOWED_TAGS = clone(ALLOWED_TAGS); | |
| } | |
| addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); | |
| } | |
| if (cfg.ADD_ATTR) { | |
| if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { | |
| ALLOWED_ATTR = clone(ALLOWED_ATTR); | |
| } | |
| addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); | |
| } | |
| if (cfg.ADD_URI_SAFE_ATTR) { | |
| addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); | |
| } | |
| if (cfg.FORBID_CONTENTS) { | |
| if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { | |
| FORBID_CONTENTS = clone(FORBID_CONTENTS); | |
| } | |
| addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); | |
| } | |
| if (KEEP_CONTENT) { | |
| ALLOWED_TAGS["#text"] = true; | |
| } | |
| if (WHOLE_DOCUMENT) { | |
| addToSet(ALLOWED_TAGS, ["html", "head", "body"]); | |
| } | |
| if (ALLOWED_TAGS.table) { | |
| addToSet(ALLOWED_TAGS, ["tbody"]); | |
| delete FORBID_TAGS.tbody; | |
| } | |
| if (cfg.TRUSTED_TYPES_POLICY) { | |
| if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") { | |
| throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.'); | |
| } | |
| if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") { | |
| throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.'); | |
| } | |
| trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; | |
| emptyHTML = trustedTypesPolicy.createHTML(""); | |
| } else { | |
| if (trustedTypesPolicy === void 0) { | |
| trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript); | |
| } | |
| if (trustedTypesPolicy !== null && typeof emptyHTML === "string") { | |
| emptyHTML = trustedTypesPolicy.createHTML(""); | |
| } | |
| } | |
| if (freeze) { | |
| freeze(cfg); | |
| } | |
| CONFIG = cfg; | |
| }; | |
| const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]); | |
| const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]); | |
| const _checkValidNamespace = function _checkValidNamespace2(element) { | |
| let parent = getParentNode(element); | |
| if (!parent || !parent.tagName) { | |
| parent = { | |
| namespaceURI: NAMESPACE, | |
| tagName: "template" | |
| }; | |
| } | |
| const tagName = stringToLowerCase(element.tagName); | |
| const parentTagName = stringToLowerCase(parent.tagName); | |
| if (!ALLOWED_NAMESPACES[element.namespaceURI]) { | |
| return false; | |
| } | |
| if (element.namespaceURI === SVG_NAMESPACE) { | |
| if (parent.namespaceURI === HTML_NAMESPACE) { | |
| return tagName === "svg"; | |
| } | |
| if (parent.namespaceURI === MATHML_NAMESPACE) { | |
| return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); | |
| } | |
| return Boolean(ALL_SVG_TAGS[tagName]); | |
| } | |
| if (element.namespaceURI === MATHML_NAMESPACE) { | |
| if (parent.namespaceURI === HTML_NAMESPACE) { | |
| return tagName === "math"; | |
| } | |
| if (parent.namespaceURI === SVG_NAMESPACE) { | |
| return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName]; | |
| } | |
| return Boolean(ALL_MATHML_TAGS[tagName]); | |
| } | |
| if (element.namespaceURI === HTML_NAMESPACE) { | |
| if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { | |
| return false; | |
| } | |
| if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { | |
| return false; | |
| } | |
| return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); | |
| } | |
| if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) { | |
| return true; | |
| } | |
| return false; | |
| }; | |
| const _forceRemove = function _forceRemove2(node) { | |
| arrayPush(DOMPurify.removed, { | |
| element: node | |
| }); | |
| try { | |
| getParentNode(node).removeChild(node); | |
| } catch (_2) { | |
| remove(node); | |
| } | |
| }; | |
| const _removeAttribute = function _removeAttribute2(name, element) { | |
| try { | |
| arrayPush(DOMPurify.removed, { | |
| attribute: element.getAttributeNode(name), | |
| from: element | |
| }); | |
| } catch (_2) { | |
| arrayPush(DOMPurify.removed, { | |
| attribute: null, | |
| from: element | |
| }); | |
| } | |
| element.removeAttribute(name); | |
| if (name === "is") { | |
| if (RETURN_DOM || RETURN_DOM_FRAGMENT) { | |
| try { | |
| _forceRemove(element); | |
| } catch (_2) { | |
| } | |
| } else { | |
| try { | |
| element.setAttribute(name, ""); | |
| } catch (_2) { | |
| } | |
| } | |
| } | |
| }; | |
| const _initDocument = function _initDocument2(dirty) { | |
| let doc = null; | |
| let leadingWhitespace = null; | |
| if (FORCE_BODY) { | |
| dirty = "<remove></remove>" + dirty; | |
| } else { | |
| const matches = stringMatch(dirty, /^[\r\n\t ]+/); | |
| leadingWhitespace = matches && matches[0]; | |
| } | |
| if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) { | |
| dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + "</body></html>"; | |
| } | |
| const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; | |
| if (NAMESPACE === HTML_NAMESPACE) { | |
| try { | |
| doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); | |
| } catch (_2) { | |
| } | |
| } | |
| if (!doc || !doc.documentElement) { | |
| doc = implementation.createDocument(NAMESPACE, "template", null); | |
| try { | |
| doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; | |
| } catch (_2) { | |
| } | |
| } | |
| const body = doc.body || doc.documentElement; | |
| if (dirty && leadingWhitespace) { | |
| body.insertBefore(document2.createTextNode(leadingWhitespace), body.childNodes[0] || null); | |
| } | |
| if (NAMESPACE === HTML_NAMESPACE) { | |
| return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0]; | |
| } | |
| return WHOLE_DOCUMENT ? doc.documentElement : body; | |
| }; | |
| const _createNodeIterator = function _createNodeIterator2(root) { | |
| return createNodeIterator.call( | |
| root.ownerDocument || root, | |
| root, | |
| // eslint-disable-next-line no-bitwise | |
| NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, | |
| null | |
| ); | |
| }; | |
| const _isClobbered = function _isClobbered2(element) { | |
| return element instanceof HTMLFormElement && (typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function"); | |
| }; | |
| const _isNode = function _isNode2(value2) { | |
| return typeof Node === "function" && value2 instanceof Node; | |
| }; | |
| function _executeHooks(hooks2, currentNode, data) { | |
| arrayForEach(hooks2, (hook) => { | |
| hook.call(DOMPurify, currentNode, data, CONFIG); | |
| }); | |
| } | |
| const _sanitizeElements = function _sanitizeElements2(currentNode) { | |
| let content = null; | |
| _executeHooks(hooks.beforeSanitizeElements, currentNode, null); | |
| if (_isClobbered(currentNode)) { | |
| _forceRemove(currentNode); | |
| return true; | |
| } | |
| const tagName = transformCaseFunc(currentNode.nodeName); | |
| _executeHooks(hooks.uponSanitizeElement, currentNode, { | |
| tagName, | |
| allowedTags: ALLOWED_TAGS | |
| }); | |
| if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) { | |
| _forceRemove(currentNode); | |
| return true; | |
| } | |
| if (currentNode.nodeType === NODE_TYPE.progressingInstruction) { | |
| _forceRemove(currentNode); | |
| return true; | |
| } | |
| if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) { | |
| _forceRemove(currentNode); | |
| return true; | |
| } | |
| if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { | |
| if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { | |
| if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) { | |
| return false; | |
| } | |
| if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) { | |
| return false; | |
| } | |
| } | |
| if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { | |
| const parentNode = getParentNode(currentNode) || currentNode.parentNode; | |
| const childNodes = getChildNodes(currentNode) || currentNode.childNodes; | |
| if (childNodes && parentNode) { | |
| const childCount = childNodes.length; | |
| for (let i = childCount - 1; i >= 0; --i) { | |
| const childClone = cloneNode(childNodes[i], true); | |
| childClone.__removalCount = (currentNode.__removalCount || 0) + 1; | |
| parentNode.insertBefore(childClone, getNextSibling(currentNode)); | |
| } | |
| } | |
| } | |
| _forceRemove(currentNode); | |
| return true; | |
| } | |
| if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { | |
| _forceRemove(currentNode); | |
| return true; | |
| } | |
| if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { | |
| _forceRemove(currentNode); | |
| return true; | |
| } | |
| if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) { | |
| content = currentNode.textContent; | |
| arrayForEach([MUSTACHE_EXPR2, ERB_EXPR2, TMPLIT_EXPR2], (expr) => { | |
| content = stringReplace(content, expr, " "); | |
| }); | |
| if (currentNode.textContent !== content) { | |
| arrayPush(DOMPurify.removed, { | |
| element: currentNode.cloneNode() | |
| }); | |
| currentNode.textContent = content; | |
| } | |
| } | |
| _executeHooks(hooks.afterSanitizeElements, currentNode, null); | |
| return false; | |
| }; | |
| const _isValidAttribute = function _isValidAttribute2(lcTag, lcName, value2) { | |
| if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value2 in document2 || value2 in formElement)) { | |
| return false; | |
| } | |
| if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR2, lcName)) ; | |
| else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR2, lcName)) ; | |
| else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { | |
| if ( | |
| // First condition does a very basic check if a) it's basically a valid custom element tagname AND | |
| // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck | |
| // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck | |
| _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) || // Alternative, second condition checks if it's an `is`-attribute, AND | |
| // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck | |
| lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value2) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value2)) | |
| ) ; | |
| else { | |
| return false; | |
| } | |
| } else if (URI_SAFE_ATTRIBUTES[lcName]) ; | |
| else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value2, ATTR_WHITESPACE2, ""))) ; | |
| else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value2, "data:") === 0 && DATA_URI_TAGS[lcTag]) ; | |
| else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA2, stringReplace(value2, ATTR_WHITESPACE2, ""))) ; | |
| else if (value2) { | |
| return false; | |
| } else ; | |
| return true; | |
| }; | |
| const _isBasicCustomElement = function _isBasicCustomElement2(tagName) { | |
| return tagName !== "annotation-xml" && stringMatch(tagName, CUSTOM_ELEMENT2); | |
| }; | |
| const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) { | |
| _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null); | |
| const { | |
| attributes | |
| } = currentNode; | |
| if (!attributes || _isClobbered(currentNode)) { | |
| return; | |
| } | |
| const hookEvent = { | |
| attrName: "", | |
| attrValue: "", | |
| keepAttr: true, | |
| allowedAttributes: ALLOWED_ATTR, | |
| forceKeepAttr: void 0 | |
| }; | |
| let l = attributes.length; | |
| while (l--) { | |
| const attr = attributes[l]; | |
| const { | |
| name, | |
| namespaceURI, | |
| value: attrValue | |
| } = attr; | |
| const lcName = transformCaseFunc(name); | |
| const initValue = attrValue; | |
| let value2 = name === "value" ? initValue : stringTrim(initValue); | |
| hookEvent.attrName = lcName; | |
| hookEvent.attrValue = value2; | |
| hookEvent.keepAttr = true; | |
| hookEvent.forceKeepAttr = void 0; | |
| _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent); | |
| value2 = hookEvent.attrValue; | |
| if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name")) { | |
| _removeAttribute(name, currentNode); | |
| value2 = SANITIZE_NAMED_PROPS_PREFIX + value2; | |
| } | |
| if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value2)) { | |
| _removeAttribute(name, currentNode); | |
| continue; | |
| } | |
| if (hookEvent.forceKeepAttr) { | |
| continue; | |
| } | |
| if (!hookEvent.keepAttr) { | |
| _removeAttribute(name, currentNode); | |
| continue; | |
| } | |
| if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value2)) { | |
| _removeAttribute(name, currentNode); | |
| continue; | |
| } | |
| if (SAFE_FOR_TEMPLATES) { | |
| arrayForEach([MUSTACHE_EXPR2, ERB_EXPR2, TMPLIT_EXPR2], (expr) => { | |
| value2 = stringReplace(value2, expr, " "); | |
| }); | |
| } | |
| const lcTag = transformCaseFunc(currentNode.nodeName); | |
| if (!_isValidAttribute(lcTag, lcName, value2)) { | |
| _removeAttribute(name, currentNode); | |
| continue; | |
| } | |
| if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function") { | |
| if (namespaceURI) ; | |
| else { | |
| switch (trustedTypes.getAttributeType(lcTag, lcName)) { | |
| case "TrustedHTML": { | |
| value2 = trustedTypesPolicy.createHTML(value2); | |
| break; | |
| } | |
| case "TrustedScriptURL": { | |
| value2 = trustedTypesPolicy.createScriptURL(value2); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| if (value2 !== initValue) { | |
| try { | |
| if (namespaceURI) { | |
| currentNode.setAttributeNS(namespaceURI, name, value2); | |
| } else { | |
| currentNode.setAttribute(name, value2); | |
| } | |
| if (_isClobbered(currentNode)) { | |
| _forceRemove(currentNode); | |
| } else { | |
| arrayPop(DOMPurify.removed); | |
| } | |
| } catch (_2) { | |
| _removeAttribute(name, currentNode); | |
| } | |
| } | |
| } | |
| _executeHooks(hooks.afterSanitizeAttributes, currentNode, null); | |
| }; | |
| const _sanitizeShadowDOM = function _sanitizeShadowDOM2(fragment) { | |
| let shadowNode = null; | |
| const shadowIterator = _createNodeIterator(fragment); | |
| _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null); | |
| while (shadowNode = shadowIterator.nextNode()) { | |
| _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null); | |
| _sanitizeElements(shadowNode); | |
| _sanitizeAttributes(shadowNode); | |
| if (shadowNode.content instanceof DocumentFragment) { | |
| _sanitizeShadowDOM2(shadowNode.content); | |
| } | |
| } | |
| _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null); | |
| }; | |
| DOMPurify.sanitize = function(dirty) { | |
| let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; | |
| let body = null; | |
| let importedNode = null; | |
| let currentNode = null; | |
| let returnNode = null; | |
| IS_EMPTY_INPUT = !dirty; | |
| if (IS_EMPTY_INPUT) { | |
| dirty = "<!-->"; | |
| } | |
| if (typeof dirty !== "string" && !_isNode(dirty)) { | |
| if (typeof dirty.toString === "function") { | |
| dirty = dirty.toString(); | |
| if (typeof dirty !== "string") { | |
| throw typeErrorCreate("dirty is not a string, aborting"); | |
| } | |
| } else { | |
| throw typeErrorCreate("toString is not a function"); | |
| } | |
| } | |
| if (!DOMPurify.isSupported) { | |
| return dirty; | |
| } | |
| if (!SET_CONFIG) { | |
| _parseConfig(cfg); | |
| } | |
| DOMPurify.removed = []; | |
| if (typeof dirty === "string") { | |
| IN_PLACE = false; | |
| } | |
| if (IN_PLACE) { | |
| if (dirty.nodeName) { | |
| const tagName = transformCaseFunc(dirty.nodeName); | |
| if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { | |
| throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place"); | |
| } | |
| } | |
| } else if (dirty instanceof Node) { | |
| body = _initDocument("<!---->"); | |
| importedNode = body.ownerDocument.importNode(dirty, true); | |
| if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") { | |
| body = importedNode; | |
| } else if (importedNode.nodeName === "HTML") { | |
| body = importedNode; | |
| } else { | |
| body.appendChild(importedNode); | |
| } | |
| } else { | |
| if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes | |
| dirty.indexOf("<") === -1) { | |
| return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty; | |
| } | |
| body = _initDocument(dirty); | |
| if (!body) { | |
| return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ""; | |
| } | |
| } | |
| if (body && FORCE_BODY) { | |
| _forceRemove(body.firstChild); | |
| } | |
| const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body); | |
| while (currentNode = nodeIterator.nextNode()) { | |
| _sanitizeElements(currentNode); | |
| _sanitizeAttributes(currentNode); | |
| if (currentNode.content instanceof DocumentFragment) { | |
| _sanitizeShadowDOM(currentNode.content); | |
| } | |
| } | |
| if (IN_PLACE) { | |
| return dirty; | |
| } | |
| if (RETURN_DOM) { | |
| if (RETURN_DOM_FRAGMENT) { | |
| returnNode = createDocumentFragment.call(body.ownerDocument); | |
| while (body.firstChild) { | |
| returnNode.appendChild(body.firstChild); | |
| } | |
| } else { | |
| returnNode = body; | |
| } | |
| if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { | |
| returnNode = importNode.call(originalDocument, returnNode, true); | |
| } | |
| return returnNode; | |
| } | |
| let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; | |
| if (WHOLE_DOCUMENT && ALLOWED_TAGS["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { | |
| serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML; | |
| } | |
| if (SAFE_FOR_TEMPLATES) { | |
| arrayForEach([MUSTACHE_EXPR2, ERB_EXPR2, TMPLIT_EXPR2], (expr) => { | |
| serializedHTML = stringReplace(serializedHTML, expr, " "); | |
| }); | |
| } | |
| return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; | |
| }; | |
| DOMPurify.setConfig = function() { | |
| let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; | |
| _parseConfig(cfg); | |
| SET_CONFIG = true; | |
| }; | |
| DOMPurify.clearConfig = function() { | |
| CONFIG = null; | |
| SET_CONFIG = false; | |
| }; | |
| DOMPurify.isValidAttribute = function(tag, attr, value2) { | |
| if (!CONFIG) { | |
| _parseConfig({}); | |
| } | |
| const lcTag = transformCaseFunc(tag); | |
| const lcName = transformCaseFunc(attr); | |
| return _isValidAttribute(lcTag, lcName, value2); | |
| }; | |
| DOMPurify.addHook = function(entryPoint, hookFunction) { | |
| if (typeof hookFunction !== "function") { | |
| return; | |
| } | |
| arrayPush(hooks[entryPoint], hookFunction); | |
| }; | |
| DOMPurify.removeHook = function(entryPoint, hookFunction) { | |
| if (hookFunction !== void 0) { | |
| const index = arrayLastIndexOf(hooks[entryPoint], hookFunction); | |
| return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0]; | |
| } | |
| return arrayPop(hooks[entryPoint]); | |
| }; | |
| DOMPurify.removeHooks = function(entryPoint) { | |
| hooks[entryPoint] = []; | |
| }; | |
| DOMPurify.removeAllHooks = function() { | |
| hooks = _createHooksMap(); | |
| }; | |
| return DOMPurify; | |
| } | |
| var purify = createDOMPurify(); | |
| // src/script.ts | |
| document.addEventListener("DOMContentLoaded", () => { | |
| const socket = lookup2(); | |
| const INITIALIZATION_TIMEOUT_MS = 1e4; | |
| const MAX_LOGS = 500; | |
| const connectBtn = document.getElementById( | |
| "connect-btn" | |
| ); | |
| const agentCardUrlInput = document.getElementById( | |
| "agent-card-url" | |
| ); | |
| const httpHeadersToggle = document.getElementById( | |
| "http-headers-toggle" | |
| ); | |
| const httpHeadersContent = document.getElementById( | |
| "http-headers-content" | |
| ); | |
| const headersList = document.getElementById("headers-list"); | |
| const addHeaderBtn = document.getElementById( | |
| "add-header-btn" | |
| ); | |
| const messageMetadataToggle = document.getElementById( | |
| "message-metadata-toggle" | |
| ); | |
| const messageMetadataContent = document.getElementById( | |
| "message-metadata-content" | |
| ); | |
| const metadataList = document.getElementById("metadata-list"); | |
| const addMetadataBtn = document.getElementById( | |
| "add-metadata-btn" | |
| ); | |
| const collapsibleHeader = document.querySelector( | |
| ".collapsible-header" | |
| ); | |
| const collapsibleContent = document.querySelector( | |
| ".collapsible-content" | |
| ); | |
| const agentCardCodeContent = document.getElementById( | |
| "agent-card-content" | |
| ); | |
| const validationErrorsContainer = document.getElementById( | |
| "validation-errors" | |
| ); | |
| const chatInput = document.getElementById("chat-input"); | |
| const sendBtn = document.getElementById("send-btn"); | |
| const chatMessages = document.getElementById("chat-messages"); | |
| const debugConsole = document.getElementById("debug-console"); | |
| const debugHandle = document.getElementById("debug-handle"); | |
| const debugContent = document.getElementById("debug-content"); | |
| const clearConsoleBtn = document.getElementById( | |
| "clear-console-btn" | |
| ); | |
| const toggleConsoleBtn = document.getElementById( | |
| "toggle-console-btn" | |
| ); | |
| const jsonModal = document.getElementById("json-modal"); | |
| const modalJsonContent = document.getElementById( | |
| "modal-json-content" | |
| ); | |
| const modalCloseBtn = document.querySelector( | |
| ".modal-close-btn" | |
| ); | |
| let isResizing = false; | |
| const rawLogStore = {}; | |
| const messageJsonStore = {}; | |
| const logIdQueue = []; | |
| let initializationTimeout; | |
| let isProcessingLogQueue = false; | |
| debugHandle.addEventListener("mousedown", (e) => { | |
| const target = e.target; | |
| if (target === debugHandle || target.tagName === "SPAN") { | |
| isResizing = true; | |
| document.body.style.userSelect = "none"; | |
| document.body.style.pointerEvents = "none"; | |
| } | |
| }); | |
| window.addEventListener("mousemove", (e) => { | |
| if (!isResizing) return; | |
| const newHeight = window.innerHeight - e.clientY; | |
| if (newHeight > 40 && newHeight < window.innerHeight * 0.9) { | |
| debugConsole.style.height = `${newHeight}px`; | |
| } | |
| }); | |
| window.addEventListener("mouseup", () => { | |
| isResizing = false; | |
| document.body.style.userSelect = ""; | |
| document.body.style.pointerEvents = ""; | |
| }); | |
| collapsibleHeader.addEventListener("click", () => { | |
| collapsibleHeader.classList.toggle("collapsed"); | |
| collapsibleContent.classList.toggle("collapsed"); | |
| collapsibleContent.style.overflow = "hidden"; | |
| }); | |
| collapsibleContent.addEventListener("transitionend", () => { | |
| if (!collapsibleContent.classList.contains("collapsed")) { | |
| collapsibleContent.style.overflow = "auto"; | |
| } | |
| }); | |
| function setupToggle(toggleElement, contentElement) { | |
| if (!toggleElement || !contentElement) return; | |
| toggleElement.addEventListener("click", () => { | |
| const isExpanded = contentElement.classList.toggle("expanded"); | |
| const toggleIcon = toggleElement.querySelector(".toggle-icon"); | |
| if (toggleIcon) { | |
| toggleIcon.textContent = isExpanded ? "\u25BC" : "\u25BA"; | |
| } | |
| }); | |
| } | |
| setupToggle(httpHeadersToggle, httpHeadersContent); | |
| setupToggle(messageMetadataToggle, messageMetadataContent); | |
| addHeaderBtn.addEventListener("click", () => addHeaderField()); | |
| addMetadataBtn.addEventListener("click", () => addMetadataField()); | |
| function setupRemoveItemListener(listElement, removeBtnSelector, itemSelector) { | |
| listElement.addEventListener("click", (event) => { | |
| const removeBtn = event.target.closest( | |
| removeBtnSelector | |
| ); | |
| if (removeBtn) { | |
| removeBtn.closest(itemSelector)?.remove(); | |
| } | |
| }); | |
| } | |
| setupRemoveItemListener(headersList, ".remove-header-btn", ".header-item"); | |
| setupRemoveItemListener( | |
| metadataList, | |
| ".remove-metadata-btn", | |
| ".metadata-item" | |
| ); | |
| function addKeyValueField(list, classes, placeholders, removeLabel, key = "", value2 = "") { | |
| const itemHTML = ` | |
| <div class="${classes.item}"> | |
| <input type="text" class="${classes.key}" placeholder="${placeholders.key}" value="${key}"> | |
| <input type="text" class="${classes.value}" placeholder="${placeholders.value}" value="${value2}"> | |
| <button type="button" class="${classes.removeBtn}" aria-label="${removeLabel}">\xD7</button> | |
| </div> | |
| `; | |
| list.insertAdjacentHTML("beforeend", itemHTML); | |
| } | |
| function addHeaderField(name = "", value2 = "") { | |
| addKeyValueField( | |
| headersList, | |
| { | |
| item: "header-item", | |
| key: "header-name", | |
| value: "header-value", | |
| removeBtn: "remove-header-btn" | |
| }, | |
| { key: "Header Name", value: "Header Value" }, | |
| "Remove header", | |
| name, | |
| value2 | |
| ); | |
| } | |
| function addMetadataField(key = "", value2 = "") { | |
| addKeyValueField( | |
| metadataList, | |
| { | |
| item: "metadata-item", | |
| key: "metadata-key", | |
| value: "metadata-value", | |
| removeBtn: "remove-metadata-btn" | |
| }, | |
| { key: "Metadata Key", value: "Metadata Value" }, | |
| "Remove metadata", | |
| key, | |
| value2 | |
| ); | |
| } | |
| function getKeyValuePairs(list, itemSelector, keySelector, valueSelector) { | |
| const items = list.querySelectorAll(itemSelector); | |
| return Array.from(items).reduce( | |
| (acc, item) => { | |
| const keyInput = item.querySelector(keySelector); | |
| const valueInput = item.querySelector( | |
| valueSelector | |
| ); | |
| const key = keyInput?.value.trim(); | |
| const value2 = valueInput?.value.trim(); | |
| if (key && value2) { | |
| acc[key] = value2; | |
| } | |
| return acc; | |
| }, | |
| {} | |
| ); | |
| } | |
| function getCustomHeaders() { | |
| return getKeyValuePairs( | |
| headersList, | |
| ".header-item", | |
| ".header-name", | |
| ".header-value" | |
| ); | |
| } | |
| function getMessageMetadata() { | |
| return getKeyValuePairs( | |
| metadataList, | |
| ".metadata-item", | |
| ".metadata-key", | |
| ".metadata-value" | |
| ); | |
| } | |
| clearConsoleBtn.addEventListener("click", () => { | |
| debugContent.innerHTML = ""; | |
| Object.keys(rawLogStore).forEach((key) => delete rawLogStore[key]); | |
| logIdQueue.length = 0; | |
| }); | |
| toggleConsoleBtn.addEventListener("click", () => { | |
| const isHidden = debugConsole.classList.toggle("hidden"); | |
| toggleConsoleBtn.textContent = isHidden ? "Show" : "Hide"; | |
| }); | |
| modalCloseBtn.addEventListener( | |
| "click", | |
| () => jsonModal.classList.add("hidden") | |
| ); | |
| jsonModal.addEventListener("click", (e) => { | |
| if (e.target === jsonModal) { | |
| jsonModal.classList.add("hidden"); | |
| } | |
| }); | |
| const showJsonInModal = (jsonData) => { | |
| if (jsonData) { | |
| let jsonString = JSON.stringify(jsonData, null, 2); | |
| jsonString = jsonString.replace( | |
| /"method": "([^"]+)"/g, | |
| '<span class="json-highlight">"method": "$1"</span>' | |
| ); | |
| modalJsonContent.innerHTML = jsonString; | |
| jsonModal.classList.remove("hidden"); | |
| } | |
| }; | |
| connectBtn.addEventListener("click", async () => { | |
| let agentCardUrl = agentCardUrlInput.value.trim(); | |
| if (!agentCardUrl) { | |
| alert("Please enter an agent card URL."); | |
| return; | |
| } | |
| if (!/^[a-zA-Z]+:\/\//.test(agentCardUrl)) { | |
| agentCardUrl = "http://" + agentCardUrl; | |
| } | |
| try { | |
| const url2 = new URL(agentCardUrl); | |
| if (url2.protocol !== "http:" && url2.protocol !== "https:") { | |
| throw new Error("Protocol must be http or https."); | |
| } | |
| } catch (error) { | |
| alert( | |
| "Invalid URL. Please enter a valid URL starting with http:// or https://." | |
| ); | |
| return; | |
| } | |
| agentCardCodeContent.textContent = ""; | |
| validationErrorsContainer.innerHTML = '<div class="loader"></div><p class="placeholder-text">Fetching Agent Card...</p>'; | |
| chatInput.disabled = true; | |
| sendBtn.disabled = true; | |
| const customHeaders = getCustomHeaders(); | |
| const requestHeaders = { | |
| "Content-Type": "application/json", | |
| ...customHeaders | |
| }; | |
| try { | |
| const response = await fetch("/agent-card", { | |
| method: "POST", | |
| headers: requestHeaders, | |
| body: JSON.stringify({ url: agentCardUrl, sid: socket.id }) | |
| }); | |
| const data = await response.json(); | |
| if (!response.ok) { | |
| throw new Error(data.error || `HTTP error! status: ${response.status}`); | |
| } | |
| agentCardCodeContent.textContent = JSON.stringify(data.card, null, 2); | |
| if (window.hljs) { | |
| window.hljs.highlightElement(agentCardCodeContent); | |
| } else { | |
| console.warn("highlight.js not loaded. Syntax highlighting skipped."); | |
| } | |
| validationErrorsContainer.innerHTML = '<p class="placeholder-text">Initializing client session...</p>'; | |
| initializationTimeout = setTimeout(() => { | |
| validationErrorsContainer.innerHTML = '<p class="error-text">Error: Client initialization timed out.</p>'; | |
| chatInput.disabled = true; | |
| sendBtn.disabled = true; | |
| }, INITIALIZATION_TIMEOUT_MS); | |
| socket.emit("initialize_client", { | |
| url: agentCardUrl, | |
| customHeaders | |
| }); | |
| if (data.validation_errors.length > 0) { | |
| validationErrorsContainer.innerHTML = `<h3>Validation Errors</h3><ul>${data.validation_errors.map((e) => `<li>${e}</li>`).join("")}</ul>`; | |
| } else { | |
| validationErrorsContainer.innerHTML = '<p style="color: green;">Agent card is valid.</p>'; | |
| } | |
| } catch (error) { | |
| clearTimeout(initializationTimeout); | |
| validationErrorsContainer.innerHTML = `<p style="color: red;">Error: ${error.message}</p>`; | |
| chatInput.disabled = true; | |
| sendBtn.disabled = true; | |
| } | |
| }); | |
| socket.on( | |
| "client_initialized", | |
| (data) => { | |
| clearTimeout(initializationTimeout); | |
| if (data.status === "success") { | |
| chatInput.disabled = false; | |
| sendBtn.disabled = false; | |
| chatMessages.innerHTML = '<p class="placeholder-text">Ready to chat.</p>'; | |
| debugContent.innerHTML = ""; | |
| Object.keys(rawLogStore).forEach((key) => delete rawLogStore[key]); | |
| logIdQueue.length = 0; | |
| Object.keys(messageJsonStore).forEach( | |
| (key) => delete messageJsonStore[key] | |
| ); | |
| } else { | |
| validationErrorsContainer.innerHTML = `<p style="color: red;">Error initializing client: ${data.message}</p>`; | |
| } | |
| } | |
| ); | |
| let contextId = null; | |
| const sendMessage = () => { | |
| const messageText = chatInput.value; | |
| if (messageText.trim() && !chatInput.disabled) { | |
| const sanitizedMessage = purify.sanitize(messageText); | |
| if (!sanitizedMessage.trim()) { | |
| chatInput.value = ""; | |
| return; | |
| } | |
| const messageId = `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; | |
| const metadata = getMessageMetadata(); | |
| appendMessage("user", sanitizedMessage, messageId); | |
| socket.emit("send_message", { | |
| message: sanitizedMessage, | |
| id: messageId, | |
| contextId, | |
| metadata | |
| }); | |
| chatInput.value = ""; | |
| } | |
| }; | |
| sendBtn.addEventListener("click", sendMessage); | |
| chatInput.addEventListener("keypress", (e) => { | |
| if (e.key === "Enter") sendMessage(); | |
| }); | |
| socket.on("agent_response", (event) => { | |
| const displayMessageId = `display-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; | |
| messageJsonStore[displayMessageId] = event; | |
| const validationErrors = event.validation_errors || []; | |
| if (event.error) { | |
| const messageHtml = `<span class="kind-chip kind-chip-error">error</span> Error: ${purify.sanitize(event.error)}`; | |
| appendMessage( | |
| "agent error", | |
| messageHtml, | |
| displayMessageId, | |
| true, | |
| validationErrors | |
| ); | |
| return; | |
| } | |
| if (event.contextId) contextId = event.contextId; | |
| switch (event.kind) { | |
| case "task": | |
| if (event.status) { | |
| const messageHtml = `<span class="kind-chip kind-chip-task">${event.kind}</span> Task created with status: ${purify.sanitize(event.status.state)}`; | |
| appendMessage( | |
| "agent progress", | |
| messageHtml, | |
| displayMessageId, | |
| true, | |
| validationErrors | |
| ); | |
| } | |
| break; | |
| case "status-update": { | |
| const statusText = event.status?.message?.parts?.[0]?.text; | |
| if (statusText) { | |
| const renderedContent = purify.sanitize( | |
| k.parse(statusText) | |
| ); | |
| const messageHtml = `<span class="kind-chip kind-chip-status-update">${event.kind}</span> Server responded with: ${renderedContent}`; | |
| appendMessage( | |
| "agent progress", | |
| messageHtml, | |
| displayMessageId, | |
| true, | |
| validationErrors | |
| ); | |
| } | |
| break; | |
| } | |
| case "artifact-update": | |
| event.artifact?.parts?.forEach((p) => { | |
| let content = null; | |
| if ("text" in p && p.text) { | |
| content = purify.sanitize(k.parse(p.text)); | |
| } else if ("file" in p && p.file) { | |
| const { uri, mimeType } = p.file; | |
| const sanitizedMimeType = purify.sanitize(mimeType); | |
| const sanitizedUri = purify.sanitize(uri); | |
| content = `File received (${sanitizedMimeType}): <a href="${sanitizedUri}" target="_blank" rel="noopener noreferrer">Open Link</a>`; | |
| } else if ("data" in p && p.data) { | |
| content = `<pre><code>${purify.sanitize(JSON.stringify(p.data, null, 2))}</code></pre>`; | |
| } | |
| if (content !== null) { | |
| const kindChip = `<span class="kind-chip kind-chip-artifact-update">${event.kind}</span>`; | |
| const messageHtml = `${kindChip} ${content}`; | |
| appendMessage( | |
| "agent", | |
| messageHtml, | |
| displayMessageId, | |
| true, | |
| validationErrors | |
| ); | |
| } | |
| }); | |
| break; | |
| case "message": { | |
| const textPart = event.parts?.find((p) => p.text); | |
| if (textPart && textPart.text) { | |
| const renderedContent = purify.sanitize( | |
| k.parse(textPart.text) | |
| ); | |
| const messageHtml = `<span class="kind-chip kind-chip-message">${event.kind}</span> ${renderedContent}`; | |
| appendMessage( | |
| "agent", | |
| messageHtml, | |
| displayMessageId, | |
| true, | |
| validationErrors | |
| ); | |
| } | |
| break; | |
| } | |
| } | |
| }); | |
| function processLogQueue() { | |
| if (isProcessingLogQueue) return; | |
| isProcessingLogQueue = true; | |
| while (logIdQueue.length > MAX_LOGS) { | |
| const oldestKey = logIdQueue.shift(); | |
| if (oldestKey && Object.prototype.hasOwnProperty.call(rawLogStore, oldestKey)) { | |
| delete rawLogStore[oldestKey]; | |
| } | |
| } | |
| isProcessingLogQueue = false; | |
| } | |
| socket.on("debug_log", (log) => { | |
| const logEntry = document.createElement("div"); | |
| const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString(); | |
| let jsonString = JSON.stringify(log.data, null, 2); | |
| jsonString = jsonString.replace( | |
| /"method": "([^"]+)"/g, | |
| '<span class="json-highlight">"method": "$1"</span>' | |
| ); | |
| logEntry.className = `log-entry log-${log.type}`; | |
| logEntry.innerHTML = ` | |
| <div> | |
| <span class="log-timestamp">${timestamp}</span> | |
| <strong>${log.type.toUpperCase()}</strong> | |
| </div> | |
| <pre>${jsonString}</pre> | |
| `; | |
| debugContent.appendChild(logEntry); | |
| if (!rawLogStore[log.id]) { | |
| rawLogStore[log.id] = {}; | |
| } | |
| rawLogStore[log.id][log.type] = log.data; | |
| logIdQueue.push(log.id); | |
| setTimeout(processLogQueue, 0); | |
| debugContent.scrollTop = debugContent.scrollHeight; | |
| }); | |
| function appendMessage(sender, content, messageId, isHtml = false, validationErrors = []) { | |
| const placeholder = chatMessages.querySelector(".placeholder-text"); | |
| if (placeholder) placeholder.remove(); | |
| const messageElement = document.createElement("div"); | |
| messageElement.className = `message ${sender.replace(" ", "-")}`; | |
| const messageContent = document.createElement("div"); | |
| messageContent.className = "message-content"; | |
| if (isHtml) { | |
| messageContent.innerHTML = content; | |
| } else { | |
| messageContent.textContent = content; | |
| } | |
| messageElement.appendChild(messageContent); | |
| const statusIndicator = document.createElement("span"); | |
| statusIndicator.className = "validation-status"; | |
| if (sender !== "user") { | |
| if (validationErrors.length > 0) { | |
| statusIndicator.classList.add("invalid"); | |
| statusIndicator.textContent = "\u26A0\uFE0F"; | |
| statusIndicator.title = validationErrors.join("\n"); | |
| } else { | |
| statusIndicator.classList.add("valid"); | |
| statusIndicator.textContent = "\u2705"; | |
| statusIndicator.title = "Message is compliant"; | |
| } | |
| messageElement.appendChild(statusIndicator); | |
| } | |
| messageElement.addEventListener("click", (e) => { | |
| const target = e.target; | |
| if (target.tagName !== "A") { | |
| const jsonData = sender === "user" ? rawLogStore[messageId]?.request : messageJsonStore[messageId]; | |
| showJsonInModal(jsonData); | |
| } | |
| }); | |
| chatMessages.appendChild(messageElement); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| } | |
| }); | |
| })(); | |
| /*! Bundled license information: | |
| dompurify/dist/purify.es.mjs: | |
| (*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE *) | |
| */ | |