UNPKG

@waku/message-hash

Version:

TypeScript implementation of the Deterministic Message Hashing as specified in 14/WAKU2-MESSAGE

1,714 lines (1,615 loc) โ€ข 57.2 kB
/** * Internal assertion helpers. * @module */ /** Asserts something is positive integer. */ /** Is number an Uint8Array? Copied from utils for perf. */ function isBytes(a) { return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array'); } /** Asserts something is Uint8Array. */ function abytes(b, ...lengths) { if (!isBytes(b)) throw new Error('Uint8Array expected'); if (lengths.length > 0 && !lengths.includes(b.length)) throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length); } /** Asserts a hash instance has not been destroyed / finished */ function aexists(instance, checkFinished = true) { if (instance.destroyed) throw new Error('Hash instance has been destroyed'); if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called'); } /** Asserts output is properly-sized byte array */ function aoutput(out, instance) { abytes(out); const min = instance.outputLen; if (out.length < min) { throw new Error('digestInto() expects output buffer of length at least ' + min); } } /** * Utilities for hex, bytes, CSPRNG. * @module */ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+. // node.js versions earlier than v19 don't declare it in global scope. // For node.js, package.json#exports field mapping rewrites import // from `crypto` to `cryptoNode`, which imports native module. // Makes the utils un-importable in browsers without a bundler. // Once node.js 18 is deprecated (2025-04-30), we can just drop the import. // Cast array to view function createView(arr) { return new DataView(arr.buffer, arr.byteOffset, arr.byteLength); } /** The rotate right (circular right shift) operation for uint32 */ function rotr(word, shift) { return (word << (32 - shift)) | (word >>> shift); } /** * Convert JS string to byte array. * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99]) */ function utf8ToBytes$1(str) { if (typeof str !== 'string') throw new Error('utf8ToBytes expected string, got ' + typeof str); return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809 } /** * Normalizes (non-hex) string or Uint8Array to Uint8Array. * Warning: when Uint8Array is passed, it would NOT get copied. * Keep in mind for future mutable operations. */ function toBytes(data) { if (typeof data === 'string') data = utf8ToBytes$1(data); abytes(data); return data; } /** For runtime check if class implements interface */ class Hash { // Safe version that clones internal state clone() { return this._cloneInto(); } } /** Wraps hash function, creating an interface on top of it */ function wrapConstructor(hashCons) { const hashC = (msg) => hashCons().update(toBytes(msg)).digest(); const tmp = hashCons(); hashC.outputLen = tmp.outputLen; hashC.blockLen = tmp.blockLen; hashC.create = () => hashCons(); return hashC; } /** * Internal Merkle-Damgard hash utils. * @module */ /** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */ function setBigUint64(view, byteOffset, value, isLE) { if (typeof view.setBigUint64 === 'function') return view.setBigUint64(byteOffset, value, isLE); const _32n = BigInt(32); const _u32_max = BigInt(0xffffffff); const wh = Number((value >> _32n) & _u32_max); const wl = Number(value & _u32_max); const h = isLE ? 4 : 0; const l = isLE ? 0 : 4; view.setUint32(byteOffset + h, wh, isLE); view.setUint32(byteOffset + l, wl, isLE); } /** Choice: a ? b : c */ function Chi(a, b, c) { return (a & b) ^ (~a & c); } /** Majority function, true if any two inputs is true. */ function Maj(a, b, c) { return (a & b) ^ (a & c) ^ (b & c); } /** * Merkle-Damgard hash construction base class. * Could be used to create MD5, RIPEMD, SHA1, SHA2. */ class HashMD extends Hash { constructor(blockLen, outputLen, padOffset, isLE) { super(); this.blockLen = blockLen; this.outputLen = outputLen; this.padOffset = padOffset; this.isLE = isLE; this.finished = false; this.length = 0; this.pos = 0; this.destroyed = false; this.buffer = new Uint8Array(blockLen); this.view = createView(this.buffer); } update(data) { aexists(this); const { view, buffer, blockLen } = this; data = toBytes(data); const len = data.length; for (let pos = 0; pos < len;) { const take = Math.min(blockLen - this.pos, len - pos); // Fast path: we have at least one block in input, cast it to view and process if (take === blockLen) { const dataView = createView(data); for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos); continue; } buffer.set(data.subarray(pos, pos + take), this.pos); this.pos += take; pos += take; if (this.pos === blockLen) { this.process(view, 0); this.pos = 0; } } this.length += data.length; this.roundClean(); return this; } digestInto(out) { aexists(this); aoutput(out, this); this.finished = true; // Padding // We can avoid allocation of buffer for padding completely if it // was previously not allocated here. But it won't change performance. const { buffer, view, blockLen, isLE } = this; let { pos } = this; // append the bit '1' to the message buffer[pos++] = 0b10000000; this.buffer.subarray(pos).fill(0); // we have less than padOffset left in buffer, so we cannot put length in // current block, need process it and pad again if (this.padOffset > blockLen - pos) { this.process(view, 0); pos = 0; } // Pad until full block byte with zeros for (let i = pos; i < blockLen; i++) buffer[i] = 0; // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen. // So we just write lowest 64 bits of that value. setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE); this.process(view, 0); const oview = createView(out); const len = this.outputLen; // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT if (len % 4) throw new Error('_sha2: outputLen should be aligned to 32bit'); const outLen = len / 4; const state = this.get(); if (outLen > state.length) throw new Error('_sha2: outputLen bigger than state'); for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE); } digest() { const { buffer, outputLen } = this; this.digestInto(buffer); const res = buffer.slice(0, outputLen); this.destroy(); return res; } _cloneInto(to) { to || (to = new this.constructor()); to.set(...this.get()); const { blockLen, buffer, length, finished, destroyed, pos } = this; to.length = length; to.pos = pos; to.finished = finished; to.destroyed = destroyed; if (length % blockLen) to.buffer.set(buffer); return to; } } /** * SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3. * * To break sha256 using birthday attack, attackers need to try 2^128 hashes. * BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025. * * Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf). * @module */ /** Round constants: first 32 bits of fractional parts of the cube roots of the first 64 primes 2..311). */ // prettier-ignore const SHA256_K = /* @__PURE__ */ new Uint32Array([ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]); /** Initial state: first 32 bits of fractional parts of the square roots of the first 8 primes 2..19. */ // prettier-ignore const SHA256_IV = /* @__PURE__ */ new Uint32Array([ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]); /** * Temporary buffer, not used to store anything between runs. * Named this way because it matches specification. */ const SHA256_W = /* @__PURE__ */ new Uint32Array(64); class SHA256 extends HashMD { constructor() { super(64, 32, 8, false); // We cannot use array here since array allows indexing by variable // which means optimizer/compiler cannot use registers. this.A = SHA256_IV[0] | 0; this.B = SHA256_IV[1] | 0; this.C = SHA256_IV[2] | 0; this.D = SHA256_IV[3] | 0; this.E = SHA256_IV[4] | 0; this.F = SHA256_IV[5] | 0; this.G = SHA256_IV[6] | 0; this.H = SHA256_IV[7] | 0; } get() { const { A, B, C, D, E, F, G, H } = this; return [A, B, C, D, E, F, G, H]; } // prettier-ignore set(A, B, C, D, E, F, G, H) { this.A = A | 0; this.B = B | 0; this.C = C | 0; this.D = D | 0; this.E = E | 0; this.F = F | 0; this.G = G | 0; this.H = H | 0; } process(view, offset) { // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array for (let i = 0; i < 16; i++, offset += 4) SHA256_W[i] = view.getUint32(offset, false); for (let i = 16; i < 64; i++) { const W15 = SHA256_W[i - 15]; const W2 = SHA256_W[i - 2]; const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3); const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10); SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0; } // Compression function main loop, 64 rounds let { A, B, C, D, E, F, G, H } = this; for (let i = 0; i < 64; i++) { const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25); const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22); const T2 = (sigma0 + Maj(A, B, C)) | 0; H = G; G = F; F = E; E = (D + T1) | 0; D = C; C = B; B = A; A = (T1 + T2) | 0; } // Add the compressed chunk to the current hash value A = (A + this.A) | 0; B = (B + this.B) | 0; C = (C + this.C) | 0; D = (D + this.D) | 0; E = (E + this.E) | 0; F = (F + this.F) | 0; G = (G + this.G) | 0; H = (H + this.H) | 0; this.set(A, B, C, D, E, F, G, H); } roundClean() { SHA256_W.fill(0); } destroy() { this.set(0, 0, 0, 0, 0, 0, 0, 0); this.buffer.fill(0); } } /** SHA2-256 hash function */ const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256()); function isDefined(value) { return Boolean(value); } var Protocols; (function (Protocols) { Protocols["Relay"] = "relay"; Protocols["Store"] = "store"; Protocols["LightPush"] = "lightpush"; Protocols["Filter"] = "filter"; })(Protocols || (Protocols = {})); var ProtocolError; (function (ProtocolError) { // // GENERAL ERRORS SECTION // /** * Could not determine the origin of the fault. Best to check connectivity and try again * */ ProtocolError["GENERIC_FAIL"] = "Generic error"; /** * The remote peer rejected the message. Information provided by the remote peer * is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE` * or `DECODE_FAILED` can be used. */ ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected"; /** * Failure to protobuf decode the message. May be due to a remote peer issue, * ensuring that messages are sent via several peer enable mitigation of this error. */ ProtocolError["DECODE_FAILED"] = "Failed to decode"; /** * Failure to find a peer with suitable protocols. This may due to a connection issue. * Mitigation can be: retrying after a given time period, display connectivity issue * to user or listening for `peer:connected:bootstrap` or `peer:connected:peer-exchange` * on the connection manager before retrying. */ ProtocolError["NO_PEER_AVAILABLE"] = "No peer available"; /** * Failure to find a stream to the peer. This may be because the connection with the peer is not still alive. * Mitigation can be: retrying after a given time period, or mitigation for `NO_PEER_AVAILABLE` can be used. */ ProtocolError["NO_STREAM_AVAILABLE"] = "No stream available"; /** * The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE` * or `DECODE_FAILED` can be used. */ ProtocolError["NO_RESPONSE"] = "No response received"; // // SEND ERRORS SECTION // /** * Failure to protobuf encode the message. This is not recoverable and needs * further investigation. */ ProtocolError["ENCODE_FAILED"] = "Failed to encode"; /** * The message payload is empty, making the message invalid. Ensure that a non-empty * payload is set on the outgoing message. */ ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty"; /** * The message size is above the maximum message size allowed on the Waku Network. * Compressing the message or using an alternative strategy for large messages is recommended. */ ProtocolError["SIZE_TOO_BIG"] = "Size is too big"; /** * The PubsubTopic passed to the send function is not configured on the Waku node. * Please ensure that the PubsubTopic is used when initializing the Waku node. */ ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured"; /** * Fails when */ ProtocolError["STREAM_ABORTED"] = "Stream aborted"; /** * General proof generation error message. * nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42 */ ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed"; // // RECEIVE ERRORS SECTION // /** * The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol. * Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol. */ ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch"; /** * The topics passed in the decoders do not match each other, or don't exist at all. * Ensure that all the pubsub topics used in the decoders are valid and match each other. */ ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics"; })(ProtocolError || (ProtocolError = {})); var Tags; (function (Tags) { Tags["BOOTSTRAP"] = "bootstrap"; Tags["PEER_EXCHANGE"] = "peer-exchange"; Tags["LOCAL"] = "local-peer-cache"; })(Tags || (Tags = {})); var EPeersByDiscoveryEvents; (function (EPeersByDiscoveryEvents) { EPeersByDiscoveryEvents["PEER_DISCOVERY_BOOTSTRAP"] = "peer:discovery:bootstrap"; EPeersByDiscoveryEvents["PEER_DISCOVERY_PEER_EXCHANGE"] = "peer:discovery:peer-exchange"; EPeersByDiscoveryEvents["PEER_CONNECT_BOOTSTRAP"] = "peer:connected:bootstrap"; EPeersByDiscoveryEvents["PEER_CONNECT_PEER_EXCHANGE"] = "peer:connected:peer-exchange"; })(EPeersByDiscoveryEvents || (EPeersByDiscoveryEvents = {})); var EConnectionStateEvents; (function (EConnectionStateEvents) { EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection"; })(EConnectionStateEvents || (EConnectionStateEvents = {})); var HealthStatusChangeEvents; (function (HealthStatusChangeEvents) { HealthStatusChangeEvents["StatusChange"] = "health:change"; })(HealthStatusChangeEvents || (HealthStatusChangeEvents = {})); var HealthStatus; (function (HealthStatus) { HealthStatus["Unhealthy"] = "Unhealthy"; HealthStatus["MinimallyHealthy"] = "MinimallyHealthy"; HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy"; })(HealthStatus || (HealthStatus = {})); function coerce(o) { if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') return o; if (o instanceof ArrayBuffer) return new Uint8Array(o); if (ArrayBuffer.isView(o)) { return new Uint8Array(o.buffer, o.byteOffset, o.byteLength); } throw new Error('Unknown type, must be binary type'); } function fromString$1(str) { return new TextEncoder().encode(str); } function toString$1(b) { return new TextDecoder().decode(b); } /* eslint-disable */ // base-x encoding / decoding // Copyright (c) 2018 base-x contributors // Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp) // Distributed under the MIT software license, see the accompanying // file LICENSE or http://www.opensource.org/licenses/mit-license.php. /** * @param {string} ALPHABET * @param {any} name */ function base(ALPHABET, name) { if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long'); } var BASE_MAP = new Uint8Array(256); for (var j = 0; j < BASE_MAP.length; j++) { BASE_MAP[j] = 255; } for (var i = 0; i < ALPHABET.length; i++) { var x = ALPHABET.charAt(i); var xc = x.charCodeAt(0); if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous'); } BASE_MAP[xc] = i; } var BASE = ALPHABET.length; var LEADER = ALPHABET.charAt(0); var FACTOR = Math.log(BASE) / Math.log(256); // log(BASE) / log(256), rounded up var iFACTOR = Math.log(256) / Math.log(BASE); // log(256) / log(BASE), rounded up /** * @param {any[] | Iterable<number>} source */ function encode(source) { // @ts-ignore if (source instanceof Uint8Array) ; else if (ArrayBuffer.isView(source)) { source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); } else if (Array.isArray(source)) { source = Uint8Array.from(source); } if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array'); } if (source.length === 0) { return ''; } // Skip & count leading zeroes. var zeroes = 0; var length = 0; var pbegin = 0; var pend = source.length; while (pbegin !== pend && source[pbegin] === 0) { pbegin++; zeroes++; } // Allocate enough space in big-endian base58 representation. var size = ((pend - pbegin) * iFACTOR + 1) >>> 0; var b58 = new Uint8Array(size); // Process the bytes. while (pbegin !== pend) { var carry = source[pbegin]; // Apply "b58 = b58 * 256 + ch". var i = 0; for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) { carry += (256 * b58[it1]) >>> 0; b58[it1] = (carry % BASE) >>> 0; carry = (carry / BASE) >>> 0; } if (carry !== 0) { throw new Error('Non-zero carry'); } length = i; pbegin++; } // Skip leading zeroes in base58 result. var it2 = size - length; while (it2 !== size && b58[it2] === 0) { it2++; } // Translate the result into a string. var str = LEADER.repeat(zeroes); for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]); } return str; } /** * @param {string | string[]} source */ function decodeUnsafe(source) { if (typeof source !== 'string') { throw new TypeError('Expected String'); } if (source.length === 0) { return new Uint8Array(); } var psz = 0; // Skip leading spaces. if (source[psz] === ' ') { return; } // Skip and count leading '1's. var zeroes = 0; var length = 0; while (source[psz] === LEADER) { zeroes++; psz++; } // Allocate enough space in big-endian base256 representation. var size = (((source.length - psz) * FACTOR) + 1) >>> 0; // log(58) / log(256), rounded up. var b256 = new Uint8Array(size); // Process the characters. while (source[psz]) { // Decode character var carry = BASE_MAP[source.charCodeAt(psz)]; // Invalid character if (carry === 255) { return; } var i = 0; for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) { carry += (BASE * b256[it3]) >>> 0; b256[it3] = (carry % 256) >>> 0; carry = (carry / 256) >>> 0; } if (carry !== 0) { throw new Error('Non-zero carry'); } length = i; psz++; } // Skip trailing spaces. if (source[psz] === ' ') { return; } // Skip leading zeroes in b256. var it4 = size - length; while (it4 !== size && b256[it4] === 0) { it4++; } var vch = new Uint8Array(zeroes + (size - it4)); var j = zeroes; while (it4 !== size) { vch[j++] = b256[it4++]; } return vch; } /** * @param {string | string[]} string */ function decode(string) { var buffer = decodeUnsafe(string); if (buffer) { return buffer; } throw new Error(`Non-${name} character`); } return { encode: encode, decodeUnsafe: decodeUnsafe, decode: decode }; } var src = base; var _brrp__multiformats_scope_baseX = src; /** * Class represents both BaseEncoder and MultibaseEncoder meaning it * can be used to encode to multibase or base encode without multibase * prefix. */ class Encoder { name; prefix; baseEncode; constructor(name, prefix, baseEncode) { this.name = name; this.prefix = prefix; this.baseEncode = baseEncode; } encode(bytes) { if (bytes instanceof Uint8Array) { return `${this.prefix}${this.baseEncode(bytes)}`; } else { throw Error('Unknown type, must be binary type'); } } } /** * Class represents both BaseDecoder and MultibaseDecoder so it could be used * to decode multibases (with matching prefix) or just base decode strings * with corresponding base encoding. */ class Decoder { name; prefix; baseDecode; prefixCodePoint; constructor(name, prefix, baseDecode) { this.name = name; this.prefix = prefix; const prefixCodePoint = prefix.codePointAt(0); /* c8 ignore next 3 */ if (prefixCodePoint === undefined) { throw new Error('Invalid prefix character'); } this.prefixCodePoint = prefixCodePoint; this.baseDecode = baseDecode; } decode(text) { if (typeof text === 'string') { if (text.codePointAt(0) !== this.prefixCodePoint) { throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`); } return this.baseDecode(text.slice(this.prefix.length)); } else { throw Error('Can only multibase decode strings'); } } or(decoder) { return or(this, decoder); } } class ComposedDecoder { decoders; constructor(decoders) { this.decoders = decoders; } or(decoder) { return or(this, decoder); } decode(input) { const prefix = input[0]; const decoder = this.decoders[prefix]; if (decoder != null) { return decoder.decode(input); } else { throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`); } } } function or(left, right) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions return new ComposedDecoder({ ...(left.decoders ?? { [left.prefix]: left }), ...(right.decoders ?? { [right.prefix]: right }) }); } class Codec { name; prefix; baseEncode; baseDecode; encoder; decoder; constructor(name, prefix, baseEncode, baseDecode) { this.name = name; this.prefix = prefix; this.baseEncode = baseEncode; this.baseDecode = baseDecode; this.encoder = new Encoder(name, prefix, baseEncode); this.decoder = new Decoder(name, prefix, baseDecode); } encode(input) { return this.encoder.encode(input); } decode(input) { return this.decoder.decode(input); } } function from({ name, prefix, encode, decode }) { return new Codec(name, prefix, encode, decode); } function baseX({ name, prefix, alphabet }) { const { encode, decode } = _brrp__multiformats_scope_baseX(alphabet, name); return from({ prefix, name, encode, decode: (text) => coerce(decode(text)) }); } function decode$1(string, alphabet, bitsPerChar, name) { // Build the character lookup table: const codes = {}; for (let i = 0; i < alphabet.length; ++i) { codes[alphabet[i]] = i; } // Count the padding bytes: let end = string.length; while (string[end - 1] === '=') { --end; } // Allocate the output: const out = new Uint8Array((end * bitsPerChar / 8) | 0); // Parse the data: let bits = 0; // Number of bits currently in the buffer let buffer = 0; // Bits waiting to be written out, MSB first let written = 0; // Next byte to write for (let i = 0; i < end; ++i) { // Read one character from the string: const value = codes[string[i]]; if (value === undefined) { throw new SyntaxError(`Non-${name} character`); } // Append the bits to the buffer: buffer = (buffer << bitsPerChar) | value; bits += bitsPerChar; // Write out some bits if the buffer has a byte's worth: if (bits >= 8) { bits -= 8; out[written++] = 0xff & (buffer >> bits); } } // Verify that we have received just enough bits: if (bits >= bitsPerChar || (0xff & (buffer << (8 - bits))) !== 0) { throw new SyntaxError('Unexpected end of data'); } return out; } function encode$1(data, alphabet, bitsPerChar) { const pad = alphabet[alphabet.length - 1] === '='; const mask = (1 << bitsPerChar) - 1; let out = ''; let bits = 0; // Number of bits currently in the buffer let buffer = 0; // Bits waiting to be written out, MSB first for (let i = 0; i < data.length; ++i) { // Slurp data into the buffer: buffer = (buffer << 8) | data[i]; bits += 8; // Write out as much as we can: while (bits > bitsPerChar) { bits -= bitsPerChar; out += alphabet[mask & (buffer >> bits)]; } } // Partial character: if (bits !== 0) { out += alphabet[mask & (buffer << (bitsPerChar - bits))]; } // Add padding characters until we hit a byte boundary: if (pad) { while (((out.length * bitsPerChar) & 7) !== 0) { out += '='; } } return out; } /** * RFC4648 Factory */ function rfc4648({ name, prefix, bitsPerChar, alphabet }) { return from({ prefix, name, encode(input) { return encode$1(input, alphabet, bitsPerChar); }, decode(input) { return decode$1(input, alphabet, bitsPerChar, name); } }); } const base10 = baseX({ prefix: '9', name: 'base10', alphabet: '0123456789' }); var base10$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base10: base10 }); const base16 = rfc4648({ prefix: 'f', name: 'base16', alphabet: '0123456789abcdef', bitsPerChar: 4 }); const base16upper = rfc4648({ prefix: 'F', name: 'base16upper', alphabet: '0123456789ABCDEF', bitsPerChar: 4 }); var base16$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base16: base16, base16upper: base16upper }); const base2 = rfc4648({ prefix: '0', name: 'base2', alphabet: '01', bitsPerChar: 1 }); var base2$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base2: base2 }); const alphabet = Array.from('๐Ÿš€๐Ÿชโ˜„๐Ÿ›ฐ๐ŸŒŒ๐ŸŒ‘๐ŸŒ’๐ŸŒ“๐ŸŒ”๐ŸŒ•๐ŸŒ–๐ŸŒ—๐ŸŒ˜๐ŸŒ๐ŸŒ๐ŸŒŽ๐Ÿ‰โ˜€๐Ÿ’ป๐Ÿ–ฅ๐Ÿ’พ๐Ÿ’ฟ๐Ÿ˜‚โค๐Ÿ˜๐Ÿคฃ๐Ÿ˜Š๐Ÿ™๐Ÿ’•๐Ÿ˜ญ๐Ÿ˜˜๐Ÿ‘๐Ÿ˜…๐Ÿ‘๐Ÿ˜๐Ÿ”ฅ๐Ÿฅฐ๐Ÿ’”๐Ÿ’–๐Ÿ’™๐Ÿ˜ข๐Ÿค”๐Ÿ˜†๐Ÿ™„๐Ÿ’ช๐Ÿ˜‰โ˜บ๐Ÿ‘Œ๐Ÿค—๐Ÿ’œ๐Ÿ˜”๐Ÿ˜Ž๐Ÿ˜‡๐ŸŒน๐Ÿคฆ๐ŸŽ‰๐Ÿ’žโœŒโœจ๐Ÿคท๐Ÿ˜ฑ๐Ÿ˜Œ๐ŸŒธ๐Ÿ™Œ๐Ÿ˜‹๐Ÿ’—๐Ÿ’š๐Ÿ˜๐Ÿ’›๐Ÿ™‚๐Ÿ’“๐Ÿคฉ๐Ÿ˜„๐Ÿ˜€๐Ÿ–ค๐Ÿ˜ƒ๐Ÿ’ฏ๐Ÿ™ˆ๐Ÿ‘‡๐ŸŽถ๐Ÿ˜’๐Ÿคญโฃ๐Ÿ˜œ๐Ÿ’‹๐Ÿ‘€๐Ÿ˜ช๐Ÿ˜‘๐Ÿ’ฅ๐Ÿ™‹๐Ÿ˜ž๐Ÿ˜ฉ๐Ÿ˜ก๐Ÿคช๐Ÿ‘Š๐Ÿฅณ๐Ÿ˜ฅ๐Ÿคค๐Ÿ‘‰๐Ÿ’ƒ๐Ÿ˜ณโœ‹๐Ÿ˜š๐Ÿ˜๐Ÿ˜ด๐ŸŒŸ๐Ÿ˜ฌ๐Ÿ™ƒ๐Ÿ€๐ŸŒท๐Ÿ˜ป๐Ÿ˜“โญโœ…๐Ÿฅบ๐ŸŒˆ๐Ÿ˜ˆ๐Ÿค˜๐Ÿ’ฆโœ”๐Ÿ˜ฃ๐Ÿƒ๐Ÿ’โ˜น๐ŸŽŠ๐Ÿ’˜๐Ÿ˜ โ˜๐Ÿ˜•๐ŸŒบ๐ŸŽ‚๐ŸŒป๐Ÿ˜๐Ÿ–•๐Ÿ’๐Ÿ™Š๐Ÿ˜น๐Ÿ—ฃ๐Ÿ’ซ๐Ÿ’€๐Ÿ‘‘๐ŸŽต๐Ÿคž๐Ÿ˜›๐Ÿ”ด๐Ÿ˜ค๐ŸŒผ๐Ÿ˜ซโšฝ๐Ÿค™โ˜•๐Ÿ†๐Ÿคซ๐Ÿ‘ˆ๐Ÿ˜ฎ๐Ÿ™†๐Ÿป๐Ÿƒ๐Ÿถ๐Ÿ’๐Ÿ˜ฒ๐ŸŒฟ๐Ÿงก๐ŸŽโšก๐ŸŒž๐ŸŽˆโŒโœŠ๐Ÿ‘‹๐Ÿ˜ฐ๐Ÿคจ๐Ÿ˜ถ๐Ÿค๐Ÿšถ๐Ÿ’ฐ๐Ÿ“๐Ÿ’ข๐ŸคŸ๐Ÿ™๐Ÿšจ๐Ÿ’จ๐Ÿคฌโœˆ๐ŸŽ€๐Ÿบ๐Ÿค“๐Ÿ˜™๐Ÿ’Ÿ๐ŸŒฑ๐Ÿ˜–๐Ÿ‘ถ๐Ÿฅดโ–ถโžกโ“๐Ÿ’Ž๐Ÿ’ธโฌ‡๐Ÿ˜จ๐ŸŒš๐Ÿฆ‹๐Ÿ˜ท๐Ÿ•บโš ๐Ÿ™…๐Ÿ˜Ÿ๐Ÿ˜ต๐Ÿ‘Ž๐Ÿคฒ๐Ÿค ๐Ÿคง๐Ÿ“Œ๐Ÿ”ต๐Ÿ’…๐Ÿง๐Ÿพ๐Ÿ’๐Ÿ˜—๐Ÿค‘๐ŸŒŠ๐Ÿคฏ๐Ÿทโ˜Ž๐Ÿ’ง๐Ÿ˜ฏ๐Ÿ’†๐Ÿ‘†๐ŸŽค๐Ÿ™‡๐Ÿ‘โ„๐ŸŒด๐Ÿ’ฃ๐Ÿธ๐Ÿ’Œ๐Ÿ“๐Ÿฅ€๐Ÿคข๐Ÿ‘…๐Ÿ’ก๐Ÿ’ฉ๐Ÿ‘๐Ÿ“ธ๐Ÿ‘ป๐Ÿค๐Ÿคฎ๐ŸŽผ๐Ÿฅต๐Ÿšฉ๐ŸŽ๐ŸŠ๐Ÿ‘ผ๐Ÿ’๐Ÿ“ฃ๐Ÿฅ‚'); const alphabetBytesToChars = (alphabet.reduce((p, c, i) => { p[i] = c; return p; }, ([]))); const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => { const codePoint = c.codePointAt(0); if (codePoint == null) { throw new Error(`Invalid character: ${c}`); } p[codePoint] = i; return p; }, ([]))); function encode(data) { return data.reduce((p, c) => { p += alphabetBytesToChars[c]; return p; }, ''); } function decode(str) { const byts = []; for (const char of str) { const codePoint = char.codePointAt(0); if (codePoint == null) { throw new Error(`Invalid character: ${char}`); } const byt = alphabetCharsToBytes[codePoint]; if (byt == null) { throw new Error(`Non-base256emoji character: ${char}`); } byts.push(byt); } return new Uint8Array(byts); } const base256emoji = from({ prefix: '๐Ÿš€', name: 'base256emoji', encode, decode }); var base256emoji$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base256emoji: base256emoji }); const base32 = rfc4648({ prefix: 'b', name: 'base32', alphabet: 'abcdefghijklmnopqrstuvwxyz234567', bitsPerChar: 5 }); const base32upper = rfc4648({ prefix: 'B', name: 'base32upper', alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', bitsPerChar: 5 }); const base32pad = rfc4648({ prefix: 'c', name: 'base32pad', alphabet: 'abcdefghijklmnopqrstuvwxyz234567=', bitsPerChar: 5 }); const base32padupper = rfc4648({ prefix: 'C', name: 'base32padupper', alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=', bitsPerChar: 5 }); const base32hex = rfc4648({ prefix: 'v', name: 'base32hex', alphabet: '0123456789abcdefghijklmnopqrstuv', bitsPerChar: 5 }); const base32hexupper = rfc4648({ prefix: 'V', name: 'base32hexupper', alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV', bitsPerChar: 5 }); const base32hexpad = rfc4648({ prefix: 't', name: 'base32hexpad', alphabet: '0123456789abcdefghijklmnopqrstuv=', bitsPerChar: 5 }); const base32hexpadupper = rfc4648({ prefix: 'T', name: 'base32hexpadupper', alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV=', bitsPerChar: 5 }); const base32z = rfc4648({ prefix: 'h', name: 'base32z', alphabet: 'ybndrfg8ejkmcpqxot1uwisza345h769', bitsPerChar: 5 }); var base32$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base32: base32, base32hex: base32hex, base32hexpad: base32hexpad, base32hexpadupper: base32hexpadupper, base32hexupper: base32hexupper, base32pad: base32pad, base32padupper: base32padupper, base32upper: base32upper, base32z: base32z }); const base36 = baseX({ prefix: 'k', name: 'base36', alphabet: '0123456789abcdefghijklmnopqrstuvwxyz' }); const base36upper = baseX({ prefix: 'K', name: 'base36upper', alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' }); var base36$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base36: base36, base36upper: base36upper }); const base58btc = baseX({ name: 'base58btc', prefix: 'z', alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' }); const base58flickr = baseX({ name: 'base58flickr', prefix: 'Z', alphabet: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' }); var base58 = /*#__PURE__*/Object.freeze({ __proto__: null, base58btc: base58btc, base58flickr: base58flickr }); const base64 = rfc4648({ prefix: 'm', name: 'base64', alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', bitsPerChar: 6 }); const base64pad = rfc4648({ prefix: 'M', name: 'base64pad', alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', bitsPerChar: 6 }); const base64url = rfc4648({ prefix: 'u', name: 'base64url', alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', bitsPerChar: 6 }); const base64urlpad = rfc4648({ prefix: 'U', name: 'base64urlpad', alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=', bitsPerChar: 6 }); var base64$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base64: base64, base64pad: base64pad, base64url: base64url, base64urlpad: base64urlpad }); const base8 = rfc4648({ prefix: '7', name: 'base8', alphabet: '01234567', bitsPerChar: 3 }); var base8$1 = /*#__PURE__*/Object.freeze({ __proto__: null, base8: base8 }); const identity = from({ prefix: '\x00', name: 'identity', encode: (buf) => toString$1(buf), decode: (str) => fromString$1(str) }); var identityBase = /*#__PURE__*/Object.freeze({ __proto__: null, identity: identity }); new TextEncoder(); new TextDecoder(); const bases = { ...identityBase, ...base2$1, ...base8$1, ...base10$1, ...base16$1, ...base32$1, ...base36$1, ...base58, ...base64$1, ...base256emoji$1 }; /** * Returns a `Uint8Array` of the requested size. Referenced memory will * be initialized to 0. */ /** * Where possible returns a Uint8Array of the requested size that references * uninitialized memory. Only use if you are certain you will immediately * overwrite every value in the returned `Uint8Array`. */ function allocUnsafe(size = 0) { return new Uint8Array(size); } function createCodec(name, prefix, encode, decode) { return { name, prefix, encoder: { name, prefix, encode }, decoder: { decode } }; } const string = createCodec('utf8', 'u', (buf) => { const decoder = new TextDecoder('utf8'); return 'u' + decoder.decode(buf); }, (str) => { const encoder = new TextEncoder(); return encoder.encode(str.substring(1)); }); const ascii = createCodec('ascii', 'a', (buf) => { let string = 'a'; for (let i = 0; i < buf.length; i++) { string += String.fromCharCode(buf[i]); } return string; }, (str) => { str = str.substring(1); const buf = allocUnsafe(str.length); for (let i = 0; i < str.length; i++) { buf[i] = str.charCodeAt(i); } return buf; }); const BASES = { utf8: string, 'utf-8': string, hex: bases.base16, latin1: ascii, ascii, binary: ascii, ...bases }; /** * Create a `Uint8Array` from the passed string * * Supports `utf8`, `utf-8`, `hex`, and any encoding supported by the multiformats module. * * Also `ascii` which is similar to node's 'binary' encoding. */ function fromString(string, encoding = 'utf8') { const base = BASES[encoding]; if (base == null) { throw new Error(`Unsupported encoding "${encoding}"`); } // add multibase prefix return base.decoder.decode(`${base.prefix}${string}`); // eslint-disable-line @typescript-eslint/restrict-template-expressions } /** * Turns a `Uint8Array` into a string. * * Supports `utf8`, `utf-8` and any encoding supported by the multibase module. * * Also `ascii` which is similar to node's 'binary' encoding. */ function toString(array, encoding = 'utf8') { const base = BASES[encoding]; if (base == null) { throw new Error(`Unsupported encoding "${encoding}"`); } // strip multibase prefix return base.encoder.encode(array).substring(1); } function numberToBytes(value) { const buffer = new ArrayBuffer(8); const view = new DataView(buffer); if (typeof value === "number") { view.setFloat64(0, value, false); } else { view.setBigInt64(0, value, false); } return new Uint8Array(buffer); } /** * Convert byte array to hex string (no `0x` prefix). */ const bytesToHex = (bytes) => toString(bytes, "base16"); /** * Encode utf-8 string to byte array. */ const utf8ToBytes = (s) => fromString(s, "utf8"); /** * Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView` */ function concat(byteArrays, totalLength) { const len = byteArrays.reduce((acc, curr) => acc + curr.length, 0); const res = new Uint8Array(len); let offset = 0; for (const bytes of byteArrays) { res.set(bytes, offset); offset += bytes.length; } return res; } var browser = {exports: {}}; /** * Helpers. */ var ms; var hasRequiredMs; function requireMs () { if (hasRequiredMs) return ms; hasRequiredMs = 1; var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} [options] * @throws {Error} throw an error if val is not a non-empty string or a number * @return {String|Number} * @api public */ ms = function (val, options) { options = options || {}; var type = typeof val; if (type === 'string' && val.length > 0) { return parse(val); } else if (type === 'number' && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error( 'val is not a non-empty string or a valid number. val=' + JSON.stringify(val) ); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = String(str); if (str.length > 100) { return; } var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( str ); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'weeks': case 'week': case 'w': return n * w; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; default: return undefined; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + 'd'; } if (msAbs >= h) { return Math.round(ms / h) + 'h'; } if (msAbs >= m) { return Math.round(ms / m) + 'm'; } if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, 'day'); } if (msAbs >= h) { return plural(ms, msAbs, h, 'hour'); } if (msAbs >= m) { return plural(ms, msAbs, m, 'minute'); } if (msAbs >= s) { return plural(ms, msAbs, s, 'second'); } return ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } return ms; } /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. */ function setup(env) { createDebug.debug = createDebug; createDebug.default = createDebug; createDebug.coerce = coerce; createDebug.disable = disable; createDebug.enable = enable; createDebug.enabled = enabled; createDebug.humanize = requireMs(); createDebug.destroy = destroy; Object.keys(env).forEach(key => { createDebug[key] = env[key]; }); /** * The currently active debug mode names, and names to skip. */ createDebug.names = []; createDebug.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ createDebug.formatters = {}; /** * Selects a color for a debug namespace * @param {String} namespace The namespace string for the debug instance to be colored * @return {Number|String} An ANSI color code for the given namespace * @api private */ function selectColor(namespace) { let hash = 0; for (let i = 0; i < namespace.length; i++) { hash = ((hash << 5) - hash) + namespace.charCodeAt(i); hash |= 0; // Convert to 32bit integer } return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; } createDebug.selectColor = selectColor; /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function createDebug(namespace) { let prevTime; let enableOverride = null; let namespacesCache; let enabledCache; function debug(...args) { // Disabled? if (!debug.enabled) { return; } const self = debug; // Set `diff` timestamp const curr = Number(new Date()); const ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; args[0] = createDebug.coerce(args[0]); if (typeof args[0] !== 'string') { // Anything else let's inspect with %O args.unshift('%O'); } // Apply any `formatters` transformations let index = 0; args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { // If we encounter an escaped % then don't increase the array index if (match === '%%') { return '%'; } index++; const formatter = createDebug.formatters[format]; if (typeof formatter === 'function') { const val = args[index]; match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` args.splice(index, 1); index--; } return match; }); // Apply env-specific formatting (colors, etc.) createDebug.formatArgs.call(self, args); const logFn = self.log || createDebug.log; logFn.apply(self, args); } debug.namespace = namespace; debug.useColors = createDebug.useColors(); debug.color = createDebug.selectColor(namespace); debug.extend = extend; debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. Object.defineProperty(debug, 'enabled', { enumerable: true, configurable: false, get: () => { if (enableOverride !== null) { return enableOverride; } if (namespacesCache !== createDebug.namespaces) { namespacesCache = createDebug.namespaces; enabledCache = createDebug.enabled(namespace); } return enabledCache; }, set: v => { enableOverride = v; } }); // Env-specific initialization logic for debug instances if (typeof createDebug.init === 'function') { createDebug.init(debug); } return debug; } function extend(namespace, delimiter) { const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); newDebug.log = this.log; return newDebug; } /** * Enables a debug mode by namespaces. This can include modes * separated by a colon and wildcards. * * @param {String} namespaces * @api public */ function enable(namespaces) { createDebug.save(namespaces); createDebug.namespaces = namespaces; createDebug.names = []; createDebug.skips = []; const split = (typeof namespaces === 'string' ? namespaces : '') .trim() .replace(' ', ',') .split(',') .filter(Boolean); for (const ns of split) { if (ns[0] === '-') { createDebug.skips.push(ns.slice(1)); } else { createDebug.names.push(ns); } } } /** * Checks if the given string matches a namespace template, honoring * asterisks as wildcards. * * @param {String} search * @param {String} template * @return {Boolean} */ function matchesTemplate(search, template) { let searchIndex = 0; let templateIndex = 0; let starIndex = -1; let matchIndex = 0; while (searchIndex < search.length) { if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) { // Match character or proceed with wildcard if (template[templateIndex] === '*') { starIndex = templateIndex; matchIndex = searchIndex; templateIndex++; // Skip the '*' } else { searchIndex++; templateIndex++; } } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition // Backtrack to the last '*' and try to match more characters templateIndex = starIndex + 1; matchIndex++; searchIndex = matchIndex; } else { return false; // No match } } // Handle trailing '*' in template while (templateIndex < template.length && template[templateIndex] === '*') { templateIndex++; } return templateIndex === template.length; } /** * Disable debug output. * * @return {String} namespaces * @api public */ function disable() { const namespaces = [ ...createDebug.names, ...createDebug.skips.map(namespace => '-' + namespace) ].join(','); createDebug.enable(''); return namespaces; } /** * Returns true if the given mode name is enabled, false otherwise. * * @param {String} name * @return {Boolean} * @api public */ function enabled(name) { for (const skip of createDebug.skips) { if (matchesTemplate(name, skip)) { return false; } } for (const ns of createDebug.names) { if (matchesTemplate(name, ns)) { return true; } } return false; } /** * Coerce `val`. * * @param {Mixed} val * @return {Mixed} * @api private */ function coerce(val) { if (val instanceof Error) { return val.stack || val.message; } return val; } /** * XXX DO NOT USE. This is a temporary stub function. * XXX It WILL be removed in the next major release. */ function destroy() { console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } createDebug.enable(createDebug.load()); return createDebug; } var common = setup; /* eslint-env browser */ (function (module, exports) { /** * This is the web browser implementation of `debug()`. */ exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); exports.destroy = (() => { let warned = false; return () => { if (!warned) { warned = true; console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); } }; })(); /** * Colors. */ exports.colors = [ '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#0