newton
Version:
A playful, particle-based physics engine designed from the ground up for JavaScript.
2 lines • 89.6 kB
JavaScript
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Newton=e()}}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module,exports){module.exports={Simulator:_dereq_("./lib/simulator"),GLRenderer:_dereq_("./lib/renderers/gl-renderer"),Particle:_dereq_("./lib/particle"),Vector:_dereq_("./lib/vector"),Body:_dereq_("./lib/body"),Constraint:_dereq_("./lib/constraint"),PinConstraint:_dereq_("./lib/constraints/pin-constraint"),DistanceConstraint:_dereq_("./lib/constraints/distance-constraint"),RopeConstraint:_dereq_("./lib/constraints/rope-constraint"),BoxConstraint:_dereq_("./lib/constraints/box-constraint"),Force:_dereq_("./lib/force"),LinearForce:_dereq_("./lib/forces/linear-force")}},{"./lib/body":3,"./lib/constraint":4,"./lib/constraints/box-constraint":5,"./lib/constraints/distance-constraint":6,"./lib/constraints/pin-constraint":7,"./lib/constraints/rope-constraint":8,"./lib/force":9,"./lib/forces/linear-force":10,"./lib/particle":12,"./lib/renderers/gl-renderer":15,"./lib/simulator":17,"./lib/vector":18}],2:[function(_dereq_,module,exports){function Accumulator(interval,max){this._interval=interval;this._max=max;this._total=0;this._lastTime=0;this._startTime=Date.now()}Accumulator.prototype.freeze=function(){this._time=Date.now();this._buffer=this._time-this._lastTime;this._lastTime=this._time;return this._interval};Accumulator.prototype.next=function(){if(this._buffer>this._max){this._buffer=0;return false}if(this._buffer<this._interval)return false;this._total+=this._interval;this._buffer-=this._interval;return this._total};module.exports=Accumulator},{}],3:[function(_dereq_,module,exports){function Body(){if(!(this instanceof Body))return new Body;this._entities=[];this._sim=undefined}Body.prototype.type="Body";Body.prototype.add=function(entity){this._entities.push(entity);if(this._sim)this._sim.add(entity);return entity};Body.prototype.setSimulator=function(sim){this._sim=sim;for(var i=0;i<this._entities.length;i++){sim.add(this._entities[i])}};module.exports=Body},{}],4:[function(_dereq_,module,exports){var id=0;function Constraint(){if(!(this instanceof Constraint))return new Constraint;this.id=id++}Constraint.prototype.type="Constraint";Constraint.prototype.priority=Infinity;Constraint.prototype.correct=function(){};Constraint.prototype.evaluate=function(){};Constraint.prototype._deleted=false;Constraint.prototype.setPriority=function(types){for(var i=0;i<types.length;i++){if(this instanceof types[i]){this.priority=i;return}}this.priority=Infinity;return};module.exports=Constraint},{}],5:[function(_dereq_,module,exports){var Constraint=_dereq_("../constraint");var Vector=_dereq_("../vector");function BoxConstraint(x,y,width,height){if(!(this instanceof BoxConstraint))return new BoxConstraint(x,y,width,height);Constraint.call(this);this._min=Vector(x,y);this._max=Vector(x+width,y+height)}BoxConstraint.prototype=Object.create(Constraint.prototype);BoxConstraint.prototype.correct=function(time,particles){for(var i=0;i<particles.length;i++){particles[i].bound(this._min,this._max)}};module.exports=BoxConstraint},{"../constraint":4,"../vector":18}],6:[function(_dereq_,module,exports){var Vector=_dereq_("../vector");var Constraint=_dereq_("../constraint");function DistanceConstraint(p1,p2){if(!(this instanceof DistanceConstraint))return new DistanceConstraint(p1,p2);Constraint.call(this);this._p1=p1;this._p2=p2;this._distance=this.getDistance();this._stiffness=1}DistanceConstraint.prototype=Object.create(Constraint.prototype);DistanceConstraint.prototype.getDistance=function(){return Vector.getDistance(this._p1.position,this._p2.position)};DistanceConstraint.prototype.correct=function(time,particles){var pos1=this._p1.position;var pos2=this._p2.position;var delta=pos2.pool().sub(pos1);var length=delta.getLength();var offBy=length-this._distance;var factor=offBy/length*this._stiffness;var correction1=delta.pool().scale(factor*1);var correction2=delta.scale(-factor*1);this._p1.move(correction1);this._p2.move(correction2);delta.free();correction1.free()};module.exports=DistanceConstraint},{"../constraint":4,"../vector":18}],7:[function(_dereq_,module,exports){var Constraint=_dereq_("../constraint");function PinConstraint(particle,position){if(!(this instanceof PinConstraint))return new PinConstraint(particle,position);Constraint.call(this);this._particle=particle;this._position=position||particle.position.clone()}PinConstraint.prototype=Object.create(Constraint.prototype);PinConstraint.prototype.correct=function(time,particles){this._particle.place(this._position)};PinConstraint.prototype.setPosition=function(position){this._position=position};module.exports=PinConstraint},{"../constraint":4}],8:[function(_dereq_,module,exports){var Vector=_dereq_("../vector");var Constraint=_dereq_("../constraint");function RopeConstraint(p1,p2,options){if(!(this instanceof RopeConstraint))return new RopeConstraint(p1,p2,options);Constraint.call(this);options=options||{};this._p1=p1;this._p2=p2;this._distance=typeof options.length==="undefined"?this.getDistance():options.length;this._stiffness=options.stiffness||1;this._expansion=.001;this._strength=options.strength||Infinity;this._deleted=false}RopeConstraint.prototype=Object.create(Constraint.prototype);RopeConstraint.prototype.getDistance=function(){return Vector.getDistance(this._p1.position,this._p2.position)};RopeConstraint.prototype.correct=function(time,particles,i,iterations){var pos1=this._p1.position;var pos2=this._p2.position;var delta=pos2.pool().sub(pos1);var length=delta.getLength();var offBy=length-this._distance;var compression=offBy<=0?this._expansion:1;var factor=offBy/length*this._stiffness*compression;var correction1=delta.pool().scale(factor*1);var correction2=delta.scale(-factor*1);this._p1.move(correction1);this._p2.move(correction2);delta.free();correction1.free()};RopeConstraint.prototype.evaluate=function(time,particles){var pos1=this._p1.position;var pos2=this._p2.position;var delta=pos2.pool().sub(pos1);var length=delta.getLength();var offBy=length-this._distance;var stress=offBy/this._distance;if(stress>this._strength)this._deleted=true};module.exports=RopeConstraint},{"../constraint":4,"../vector":18}],9:[function(_dereq_,module,exports){function Force(){}Force.prototype.type="Force";Force.prototype.apply=function(){};module.exports=Force},{}],10:[function(_dereq_,module,exports){var Force=_dereq_("../force");var Vector=_dereq_("../vector");function LinearForce(strength,angle){if(!(this instanceof LinearForce))return new LinearForce(strength,angle);Force.call(this);this._vector=Vector(strength,0).rotate(angle)}LinearForce.prototype=Object.create(Force.prototype);LinearForce.prototype.applyTo=function(particle){particle.accelerate(this._vector)};module.exports=LinearForce},{"../force":9,"../vector":18}],11:[function(_dereq_,module,exports){module.exports=getFrame();function getFrame(){var lastTime=0;if(typeof window!=="undefined"){var vendors=["ms","moz","webkit","o"];var isOpera=!!window.opera||navigator.userAgent.indexOf(" OPR/")>=0;var isFirefox=typeof InstallTrigger!=="undefined";var isSafari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0;var isChrome=!!window.chrome&&!isOpera;for(var x=0;x<vendors.length&&!window.requestAnimationFrame;++x){window.requestAnimationFrame=window[vendors[x]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[vendors[x]+"CancelAnimationFrame"]||window[vendors[x]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=timeoutFrame;window.cancelAnimationFrame=cancelTimeoutFrame}return{onFrame:window.requestAnimationFrame.bind(window),cancelFrame:window.cancelAnimationFrame.bind(window)}}return{onFrame:timeoutFrame,cancelFrame:cancelTimeoutFrame};function timeoutFrame(simulator,element){var currTime=(new Date).getTime();var timeToCall=Math.max(0,16-(currTime-lastTime));var id=setTimeout(function(){simulator(currTime+timeToCall)},timeToCall);lastTime=currTime+timeToCall;return id}function cancelTimeoutFrame(id){clearTimeout(id)}}},{}],12:[function(_dereq_,module,exports){var Vector=_dereq_("./vector");function Particle(x,y,size){if(!(this instanceof Particle))return new Particle(x,y,size);this.size=size||1;this.position=Vector(x,y);this.lastPosition=Vector(x,y);this.acceleration=Vector(0,0);this._velocityBuffer=Vector(0,0)}Particle.prototype.type="Particle";Particle.prototype.accelerate=function(v){this.acceleration.add(v)};Particle.prototype.bound=function(min,max){if(this.position.x<min.x){this.position.x=this.lastPosition.x=min.x}else if(this.position.x>max.x){this.position.x=this.lastPosition.x=max.x}if(this.position.y<min.y){this.position.y=this.lastPosition.y=min.y}else if(this.position.y>max.y){this.position.y=this.lastPosition.y=max.y}};Particle.prototype.getPoint=function(){return{x:this.position.x,y:this.position.y}};Particle.prototype.getVelocity=function(){return this.position.clone().sub(this.lastPosition)};Particle.prototype.integrate=function(time){this._velocityBuffer.copy(this.position).sub(this.lastPosition);this.acceleration.scale(time*time*.001);this.lastPosition.copy(this.position);this.position.add(this._velocityBuffer).add(this.acceleration);this.acceleration.zero()};Particle.prototype.move=function(v){this.position.add(v)};Particle.prototype.place=function(v){this.position.copy(v);this.lastPosition.copy(this.position);return this};Particle.prototype.setVelocity=function(v){this.lastPosition.copy(this.position).sub(v)};module.exports=Particle},{"./vector":18}],13:[function(_dereq_,module,exports){function Renderer(){}Renderer.prototype.render=function(sim){this._sim=sim};module.exports=Renderer},{}],14:[function(_dereq_,module,exports){var POINT_VS=["uniform vec2 viewport;","attribute vec3 position;","attribute float size;","void main() {","vec2 scaled = ((position.xy / viewport) * 2.0) - 1.0;","vec2 flipped = vec2(scaled.x, -scaled.y);","gl_Position = vec4(flipped, 0, 1);","gl_PointSize = size + 1.0;","}"].join("\n");var CIRCLE_FS=["precision mediump float;","uniform sampler2D texture;","void main() {","gl_FragColor = texture2D(texture, gl_PointCoord);","}"].join("\n");module.exports={getGLContext:getGLContext,createCircleTexture:createCircleTexture,createCircleShader:createCircleShader,createShaderProgram:createShaderProgram,createTexture:createTexture};function getGLContext(canvas){var names=["webgl","experimental-webgl","webkit-3d","moz-webgl"];var i=0,gl;while(!gl&&i++<names.length){try{gl=canvas.getContext(names[i])}catch(e){}}return gl}function createCircleTexture(gl,size){size=size||32;var canvas=document.createElement("canvas");canvas.width=canvas.height=size;var ctx=canvas.getContext("2d");var rad=size*.5;ctx.beginPath();ctx.arc(rad,rad,rad,0,Math.PI*2,false);ctx.closePath();ctx.fillStyle="#fff";ctx.fill();return createTexture(gl,canvas)}function createTexture(gl,data){var texture=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,texture);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,data);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.generateMipmap(gl.TEXTURE_2D);gl.bindTexture(gl.TEXTURE_2D,null);return texture}function createShaderProgram(gl,vsText,fsText){var vs=gl.createShader(gl.VERTEX_SHADER);var fs=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(vs,vsText);gl.shaderSource(fs,fsText);gl.compileShader(vs);gl.compileShader(fs);if(!gl.getShaderParameter(vs,gl.COMPILE_STATUS)){console.error("error compiling VS shaders:",gl.getShaderInfoLog(vs));throw new Error("shader failure")}if(!gl.getShaderParameter(fs,gl.COMPILE_STATUS)){console.error("error compiling FS shaders:",gl.getShaderInfoLog(fs));throw new Error("shader failure")}var program=gl.createProgram();gl.attachShader(program,vs);gl.attachShader(program,fs);gl.linkProgram(program);return program}function createCircleShader(gl,viewportArray,viewportAttr,positionAttr,sizeAttr){viewportAttr=viewportAttr||"viewport";positionAttr=positionAttr||"position";sizeAttr=sizeAttr||"size";var shader=createShaderProgram(gl,POINT_VS,CIRCLE_FS);shader.uniforms={viewport:gl.getUniformLocation(shader,viewportAttr)};shader.attributes={position:gl.getAttribLocation(shader,positionAttr),size:gl.getAttribLocation(shader,sizeAttr)};gl.useProgram(shader);gl.uniform2fv(shader.uniforms.viewport,viewportArray);return shader}},{}],15:[function(_dereq_,module,exports){var Renderer=_dereq_("../../renderer");var GLUtil=_dereq_("./gl-util");var onFrame=_dereq_("../../frame").onFrame;var Vector=_dereq_("../../vector");var PointRenderer=_dereq_("./point-renderer");var Emitter=_dereq_("eventemitter2").EventEmitter2;var extend=_dereq_("lodash").extend;var MAX_PARTICLES=1e4;function GLRenderer(el){if(!(this instanceof GLRenderer))return new GLRenderer(el);Emitter.call(this);this._el=el;this._drawFrame=this._drawFrame.bind(this);this._gl=GLUtil.getGLContext(el);this._gl.clearColor(0,0,0,0);this._viewportArray=new Float32Array([el.width,el.height]);this._pointRenderer=new PointRenderer(this._gl,this._viewportArray);this._listen()}GLRenderer.prototype=Object.create(Renderer.prototype);extend(GLRenderer.prototype,Emitter.prototype);GLRenderer.prototype.render=function(sim){this._sim=sim;onFrame(this._drawFrame)};GLRenderer.prototype._drawFrame=function(){this._clear();this._pointRenderer.draw(this._sim.getParticles());onFrame(this._drawFrame)};GLRenderer.prototype._clear=function(){var gl=this._gl;gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)};GLRenderer.prototype._listen=function(){var self=this;var canvas=this._el;var down=false;canvas.addEventListener("mousedown",onDown);canvas.addEventListener("mousemove",onMove);document.addEventListener("mouseup",onUp);function onDown(e){down=true;self.emit("pointerdown",getVector(e,canvas))}function onMove(e){var vector=getVector(e,canvas);self.emit("pointermove",vector);if(down)self.emit("pointerdrag",vector)}function onUp(e){if(!down)return;self.emit("pointerup",getVector(e,canvas))}};module.exports=GLRenderer;function getVector(event,canvas){var x=event.clientX-document.documentElement.scrollLeft-canvas.offsetLeft;var y=event.clientY-document.documentElement.scrollTop-canvas.offsetTop;return Vector(x,y)}},{"../../frame":11,"../../renderer":13,"../../vector":18,"./gl-util":14,"./point-renderer":16,eventemitter2:20,lodash:21}],16:[function(_dereq_,module,exports){var GLUtil=_dereq_("./gl-util");var MAX_POINTS=1e4;var VERTEX_SHADER=["uniform vec2 viewport;","attribute vec3 position;","attribute float size;","void main() {","vec2 scaled = ((position.xy / viewport) * 2.0) - 1.0;","vec2 flipped = vec2(scaled.x, -scaled.y);","gl_Position = vec4(flipped, 0, 1);","gl_PointSize = size + 1.0;","}"].join("\n");var FRAGMENT_SHADER=["precision mediump float;","uniform sampler2D texture;","void main() {","gl_FragColor = texture2D(texture, gl_PointCoord);","}"].join("\n");function PointRenderer(gl,viewportArray){this._gl=gl;this._viewportArray=viewportArray;this._verticesCache=[];this._sizesCache=[];this._vArray=new Float32Array(MAX_POINTS*2);this._sArray=new Float32Array(MAX_POINTS);this._texture=createCircleTexture(gl);this._shader=createCircleShader(gl,viewportArray);this._positionBuffer=gl.createBuffer();this._sizeBuffer=gl.createBuffer()}PointRenderer.prototype.draw=function(points){var gl=this._gl;var vertices=this._verticesCache;var sizes=this._sizesCache;var vArray=this._vArray;var sArray=this._sArray;var attributes=this._shader.attributes;var point;vertices.length=0;sizes.length=0;for(var i=0;i<points.length;i++){point=points[i];vertices.push(point.position.x,point.position.y);sizes.push(4)}vArray.set(vertices,0);sArray.set(sizes,0);gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,this._texture);gl.bindBuffer(gl.ARRAY_BUFFER,this._positionBuffer);gl.bufferData(gl.ARRAY_BUFFER,vArray,gl.STATIC_DRAW);gl.vertexAttribPointer(attributes.position,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(attributes.position);gl.bindBuffer(gl.ARRAY_BUFFER,this._sizeBuffer);gl.bufferData(gl.ARRAY_BUFFER,sArray,gl.STATIC_DRAW);gl.vertexAttribPointer(attributes.size,1,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(attributes.size);gl.drawArrays(gl.POINTS,0,vertices.length/2)};module.exports=PointRenderer;function createCircleTexture(gl,size){size=size||128;var canvas=document.createElement("canvas");canvas.width=canvas.height=size;var ctx=canvas.getContext("2d");var rad=size*.5;ctx.beginPath();ctx.arc(rad,rad,rad,0,Math.PI*2,false);ctx.closePath();ctx.fillStyle="#fff";ctx.fill();return GLUtil.createTexture(gl,canvas)}function createCircleShader(gl,viewportArray){var vs=gl.createShader(gl.VERTEX_SHADER);var fs=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(vs,VERTEX_SHADER);gl.shaderSource(fs,FRAGMENT_SHADER);gl.compileShader(vs);gl.compileShader(fs);if(!gl.getShaderParameter(vs,gl.COMPILE_STATUS)){console.error("error compiling VS shaders:",gl.getShaderInfoLog(vs));throw new Error("shader failure")}if(!gl.getShaderParameter(fs,gl.COMPILE_STATUS)){console.error("error compiling FS shaders:",gl.getShaderInfoLog(fs));throw new Error("shader failure")}var program=gl.createProgram();gl.attachShader(program,vs);gl.attachShader(program,fs);gl.linkProgram(program);program.uniforms={viewport:gl.getUniformLocation(program,"viewport")};program.attributes={position:gl.getAttribLocation(program,"position"),size:gl.getAttribLocation(program,"size")};gl.useProgram(program);gl.uniform2fv(program.uniforms.viewport,viewportArray);return program}},{"./gl-util":14}],17:[function(_dereq_,module,exports){var Emitter=_dereq_("eventemitter2").EventEmitter2;var onFrame=_dereq_("./frame").onFrame;var Accumulator=_dereq_("./accumulator");function Simulator(options){if(!(this instanceof Simulator))return new Simulator(options);Emitter.call(this);options=options||{};this._step=this._step.bind(this);this._stepInterval=1e3/60;this._running=false;this._accumulator=undefined;this._particles=[];this._bodies=[];this._forces=[];this._constraints=[];this._priorities=options.solve||[];this._iterations=10}Simulator.prototype=Object.create(Emitter.prototype);Simulator.prototype.start=function(){this._running=true;this._accumulator=new Accumulator(this._stepInterval,100);onFrame(this._step)};Simulator.prototype.add=function(entity){if(entity.type==="Particle")this._particles.push(entity);else if(entity.type==="Force")this._forces.push(entity);else if(entity.type==="Constraint"){entity.setPriority(this._priorities);this._constraints.push(entity);this._constraints.sort(prioritySort)}else if(entity.type==="Body"){this._bodies.push(entity);entity.setSimulator(this)}return entity};Simulator.prototype.findNearest=function(point,radius){var nearestDistance=radius*radius;var nearest,distance;for(var i=0;i<this._particles.length;i++){distance=this._particles[i].position.getDistance2(point);if(distance<nearestDistance){nearest=this._particles[i];nearestDistance=distance}}return nearest};Simulator.prototype.getParticles=function(){return this._particles};Simulator.prototype.remove=function(entity){if(entity.type==="Constraint"){var index=this._constraints.indexOf(entity);if(index===-1)throw new Error("entity not found");this._constraints.splice(index,1)}};Simulator.prototype._step=function(){if(!this._running)return;var time;var interval=this._accumulator.freeze();while(time=this._accumulator.next()){this._simulate(interval,time)}onFrame(this._step)};Simulator.prototype._simulate=function(time,totalTime){this._cull();this._integrate(time);this._constrain(time)};Simulator.prototype._cull=function(){var i=0;while(i<this._constraints.length){if(this._constraints[i]._deleted){this._constraints.splice(i,1)}else i++}};Simulator.prototype._integrate=function(time){var particles=this._particles;var forces=this._forces;var particle,force;for(var p=0;p<particles.length;p++){particle=particles[p];for(var f=0;f<forces.length;f++){force=forces[f];force.applyTo(particle)}particle.integrate(time)}};Simulator.prototype._constrain=function(time){var constraints=this._constraints;var particles=this._particles;for(var i=0;i<this._iterations;i++){for(var c=0;c<constraints.length;c++){constraints[c].correct(time,particles,i,this._iterations)}}for(var c=0;c<constraints.length;c++){constraints[c].evaluate(time,particles)}};module.exports=Simulator;function prioritySort(a,b){return b.priority-a.priority||b.id-a.id}},{"./accumulator":2,"./frame":11,eventemitter2:20}],18:[function(_dereq_,module,exports){var pool=[];function Vector(x,y){if(!(this instanceof Vector))return new Vector(x,y);this.x=x||0;this.y=y||0}Vector.claim=function(){return pool.pop()||Vector()};Vector.getDistance=function(a,b){var dx=a.x-b.x;var dy=a.y-b.y;return Math.sqrt(dx*dx+dy*dy)};Vector.pool=function(size){if(typeof size!=="undefined"){pool.length=0;for(var i=0;i<size;i++){pool.push(Vector())}}else{return pool.length}};Vector.prototype.add=function(v){this.x+=v.x;this.y+=v.y;return this};Vector.prototype.clone=function(){return Vector(this.x,this.y)};Vector.prototype.copy=function(v){this.x=v.x;this.y=v.y;return this};Vector.prototype.getDistance2=function(v){var dx=v.x-this.x;var dy=v.y-this.y;return dx*dx+dy*dy};Vector.prototype.equals=function(v){return this.x===v.x&&this.y===v.y};Vector.prototype.pool=function(){return Vector.claim().copy(this)};Vector.prototype.free=function(){pool.push(this);return this};Vector.prototype.getLength=function(){return Math.sqrt(this.x*this.x+this.y*this.y)};Vector.prototype.min=function(v){if(this.x<v.x)this.x=v.x;if(this.y<v.y)this.y=v.y;else return false};Vector.prototype.max=function(v){if(this.x>v.x)this.x=v.x;if(this.y>v.y)this.y=v.y;return this};Vector.prototype.rotate=function(angle){var x=this.x;var y=-this.y;var sin=Math.sin(angle);var cos=Math.cos(angle);this.x=x*cos-y*sin;this.y=-(x*sin+y*cos);return this};Vector.prototype.scale=function(scalar){this.x*=scalar;this.y*=scalar;return this};Vector.prototype.sub=function(v){this.x-=v.x;this.y-=v.y;return this};Vector.prototype.zero=function(){this.x=this.y=0;return this};module.exports=Vector},{}],19:[function(_dereq_,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){var source=ev.source;if((source===window||source===null)&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];function noop(){}process.on=noop;process.once=noop;process.off=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],20:[function(_dereq_,module,exports){(function(process){!function(exports,undefined){var isArray=Array.isArray?Array.isArray:function _isArray(obj){return Object.prototype.toString.call(obj)==="[object Array]"};var defaultMaxListeners=10;function init(){this._events={};if(this._conf){configure.call(this,this._conf)}}function configure(conf){if(conf){this._conf=conf;conf.delimiter&&(this.delimiter=conf.delimiter);conf.maxListeners&&(this._events.maxListeners=conf.maxListeners);conf.wildcard&&(this.wildcard=conf.wildcard);conf.newListener&&(this.newListener=conf.newListener);if(this.wildcard){this.listenerTree={}}}}function EventEmitter(conf){this._events={};this.newListener=false;configure.call(this,conf)}function searchListenerTree(handlers,type,tree,i){if(!tree){return[]}var listeners=[],leaf,len,branch,xTree,xxTree,isolatedBranch,endReached,typeLength=type.length,currentType=type[i],nextType=type[i+1];if(i===typeLength&&tree._listeners){if(typeof tree._listeners==="function"){handlers&&handlers.push(tree._listeners);return[tree]}else{for(leaf=0,len=tree._listeners.length;leaf<len;leaf++){handlers&&handlers.push(tree._listeners[leaf])}return[tree]}}if(currentType==="*"||currentType==="**"||tree[currentType]){if(currentType==="*"){for(branch in tree){if(branch!=="_listeners"&&tree.hasOwnProperty(branch)){listeners=listeners.concat(searchListenerTree(handlers,type,tree[branch],i+1))}}return listeners}else if(currentType==="**"){endReached=i+1===typeLength||i+2===typeLength&&nextType==="*";if(endReached&&tree._listeners){listeners=listeners.concat(searchListenerTree(handlers,type,tree,typeLength))}for(branch in tree){if(branch!=="_listeners"&&tree.hasOwnProperty(branch)){if(branch==="*"||branch==="**"){if(tree[branch]._listeners&&!endReached){listeners=listeners.concat(searchListenerTree(handlers,type,tree[branch],typeLength))}listeners=listeners.concat(searchListenerTree(handlers,type,tree[branch],i))}else if(branch===nextType){listeners=listeners.concat(searchListenerTree(handlers,type,tree[branch],i+2))}else{listeners=listeners.concat(searchListenerTree(handlers,type,tree[branch],i))}}}return listeners}listeners=listeners.concat(searchListenerTree(handlers,type,tree[currentType],i+1))}xTree=tree["*"];if(xTree){searchListenerTree(handlers,type,xTree,i+1)}xxTree=tree["**"];if(xxTree){if(i<typeLength){if(xxTree._listeners){searchListenerTree(handlers,type,xxTree,typeLength)}for(branch in xxTree){if(branch!=="_listeners"&&xxTree.hasOwnProperty(branch)){if(branch===nextType){searchListenerTree(handlers,type,xxTree[branch],i+2)}else if(branch===currentType){searchListenerTree(handlers,type,xxTree[branch],i+1)}else{isolatedBranch={};isolatedBranch[branch]=xxTree[branch];searchListenerTree(handlers,type,{"**":isolatedBranch},i+1)}}}}else if(xxTree._listeners){searchListenerTree(handlers,type,xxTree,typeLength)}else if(xxTree["*"]&&xxTree["*"]._listeners){searchListenerTree(handlers,type,xxTree["*"],typeLength)}}return listeners}function growListenerTree(type,listener){type=typeof type==="string"?type.split(this.delimiter):type.slice();for(var i=0,len=type.length;i+1<len;i++){if(type[i]==="**"&&type[i+1]==="**"){return}}var tree=this.listenerTree;var name=type.shift();while(name){if(!tree[name]){tree[name]={}}tree=tree[name];if(type.length===0){if(!tree._listeners){tree._listeners=listener}else if(typeof tree._listeners==="function"){tree._listeners=[tree._listeners,listener]}else if(isArray(tree._listeners)){tree._listeners.push(listener);if(!tree._listeners.warned){var m=defaultMaxListeners;if(typeof this._events.maxListeners!=="undefined"){m=this._events.maxListeners}if(m>0&&tree._listeners.length>m){tree._listeners.warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",tree._listeners.length);console.trace()}}}return true}name=type.shift()}return true}EventEmitter.prototype.delimiter=".";EventEmitter.prototype.setMaxListeners=function(n){this._events||init.call(this);this._events.maxListeners=n;if(!this._conf)this._conf={};this._conf.maxListeners=n};EventEmitter.prototype.event="";EventEmitter.prototype.once=function(event,fn){this.many(event,1,fn);return this};EventEmitter.prototype.many=function(event,ttl,fn){var self=this;if(typeof fn!=="function"){throw new Error("many only accepts instances of Function")}function listener(){if(--ttl===0){self.off(event,listener)}fn.apply(this,arguments)}listener._origin=fn;this.on(event,listener);return self};EventEmitter.prototype.emit=function(){this._events||init.call(this);var type=arguments[0];if(type==="newListener"&&!this.newListener){if(!this._events.newListener){return false}}if(this._all){var l=arguments.length;var args=new Array(l-1);for(var i=1;i<l;i++)args[i-1]=arguments[i];for(i=0,l=this._all.length;i<l;i++){this.event=type;this._all[i].apply(this,args)}}if(type==="error"){if(!this._all&&!this._events.error&&!(this.wildcard&&this.listenerTree.error)){if(arguments[1]instanceof Error){throw arguments[1]}else{throw new Error("Uncaught, unspecified 'error' event.")}return false}}var handler;if(this.wildcard){handler=[];var ns=typeof type==="string"?type.split(this.delimiter):type.slice();searchListenerTree.call(this,handler,ns,this.listenerTree,0)}else{handler=this._events[type]}if(typeof handler==="function"){this.event=type;if(arguments.length===1){handler.call(this)}else if(arguments.length>1)switch(arguments.length){case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:var l=arguments.length;var args=new Array(l-1);for(var i=1;i<l;i++)args[i-1]=arguments[i];handler.apply(this,args)}return true}else if(handler){var l=arguments.length;var args=new Array(l-1);for(var i=1;i<l;i++)args[i-1]=arguments[i];var listeners=handler.slice();for(var i=0,l=listeners.length;i<l;i++){this.event=type;listeners[i].apply(this,args)}return listeners.length>0||this._all}else{return this._all}};EventEmitter.prototype.on=function(type,listener){if(typeof type==="function"){this.onAny(type);return this}if(typeof listener!=="function"){throw new Error("on only accepts instances of Function")}this._events||init.call(this);this.emit("newListener",type,listener);if(this.wildcard){growListenerTree.call(this,type,listener);return this}if(!this._events[type]){this._events[type]=listener}else if(typeof this._events[type]==="function"){this._events[type]=[this._events[type],listener]}else if(isArray(this._events[type])){this._events[type].push(listener);if(!this._events[type].warned){var m=defaultMaxListeners;if(typeof this._events.maxListeners!=="undefined"){m=this._events.maxListeners}if(m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);console.trace()}}}return this};EventEmitter.prototype.onAny=function(fn){if(!this._all){this._all=[]}if(typeof fn!=="function"){throw new Error("onAny only accepts instances of Function")}this._all.push(fn);return this};EventEmitter.prototype.addListener=EventEmitter.prototype.on;EventEmitter.prototype.off=function(type,listener){if(typeof listener!=="function"){throw new Error("removeListener only takes instances of Function")}var handlers,leafs=[];if(this.wildcard){var ns=typeof type==="string"?type.split(this.delimiter):type.slice();leafs=searchListenerTree.call(this,null,ns,this.listenerTree,0)}else{if(!this._events[type])return this;handlers=this._events[type];leafs.push({_listeners:handlers})}for(var iLeaf=0;iLeaf<leafs.length;iLeaf++){var leaf=leafs[iLeaf];handlers=leaf._listeners;if(isArray(handlers)){var position=-1;for(var i=0,length=handlers.length;i<length;i++){if(handlers[i]===listener||handlers[i].listener&&handlers[i].listener===listener||handlers[i]._origin&&handlers[i]._origin===listener){position=i;break}}if(position<0){continue}if(this.wildcard){leaf._listeners.splice(position,1)}else{this._events[type].splice(position,1)}if(handlers.length===0){if(this.wildcard){delete leaf._listeners
}else{delete this._events[type]}}return this}else if(handlers===listener||handlers.listener&&handlers.listener===listener||handlers._origin&&handlers._origin===listener){if(this.wildcard){delete leaf._listeners}else{delete this._events[type]}}}return this};EventEmitter.prototype.offAny=function(fn){var i=0,l=0,fns;if(fn&&this._all&&this._all.length>0){fns=this._all;for(i=0,l=fns.length;i<l;i++){if(fn===fns[i]){fns.splice(i,1);return this}}}else{this._all=[]}return this};EventEmitter.prototype.removeListener=EventEmitter.prototype.off;EventEmitter.prototype.removeAllListeners=function(type){if(arguments.length===0){!this._events||init.call(this);return this}if(this.wildcard){var ns=typeof type==="string"?type.split(this.delimiter):type.slice();var leafs=searchListenerTree.call(this,null,ns,this.listenerTree,0);for(var iLeaf=0;iLeaf<leafs.length;iLeaf++){var leaf=leafs[iLeaf];leaf._listeners=null}}else{if(!this._events[type])return this;this._events[type]=null}return this};EventEmitter.prototype.listeners=function(type){if(this.wildcard){var handlers=[];var ns=typeof type==="string"?type.split(this.delimiter):type.slice();searchListenerTree.call(this,handlers,ns,this.listenerTree,0);return handlers}this._events||init.call(this);if(!this._events[type])this._events[type]=[];if(!isArray(this._events[type])){this._events[type]=[this._events[type]]}return this._events[type]};EventEmitter.prototype.listenersAny=function(){if(this._all){return this._all}else{return[]}};if(typeof define==="function"&&define.amd){define(function(){return EventEmitter})}else{exports.EventEmitter2=EventEmitter}}(typeof process!=="undefined"&&typeof process.title!=="undefined"&&typeof exports!=="undefined"?exports:window)}).call(this,_dereq_("/Users/hunter/code/newton/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))},{"/Users/hunter/code/newton/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":19}],21:[function(_dereq_,module,exports){(function(global){(function(){var undefined;var arrayPool=[],objectPool=[];var idCounter=0;var keyPrefix=+new Date+"";var largeArraySize=75;var maxPoolSize=40;var whitespace=" \f "+"\n\r\u2028\u2029"+" ";var reEmptyStringLeading=/\b__p \+= '';/g,reEmptyStringMiddle=/\b(__p \+=) '' \+/g,reEmptyStringTrailing=/(__e\(.*?\)|\b__t\)) \+\n'';/g;var reEsTemplate=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;var reFlags=/\w*$/;var reFuncName=/^\s*function[ \n\r\t]+\w/;var reInterpolate=/<%=([\s\S]+?)%>/g;var reLeadingSpacesAndZeros=RegExp("^["+whitespace+"]*0+(?=.$)");var reNoMatch=/($^)/;var reThis=/\bthis\b/;var reUnescapedString=/['\n\r\t\u2028\u2029\\]/g;var contextProps=["Array","Boolean","Date","Function","Math","Number","Object","RegExp","String","_","attachEvent","clearTimeout","isFinite","isNaN","parseInt","setTimeout"];var templateCounter=0;var argsClass="[object Arguments]",arrayClass="[object Array]",boolClass="[object Boolean]",dateClass="[object Date]",funcClass="[object Function]",numberClass="[object Number]",objectClass="[object Object]",regexpClass="[object RegExp]",stringClass="[object String]";var cloneableClasses={};cloneableClasses[funcClass]=false;cloneableClasses[argsClass]=cloneableClasses[arrayClass]=cloneableClasses[boolClass]=cloneableClasses[dateClass]=cloneableClasses[numberClass]=cloneableClasses[objectClass]=cloneableClasses[regexpClass]=cloneableClasses[stringClass]=true;var debounceOptions={leading:false,maxWait:0,trailing:false};var descriptor={configurable:false,enumerable:false,value:null,writable:false};var objectTypes={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false};var stringEscapes={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"};var root=objectTypes[typeof window]&&window||this;var freeExports=objectTypes[typeof exports]&&exports&&!exports.nodeType&&exports;var freeModule=objectTypes[typeof module]&&module&&!module.nodeType&&module;var moduleExports=freeModule&&freeModule.exports===freeExports&&freeExports;var freeGlobal=objectTypes[typeof global]&&global;if(freeGlobal&&(freeGlobal.global===freeGlobal||freeGlobal.window===freeGlobal)){root=freeGlobal}function baseIndexOf(array,value,fromIndex){var index=(fromIndex||0)-1,length=array?array.length:0;while(++index<length){if(array[index]===value){return index}}return-1}function cacheIndexOf(cache,value){var type=typeof value;cache=cache.cache;if(type=="boolean"||value==null){return cache[value]?0:-1}if(type!="number"&&type!="string"){type="object"}var key=type=="number"?value:keyPrefix+value;cache=(cache=cache[type])&&cache[key];return type=="object"?cache&&baseIndexOf(cache,value)>-1?0:-1:cache?0:-1}function cachePush(value){var cache=this.cache,type=typeof value;if(type=="boolean"||value==null){cache[value]=true}else{if(type!="number"&&type!="string"){type="object"}var key=type=="number"?value:keyPrefix+value,typeCache=cache[type]||(cache[type]={});if(type=="object"){(typeCache[key]||(typeCache[key]=[])).push(value)}else{typeCache[key]=true}}}function charAtCallback(value){return value.charCodeAt(0)}function compareAscending(a,b){var ac=a.criteria,bc=b.criteria,index=-1,length=ac.length;while(++index<length){var value=ac[index],other=bc[index];if(value!==other){if(value>other||typeof value=="undefined"){return 1}if(value<other||typeof other=="undefined"){return-1}}}return a.index-b.index}function createCache(array){var index=-1,length=array.length,first=array[0],mid=array[length/2|0],last=array[length-1];if(first&&typeof first=="object"&&mid&&typeof mid=="object"&&last&&typeof last=="object"){return false}var cache=getObject();cache["false"]=cache["null"]=cache["true"]=cache["undefined"]=false;var result=getObject();result.array=array;result.cache=cache;result.push=cachePush;while(++index<length){result.push(array[index])}return result}function escapeStringChar(match){return"\\"+stringEscapes[match]}function getArray(){return arrayPool.pop()||[]}function getObject(){return objectPool.pop()||{array:null,cache:null,criteria:null,"false":false,index:0,"null":false,number:null,object:null,push:null,string:null,"true":false,undefined:false,value:null}}function releaseArray(array){array.length=0;if(arrayPool.length<maxPoolSize){arrayPool.push(array)}}function releaseObject(object){var cache=object.cache;if(cache){releaseObject(cache)}object.array=object.cache=object.criteria=object.object=object.number=object.string=object.value=null;if(objectPool.length<maxPoolSize){objectPool.push(object)}}function slice(array,start,end){start||(start=0);if(typeof end=="undefined"){end=array?array.length:0}var index=-1,length=end-start||0,result=Array(length<0?0:length);while(++index<length){result[index]=array[start+index]}return result}function runInContext(context){context=context?_.defaults(root.Object(),context,_.pick(root,contextProps)):root;var Array=context.Array,Boolean=context.Boolean,Date=context.Date,Function=context.Function,Math=context.Math,Number=context.Number,Object=context.Object,RegExp=context.RegExp,String=context.String,TypeError=context.TypeError;var arrayRef=[];var objectProto=Object.prototype;var oldDash=context._;var toString=objectProto.toString;var reNative=RegExp("^"+String(toString).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$");var ceil=Math.ceil,clearTimeout=context.clearTimeout,floor=Math.floor,fnToString=Function.prototype.toString,getPrototypeOf=isNative(getPrototypeOf=Object.getPrototypeOf)&&getPrototypeOf,hasOwnProperty=objectProto.hasOwnProperty,push=arrayRef.push,setTimeout=context.setTimeout,splice=arrayRef.splice,unshift=arrayRef.unshift;var defineProperty=function(){try{var o={},func=isNative(func=Object.defineProperty)&&func,result=func(o,o,o)&&func}catch(e){}return result}();var nativeCreate=isNative(nativeCreate=Object.create)&&nativeCreate,nativeIsArray=isNative(nativeIsArray=Array.isArray)&&nativeIsArray,nativeIsFinite=context.isFinite,nativeIsNaN=context.isNaN,nativeKeys=isNative(nativeKeys=Object.keys)&&nativeKeys,nativeMax=Math.max,nativeMin=Math.min,nativeParseInt=context.parseInt,nativeRandom=Math.random;var ctorByClass={};ctorByClass[arrayClass]=Array;ctorByClass[boolClass]=Boolean;ctorByClass[dateClass]=Date;ctorByClass[funcClass]=Function;ctorByClass[objectClass]=Object;ctorByClass[numberClass]=Number;ctorByClass[regexpClass]=RegExp;ctorByClass[stringClass]=String;function lodash(value){return value&&typeof value=="object"&&!isArray(value)&&hasOwnProperty.call(value,"__wrapped__")?value:new lodashWrapper(value)}function lodashWrapper(value,chainAll){this.__chain__=!!chainAll;this.__wrapped__=value}lodashWrapper.prototype=lodash.prototype;var support=lodash.support={};support.funcDecomp=!isNative(context.WinRTError)&&reThis.test(runInContext);support.funcNames=typeof Function.name=="string";lodash.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:reInterpolate,variable:"",imports:{_:lodash}};function baseBind(bindData){var func=bindData[0],partialArgs=bindData[2],thisArg=bindData[4];function bound(){if(partialArgs){var args=slice(partialArgs);push.apply(args,arguments)}if(this instanceof bound){var thisBinding=baseCreate(func.prototype),result=func.apply(thisBinding,args||arguments);return isObject(result)?result:thisBinding}return func.apply(thisArg,args||arguments)}setBindData(bound,bindData);return bound}function baseClone(value,isDeep,callback,stackA,stackB){if(callback){var result=callback(value);if(typeof result!="undefined"){return result}}var isObj=isObject(value);if(isObj){var className=toString.call(value);if(!cloneableClasses[className]){return value}var ctor=ctorByClass[className];switch(className){case boolClass:case dateClass:return new ctor(+value);case numberClass:case stringClass:return new ctor(value);case regexpClass:result=ctor(value.source,reFlags.exec(value));result.lastIndex=value.lastIndex;return result}}else{return value}var isArr=isArray(value);if(isDeep){var initedStack=!stackA;stackA||(stackA=getArray());stackB||(stackB=getArray());var length=stackA.length;while(length--){if(stackA[length]==value){return stackB[length]}}result=isArr?ctor(value.length):{}}else{result=isArr?slice(value):assign({},value)}if(isArr){if(hasOwnProperty.call(value,"index")){result.index=value.index}if(hasOwnProperty.call(value,"input")){result.input=value.input}}if(!isDeep){return result}stackA.push(value);stackB.push(result);(isArr?forEach:forOwn)(value,function(objValue,key){result[key]=baseClone(objValue,isDeep,callback,stackA,stackB)});if(initedStack){releaseArray(stackA);releaseArray(stackB)}return result}function baseCreate(prototype,properties){return isObject(prototype)?nativeCreate(prototype):{}}if(!nativeCreate){baseCreate=function(){function Object(){}return function(prototype){if(isObject(prototype)){Object.prototype=prototype;var result=new Object;Object.prototype=null}return result||context.Object()}}()}function baseCreateCallback(func,thisArg,argCount){if(typeof func!="function"){return identity}if(typeof thisArg=="undefined"||!("prototype"in func)){return func}var bindData=func.__bindData__;if(typeof bindData=="undefined"){if(support.funcNames){bindData=!func.name}bindData=bindData||!support.funcDecomp;if(!bindData){var source=fnToString.call(func);if(!support.funcNames){bindData=!reFuncName.test(source)}if(!bindData){bindData=reThis.test(source);setBindData(func,bindData)}}}if(bindData===false||bindData!==true&&bindData[1]&1){return func}switch(argCount){case 1:return function(value){return func.call(thisArg,value)};case 2:return function(a,b){return func.call(thisArg,a,b)};case 3:return function(value,index,collection){return func.call(thisArg,value,index,collection)};case 4:return function(accumulator,value,index,collection){return func.call(thisArg,accumulator,value,index,collection)}}return bind(func,thisArg)}function baseCreateWrapper(bindData){var func=bindData[0],bitmask=bindData[1],partialArgs=bindData[2],partialRightArgs=bindData[3],thisArg=bindData[4],arity=bindData[5];var isBind=bitmask&1,isBindKey=bitmask&2,isCurry=bitmask&4,isCurryBound=bitmask&8,key=func;function bound(){var thisBinding=isBind?thisArg:this;if(partialArgs){var args=slice(partialArgs);push.apply(args,arguments)}if(partialRightArgs||isCurry){args||(args=slice(arguments));if(partialRightArgs){push.apply(args,partialRightArgs)}if(isCurry&&args.length<arity){bitmask|=16&~32;return baseCreateWrapper([func,isCurryBound?bitmask:bitmask&~3,args,null,thisArg,arity])}}args||(args=arguments);if(isBindKey){func=thisBinding[key]}if(this instanceof bound){thisBinding=baseCreate(func.prototype);var result=func.apply(thisBinding,args);return isObject(result)?result:thisBinding}return func.apply(thisBinding,args)}setBindData(bound,bindData);return bound}function baseDifference(array,values){var index=-1,indexOf=getIndexOf(),length=array?array.length:0,isLarge=length>=largeArraySize&&indexOf===baseIndexOf,result=[];if(isLarge){var cache=createCache(values);if(cache){indexOf=cacheIndexOf;values=cache}else{isLarge=false}}while(++index<length){var value=array[index];if(indexOf(values,value)<0){result.push(value)}}if(isLarge){releaseObject(values)}return result}function baseFlatten(array,isShallow,isStrict,fromIndex){var index=(fromIndex||0)-1,length=array?array.length:0,result=[];while(++index<length){var value=array[index];if(value&&typeof value=="object"&&typeof value.length=="number"&&(isArray(value)||isArguments(value))){if(!isShallow){value=baseFlatten(value,isShallow,isStrict)}var valIndex=-1,valLength=value.length,resIndex=result.length;result.length+=valLength;while(++valIndex<valLength){result[resIndex++]=value[valIndex]}}else if(!isStrict){result.push(value)}}return result}function baseIsEqual(a,b,callback,isWhere,stackA,stackB){if(callback){var result=callback(a,b);if(typeof result!="undefined"){return!!result}}if(a===b){return a!==0||1/a==1/b}var type=typeof a,otherType=typeof b;if(a===a&&!(a&&objectTypes[type])&&!(b&&objectTypes[otherType])){return false}if(a==null||b==null){return a===b}var className=toString.call(a),otherClass=toString.call(b);if(className==argsClass){className=objectClass}if(otherClass==argsClass){otherClass=objectClass}if(className!=otherClass){return false}switch(className){case boolClass:case dateClass:return+a==+b;case numberClass:return a!=+a?b!=+b:a==0?1/a==1/b:a==+b;case regexpClass:case stringClass:return a==String(b)}var isArr=className==arrayClass;if(!isArr){var aWrapped=hasOwnProperty.call(a,"__wrapped__"),bWrapped=hasOwnProperty.call(b,"__wrapped__");if(aWrapped||bWrapped){return baseIsEqual(aWrapped?a.__wrapped__:a,bWrapped?b.__wrapped__:b,callback,isWhere,stackA,stackB)}if(className!=objectClass){return false}var ctorA=a.constructor,ctorB=b.constructor;if(ctorA!=ctorB&&!(isFunction(ctorA)&&ctorA instanceof ctorA&&isFunction(ctorB)&&ctorB instanceof ctorB)&&("constructor"in a&&"constructor"in b)){return false}}var initedStack=!stackA;stackA||(stackA=getArray());stackB||(stackB=getArray());var length=stackA.length;while(length--){if(stackA[length]==a){return stackB[length]==b}}var size=0;result=true;stackA.push(a);stackB.push(b);if(isArr){length=a.length;size=b.length;result=size==length;if(result||isWhere){while(size--){var index=length,value=b[size];if(isWhere){while(index--){if(result=baseIsEqual(a[index],value,callback,isWhere,stackA,stackB)){break}}}else if(!(result=baseIsEqual(a[size],value,callback,isWhere,stackA,stackB))){break}}}}else{forIn(b,function(value,key,b){if(hasOwnProperty.call(b,key)){size++;return result=hasOwnProperty.call(a,key)&&baseIsEqual(a[key],value,callback,isWhere,stackA,stackB)}});if(result&&!isWhere){forIn(a,function(value,key,a){if(hasOwnProperty.call(a,key)){return result=--size>-1}})}}stackA.pop();stackB.pop();if(initedStack){releaseArray(stackA);releaseArray(stackB)}return result}function baseMerge(object,source,callback,stackA,stackB){(isArray(source)?forEach:forOwn)(source,function(source,key){var found,isArr,result=source,value=object[key];if(source&&((isArr=isArray(source))||isPlainObject(source))){var stackLength=stackA.length;while(stackLength--){if(found=stackA[stackLength]==source){value=stackB[stackLength];break}}if(!found){var isShallow;if(callback){result=callback(value,source);if(isShallow=typeof result!="undefined"){value=result}}if(!isShallow){value=isArr?isArray(value)?value:[]:isPlainObject(value)?value:{}}stackA.push(source);stackB.push(value);if(!isShallow){baseMerge(value,source,callback,stackA,stackB)}}}else{if(callback){result=callback(value,source);if(typeof result=="undefined"){result=source}}if(typeof result!="undefined"){value=result}}object[key]=value})}function baseRandom(min,max){return min+floor(nativeRandom()*(max-min+1))}function baseUniq(array,isSorted,callback){var index=-1,indexOf=getIndexOf(),length=array?array.length:0,result=[];var isLarge=!isSorted&&length>=largeArraySize&&indexOf===baseIndexOf,seen=callback||isLarge?getArray():result;if(isLarge){var cache=createCache(seen);indexOf=cacheIndexOf;seen=cache}while(++index<length){var value=array[index],computed=callback?callback(value,index,array):value;if(isSorted?!index||seen[seen.length-1]!==computed:indexOf(seen,computed)<0){if(callback||isLarge){seen.push(computed)}result.push(value)}}if(isLarge){releaseArray(seen.array);releaseObject(seen)}else if(callback){releaseArray(seen)}return result}function createAggregator(setter){return function(collection,callback,thisArg){var result={};callback=lodash.createCallback(callback,thisArg,3);var index=-1,length=collection?collection.length:0;if(typeof length=="number"){while(++index<length){var value=collection[index];setter(result,value,callback(value,index,collection),collection)}}else{forOwn(collection,function(value,key,collection){setter(result,value,callback(value,key,collection),collection)})}return result}}function createWrapper(func,bitmask,partialArgs,partialRightArgs,thisArg,arity){var isBind=bitma