347 lines
11 KiB
JavaScript
347 lines
11 KiB
JavaScript
//////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// This is a generated file. You can view the original //
|
|
// source in your browser if your browser supports source maps. //
|
|
// Source maps are supported by all recent versions of Chrome, Safari, //
|
|
// and Firefox, and by Internet Explorer 11. //
|
|
// //
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
(function () {
|
|
|
|
/* Imports */
|
|
var Meteor = Package.meteor.Meteor;
|
|
var global = Package.meteor.global;
|
|
var meteorEnv = Package.meteor.meteorEnv;
|
|
var meteorInstall = Package.modules.meteorInstall;
|
|
var meteorBabelHelpers = Package['babel-runtime'].meteorBabelHelpers;
|
|
var Promise = Package.promise.Promise;
|
|
var Symbol = Package['ecmascript-runtime-client'].Symbol;
|
|
var Map = Package['ecmascript-runtime-client'].Map;
|
|
var Set = Package['ecmascript-runtime-client'].Set;
|
|
|
|
/* Package-scope variables */
|
|
var Random;
|
|
|
|
var require = meteorInstall({"node_modules":{"meteor":{"random":{"random.js":function(require){
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// packages/random/random.js //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// We use cryptographically strong PRNGs (crypto.getRandomBytes() on the server,
|
|
// window.crypto.getRandomValues() in the browser) when available. If these
|
|
// PRNGs fail, we fall back to the Alea PRNG, which is not cryptographically
|
|
// strong, and we seed it with various sources such as the date, Math.random,
|
|
// and window size on the client. When using crypto.getRandomValues(), our
|
|
// primitive is hexString(), from which we construct fraction(). When using
|
|
// window.crypto.getRandomValues() or alea, the primitive is fraction and we use
|
|
// that to construct hex string.
|
|
if (Meteor.isServer) var nodeCrypto = Npm.require('crypto'); // see http://baagoe.org/en/wiki/Better_random_numbers_for_javascript
|
|
// for a full discussion and Alea implementation.
|
|
|
|
var Alea = function () {
|
|
function Mash() {
|
|
var n = 0xefc8249d;
|
|
|
|
var mash = function (data) {
|
|
data = data.toString();
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
n += data.charCodeAt(i);
|
|
var h = 0.02519603282416938 * n;
|
|
n = h >>> 0;
|
|
h -= n;
|
|
h *= n;
|
|
n = h >>> 0;
|
|
h -= n;
|
|
n += h * 0x100000000; // 2^32
|
|
}
|
|
|
|
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
|
|
};
|
|
|
|
mash.version = 'Mash 0.9';
|
|
return mash;
|
|
}
|
|
|
|
return function (args) {
|
|
var s0 = 0;
|
|
var s1 = 0;
|
|
var s2 = 0;
|
|
var c = 1;
|
|
|
|
if (args.length == 0) {
|
|
args = [+new Date()];
|
|
}
|
|
|
|
var mash = Mash();
|
|
s0 = mash(' ');
|
|
s1 = mash(' ');
|
|
s2 = mash(' ');
|
|
|
|
for (var i = 0; i < args.length; i++) {
|
|
s0 -= mash(args[i]);
|
|
|
|
if (s0 < 0) {
|
|
s0 += 1;
|
|
}
|
|
|
|
s1 -= mash(args[i]);
|
|
|
|
if (s1 < 0) {
|
|
s1 += 1;
|
|
}
|
|
|
|
s2 -= mash(args[i]);
|
|
|
|
if (s2 < 0) {
|
|
s2 += 1;
|
|
}
|
|
}
|
|
|
|
mash = null;
|
|
|
|
var random = function () {
|
|
var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
|
|
|
|
s0 = s1;
|
|
s1 = s2;
|
|
return s2 = t - (c = t | 0);
|
|
};
|
|
|
|
random.uint32 = function () {
|
|
return random() * 0x100000000; // 2^32
|
|
};
|
|
|
|
random.fract53 = function () {
|
|
return random() + (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
|
|
};
|
|
|
|
random.version = 'Alea 0.9';
|
|
random.args = args;
|
|
return random;
|
|
}(Array.prototype.slice.call(arguments));
|
|
};
|
|
|
|
var UNMISTAKABLE_CHARS = "23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz";
|
|
var BASE64_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789-_"; // `type` is one of `RandomGenerator.Type` as defined below.
|
|
//
|
|
// options:
|
|
// - seeds: (required, only for RandomGenerator.Type.ALEA) an array
|
|
// whose items will be `toString`ed and used as the seed to the Alea
|
|
// algorithm
|
|
|
|
var RandomGenerator = function (type, options) {
|
|
var self = this;
|
|
self.type = type;
|
|
|
|
if (!RandomGenerator.Type[type]) {
|
|
throw new Error("Unknown random generator type: " + type);
|
|
}
|
|
|
|
if (type === RandomGenerator.Type.ALEA) {
|
|
if (!options.seeds) {
|
|
throw new Error("No seeds were provided for Alea PRNG");
|
|
}
|
|
|
|
self.alea = Alea.apply(null, options.seeds);
|
|
}
|
|
}; // Types of PRNGs supported by the `RandomGenerator` class
|
|
|
|
|
|
RandomGenerator.Type = {
|
|
// Use Node's built-in `crypto.getRandomBytes` (cryptographically
|
|
// secure but not seedable, runs only on the server). Reverts to
|
|
// `crypto.getPseudoRandomBytes` in the extremely uncommon case that
|
|
// there isn't enough entropy yet
|
|
NODE_CRYPTO: "NODE_CRYPTO",
|
|
// Use non-IE browser's built-in `window.crypto.getRandomValues`
|
|
// (cryptographically secure but not seedable, runs only in the
|
|
// browser).
|
|
BROWSER_CRYPTO: "BROWSER_CRYPTO",
|
|
// Use the *fast*, seedaable and not cryptographically secure
|
|
// Alea algorithm
|
|
ALEA: "ALEA"
|
|
};
|
|
/**
|
|
* @name Random.fraction
|
|
* @summary Return a number between 0 and 1, like `Math.random`.
|
|
* @locus Anywhere
|
|
*/
|
|
|
|
RandomGenerator.prototype.fraction = function () {
|
|
var self = this;
|
|
|
|
if (self.type === RandomGenerator.Type.ALEA) {
|
|
return self.alea();
|
|
} else if (self.type === RandomGenerator.Type.NODE_CRYPTO) {
|
|
var numerator = parseInt(self.hexString(8), 16);
|
|
return numerator * 2.3283064365386963e-10; // 2^-32
|
|
} else if (self.type === RandomGenerator.Type.BROWSER_CRYPTO) {
|
|
var array = new Uint32Array(1);
|
|
window.crypto.getRandomValues(array);
|
|
return array[0] * 2.3283064365386963e-10; // 2^-32
|
|
} else {
|
|
throw new Error('Unknown random generator type: ' + self.type);
|
|
}
|
|
};
|
|
/**
|
|
* @name Random.hexString
|
|
* @summary Return a random string of `n` hexadecimal digits.
|
|
* @locus Anywhere
|
|
* @param {Number} n Length of the string
|
|
*/
|
|
|
|
|
|
RandomGenerator.prototype.hexString = function (digits) {
|
|
var self = this;
|
|
|
|
if (self.type === RandomGenerator.Type.NODE_CRYPTO) {
|
|
var numBytes = Math.ceil(digits / 2);
|
|
var bytes; // Try to get cryptographically strong randomness. Fall back to
|
|
// non-cryptographically strong if not available.
|
|
|
|
try {
|
|
bytes = nodeCrypto.randomBytes(numBytes);
|
|
} catch (e) {
|
|
// XXX should re-throw any error except insufficient entropy
|
|
bytes = nodeCrypto.pseudoRandomBytes(numBytes);
|
|
}
|
|
|
|
var result = bytes.toString("hex"); // If the number of digits is odd, we'll have generated an extra 4 bits
|
|
// of randomness, so we need to trim the last digit.
|
|
|
|
return result.substring(0, digits);
|
|
} else {
|
|
return this._randomString(digits, "0123456789abcdef");
|
|
}
|
|
};
|
|
|
|
RandomGenerator.prototype._randomString = function (charsCount, alphabet) {
|
|
var self = this;
|
|
var digits = [];
|
|
|
|
for (var i = 0; i < charsCount; i++) {
|
|
digits[i] = self.choice(alphabet);
|
|
}
|
|
|
|
return digits.join("");
|
|
};
|
|
/**
|
|
* @name Random.id
|
|
* @summary Return a unique identifier, such as `"Jjwjg6gouWLXhMGKW"`, that is
|
|
* likely to be unique in the whole world.
|
|
* @locus Anywhere
|
|
* @param {Number} [n] Optional length of the identifier in characters
|
|
* (defaults to 17)
|
|
*/
|
|
|
|
|
|
RandomGenerator.prototype.id = function (charsCount) {
|
|
var self = this; // 17 characters is around 96 bits of entropy, which is the amount of
|
|
// state in the Alea PRNG.
|
|
|
|
if (charsCount === undefined) charsCount = 17;
|
|
return self._randomString(charsCount, UNMISTAKABLE_CHARS);
|
|
};
|
|
/**
|
|
* @name Random.secret
|
|
* @summary Return a random string of printable characters with 6 bits of
|
|
* entropy per character. Use `Random.secret` for security-critical secrets
|
|
* that are intended for machine, rather than human, consumption.
|
|
* @locus Anywhere
|
|
* @param {Number} [n] Optional length of the secret string (defaults to 43
|
|
* characters, or 256 bits of entropy)
|
|
*/
|
|
|
|
|
|
RandomGenerator.prototype.secret = function (charsCount) {
|
|
var self = this; // Default to 256 bits of entropy, or 43 characters at 6 bits per
|
|
// character.
|
|
|
|
if (charsCount === undefined) charsCount = 43;
|
|
return self._randomString(charsCount, BASE64_CHARS);
|
|
};
|
|
/**
|
|
* @name Random.choice
|
|
* @summary Return a random element of the given array or string.
|
|
* @locus Anywhere
|
|
* @param {Array|String} arrayOrString Array or string to choose from
|
|
*/
|
|
|
|
|
|
RandomGenerator.prototype.choice = function (arrayOrString) {
|
|
var index = Math.floor(this.fraction() * arrayOrString.length);
|
|
if (typeof arrayOrString === "string") return arrayOrString.substr(index, 1);else return arrayOrString[index];
|
|
}; // instantiate RNG. Heuristically collect entropy from various sources when a
|
|
// cryptographic PRNG isn't available.
|
|
// client sources
|
|
|
|
|
|
var height = typeof window !== 'undefined' && window.innerHeight || typeof document !== 'undefined' && document.documentElement && document.documentElement.clientHeight || typeof document !== 'undefined' && document.body && document.body.clientHeight || 1;
|
|
var width = typeof window !== 'undefined' && window.innerWidth || typeof document !== 'undefined' && document.documentElement && document.documentElement.clientWidth || typeof document !== 'undefined' && document.body && document.body.clientWidth || 1;
|
|
var agent = typeof navigator !== 'undefined' && navigator.userAgent || "";
|
|
|
|
function createAleaGeneratorWithGeneratedSeed() {
|
|
return new RandomGenerator(RandomGenerator.Type.ALEA, {
|
|
seeds: [new Date(), height, width, agent, Math.random()]
|
|
});
|
|
}
|
|
|
|
;
|
|
|
|
if (Meteor.isServer) {
|
|
Random = new RandomGenerator(RandomGenerator.Type.NODE_CRYPTO);
|
|
} else {
|
|
if (typeof window !== "undefined" && window.crypto && window.crypto.getRandomValues) {
|
|
Random = new RandomGenerator(RandomGenerator.Type.BROWSER_CRYPTO);
|
|
} else {
|
|
// On IE 10 and below, there's no browser crypto API
|
|
// available. Fall back to Alea
|
|
//
|
|
// XXX looks like at the moment, we use Alea in IE 11 as well,
|
|
// which has `window.msCrypto` instead of `window.crypto`.
|
|
Random = createAleaGeneratorWithGeneratedSeed();
|
|
}
|
|
} // Create a non-cryptographically secure PRNG with a given seed (using
|
|
// the Alea algorithm)
|
|
|
|
|
|
Random.createWithSeeds = function () {
|
|
for (var _len = arguments.length, seeds = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
seeds[_key] = arguments[_key];
|
|
}
|
|
|
|
if (seeds.length === 0) {
|
|
throw new Error("No seeds were provided");
|
|
}
|
|
|
|
return new RandomGenerator(RandomGenerator.Type.ALEA, {
|
|
seeds: seeds
|
|
});
|
|
}; // Used like `Random`, but much faster and not cryptographically
|
|
// secure
|
|
|
|
|
|
Random.insecure = createAleaGeneratorWithGeneratedSeed();
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
}}}}},{
|
|
"extensions": [
|
|
".js",
|
|
".json"
|
|
]
|
|
});
|
|
require("/node_modules/meteor/random/random.js");
|
|
|
|
/* Exports */
|
|
Package._define("random", {
|
|
Random: Random
|
|
});
|
|
|
|
})();
|