|  | @@ -0,0 +1,251 @@
 | 
	
		
			
				|  |  | +module.exports = function nailfactory(boot) {
 | 
	
		
			
				|  |  | +    var BOOT = boot || 0xbadebabe;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    function stringify(obj, replacer, spaces, cycleReplacer) {
 | 
	
		
			
				|  |  | +        return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    function serializer(replacer, cycleReplacer) {
 | 
	
		
			
				|  |  | +        var stack = [],
 | 
	
		
			
				|  |  | +            keys = []
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (cycleReplacer == null) cycleReplacer = function(key, value) {
 | 
	
		
			
				|  |  | +            if (stack[0] === value) return "[Circular ~]"
 | 
	
		
			
				|  |  | +            return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]"
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        /*
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return function(key, value) {
 | 
	
		
			
				|  |  | +            if (stack.length > 0) {
 | 
	
		
			
				|  |  | +                var thisPos = stack.indexOf(this);
 | 
	
		
			
				|  |  | +                (~thisPos) ? stack.splice(thisPos + 1) : stack.push(this);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                (~thisPos) ? keys.splice(thisPos, Infinity, key) : keys.push(key);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if (~stack.indexOf(value)) {
 | 
	
		
			
				|  |  | +                    value = cycleReplacer.call(this, key, value)
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                stack.push(value)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return replacer == null ? value : replacer.call(this, key, value)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    var Mash = function() {
 | 
	
		
			
				|  |  | +        //	var n = 0xefc8249d;
 | 
	
		
			
				|  |  | +        var n = BOOT;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        var mash = function(data) {
 | 
	
		
			
				|  |  | +            if (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
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                n = BOOT;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        return mash;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    var uheprng = function(seed) {
 | 
	
		
			
				|  |  | +        return (function() {
 | 
	
		
			
				|  |  | +            var o = 48; // set the 'order' number of ENTROPY-holding 32-bit values
 | 
	
		
			
				|  |  | +            var c = 1; // init the 'carry' used by the multiply-with-carry (MWC) algorithm
 | 
	
		
			
				|  |  | +            var p = o; // init the 'phase' (max-1) of the intermediate variable pointer
 | 
	
		
			
				|  |  | +            var s = new Array(o); // declare our intermediate variables array
 | 
	
		
			
				|  |  | +            var i; // general purpose local
 | 
	
		
			
				|  |  | +            var j; // general purpose local
 | 
	
		
			
				|  |  | +            var k = 0; // general purpose local
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // when our "uheprng" is initially invoked our PRNG state is initialized from the
 | 
	
		
			
				|  |  | +            // browser's own local PRNG. This is okay since although its generator might not
 | 
	
		
			
				|  |  | +            // be wonderful, it's useful for establishing large startup entropy for our usage.
 | 
	
		
			
				|  |  | +            var mash = new Mash(); // get a pointer to our high-performance "Mash" hash
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // fill the array with initial mash hash values
 | 
	
		
			
				|  |  | +            for (i = 0; i < o; i++) {
 | 
	
		
			
				|  |  | +                s[i] = mash(Math.random());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this PRIVATE (internal access only) function is the heart of the multiply-with-carry
 | 
	
		
			
				|  |  | +            // (MWC) PRNG algorithm. When called it returns a pseudo-random number in the form of a
 | 
	
		
			
				|  |  | +            // 32-bit JavaScript fraction (0.0 to <1.0) it is a PRIVATE function used by the default
 | 
	
		
			
				|  |  | +            // [0-1] return function, and by the random 'string(n)' function which returns 'n'
 | 
	
		
			
				|  |  | +            // characters from 33 to 126.
 | 
	
		
			
				|  |  | +            var rawprng = function() {
 | 
	
		
			
				|  |  | +                if (++p >= o) {
 | 
	
		
			
				|  |  | +                    p = 0;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                var t = 1768863 * s[p] + c * 2.3283064365386963e-10; // 2^-32
 | 
	
		
			
				|  |  | +                return s[p] = t - (c = t | 0);
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this EXPORTED function is the default function returned by this library.
 | 
	
		
			
				|  |  | +            // The values returned are integers in the range from 0 to range-1. We first
 | 
	
		
			
				|  |  | +            // obtain two 32-bit fractions (from rawprng) to synthesize a single high
 | 
	
		
			
				|  |  | +            // resolution 53-bit prng (0 to <1), then we multiply this by the caller's
 | 
	
		
			
				|  |  | +            // "range" param and take the "floor" to return a equally probable integer.
 | 
	
		
			
				|  |  | +            var random = function(range) {
 | 
	
		
			
				|  |  | +                return Math.floor(range * (rawprng() + (rawprng() * 0x200000 | 0) * 1.1102230246251565e-16)); // 2^-53
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this EXPORTED function 'string(n)' returns a pseudo-random string of
 | 
	
		
			
				|  |  | +            // 'n' printable characters ranging from chr(33) to chr(126) inclusive.
 | 
	
		
			
				|  |  | +            random.string = function(count) {
 | 
	
		
			
				|  |  | +                var i;
 | 
	
		
			
				|  |  | +                var s = '';
 | 
	
		
			
				|  |  | +                for (i = 0; i < count; i++) {
 | 
	
		
			
				|  |  | +                    s += String.fromCharCode(33 + random(94));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                return s;
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this PRIVATE "hash" function is used to evolve the generator's internal
 | 
	
		
			
				|  |  | +            // entropy state. It is also called by the EXPORTED addEntropy() function
 | 
	
		
			
				|  |  | +            // which is used to pour entropy into the PRNG.
 | 
	
		
			
				|  |  | +            var hash = function() {
 | 
	
		
			
				|  |  | +                var args = Array.prototype.slice.call(arguments);
 | 
	
		
			
				|  |  | +                for (i = 0; i < args.length; i++) {
 | 
	
		
			
				|  |  | +                    for (j = 0; j < o; j++) {
 | 
	
		
			
				|  |  | +                        s[j] -= mash(args[i]);
 | 
	
		
			
				|  |  | +                        if (s[j] < 0) {
 | 
	
		
			
				|  |  | +                            s[j] += 1;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this EXPORTED "clean string" function removes leading and trailing spaces and non-printing
 | 
	
		
			
				|  |  | +            // control characters, including any embedded carriage-return (CR) and line-feed (LF) characters,
 | 
	
		
			
				|  |  | +            // from any string it is handed. this is also used by the 'hashstring' function (below) to help
 | 
	
		
			
				|  |  | +            // users always obtain the same EFFECTIVE uheprng seeding key.
 | 
	
		
			
				|  |  | +            random.cleanString = function(inStr) {
 | 
	
		
			
				|  |  | +                inStr = inStr.replace(/(^\s*)|(\s*$)/gi, ''); // remove any/all leading spaces
 | 
	
		
			
				|  |  | +                inStr = inStr.replace(/[\x00-\x1F]/gi, ''); // remove any/all control characters
 | 
	
		
			
				|  |  | +                inStr = inStr.replace(/\n /, '\n'); // remove any/all trailing spaces
 | 
	
		
			
				|  |  | +                return inStr; // return the cleaned up result
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this EXPORTED "hash string" function hashes the provided character string after first removing
 | 
	
		
			
				|  |  | +            // any leading or trailing spaces and ignoring any embedded carriage returns (CR) or Line Feeds (LF)
 | 
	
		
			
				|  |  | +            random.hashString = function(inStr) {
 | 
	
		
			
				|  |  | +                inStr = random.cleanString(inStr);
 | 
	
		
			
				|  |  | +                mash(inStr); // use the string to evolve the 'mash' state
 | 
	
		
			
				|  |  | +                for (i = 0; i < inStr.length; i++) { // scan through the characters in our string
 | 
	
		
			
				|  |  | +                    k = inStr.charCodeAt(i); // get the character code at the location
 | 
	
		
			
				|  |  | +                    for (j = 0; j < o; j++) { //	"mash" it into the UHEPRNG state
 | 
	
		
			
				|  |  | +                        s[j] -= mash(k);
 | 
	
		
			
				|  |  | +                        if (s[j] < 0) {
 | 
	
		
			
				|  |  | +                            s[j] += 1;
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this EXPORTED function allows you to seed the random generator.
 | 
	
		
			
				|  |  | +            random.seed = function(seed) {
 | 
	
		
			
				|  |  | +                if (typeof seed === 'undefined' || seed === null) {
 | 
	
		
			
				|  |  | +                    seed = Math.random();
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (typeof seed !== 'string') {
 | 
	
		
			
				|  |  | +                    seed = stringify(seed, function(key, value) {
 | 
	
		
			
				|  |  | +                        if (typeof value === 'function') {
 | 
	
		
			
				|  |  | +                            return (value).toString();
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                        return value;
 | 
	
		
			
				|  |  | +                    });
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                random.initState();
 | 
	
		
			
				|  |  | +                random.hashString(seed);
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // this handy exported function is used to add entropy to our uheprng at any time
 | 
	
		
			
				|  |  | +            random.addEntropy = function( /* accept zero or more arguments */ ) {
 | 
	
		
			
				|  |  | +                var args = [];
 | 
	
		
			
				|  |  | +                for (i = 0; i < arguments.length; i++) {
 | 
	
		
			
				|  |  | +                    args.push(arguments[i]);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                hash(args.join(''));
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // if we want to provide a deterministic startup context for our PRNG,
 | 
	
		
			
				|  |  | +            // but without directly setting the internal state variables, this allows
 | 
	
		
			
				|  |  | +            // us to initialize the mash hash and PRNG's internal state before providing
 | 
	
		
			
				|  |  | +            // some hashing input
 | 
	
		
			
				|  |  | +            random.initState = function() {
 | 
	
		
			
				|  |  | +                mash(); // pass a null arg to force mash hash to init
 | 
	
		
			
				|  |  | +                for (i = 0; i < o; i++) {
 | 
	
		
			
				|  |  | +                    s[i] = mash(' '); // fill the array with initial mash hash values
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                c = 1; // init our multiply-with-carry carry
 | 
	
		
			
				|  |  | +                p = o; // init our phase
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // we use this (optional) exported function to signal the JavaScript interpreter
 | 
	
		
			
				|  |  | +            // that we're finished using the "Mash" hash function so that it can free up the
 | 
	
		
			
				|  |  | +            // local "instance variables" is will have been maintaining.  It's not strictly
 | 
	
		
			
				|  |  | +            // necessary, of course, but it's good JavaScript citizenship.
 | 
	
		
			
				|  |  | +            random.done = function() {
 | 
	
		
			
				|  |  | +                mash = null;
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // if we called "uheprng" with a seed value, then execute random.seed() before returning
 | 
	
		
			
				|  |  | +            if (typeof seed !== 'undefined') {
 | 
	
		
			
				|  |  | +                random.seed(seed);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Returns a random integer between 0 (inclusive) and range (exclusive)
 | 
	
		
			
				|  |  | +            random.range = function(range) {
 | 
	
		
			
				|  |  | +                return random(range);
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Returns a random float between 0 (inclusive) and 1 (exclusive)
 | 
	
		
			
				|  |  | +            random.random = function() {
 | 
	
		
			
				|  |  | +                return random(Number.MAX_VALUE - 1) / Number.MAX_VALUE;
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Returns a random float between min (inclusive) and max (exclusive)
 | 
	
		
			
				|  |  | +            random.floatBetween = function(min, max) {
 | 
	
		
			
				|  |  | +                return random.random() * (max - min) + min;
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // Returns a random integer between min (inclusive) and max (inclusive)
 | 
	
		
			
				|  |  | +            random.intBetween = function(min, max) {
 | 
	
		
			
				|  |  | +                return Math.floor(random.random() * (max - min + 1)) + min;
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // when our main outer "uheprng" function is called, after setting up our
 | 
	
		
			
				|  |  | +            // initial variables and entropic state, we return an "instance pointer"
 | 
	
		
			
				|  |  | +            // to the internal anonymous function which can then be used to access
 | 
	
		
			
				|  |  | +            // the uheprng's various exported functions.  As with the ".done" function
 | 
	
		
			
				|  |  | +            // above, we should set the returned value to 'null' once we're finished
 | 
	
		
			
				|  |  | +            // using any of these functions.
 | 
	
		
			
				|  |  | +            return random;
 | 
	
		
			
				|  |  | +        }());
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // Modification for use in node:
 | 
	
		
			
				|  |  | +    uheprng.create = function(seed) {
 | 
	
		
			
				|  |  | +        return new uheprng(seed);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return uheprng;
 | 
	
		
			
				|  |  | +}
 |