UNPKG

random

Version:

Seedable random number generator supporting many common distributions.

934 lines (907 loc) 25.2 kB
//#region src/rng.ts var RNG = class {}; //#endregion //#region \0@oxc-project+runtime@0.144.0/helpers/esm/typeof.js function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) { return typeof o; } : function(o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } //#endregion //#region \0@oxc-project+runtime@0.144.0/helpers/esm/toPrimitive.js function toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } //#endregion //#region \0@oxc-project+runtime@0.144.0/helpers/esm/toPropertyKey.js function toPropertyKey(t) { var i = toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } //#endregion //#region \0@oxc-project+runtime@0.144.0/helpers/esm/defineProperty.js function _defineProperty(e, r, t) { return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } //#endregion //#region src/generators/function.ts var FunctionRNG = class FunctionRNG extends RNG { constructor(rngFn) { super(); _defineProperty(this, "_name", void 0); _defineProperty(this, "_rngFn", void 0); this._name = rngFn.name || "function"; this._rngFn = rngFn; } get name() { return this._name; } next() { return this._rngFn(); } clone() { return new FunctionRNG(this._rngFn); } }; //#endregion //#region src/generators/xoshiro128-star-star.ts const UINT53_SIZE = 9007199254740992; const UINT26_SIZE = 67108864; function rotateLeft(value, shift) { return value << shift | value >>> 32 - shift; } /** * cyrb128, a compact non-cryptographic string hash for seed generation. * * @see https://stackoverflow.com/a/47593316 */ function cyrb128(seed) { const value = `${seed}`; let s0 = 1779033703; let s1 = 3144134277; let s2 = 1013904242; let s3 = 2773480762; for (let i = 0; i < value.length; i++) { const code = value.charCodeAt(i); s0 = s1 ^ Math.imul(s0 ^ code, 597399067); s1 = s2 ^ Math.imul(s1 ^ code, 2869860233); s2 = s3 ^ Math.imul(s2 ^ code, 951274213); s3 = s0 ^ Math.imul(s3 ^ code, 2716044179); } s0 = Math.imul(s2 ^ s0 >>> 18, 597399067); s1 = Math.imul(s3 ^ s1 >>> 22, 2869860233); s2 = Math.imul(s0 ^ s2 >>> 17, 951274213); s3 = Math.imul(s1 ^ s3 >>> 19, 2716044179); s0 ^= s1 ^ s2 ^ s3; s1 ^= s0; s2 ^= s0; s3 ^= s0; return [ s0 >>> 0, s1 >>> 0, s2 >>> 0, s3 >>> 0 ]; } /** * xoshiro128** is a small, fast, general-purpose pseudorandom number generator * with 128 bits of state and a period of 2^128 - 1. * * It is not cryptographically secure. * * @see https://prng.di.unimi.it/xoshiro128starstar.c */ var Xoshiro128StarStarRNG = class Xoshiro128StarStarRNG extends RNG { constructor(seed = crypto.randomUUID()) { super(); _defineProperty(this, "_seed", void 0); _defineProperty(this, "s0", 0); _defineProperty(this, "s1", 0); _defineProperty(this, "s2", 0); _defineProperty(this, "s3", 0); this._seed = seed; this.setState(cyrb128(seed)); } setState(state) { this.s0 = state[0]; this.s1 = state[1]; this.s2 = state[2]; this.s3 = state[3]; if ((this.s0 | this.s1 | this.s2 | this.s3) === 0) this.s0 = 1831565813; } get name() { return "xoshiro128**"; } next() { const high = this.nextUint32() >>> 5; const low = this.nextUint32() >>> 6; return (high * UINT26_SIZE + low) / UINT53_SIZE; } clone() { const clone = new Xoshiro128StarStarRNG(this._seed); clone.setState([ this.s0, this.s1, this.s2, this.s3 ]); return clone; } nextUint32() { const result = Math.imul(rotateLeft(Math.imul(this.s1, 5), 7), 9) >>> 0; const t = this.s1 << 9; this.s2 ^= this.s0; this.s3 ^= this.s1; this.s1 ^= this.s2; this.s0 ^= this.s3; this.s2 ^= t; this.s3 = rotateLeft(this.s3, 11); return result; } }; //#endregion //#region src/utils.ts function createRNG(seedOrRNG) { switch (typeof seedOrRNG) { case "object": if (seedOrRNG instanceof RNG) return seedOrRNG; break; case "function": return new FunctionRNG(seedOrRNG); case "number": case "string": case "undefined": return new Xoshiro128StarStarRNG(seedOrRNG); } throw new TypeError(`Invalid seed or RNG: ${String(seedOrRNG)}`); } /** * Mixes a string seed into a key that is an array of integers, and returns a * shortened string seed that is equivalent to the result key. */ function mixKey(seed, key) { const seedStr = `${seed}`; let smear = 0; let j = 0; while (j < seedStr.length) key[255 & j] = 255 & (smear ^= (key[255 & j] ?? 0) * 19) + seedStr.charCodeAt(j++); if (!key.length) return [0]; return key; } function shuffleInPlace(gen, array) { for (let i = array.length - 1; i > 0; i -= 1) { const j = Math.floor(gen.next() * (i + 1)); const tmp = array[i]; array[i] = array[j]; array[j] = tmp; } } /** * Fisher-Yates sampling without replacement * O(k) time and space, by using a hash table instead of a full copy of the array * see https://arxiv.org/pdf/2104.05091 Algorithm 2 */ function sparseFisherYates(gen, array, k) { const H = /* @__PURE__ */ new Map(); const lastIndex = array.length - 1; const result = Array.from({ length: k }); for (let i = 0; i < k; i++) { const remaining = lastIndex - i + 1; const r = Math.floor(gen.next() * remaining); result[i] = array[H.get(r) ?? r]; H.set(r, H.get(lastIndex - i) ?? lastIndex - i); } return result; } //#endregion //#region src/generators/arc4.ts const _arc4_startdenom = 281474976710656; const _arc4_significance = 4503599627370496; const _arc4_overflow = 9007199254740992; var ARC4RNG = class ARC4RNG extends RNG { constructor(seed = crypto.randomUUID()) { super(); _defineProperty(this, "_seed", void 0); _defineProperty(this, "i", void 0); _defineProperty(this, "j", void 0); _defineProperty(this, "S", void 0); this._seed = seed; const key = mixKey(seed, []); const S = []; const keylen = key.length; this.i = 0; this.j = 0; this.S = S; let i = 0; while (i <= 255) S[i] = i++; for (let i = 0, j = 0; i <= 255; i++) { const t = S[i]; j = 255 & j + key[i % keylen] + t; S[i] = S[j]; S[j] = t; } this.g(256); } get name() { return "arc4"; } next() { let n = this.g(6); let d = _arc4_startdenom; let x = 0; while (n < _arc4_significance) { n = (n + x) * 256; d *= 256; x = this.g(1); } while (n >= _arc4_overflow) { n /= 2; d /= 2; x >>>= 1; } return (n + x) / d; } g(count) { const { S } = this; let { i, j } = this; let r = 0; while (count--) { i = 255 & i + 1; const t = S[i]; j = 255 & j + t; S[i] = S[j]; S[j] = t; r = r * 256 + S[255 & S[i] + t]; } this.i = i; this.j = j; return r; } clone() { const clone = new ARC4RNG(this._seed); clone.i = this.i; clone.j = this.j; clone.S = [...this.S]; return clone; } }; //#endregion //#region src/generators/math-random.ts var MathRandomRNG = class MathRandomRNG extends RNG { get name() { return "Math.random"; } next() { return Math.random(); } clone() { return new MathRandomRNG(); } }; //#endregion //#region src/generators/xor128.ts var XOR128RNG = class XOR128RNG extends RNG { constructor(seed = crypto.randomUUID()) { super(); _defineProperty(this, "_seed", void 0); _defineProperty(this, "x", void 0); _defineProperty(this, "y", void 0); _defineProperty(this, "z", void 0); _defineProperty(this, "w", void 0); this._seed = seed; this.x = 0; this.y = 0; this.z = 0; this.w = 0; let strSeed = ""; if (typeof seed === "number") this.x = seed; else strSeed += `${seed}`; for (let i = 0; i < strSeed.length + 64; ++i) { this.x ^= strSeed.charCodeAt(i) | 0; this.next(); } if ((this.x | this.y | this.z | this.w) === 0) { this.x = 1831565813; for (let i = 0; i < 64; ++i) this.next(); } } get name() { return "xor128"; } next() { const t = this.x ^ this.x << 11; this.x = this.y; this.y = this.z; this.z = this.w; this.w = this.w ^ (this.w >>> 19 ^ t ^ t >>> 8); return (this.w >>> 0) / 4294967296; } clone() { const clone = new XOR128RNG(this._seed); clone.x = this.x; clone.y = this.y; clone.z = this.z; clone.w = this.w; return clone; } }; //#endregion //#region src/validation.ts function numberValidator(num) { return new NumberValidator(num); } var NumberValidator = class { constructor(num) { _defineProperty(this, "n", void 0); _defineProperty(this, "isInt", () => { if (Number.isInteger(this.n)) return this; throw new Error(`Expected number to be an integer, got ${this.n}`); }); _defineProperty(this, "isPositive", () => { if (this.n > 0) return this; throw new Error(`Expected number to be positive, got ${this.n}`); }); _defineProperty(this, "lessThan", (v) => { if (this.n < v) return this; throw new Error(`Expected number to be less than ${v}, got ${this.n}`); }); _defineProperty(this, "lessThanOrEqual", (v) => { if (this.n <= v) return this; throw new Error(`Expected number to be less than or equal to ${v}, got ${this.n}`); }); _defineProperty(this, "greaterThanOrEqual", (v) => { if (this.n >= v) return this; throw new Error(`Expected number to be greater than or equal to ${v}, got ${this.n}`); }); _defineProperty(this, "greaterThan", (v) => { if (this.n > v) return this; throw new Error(`Expected number to be greater than ${v}, got ${this.n}`); }); this.n = num; } }; //#endregion //#region src/distributions/bates.ts function bates(random, n = 1) { numberValidator(n).isInt().isPositive(); const irwinHall = random.irwinHall(n); return () => { return irwinHall() / n; }; } //#endregion //#region src/distributions/bernoulli.ts function bernoulli(random, p = .5) { numberValidator(p).greaterThanOrEqual(0).lessThanOrEqual(1); return () => { return Math.min(1, Math.floor(random.next() + p)); }; } //#endregion //#region src/distributions/binomial.ts function binomial(random, n = 1, p = .5) { numberValidator(n).isInt().isPositive(); numberValidator(p).greaterThanOrEqual(0).lessThan(1); return () => { let i = 0; let x = 0; while (i++ < n) if (random.next() < p) x++; return x; }; } //#endregion //#region src/distributions/exponential.ts function exponential(random, lambda = 1) { numberValidator(lambda).isPositive(); return () => { return -Math.log(1 - random.next()) / lambda; }; } //#endregion //#region src/distributions/geometric.ts function geometric(random, p = .5) { numberValidator(p).greaterThan(0).lessThan(1); const invLogP = 1 / Math.log(1 - p); return () => { return Math.floor(1 + Math.log(random.next()) * invLogP); }; } //#endregion //#region src/distributions/irwin-hall.ts function irwinHall(random, n = 1) { numberValidator(n).isInt().greaterThanOrEqual(0); return () => { let sum = 0; for (let i = 0; i < n; ++i) sum += random.next(); return sum; }; } //#endregion //#region src/distributions/log-normal.ts function logNormal(random, mu = 0, sigma = 1) { const normal = random.normal(mu, sigma); return () => { return Math.exp(normal()); }; } //#endregion //#region src/distributions/normal.ts function normal(random, mu = 0, sigma = 1) { return () => { let x, y, r; do { x = random.next() * 2 - 1; y = random.next() * 2 - 1; r = x * x + y * y; } while (!r || r > 1); return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r); }; } //#endregion //#region src/distributions/pareto.ts function pareto(random, alpha = 1) { numberValidator(alpha).greaterThanOrEqual(0); const invAlpha = 1 / alpha; return () => { return 1 / Math.pow(1 - random.next(), invAlpha); }; } //#endregion //#region src/distributions/poisson.ts const logFactorialTable = [ 0, 0, .6931471805599453, 1.791759469228055, 3.1780538303479458, 4.787491742782046, 6.579251212010101, 8.525161361065415, 10.60460290274525, 12.801827480081469 ]; const logFactorial = (k) => { return logFactorialTable[k]; }; const logSqrt2PI = .9189385332046727; function poisson(random, lambda = 1) { numberValidator(lambda).isPositive(); if (lambda < 10) { const expMean = Math.exp(-lambda); return () => { let p = expMean; let x = 0; let u = random.next(); while (u > p) { u = u - p; p = lambda * p / ++x; } return x; }; } else { const smu = Math.sqrt(lambda); const b = .931 + 2.53 * smu; const a = -.059 + .02483 * b; const invAlpha = 1.1239 + 1.1328 / (b - 3.4); const vR = .9277 - 3.6224 / (b - 2); return () => { while (true) { let u; let v = random.next(); if (v <= .86 * vR) { u = v / vR - .43; return Math.floor((2 * a / (.5 - Math.abs(u)) + b) * u + lambda + .445); } if (v >= vR) u = random.next() - .5; else { u = v / vR - .93; u = (u < 0 ? -.5 : .5) - u; v = random.next() * vR; } const us = .5 - Math.abs(u); if (us < .013 && v > us) continue; const k = Math.floor((2 * a / us + b) * u + lambda + .445); v = v * invAlpha / (a / (us * us) + b); if (k >= 10) { const t = (k + .5) * Math.log(lambda / k) - lambda - logSqrt2PI + k - (1 / 12 - (1 / 360 - 1 / (1260 * k * k)) / (k * k)) / k; if (Math.log(v * smu) <= t) return k; } else if (k >= 0) { const f = logFactorial(k) ?? 0; if (Math.log(v) <= k * Math.log(lambda) - lambda - f) return k; } } }; } } //#endregion //#region src/distributions/uniform.ts function uniform(random, min, max) { if (max === void 0) { max = min === void 0 ? 1 : min; min = 0; } min ?? (min = 0); return () => { return random.next() * (max - min) + min; }; } //#endregion //#region src/distributions/uniform-boolean.ts function uniformBoolean(random) { return () => { return random.next() >= .5; }; } //#endregion //#region src/distributions/uniform-int.ts function uniformInt(random, min, max) { if (max === void 0) { max = min === void 0 ? 1 : min; min = 0; } min ?? (min = 0); numberValidator(min).isInt(); numberValidator(max).isInt(); return () => { return Math.floor(random.next() * (max - min + 1) + min); }; } //#endregion //#region src/distributions/weibull.ts function weibull(random, lambda, k) { numberValidator(lambda).greaterThan(0); numberValidator(k).greaterThan(0); return () => { const u = 1 - random.next(); return lambda * Math.pow(-Math.log(u), 1 / k); }; } //#endregion //#region src/random.ts /** * Seedable random number generator supporting many common distributions. * * @name Random * @class * * @param {RNG|function|string|number} [rng=Math.random] - Underlying random number generator or a seed for the default PRNG. Defaults to `Math.random`. */ var Random = class Random { constructor(seedOrRNG = new MathRandomRNG()) { _defineProperty(this, "_rng", void 0); _defineProperty(this, "_cache", {}); this._rng = createRNG(seedOrRNG); } /** * @member {RNG} rng - Underlying pseudo-random number generator. */ get rng() { return this._rng; } /** * Creates a new `Random` instance, optionally specifying parameters to * set a new seed. */ clone(seedOrRNG = this.rng.clone()) { return new Random(seedOrRNG); } /** * Sets the underlying pseudorandom number generator. * * @example * ```ts * import random from 'random' * * random.use('example-seed') * // or * random.use(Math.random) * ``` */ use(seedOrRNG) { this._rng = createRNG(seedOrRNG); this._cache = {}; } /** * Convenience wrapper around `this.rng.next()` * * Returns a floating point number in [0, 1). * * @return {number} */ next() { return this._rng.next(); } /** * Samples a uniform random floating point number, optionally specifying * lower and upper bounds. * * Convenience wrapper around `random.uniform()` * * @param {number} [min=0] - Lower bound (float, inclusive) * @param {number} [max=1] - Upper bound (float, exclusive) */ float(min, max) { return this.uniform(min, max)(); } /** * Samples a uniform random integer, optionally specifying lower and upper * bounds. * * Convenience wrapper around `random.uniformInt()` * * @param {number} [min=0] - Lower bound (integer, inclusive) * @param {number} [max=1] - Upper bound (integer, inclusive) */ int(min, max) { return this.uniformInt(min, max)(); } /** * Samples a uniform random integer, optionally specifying lower and upper * bounds. * * Convenience wrapper around `random.uniformInt()` * * @alias `random.int` * * @param {number} [min=0] - Lower bound (integer, inclusive) * @param {number} [max=1] - Upper bound (integer, inclusive) */ integer(min, max) { return this.uniformInt(min, max)(); } /** * Samples a uniform random boolean value. * * Convenience wrapper around `random.uniformBoolean()` * * @alias `random.boolean` */ bool() { return this.uniformBoolean()(); } /** * Samples a uniform random boolean value. * * Convenience wrapper around `random.uniformBoolean()` */ boolean() { return this.uniformBoolean()(); } /** * Returns an item chosen uniformly at random from the given array. * If weights are provided, returns an item based on weighted probabilities. * * Convenience wrapper around `random.uniformInt()` for uniform selection, * or implements weighted selection using cumulative distribution. * * @param {Array<T>} [array] - Input array * @param {Array<number>} [weights] - Optional weights for each item (must be same length as array) */ choice(array, weights) { if (!Array.isArray(array)) throw new TypeError(`Random.choice expected input to be an array, got ${typeof array}`); const length = array.length; if (length === 0) return; if (!weights) return array[this.uniformInt(0, length - 1)()]; if (!Array.isArray(weights)) throw new TypeError(`Random.choice expected weights to be an array, got ${typeof weights}`); if (weights.length !== length) throw new Error(`Random.choice expected weights array length (${weights.length}) to match array length (${length})`); for (const [i, weight] of weights.entries()) if (typeof weight !== "number" || weight < 0 || !Number.isFinite(weight)) throw new Error(`Random.choice expected all weights to be non-negative finite numbers, got ${weight} at index ${i}`); const totalWeight = weights.reduce((sum, weight) => sum + weight, 0); if (totalWeight === 0) throw new Error("Random.choice expected at least one positive weight, got all zeros"); const random = this.float(0, totalWeight); let cumulativeWeight = 0; for (let i = 0; i < length; i++) { cumulativeWeight += weights[i]; if (random <= cumulativeWeight) return array[i]; } return array[length - 1]; } /** * Returns a random subset of k items from the given array (without replacement). * * @param {Array<T>} [array] - Input array */ sample(array, k) { if (!Array.isArray(array)) throw new TypeError(`Random.sample expected input to be an array, got ${typeof array}`); if (k < 0 || k > array.length) throw new Error(`Random.sample: k must be between 0 and array.length (${array.length}), got ${k}`); return sparseFisherYates(this.rng, array, k); } /** * Generates a thunk which returns samples of size k from the given array. * * This is for convenience only; there is no gain in efficiency. * * @param {Array<T>} [array] - Input array */ sampler(array, k) { if (!Array.isArray(array)) throw new TypeError(`Random.sampler expected input to be an array, got ${typeof array}`); if (k < 0 || k > array.length) throw new Error(`Random.sampler: k must be between 0 and array.length (${array.length}), got ${k}`); const gen = this.rng; return () => { return sparseFisherYates(gen, array, k); }; } /** * Returns a shuffled copy of the given array. * * @param {Array<T>} [array] - Input array */ shuffle(array) { if (!Array.isArray(array)) throw new TypeError(`Random.shuffle expected input to be an array, got ${typeof array}`); const copy = [...array]; shuffleInPlace(this.rng, copy); return copy; } /** * Generates a thunk which returns shuffled copies of the given array. * * @param {Array<T>} [array] - Input array */ shuffler(array) { if (!Array.isArray(array)) throw new TypeError(`Random.shuffler expected input to be an array, got ${typeof array}`); const gen = this.rng; const copy = [...array]; return () => { shuffleInPlace(gen, copy); return [...copy]; }; } /** * Generates a [Continuous uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)). * * @param {number} [min=0] - Lower bound (float, inclusive) * @param {number} [max=1] - Upper bound (float, exclusive) */ uniform(min, max) { return this._memoize("uniform", uniform, min, max); } /** * Generates a [Discrete uniform distribution](https://en.wikipedia.org/wiki/Discrete_uniform_distribution). * * @param {number} [min=0] - Lower bound (integer, inclusive) * @param {number} [max=1] - Upper bound (integer, inclusive) */ uniformInt(min, max) { return this._memoize("uniformInt", uniformInt, min, max); } /** * Generates a [Discrete uniform distribution](https://en.wikipedia.org/wiki/Discrete_uniform_distribution), * with two possible outcomes, `true` or `false. * * This method is analogous to flipping a coin. */ uniformBoolean() { return this._memoize("uniformBoolean", uniformBoolean); } /** * Generates a [Normal distribution](https://en.wikipedia.org/wiki/Normal_distribution). * * @param {number} [mu=0] - Mean * @param {number} [sigma=1] - Standard deviation */ normal(mu, sigma) { return normal(this, mu, sigma); } /** * Generates a [Log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution). * * @param {number} [mu=0] - Mean of underlying normal distribution * @param {number} [sigma=1] - Standard deviation of underlying normal distribution */ logNormal(mu, sigma) { return logNormal(this, mu, sigma); } /** * Generates a [Bernoulli distribution](https://en.wikipedia.org/wiki/Bernoulli_distribution). * * @param {number} [p=0.5] - Success probability of each trial. */ bernoulli(p) { return bernoulli(this, p); } /** * Generates a [Binomial distribution](https://en.wikipedia.org/wiki/Binomial_distribution). * * @param {number} [n=1] - Number of trials. * @param {number} [p=0.5] - Success probability of each trial. */ binomial(n, p) { return binomial(this, n, p); } /** * Generates a [Geometric distribution](https://en.wikipedia.org/wiki/Geometric_distribution). * * @param {number} [p=0.5] - Success probability of each trial. */ geometric(p) { return geometric(this, p); } /** * Generates a [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution). * * @param {number} [lambda=1] - Mean (lambda > 0) */ poisson(lambda) { return poisson(this, lambda); } /** * Generates an [Exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution). * * @param {number} [lambda=1] - Inverse mean (lambda > 0) */ exponential(lambda) { return exponential(this, lambda); } /** * Generates an [Irwin Hall distribution](https://en.wikipedia.org/wiki/Irwin%E2%80%93Hall_distribution). * * @param {number} [n=1] - Number of uniform samples to sum (n >= 0) */ irwinHall(n) { return irwinHall(this, n); } /** * Generates a [Bates distribution](https://en.wikipedia.org/wiki/Bates_distribution). * * @param {number} [n=1] - Number of uniform samples to average (n >= 1) */ bates(n) { return bates(this, n); } /** * Generates a [Pareto distribution](https://en.wikipedia.org/wiki/Pareto_distribution). * * @param {number} [alpha=1] - Alpha */ pareto(alpha) { return pareto(this, alpha); } /** * Generates a [Weibull distribution](https://en.wikipedia.org/wiki/Weibull_distribution). * * @param {number} [lambda] - Lambda, the scale parameter * @param {number} [k] - k, the shape parameter */ weibull(lambda, k) { return weibull(this, lambda, k); } /** * Memoizes distributions to ensure they're only created when necessary. * * Returns a thunk which that returns independent, identically distributed * samples from the specified distribution. * * @internal * * @param {string} label - Name of distribution * @param {function} getter - Function which generates a new distribution * @param {...*} args - Distribution-specific arguments */ _memoize(label, getter, ...args) { const key = `${args.join(";")}`; let value = this._cache[label]; if (value === void 0 || value.key !== key) { value = { key, distribution: getter(this, ...args) }; this._cache[label] = value; } return value.distribution; } }; var random_default = new Random(); //#endregion export { ARC4RNG, FunctionRNG, MathRandomRNG, RNG, Random, XOR128RNG, Xoshiro128StarStarRNG, createRNG, random_default as default, mixKey, shuffleInPlace, sparseFisherYates }; //# sourceMappingURL=index.js.map