terra is a super customizable library for creating and analyzing biological simulations. It's open-source and licenced under MIT.
+terra is a super customizable library for creating and analyzing biological simulations. It's open-source and licensed under MIT.
Usage
@@ -66,7 +66,7 @@ window.terra;Creating the environment
To run a simulation, we'll need to create an environment. Let's make a 25x25 grid, populate 10% of the space with our lonely purple creature, and fill the rest with simple plants.
-var ex1 = new terra.Terrarium(25, 25, 'ex1');
+ var ex1 = new terra.Terrarium(25, 25, {id: 'ex1'});
ex1.grid = ex1.makeGridWithDistribution([['secondCreature', 10], ['simplePlant', 90]]);
Running a simulation
@@ -79,7 +79,10 @@ ex1.grid = ex1.makeGridWithDistribution([['secondCreature', 10], ['simplePlant',
Examples
Conway's Game of Life ?
- var gameOfLife = new terra.Terrarium(25, 25);
+ var gameOfLife = new terra.Terrarium(25, 25, {
+ trails: 0.9,
+ background: [22, 22, 22]
+});
terra.registerCA({
type: 'GoL',
@@ -342,9 +345,13 @@ elementary.animate();
Terrarium
Terrariums are where the action happens. They're initialized with the following constructor:
- //new terra.Terrarium(width, height, id, cellSize, insertAfter);
+ //new terra.Terrarium(width, height, {options});
//example: create a 4x4 terrarium called #myTerrarium after element #bugStory
-var t = new terra.Terrarium(4, 4, 'myTerrarium', 15, document.getElementById('bugStory');
+var t = new terra.Terrarium(4, 4, {
+ id: 'myTerrarium',
+ cellSize: 15,
+ insertAfter: document.getElementById('bugStory')
+});
Required
-
@@ -376,6 +383,23 @@ var t = new terra.Terrarium(4, 4, 'myTerrarium', 15, document.getElementById('bu
- Default: canvas is appended to
document.body
+
+ float trails
+ Allows for "trails", which visualize system history. A value of 1 shows all past state; trails fade faster as we approach 0.
+
+ - Range: [0, 1]
+ - Default: canvas is appended to
document.body
+ - Dependencies: "background" option is required if trails is set.
+
+
+
+ int [3] background
+ RGB components of the canvas' background.
+
+ - Range: [0, 255]
+ - Default: transparent
+
+
Once initialized, terrariums have a few exposed methods. Using our terrarium t
that we just created:
diff --git a/terra.demo.min.js b/terra.demo.min.js
index 5f7e660..c46f468 100755
--- a/terra.demo.min.js
+++ b/terra.demo.min.js
@@ -1,1212 +1,2 @@
-/** smooth-scroll v5.0.4, by Chris Ferdinandi | http://github.com/cferdinandi/smooth-scroll | Licensed under MIT: http://gomakethings.com/mit/ */
-Function.prototype.bind||(Function.prototype.bind=function(t){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var o=Array.prototype.slice.call(arguments,1),n=this;return fNOP=function(){},fBound=function(){return n.apply(this instanceof fNOP&&t?this:t,o.concat(Array.prototype.slice.call(arguments)))},fNOP.prototype=this.prototype,fBound.prototype=new fNOP,fBound});
-/** smooth-scroll v5.0.4, by Chris Ferdinandi | http://github.com/cferdinandi/smooth-scroll | Licensed under MIT: http://gomakethings.com/mit/ */
-!function(e,t){"function"==typeof define&&define.amd?define("smoothScroll",t(e)):"object"==typeof exports?module.exports=t(e):e.smoothScroll=t(e)}(this,function(e){"use strict";var t,n={},o=!!document.querySelector&&!!e.addEventListener,a={speed:500,easing:"easeInOutCubic",offset:0,updateURL:!0,callbackBefore:function(){},callbackAfter:function(){}},r=function(e,t,n){if("[object Object]"===Object.prototype.toString.call(e))for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.call(n,e[o],o,e);else for(var a=0,r=e.length;r>a;a++)t.call(n,e[a],a,e)},c=function(e,t){var n={};return r(e,function(t,o){n[o]=e[o]}),r(t,function(e,o){n[o]=t[o]}),n},u=function(e){for(var t,n=String(e),o=n.length,a=-1,r="",c=n.charCodeAt(0);++a=1&&31>=t||127==t||0===a&&t>=48&&57>=t||1===a&&t>=48&&57>=t&&45===c?"\\"+t.toString(16)+" ":t>=128||45===t||95===t||t>=48&&57>=t||t>=65&&90>=t||t>=97&&122>=t?n.charAt(a):"\\"+n.charAt(a)}return r},i=function(e,t){var n;return"easeInQuad"===e&&(n=t*t),"easeOutQuad"===e&&(n=t*(2-t)),"easeInOutQuad"===e&&(n=.5>t?2*t*t:-1+(4-2*t)*t),"easeInCubic"===e&&(n=t*t*t),"easeOutCubic"===e&&(n=--t*t*t+1),"easeInOutCubic"===e&&(n=.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1),"easeInQuart"===e&&(n=t*t*t*t),"easeOutQuart"===e&&(n=1- --t*t*t*t),"easeInOutQuart"===e&&(n=.5>t?8*t*t*t*t:1-8*--t*t*t*t),"easeInQuint"===e&&(n=t*t*t*t*t),"easeOutQuint"===e&&(n=1+--t*t*t*t*t),"easeInOutQuint"===e&&(n=.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t),n||t},l=function(e,t,n){var o=0;if(e.offsetParent)do o+=e.offsetTop,e=e.offsetParent;while(e);return o=o-t-n,o>=0?o:0},f=function(){return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},s=function(e){return e&&"object"==typeof JSON&&"function"==typeof JSON.parse?JSON.parse(e):{}},d=function(e,t){history.pushState&&(t||"true"===t)&&history.pushState({pos:e.id},"",window.location.pathname+e)};return n.animateScroll=function(t,n,o,r){var h=c(h||a,o||{}),p=s(t?t.getAttribute("data-options"):null);h=c(h,p),n="#"+u(n.substr(1));var m,b,g,v=document.querySelector("[data-scroll-header]"),O=null===v?0:v.offsetHeight+v.offsetTop,y=e.pageYOffset,S=l(document.querySelector(n),O,parseInt(h.offset,10)),I=S-y,Q=f(),A=0;t&&"a"===t.tagName.toLowerCase()&&r&&r.preventDefault(),d(n,h.updateURL);var C=function(o,a,r){var c=e.pageYOffset;(o==a||c==a||e.innerHeight+c>=Q)&&(clearInterval(r),h.callbackAfter(t,n))},H=function(){A+=16,b=A/parseInt(h.speed,10),b=b>1?1:b,g=y+I*i(h.easing,b),e.scrollTo(0,Math.floor(g)),C(g,S,m)},w=function(){h.callbackBefore(t,n),m=setInterval(H,16)};0===e.pageYOffset&&e.scrollTo(0,0),w()},n.init=function(e){if(o){t=c(a,e||{});var u=document.querySelectorAll("[data-scroll]");r(u,function(e){e.addEventListener("click",n.animateScroll.bind(null,e,e.hash,t),!1)})}},n});
-/* http://prismjs.com/download.html?themes=prism&languages=markup+clike+javascript+bash */
-self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof r)){c.lastIndex=0;var p=c.exec(d);if(p){u&&(f=p[1].length);var m=p.index-1+f,p=p[0].slice(f),v=p.length,y=m+v,k=d.slice(0,m+1),b=d.slice(y+1),w=[h,1];k&&w.push(k);var N=new r(o,g?t.tokenize(p,g):p);w.push(N),b&&w.push(b),Array.prototype.splice.apply(a,w)}}}}}return a},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var a,i=0;a=r[i++];)a(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,a){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var i={type:e.type,content:n.stringify(e.content,r,a),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:a};"comment"==i.type&&(i.attributes.spellcheck="true"),t.hooks.run("wrap",i);var o="";for(var l in i.attributes)o+=l+'="'+(i.attributes[l]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""+i.tag+">"},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,a=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(a,t.languages[r])))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);;
-Prism.languages.markup={comment://g,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/\?[\da-z]{1,8};/gi},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});;
-Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//g,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*?(\r?\n|$)/g,lookbehind:!0}],string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};;
-Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/
-
-// Sets Math.random to a PRNG initialized using the given explicit seed.
-Math.seedrandom('hello.');
-console.log(Math.random()); // Always 0.9282578795792454
-console.log(Math.random()); // Always 0.3752569768646784
-
-// Sets Math.random to an ARC4-based PRNG that is autoseeded using the
-// current time, dom state, and other accumulated local entropy.
-// The generated seed string is returned.
-Math.seedrandom();
-console.log(Math.random()); // Reasonably unpredictable.
-
-// Seeds using the given explicit seed mixed with accumulated entropy.
-Math.seedrandom('added entropy.', { entropy: true });
-console.log(Math.random()); // As unpredictable as added entropy.
-
-// Use "new" to create a local prng without altering Math.random.
-var myrng = new Math.seedrandom('hello.');
-console.log(myrng()); // Always 0.9282578795792454
-
-
-Node.js usage
--------------
-
-npm install seedrandom
-
-// Local PRNG: does not affect Math.random.
-var seedrandom = require('seedrandom');
-var rng = seedrandom('hello.');
-console.log(rng()); // Always 0.9282578795792454
-
-// Autoseeded ARC4-based PRNG.
-rng = seedrandom();
-console.log(rng()); // Reasonably unpredictable.
-
-// Global PRNG: set Math.random.
-seedrandom('hello.', { global: true });
-console.log(Math.random()); // Always 0.9282578795792454
-
-// Mixing accumulated entropy.
-rng = seedrandom('added entropy.', { entropy: true });
-console.log(rng()); // As unpredictable as added entropy.
-
-
-Require.js usage
-----------------
-
-Similar to node.js usage:
-
-bower install seedrandom
-
-require(['seedrandom'], function(seedrandom) {
- var rng = seedrandom('hello.');
- console.log(rng()); // Always 0.9282578795792454
-});
-
-
-Network seeding via a script tag
---------------------------------
-
-
-
-
-
-Examples of manipulating the seed for various purposes:
-
-var seed = Math.seedrandom(); // Use prng with an automatic seed.
-document.write(Math.random()); // Pretty much unpredictable x.
-
-var rng = new Math.seedrandom(seed); // A new prng with the same seed.
-document.write(rng()); // Repeat the 'unpredictable' x.
-
-function reseed(event, count) { // Define a custom entropy collector.
- var t = [];
- function w(e) {
- t.push([e.pageX, e.pageY, +new Date]);
- if (t.length < count) { return; }
- document.removeEventListener(event, w);
- Math.seedrandom(t, { entropy: true });
- }
- document.addEventListener(event, w);
-}
-reseed('mousemove', 100); // Reseed after 100 mouse moves.
-
-The "pass" option can be used to get both the prng and the seed.
-The following returns both an autoseeded prng and the seed as an object,
-without mutating Math.random:
-
-var obj = Math.seedrandom(null, { pass: function(prng, seed) {
- return { random: prng, seed: seed };
-}});
-
-
-Version notes
--------------
-
-The random number sequence is the same as version 1.0 for string seeds.
-* Version 2.0 changed the sequence for non-string seeds.
-* Version 2.1 speeds seeding and uses window.crypto to autoseed if present.
-* Version 2.2 alters non-crypto autoseeding to sweep up entropy from plugins.
-* Version 2.3 adds support for "new", module loading, and a null seed arg.
-* Version 2.3.1 adds a build environment, module packaging, and tests.
-* Version 2.3.4 fixes bugs on IE8, and switches to MIT license.
-* Version 2.3.6 adds a readable options object argument.
-
-The standard ARC4 key scheduler cycles short keys, which means that
-seedrandom('ab') is equivalent to seedrandom('abab') and 'ababab'.
-Therefore it is a good idea to add a terminator to avoid trivial
-equivalences on short string seeds, e.g., Math.seedrandom(str + '\0').
-Starting with version 2.0, a terminator is added automatically for
-non-string seeds, so seeding with the number 111 is the same as seeding
-with '111\0'.
-
-When seedrandom() is called with zero args or a null seed, it uses a
-seed drawn from the browser crypto object if present. If there is no
-crypto support, seedrandom() uses the current time, the native rng,
-and a walk of several DOM objects to collect a few bits of entropy.
-
-Each time the one- or two-argument forms of seedrandom are called,
-entropy from the passed seed is accumulated in a pool to help generate
-future seeds for the zero- and two-argument forms of seedrandom.
-
-On speed - This javascript implementation of Math.random() is several
-times slower than the built-in Math.random() because it is not native
-code, but that is typically fast enough. Some details (timings on
-Chrome 25 on a 2010 vintage macbook):
-
-* seeded Math.random() - avg less than 0.0002 milliseconds per call
-* seedrandom('explicit.') - avg less than 0.2 milliseconds per call
-* seedrandom('explicit.', true) - avg less than 0.2 milliseconds per call
-* seedrandom() with crypto - avg less than 0.2 milliseconds per call
-
-Autoseeding without crypto is somewhat slower, about 20-30 milliseconds on
-a 2012 windows 7 1.5ghz i5 laptop, as seen on Firefox 19, IE 10, and Opera.
-Seeded rng calls themselves are fast across these browsers, with slowest
-numbers on Opera at about 0.0005 ms per seeded Math.random().
-
-
-LICENSE (MIT)
--------------
-
-Copyright (c)2014 David Bau.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-*/
-
-/**
- * All code is in an anonymous closure to keep the global namespace clean.
- */
-(function (
- global, pool, math, width, chunks, digits, module, define, rngname) {
-
-//
-// The following constants are related to IEEE 754 limits.
-//
-var startdenom = math.pow(width, chunks),
- significance = math.pow(2, digits),
- overflow = significance * 2,
- mask = width - 1,
-
-//
-// seedrandom()
-// This is the seedrandom function described above.
-//
-impl = math['seed' + rngname] = function(seed, options, callback) {
- var key = [];
- options = (options == true) ? { entropy: true } : (options || {});
-
- // Flatten the seed string or build one from local entropy if needed.
- var shortseed = mixkey(flatten(
- options.entropy ? [seed, tostring(pool)] :
- (seed == null) ? autoseed() : seed, 3), key);
-
- // Use the seed to initialize an ARC4 generator.
- var arc4 = new ARC4(key);
-
- // Mix the randomness into accumulated entropy.
- mixkey(tostring(arc4.S), pool);
-
- // Calling convention: what to return as a function of prng, seed, is_math.
- return (options.pass || callback ||
- // If called as a method of Math (Math.seedrandom()), mutate Math.random
- // because that is how seedrandom.js has worked since v1.0. Otherwise,
- // it is a newer calling convention, so return the prng directly.
- function(prng, seed, is_math_call) {
- if (is_math_call) { math[rngname] = prng; return seed; }
- else return prng;
- })(
-
- // This function returns a random double in [0, 1) that contains
- // randomness in every bit of the mantissa of the IEEE 754 value.
- function() {
- var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48
- d = startdenom, // and denominator d = 2 ^ 48.
- x = 0; // and no 'extra last byte'.
- while (n < significance) { // Fill up all significant digits by
- n = (n + x) * width; // shifting numerator and
- d *= width; // denominator and generating a
- x = arc4.g(1); // new least-significant-byte.
- }
- while (n >= overflow) { // To avoid rounding up, before adding
- n /= 2; // last byte, shift everything
- d /= 2; // right using integer math until
- x >>>= 1; // we have exactly the desired bits.
- }
- return (n + x) / d; // Form the number within [0, 1).
- }, shortseed, 'global' in options ? options.global : (this == math));
-};
-
-//
-// ARC4
-//
-// An ARC4 implementation. The constructor takes a key in the form of
-// an array of at most (width) integers that should be 0 <= x < (width).
-//
-// The g(count) method returns a pseudorandom integer that concatenates
-// the next (count) outputs from ARC4. Its return value is a number x
-// that is in the range 0 <= x < (width ^ count).
-//
-/** @constructor */
-function ARC4(key) {
- var t, keylen = key.length,
- me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
-
- // The empty key [] is treated as [0].
- if (!keylen) { key = [keylen++]; }
-
- // Set up S using the standard key scheduling algorithm.
- while (i < width) {
- s[i] = i++;
- }
- for (i = 0; i < width; i++) {
- s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
- s[j] = t;
- }
-
- // The "g" method returns the next (count) outputs as one number.
- (me.g = function(count) {
- // Using instance members instead of closure state nearly doubles speed.
- var t, r = 0,
- i = me.i, j = me.j, s = me.S;
- while (count--) {
- t = s[i = mask & (i + 1)];
- r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
- }
- me.i = i; me.j = j;
- return r;
- // For robust unpredictability discard an initial batch of values.
- // See http://www.rsa.com/rsalabs/node.asp?id=2009
- })(width);
-}
-
-//
-// flatten()
-// Converts an object tree to nested arrays of strings.
-//
-function flatten(obj, depth) {
- var result = [], typ = (typeof obj), prop;
- if (depth && typ == 'object') {
- for (prop in obj) {
- try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
- }
- }
- return (result.length ? result : typ == 'string' ? obj : obj + '\0');
-}
-
-//
-// mixkey()
-// 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) {
- var stringseed = seed + '', smear, j = 0;
- while (j < stringseed.length) {
- key[mask & j] =
- mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
- }
- return tostring(key);
-}
-
-//
-// autoseed()
-// Returns an object for autoseeding, using window.crypto if available.
-//
-/** @param {Uint8Array|Navigator=} seed */
-function autoseed(seed) {
- try {
- global.crypto.getRandomValues(seed = new Uint8Array(width));
- return tostring(seed);
- } catch (e) {
- return [+new Date, global, (seed = global.navigator) && seed.plugins,
- global.screen, tostring(pool)];
- }
-}
-
-//
-// tostring()
-// Converts an array of charcodes to a string
-//
-function tostring(a) {
- return String.fromCharCode.apply(0, a);
-}
-
-//
-// When seedrandom.js is loaded, we immediately mix a few bits
-// from the built-in RNG into the entropy pool. Because we do
-// not want to intefere with determinstic PRNG state later,
-// seedrandom will not call math.random on its own again after
-// initialization.
-//
-mixkey(math[rngname](), pool);
-
-//
-// Nodejs and AMD support: export the implemenation as a module using
-// either convention.
-//
-if (module && module.exports) {
- module.exports = impl;
-} else if (define && define.amd) {
- define(function() { return impl; });
-}
-
-// End anonymous scope, and pass initial values.
-})(
- this, // global window object
- [], // pool: entropy pool starts empty
- Math, // math: package containing random, pow, and seedrandom
- 256, // width: each RC4 output is 0 <= x < 256
- 6, // chunks: at least six RC4 outputs for each double
- 52, // digits: there are 52 significant digits in a double
- (typeof module) == 'object' && module, // present in node.js
- (typeof define) == 'function' && define, // present with an AMD loader
- 'random'// rngname: name for Math.random and Math.seedrandom
-);
-
-},{}],8:[function(require,module,exports){
-var factory = require('../../app/creature.js');
-var _ = require('../../app/util.js');
-
-factory.registerCreature({
- type: 'plant',
- color: [0, 120, 0],
- size: 10,
- initialEnergy: 5,
- maxEnergy: 20,
- wait: function() {
- this.energy += 1;
- },
- move: false,
- reproduceLv: 0.65
-});
-
-factory.registerCreature({
- type: 'brute',
- color: [0, 255, 255],
- maxEnergy: 50,
- initialEnergy: 10,
- size: 20
-});
-
-factory.registerCreature({
- type: 'bully',
- color: [241, 196, 15],
- initialEnergy: 20,
- reproduceLv: 0.6,
- sustainability: 3
-});
-
-factory.registerCA({
- type: 'GoL',
- colorFn: function () { return this.alive ? this.color + ',1' : '0,0,0,0'; },
- process: function (neighbors) {
- var surrounding = _.filter(neighbors, function (spot) {
- return spot.creature.alive;
- }).length;
- this.alive = surrounding === 3 || surrounding === 2 && this.alive;
- return true;
- }
-}, function () {
- this.alive = Math.random() < 0.5;
-});
-
-factory.registerCA({
- type: 'cyclic',
- colors: ['255,0,0,1', '255,96,0,1', '255,191,0,1', '223,255,0,1', '128,255,0,1', '32,255,0,1', '0,255,64,1', '0,255,159,1', '0,255,255,1', '0,159,255,1', '0,64,255,1', '32,0,255,1', '127,0,255,1', '223,0,255,1', '255,0,191,1', '255,0,96,1'],
- colorFn: function () { return this.colors[this.state];},
- process: function (neighbors) {
- var next = (this.state + 1) % 16;
- var changing = _.some(neighbors, function (spot) {
- return spot.creature.state === next;
- });
- if (changing) this.state = next;
- return true;
- }
-}, function () {
- this.state = Math.floor(Math.random() * 16);
-});
-
-factory.registerCreature({
- type: 'secondCreature',
- color: [154, 109, 235],
- initialEnergy: 100,
- sustainability: 6,
- reproduceLv: 1,
- moveLv: 0
-});
-
-factory.registerCreature({
- type: 'simplePlant',
- color: [166, 226, 46],
- colorFn: function () {
- return this.color + ',1';
- },
- size: 10,
- initialEnergy: 5,
- maxEnergy: 20,
- wait: function() {
- this.energy += 1;
- },
- move: false,
- reproduceLv: 0.65
-});
-
-factory.registerCA({
- type: 'elementary',
- alive: false,
- ruleset: [1, 0, 0, 1, 0, 0, 1, 0].reverse(), // rule 146
- colorFn: function () { return this.alive ? this.color + ',1' : '0,0,0,0'; },
- process: function (neighbors, x, y) {
- if (this.age === y) {
- var index = _.map(_.filter(neighbors, function (neighbor) {
- return neighbor.coords.y === y - 1;
- }), function (neighbor) {
- return neighbor.creature.alive ? 1 : 0;
- });
- index = parseInt(index.join(''), 2);
- this.alive = isNaN(index) ? !x : this.ruleset[index];
- }
- return true;
- }
-});
-
-},{"../../app/creature.js":2,"../../app/util.js":6}],9:[function(require,module,exports){
-(function (global){
-/**
- * @license
- * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE
- * Build: `lodash exports="commonjs" include="assign,clone,filter,each,map,random,reduce,some"`
- */
-;(function(){function n(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}function t(n){n.length=0,S.lengthe?0:e);++rk;k++)r+="n='"+e.h[k]+"';if((!(r&&x[n])&&m.call(t,n))",e.j||(r+="||(!x[n]&&t[n]!==A[n])"),r+="){"+e.g+"}";r+="}"}return(e.b||bt.nonEnumArgs)&&(r+="}"),r+=e.c+";return E",n("d,j,k,m,o,p,q,s,v,A,B,y,I,J,L",t+r+"}")(c,$,Y,ut,A,g,mt,v,q.f,Z,H,vt,M,nt,tt)
-}function s(n){return typeof n=="function"&&et.test(n)}function g(n){return n&&typeof n=="object"&&typeof n.length=="number"&&tt.call(n)==B||false}function y(n){return typeof n=="function"}function h(n){return!(!n||!H[typeof n])}function v(n){return typeof n=="string"||n&&typeof n=="object"&&tt.call(n)==M||false}function b(n,t,e){var o=[];if(t=r.createCallback(t,e,3),mt(n)){e=-1;for(var u=n.length;++earguments.length;if(t=r.createCallback(t,o,4),mt(n)){var a=-1,c=n.length;for(u&&(e=n[++a]);++a3&&typeof a[c-2]=='function'){var e=d(a[--c-1],a[c--],2)}else if(c>2&&typeof a[c-1]=='function'){e=a[--c]}"),g:"E[n]=e?e(E[n],t[n]):t[n]"}),Ot=p(U,wt,{j:false}),St=p(U,wt);
-y(/x/)&&(y=function(n){return typeof n=="function"&&"[object Function]"==tt.call(n)}),r.assign=xt,r.bind=w,r.createCallback=function(n,t,e){var r=typeof n;if(null==n||"function"==r)return c(n,t,e);if("object"!=r)return O(n);var o=Et(n),u=o[0],a=n[u];return 1!=o.length||a!==a||h(a)?function(t){for(var e=o.length,r=false;e--&&(r=l(t[o[e]],n[o[e]],null,true)););return r}:function(n){return n=n[u],a===n&&(0!==a||1/a==1/n)}},r.filter=b,r.forEach=d,r.forIn=Ot,r.forOwn=St,r.keys=Et,r.map=m,r.property=O,r.collect=m,r.each=d,r.extend=xt,r.select=b,r.clone=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=t,t=false),u(n,t,typeof e=="function"&&c(e,r,1))
-},r.identity=_,r.isArguments=g,r.isArray=mt,r.isFunction=y,r.isObject=h,r.isString=v,r.noop=x,r.random=function(n,t,e){var r=null==n,o=null==t;return null==e&&(typeof n=="boolean"&&o?(e=n,n=1):o||typeof t!="boolean"||(e=t,o=true)),r&&o&&(t=1),n=+n||0,o?(t=n,n=0):t=+t||0,e||n%1||t%1?(e=yt(),gt(n+e*(t-n+parseFloat("1e-"+((e+"").length-1))),t)):n+rt(yt()*(t-n+1))},r.reduce=j,r.some=E,r.any=E,r.foldl=j,r.inject=j,r.VERSION="2.4.1",W&&Q&&(W._=r)}).call(this);
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}]},{},[1]);
+Function.prototype.bind||(Function.prototype.bind=function(e){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var t=Array.prototype.slice.call(arguments,1),n=this;return fNOP=function(){},fBound=function(){return n.apply(this instanceof fNOP&&e?this:e,t.concat(Array.prototype.slice.call(arguments)))},fNOP.prototype=this.prototype,fBound.prototype=new fNOP,fBound}),!function(e,t){"function"==typeof define&&define.amd?define("smoothScroll",t(e)):"object"==typeof exports?module.exports=t(e):e.smoothScroll=t(e)}(this,function(e){"use strict";var t,n={},r=!!document.querySelector&&!!e.addEventListener,i={speed:500,easing:"easeInOutCubic",offset:0,updateURL:!0,callbackBefore:function(){},callbackAfter:function(){}},o=function(e,t,n){if("[object Object]"===Object.prototype.toString.call(e))for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.call(n,e[r],r,e);else for(var i=0,o=e.length;o>i;i++)t.call(n,e[i],i,e)},a=function(e,t){var n={};return o(e,function(t,r){n[r]=e[r]}),o(t,function(e,r){n[r]=t[r]}),n},u=function(e){for(var t,n=String(e),r=n.length,i=-1,o="",a=n.charCodeAt(0);++i=1&&31>=t||127==t||0===i&&t>=48&&57>=t||1===i&&t>=48&&57>=t&&45===a?"\\"+t.toString(16)+" ":t>=128||45===t||95===t||t>=48&&57>=t||t>=65&&90>=t||t>=97&&122>=t?n.charAt(i):"\\"+n.charAt(i)}return o},c=function(e,t){var n;return"easeInQuad"===e&&(n=t*t),"easeOutQuad"===e&&(n=t*(2-t)),"easeInOutQuad"===e&&(n=.5>t?2*t*t:-1+(4-2*t)*t),"easeInCubic"===e&&(n=t*t*t),"easeOutCubic"===e&&(n=--t*t*t+1),"easeInOutCubic"===e&&(n=.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1),"easeInQuart"===e&&(n=t*t*t*t),"easeOutQuart"===e&&(n=1- --t*t*t*t),"easeInOutQuart"===e&&(n=.5>t?8*t*t*t*t:1-8*--t*t*t*t),"easeInQuint"===e&&(n=t*t*t*t*t),"easeOutQuint"===e&&(n=1+--t*t*t*t*t),"easeInOutQuint"===e&&(n=.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t),n||t},s=function(e,t,n){var r=0;if(e.offsetParent)do r+=e.offsetTop,e=e.offsetParent;while(e);return r=r-t-n,r>=0?r:0},l=function(){return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},f=function(e){return e&&"object"==typeof JSON&&"function"==typeof JSON.parse?JSON.parse(e):{}},p=function(e,t){history.pushState&&(t||"true"===t)&&history.pushState({pos:e.id},"",window.location.pathname+e)};return n.animateScroll=function(t,n,r,o){var g=a(g||i,r||{}),d=f(t?t.getAttribute("data-options"):null);g=a(g,d),n="#"+u(n.substr(1));var h,y,m,v=document.querySelector("[data-scroll-header]"),b=null===v?0:v.offsetHeight+v.offsetTop,w=e.pageYOffset,k=s(document.querySelector(n),b,parseInt(g.offset,10)),x=k-w,E=l(),j=0;t&&"a"===t.tagName.toLowerCase()&&o&&o.preventDefault(),p(n,g.updateURL);var C=function(r,i,o){var a=e.pageYOffset;(r==i||a==i||e.innerHeight+a>=E)&&(clearInterval(o),g.callbackAfter(t,n))},S=function(){j+=16,y=j/parseInt(g.speed,10),y=y>1?1:y,m=w+x*c(g.easing,y),e.scrollTo(0,Math.floor(m)),C(m,k,h)},O=function(){g.callbackBefore(t,n),h=setInterval(S,16)};0===e.pageYOffset&&e.scrollTo(0,0),O()},n.init=function(e){if(r){t=a(i,e||{});var u=document.querySelectorAll("[data-scroll]");o(u,function(e){e.addEventListener("click",n.animateScroll.bind(null,e,e.hash,t),!1)})}},n}),self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof r)){s.lastIndex=0;var h=s.exec(d);if(h){f&&(p=h[1].length);var y=h.index-1+p,h=h[0].slice(p),m=h.length,v=y+m,b=d.slice(0,y+1),w=d.slice(v+1),k=[g,1];b&&k.push(b);var x=new r(a,l?t.tokenize(h,l):h);k.push(x),w&&k.push(w),Array.prototype.splice.apply(i,k)}}}}}return i},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(r&&r.length)for(var i,o=0;i=r[o++];)i(n)}}},n=t.Token=function(e,t){this.type=e,this.content=t};if(n.stringify=function(e,r,i){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,r,e)}).join("");var o={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};"comment"==o.type&&(o.attributes.spellcheck="true"),t.hooks.run("wrap",o);var a="";for(var u in o.attributes)a+=u+'="'+(o.attributes[u]||"")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'" '+a+">"+o.content+""+o.tag+">"},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(i,t.languages[r])))),self.close()},!1),self.Prism):self.Prism;var r=document.getElementsByTagName("script");return r=r[r.length-1],r&&(t.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),Prism.languages.markup={comment://g,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/\?[\da-z]{1,8};/gi},Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//g,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*?(\r?\n|$)/g,lookbehind:!0}],string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g},Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/