@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
JavaScript
/**
* 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