trickytowers

simple tricky towers clone using matter.js
git clone https://git.ce9e.org/trickytowers.git

commit
320e55fa9b91bc4e4411236a803b729090500bc5
parent
7ca90b565ce787f12fdadc85b58476e0ec77c485
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2018-09-16 08:50
build

Diffstat

A docs/build.js 10516 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A docs/index.html 16 ++++++++++++++++

2 files changed, 10532 insertions, 0 deletions


diff --git a/docs/build.js b/docs/build.js

@@ -0,0 +1,10516 @@
   -1     1 (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
   -1     2 (function (global){
   -1     3 /**
   -1     4 * matter-js 0.14.2 by @liabru 2018-06-11
   -1     5 * http://brm.io/matter-js/
   -1     6 * License MIT
   -1     7 */
   -1     8 
   -1     9 /**
   -1    10  * The MIT License (MIT)
   -1    11  * 
   -1    12  * Copyright (c) Liam Brummitt and contributors.
   -1    13  * 
   -1    14  * Permission is hereby granted, free of charge, to any person obtaining a copy
   -1    15  * of this software and associated documentation files (the "Software"), to deal
   -1    16  * in the Software without restriction, including without limitation the rights
   -1    17  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   -1    18  * copies of the Software, and to permit persons to whom the Software is
   -1    19  * furnished to do so, subject to the following conditions:
   -1    20  * 
   -1    21  * The above copyright notice and this permission notice shall be included in
   -1    22  * all copies or substantial portions of the Software.
   -1    23  * 
   -1    24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   -1    25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   -1    26  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   -1    27  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   -1    28  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   -1    29  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   -1    30  * THE SOFTWARE.
   -1    31  */
   -1    32 
   -1    33 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Matter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){
   -1    34 /**
   -1    35 * The `Matter.Body` module contains methods for creating and manipulating body models.
   -1    36 * A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`.
   -1    37 * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`.
   -1    38 *
   -1    39 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1    40 
   -1    41 * @class Body
   -1    42 */
   -1    43 
   -1    44 var Body = {};
   -1    45 
   -1    46 module.exports = Body;
   -1    47 
   -1    48 var Vertices = _dereq_('../geometry/Vertices');
   -1    49 var Vector = _dereq_('../geometry/Vector');
   -1    50 var Sleeping = _dereq_('../core/Sleeping');
   -1    51 var Render = _dereq_('../render/Render');
   -1    52 var Common = _dereq_('../core/Common');
   -1    53 var Bounds = _dereq_('../geometry/Bounds');
   -1    54 var Axes = _dereq_('../geometry/Axes');
   -1    55 
   -1    56 (function() {
   -1    57 
   -1    58     Body._inertiaScale = 4;
   -1    59     Body._nextCollidingGroupId = 1;
   -1    60     Body._nextNonCollidingGroupId = -1;
   -1    61     Body._nextCategory = 0x0001;
   -1    62 
   -1    63     /**
   -1    64      * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults.
   -1    65      * All properties have default values, and many are pre-calculated automatically based on other properties.
   -1    66      * Vertices must be specified in clockwise order.
   -1    67      * See the properties section below for detailed information on what you can pass via the `options` object.
   -1    68      * @method create
   -1    69      * @param {} options
   -1    70      * @return {body} body
   -1    71      */
   -1    72     Body.create = function(options) {
   -1    73         var defaults = {
   -1    74             id: Common.nextId(),
   -1    75             type: 'body',
   -1    76             label: 'Body',
   -1    77             parts: [],
   -1    78             plugin: {},
   -1    79             angle: 0,
   -1    80             vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'),
   -1    81             position: { x: 0, y: 0 },
   -1    82             force: { x: 0, y: 0 },
   -1    83             torque: 0,
   -1    84             positionImpulse: { x: 0, y: 0 },
   -1    85             constraintImpulse: { x: 0, y: 0, angle: 0 },
   -1    86             totalContacts: 0,
   -1    87             speed: 0,
   -1    88             angularSpeed: 0,
   -1    89             velocity: { x: 0, y: 0 },
   -1    90             angularVelocity: 0,
   -1    91             isSensor: false,
   -1    92             isStatic: false,
   -1    93             isSleeping: false,
   -1    94             motion: 0,
   -1    95             sleepThreshold: 60,
   -1    96             density: 0.001,
   -1    97             restitution: 0,
   -1    98             friction: 0.1,
   -1    99             frictionStatic: 0.5,
   -1   100             frictionAir: 0.01,
   -1   101             collisionFilter: {
   -1   102                 category: 0x0001,
   -1   103                 mask: 0xFFFFFFFF,
   -1   104                 group: 0
   -1   105             },
   -1   106             slop: 0.05,
   -1   107             timeScale: 1,
   -1   108             render: {
   -1   109                 visible: true,
   -1   110                 opacity: 1,
   -1   111                 sprite: {
   -1   112                     xScale: 1,
   -1   113                     yScale: 1,
   -1   114                     xOffset: 0,
   -1   115                     yOffset: 0
   -1   116                 },
   -1   117                 lineWidth: 0
   -1   118             }
   -1   119         };
   -1   120 
   -1   121         var body = Common.extend(defaults, options);
   -1   122 
   -1   123         _initProperties(body, options);
   -1   124 
   -1   125         return body;
   -1   126     };
   -1   127 
   -1   128     /**
   -1   129      * Returns the next unique group index for which bodies will collide.
   -1   130      * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide.
   -1   131      * See `body.collisionFilter` for more information.
   -1   132      * @method nextGroup
   -1   133      * @param {bool} [isNonColliding=false]
   -1   134      * @return {Number} Unique group index
   -1   135      */
   -1   136     Body.nextGroup = function(isNonColliding) {
   -1   137         if (isNonColliding)
   -1   138             return Body._nextNonCollidingGroupId--;
   -1   139 
   -1   140         return Body._nextCollidingGroupId++;
   -1   141     };
   -1   142 
   -1   143     /**
   -1   144      * Returns the next unique category bitfield (starting after the initial default category `0x0001`).
   -1   145      * There are 32 available. See `body.collisionFilter` for more information.
   -1   146      * @method nextCategory
   -1   147      * @return {Number} Unique category bitfield
   -1   148      */
   -1   149     Body.nextCategory = function() {
   -1   150         Body._nextCategory = Body._nextCategory << 1;
   -1   151         return Body._nextCategory;
   -1   152     };
   -1   153 
   -1   154     /**
   -1   155      * Initialises body properties.
   -1   156      * @method _initProperties
   -1   157      * @private
   -1   158      * @param {body} body
   -1   159      * @param {} [options]
   -1   160      */
   -1   161     var _initProperties = function(body, options) {
   -1   162         options = options || {};
   -1   163 
   -1   164         // init required properties (order is important)
   -1   165         Body.set(body, {
   -1   166             bounds: body.bounds || Bounds.create(body.vertices),
   -1   167             positionPrev: body.positionPrev || Vector.clone(body.position),
   -1   168             anglePrev: body.anglePrev || body.angle,
   -1   169             vertices: body.vertices,
   -1   170             parts: body.parts || [body],
   -1   171             isStatic: body.isStatic,
   -1   172             isSleeping: body.isSleeping,
   -1   173             parent: body.parent || body
   -1   174         });
   -1   175 
   -1   176         Vertices.rotate(body.vertices, body.angle, body.position);
   -1   177         Axes.rotate(body.axes, body.angle);
   -1   178         Bounds.update(body.bounds, body.vertices, body.velocity);
   -1   179 
   -1   180         // allow options to override the automatically calculated properties
   -1   181         Body.set(body, {
   -1   182             axes: options.axes || body.axes,
   -1   183             area: options.area || body.area,
   -1   184             mass: options.mass || body.mass,
   -1   185             inertia: options.inertia || body.inertia
   -1   186         });
   -1   187 
   -1   188         // render properties
   -1   189         var defaultFillStyle = (body.isStatic ? '#2e2b44' : Common.choose(['#006BA6', '#0496FF', '#FFBC42', '#D81159', '#8F2D56'])),
   -1   190             defaultStrokeStyle = '#000';
   -1   191         body.render.fillStyle = body.render.fillStyle || defaultFillStyle;
   -1   192         body.render.strokeStyle = body.render.strokeStyle || defaultStrokeStyle;
   -1   193         body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x);
   -1   194         body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y);
   -1   195     };
   -1   196 
   -1   197     /**
   -1   198      * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist.
   -1   199      * Prefer to use the actual setter functions in performance critical situations.
   -1   200      * @method set
   -1   201      * @param {body} body
   -1   202      * @param {} settings A property name (or map of properties and values) to set on the body.
   -1   203      * @param {} value The value to set if `settings` is a single property name.
   -1   204      */
   -1   205     Body.set = function(body, settings, value) {
   -1   206         var property;
   -1   207 
   -1   208         if (typeof settings === 'string') {
   -1   209             property = settings;
   -1   210             settings = {};
   -1   211             settings[property] = value;
   -1   212         }
   -1   213 
   -1   214         for (property in settings) {
   -1   215             value = settings[property];
   -1   216 
   -1   217             if (!settings.hasOwnProperty(property))
   -1   218                 continue;
   -1   219 
   -1   220             switch (property) {
   -1   221 
   -1   222             case 'isStatic':
   -1   223                 Body.setStatic(body, value);
   -1   224                 break;
   -1   225             case 'isSleeping':
   -1   226                 Sleeping.set(body, value);
   -1   227                 break;
   -1   228             case 'mass':
   -1   229                 Body.setMass(body, value);
   -1   230                 break;
   -1   231             case 'density':
   -1   232                 Body.setDensity(body, value);
   -1   233                 break;
   -1   234             case 'inertia':
   -1   235                 Body.setInertia(body, value);
   -1   236                 break;
   -1   237             case 'vertices':
   -1   238                 Body.setVertices(body, value);
   -1   239                 break;
   -1   240             case 'position':
   -1   241                 Body.setPosition(body, value);
   -1   242                 break;
   -1   243             case 'angle':
   -1   244                 Body.setAngle(body, value);
   -1   245                 break;
   -1   246             case 'velocity':
   -1   247                 Body.setVelocity(body, value);
   -1   248                 break;
   -1   249             case 'angularVelocity':
   -1   250                 Body.setAngularVelocity(body, value);
   -1   251                 break;
   -1   252             case 'parts':
   -1   253                 Body.setParts(body, value);
   -1   254                 break;
   -1   255             default:
   -1   256                 body[property] = value;
   -1   257 
   -1   258             }
   -1   259         }
   -1   260     };
   -1   261 
   -1   262     /**
   -1   263      * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity.
   -1   264      * @method setStatic
   -1   265      * @param {body} body
   -1   266      * @param {bool} isStatic
   -1   267      */
   -1   268     Body.setStatic = function(body, isStatic) {
   -1   269         for (var i = 0; i < body.parts.length; i++) {
   -1   270             var part = body.parts[i];
   -1   271             part.isStatic = isStatic;
   -1   272 
   -1   273             if (isStatic) {
   -1   274                 part._original = {
   -1   275                     restitution: part.restitution,
   -1   276                     friction: part.friction,
   -1   277                     mass: part.mass,
   -1   278                     inertia: part.inertia,
   -1   279                     density: part.density,
   -1   280                     inverseMass: part.inverseMass,
   -1   281                     inverseInertia: part.inverseInertia
   -1   282                 };
   -1   283 
   -1   284                 part.restitution = 0;
   -1   285                 part.friction = 1;
   -1   286                 part.mass = part.inertia = part.density = Infinity;
   -1   287                 part.inverseMass = part.inverseInertia = 0;
   -1   288 
   -1   289                 part.positionPrev.x = part.position.x;
   -1   290                 part.positionPrev.y = part.position.y;
   -1   291                 part.anglePrev = part.angle;
   -1   292                 part.angularVelocity = 0;
   -1   293                 part.speed = 0;
   -1   294                 part.angularSpeed = 0;
   -1   295                 part.motion = 0;
   -1   296             } else if (part._original) {
   -1   297                 part.restitution = part._original.restitution;
   -1   298                 part.friction = part._original.friction;
   -1   299                 part.mass = part._original.mass;
   -1   300                 part.inertia = part._original.inertia;
   -1   301                 part.density = part._original.density;
   -1   302                 part.inverseMass = part._original.inverseMass;
   -1   303                 part.inverseInertia = part._original.inverseInertia;
   -1   304 
   -1   305                 delete part._original;
   -1   306             }
   -1   307         }
   -1   308     };
   -1   309 
   -1   310     /**
   -1   311      * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change.
   -1   312      * @method setMass
   -1   313      * @param {body} body
   -1   314      * @param {number} mass
   -1   315      */
   -1   316     Body.setMass = function(body, mass) {
   -1   317         var moment = body.inertia / (body.mass / 6);
   -1   318         body.inertia = moment * (mass / 6);
   -1   319         body.inverseInertia = 1 / body.inertia;
   -1   320 
   -1   321         body.mass = mass;
   -1   322         body.inverseMass = 1 / body.mass;
   -1   323         body.density = body.mass / body.area;
   -1   324     };
   -1   325 
   -1   326     /**
   -1   327      * Sets the density of the body. Mass and inertia are automatically updated to reflect the change.
   -1   328      * @method setDensity
   -1   329      * @param {body} body
   -1   330      * @param {number} density
   -1   331      */
   -1   332     Body.setDensity = function(body, density) {
   -1   333         Body.setMass(body, density * body.area);
   -1   334         body.density = density;
   -1   335     };
   -1   336 
   -1   337     /**
   -1   338      * Sets the moment of inertia (i.e. second moment of area) of the body of the body. 
   -1   339      * Inverse inertia is automatically updated to reflect the change. Mass is not changed.
   -1   340      * @method setInertia
   -1   341      * @param {body} body
   -1   342      * @param {number} inertia
   -1   343      */
   -1   344     Body.setInertia = function(body, inertia) {
   -1   345         body.inertia = inertia;
   -1   346         body.inverseInertia = 1 / body.inertia;
   -1   347     };
   -1   348 
   -1   349     /**
   -1   350      * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`).
   -1   351      * Vertices will be automatically transformed to be orientated around their centre of mass as the origin.
   -1   352      * They are then automatically translated to world space based on `body.position`.
   -1   353      *
   -1   354      * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array).
   -1   355      * Vertices must form a convex hull, concave hulls are not supported.
   -1   356      *
   -1   357      * @method setVertices
   -1   358      * @param {body} body
   -1   359      * @param {vector[]} vertices
   -1   360      */
   -1   361     Body.setVertices = function(body, vertices) {
   -1   362         // change vertices
   -1   363         if (vertices[0].body === body) {
   -1   364             body.vertices = vertices;
   -1   365         } else {
   -1   366             body.vertices = Vertices.create(vertices, body);
   -1   367         }
   -1   368 
   -1   369         // update properties
   -1   370         body.axes = Axes.fromVertices(body.vertices);
   -1   371         body.area = Vertices.area(body.vertices);
   -1   372         Body.setMass(body, body.density * body.area);
   -1   373 
   -1   374         // orient vertices around the centre of mass at origin (0, 0)
   -1   375         var centre = Vertices.centre(body.vertices);
   -1   376         Vertices.translate(body.vertices, centre, -1);
   -1   377 
   -1   378         // update inertia while vertices are at origin (0, 0)
   -1   379         Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass));
   -1   380 
   -1   381         // update geometry
   -1   382         Vertices.translate(body.vertices, body.position);
   -1   383         Bounds.update(body.bounds, body.vertices, body.velocity);
   -1   384     };
   -1   385 
   -1   386     /**
   -1   387      * Sets the parts of the `body` and updates mass, inertia and centroid.
   -1   388      * Each part will have its parent set to `body`.
   -1   389      * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.`
   -1   390      * Note that this method will ensure that the first part in `body.parts` will always be the `body`.
   -1   391      * @method setParts
   -1   392      * @param {body} body
   -1   393      * @param [body] parts
   -1   394      * @param {bool} [autoHull=true]
   -1   395      */
   -1   396     Body.setParts = function(body, parts, autoHull) {
   -1   397         var i;
   -1   398 
   -1   399         // add all the parts, ensuring that the first part is always the parent body
   -1   400         parts = parts.slice(0);
   -1   401         body.parts.length = 0;
   -1   402         body.parts.push(body);
   -1   403         body.parent = body;
   -1   404 
   -1   405         for (i = 0; i < parts.length; i++) {
   -1   406             var part = parts[i];
   -1   407             if (part !== body) {
   -1   408                 part.parent = body;
   -1   409                 body.parts.push(part);
   -1   410             }
   -1   411         }
   -1   412 
   -1   413         if (body.parts.length === 1)
   -1   414             return;
   -1   415 
   -1   416         autoHull = typeof autoHull !== 'undefined' ? autoHull : true;
   -1   417 
   -1   418         // find the convex hull of all parts to set on the parent body
   -1   419         if (autoHull) {
   -1   420             var vertices = [];
   -1   421             for (i = 0; i < parts.length; i++) {
   -1   422                 vertices = vertices.concat(parts[i].vertices);
   -1   423             }
   -1   424 
   -1   425             Vertices.clockwiseSort(vertices);
   -1   426 
   -1   427             var hull = Vertices.hull(vertices),
   -1   428                 hullCentre = Vertices.centre(hull);
   -1   429 
   -1   430             Body.setVertices(body, hull);
   -1   431             Vertices.translate(body.vertices, hullCentre);
   -1   432         }
   -1   433 
   -1   434         // sum the properties of all compound parts of the parent body
   -1   435         var total = Body._totalProperties(body);
   -1   436 
   -1   437         body.area = total.area;
   -1   438         body.parent = body;
   -1   439         body.position.x = total.centre.x;
   -1   440         body.position.y = total.centre.y;
   -1   441         body.positionPrev.x = total.centre.x;
   -1   442         body.positionPrev.y = total.centre.y;
   -1   443 
   -1   444         Body.setMass(body, total.mass);
   -1   445         Body.setInertia(body, total.inertia);
   -1   446         Body.setPosition(body, total.centre);
   -1   447     };
   -1   448 
   -1   449     /**
   -1   450      * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged.
   -1   451      * @method setPosition
   -1   452      * @param {body} body
   -1   453      * @param {vector} position
   -1   454      */
   -1   455     Body.setPosition = function(body, position) {
   -1   456         var delta = Vector.sub(position, body.position);
   -1   457         body.positionPrev.x += delta.x;
   -1   458         body.positionPrev.y += delta.y;
   -1   459 
   -1   460         for (var i = 0; i < body.parts.length; i++) {
   -1   461             var part = body.parts[i];
   -1   462             part.position.x += delta.x;
   -1   463             part.position.y += delta.y;
   -1   464             Vertices.translate(part.vertices, delta);
   -1   465             Bounds.update(part.bounds, part.vertices, body.velocity);
   -1   466         }
   -1   467     };
   -1   468 
   -1   469     /**
   -1   470      * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged.
   -1   471      * @method setAngle
   -1   472      * @param {body} body
   -1   473      * @param {number} angle
   -1   474      */
   -1   475     Body.setAngle = function(body, angle) {
   -1   476         var delta = angle - body.angle;
   -1   477         body.anglePrev += delta;
   -1   478 
   -1   479         for (var i = 0; i < body.parts.length; i++) {
   -1   480             var part = body.parts[i];
   -1   481             part.angle += delta;
   -1   482             Vertices.rotate(part.vertices, delta, body.position);
   -1   483             Axes.rotate(part.axes, delta);
   -1   484             Bounds.update(part.bounds, part.vertices, body.velocity);
   -1   485             if (i > 0) {
   -1   486                 Vector.rotateAbout(part.position, delta, body.position, part.position);
   -1   487             }
   -1   488         }
   -1   489     };
   -1   490 
   -1   491     /**
   -1   492      * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
   -1   493      * @method setVelocity
   -1   494      * @param {body} body
   -1   495      * @param {vector} velocity
   -1   496      */
   -1   497     Body.setVelocity = function(body, velocity) {
   -1   498         body.positionPrev.x = body.position.x - velocity.x;
   -1   499         body.positionPrev.y = body.position.y - velocity.y;
   -1   500         body.velocity.x = velocity.x;
   -1   501         body.velocity.y = velocity.y;
   -1   502         body.speed = Vector.magnitude(body.velocity);
   -1   503     };
   -1   504 
   -1   505     /**
   -1   506      * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
   -1   507      * @method setAngularVelocity
   -1   508      * @param {body} body
   -1   509      * @param {number} velocity
   -1   510      */
   -1   511     Body.setAngularVelocity = function(body, velocity) {
   -1   512         body.anglePrev = body.angle - velocity;
   -1   513         body.angularVelocity = velocity;
   -1   514         body.angularSpeed = Math.abs(body.angularVelocity);
   -1   515     };
   -1   516 
   -1   517     /**
   -1   518      * Moves a body by a given vector relative to its current position, without imparting any velocity.
   -1   519      * @method translate
   -1   520      * @param {body} body
   -1   521      * @param {vector} translation
   -1   522      */
   -1   523     Body.translate = function(body, translation) {
   -1   524         Body.setPosition(body, Vector.add(body.position, translation));
   -1   525     };
   -1   526 
   -1   527     /**
   -1   528      * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity.
   -1   529      * @method rotate
   -1   530      * @param {body} body
   -1   531      * @param {number} rotation
   -1   532      * @param {vector} [point]
   -1   533      */
   -1   534     Body.rotate = function(body, rotation, point) {
   -1   535         if (!point) {
   -1   536             Body.setAngle(body, body.angle + rotation);
   -1   537         } else {
   -1   538             var cos = Math.cos(rotation),
   -1   539                 sin = Math.sin(rotation),
   -1   540                 dx = body.position.x - point.x,
   -1   541                 dy = body.position.y - point.y;
   -1   542                 
   -1   543             Body.setPosition(body, {
   -1   544                 x: point.x + (dx * cos - dy * sin),
   -1   545                 y: point.y + (dx * sin + dy * cos)
   -1   546             });
   -1   547 
   -1   548             Body.setAngle(body, body.angle + rotation);
   -1   549         }
   -1   550     };
   -1   551 
   -1   552     /**
   -1   553      * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre).
   -1   554      * @method scale
   -1   555      * @param {body} body
   -1   556      * @param {number} scaleX
   -1   557      * @param {number} scaleY
   -1   558      * @param {vector} [point]
   -1   559      */
   -1   560     Body.scale = function(body, scaleX, scaleY, point) {
   -1   561         var totalArea = 0,
   -1   562             totalInertia = 0;
   -1   563 
   -1   564         point = point || body.position;
   -1   565 
   -1   566         for (var i = 0; i < body.parts.length; i++) {
   -1   567             var part = body.parts[i];
   -1   568 
   -1   569             // scale vertices
   -1   570             Vertices.scale(part.vertices, scaleX, scaleY, point);
   -1   571 
   -1   572             // update properties
   -1   573             part.axes = Axes.fromVertices(part.vertices);
   -1   574             part.area = Vertices.area(part.vertices);
   -1   575             Body.setMass(part, body.density * part.area);
   -1   576 
   -1   577             // update inertia (requires vertices to be at origin)
   -1   578             Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y });
   -1   579             Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass));
   -1   580             Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y });
   -1   581 
   -1   582             if (i > 0) {
   -1   583                 totalArea += part.area;
   -1   584                 totalInertia += part.inertia;
   -1   585             }
   -1   586 
   -1   587             // scale position
   -1   588             part.position.x = point.x + (part.position.x - point.x) * scaleX;
   -1   589             part.position.y = point.y + (part.position.y - point.y) * scaleY;
   -1   590 
   -1   591             // update bounds
   -1   592             Bounds.update(part.bounds, part.vertices, body.velocity);
   -1   593         }
   -1   594 
   -1   595         // handle parent body
   -1   596         if (body.parts.length > 1) {
   -1   597             body.area = totalArea;
   -1   598 
   -1   599             if (!body.isStatic) {
   -1   600                 Body.setMass(body, body.density * totalArea);
   -1   601                 Body.setInertia(body, totalInertia);
   -1   602             }
   -1   603         }
   -1   604 
   -1   605         // handle circles
   -1   606         if (body.circleRadius) { 
   -1   607             if (scaleX === scaleY) {
   -1   608                 body.circleRadius *= scaleX;
   -1   609             } else {
   -1   610                 // body is no longer a circle
   -1   611                 body.circleRadius = null;
   -1   612             }
   -1   613         }
   -1   614     };
   -1   615 
   -1   616     /**
   -1   617      * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration.
   -1   618      * @method update
   -1   619      * @param {body} body
   -1   620      * @param {number} deltaTime
   -1   621      * @param {number} timeScale
   -1   622      * @param {number} correction
   -1   623      */
   -1   624     Body.update = function(body, deltaTime, timeScale, correction) {
   -1   625         var deltaTimeSquared = Math.pow(deltaTime * timeScale * body.timeScale, 2);
   -1   626 
   -1   627         // from the previous step
   -1   628         var frictionAir = 1 - body.frictionAir * timeScale * body.timeScale,
   -1   629             velocityPrevX = body.position.x - body.positionPrev.x,
   -1   630             velocityPrevY = body.position.y - body.positionPrev.y;
   -1   631 
   -1   632         // update velocity with Verlet integration
   -1   633         body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared;
   -1   634         body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared;
   -1   635 
   -1   636         body.positionPrev.x = body.position.x;
   -1   637         body.positionPrev.y = body.position.y;
   -1   638         body.position.x += body.velocity.x;
   -1   639         body.position.y += body.velocity.y;
   -1   640 
   -1   641         // update angular velocity with Verlet integration
   -1   642         body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared;
   -1   643         body.anglePrev = body.angle;
   -1   644         body.angle += body.angularVelocity;
   -1   645 
   -1   646         // track speed and acceleration
   -1   647         body.speed = Vector.magnitude(body.velocity);
   -1   648         body.angularSpeed = Math.abs(body.angularVelocity);
   -1   649 
   -1   650         // transform the body geometry
   -1   651         for (var i = 0; i < body.parts.length; i++) {
   -1   652             var part = body.parts[i];
   -1   653 
   -1   654             Vertices.translate(part.vertices, body.velocity);
   -1   655             
   -1   656             if (i > 0) {
   -1   657                 part.position.x += body.velocity.x;
   -1   658                 part.position.y += body.velocity.y;
   -1   659             }
   -1   660 
   -1   661             if (body.angularVelocity !== 0) {
   -1   662                 Vertices.rotate(part.vertices, body.angularVelocity, body.position);
   -1   663                 Axes.rotate(part.axes, body.angularVelocity);
   -1   664                 if (i > 0) {
   -1   665                     Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position);
   -1   666                 }
   -1   667             }
   -1   668 
   -1   669             Bounds.update(part.bounds, part.vertices, body.velocity);
   -1   670         }
   -1   671     };
   -1   672 
   -1   673     /**
   -1   674      * Applies a force to a body from a given world-space position, including resulting torque.
   -1   675      * @method applyForce
   -1   676      * @param {body} body
   -1   677      * @param {vector} position
   -1   678      * @param {vector} force
   -1   679      */
   -1   680     Body.applyForce = function(body, position, force) {
   -1   681         body.force.x += force.x;
   -1   682         body.force.y += force.y;
   -1   683         var offset = { x: position.x - body.position.x, y: position.y - body.position.y };
   -1   684         body.torque += offset.x * force.y - offset.y * force.x;
   -1   685     };
   -1   686 
   -1   687     /**
   -1   688      * Returns the sums of the properties of all compound parts of the parent body.
   -1   689      * @method _totalProperties
   -1   690      * @private
   -1   691      * @param {body} body
   -1   692      * @return {}
   -1   693      */
   -1   694     Body._totalProperties = function(body) {
   -1   695         // from equations at:
   -1   696         // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory
   -1   697         // http://output.to/sideway/default.asp?qno=121100087
   -1   698 
   -1   699         var properties = {
   -1   700             mass: 0,
   -1   701             area: 0,
   -1   702             inertia: 0,
   -1   703             centre: { x: 0, y: 0 }
   -1   704         };
   -1   705 
   -1   706         // sum the properties of all compound parts of the parent body
   -1   707         for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) {
   -1   708             var part = body.parts[i],
   -1   709                 mass = part.mass !== Infinity ? part.mass : 1;
   -1   710 
   -1   711             properties.mass += mass;
   -1   712             properties.area += part.area;
   -1   713             properties.inertia += part.inertia;
   -1   714             properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass));
   -1   715         }
   -1   716 
   -1   717         properties.centre = Vector.div(properties.centre, properties.mass);
   -1   718 
   -1   719         return properties;
   -1   720     };
   -1   721 
   -1   722     /*
   -1   723     *
   -1   724     *  Events Documentation
   -1   725     *
   -1   726     */
   -1   727 
   -1   728     /**
   -1   729     * Fired when a body starts sleeping (where `this` is the body).
   -1   730     *
   -1   731     * @event sleepStart
   -1   732     * @this {body} The body that has started sleeping
   -1   733     * @param {} event An event object
   -1   734     * @param {} event.source The source object of the event
   -1   735     * @param {} event.name The name of the event
   -1   736     */
   -1   737 
   -1   738     /**
   -1   739     * Fired when a body ends sleeping (where `this` is the body).
   -1   740     *
   -1   741     * @event sleepEnd
   -1   742     * @this {body} The body that has ended sleeping
   -1   743     * @param {} event An event object
   -1   744     * @param {} event.source The source object of the event
   -1   745     * @param {} event.name The name of the event
   -1   746     */
   -1   747 
   -1   748     /*
   -1   749     *
   -1   750     *  Properties Documentation
   -1   751     *
   -1   752     */
   -1   753 
   -1   754     /**
   -1   755      * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`.
   -1   756      *
   -1   757      * @property id
   -1   758      * @type number
   -1   759      */
   -1   760 
   -1   761     /**
   -1   762      * A `String` denoting the type of object.
   -1   763      *
   -1   764      * @property type
   -1   765      * @type string
   -1   766      * @default "body"
   -1   767      * @readOnly
   -1   768      */
   -1   769 
   -1   770     /**
   -1   771      * An arbitrary `String` name to help the user identify and manage bodies.
   -1   772      *
   -1   773      * @property label
   -1   774      * @type string
   -1   775      * @default "Body"
   -1   776      */
   -1   777 
   -1   778     /**
   -1   779      * An array of bodies that make up this body. 
   -1   780      * The first body in the array must always be a self reference to the current body instance.
   -1   781      * All bodies in the `parts` array together form a single rigid compound body.
   -1   782      * Parts are allowed to overlap, have gaps or holes or even form concave bodies.
   -1   783      * Parts themselves should never be added to a `World`, only the parent body should be.
   -1   784      * Use `Body.setParts` when setting parts to ensure correct updates of all properties.
   -1   785      *
   -1   786      * @property parts
   -1   787      * @type body[]
   -1   788      */
   -1   789 
   -1   790     /**
   -1   791      * An object reserved for storing plugin-specific properties.
   -1   792      *
   -1   793      * @property plugin
   -1   794      * @type {}
   -1   795      */
   -1   796 
   -1   797     /**
   -1   798      * A self reference if the body is _not_ a part of another body.
   -1   799      * Otherwise this is a reference to the body that this is a part of.
   -1   800      * See `body.parts`.
   -1   801      *
   -1   802      * @property parent
   -1   803      * @type body
   -1   804      */
   -1   805 
   -1   806     /**
   -1   807      * A `Number` specifying the angle of the body, in radians.
   -1   808      *
   -1   809      * @property angle
   -1   810      * @type number
   -1   811      * @default 0
   -1   812      */
   -1   813 
   -1   814     /**
   -1   815      * An array of `Vector` objects that specify the convex hull of the rigid body.
   -1   816      * These should be provided about the origin `(0, 0)`. E.g.
   -1   817      *
   -1   818      *     [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]
   -1   819      *
   -1   820      * When passed via `Body.create`, the vertices are translated relative to `body.position` (i.e. world-space, and constantly updated by `Body.update` during simulation).
   -1   821      * The `Vector` objects are also augmented with additional properties required for efficient collision detection. 
   -1   822      *
   -1   823      * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`).
   -1   824      * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices.
   -1   825      *
   -1   826      * @property vertices
   -1   827      * @type vector[]
   -1   828      */
   -1   829 
   -1   830     /**
   -1   831      * A `Vector` that specifies the current world-space position of the body.
   -1   832      *
   -1   833      * @property position
   -1   834      * @type vector
   -1   835      * @default { x: 0, y: 0 }
   -1   836      */
   -1   837 
   -1   838     /**
   -1   839      * A `Vector` that specifies the force to apply in the current step. It is zeroed after every `Body.update`. See also `Body.applyForce`.
   -1   840      *
   -1   841      * @property force
   -1   842      * @type vector
   -1   843      * @default { x: 0, y: 0 }
   -1   844      */
   -1   845 
   -1   846     /**
   -1   847      * A `Number` that specifies the torque (turning force) to apply in the current step. It is zeroed after every `Body.update`.
   -1   848      *
   -1   849      * @property torque
   -1   850      * @type number
   -1   851      * @default 0
   -1   852      */
   -1   853 
   -1   854     /**
   -1   855      * A `Number` that _measures_ the current speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.velocity`).
   -1   856      *
   -1   857      * @readOnly
   -1   858      * @property speed
   -1   859      * @type number
   -1   860      * @default 0
   -1   861      */
   -1   862 
   -1   863     /**
   -1   864      * A `Number` that _measures_ the current angular speed of the body after the last `Body.update`. It is read-only and always positive (it's the magnitude of `body.angularVelocity`).
   -1   865      *
   -1   866      * @readOnly
   -1   867      * @property angularSpeed
   -1   868      * @type number
   -1   869      * @default 0
   -1   870      */
   -1   871 
   -1   872     /**
   -1   873      * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only. 
   -1   874      * If you need to modify a body's velocity directly, you should either apply a force or simply change the body's `position` (as the engine uses position-Verlet integration).
   -1   875      *
   -1   876      * @readOnly
   -1   877      * @property velocity
   -1   878      * @type vector
   -1   879      * @default { x: 0, y: 0 }
   -1   880      */
   -1   881 
   -1   882     /**
   -1   883      * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only. 
   -1   884      * If you need to modify a body's angular velocity directly, you should apply a torque or simply change the body's `angle` (as the engine uses position-Verlet integration).
   -1   885      *
   -1   886      * @readOnly
   -1   887      * @property angularVelocity
   -1   888      * @type number
   -1   889      * @default 0
   -1   890      */
   -1   891 
   -1   892     /**
   -1   893      * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed.
   -1   894      * If you need to set a body as static after its creation, you should use `Body.setStatic` as this requires more than just setting this flag.
   -1   895      *
   -1   896      * @property isStatic
   -1   897      * @type boolean
   -1   898      * @default false
   -1   899      */
   -1   900 
   -1   901     /**
   -1   902      * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically.
   -1   903      *
   -1   904      * @property isSensor
   -1   905      * @type boolean
   -1   906      * @default false
   -1   907      */
   -1   908 
   -1   909     /**
   -1   910      * A flag that indicates whether the body is considered sleeping. A sleeping body acts similar to a static body, except it is only temporary and can be awoken.
   -1   911      * If you need to set a body as sleeping, you should use `Sleeping.set` as this requires more than just setting this flag.
   -1   912      *
   -1   913      * @property isSleeping
   -1   914      * @type boolean
   -1   915      * @default false
   -1   916      */
   -1   917 
   -1   918     /**
   -1   919      * A `Number` that _measures_ the amount of movement a body currently has (a combination of `speed` and `angularSpeed`). It is read-only and always positive.
   -1   920      * It is used and updated by the `Matter.Sleeping` module during simulation to decide if a body has come to rest.
   -1   921      *
   -1   922      * @readOnly
   -1   923      * @property motion
   -1   924      * @type number
   -1   925      * @default 0
   -1   926      */
   -1   927 
   -1   928     /**
   -1   929      * A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping by the `Matter.Sleeping` module (if sleeping is enabled by the engine).
   -1   930      *
   -1   931      * @property sleepThreshold
   -1   932      * @type number
   -1   933      * @default 60
   -1   934      */
   -1   935 
   -1   936     /**
   -1   937      * A `Number` that defines the density of the body, that is its mass per unit area.
   -1   938      * If you pass the density via `Body.create` the `mass` property is automatically calculated for you based on the size (area) of the object.
   -1   939      * This is generally preferable to simply setting mass and allows for more intuitive definition of materials (e.g. rock has a higher density than wood).
   -1   940      *
   -1   941      * @property density
   -1   942      * @type number
   -1   943      * @default 0.001
   -1   944      */
   -1   945 
   -1   946     /**
   -1   947      * A `Number` that defines the mass of the body, although it may be more appropriate to specify the `density` property instead.
   -1   948      * If you modify this value, you must also modify the `body.inverseMass` property (`1 / mass`).
   -1   949      *
   -1   950      * @property mass
   -1   951      * @type number
   -1   952      */
   -1   953 
   -1   954     /**
   -1   955      * A `Number` that defines the inverse mass of the body (`1 / mass`).
   -1   956      * If you modify this value, you must also modify the `body.mass` property.
   -1   957      *
   -1   958      * @property inverseMass
   -1   959      * @type number
   -1   960      */
   -1   961 
   -1   962     /**
   -1   963      * A `Number` that defines the moment of inertia (i.e. second moment of area) of the body.
   -1   964      * It is automatically calculated from the given convex hull (`vertices` array) and density in `Body.create`.
   -1   965      * If you modify this value, you must also modify the `body.inverseInertia` property (`1 / inertia`).
   -1   966      *
   -1   967      * @property inertia
   -1   968      * @type number
   -1   969      */
   -1   970 
   -1   971     /**
   -1   972      * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`).
   -1   973      * If you modify this value, you must also modify the `body.inertia` property.
   -1   974      *
   -1   975      * @property inverseInertia
   -1   976      * @type number
   -1   977      */
   -1   978 
   -1   979     /**
   -1   980      * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`.
   -1   981      * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur. 
   -1   982      * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy.
   -1   983      * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula:
   -1   984      *
   -1   985      *     Math.max(bodyA.restitution, bodyB.restitution)
   -1   986      *
   -1   987      * @property restitution
   -1   988      * @type number
   -1   989      * @default 0
   -1   990      */
   -1   991 
   -1   992     /**
   -1   993      * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`.
   -1   994      * A value of `0` means that the body may slide indefinitely.
   -1   995      * A value of `1` means the body may come to a stop almost instantly after a force is applied.
   -1   996      *
   -1   997      * The effects of the value may be non-linear. 
   -1   998      * High values may be unstable depending on the body.
   -1   999      * The engine uses a Coulomb friction model including static and kinetic friction.
   -1  1000      * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula:
   -1  1001      *
   -1  1002      *     Math.min(bodyA.friction, bodyB.friction)
   -1  1003      *
   -1  1004      * @property friction
   -1  1005      * @type number
   -1  1006      * @default 0.1
   -1  1007      */
   -1  1008 
   -1  1009     /**
   -1  1010      * A `Number` that defines the static friction of the body (in the Coulomb friction model). 
   -1  1011      * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used.
   -1  1012      * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary.
   -1  1013      * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction.
   -1  1014      *
   -1  1015      * @property frictionStatic
   -1  1016      * @type number
   -1  1017      * @default 0.5
   -1  1018      */
   -1  1019 
   -1  1020     /**
   -1  1021      * A `Number` that defines the air friction of the body (air resistance). 
   -1  1022      * A value of `0` means the body will never slow as it moves through space.
   -1  1023      * The higher the value, the faster a body slows when moving through space.
   -1  1024      * The effects of the value are non-linear. 
   -1  1025      *
   -1  1026      * @property frictionAir
   -1  1027      * @type number
   -1  1028      * @default 0.01
   -1  1029      */
   -1  1030 
   -1  1031     /**
   -1  1032      * An `Object` that specifies the collision filtering properties of this body.
   -1  1033      *
   -1  1034      * Collisions between two bodies will obey the following rules:
   -1  1035      * - If the two bodies have the same non-zero value of `collisionFilter.group`,
   -1  1036      *   they will always collide if the value is positive, and they will never collide
   -1  1037      *   if the value is negative.
   -1  1038      * - If the two bodies have different values of `collisionFilter.group` or if one
   -1  1039      *   (or both) of the bodies has a value of 0, then the category/mask rules apply as follows:
   -1  1040      *
   -1  1041      * Each body belongs to a collision category, given by `collisionFilter.category`. This
   -1  1042      * value is used as a bit field and the category should have only one bit set, meaning that
   -1  1043      * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32
   -1  1044      * different collision categories available.
   -1  1045      *
   -1  1046      * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies
   -1  1047      * the categories it collides with (the value is the bitwise AND value of all these categories).
   -1  1048      *
   -1  1049      * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's
   -1  1050      * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0`
   -1  1051      * are both true.
   -1  1052      *
   -1  1053      * @property collisionFilter
   -1  1054      * @type object
   -1  1055      */
   -1  1056 
   -1  1057     /**
   -1  1058      * An Integer `Number`, that specifies the collision group this body belongs to.
   -1  1059      * See `body.collisionFilter` for more information.
   -1  1060      *
   -1  1061      * @property collisionFilter.group
   -1  1062      * @type object
   -1  1063      * @default 0
   -1  1064      */
   -1  1065 
   -1  1066     /**
   -1  1067      * A bit field that specifies the collision category this body belongs to.
   -1  1068      * The category value should have only one bit set, for example `0x0001`.
   -1  1069      * This means there are up to 32 unique collision categories available.
   -1  1070      * See `body.collisionFilter` for more information.
   -1  1071      *
   -1  1072      * @property collisionFilter.category
   -1  1073      * @type object
   -1  1074      * @default 1
   -1  1075      */
   -1  1076 
   -1  1077     /**
   -1  1078      * A bit mask that specifies the collision categories this body may collide with.
   -1  1079      * See `body.collisionFilter` for more information.
   -1  1080      *
   -1  1081      * @property collisionFilter.mask
   -1  1082      * @type object
   -1  1083      * @default -1
   -1  1084      */
   -1  1085 
   -1  1086     /**
   -1  1087      * A `Number` that specifies a tolerance on how far a body is allowed to 'sink' or rotate into other bodies.
   -1  1088      * Avoid changing this value unless you understand the purpose of `slop` in physics engines.
   -1  1089      * The default should generally suffice, although very large bodies may require larger values for stable stacking.
   -1  1090      *
   -1  1091      * @property slop
   -1  1092      * @type number
   -1  1093      * @default 0.05
   -1  1094      */
   -1  1095 
   -1  1096     /**
   -1  1097      * A `Number` that allows per-body time scaling, e.g. a force-field where bodies inside are in slow-motion, while others are at full speed.
   -1  1098      *
   -1  1099      * @property timeScale
   -1  1100      * @type number
   -1  1101      * @default 1
   -1  1102      */
   -1  1103 
   -1  1104     /**
   -1  1105      * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
   -1  1106      *
   -1  1107      * @property render
   -1  1108      * @type object
   -1  1109      */
   -1  1110 
   -1  1111     /**
   -1  1112      * A flag that indicates if the body should be rendered.
   -1  1113      *
   -1  1114      * @property render.visible
   -1  1115      * @type boolean
   -1  1116      * @default true
   -1  1117      */
   -1  1118 
   -1  1119     /**
   -1  1120      * Sets the opacity to use when rendering.
   -1  1121      *
   -1  1122      * @property render.opacity
   -1  1123      * @type number
   -1  1124      * @default 1
   -1  1125     */
   -1  1126 
   -1  1127     /**
   -1  1128      * An `Object` that defines the sprite properties to use when rendering, if any.
   -1  1129      *
   -1  1130      * @property render.sprite
   -1  1131      * @type object
   -1  1132      */
   -1  1133 
   -1  1134     /**
   -1  1135      * An `String` that defines the path to the image to use as the sprite texture, if any.
   -1  1136      *
   -1  1137      * @property render.sprite.texture
   -1  1138      * @type string
   -1  1139      */
   -1  1140      
   -1  1141     /**
   -1  1142      * A `Number` that defines the scaling in the x-axis for the sprite, if any.
   -1  1143      *
   -1  1144      * @property render.sprite.xScale
   -1  1145      * @type number
   -1  1146      * @default 1
   -1  1147      */
   -1  1148 
   -1  1149     /**
   -1  1150      * A `Number` that defines the scaling in the y-axis for the sprite, if any.
   -1  1151      *
   -1  1152      * @property render.sprite.yScale
   -1  1153      * @type number
   -1  1154      * @default 1
   -1  1155      */
   -1  1156 
   -1  1157      /**
   -1  1158       * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width).
   -1  1159       *
   -1  1160       * @property render.sprite.xOffset
   -1  1161       * @type number
   -1  1162       * @default 0
   -1  1163       */
   -1  1164 
   -1  1165      /**
   -1  1166       * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height).
   -1  1167       *
   -1  1168       * @property render.sprite.yOffset
   -1  1169       * @type number
   -1  1170       * @default 0
   -1  1171       */
   -1  1172 
   -1  1173     /**
   -1  1174      * A `Number` that defines the line width to use when rendering the body outline (if a sprite is not defined).
   -1  1175      * A value of `0` means no outline will be rendered.
   -1  1176      *
   -1  1177      * @property render.lineWidth
   -1  1178      * @type number
   -1  1179      * @default 0
   -1  1180      */
   -1  1181 
   -1  1182     /**
   -1  1183      * A `String` that defines the fill style to use when rendering the body (if a sprite is not defined).
   -1  1184      * It is the same as when using a canvas, so it accepts CSS style property values.
   -1  1185      *
   -1  1186      * @property render.fillStyle
   -1  1187      * @type string
   -1  1188      * @default a random colour
   -1  1189      */
   -1  1190 
   -1  1191     /**
   -1  1192      * A `String` that defines the stroke style to use when rendering the body outline (if a sprite is not defined).
   -1  1193      * It is the same as when using a canvas, so it accepts CSS style property values.
   -1  1194      *
   -1  1195      * @property render.strokeStyle
   -1  1196      * @type string
   -1  1197      * @default a random colour
   -1  1198      */
   -1  1199 
   -1  1200     /**
   -1  1201      * An array of unique axis vectors (edge normals) used for collision detection.
   -1  1202      * These are automatically calculated from the given convex hull (`vertices` array) in `Body.create`.
   -1  1203      * They are constantly updated by `Body.update` during the simulation.
   -1  1204      *
   -1  1205      * @property axes
   -1  1206      * @type vector[]
   -1  1207      */
   -1  1208      
   -1  1209     /**
   -1  1210      * A `Number` that _measures_ the area of the body's convex hull, calculated at creation by `Body.create`.
   -1  1211      *
   -1  1212      * @property area
   -1  1213      * @type string
   -1  1214      * @default 
   -1  1215      */
   -1  1216 
   -1  1217     /**
   -1  1218      * A `Bounds` object that defines the AABB region for the body.
   -1  1219      * It is automatically calculated from the given convex hull (`vertices` array) in `Body.create` and constantly updated by `Body.update` during simulation.
   -1  1220      *
   -1  1221      * @property bounds
   -1  1222      * @type bounds
   -1  1223      */
   -1  1224 
   -1  1225 })();
   -1  1226 
   -1  1227 },{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29,"../render/Render":31}],2:[function(_dereq_,module,exports){
   -1  1228 /**
   -1  1229 * The `Matter.Composite` module contains methods for creating and manipulating composite bodies.
   -1  1230 * A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure.
   -1  1231 * It is important to use the functions in this module to modify composites, rather than directly modifying their properties.
   -1  1232 * Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`.
   -1  1233 *
   -1  1234 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  1235 *
   -1  1236 * @class Composite
   -1  1237 */
   -1  1238 
   -1  1239 var Composite = {};
   -1  1240 
   -1  1241 module.exports = Composite;
   -1  1242 
   -1  1243 var Events = _dereq_('../core/Events');
   -1  1244 var Common = _dereq_('../core/Common');
   -1  1245 var Bounds = _dereq_('../geometry/Bounds');
   -1  1246 var Body = _dereq_('./Body');
   -1  1247 
   -1  1248 (function() {
   -1  1249 
   -1  1250     /**
   -1  1251      * Creates a new composite. The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  1252      * See the properites section below for detailed information on what you can pass via the `options` object.
   -1  1253      * @method create
   -1  1254      * @param {} [options]
   -1  1255      * @return {composite} A new composite
   -1  1256      */
   -1  1257     Composite.create = function(options) {
   -1  1258         return Common.extend({ 
   -1  1259             id: Common.nextId(),
   -1  1260             type: 'composite',
   -1  1261             parent: null,
   -1  1262             isModified: false,
   -1  1263             bodies: [], 
   -1  1264             constraints: [], 
   -1  1265             composites: [],
   -1  1266             label: 'Composite',
   -1  1267             plugin: {}
   -1  1268         }, options);
   -1  1269     };
   -1  1270 
   -1  1271     /**
   -1  1272      * Sets the composite's `isModified` flag. 
   -1  1273      * If `updateParents` is true, all parents will be set (default: false).
   -1  1274      * If `updateChildren` is true, all children will be set (default: false).
   -1  1275      * @method setModified
   -1  1276      * @param {composite} composite
   -1  1277      * @param {boolean} isModified
   -1  1278      * @param {boolean} [updateParents=false]
   -1  1279      * @param {boolean} [updateChildren=false]
   -1  1280      */
   -1  1281     Composite.setModified = function(composite, isModified, updateParents, updateChildren) {
   -1  1282         composite.isModified = isModified;
   -1  1283 
   -1  1284         if (updateParents && composite.parent) {
   -1  1285             Composite.setModified(composite.parent, isModified, updateParents, updateChildren);
   -1  1286         }
   -1  1287 
   -1  1288         if (updateChildren) {
   -1  1289             for(var i = 0; i < composite.composites.length; i++) {
   -1  1290                 var childComposite = composite.composites[i];
   -1  1291                 Composite.setModified(childComposite, isModified, updateParents, updateChildren);
   -1  1292             }
   -1  1293         }
   -1  1294     };
   -1  1295 
   -1  1296     /**
   -1  1297      * Generic add function. Adds one or many body(s), constraint(s) or a composite(s) to the given composite.
   -1  1298      * Triggers `beforeAdd` and `afterAdd` events on the `composite`.
   -1  1299      * @method add
   -1  1300      * @param {composite} composite
   -1  1301      * @param {} object
   -1  1302      * @return {composite} The original composite with the objects added
   -1  1303      */
   -1  1304     Composite.add = function(composite, object) {
   -1  1305         var objects = [].concat(object);
   -1  1306 
   -1  1307         Events.trigger(composite, 'beforeAdd', { object: object });
   -1  1308 
   -1  1309         for (var i = 0; i < objects.length; i++) {
   -1  1310             var obj = objects[i];
   -1  1311 
   -1  1312             switch (obj.type) {
   -1  1313 
   -1  1314             case 'body':
   -1  1315                 // skip adding compound parts
   -1  1316                 if (obj.parent !== obj) {
   -1  1317                     Common.warn('Composite.add: skipped adding a compound body part (you must add its parent instead)');
   -1  1318                     break;
   -1  1319                 }
   -1  1320 
   -1  1321                 Composite.addBody(composite, obj);
   -1  1322                 break;
   -1  1323             case 'constraint':
   -1  1324                 Composite.addConstraint(composite, obj);
   -1  1325                 break;
   -1  1326             case 'composite':
   -1  1327                 Composite.addComposite(composite, obj);
   -1  1328                 break;
   -1  1329             case 'mouseConstraint':
   -1  1330                 Composite.addConstraint(composite, obj.constraint);
   -1  1331                 break;
   -1  1332 
   -1  1333             }
   -1  1334         }
   -1  1335 
   -1  1336         Events.trigger(composite, 'afterAdd', { object: object });
   -1  1337 
   -1  1338         return composite;
   -1  1339     };
   -1  1340 
   -1  1341     /**
   -1  1342      * Generic remove function. Removes one or many body(s), constraint(s) or a composite(s) to the given composite.
   -1  1343      * Optionally searching its children recursively.
   -1  1344      * Triggers `beforeRemove` and `afterRemove` events on the `composite`.
   -1  1345      * @method remove
   -1  1346      * @param {composite} composite
   -1  1347      * @param {} object
   -1  1348      * @param {boolean} [deep=false]
   -1  1349      * @return {composite} The original composite with the objects removed
   -1  1350      */
   -1  1351     Composite.remove = function(composite, object, deep) {
   -1  1352         var objects = [].concat(object);
   -1  1353 
   -1  1354         Events.trigger(composite, 'beforeRemove', { object: object });
   -1  1355 
   -1  1356         for (var i = 0; i < objects.length; i++) {
   -1  1357             var obj = objects[i];
   -1  1358 
   -1  1359             switch (obj.type) {
   -1  1360 
   -1  1361             case 'body':
   -1  1362                 Composite.removeBody(composite, obj, deep);
   -1  1363                 break;
   -1  1364             case 'constraint':
   -1  1365                 Composite.removeConstraint(composite, obj, deep);
   -1  1366                 break;
   -1  1367             case 'composite':
   -1  1368                 Composite.removeComposite(composite, obj, deep);
   -1  1369                 break;
   -1  1370             case 'mouseConstraint':
   -1  1371                 Composite.removeConstraint(composite, obj.constraint);
   -1  1372                 break;
   -1  1373 
   -1  1374             }
   -1  1375         }
   -1  1376 
   -1  1377         Events.trigger(composite, 'afterRemove', { object: object });
   -1  1378 
   -1  1379         return composite;
   -1  1380     };
   -1  1381 
   -1  1382     /**
   -1  1383      * Adds a composite to the given composite.
   -1  1384      * @private
   -1  1385      * @method addComposite
   -1  1386      * @param {composite} compositeA
   -1  1387      * @param {composite} compositeB
   -1  1388      * @return {composite} The original compositeA with the objects from compositeB added
   -1  1389      */
   -1  1390     Composite.addComposite = function(compositeA, compositeB) {
   -1  1391         compositeA.composites.push(compositeB);
   -1  1392         compositeB.parent = compositeA;
   -1  1393         Composite.setModified(compositeA, true, true, false);
   -1  1394         return compositeA;
   -1  1395     };
   -1  1396 
   -1  1397     /**
   -1  1398      * Removes a composite from the given composite, and optionally searching its children recursively.
   -1  1399      * @private
   -1  1400      * @method removeComposite
   -1  1401      * @param {composite} compositeA
   -1  1402      * @param {composite} compositeB
   -1  1403      * @param {boolean} [deep=false]
   -1  1404      * @return {composite} The original compositeA with the composite removed
   -1  1405      */
   -1  1406     Composite.removeComposite = function(compositeA, compositeB, deep) {
   -1  1407         var position = Common.indexOf(compositeA.composites, compositeB);
   -1  1408         if (position !== -1) {
   -1  1409             Composite.removeCompositeAt(compositeA, position);
   -1  1410             Composite.setModified(compositeA, true, true, false);
   -1  1411         }
   -1  1412 
   -1  1413         if (deep) {
   -1  1414             for (var i = 0; i < compositeA.composites.length; i++){
   -1  1415                 Composite.removeComposite(compositeA.composites[i], compositeB, true);
   -1  1416             }
   -1  1417         }
   -1  1418 
   -1  1419         return compositeA;
   -1  1420     };
   -1  1421 
   -1  1422     /**
   -1  1423      * Removes a composite from the given composite.
   -1  1424      * @private
   -1  1425      * @method removeCompositeAt
   -1  1426      * @param {composite} composite
   -1  1427      * @param {number} position
   -1  1428      * @return {composite} The original composite with the composite removed
   -1  1429      */
   -1  1430     Composite.removeCompositeAt = function(composite, position) {
   -1  1431         composite.composites.splice(position, 1);
   -1  1432         Composite.setModified(composite, true, true, false);
   -1  1433         return composite;
   -1  1434     };
   -1  1435 
   -1  1436     /**
   -1  1437      * Adds a body to the given composite.
   -1  1438      * @private
   -1  1439      * @method addBody
   -1  1440      * @param {composite} composite
   -1  1441      * @param {body} body
   -1  1442      * @return {composite} The original composite with the body added
   -1  1443      */
   -1  1444     Composite.addBody = function(composite, body) {
   -1  1445         composite.bodies.push(body);
   -1  1446         Composite.setModified(composite, true, true, false);
   -1  1447         return composite;
   -1  1448     };
   -1  1449 
   -1  1450     /**
   -1  1451      * Removes a body from the given composite, and optionally searching its children recursively.
   -1  1452      * @private
   -1  1453      * @method removeBody
   -1  1454      * @param {composite} composite
   -1  1455      * @param {body} body
   -1  1456      * @param {boolean} [deep=false]
   -1  1457      * @return {composite} The original composite with the body removed
   -1  1458      */
   -1  1459     Composite.removeBody = function(composite, body, deep) {
   -1  1460         var position = Common.indexOf(composite.bodies, body);
   -1  1461         if (position !== -1) {
   -1  1462             Composite.removeBodyAt(composite, position);
   -1  1463             Composite.setModified(composite, true, true, false);
   -1  1464         }
   -1  1465 
   -1  1466         if (deep) {
   -1  1467             for (var i = 0; i < composite.composites.length; i++){
   -1  1468                 Composite.removeBody(composite.composites[i], body, true);
   -1  1469             }
   -1  1470         }
   -1  1471 
   -1  1472         return composite;
   -1  1473     };
   -1  1474 
   -1  1475     /**
   -1  1476      * Removes a body from the given composite.
   -1  1477      * @private
   -1  1478      * @method removeBodyAt
   -1  1479      * @param {composite} composite
   -1  1480      * @param {number} position
   -1  1481      * @return {composite} The original composite with the body removed
   -1  1482      */
   -1  1483     Composite.removeBodyAt = function(composite, position) {
   -1  1484         composite.bodies.splice(position, 1);
   -1  1485         Composite.setModified(composite, true, true, false);
   -1  1486         return composite;
   -1  1487     };
   -1  1488 
   -1  1489     /**
   -1  1490      * Adds a constraint to the given composite.
   -1  1491      * @private
   -1  1492      * @method addConstraint
   -1  1493      * @param {composite} composite
   -1  1494      * @param {constraint} constraint
   -1  1495      * @return {composite} The original composite with the constraint added
   -1  1496      */
   -1  1497     Composite.addConstraint = function(composite, constraint) {
   -1  1498         composite.constraints.push(constraint);
   -1  1499         Composite.setModified(composite, true, true, false);
   -1  1500         return composite;
   -1  1501     };
   -1  1502 
   -1  1503     /**
   -1  1504      * Removes a constraint from the given composite, and optionally searching its children recursively.
   -1  1505      * @private
   -1  1506      * @method removeConstraint
   -1  1507      * @param {composite} composite
   -1  1508      * @param {constraint} constraint
   -1  1509      * @param {boolean} [deep=false]
   -1  1510      * @return {composite} The original composite with the constraint removed
   -1  1511      */
   -1  1512     Composite.removeConstraint = function(composite, constraint, deep) {
   -1  1513         var position = Common.indexOf(composite.constraints, constraint);
   -1  1514         if (position !== -1) {
   -1  1515             Composite.removeConstraintAt(composite, position);
   -1  1516         }
   -1  1517 
   -1  1518         if (deep) {
   -1  1519             for (var i = 0; i < composite.composites.length; i++){
   -1  1520                 Composite.removeConstraint(composite.composites[i], constraint, true);
   -1  1521             }
   -1  1522         }
   -1  1523 
   -1  1524         return composite;
   -1  1525     };
   -1  1526 
   -1  1527     /**
   -1  1528      * Removes a body from the given composite.
   -1  1529      * @private
   -1  1530      * @method removeConstraintAt
   -1  1531      * @param {composite} composite
   -1  1532      * @param {number} position
   -1  1533      * @return {composite} The original composite with the constraint removed
   -1  1534      */
   -1  1535     Composite.removeConstraintAt = function(composite, position) {
   -1  1536         composite.constraints.splice(position, 1);
   -1  1537         Composite.setModified(composite, true, true, false);
   -1  1538         return composite;
   -1  1539     };
   -1  1540 
   -1  1541     /**
   -1  1542      * Removes all bodies, constraints and composites from the given composite.
   -1  1543      * Optionally clearing its children recursively.
   -1  1544      * @method clear
   -1  1545      * @param {composite} composite
   -1  1546      * @param {boolean} keepStatic
   -1  1547      * @param {boolean} [deep=false]
   -1  1548      */
   -1  1549     Composite.clear = function(composite, keepStatic, deep) {
   -1  1550         if (deep) {
   -1  1551             for (var i = 0; i < composite.composites.length; i++){
   -1  1552                 Composite.clear(composite.composites[i], keepStatic, true);
   -1  1553             }
   -1  1554         }
   -1  1555         
   -1  1556         if (keepStatic) {
   -1  1557             composite.bodies = composite.bodies.filter(function(body) { return body.isStatic; });
   -1  1558         } else {
   -1  1559             composite.bodies.length = 0;
   -1  1560         }
   -1  1561 
   -1  1562         composite.constraints.length = 0;
   -1  1563         composite.composites.length = 0;
   -1  1564         Composite.setModified(composite, true, true, false);
   -1  1565 
   -1  1566         return composite;
   -1  1567     };
   -1  1568 
   -1  1569     /**
   -1  1570      * Returns all bodies in the given composite, including all bodies in its children, recursively.
   -1  1571      * @method allBodies
   -1  1572      * @param {composite} composite
   -1  1573      * @return {body[]} All the bodies
   -1  1574      */
   -1  1575     Composite.allBodies = function(composite) {
   -1  1576         var bodies = [].concat(composite.bodies);
   -1  1577 
   -1  1578         for (var i = 0; i < composite.composites.length; i++)
   -1  1579             bodies = bodies.concat(Composite.allBodies(composite.composites[i]));
   -1  1580 
   -1  1581         return bodies;
   -1  1582     };
   -1  1583 
   -1  1584     /**
   -1  1585      * Returns all constraints in the given composite, including all constraints in its children, recursively.
   -1  1586      * @method allConstraints
   -1  1587      * @param {composite} composite
   -1  1588      * @return {constraint[]} All the constraints
   -1  1589      */
   -1  1590     Composite.allConstraints = function(composite) {
   -1  1591         var constraints = [].concat(composite.constraints);
   -1  1592 
   -1  1593         for (var i = 0; i < composite.composites.length; i++)
   -1  1594             constraints = constraints.concat(Composite.allConstraints(composite.composites[i]));
   -1  1595 
   -1  1596         return constraints;
   -1  1597     };
   -1  1598 
   -1  1599     /**
   -1  1600      * Returns all composites in the given composite, including all composites in its children, recursively.
   -1  1601      * @method allComposites
   -1  1602      * @param {composite} composite
   -1  1603      * @return {composite[]} All the composites
   -1  1604      */
   -1  1605     Composite.allComposites = function(composite) {
   -1  1606         var composites = [].concat(composite.composites);
   -1  1607 
   -1  1608         for (var i = 0; i < composite.composites.length; i++)
   -1  1609             composites = composites.concat(Composite.allComposites(composite.composites[i]));
   -1  1610 
   -1  1611         return composites;
   -1  1612     };
   -1  1613 
   -1  1614     /**
   -1  1615      * Searches the composite recursively for an object matching the type and id supplied, null if not found.
   -1  1616      * @method get
   -1  1617      * @param {composite} composite
   -1  1618      * @param {number} id
   -1  1619      * @param {string} type
   -1  1620      * @return {object} The requested object, if found
   -1  1621      */
   -1  1622     Composite.get = function(composite, id, type) {
   -1  1623         var objects,
   -1  1624             object;
   -1  1625 
   -1  1626         switch (type) {
   -1  1627         case 'body':
   -1  1628             objects = Composite.allBodies(composite);
   -1  1629             break;
   -1  1630         case 'constraint':
   -1  1631             objects = Composite.allConstraints(composite);
   -1  1632             break;
   -1  1633         case 'composite':
   -1  1634             objects = Composite.allComposites(composite).concat(composite);
   -1  1635             break;
   -1  1636         }
   -1  1637 
   -1  1638         if (!objects)
   -1  1639             return null;
   -1  1640 
   -1  1641         object = objects.filter(function(object) { 
   -1  1642             return object.id.toString() === id.toString(); 
   -1  1643         });
   -1  1644 
   -1  1645         return object.length === 0 ? null : object[0];
   -1  1646     };
   -1  1647 
   -1  1648     /**
   -1  1649      * Moves the given object(s) from compositeA to compositeB (equal to a remove followed by an add).
   -1  1650      * @method move
   -1  1651      * @param {compositeA} compositeA
   -1  1652      * @param {object[]} objects
   -1  1653      * @param {compositeB} compositeB
   -1  1654      * @return {composite} Returns compositeA
   -1  1655      */
   -1  1656     Composite.move = function(compositeA, objects, compositeB) {
   -1  1657         Composite.remove(compositeA, objects);
   -1  1658         Composite.add(compositeB, objects);
   -1  1659         return compositeA;
   -1  1660     };
   -1  1661 
   -1  1662     /**
   -1  1663      * Assigns new ids for all objects in the composite, recursively.
   -1  1664      * @method rebase
   -1  1665      * @param {composite} composite
   -1  1666      * @return {composite} Returns composite
   -1  1667      */
   -1  1668     Composite.rebase = function(composite) {
   -1  1669         var objects = Composite.allBodies(composite)
   -1  1670                         .concat(Composite.allConstraints(composite))
   -1  1671                         .concat(Composite.allComposites(composite));
   -1  1672 
   -1  1673         for (var i = 0; i < objects.length; i++) {
   -1  1674             objects[i].id = Common.nextId();
   -1  1675         }
   -1  1676 
   -1  1677         Composite.setModified(composite, true, true, false);
   -1  1678 
   -1  1679         return composite;
   -1  1680     };
   -1  1681 
   -1  1682     /**
   -1  1683      * Translates all children in the composite by a given vector relative to their current positions, 
   -1  1684      * without imparting any velocity.
   -1  1685      * @method translate
   -1  1686      * @param {composite} composite
   -1  1687      * @param {vector} translation
   -1  1688      * @param {bool} [recursive=true]
   -1  1689      */
   -1  1690     Composite.translate = function(composite, translation, recursive) {
   -1  1691         var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
   -1  1692 
   -1  1693         for (var i = 0; i < bodies.length; i++) {
   -1  1694             Body.translate(bodies[i], translation);
   -1  1695         }
   -1  1696 
   -1  1697         Composite.setModified(composite, true, true, false);
   -1  1698 
   -1  1699         return composite;
   -1  1700     };
   -1  1701 
   -1  1702     /**
   -1  1703      * Rotates all children in the composite by a given angle about the given point, without imparting any angular velocity.
   -1  1704      * @method rotate
   -1  1705      * @param {composite} composite
   -1  1706      * @param {number} rotation
   -1  1707      * @param {vector} point
   -1  1708      * @param {bool} [recursive=true]
   -1  1709      */
   -1  1710     Composite.rotate = function(composite, rotation, point, recursive) {
   -1  1711         var cos = Math.cos(rotation),
   -1  1712             sin = Math.sin(rotation),
   -1  1713             bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
   -1  1714 
   -1  1715         for (var i = 0; i < bodies.length; i++) {
   -1  1716             var body = bodies[i],
   -1  1717                 dx = body.position.x - point.x,
   -1  1718                 dy = body.position.y - point.y;
   -1  1719                 
   -1  1720             Body.setPosition(body, {
   -1  1721                 x: point.x + (dx * cos - dy * sin),
   -1  1722                 y: point.y + (dx * sin + dy * cos)
   -1  1723             });
   -1  1724 
   -1  1725             Body.rotate(body, rotation);
   -1  1726         }
   -1  1727 
   -1  1728         Composite.setModified(composite, true, true, false);
   -1  1729 
   -1  1730         return composite;
   -1  1731     };
   -1  1732 
   -1  1733     /**
   -1  1734      * Scales all children in the composite, including updating physical properties (mass, area, axes, inertia), from a world-space point.
   -1  1735      * @method scale
   -1  1736      * @param {composite} composite
   -1  1737      * @param {number} scaleX
   -1  1738      * @param {number} scaleY
   -1  1739      * @param {vector} point
   -1  1740      * @param {bool} [recursive=true]
   -1  1741      */
   -1  1742     Composite.scale = function(composite, scaleX, scaleY, point, recursive) {
   -1  1743         var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
   -1  1744 
   -1  1745         for (var i = 0; i < bodies.length; i++) {
   -1  1746             var body = bodies[i],
   -1  1747                 dx = body.position.x - point.x,
   -1  1748                 dy = body.position.y - point.y;
   -1  1749                 
   -1  1750             Body.setPosition(body, {
   -1  1751                 x: point.x + dx * scaleX,
   -1  1752                 y: point.y + dy * scaleY
   -1  1753             });
   -1  1754 
   -1  1755             Body.scale(body, scaleX, scaleY);
   -1  1756         }
   -1  1757 
   -1  1758         Composite.setModified(composite, true, true, false);
   -1  1759 
   -1  1760         return composite;
   -1  1761     };
   -1  1762 
   -1  1763     /**
   -1  1764      * Returns the union of the bounds of all of the composite's bodies.
   -1  1765      * @method bounds
   -1  1766      * @param {composite} composite The composite.
   -1  1767      * @returns {bounds} The composite bounds.
   -1  1768      */
   -1  1769     Composite.bounds = function(composite) {
   -1  1770         var bodies = Composite.allBodies(composite),
   -1  1771             vertices = [];
   -1  1772 
   -1  1773         for (var i = 0; i < bodies.length; i += 1) {
   -1  1774             var body = bodies[i];
   -1  1775             vertices.push(body.bounds.min, body.bounds.max);
   -1  1776         }
   -1  1777 
   -1  1778         return Bounds.create(vertices);
   -1  1779     };
   -1  1780 
   -1  1781     /*
   -1  1782     *
   -1  1783     *  Events Documentation
   -1  1784     *
   -1  1785     */
   -1  1786 
   -1  1787     /**
   -1  1788     * Fired when a call to `Composite.add` is made, before objects have been added.
   -1  1789     *
   -1  1790     * @event beforeAdd
   -1  1791     * @param {} event An event object
   -1  1792     * @param {} event.object The object(s) to be added (may be a single body, constraint, composite or a mixed array of these)
   -1  1793     * @param {} event.source The source object of the event
   -1  1794     * @param {} event.name The name of the event
   -1  1795     */
   -1  1796 
   -1  1797     /**
   -1  1798     * Fired when a call to `Composite.add` is made, after objects have been added.
   -1  1799     *
   -1  1800     * @event afterAdd
   -1  1801     * @param {} event An event object
   -1  1802     * @param {} event.object The object(s) that have been added (may be a single body, constraint, composite or a mixed array of these)
   -1  1803     * @param {} event.source The source object of the event
   -1  1804     * @param {} event.name The name of the event
   -1  1805     */
   -1  1806 
   -1  1807     /**
   -1  1808     * Fired when a call to `Composite.remove` is made, before objects have been removed.
   -1  1809     *
   -1  1810     * @event beforeRemove
   -1  1811     * @param {} event An event object
   -1  1812     * @param {} event.object The object(s) to be removed (may be a single body, constraint, composite or a mixed array of these)
   -1  1813     * @param {} event.source The source object of the event
   -1  1814     * @param {} event.name The name of the event
   -1  1815     */
   -1  1816 
   -1  1817     /**
   -1  1818     * Fired when a call to `Composite.remove` is made, after objects have been removed.
   -1  1819     *
   -1  1820     * @event afterRemove
   -1  1821     * @param {} event An event object
   -1  1822     * @param {} event.object The object(s) that have been removed (may be a single body, constraint, composite or a mixed array of these)
   -1  1823     * @param {} event.source The source object of the event
   -1  1824     * @param {} event.name The name of the event
   -1  1825     */
   -1  1826 
   -1  1827     /*
   -1  1828     *
   -1  1829     *  Properties Documentation
   -1  1830     *
   -1  1831     */
   -1  1832 
   -1  1833     /**
   -1  1834      * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
   -1  1835      *
   -1  1836      * @property id
   -1  1837      * @type number
   -1  1838      */
   -1  1839 
   -1  1840     /**
   -1  1841      * A `String` denoting the type of object.
   -1  1842      *
   -1  1843      * @property type
   -1  1844      * @type string
   -1  1845      * @default "composite"
   -1  1846      * @readOnly
   -1  1847      */
   -1  1848 
   -1  1849     /**
   -1  1850      * An arbitrary `String` name to help the user identify and manage composites.
   -1  1851      *
   -1  1852      * @property label
   -1  1853      * @type string
   -1  1854      * @default "Composite"
   -1  1855      */
   -1  1856 
   -1  1857     /**
   -1  1858      * A flag that specifies whether the composite has been modified during the current step.
   -1  1859      * Most `Matter.Composite` methods will automatically set this flag to `true` to inform the engine of changes to be handled.
   -1  1860      * If you need to change it manually, you should use the `Composite.setModified` method.
   -1  1861      *
   -1  1862      * @property isModified
   -1  1863      * @type boolean
   -1  1864      * @default false
   -1  1865      */
   -1  1866 
   -1  1867     /**
   -1  1868      * The `Composite` that is the parent of this composite. It is automatically managed by the `Matter.Composite` methods.
   -1  1869      *
   -1  1870      * @property parent
   -1  1871      * @type composite
   -1  1872      * @default null
   -1  1873      */
   -1  1874 
   -1  1875     /**
   -1  1876      * An array of `Body` that are _direct_ children of this composite.
   -1  1877      * To add or remove bodies you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
   -1  1878      * If you wish to recursively find all descendants, you should use the `Composite.allBodies` method.
   -1  1879      *
   -1  1880      * @property bodies
   -1  1881      * @type body[]
   -1  1882      * @default []
   -1  1883      */
   -1  1884 
   -1  1885     /**
   -1  1886      * An array of `Constraint` that are _direct_ children of this composite.
   -1  1887      * To add or remove constraints you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
   -1  1888      * If you wish to recursively find all descendants, you should use the `Composite.allConstraints` method.
   -1  1889      *
   -1  1890      * @property constraints
   -1  1891      * @type constraint[]
   -1  1892      * @default []
   -1  1893      */
   -1  1894 
   -1  1895     /**
   -1  1896      * An array of `Composite` that are _direct_ children of this composite.
   -1  1897      * To add or remove composites you should use `Composite.add` and `Composite.remove` methods rather than directly modifying this property.
   -1  1898      * If you wish to recursively find all descendants, you should use the `Composite.allComposites` method.
   -1  1899      *
   -1  1900      * @property composites
   -1  1901      * @type composite[]
   -1  1902      * @default []
   -1  1903      */
   -1  1904 
   -1  1905     /**
   -1  1906      * An object reserved for storing plugin-specific properties.
   -1  1907      *
   -1  1908      * @property plugin
   -1  1909      * @type {}
   -1  1910      */
   -1  1911 
   -1  1912 })();
   -1  1913 
   -1  1914 },{"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"./Body":1}],3:[function(_dereq_,module,exports){
   -1  1915 /**
   -1  1916 * The `Matter.World` module contains methods for creating and manipulating the world composite.
   -1  1917 * A `Matter.World` is a `Matter.Composite` body, which is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`.
   -1  1918 * A `Matter.World` has a few additional properties including `gravity` and `bounds`.
   -1  1919 * It is important to use the functions in the `Matter.Composite` module to modify the world composite, rather than directly modifying its properties.
   -1  1920 * There are also a few methods here that alias those in `Matter.Composite` for easier readability.
   -1  1921 *
   -1  1922 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  1923 *
   -1  1924 * @class World
   -1  1925 * @extends Composite
   -1  1926 */
   -1  1927 
   -1  1928 var World = {};
   -1  1929 
   -1  1930 module.exports = World;
   -1  1931 
   -1  1932 var Composite = _dereq_('./Composite');
   -1  1933 var Constraint = _dereq_('../constraint/Constraint');
   -1  1934 var Common = _dereq_('../core/Common');
   -1  1935 
   -1  1936 (function() {
   -1  1937 
   -1  1938     /**
   -1  1939      * Creates a new world composite. The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  1940      * See the properties section below for detailed information on what you can pass via the `options` object.
   -1  1941      * @method create
   -1  1942      * @constructor
   -1  1943      * @param {} options
   -1  1944      * @return {world} A new world
   -1  1945      */
   -1  1946     World.create = function(options) {
   -1  1947         var composite = Composite.create();
   -1  1948 
   -1  1949         var defaults = {
   -1  1950             label: 'World',
   -1  1951             gravity: {
   -1  1952                 x: 0,
   -1  1953                 y: 1,
   -1  1954                 scale: 0.001
   -1  1955             },
   -1  1956             bounds: { 
   -1  1957                 min: { x: -Infinity, y: -Infinity }, 
   -1  1958                 max: { x: Infinity, y: Infinity } 
   -1  1959             }
   -1  1960         };
   -1  1961         
   -1  1962         return Common.extend(composite, defaults, options);
   -1  1963     };
   -1  1964 
   -1  1965     /*
   -1  1966     *
   -1  1967     *  Properties Documentation
   -1  1968     *
   -1  1969     */
   -1  1970 
   -1  1971     /**
   -1  1972      * The gravity to apply on the world.
   -1  1973      *
   -1  1974      * @property gravity
   -1  1975      * @type object
   -1  1976      */
   -1  1977 
   -1  1978     /**
   -1  1979      * The gravity x component.
   -1  1980      *
   -1  1981      * @property gravity.x
   -1  1982      * @type object
   -1  1983      * @default 0
   -1  1984      */
   -1  1985 
   -1  1986     /**
   -1  1987      * The gravity y component.
   -1  1988      *
   -1  1989      * @property gravity.y
   -1  1990      * @type object
   -1  1991      * @default 1
   -1  1992      */
   -1  1993 
   -1  1994     /**
   -1  1995      * The gravity scale factor.
   -1  1996      *
   -1  1997      * @property gravity.scale
   -1  1998      * @type object
   -1  1999      * @default 0.001
   -1  2000      */
   -1  2001 
   -1  2002     /**
   -1  2003      * A `Bounds` object that defines the world bounds for collision detection.
   -1  2004      *
   -1  2005      * @property bounds
   -1  2006      * @type bounds
   -1  2007      * @default { min: { x: -Infinity, y: -Infinity }, max: { x: Infinity, y: Infinity } }
   -1  2008      */
   -1  2009 
   -1  2010     // World is a Composite body
   -1  2011     // see src/module/Outro.js for these aliases:
   -1  2012     
   -1  2013     /**
   -1  2014      * An alias for Composite.add
   -1  2015      * @method add
   -1  2016      * @param {world} world
   -1  2017      * @param {} object
   -1  2018      * @return {composite} The original world with the objects added
   -1  2019      */
   -1  2020 
   -1  2021     /**
   -1  2022      * An alias for Composite.remove
   -1  2023      * @method remove
   -1  2024      * @param {world} world
   -1  2025      * @param {} object
   -1  2026      * @param {boolean} [deep=false]
   -1  2027      * @return {composite} The original world with the objects removed
   -1  2028      */
   -1  2029 
   -1  2030     /**
   -1  2031      * An alias for Composite.clear
   -1  2032      * @method clear
   -1  2033      * @param {world} world
   -1  2034      * @param {boolean} keepStatic
   -1  2035      */
   -1  2036 
   -1  2037     /**
   -1  2038      * An alias for Composite.addComposite
   -1  2039      * @method addComposite
   -1  2040      * @param {world} world
   -1  2041      * @param {composite} composite
   -1  2042      * @return {world} The original world with the objects from composite added
   -1  2043      */
   -1  2044     
   -1  2045      /**
   -1  2046       * An alias for Composite.addBody
   -1  2047       * @method addBody
   -1  2048       * @param {world} world
   -1  2049       * @param {body} body
   -1  2050       * @return {world} The original world with the body added
   -1  2051       */
   -1  2052 
   -1  2053      /**
   -1  2054       * An alias for Composite.addConstraint
   -1  2055       * @method addConstraint
   -1  2056       * @param {world} world
   -1  2057       * @param {constraint} constraint
   -1  2058       * @return {world} The original world with the constraint added
   -1  2059       */
   -1  2060 
   -1  2061 })();
   -1  2062 
   -1  2063 },{"../constraint/Constraint":12,"../core/Common":14,"./Composite":2}],4:[function(_dereq_,module,exports){
   -1  2064 /**
   -1  2065 * The `Matter.Contact` module contains methods for creating and manipulating collision contacts.
   -1  2066 *
   -1  2067 * @class Contact
   -1  2068 */
   -1  2069 
   -1  2070 var Contact = {};
   -1  2071 
   -1  2072 module.exports = Contact;
   -1  2073 
   -1  2074 (function() {
   -1  2075 
   -1  2076     /**
   -1  2077      * Creates a new contact.
   -1  2078      * @method create
   -1  2079      * @param {vertex} vertex
   -1  2080      * @return {contact} A new contact
   -1  2081      */
   -1  2082     Contact.create = function(vertex) {
   -1  2083         return {
   -1  2084             id: Contact.id(vertex),
   -1  2085             vertex: vertex,
   -1  2086             normalImpulse: 0,
   -1  2087             tangentImpulse: 0
   -1  2088         };
   -1  2089     };
   -1  2090     
   -1  2091     /**
   -1  2092      * Generates a contact id.
   -1  2093      * @method id
   -1  2094      * @param {vertex} vertex
   -1  2095      * @return {string} Unique contactID
   -1  2096      */
   -1  2097     Contact.id = function(vertex) {
   -1  2098         return vertex.body.id + '_' + vertex.index;
   -1  2099     };
   -1  2100 
   -1  2101 })();
   -1  2102 
   -1  2103 },{}],5:[function(_dereq_,module,exports){
   -1  2104 /**
   -1  2105 * The `Matter.Detector` module contains methods for detecting collisions given a set of pairs.
   -1  2106 *
   -1  2107 * @class Detector
   -1  2108 */
   -1  2109 
   -1  2110 // TODO: speculative contacts
   -1  2111 
   -1  2112 var Detector = {};
   -1  2113 
   -1  2114 module.exports = Detector;
   -1  2115 
   -1  2116 var SAT = _dereq_('./SAT');
   -1  2117 var Pair = _dereq_('./Pair');
   -1  2118 var Bounds = _dereq_('../geometry/Bounds');
   -1  2119 
   -1  2120 (function() {
   -1  2121 
   -1  2122     /**
   -1  2123      * Finds all collisions given a list of pairs.
   -1  2124      * @method collisions
   -1  2125      * @param {pair[]} broadphasePairs
   -1  2126      * @param {engine} engine
   -1  2127      * @return {array} collisions
   -1  2128      */
   -1  2129     Detector.collisions = function(broadphasePairs, engine) {
   -1  2130         var collisions = [],
   -1  2131             pairsTable = engine.pairs.table;
   -1  2132 
   -1  2133         
   -1  2134         for (var i = 0; i < broadphasePairs.length; i++) {
   -1  2135             var bodyA = broadphasePairs[i][0], 
   -1  2136                 bodyB = broadphasePairs[i][1];
   -1  2137 
   -1  2138             if ((bodyA.isStatic || bodyA.isSleeping) && (bodyB.isStatic || bodyB.isSleeping))
   -1  2139                 continue;
   -1  2140             
   -1  2141             if (!Detector.canCollide(bodyA.collisionFilter, bodyB.collisionFilter))
   -1  2142                 continue;
   -1  2143 
   -1  2144 
   -1  2145             // mid phase
   -1  2146             if (Bounds.overlaps(bodyA.bounds, bodyB.bounds)) {
   -1  2147                 for (var j = bodyA.parts.length > 1 ? 1 : 0; j < bodyA.parts.length; j++) {
   -1  2148                     var partA = bodyA.parts[j];
   -1  2149 
   -1  2150                     for (var k = bodyB.parts.length > 1 ? 1 : 0; k < bodyB.parts.length; k++) {
   -1  2151                         var partB = bodyB.parts[k];
   -1  2152 
   -1  2153                         if ((partA === bodyA && partB === bodyB) || Bounds.overlaps(partA.bounds, partB.bounds)) {
   -1  2154                             // find a previous collision we could reuse
   -1  2155                             var pairId = Pair.id(partA, partB),
   -1  2156                                 pair = pairsTable[pairId],
   -1  2157                                 previousCollision;
   -1  2158 
   -1  2159                             if (pair && pair.isActive) {
   -1  2160                                 previousCollision = pair.collision;
   -1  2161                             } else {
   -1  2162                                 previousCollision = null;
   -1  2163                             }
   -1  2164 
   -1  2165                             // narrow phase
   -1  2166                             var collision = SAT.collides(partA, partB, previousCollision);
   -1  2167 
   -1  2168 
   -1  2169                             if (collision.collided) {
   -1  2170                                 collisions.push(collision);
   -1  2171                             }
   -1  2172                         }
   -1  2173                     }
   -1  2174                 }
   -1  2175             }
   -1  2176         }
   -1  2177 
   -1  2178         return collisions;
   -1  2179     };
   -1  2180 
   -1  2181     /**
   -1  2182      * Returns `true` if both supplied collision filters will allow a collision to occur.
   -1  2183      * See `body.collisionFilter` for more information.
   -1  2184      * @method canCollide
   -1  2185      * @param {} filterA
   -1  2186      * @param {} filterB
   -1  2187      * @return {bool} `true` if collision can occur
   -1  2188      */
   -1  2189     Detector.canCollide = function(filterA, filterB) {
   -1  2190         if (filterA.group === filterB.group && filterA.group !== 0)
   -1  2191             return filterA.group > 0;
   -1  2192 
   -1  2193         return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0;
   -1  2194     };
   -1  2195 
   -1  2196 })();
   -1  2197 
   -1  2198 },{"../geometry/Bounds":26,"./Pair":7,"./SAT":11}],6:[function(_dereq_,module,exports){
   -1  2199 /**
   -1  2200 * The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
   -1  2201 *
   -1  2202 * @class Grid
   -1  2203 */
   -1  2204 
   -1  2205 var Grid = {};
   -1  2206 
   -1  2207 module.exports = Grid;
   -1  2208 
   -1  2209 var Pair = _dereq_('./Pair');
   -1  2210 var Detector = _dereq_('./Detector');
   -1  2211 var Common = _dereq_('../core/Common');
   -1  2212 
   -1  2213 (function() {
   -1  2214 
   -1  2215     /**
   -1  2216      * Creates a new grid.
   -1  2217      * @method create
   -1  2218      * @param {} options
   -1  2219      * @return {grid} A new grid
   -1  2220      */
   -1  2221     Grid.create = function(options) {
   -1  2222         var defaults = {
   -1  2223             controller: Grid,
   -1  2224             detector: Detector.collisions,
   -1  2225             buckets: {},
   -1  2226             pairs: {},
   -1  2227             pairsList: [],
   -1  2228             bucketWidth: 48,
   -1  2229             bucketHeight: 48
   -1  2230         };
   -1  2231 
   -1  2232         return Common.extend(defaults, options);
   -1  2233     };
   -1  2234 
   -1  2235     /**
   -1  2236      * The width of a single grid bucket.
   -1  2237      *
   -1  2238      * @property bucketWidth
   -1  2239      * @type number
   -1  2240      * @default 48
   -1  2241      */
   -1  2242 
   -1  2243     /**
   -1  2244      * The height of a single grid bucket.
   -1  2245      *
   -1  2246      * @property bucketHeight
   -1  2247      * @type number
   -1  2248      * @default 48
   -1  2249      */
   -1  2250 
   -1  2251     /**
   -1  2252      * Updates the grid.
   -1  2253      * @method update
   -1  2254      * @param {grid} grid
   -1  2255      * @param {body[]} bodies
   -1  2256      * @param {engine} engine
   -1  2257      * @param {boolean} forceUpdate
   -1  2258      */
   -1  2259     Grid.update = function(grid, bodies, engine, forceUpdate) {
   -1  2260         var i, col, row,
   -1  2261             world = engine.world,
   -1  2262             buckets = grid.buckets,
   -1  2263             bucket,
   -1  2264             bucketId,
   -1  2265             gridChanged = false;
   -1  2266 
   -1  2267 
   -1  2268         for (i = 0; i < bodies.length; i++) {
   -1  2269             var body = bodies[i];
   -1  2270 
   -1  2271             if (body.isSleeping && !forceUpdate)
   -1  2272                 continue;
   -1  2273 
   -1  2274             // don't update out of world bodies
   -1  2275             if (body.bounds.max.x < world.bounds.min.x || body.bounds.min.x > world.bounds.max.x
   -1  2276                 || body.bounds.max.y < world.bounds.min.y || body.bounds.min.y > world.bounds.max.y)
   -1  2277                 continue;
   -1  2278 
   -1  2279             var newRegion = Grid._getRegion(grid, body);
   -1  2280 
   -1  2281             // if the body has changed grid region
   -1  2282             if (!body.region || newRegion.id !== body.region.id || forceUpdate) {
   -1  2283 
   -1  2284 
   -1  2285                 if (!body.region || forceUpdate)
   -1  2286                     body.region = newRegion;
   -1  2287 
   -1  2288                 var union = Grid._regionUnion(newRegion, body.region);
   -1  2289 
   -1  2290                 // update grid buckets affected by region change
   -1  2291                 // iterate over the union of both regions
   -1  2292                 for (col = union.startCol; col <= union.endCol; col++) {
   -1  2293                     for (row = union.startRow; row <= union.endRow; row++) {
   -1  2294                         bucketId = Grid._getBucketId(col, row);
   -1  2295                         bucket = buckets[bucketId];
   -1  2296 
   -1  2297                         var isInsideNewRegion = (col >= newRegion.startCol && col <= newRegion.endCol
   -1  2298                                                 && row >= newRegion.startRow && row <= newRegion.endRow);
   -1  2299 
   -1  2300                         var isInsideOldRegion = (col >= body.region.startCol && col <= body.region.endCol
   -1  2301                                                 && row >= body.region.startRow && row <= body.region.endRow);
   -1  2302 
   -1  2303                         // remove from old region buckets
   -1  2304                         if (!isInsideNewRegion && isInsideOldRegion) {
   -1  2305                             if (isInsideOldRegion) {
   -1  2306                                 if (bucket)
   -1  2307                                     Grid._bucketRemoveBody(grid, bucket, body);
   -1  2308                             }
   -1  2309                         }
   -1  2310 
   -1  2311                         // add to new region buckets
   -1  2312                         if (body.region === newRegion || (isInsideNewRegion && !isInsideOldRegion) || forceUpdate) {
   -1  2313                             if (!bucket)
   -1  2314                                 bucket = Grid._createBucket(buckets, bucketId);
   -1  2315                             Grid._bucketAddBody(grid, bucket, body);
   -1  2316                         }
   -1  2317                     }
   -1  2318                 }
   -1  2319 
   -1  2320                 // set the new region
   -1  2321                 body.region = newRegion;
   -1  2322 
   -1  2323                 // flag changes so we can update pairs
   -1  2324                 gridChanged = true;
   -1  2325             }
   -1  2326         }
   -1  2327 
   -1  2328         // update pairs list only if pairs changed (i.e. a body changed region)
   -1  2329         if (gridChanged)
   -1  2330             grid.pairsList = Grid._createActivePairsList(grid);
   -1  2331     };
   -1  2332 
   -1  2333     /**
   -1  2334      * Clears the grid.
   -1  2335      * @method clear
   -1  2336      * @param {grid} grid
   -1  2337      */
   -1  2338     Grid.clear = function(grid) {
   -1  2339         grid.buckets = {};
   -1  2340         grid.pairs = {};
   -1  2341         grid.pairsList = [];
   -1  2342     };
   -1  2343 
   -1  2344     /**
   -1  2345      * Finds the union of two regions.
   -1  2346      * @method _regionUnion
   -1  2347      * @private
   -1  2348      * @param {} regionA
   -1  2349      * @param {} regionB
   -1  2350      * @return {} region
   -1  2351      */
   -1  2352     Grid._regionUnion = function(regionA, regionB) {
   -1  2353         var startCol = Math.min(regionA.startCol, regionB.startCol),
   -1  2354             endCol = Math.max(regionA.endCol, regionB.endCol),
   -1  2355             startRow = Math.min(regionA.startRow, regionB.startRow),
   -1  2356             endRow = Math.max(regionA.endRow, regionB.endRow);
   -1  2357 
   -1  2358         return Grid._createRegion(startCol, endCol, startRow, endRow);
   -1  2359     };
   -1  2360 
   -1  2361     /**
   -1  2362      * Gets the region a given body falls in for a given grid.
   -1  2363      * @method _getRegion
   -1  2364      * @private
   -1  2365      * @param {} grid
   -1  2366      * @param {} body
   -1  2367      * @return {} region
   -1  2368      */
   -1  2369     Grid._getRegion = function(grid, body) {
   -1  2370         var bounds = body.bounds,
   -1  2371             startCol = Math.floor(bounds.min.x / grid.bucketWidth),
   -1  2372             endCol = Math.floor(bounds.max.x / grid.bucketWidth),
   -1  2373             startRow = Math.floor(bounds.min.y / grid.bucketHeight),
   -1  2374             endRow = Math.floor(bounds.max.y / grid.bucketHeight);
   -1  2375 
   -1  2376         return Grid._createRegion(startCol, endCol, startRow, endRow);
   -1  2377     };
   -1  2378 
   -1  2379     /**
   -1  2380      * Creates a region.
   -1  2381      * @method _createRegion
   -1  2382      * @private
   -1  2383      * @param {} startCol
   -1  2384      * @param {} endCol
   -1  2385      * @param {} startRow
   -1  2386      * @param {} endRow
   -1  2387      * @return {} region
   -1  2388      */
   -1  2389     Grid._createRegion = function(startCol, endCol, startRow, endRow) {
   -1  2390         return { 
   -1  2391             id: startCol + ',' + endCol + ',' + startRow + ',' + endRow,
   -1  2392             startCol: startCol, 
   -1  2393             endCol: endCol, 
   -1  2394             startRow: startRow, 
   -1  2395             endRow: endRow 
   -1  2396         };
   -1  2397     };
   -1  2398 
   -1  2399     /**
   -1  2400      * Gets the bucket id at the given position.
   -1  2401      * @method _getBucketId
   -1  2402      * @private
   -1  2403      * @param {} column
   -1  2404      * @param {} row
   -1  2405      * @return {string} bucket id
   -1  2406      */
   -1  2407     Grid._getBucketId = function(column, row) {
   -1  2408         return 'C' + column + 'R' + row;
   -1  2409     };
   -1  2410 
   -1  2411     /**
   -1  2412      * Creates a bucket.
   -1  2413      * @method _createBucket
   -1  2414      * @private
   -1  2415      * @param {} buckets
   -1  2416      * @param {} bucketId
   -1  2417      * @return {} bucket
   -1  2418      */
   -1  2419     Grid._createBucket = function(buckets, bucketId) {
   -1  2420         var bucket = buckets[bucketId] = [];
   -1  2421         return bucket;
   -1  2422     };
   -1  2423 
   -1  2424     /**
   -1  2425      * Adds a body to a bucket.
   -1  2426      * @method _bucketAddBody
   -1  2427      * @private
   -1  2428      * @param {} grid
   -1  2429      * @param {} bucket
   -1  2430      * @param {} body
   -1  2431      */
   -1  2432     Grid._bucketAddBody = function(grid, bucket, body) {
   -1  2433         // add new pairs
   -1  2434         for (var i = 0; i < bucket.length; i++) {
   -1  2435             var bodyB = bucket[i];
   -1  2436 
   -1  2437             if (body.id === bodyB.id || (body.isStatic && bodyB.isStatic))
   -1  2438                 continue;
   -1  2439 
   -1  2440             // keep track of the number of buckets the pair exists in
   -1  2441             // important for Grid.update to work
   -1  2442             var pairId = Pair.id(body, bodyB),
   -1  2443                 pair = grid.pairs[pairId];
   -1  2444 
   -1  2445             if (pair) {
   -1  2446                 pair[2] += 1;
   -1  2447             } else {
   -1  2448                 grid.pairs[pairId] = [body, bodyB, 1];
   -1  2449             }
   -1  2450         }
   -1  2451 
   -1  2452         // add to bodies (after pairs, otherwise pairs with self)
   -1  2453         bucket.push(body);
   -1  2454     };
   -1  2455 
   -1  2456     /**
   -1  2457      * Removes a body from a bucket.
   -1  2458      * @method _bucketRemoveBody
   -1  2459      * @private
   -1  2460      * @param {} grid
   -1  2461      * @param {} bucket
   -1  2462      * @param {} body
   -1  2463      */
   -1  2464     Grid._bucketRemoveBody = function(grid, bucket, body) {
   -1  2465         // remove from bucket
   -1  2466         bucket.splice(Common.indexOf(bucket, body), 1);
   -1  2467 
   -1  2468         // update pair counts
   -1  2469         for (var i = 0; i < bucket.length; i++) {
   -1  2470             // keep track of the number of buckets the pair exists in
   -1  2471             // important for _createActivePairsList to work
   -1  2472             var bodyB = bucket[i],
   -1  2473                 pairId = Pair.id(body, bodyB),
   -1  2474                 pair = grid.pairs[pairId];
   -1  2475 
   -1  2476             if (pair)
   -1  2477                 pair[2] -= 1;
   -1  2478         }
   -1  2479     };
   -1  2480 
   -1  2481     /**
   -1  2482      * Generates a list of the active pairs in the grid.
   -1  2483      * @method _createActivePairsList
   -1  2484      * @private
   -1  2485      * @param {} grid
   -1  2486      * @return [] pairs
   -1  2487      */
   -1  2488     Grid._createActivePairsList = function(grid) {
   -1  2489         var pairKeys,
   -1  2490             pair,
   -1  2491             pairs = [];
   -1  2492 
   -1  2493         // grid.pairs is used as a hashmap
   -1  2494         pairKeys = Common.keys(grid.pairs);
   -1  2495 
   -1  2496         // iterate over grid.pairs
   -1  2497         for (var k = 0; k < pairKeys.length; k++) {
   -1  2498             pair = grid.pairs[pairKeys[k]];
   -1  2499 
   -1  2500             // if pair exists in at least one bucket
   -1  2501             // it is a pair that needs further collision testing so push it
   -1  2502             if (pair[2] > 0) {
   -1  2503                 pairs.push(pair);
   -1  2504             } else {
   -1  2505                 delete grid.pairs[pairKeys[k]];
   -1  2506             }
   -1  2507         }
   -1  2508 
   -1  2509         return pairs;
   -1  2510     };
   -1  2511     
   -1  2512 })();
   -1  2513 
   -1  2514 },{"../core/Common":14,"./Detector":5,"./Pair":7}],7:[function(_dereq_,module,exports){
   -1  2515 /**
   -1  2516 * The `Matter.Pair` module contains methods for creating and manipulating collision pairs.
   -1  2517 *
   -1  2518 * @class Pair
   -1  2519 */
   -1  2520 
   -1  2521 var Pair = {};
   -1  2522 
   -1  2523 module.exports = Pair;
   -1  2524 
   -1  2525 var Contact = _dereq_('./Contact');
   -1  2526 
   -1  2527 (function() {
   -1  2528     
   -1  2529     /**
   -1  2530      * Creates a pair.
   -1  2531      * @method create
   -1  2532      * @param {collision} collision
   -1  2533      * @param {number} timestamp
   -1  2534      * @return {pair} A new pair
   -1  2535      */
   -1  2536     Pair.create = function(collision, timestamp) {
   -1  2537         var bodyA = collision.bodyA,
   -1  2538             bodyB = collision.bodyB,
   -1  2539             parentA = collision.parentA,
   -1  2540             parentB = collision.parentB;
   -1  2541 
   -1  2542         var pair = {
   -1  2543             id: Pair.id(bodyA, bodyB),
   -1  2544             bodyA: bodyA,
   -1  2545             bodyB: bodyB,
   -1  2546             contacts: {},
   -1  2547             activeContacts: [],
   -1  2548             separation: 0,
   -1  2549             isActive: true,
   -1  2550             isSensor: bodyA.isSensor || bodyB.isSensor,
   -1  2551             timeCreated: timestamp,
   -1  2552             timeUpdated: timestamp,
   -1  2553             inverseMass: parentA.inverseMass + parentB.inverseMass,
   -1  2554             friction: Math.min(parentA.friction, parentB.friction),
   -1  2555             frictionStatic: Math.max(parentA.frictionStatic, parentB.frictionStatic),
   -1  2556             restitution: Math.max(parentA.restitution, parentB.restitution),
   -1  2557             slop: Math.max(parentA.slop, parentB.slop)
   -1  2558         };
   -1  2559 
   -1  2560         Pair.update(pair, collision, timestamp);
   -1  2561 
   -1  2562         return pair;
   -1  2563     };
   -1  2564 
   -1  2565     /**
   -1  2566      * Updates a pair given a collision.
   -1  2567      * @method update
   -1  2568      * @param {pair} pair
   -1  2569      * @param {collision} collision
   -1  2570      * @param {number} timestamp
   -1  2571      */
   -1  2572     Pair.update = function(pair, collision, timestamp) {
   -1  2573         var contacts = pair.contacts,
   -1  2574             supports = collision.supports,
   -1  2575             activeContacts = pair.activeContacts,
   -1  2576             parentA = collision.parentA,
   -1  2577             parentB = collision.parentB;
   -1  2578         
   -1  2579         pair.collision = collision;
   -1  2580         pair.inverseMass = parentA.inverseMass + parentB.inverseMass;
   -1  2581         pair.friction = Math.min(parentA.friction, parentB.friction);
   -1  2582         pair.frictionStatic = Math.max(parentA.frictionStatic, parentB.frictionStatic);
   -1  2583         pair.restitution = Math.max(parentA.restitution, parentB.restitution);
   -1  2584         pair.slop = Math.max(parentA.slop, parentB.slop);
   -1  2585         activeContacts.length = 0;
   -1  2586         
   -1  2587         if (collision.collided) {
   -1  2588             for (var i = 0; i < supports.length; i++) {
   -1  2589                 var support = supports[i],
   -1  2590                     contactId = Contact.id(support),
   -1  2591                     contact = contacts[contactId];
   -1  2592 
   -1  2593                 if (contact) {
   -1  2594                     activeContacts.push(contact);
   -1  2595                 } else {
   -1  2596                     activeContacts.push(contacts[contactId] = Contact.create(support));
   -1  2597                 }
   -1  2598             }
   -1  2599 
   -1  2600             pair.separation = collision.depth;
   -1  2601             Pair.setActive(pair, true, timestamp);
   -1  2602         } else {
   -1  2603             if (pair.isActive === true)
   -1  2604                 Pair.setActive(pair, false, timestamp);
   -1  2605         }
   -1  2606     };
   -1  2607     
   -1  2608     /**
   -1  2609      * Set a pair as active or inactive.
   -1  2610      * @method setActive
   -1  2611      * @param {pair} pair
   -1  2612      * @param {bool} isActive
   -1  2613      * @param {number} timestamp
   -1  2614      */
   -1  2615     Pair.setActive = function(pair, isActive, timestamp) {
   -1  2616         if (isActive) {
   -1  2617             pair.isActive = true;
   -1  2618             pair.timeUpdated = timestamp;
   -1  2619         } else {
   -1  2620             pair.isActive = false;
   -1  2621             pair.activeContacts.length = 0;
   -1  2622         }
   -1  2623     };
   -1  2624 
   -1  2625     /**
   -1  2626      * Get the id for the given pair.
   -1  2627      * @method id
   -1  2628      * @param {body} bodyA
   -1  2629      * @param {body} bodyB
   -1  2630      * @return {string} Unique pairId
   -1  2631      */
   -1  2632     Pair.id = function(bodyA, bodyB) {
   -1  2633         if (bodyA.id < bodyB.id) {
   -1  2634             return 'A' + bodyA.id + 'B' + bodyB.id;
   -1  2635         } else {
   -1  2636             return 'A' + bodyB.id + 'B' + bodyA.id;
   -1  2637         }
   -1  2638     };
   -1  2639 
   -1  2640 })();
   -1  2641 
   -1  2642 },{"./Contact":4}],8:[function(_dereq_,module,exports){
   -1  2643 /**
   -1  2644 * The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets.
   -1  2645 *
   -1  2646 * @class Pairs
   -1  2647 */
   -1  2648 
   -1  2649 var Pairs = {};
   -1  2650 
   -1  2651 module.exports = Pairs;
   -1  2652 
   -1  2653 var Pair = _dereq_('./Pair');
   -1  2654 var Common = _dereq_('../core/Common');
   -1  2655 
   -1  2656 (function() {
   -1  2657     
   -1  2658     Pairs._pairMaxIdleLife = 1000;
   -1  2659 
   -1  2660     /**
   -1  2661      * Creates a new pairs structure.
   -1  2662      * @method create
   -1  2663      * @param {object} options
   -1  2664      * @return {pairs} A new pairs structure
   -1  2665      */
   -1  2666     Pairs.create = function(options) {
   -1  2667         return Common.extend({ 
   -1  2668             table: {},
   -1  2669             list: [],
   -1  2670             collisionStart: [],
   -1  2671             collisionActive: [],
   -1  2672             collisionEnd: []
   -1  2673         }, options);
   -1  2674     };
   -1  2675 
   -1  2676     /**
   -1  2677      * Updates pairs given a list of collisions.
   -1  2678      * @method update
   -1  2679      * @param {object} pairs
   -1  2680      * @param {collision[]} collisions
   -1  2681      * @param {number} timestamp
   -1  2682      */
   -1  2683     Pairs.update = function(pairs, collisions, timestamp) {
   -1  2684         var pairsList = pairs.list,
   -1  2685             pairsTable = pairs.table,
   -1  2686             collisionStart = pairs.collisionStart,
   -1  2687             collisionEnd = pairs.collisionEnd,
   -1  2688             collisionActive = pairs.collisionActive,
   -1  2689             activePairIds = [],
   -1  2690             collision,
   -1  2691             pairId,
   -1  2692             pair,
   -1  2693             i;
   -1  2694 
   -1  2695         // clear collision state arrays, but maintain old reference
   -1  2696         collisionStart.length = 0;
   -1  2697         collisionEnd.length = 0;
   -1  2698         collisionActive.length = 0;
   -1  2699 
   -1  2700         for (i = 0; i < collisions.length; i++) {
   -1  2701             collision = collisions[i];
   -1  2702 
   -1  2703             if (collision.collided) {
   -1  2704                 pairId = Pair.id(collision.bodyA, collision.bodyB);
   -1  2705                 activePairIds.push(pairId);
   -1  2706 
   -1  2707                 pair = pairsTable[pairId];
   -1  2708                 
   -1  2709                 if (pair) {
   -1  2710                     // pair already exists (but may or may not be active)
   -1  2711                     if (pair.isActive) {
   -1  2712                         // pair exists and is active
   -1  2713                         collisionActive.push(pair);
   -1  2714                     } else {
   -1  2715                         // pair exists but was inactive, so a collision has just started again
   -1  2716                         collisionStart.push(pair);
   -1  2717                     }
   -1  2718 
   -1  2719                     // update the pair
   -1  2720                     Pair.update(pair, collision, timestamp);
   -1  2721                 } else {
   -1  2722                     // pair did not exist, create a new pair
   -1  2723                     pair = Pair.create(collision, timestamp);
   -1  2724                     pairsTable[pairId] = pair;
   -1  2725 
   -1  2726                     // push the new pair
   -1  2727                     collisionStart.push(pair);
   -1  2728                     pairsList.push(pair);
   -1  2729                 }
   -1  2730             }
   -1  2731         }
   -1  2732 
   -1  2733         // deactivate previously active pairs that are now inactive
   -1  2734         for (i = 0; i < pairsList.length; i++) {
   -1  2735             pair = pairsList[i];
   -1  2736             if (pair.isActive && Common.indexOf(activePairIds, pair.id) === -1) {
   -1  2737                 Pair.setActive(pair, false, timestamp);
   -1  2738                 collisionEnd.push(pair);
   -1  2739             }
   -1  2740         }
   -1  2741     };
   -1  2742     
   -1  2743     /**
   -1  2744      * Finds and removes pairs that have been inactive for a set amount of time.
   -1  2745      * @method removeOld
   -1  2746      * @param {object} pairs
   -1  2747      * @param {number} timestamp
   -1  2748      */
   -1  2749     Pairs.removeOld = function(pairs, timestamp) {
   -1  2750         var pairsList = pairs.list,
   -1  2751             pairsTable = pairs.table,
   -1  2752             indexesToRemove = [],
   -1  2753             pair,
   -1  2754             collision,
   -1  2755             pairIndex,
   -1  2756             i;
   -1  2757 
   -1  2758         for (i = 0; i < pairsList.length; i++) {
   -1  2759             pair = pairsList[i];
   -1  2760             collision = pair.collision;
   -1  2761             
   -1  2762             // never remove sleeping pairs
   -1  2763             if (collision.bodyA.isSleeping || collision.bodyB.isSleeping) {
   -1  2764                 pair.timeUpdated = timestamp;
   -1  2765                 continue;
   -1  2766             }
   -1  2767 
   -1  2768             // if pair is inactive for too long, mark it to be removed
   -1  2769             if (timestamp - pair.timeUpdated > Pairs._pairMaxIdleLife) {
   -1  2770                 indexesToRemove.push(i);
   -1  2771             }
   -1  2772         }
   -1  2773 
   -1  2774         // remove marked pairs
   -1  2775         for (i = 0; i < indexesToRemove.length; i++) {
   -1  2776             pairIndex = indexesToRemove[i] - i;
   -1  2777             pair = pairsList[pairIndex];
   -1  2778             delete pairsTable[pair.id];
   -1  2779             pairsList.splice(pairIndex, 1);
   -1  2780         }
   -1  2781     };
   -1  2782 
   -1  2783     /**
   -1  2784      * Clears the given pairs structure.
   -1  2785      * @method clear
   -1  2786      * @param {pairs} pairs
   -1  2787      * @return {pairs} pairs
   -1  2788      */
   -1  2789     Pairs.clear = function(pairs) {
   -1  2790         pairs.table = {};
   -1  2791         pairs.list.length = 0;
   -1  2792         pairs.collisionStart.length = 0;
   -1  2793         pairs.collisionActive.length = 0;
   -1  2794         pairs.collisionEnd.length = 0;
   -1  2795         return pairs;
   -1  2796     };
   -1  2797 
   -1  2798 })();
   -1  2799 
   -1  2800 },{"../core/Common":14,"./Pair":7}],9:[function(_dereq_,module,exports){
   -1  2801 /**
   -1  2802 * The `Matter.Query` module contains methods for performing collision queries.
   -1  2803 *
   -1  2804 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  2805 *
   -1  2806 * @class Query
   -1  2807 */
   -1  2808 
   -1  2809 var Query = {};
   -1  2810 
   -1  2811 module.exports = Query;
   -1  2812 
   -1  2813 var Vector = _dereq_('../geometry/Vector');
   -1  2814 var SAT = _dereq_('./SAT');
   -1  2815 var Bounds = _dereq_('../geometry/Bounds');
   -1  2816 var Bodies = _dereq_('../factory/Bodies');
   -1  2817 var Vertices = _dereq_('../geometry/Vertices');
   -1  2818 
   -1  2819 (function() {
   -1  2820 
   -1  2821     /**
   -1  2822      * Returns a list of collisions between `body` and `bodies`.
   -1  2823      * @method collides
   -1  2824      * @param {body} body
   -1  2825      * @param {body[]} bodies
   -1  2826      * @return {object[]} Collisions
   -1  2827      */
   -1  2828     Query.collides = function(body, bodies) {
   -1  2829         var collisions = [];
   -1  2830 
   -1  2831         for (var i = 0; i < bodies.length; i++) {
   -1  2832             var bodyA = bodies[i];
   -1  2833             
   -1  2834             if (Bounds.overlaps(bodyA.bounds, body.bounds)) {
   -1  2835                 for (var j = bodyA.parts.length === 1 ? 0 : 1; j < bodyA.parts.length; j++) {
   -1  2836                     var part = bodyA.parts[j];
   -1  2837 
   -1  2838                     if (Bounds.overlaps(part.bounds, body.bounds)) {
   -1  2839                         var collision = SAT.collides(part, body);
   -1  2840 
   -1  2841                         if (collision.collided) {
   -1  2842                             collisions.push(collision);
   -1  2843                             break;
   -1  2844                         }
   -1  2845                     }
   -1  2846                 }
   -1  2847             }
   -1  2848         }
   -1  2849 
   -1  2850         return collisions;
   -1  2851     };
   -1  2852 
   -1  2853     /**
   -1  2854      * Casts a ray segment against a set of bodies and returns all collisions, ray width is optional. Intersection points are not provided.
   -1  2855      * @method ray
   -1  2856      * @param {body[]} bodies
   -1  2857      * @param {vector} startPoint
   -1  2858      * @param {vector} endPoint
   -1  2859      * @param {number} [rayWidth]
   -1  2860      * @return {object[]} Collisions
   -1  2861      */
   -1  2862     Query.ray = function(bodies, startPoint, endPoint, rayWidth) {
   -1  2863         rayWidth = rayWidth || 1e-100;
   -1  2864 
   -1  2865         var rayAngle = Vector.angle(startPoint, endPoint),
   -1  2866             rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)),
   -1  2867             rayX = (endPoint.x + startPoint.x) * 0.5,
   -1  2868             rayY = (endPoint.y + startPoint.y) * 0.5,
   -1  2869             ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }),
   -1  2870             collisions = Query.collides(ray, bodies);
   -1  2871 
   -1  2872         for (var i = 0; i < collisions.length; i += 1) {
   -1  2873             var collision = collisions[i];
   -1  2874             collision.body = collision.bodyB = collision.bodyA;            
   -1  2875         }
   -1  2876 
   -1  2877         return collisions;
   -1  2878     };
   -1  2879 
   -1  2880     /**
   -1  2881      * Returns all bodies whose bounds are inside (or outside if set) the given set of bounds, from the given set of bodies.
   -1  2882      * @method region
   -1  2883      * @param {body[]} bodies
   -1  2884      * @param {bounds} bounds
   -1  2885      * @param {bool} [outside=false]
   -1  2886      * @return {body[]} The bodies matching the query
   -1  2887      */
   -1  2888     Query.region = function(bodies, bounds, outside) {
   -1  2889         var result = [];
   -1  2890 
   -1  2891         for (var i = 0; i < bodies.length; i++) {
   -1  2892             var body = bodies[i],
   -1  2893                 overlaps = Bounds.overlaps(body.bounds, bounds);
   -1  2894             if ((overlaps && !outside) || (!overlaps && outside))
   -1  2895                 result.push(body);
   -1  2896         }
   -1  2897 
   -1  2898         return result;
   -1  2899     };
   -1  2900 
   -1  2901     /**
   -1  2902      * Returns all bodies whose vertices contain the given point, from the given set of bodies.
   -1  2903      * @method point
   -1  2904      * @param {body[]} bodies
   -1  2905      * @param {vector} point
   -1  2906      * @return {body[]} The bodies matching the query
   -1  2907      */
   -1  2908     Query.point = function(bodies, point) {
   -1  2909         var result = [];
   -1  2910 
   -1  2911         for (var i = 0; i < bodies.length; i++) {
   -1  2912             var body = bodies[i];
   -1  2913             
   -1  2914             if (Bounds.contains(body.bounds, point)) {
   -1  2915                 for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) {
   -1  2916                     var part = body.parts[j];
   -1  2917 
   -1  2918                     if (Bounds.contains(part.bounds, point)
   -1  2919                         && Vertices.contains(part.vertices, point)) {
   -1  2920                         result.push(body);
   -1  2921                         break;
   -1  2922                     }
   -1  2923                 }
   -1  2924             }
   -1  2925         }
   -1  2926 
   -1  2927         return result;
   -1  2928     };
   -1  2929 
   -1  2930 })();
   -1  2931 
   -1  2932 },{"../factory/Bodies":23,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29,"./SAT":11}],10:[function(_dereq_,module,exports){
   -1  2933 /**
   -1  2934 * The `Matter.Resolver` module contains methods for resolving collision pairs.
   -1  2935 *
   -1  2936 * @class Resolver
   -1  2937 */
   -1  2938 
   -1  2939 var Resolver = {};
   -1  2940 
   -1  2941 module.exports = Resolver;
   -1  2942 
   -1  2943 var Vertices = _dereq_('../geometry/Vertices');
   -1  2944 var Vector = _dereq_('../geometry/Vector');
   -1  2945 var Common = _dereq_('../core/Common');
   -1  2946 var Bounds = _dereq_('../geometry/Bounds');
   -1  2947 
   -1  2948 (function() {
   -1  2949 
   -1  2950     Resolver._restingThresh = 4;
   -1  2951     Resolver._restingThreshTangent = 6;
   -1  2952     Resolver._positionDampen = 0.9;
   -1  2953     Resolver._positionWarming = 0.8;
   -1  2954     Resolver._frictionNormalMultiplier = 5;
   -1  2955 
   -1  2956     /**
   -1  2957      * Prepare pairs for position solving.
   -1  2958      * @method preSolvePosition
   -1  2959      * @param {pair[]} pairs
   -1  2960      */
   -1  2961     Resolver.preSolvePosition = function(pairs) {
   -1  2962         var i,
   -1  2963             pair,
   -1  2964             activeCount;
   -1  2965 
   -1  2966         // find total contacts on each body
   -1  2967         for (i = 0; i < pairs.length; i++) {
   -1  2968             pair = pairs[i];
   -1  2969             
   -1  2970             if (!pair.isActive)
   -1  2971                 continue;
   -1  2972             
   -1  2973             activeCount = pair.activeContacts.length;
   -1  2974             pair.collision.parentA.totalContacts += activeCount;
   -1  2975             pair.collision.parentB.totalContacts += activeCount;
   -1  2976         }
   -1  2977     };
   -1  2978 
   -1  2979     /**
   -1  2980      * Find a solution for pair positions.
   -1  2981      * @method solvePosition
   -1  2982      * @param {pair[]} pairs
   -1  2983      * @param {number} timeScale
   -1  2984      */
   -1  2985     Resolver.solvePosition = function(pairs, timeScale) {
   -1  2986         var i,
   -1  2987             pair,
   -1  2988             collision,
   -1  2989             bodyA,
   -1  2990             bodyB,
   -1  2991             normal,
   -1  2992             bodyBtoA,
   -1  2993             contactShare,
   -1  2994             positionImpulse,
   -1  2995             contactCount = {},
   -1  2996             tempA = Vector._temp[0],
   -1  2997             tempB = Vector._temp[1],
   -1  2998             tempC = Vector._temp[2],
   -1  2999             tempD = Vector._temp[3];
   -1  3000 
   -1  3001         // find impulses required to resolve penetration
   -1  3002         for (i = 0; i < pairs.length; i++) {
   -1  3003             pair = pairs[i];
   -1  3004             
   -1  3005             if (!pair.isActive || pair.isSensor)
   -1  3006                 continue;
   -1  3007 
   -1  3008             collision = pair.collision;
   -1  3009             bodyA = collision.parentA;
   -1  3010             bodyB = collision.parentB;
   -1  3011             normal = collision.normal;
   -1  3012 
   -1  3013             // get current separation between body edges involved in collision
   -1  3014             bodyBtoA = Vector.sub(Vector.add(bodyB.positionImpulse, bodyB.position, tempA), 
   -1  3015                                     Vector.add(bodyA.positionImpulse, 
   -1  3016                                         Vector.sub(bodyB.position, collision.penetration, tempB), tempC), tempD);
   -1  3017 
   -1  3018             pair.separation = Vector.dot(normal, bodyBtoA);
   -1  3019         }
   -1  3020         
   -1  3021         for (i = 0; i < pairs.length; i++) {
   -1  3022             pair = pairs[i];
   -1  3023 
   -1  3024             if (!pair.isActive || pair.isSensor)
   -1  3025                 continue;
   -1  3026             
   -1  3027             collision = pair.collision;
   -1  3028             bodyA = collision.parentA;
   -1  3029             bodyB = collision.parentB;
   -1  3030             normal = collision.normal;
   -1  3031             positionImpulse = (pair.separation - pair.slop) * timeScale;
   -1  3032 
   -1  3033             if (bodyA.isStatic || bodyB.isStatic)
   -1  3034                 positionImpulse *= 2;
   -1  3035             
   -1  3036             if (!(bodyA.isStatic || bodyA.isSleeping)) {
   -1  3037                 contactShare = Resolver._positionDampen / bodyA.totalContacts;
   -1  3038                 bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
   -1  3039                 bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
   -1  3040             }
   -1  3041 
   -1  3042             if (!(bodyB.isStatic || bodyB.isSleeping)) {
   -1  3043                 contactShare = Resolver._positionDampen / bodyB.totalContacts;
   -1  3044                 bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
   -1  3045                 bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
   -1  3046             }
   -1  3047         }
   -1  3048     };
   -1  3049 
   -1  3050     /**
   -1  3051      * Apply position resolution.
   -1  3052      * @method postSolvePosition
   -1  3053      * @param {body[]} bodies
   -1  3054      */
   -1  3055     Resolver.postSolvePosition = function(bodies) {
   -1  3056         for (var i = 0; i < bodies.length; i++) {
   -1  3057             var body = bodies[i];
   -1  3058 
   -1  3059             // reset contact count
   -1  3060             body.totalContacts = 0;
   -1  3061 
   -1  3062             if (body.positionImpulse.x !== 0 || body.positionImpulse.y !== 0) {
   -1  3063                 // update body geometry
   -1  3064                 for (var j = 0; j < body.parts.length; j++) {
   -1  3065                     var part = body.parts[j];
   -1  3066                     Vertices.translate(part.vertices, body.positionImpulse);
   -1  3067                     Bounds.update(part.bounds, part.vertices, body.velocity);
   -1  3068                     part.position.x += body.positionImpulse.x;
   -1  3069                     part.position.y += body.positionImpulse.y;
   -1  3070                 }
   -1  3071 
   -1  3072                 // move the body without changing velocity
   -1  3073                 body.positionPrev.x += body.positionImpulse.x;
   -1  3074                 body.positionPrev.y += body.positionImpulse.y;
   -1  3075 
   -1  3076                 if (Vector.dot(body.positionImpulse, body.velocity) < 0) {
   -1  3077                     // reset cached impulse if the body has velocity along it
   -1  3078                     body.positionImpulse.x = 0;
   -1  3079                     body.positionImpulse.y = 0;
   -1  3080                 } else {
   -1  3081                     // warm the next iteration
   -1  3082                     body.positionImpulse.x *= Resolver._positionWarming;
   -1  3083                     body.positionImpulse.y *= Resolver._positionWarming;
   -1  3084                 }
   -1  3085             }
   -1  3086         }
   -1  3087     };
   -1  3088 
   -1  3089     /**
   -1  3090      * Prepare pairs for velocity solving.
   -1  3091      * @method preSolveVelocity
   -1  3092      * @param {pair[]} pairs
   -1  3093      */
   -1  3094     Resolver.preSolveVelocity = function(pairs) {
   -1  3095         var i,
   -1  3096             j,
   -1  3097             pair,
   -1  3098             contacts,
   -1  3099             collision,
   -1  3100             bodyA,
   -1  3101             bodyB,
   -1  3102             normal,
   -1  3103             tangent,
   -1  3104             contact,
   -1  3105             contactVertex,
   -1  3106             normalImpulse,
   -1  3107             tangentImpulse,
   -1  3108             offset,
   -1  3109             impulse = Vector._temp[0],
   -1  3110             tempA = Vector._temp[1];
   -1  3111         
   -1  3112         for (i = 0; i < pairs.length; i++) {
   -1  3113             pair = pairs[i];
   -1  3114             
   -1  3115             if (!pair.isActive || pair.isSensor)
   -1  3116                 continue;
   -1  3117             
   -1  3118             contacts = pair.activeContacts;
   -1  3119             collision = pair.collision;
   -1  3120             bodyA = collision.parentA;
   -1  3121             bodyB = collision.parentB;
   -1  3122             normal = collision.normal;
   -1  3123             tangent = collision.tangent;
   -1  3124 
   -1  3125             // resolve each contact
   -1  3126             for (j = 0; j < contacts.length; j++) {
   -1  3127                 contact = contacts[j];
   -1  3128                 contactVertex = contact.vertex;
   -1  3129                 normalImpulse = contact.normalImpulse;
   -1  3130                 tangentImpulse = contact.tangentImpulse;
   -1  3131 
   -1  3132                 if (normalImpulse !== 0 || tangentImpulse !== 0) {
   -1  3133                     // total impulse from contact
   -1  3134                     impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
   -1  3135                     impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
   -1  3136                     
   -1  3137                     // apply impulse from contact
   -1  3138                     if (!(bodyA.isStatic || bodyA.isSleeping)) {
   -1  3139                         offset = Vector.sub(contactVertex, bodyA.position, tempA);
   -1  3140                         bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
   -1  3141                         bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
   -1  3142                         bodyA.anglePrev += Vector.cross(offset, impulse) * bodyA.inverseInertia;
   -1  3143                     }
   -1  3144 
   -1  3145                     if (!(bodyB.isStatic || bodyB.isSleeping)) {
   -1  3146                         offset = Vector.sub(contactVertex, bodyB.position, tempA);
   -1  3147                         bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
   -1  3148                         bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
   -1  3149                         bodyB.anglePrev -= Vector.cross(offset, impulse) * bodyB.inverseInertia;
   -1  3150                     }
   -1  3151                 }
   -1  3152             }
   -1  3153         }
   -1  3154     };
   -1  3155 
   -1  3156     /**
   -1  3157      * Find a solution for pair velocities.
   -1  3158      * @method solveVelocity
   -1  3159      * @param {pair[]} pairs
   -1  3160      * @param {number} timeScale
   -1  3161      */
   -1  3162     Resolver.solveVelocity = function(pairs, timeScale) {
   -1  3163         var timeScaleSquared = timeScale * timeScale,
   -1  3164             impulse = Vector._temp[0],
   -1  3165             tempA = Vector._temp[1],
   -1  3166             tempB = Vector._temp[2],
   -1  3167             tempC = Vector._temp[3],
   -1  3168             tempD = Vector._temp[4],
   -1  3169             tempE = Vector._temp[5];
   -1  3170         
   -1  3171         for (var i = 0; i < pairs.length; i++) {
   -1  3172             var pair = pairs[i];
   -1  3173             
   -1  3174             if (!pair.isActive || pair.isSensor)
   -1  3175                 continue;
   -1  3176             
   -1  3177             var collision = pair.collision,
   -1  3178                 bodyA = collision.parentA,
   -1  3179                 bodyB = collision.parentB,
   -1  3180                 normal = collision.normal,
   -1  3181                 tangent = collision.tangent,
   -1  3182                 contacts = pair.activeContacts,
   -1  3183                 contactShare = 1 / contacts.length;
   -1  3184 
   -1  3185             // update body velocities
   -1  3186             bodyA.velocity.x = bodyA.position.x - bodyA.positionPrev.x;
   -1  3187             bodyA.velocity.y = bodyA.position.y - bodyA.positionPrev.y;
   -1  3188             bodyB.velocity.x = bodyB.position.x - bodyB.positionPrev.x;
   -1  3189             bodyB.velocity.y = bodyB.position.y - bodyB.positionPrev.y;
   -1  3190             bodyA.angularVelocity = bodyA.angle - bodyA.anglePrev;
   -1  3191             bodyB.angularVelocity = bodyB.angle - bodyB.anglePrev;
   -1  3192 
   -1  3193             // resolve each contact
   -1  3194             for (var j = 0; j < contacts.length; j++) {
   -1  3195                 var contact = contacts[j],
   -1  3196                     contactVertex = contact.vertex,
   -1  3197                     offsetA = Vector.sub(contactVertex, bodyA.position, tempA),
   -1  3198                     offsetB = Vector.sub(contactVertex, bodyB.position, tempB),
   -1  3199                     velocityPointA = Vector.add(bodyA.velocity, Vector.mult(Vector.perp(offsetA), bodyA.angularVelocity), tempC),
   -1  3200                     velocityPointB = Vector.add(bodyB.velocity, Vector.mult(Vector.perp(offsetB), bodyB.angularVelocity), tempD), 
   -1  3201                     relativeVelocity = Vector.sub(velocityPointA, velocityPointB, tempE),
   -1  3202                     normalVelocity = Vector.dot(normal, relativeVelocity);
   -1  3203 
   -1  3204                 var tangentVelocity = Vector.dot(tangent, relativeVelocity),
   -1  3205                     tangentSpeed = Math.abs(tangentVelocity),
   -1  3206                     tangentVelocityDirection = Common.sign(tangentVelocity);
   -1  3207 
   -1  3208                 // raw impulses
   -1  3209                 var normalImpulse = (1 + pair.restitution) * normalVelocity,
   -1  3210                     normalForce = Common.clamp(pair.separation + normalVelocity, 0, 1) * Resolver._frictionNormalMultiplier;
   -1  3211 
   -1  3212                 // coulomb friction
   -1  3213                 var tangentImpulse = tangentVelocity,
   -1  3214                     maxFriction = Infinity;
   -1  3215 
   -1  3216                 if (tangentSpeed > pair.friction * pair.frictionStatic * normalForce * timeScaleSquared) {
   -1  3217                     maxFriction = tangentSpeed;
   -1  3218                     tangentImpulse = Common.clamp(
   -1  3219                         pair.friction * tangentVelocityDirection * timeScaleSquared,
   -1  3220                         -maxFriction, maxFriction
   -1  3221                     );
   -1  3222                 }
   -1  3223 
   -1  3224                 // modify impulses accounting for mass, inertia and offset
   -1  3225                 var oAcN = Vector.cross(offsetA, normal),
   -1  3226                     oBcN = Vector.cross(offsetB, normal),
   -1  3227                     share = contactShare / (bodyA.inverseMass + bodyB.inverseMass + bodyA.inverseInertia * oAcN * oAcN  + bodyB.inverseInertia * oBcN * oBcN);
   -1  3228 
   -1  3229                 normalImpulse *= share;
   -1  3230                 tangentImpulse *= share;
   -1  3231 
   -1  3232                 // handle high velocity and resting collisions separately
   -1  3233                 if (normalVelocity < 0 && normalVelocity * normalVelocity > Resolver._restingThresh * timeScaleSquared) {
   -1  3234                     // high normal velocity so clear cached contact normal impulse
   -1  3235                     contact.normalImpulse = 0;
   -1  3236                 } else {
   -1  3237                     // solve resting collision constraints using Erin Catto's method (GDC08)
   -1  3238                     // impulse constraint tends to 0
   -1  3239                     var contactNormalImpulse = contact.normalImpulse;
   -1  3240                     contact.normalImpulse = Math.min(contact.normalImpulse + normalImpulse, 0);
   -1  3241                     normalImpulse = contact.normalImpulse - contactNormalImpulse;
   -1  3242                 }
   -1  3243 
   -1  3244                 // handle high velocity and resting collisions separately
   -1  3245                 if (tangentVelocity * tangentVelocity > Resolver._restingThreshTangent * timeScaleSquared) {
   -1  3246                     // high tangent velocity so clear cached contact tangent impulse
   -1  3247                     contact.tangentImpulse = 0;
   -1  3248                 } else {
   -1  3249                     // solve resting collision constraints using Erin Catto's method (GDC08)
   -1  3250                     // tangent impulse tends to -tangentSpeed or +tangentSpeed
   -1  3251                     var contactTangentImpulse = contact.tangentImpulse;
   -1  3252                     contact.tangentImpulse = Common.clamp(contact.tangentImpulse + tangentImpulse, -maxFriction, maxFriction);
   -1  3253                     tangentImpulse = contact.tangentImpulse - contactTangentImpulse;
   -1  3254                 }
   -1  3255 
   -1  3256                 // total impulse from contact
   -1  3257                 impulse.x = (normal.x * normalImpulse) + (tangent.x * tangentImpulse);
   -1  3258                 impulse.y = (normal.y * normalImpulse) + (tangent.y * tangentImpulse);
   -1  3259                 
   -1  3260                 // apply impulse from contact
   -1  3261                 if (!(bodyA.isStatic || bodyA.isSleeping)) {
   -1  3262                     bodyA.positionPrev.x += impulse.x * bodyA.inverseMass;
   -1  3263                     bodyA.positionPrev.y += impulse.y * bodyA.inverseMass;
   -1  3264                     bodyA.anglePrev += Vector.cross(offsetA, impulse) * bodyA.inverseInertia;
   -1  3265                 }
   -1  3266 
   -1  3267                 if (!(bodyB.isStatic || bodyB.isSleeping)) {
   -1  3268                     bodyB.positionPrev.x -= impulse.x * bodyB.inverseMass;
   -1  3269                     bodyB.positionPrev.y -= impulse.y * bodyB.inverseMass;
   -1  3270                     bodyB.anglePrev -= Vector.cross(offsetB, impulse) * bodyB.inverseInertia;
   -1  3271                 }
   -1  3272             }
   -1  3273         }
   -1  3274     };
   -1  3275 
   -1  3276 })();
   -1  3277 
   -1  3278 },{"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],11:[function(_dereq_,module,exports){
   -1  3279 /**
   -1  3280 * The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
   -1  3281 *
   -1  3282 * @class SAT
   -1  3283 */
   -1  3284 
   -1  3285 // TODO: true circles and curves
   -1  3286 
   -1  3287 var SAT = {};
   -1  3288 
   -1  3289 module.exports = SAT;
   -1  3290 
   -1  3291 var Vertices = _dereq_('../geometry/Vertices');
   -1  3292 var Vector = _dereq_('../geometry/Vector');
   -1  3293 
   -1  3294 (function() {
   -1  3295 
   -1  3296     /**
   -1  3297      * Detect collision between two bodies using the Separating Axis Theorem.
   -1  3298      * @method collides
   -1  3299      * @param {body} bodyA
   -1  3300      * @param {body} bodyB
   -1  3301      * @param {collision} previousCollision
   -1  3302      * @return {collision} collision
   -1  3303      */
   -1  3304     SAT.collides = function(bodyA, bodyB, previousCollision) {
   -1  3305         var overlapAB,
   -1  3306             overlapBA, 
   -1  3307             minOverlap,
   -1  3308             collision,
   -1  3309             canReusePrevCol = false;
   -1  3310 
   -1  3311         if (previousCollision) {
   -1  3312             // estimate total motion
   -1  3313             var parentA = bodyA.parent,
   -1  3314                 parentB = bodyB.parent,
   -1  3315                 motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed
   -1  3316                        + parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed;
   -1  3317 
   -1  3318             // we may be able to (partially) reuse collision result 
   -1  3319             // but only safe if collision was resting
   -1  3320             canReusePrevCol = previousCollision && previousCollision.collided && motion < 0.2;
   -1  3321 
   -1  3322             // reuse collision object
   -1  3323             collision = previousCollision;
   -1  3324         } else {
   -1  3325             collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
   -1  3326         }
   -1  3327 
   -1  3328         if (previousCollision && canReusePrevCol) {
   -1  3329             // if we can reuse the collision result
   -1  3330             // we only need to test the previously found axis
   -1  3331             var axisBodyA = collision.axisBody,
   -1  3332                 axisBodyB = axisBodyA === bodyA ? bodyB : bodyA,
   -1  3333                 axes = [axisBodyA.axes[previousCollision.axisNumber]];
   -1  3334 
   -1  3335             minOverlap = SAT._overlapAxes(axisBodyA.vertices, axisBodyB.vertices, axes);
   -1  3336             collision.reused = true;
   -1  3337 
   -1  3338             if (minOverlap.overlap <= 0) {
   -1  3339                 collision.collided = false;
   -1  3340                 return collision;
   -1  3341             }
   -1  3342         } else {
   -1  3343             // if we can't reuse a result, perform a full SAT test
   -1  3344 
   -1  3345             overlapAB = SAT._overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);
   -1  3346 
   -1  3347             if (overlapAB.overlap <= 0) {
   -1  3348                 collision.collided = false;
   -1  3349                 return collision;
   -1  3350             }
   -1  3351 
   -1  3352             overlapBA = SAT._overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);
   -1  3353 
   -1  3354             if (overlapBA.overlap <= 0) {
   -1  3355                 collision.collided = false;
   -1  3356                 return collision;
   -1  3357             }
   -1  3358 
   -1  3359             if (overlapAB.overlap < overlapBA.overlap) {
   -1  3360                 minOverlap = overlapAB;
   -1  3361                 collision.axisBody = bodyA;
   -1  3362             } else {
   -1  3363                 minOverlap = overlapBA;
   -1  3364                 collision.axisBody = bodyB;
   -1  3365             }
   -1  3366 
   -1  3367             // important for reuse later
   -1  3368             collision.axisNumber = minOverlap.axisNumber;
   -1  3369         }
   -1  3370 
   -1  3371         collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB;
   -1  3372         collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA;
   -1  3373         collision.collided = true;
   -1  3374         collision.depth = minOverlap.overlap;
   -1  3375         collision.parentA = collision.bodyA.parent;
   -1  3376         collision.parentB = collision.bodyB.parent;
   -1  3377         
   -1  3378         bodyA = collision.bodyA;
   -1  3379         bodyB = collision.bodyB;
   -1  3380 
   -1  3381         // ensure normal is facing away from bodyA
   -1  3382         if (Vector.dot(minOverlap.axis, Vector.sub(bodyB.position, bodyA.position)) < 0) {
   -1  3383             collision.normal = {
   -1  3384                 x: minOverlap.axis.x,
   -1  3385                 y: minOverlap.axis.y
   -1  3386             };
   -1  3387         } else {
   -1  3388             collision.normal = {
   -1  3389                 x: -minOverlap.axis.x,
   -1  3390                 y: -minOverlap.axis.y
   -1  3391             };
   -1  3392         }
   -1  3393 
   -1  3394         collision.tangent = Vector.perp(collision.normal);
   -1  3395 
   -1  3396         collision.penetration = collision.penetration || {};
   -1  3397         collision.penetration.x = collision.normal.x * collision.depth;
   -1  3398         collision.penetration.y = collision.normal.y * collision.depth; 
   -1  3399 
   -1  3400         // find support points, there is always either exactly one or two
   -1  3401         var verticesB = SAT._findSupports(bodyA, bodyB, collision.normal),
   -1  3402             supports = [];
   -1  3403 
   -1  3404         // find the supports from bodyB that are inside bodyA
   -1  3405         if (Vertices.contains(bodyA.vertices, verticesB[0]))
   -1  3406             supports.push(verticesB[0]);
   -1  3407 
   -1  3408         if (Vertices.contains(bodyA.vertices, verticesB[1]))
   -1  3409             supports.push(verticesB[1]);
   -1  3410 
   -1  3411         // find the supports from bodyA that are inside bodyB
   -1  3412         if (supports.length < 2) {
   -1  3413             var verticesA = SAT._findSupports(bodyB, bodyA, Vector.neg(collision.normal));
   -1  3414                 
   -1  3415             if (Vertices.contains(bodyB.vertices, verticesA[0]))
   -1  3416                 supports.push(verticesA[0]);
   -1  3417 
   -1  3418             if (supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
   -1  3419                 supports.push(verticesA[1]);
   -1  3420         }
   -1  3421 
   -1  3422         // account for the edge case of overlapping but no vertex containment
   -1  3423         if (supports.length < 1)
   -1  3424             supports = [verticesB[0]];
   -1  3425         
   -1  3426         collision.supports = supports;
   -1  3427 
   -1  3428         return collision;
   -1  3429     };
   -1  3430 
   -1  3431     /**
   -1  3432      * Find the overlap between two sets of vertices.
   -1  3433      * @method _overlapAxes
   -1  3434      * @private
   -1  3435      * @param {} verticesA
   -1  3436      * @param {} verticesB
   -1  3437      * @param {} axes
   -1  3438      * @return result
   -1  3439      */
   -1  3440     SAT._overlapAxes = function(verticesA, verticesB, axes) {
   -1  3441         var projectionA = Vector._temp[0], 
   -1  3442             projectionB = Vector._temp[1],
   -1  3443             result = { overlap: Number.MAX_VALUE },
   -1  3444             overlap,
   -1  3445             axis;
   -1  3446 
   -1  3447         for (var i = 0; i < axes.length; i++) {
   -1  3448             axis = axes[i];
   -1  3449 
   -1  3450             SAT._projectToAxis(projectionA, verticesA, axis);
   -1  3451             SAT._projectToAxis(projectionB, verticesB, axis);
   -1  3452 
   -1  3453             overlap = Math.min(projectionA.max - projectionB.min, projectionB.max - projectionA.min);
   -1  3454 
   -1  3455             if (overlap <= 0) {
   -1  3456                 result.overlap = overlap;
   -1  3457                 return result;
   -1  3458             }
   -1  3459 
   -1  3460             if (overlap < result.overlap) {
   -1  3461                 result.overlap = overlap;
   -1  3462                 result.axis = axis;
   -1  3463                 result.axisNumber = i;
   -1  3464             }
   -1  3465         }
   -1  3466 
   -1  3467         return result;
   -1  3468     };
   -1  3469 
   -1  3470     /**
   -1  3471      * Projects vertices on an axis and returns an interval.
   -1  3472      * @method _projectToAxis
   -1  3473      * @private
   -1  3474      * @param {} projection
   -1  3475      * @param {} vertices
   -1  3476      * @param {} axis
   -1  3477      */
   -1  3478     SAT._projectToAxis = function(projection, vertices, axis) {
   -1  3479         var min = Vector.dot(vertices[0], axis),
   -1  3480             max = min;
   -1  3481 
   -1  3482         for (var i = 1; i < vertices.length; i += 1) {
   -1  3483             var dot = Vector.dot(vertices[i], axis);
   -1  3484 
   -1  3485             if (dot > max) { 
   -1  3486                 max = dot; 
   -1  3487             } else if (dot < min) { 
   -1  3488                 min = dot; 
   -1  3489             }
   -1  3490         }
   -1  3491 
   -1  3492         projection.min = min;
   -1  3493         projection.max = max;
   -1  3494     };
   -1  3495     
   -1  3496     /**
   -1  3497      * Finds supporting vertices given two bodies along a given direction using hill-climbing.
   -1  3498      * @method _findSupports
   -1  3499      * @private
   -1  3500      * @param {} bodyA
   -1  3501      * @param {} bodyB
   -1  3502      * @param {} normal
   -1  3503      * @return [vector]
   -1  3504      */
   -1  3505     SAT._findSupports = function(bodyA, bodyB, normal) {
   -1  3506         var nearestDistance = Number.MAX_VALUE,
   -1  3507             vertexToBody = Vector._temp[0],
   -1  3508             vertices = bodyB.vertices,
   -1  3509             bodyAPosition = bodyA.position,
   -1  3510             distance,
   -1  3511             vertex,
   -1  3512             vertexA,
   -1  3513             vertexB;
   -1  3514 
   -1  3515         // find closest vertex on bodyB
   -1  3516         for (var i = 0; i < vertices.length; i++) {
   -1  3517             vertex = vertices[i];
   -1  3518             vertexToBody.x = vertex.x - bodyAPosition.x;
   -1  3519             vertexToBody.y = vertex.y - bodyAPosition.y;
   -1  3520             distance = -Vector.dot(normal, vertexToBody);
   -1  3521 
   -1  3522             if (distance < nearestDistance) {
   -1  3523                 nearestDistance = distance;
   -1  3524                 vertexA = vertex;
   -1  3525             }
   -1  3526         }
   -1  3527 
   -1  3528         // find next closest vertex using the two connected to it
   -1  3529         var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
   -1  3530         vertex = vertices[prevIndex];
   -1  3531         vertexToBody.x = vertex.x - bodyAPosition.x;
   -1  3532         vertexToBody.y = vertex.y - bodyAPosition.y;
   -1  3533         nearestDistance = -Vector.dot(normal, vertexToBody);
   -1  3534         vertexB = vertex;
   -1  3535 
   -1  3536         var nextIndex = (vertexA.index + 1) % vertices.length;
   -1  3537         vertex = vertices[nextIndex];
   -1  3538         vertexToBody.x = vertex.x - bodyAPosition.x;
   -1  3539         vertexToBody.y = vertex.y - bodyAPosition.y;
   -1  3540         distance = -Vector.dot(normal, vertexToBody);
   -1  3541         if (distance < nearestDistance) {
   -1  3542             vertexB = vertex;
   -1  3543         }
   -1  3544 
   -1  3545         return [vertexA, vertexB];
   -1  3546     };
   -1  3547 
   -1  3548 })();
   -1  3549 
   -1  3550 },{"../geometry/Vector":28,"../geometry/Vertices":29}],12:[function(_dereq_,module,exports){
   -1  3551 /**
   -1  3552 * The `Matter.Constraint` module contains methods for creating and manipulating constraints.
   -1  3553 * Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
   -1  3554 * The stiffness of constraints can be modified to create springs or elastic.
   -1  3555 *
   -1  3556 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  3557 *
   -1  3558 * @class Constraint
   -1  3559 */
   -1  3560 
   -1  3561 var Constraint = {};
   -1  3562 
   -1  3563 module.exports = Constraint;
   -1  3564 
   -1  3565 var Vertices = _dereq_('../geometry/Vertices');
   -1  3566 var Vector = _dereq_('../geometry/Vector');
   -1  3567 var Sleeping = _dereq_('../core/Sleeping');
   -1  3568 var Bounds = _dereq_('../geometry/Bounds');
   -1  3569 var Axes = _dereq_('../geometry/Axes');
   -1  3570 var Common = _dereq_('../core/Common');
   -1  3571 
   -1  3572 (function() {
   -1  3573 
   -1  3574     Constraint._warming = 0.4;
   -1  3575     Constraint._torqueDampen = 1;
   -1  3576     Constraint._minLength = 0.000001;
   -1  3577 
   -1  3578     /**
   -1  3579      * Creates a new constraint.
   -1  3580      * All properties have default values, and many are pre-calculated automatically based on other properties.
   -1  3581      * To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness` value (e.g. `0.7` or above).
   -1  3582      * If the constraint is unstable, try lowering the `stiffness` value and / or increasing `engine.constraintIterations`.
   -1  3583      * For compound bodies, constraints must be applied to the parent body (not one of its parts).
   -1  3584      * See the properties section below for detailed information on what you can pass via the `options` object.
   -1  3585      * @method create
   -1  3586      * @param {} options
   -1  3587      * @return {constraint} constraint
   -1  3588      */
   -1  3589     Constraint.create = function(options) {
   -1  3590         var constraint = options;
   -1  3591 
   -1  3592         // if bodies defined but no points, use body centre
   -1  3593         if (constraint.bodyA && !constraint.pointA)
   -1  3594             constraint.pointA = { x: 0, y: 0 };
   -1  3595         if (constraint.bodyB && !constraint.pointB)
   -1  3596             constraint.pointB = { x: 0, y: 0 };
   -1  3597 
   -1  3598         // calculate static length using initial world space points
   -1  3599         var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA,
   -1  3600             initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB,
   -1  3601             length = Vector.magnitude(Vector.sub(initialPointA, initialPointB));
   -1  3602     
   -1  3603         constraint.length = typeof constraint.length !== 'undefined' ? constraint.length : length;
   -1  3604 
   -1  3605         // option defaults
   -1  3606         constraint.id = constraint.id || Common.nextId();
   -1  3607         constraint.label = constraint.label || 'Constraint';
   -1  3608         constraint.type = 'constraint';
   -1  3609         constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7);
   -1  3610         constraint.damping = constraint.damping || 0;
   -1  3611         constraint.angularStiffness = constraint.angularStiffness || 0;
   -1  3612         constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA;
   -1  3613         constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB;
   -1  3614         constraint.plugin = {};
   -1  3615 
   -1  3616         // render
   -1  3617         var render = {
   -1  3618             visible: true,
   -1  3619             lineWidth: 2,
   -1  3620             strokeStyle: '#ffffff',
   -1  3621             type: 'line',
   -1  3622             anchors: true
   -1  3623         };
   -1  3624 
   -1  3625         if (constraint.length === 0 && constraint.stiffness > 0.1) {
   -1  3626             render.type = 'pin';
   -1  3627             render.anchors = false;
   -1  3628         } else if (constraint.stiffness < 0.9) {
   -1  3629             render.type = 'spring';
   -1  3630         }
   -1  3631 
   -1  3632         constraint.render = Common.extend(render, constraint.render);
   -1  3633 
   -1  3634         return constraint;
   -1  3635     };
   -1  3636 
   -1  3637     /**
   -1  3638      * Prepares for solving by constraint warming.
   -1  3639      * @private
   -1  3640      * @method preSolveAll
   -1  3641      * @param {body[]} bodies
   -1  3642      */
   -1  3643     Constraint.preSolveAll = function(bodies) {
   -1  3644         for (var i = 0; i < bodies.length; i += 1) {
   -1  3645             var body = bodies[i],
   -1  3646                 impulse = body.constraintImpulse;
   -1  3647 
   -1  3648             if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
   -1  3649                 continue;
   -1  3650             }
   -1  3651 
   -1  3652             body.position.x += impulse.x;
   -1  3653             body.position.y += impulse.y;
   -1  3654             body.angle += impulse.angle;
   -1  3655         }
   -1  3656     };
   -1  3657 
   -1  3658     /**
   -1  3659      * Solves all constraints in a list of collisions.
   -1  3660      * @private
   -1  3661      * @method solveAll
   -1  3662      * @param {constraint[]} constraints
   -1  3663      * @param {number} timeScale
   -1  3664      */
   -1  3665     Constraint.solveAll = function(constraints, timeScale) {
   -1  3666         // Solve fixed constraints first.
   -1  3667         for (var i = 0; i < constraints.length; i += 1) {
   -1  3668             var constraint = constraints[i],
   -1  3669                 fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic),
   -1  3670                 fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);
   -1  3671 
   -1  3672             if (fixedA || fixedB) {
   -1  3673                 Constraint.solve(constraints[i], timeScale);
   -1  3674             }
   -1  3675         }
   -1  3676 
   -1  3677         // Solve free constraints last.
   -1  3678         for (i = 0; i < constraints.length; i += 1) {
   -1  3679             constraint = constraints[i];
   -1  3680             fixedA = !constraint.bodyA || (constraint.bodyA && constraint.bodyA.isStatic);
   -1  3681             fixedB = !constraint.bodyB || (constraint.bodyB && constraint.bodyB.isStatic);
   -1  3682 
   -1  3683             if (!fixedA && !fixedB) {
   -1  3684                 Constraint.solve(constraints[i], timeScale);
   -1  3685             }
   -1  3686         }
   -1  3687     };
   -1  3688 
   -1  3689     /**
   -1  3690      * Solves a distance constraint with Gauss-Siedel method.
   -1  3691      * @private
   -1  3692      * @method solve
   -1  3693      * @param {constraint} constraint
   -1  3694      * @param {number} timeScale
   -1  3695      */
   -1  3696     Constraint.solve = function(constraint, timeScale) {
   -1  3697         var bodyA = constraint.bodyA,
   -1  3698             bodyB = constraint.bodyB,
   -1  3699             pointA = constraint.pointA,
   -1  3700             pointB = constraint.pointB;
   -1  3701 
   -1  3702         if (!bodyA && !bodyB)
   -1  3703             return;
   -1  3704 
   -1  3705         // update reference angle
   -1  3706         if (bodyA && !bodyA.isStatic) {
   -1  3707             Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
   -1  3708             constraint.angleA = bodyA.angle;
   -1  3709         }
   -1  3710         
   -1  3711         // update reference angle
   -1  3712         if (bodyB && !bodyB.isStatic) {
   -1  3713             Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB);
   -1  3714             constraint.angleB = bodyB.angle;
   -1  3715         }
   -1  3716 
   -1  3717         var pointAWorld = pointA,
   -1  3718             pointBWorld = pointB;
   -1  3719 
   -1  3720         if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA);
   -1  3721         if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB);
   -1  3722 
   -1  3723         if (!pointAWorld || !pointBWorld)
   -1  3724             return;
   -1  3725 
   -1  3726         var delta = Vector.sub(pointAWorld, pointBWorld),
   -1  3727             currentLength = Vector.magnitude(delta);
   -1  3728 
   -1  3729         // prevent singularity
   -1  3730         if (currentLength < Constraint._minLength) {
   -1  3731             currentLength = Constraint._minLength;
   -1  3732         }
   -1  3733 
   -1  3734         // solve distance constraint with Gauss-Siedel method
   -1  3735         var difference = (currentLength - constraint.length) / currentLength,
   -1  3736             stiffness = constraint.stiffness < 1 ? constraint.stiffness * timeScale : constraint.stiffness,
   -1  3737             force = Vector.mult(delta, difference * stiffness),
   -1  3738             massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0),
   -1  3739             inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0),
   -1  3740             resistanceTotal = massTotal + inertiaTotal,
   -1  3741             torque,
   -1  3742             share,
   -1  3743             normal,
   -1  3744             normalVelocity,
   -1  3745             relativeVelocity;
   -1  3746 
   -1  3747         if (constraint.damping) {
   -1  3748             var zero = Vector.create();
   -1  3749             normal = Vector.div(delta, currentLength);
   -1  3750 
   -1  3751             relativeVelocity = Vector.sub(
   -1  3752                 bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero,
   -1  3753                 bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero
   -1  3754             );
   -1  3755 
   -1  3756             normalVelocity = Vector.dot(normal, relativeVelocity);
   -1  3757         }
   -1  3758 
   -1  3759         if (bodyA && !bodyA.isStatic) {
   -1  3760             share = bodyA.inverseMass / massTotal;
   -1  3761 
   -1  3762             // keep track of applied impulses for post solving
   -1  3763             bodyA.constraintImpulse.x -= force.x * share;
   -1  3764             bodyA.constraintImpulse.y -= force.y * share;
   -1  3765 
   -1  3766             // apply forces
   -1  3767             bodyA.position.x -= force.x * share;
   -1  3768             bodyA.position.y -= force.y * share;
   -1  3769 
   -1  3770             // apply damping
   -1  3771             if (constraint.damping) {
   -1  3772                 bodyA.positionPrev.x -= constraint.damping * normal.x * normalVelocity * share;
   -1  3773                 bodyA.positionPrev.y -= constraint.damping * normal.y * normalVelocity * share;
   -1  3774             }
   -1  3775 
   -1  3776             // apply torque
   -1  3777             torque = (Vector.cross(pointA, force) / resistanceTotal) * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness);
   -1  3778             bodyA.constraintImpulse.angle -= torque;
   -1  3779             bodyA.angle -= torque;
   -1  3780         }
   -1  3781 
   -1  3782         if (bodyB && !bodyB.isStatic) {
   -1  3783             share = bodyB.inverseMass / massTotal;
   -1  3784 
   -1  3785             // keep track of applied impulses for post solving
   -1  3786             bodyB.constraintImpulse.x += force.x * share;
   -1  3787             bodyB.constraintImpulse.y += force.y * share;
   -1  3788             
   -1  3789             // apply forces
   -1  3790             bodyB.position.x += force.x * share;
   -1  3791             bodyB.position.y += force.y * share;
   -1  3792 
   -1  3793             // apply damping
   -1  3794             if (constraint.damping) {
   -1  3795                 bodyB.positionPrev.x += constraint.damping * normal.x * normalVelocity * share;
   -1  3796                 bodyB.positionPrev.y += constraint.damping * normal.y * normalVelocity * share;
   -1  3797             }
   -1  3798 
   -1  3799             // apply torque
   -1  3800             torque = (Vector.cross(pointB, force) / resistanceTotal) * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness);
   -1  3801             bodyB.constraintImpulse.angle += torque;
   -1  3802             bodyB.angle += torque;
   -1  3803         }
   -1  3804 
   -1  3805     };
   -1  3806 
   -1  3807     /**
   -1  3808      * Performs body updates required after solving constraints.
   -1  3809      * @private
   -1  3810      * @method postSolveAll
   -1  3811      * @param {body[]} bodies
   -1  3812      */
   -1  3813     Constraint.postSolveAll = function(bodies) {
   -1  3814         for (var i = 0; i < bodies.length; i++) {
   -1  3815             var body = bodies[i],
   -1  3816                 impulse = body.constraintImpulse;
   -1  3817 
   -1  3818             if (body.isStatic || (impulse.x === 0 && impulse.y === 0 && impulse.angle === 0)) {
   -1  3819                 continue;
   -1  3820             }
   -1  3821 
   -1  3822             Sleeping.set(body, false);
   -1  3823 
   -1  3824             // update geometry and reset
   -1  3825             for (var j = 0; j < body.parts.length; j++) {
   -1  3826                 var part = body.parts[j];
   -1  3827                 
   -1  3828                 Vertices.translate(part.vertices, impulse);
   -1  3829 
   -1  3830                 if (j > 0) {
   -1  3831                     part.position.x += impulse.x;
   -1  3832                     part.position.y += impulse.y;
   -1  3833                 }
   -1  3834 
   -1  3835                 if (impulse.angle !== 0) {
   -1  3836                     Vertices.rotate(part.vertices, impulse.angle, body.position);
   -1  3837                     Axes.rotate(part.axes, impulse.angle);
   -1  3838                     if (j > 0) {
   -1  3839                         Vector.rotateAbout(part.position, impulse.angle, body.position, part.position);
   -1  3840                     }
   -1  3841                 }
   -1  3842 
   -1  3843                 Bounds.update(part.bounds, part.vertices, body.velocity);
   -1  3844             }
   -1  3845 
   -1  3846             // dampen the cached impulse for warming next step
   -1  3847             impulse.angle *= Constraint._warming;
   -1  3848             impulse.x *= Constraint._warming;
   -1  3849             impulse.y *= Constraint._warming;
   -1  3850         }
   -1  3851     };
   -1  3852 
   -1  3853     /*
   -1  3854     *
   -1  3855     *  Properties Documentation
   -1  3856     *
   -1  3857     */
   -1  3858 
   -1  3859     /**
   -1  3860      * An integer `Number` uniquely identifying number generated in `Composite.create` by `Common.nextId`.
   -1  3861      *
   -1  3862      * @property id
   -1  3863      * @type number
   -1  3864      */
   -1  3865 
   -1  3866     /**
   -1  3867      * A `String` denoting the type of object.
   -1  3868      *
   -1  3869      * @property type
   -1  3870      * @type string
   -1  3871      * @default "constraint"
   -1  3872      * @readOnly
   -1  3873      */
   -1  3874 
   -1  3875     /**
   -1  3876      * An arbitrary `String` name to help the user identify and manage bodies.
   -1  3877      *
   -1  3878      * @property label
   -1  3879      * @type string
   -1  3880      * @default "Constraint"
   -1  3881      */
   -1  3882 
   -1  3883     /**
   -1  3884      * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
   -1  3885      *
   -1  3886      * @property render
   -1  3887      * @type object
   -1  3888      */
   -1  3889 
   -1  3890     /**
   -1  3891      * A flag that indicates if the constraint should be rendered.
   -1  3892      *
   -1  3893      * @property render.visible
   -1  3894      * @type boolean
   -1  3895      * @default true
   -1  3896      */
   -1  3897 
   -1  3898     /**
   -1  3899      * A `Number` that defines the line width to use when rendering the constraint outline.
   -1  3900      * A value of `0` means no outline will be rendered.
   -1  3901      *
   -1  3902      * @property render.lineWidth
   -1  3903      * @type number
   -1  3904      * @default 2
   -1  3905      */
   -1  3906 
   -1  3907     /**
   -1  3908      * A `String` that defines the stroke style to use when rendering the constraint outline.
   -1  3909      * It is the same as when using a canvas, so it accepts CSS style property values.
   -1  3910      *
   -1  3911      * @property render.strokeStyle
   -1  3912      * @type string
   -1  3913      * @default a random colour
   -1  3914      */
   -1  3915 
   -1  3916     /**
   -1  3917      * A `String` that defines the constraint rendering type. 
   -1  3918      * The possible values are 'line', 'pin', 'spring'.
   -1  3919      * An appropriate render type will be automatically chosen unless one is given in options.
   -1  3920      *
   -1  3921      * @property render.type
   -1  3922      * @type string
   -1  3923      * @default 'line'
   -1  3924      */
   -1  3925 
   -1  3926     /**
   -1  3927      * A `Boolean` that defines if the constraint's anchor points should be rendered.
   -1  3928      *
   -1  3929      * @property render.anchors
   -1  3930      * @type boolean
   -1  3931      * @default true
   -1  3932      */
   -1  3933 
   -1  3934     /**
   -1  3935      * The first possible `Body` that this constraint is attached to.
   -1  3936      *
   -1  3937      * @property bodyA
   -1  3938      * @type body
   -1  3939      * @default null
   -1  3940      */
   -1  3941 
   -1  3942     /**
   -1  3943      * The second possible `Body` that this constraint is attached to.
   -1  3944      *
   -1  3945      * @property bodyB
   -1  3946      * @type body
   -1  3947      * @default null
   -1  3948      */
   -1  3949 
   -1  3950     /**
   -1  3951      * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyA` if defined, otherwise a world-space position.
   -1  3952      *
   -1  3953      * @property pointA
   -1  3954      * @type vector
   -1  3955      * @default { x: 0, y: 0 }
   -1  3956      */
   -1  3957 
   -1  3958     /**
   -1  3959      * A `Vector` that specifies the offset of the constraint from center of the `constraint.bodyB` if defined, otherwise a world-space position.
   -1  3960      *
   -1  3961      * @property pointB
   -1  3962      * @type vector
   -1  3963      * @default { x: 0, y: 0 }
   -1  3964      */
   -1  3965 
   -1  3966     /**
   -1  3967      * A `Number` that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`.
   -1  3968      * A value of `1` means the constraint should be very stiff.
   -1  3969      * A value of `0.2` means the constraint acts like a soft spring.
   -1  3970      *
   -1  3971      * @property stiffness
   -1  3972      * @type number
   -1  3973      * @default 1
   -1  3974      */
   -1  3975 
   -1  3976     /**
   -1  3977      * A `Number` that specifies the damping of the constraint, 
   -1  3978      * i.e. the amount of resistance applied to each body based on their velocities to limit the amount of oscillation.
   -1  3979      * Damping will only be apparent when the constraint also has a very low `stiffness`.
   -1  3980      * A value of `0.1` means the constraint will apply heavy damping, resulting in little to no oscillation.
   -1  3981      * A value of `0` means the constraint will apply no damping.
   -1  3982      *
   -1  3983      * @property damping
   -1  3984      * @type number
   -1  3985      * @default 0
   -1  3986      */
   -1  3987 
   -1  3988     /**
   -1  3989      * A `Number` that specifies the target resting length of the constraint. 
   -1  3990      * It is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
   -1  3991      *
   -1  3992      * @property length
   -1  3993      * @type number
   -1  3994      */
   -1  3995 
   -1  3996     /**
   -1  3997      * An object reserved for storing plugin-specific properties.
   -1  3998      *
   -1  3999      * @property plugin
   -1  4000      * @type {}
   -1  4001      */
   -1  4002 
   -1  4003 })();
   -1  4004 
   -1  4005 },{"../core/Common":14,"../core/Sleeping":22,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],13:[function(_dereq_,module,exports){
   -1  4006 /**
   -1  4007 * The `Matter.MouseConstraint` module contains methods for creating mouse constraints.
   -1  4008 * Mouse constraints are used for allowing user interaction, providing the ability to move bodies via the mouse or touch.
   -1  4009 *
   -1  4010 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  4011 *
   -1  4012 * @class MouseConstraint
   -1  4013 */
   -1  4014 
   -1  4015 var MouseConstraint = {};
   -1  4016 
   -1  4017 module.exports = MouseConstraint;
   -1  4018 
   -1  4019 var Vertices = _dereq_('../geometry/Vertices');
   -1  4020 var Sleeping = _dereq_('../core/Sleeping');
   -1  4021 var Mouse = _dereq_('../core/Mouse');
   -1  4022 var Events = _dereq_('../core/Events');
   -1  4023 var Detector = _dereq_('../collision/Detector');
   -1  4024 var Constraint = _dereq_('./Constraint');
   -1  4025 var Composite = _dereq_('../body/Composite');
   -1  4026 var Common = _dereq_('../core/Common');
   -1  4027 var Bounds = _dereq_('../geometry/Bounds');
   -1  4028 
   -1  4029 (function() {
   -1  4030 
   -1  4031     /**
   -1  4032      * Creates a new mouse constraint.
   -1  4033      * All properties have default values, and many are pre-calculated automatically based on other properties.
   -1  4034      * See the properties section below for detailed information on what you can pass via the `options` object.
   -1  4035      * @method create
   -1  4036      * @param {engine} engine
   -1  4037      * @param {} options
   -1  4038      * @return {MouseConstraint} A new MouseConstraint
   -1  4039      */
   -1  4040     MouseConstraint.create = function(engine, options) {
   -1  4041         var mouse = (engine ? engine.mouse : null) || (options ? options.mouse : null);
   -1  4042 
   -1  4043         if (!mouse) {
   -1  4044             if (engine && engine.render && engine.render.canvas) {
   -1  4045                 mouse = Mouse.create(engine.render.canvas);
   -1  4046             } else if (options && options.element) {
   -1  4047                 mouse = Mouse.create(options.element);
   -1  4048             } else {
   -1  4049                 mouse = Mouse.create();
   -1  4050                 Common.warn('MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected');
   -1  4051             }
   -1  4052         }
   -1  4053 
   -1  4054         var constraint = Constraint.create({ 
   -1  4055             label: 'Mouse Constraint',
   -1  4056             pointA: mouse.position,
   -1  4057             pointB: { x: 0, y: 0 },
   -1  4058             length: 0.01, 
   -1  4059             stiffness: 0.1,
   -1  4060             angularStiffness: 1,
   -1  4061             render: {
   -1  4062                 strokeStyle: '#90EE90',
   -1  4063                 lineWidth: 3
   -1  4064             }
   -1  4065         });
   -1  4066 
   -1  4067         var defaults = {
   -1  4068             type: 'mouseConstraint',
   -1  4069             mouse: mouse,
   -1  4070             element: null,
   -1  4071             body: null,
   -1  4072             constraint: constraint,
   -1  4073             collisionFilter: {
   -1  4074                 category: 0x0001,
   -1  4075                 mask: 0xFFFFFFFF,
   -1  4076                 group: 0
   -1  4077             }
   -1  4078         };
   -1  4079 
   -1  4080         var mouseConstraint = Common.extend(defaults, options);
   -1  4081 
   -1  4082         Events.on(engine, 'beforeUpdate', function() {
   -1  4083             var allBodies = Composite.allBodies(engine.world);
   -1  4084             MouseConstraint.update(mouseConstraint, allBodies);
   -1  4085             MouseConstraint._triggerEvents(mouseConstraint);
   -1  4086         });
   -1  4087 
   -1  4088         return mouseConstraint;
   -1  4089     };
   -1  4090 
   -1  4091     /**
   -1  4092      * Updates the given mouse constraint.
   -1  4093      * @private
   -1  4094      * @method update
   -1  4095      * @param {MouseConstraint} mouseConstraint
   -1  4096      * @param {body[]} bodies
   -1  4097      */
   -1  4098     MouseConstraint.update = function(mouseConstraint, bodies) {
   -1  4099         var mouse = mouseConstraint.mouse,
   -1  4100             constraint = mouseConstraint.constraint,
   -1  4101             body = mouseConstraint.body;
   -1  4102 
   -1  4103         if (mouse.button === 0) {
   -1  4104             if (!constraint.bodyB) {
   -1  4105                 for (var i = 0; i < bodies.length; i++) {
   -1  4106                     body = bodies[i];
   -1  4107                     if (Bounds.contains(body.bounds, mouse.position) 
   -1  4108                             && Detector.canCollide(body.collisionFilter, mouseConstraint.collisionFilter)) {
   -1  4109                         for (var j = body.parts.length > 1 ? 1 : 0; j < body.parts.length; j++) {
   -1  4110                             var part = body.parts[j];
   -1  4111                             if (Vertices.contains(part.vertices, mouse.position)) {
   -1  4112                                 constraint.pointA = mouse.position;
   -1  4113                                 constraint.bodyB = mouseConstraint.body = body;
   -1  4114                                 constraint.pointB = { x: mouse.position.x - body.position.x, y: mouse.position.y - body.position.y };
   -1  4115                                 constraint.angleB = body.angle;
   -1  4116 
   -1  4117                                 Sleeping.set(body, false);
   -1  4118                                 Events.trigger(mouseConstraint, 'startdrag', { mouse: mouse, body: body });
   -1  4119 
   -1  4120                                 break;
   -1  4121                             }
   -1  4122                         }
   -1  4123                     }
   -1  4124                 }
   -1  4125             } else {
   -1  4126                 Sleeping.set(constraint.bodyB, false);
   -1  4127                 constraint.pointA = mouse.position;
   -1  4128             }
   -1  4129         } else {
   -1  4130             constraint.bodyB = mouseConstraint.body = null;
   -1  4131             constraint.pointB = null;
   -1  4132 
   -1  4133             if (body)
   -1  4134                 Events.trigger(mouseConstraint, 'enddrag', { mouse: mouse, body: body });
   -1  4135         }
   -1  4136     };
   -1  4137 
   -1  4138     /**
   -1  4139      * Triggers mouse constraint events.
   -1  4140      * @method _triggerEvents
   -1  4141      * @private
   -1  4142      * @param {mouse} mouseConstraint
   -1  4143      */
   -1  4144     MouseConstraint._triggerEvents = function(mouseConstraint) {
   -1  4145         var mouse = mouseConstraint.mouse,
   -1  4146             mouseEvents = mouse.sourceEvents;
   -1  4147 
   -1  4148         if (mouseEvents.mousemove)
   -1  4149             Events.trigger(mouseConstraint, 'mousemove', { mouse: mouse });
   -1  4150 
   -1  4151         if (mouseEvents.mousedown)
   -1  4152             Events.trigger(mouseConstraint, 'mousedown', { mouse: mouse });
   -1  4153 
   -1  4154         if (mouseEvents.mouseup)
   -1  4155             Events.trigger(mouseConstraint, 'mouseup', { mouse: mouse });
   -1  4156 
   -1  4157         // reset the mouse state ready for the next step
   -1  4158         Mouse.clearSourceEvents(mouse);
   -1  4159     };
   -1  4160 
   -1  4161     /*
   -1  4162     *
   -1  4163     *  Events Documentation
   -1  4164     *
   -1  4165     */
   -1  4166 
   -1  4167     /**
   -1  4168     * Fired when the mouse has moved (or a touch moves) during the last step
   -1  4169     *
   -1  4170     * @event mousemove
   -1  4171     * @param {} event An event object
   -1  4172     * @param {mouse} event.mouse The engine's mouse instance
   -1  4173     * @param {} event.source The source object of the event
   -1  4174     * @param {} event.name The name of the event
   -1  4175     */
   -1  4176 
   -1  4177     /**
   -1  4178     * Fired when the mouse is down (or a touch has started) during the last step
   -1  4179     *
   -1  4180     * @event mousedown
   -1  4181     * @param {} event An event object
   -1  4182     * @param {mouse} event.mouse The engine's mouse instance
   -1  4183     * @param {} event.source The source object of the event
   -1  4184     * @param {} event.name The name of the event
   -1  4185     */
   -1  4186 
   -1  4187     /**
   -1  4188     * Fired when the mouse is up (or a touch has ended) during the last step
   -1  4189     *
   -1  4190     * @event mouseup
   -1  4191     * @param {} event An event object
   -1  4192     * @param {mouse} event.mouse The engine's mouse instance
   -1  4193     * @param {} event.source The source object of the event
   -1  4194     * @param {} event.name The name of the event
   -1  4195     */
   -1  4196 
   -1  4197     /**
   -1  4198     * Fired when the user starts dragging a body
   -1  4199     *
   -1  4200     * @event startdrag
   -1  4201     * @param {} event An event object
   -1  4202     * @param {mouse} event.mouse The engine's mouse instance
   -1  4203     * @param {body} event.body The body being dragged
   -1  4204     * @param {} event.source The source object of the event
   -1  4205     * @param {} event.name The name of the event
   -1  4206     */
   -1  4207 
   -1  4208     /**
   -1  4209     * Fired when the user ends dragging a body
   -1  4210     *
   -1  4211     * @event enddrag
   -1  4212     * @param {} event An event object
   -1  4213     * @param {mouse} event.mouse The engine's mouse instance
   -1  4214     * @param {body} event.body The body that has stopped being dragged
   -1  4215     * @param {} event.source The source object of the event
   -1  4216     * @param {} event.name The name of the event
   -1  4217     */
   -1  4218 
   -1  4219     /*
   -1  4220     *
   -1  4221     *  Properties Documentation
   -1  4222     *
   -1  4223     */
   -1  4224 
   -1  4225     /**
   -1  4226      * A `String` denoting the type of object.
   -1  4227      *
   -1  4228      * @property type
   -1  4229      * @type string
   -1  4230      * @default "constraint"
   -1  4231      * @readOnly
   -1  4232      */
   -1  4233 
   -1  4234     /**
   -1  4235      * The `Mouse` instance in use. If not supplied in `MouseConstraint.create`, one will be created.
   -1  4236      *
   -1  4237      * @property mouse
   -1  4238      * @type mouse
   -1  4239      * @default mouse
   -1  4240      */
   -1  4241 
   -1  4242     /**
   -1  4243      * The `Body` that is currently being moved by the user, or `null` if no body.
   -1  4244      *
   -1  4245      * @property body
   -1  4246      * @type body
   -1  4247      * @default null
   -1  4248      */
   -1  4249 
   -1  4250     /**
   -1  4251      * The `Constraint` object that is used to move the body during interaction.
   -1  4252      *
   -1  4253      * @property constraint
   -1  4254      * @type constraint
   -1  4255      */
   -1  4256 
   -1  4257     /**
   -1  4258      * An `Object` that specifies the collision filter properties.
   -1  4259      * The collision filter allows the user to define which types of body this mouse constraint can interact with.
   -1  4260      * See `body.collisionFilter` for more information.
   -1  4261      *
   -1  4262      * @property collisionFilter
   -1  4263      * @type object
   -1  4264      */
   -1  4265 
   -1  4266 })();
   -1  4267 
   -1  4268 },{"../body/Composite":2,"../collision/Detector":5,"../core/Common":14,"../core/Events":16,"../core/Mouse":19,"../core/Sleeping":22,"../geometry/Bounds":26,"../geometry/Vertices":29,"./Constraint":12}],14:[function(_dereq_,module,exports){
   -1  4269 (function (global){
   -1  4270 /**
   -1  4271 * The `Matter.Common` module contains utility functions that are common to all modules.
   -1  4272 *
   -1  4273 * @class Common
   -1  4274 */
   -1  4275 
   -1  4276 var Common = {};
   -1  4277 
   -1  4278 module.exports = Common;
   -1  4279 
   -1  4280 (function() {
   -1  4281 
   -1  4282     Common._nextId = 0;
   -1  4283     Common._seed = 0;
   -1  4284     Common._nowStartTime = +(new Date());
   -1  4285 
   -1  4286     /**
   -1  4287      * Extends the object in the first argument using the object in the second argument.
   -1  4288      * @method extend
   -1  4289      * @param {} obj
   -1  4290      * @param {boolean} deep
   -1  4291      * @return {} obj extended
   -1  4292      */
   -1  4293     Common.extend = function(obj, deep) {
   -1  4294         var argsStart,
   -1  4295             args,
   -1  4296             deepClone;
   -1  4297 
   -1  4298         if (typeof deep === 'boolean') {
   -1  4299             argsStart = 2;
   -1  4300             deepClone = deep;
   -1  4301         } else {
   -1  4302             argsStart = 1;
   -1  4303             deepClone = true;
   -1  4304         }
   -1  4305 
   -1  4306         for (var i = argsStart; i < arguments.length; i++) {
   -1  4307             var source = arguments[i];
   -1  4308 
   -1  4309             if (source) {
   -1  4310                 for (var prop in source) {
   -1  4311                     if (deepClone && source[prop] && source[prop].constructor === Object) {
   -1  4312                         if (!obj[prop] || obj[prop].constructor === Object) {
   -1  4313                             obj[prop] = obj[prop] || {};
   -1  4314                             Common.extend(obj[prop], deepClone, source[prop]);
   -1  4315                         } else {
   -1  4316                             obj[prop] = source[prop];
   -1  4317                         }
   -1  4318                     } else {
   -1  4319                         obj[prop] = source[prop];
   -1  4320                     }
   -1  4321                 }
   -1  4322             }
   -1  4323         }
   -1  4324         
   -1  4325         return obj;
   -1  4326     };
   -1  4327 
   -1  4328     /**
   -1  4329      * Creates a new clone of the object, if deep is true references will also be cloned.
   -1  4330      * @method clone
   -1  4331      * @param {} obj
   -1  4332      * @param {bool} deep
   -1  4333      * @return {} obj cloned
   -1  4334      */
   -1  4335     Common.clone = function(obj, deep) {
   -1  4336         return Common.extend({}, deep, obj);
   -1  4337     };
   -1  4338 
   -1  4339     /**
   -1  4340      * Returns the list of keys for the given object.
   -1  4341      * @method keys
   -1  4342      * @param {} obj
   -1  4343      * @return {string[]} keys
   -1  4344      */
   -1  4345     Common.keys = function(obj) {
   -1  4346         if (Object.keys)
   -1  4347             return Object.keys(obj);
   -1  4348 
   -1  4349         // avoid hasOwnProperty for performance
   -1  4350         var keys = [];
   -1  4351         for (var key in obj)
   -1  4352             keys.push(key);
   -1  4353         return keys;
   -1  4354     };
   -1  4355 
   -1  4356     /**
   -1  4357      * Returns the list of values for the given object.
   -1  4358      * @method values
   -1  4359      * @param {} obj
   -1  4360      * @return {array} Array of the objects property values
   -1  4361      */
   -1  4362     Common.values = function(obj) {
   -1  4363         var values = [];
   -1  4364         
   -1  4365         if (Object.keys) {
   -1  4366             var keys = Object.keys(obj);
   -1  4367             for (var i = 0; i < keys.length; i++) {
   -1  4368                 values.push(obj[keys[i]]);
   -1  4369             }
   -1  4370             return values;
   -1  4371         }
   -1  4372         
   -1  4373         // avoid hasOwnProperty for performance
   -1  4374         for (var key in obj)
   -1  4375             values.push(obj[key]);
   -1  4376         return values;
   -1  4377     };
   -1  4378 
   -1  4379     /**
   -1  4380      * Gets a value from `base` relative to the `path` string.
   -1  4381      * @method get
   -1  4382      * @param {} obj The base object
   -1  4383      * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz'
   -1  4384      * @param {number} [begin] Path slice begin
   -1  4385      * @param {number} [end] Path slice end
   -1  4386      * @return {} The object at the given path
   -1  4387      */
   -1  4388     Common.get = function(obj, path, begin, end) {
   -1  4389         path = path.split('.').slice(begin, end);
   -1  4390 
   -1  4391         for (var i = 0; i < path.length; i += 1) {
   -1  4392             obj = obj[path[i]];
   -1  4393         }
   -1  4394 
   -1  4395         return obj;
   -1  4396     };
   -1  4397 
   -1  4398     /**
   -1  4399      * Sets a value on `base` relative to the given `path` string.
   -1  4400      * @method set
   -1  4401      * @param {} obj The base object
   -1  4402      * @param {string} path The path relative to `base`, e.g. 'Foo.Bar.baz'
   -1  4403      * @param {} val The value to set
   -1  4404      * @param {number} [begin] Path slice begin
   -1  4405      * @param {number} [end] Path slice end
   -1  4406      * @return {} Pass through `val` for chaining
   -1  4407      */
   -1  4408     Common.set = function(obj, path, val, begin, end) {
   -1  4409         var parts = path.split('.').slice(begin, end);
   -1  4410         Common.get(obj, path, 0, -1)[parts[parts.length - 1]] = val;
   -1  4411         return val;
   -1  4412     };
   -1  4413 
   -1  4414     /**
   -1  4415      * Shuffles the given array in-place.
   -1  4416      * The function uses a seeded random generator.
   -1  4417      * @method shuffle
   -1  4418      * @param {array} array
   -1  4419      * @return {array} array shuffled randomly
   -1  4420      */
   -1  4421     Common.shuffle = function(array) {
   -1  4422         for (var i = array.length - 1; i > 0; i--) {
   -1  4423             var j = Math.floor(Common.random() * (i + 1));
   -1  4424             var temp = array[i];
   -1  4425             array[i] = array[j];
   -1  4426             array[j] = temp;
   -1  4427         }
   -1  4428         return array;
   -1  4429     };
   -1  4430 
   -1  4431     /**
   -1  4432      * Randomly chooses a value from a list with equal probability.
   -1  4433      * The function uses a seeded random generator.
   -1  4434      * @method choose
   -1  4435      * @param {array} choices
   -1  4436      * @return {object} A random choice object from the array
   -1  4437      */
   -1  4438     Common.choose = function(choices) {
   -1  4439         return choices[Math.floor(Common.random() * choices.length)];
   -1  4440     };
   -1  4441 
   -1  4442     /**
   -1  4443      * Returns true if the object is a HTMLElement, otherwise false.
   -1  4444      * @method isElement
   -1  4445      * @param {object} obj
   -1  4446      * @return {boolean} True if the object is a HTMLElement, otherwise false
   -1  4447      */
   -1  4448     Common.isElement = function(obj) {
   -1  4449         if (typeof HTMLElement !== 'undefined') {
   -1  4450             return obj instanceof HTMLElement;
   -1  4451         }
   -1  4452 
   -1  4453         return !!(obj && obj.nodeType && obj.nodeName);
   -1  4454     };
   -1  4455 
   -1  4456     /**
   -1  4457      * Returns true if the object is an array.
   -1  4458      * @method isArray
   -1  4459      * @param {object} obj
   -1  4460      * @return {boolean} True if the object is an array, otherwise false
   -1  4461      */
   -1  4462     Common.isArray = function(obj) {
   -1  4463         return Object.prototype.toString.call(obj) === '[object Array]';
   -1  4464     };
   -1  4465 
   -1  4466     /**
   -1  4467      * Returns true if the object is a function.
   -1  4468      * @method isFunction
   -1  4469      * @param {object} obj
   -1  4470      * @return {boolean} True if the object is a function, otherwise false
   -1  4471      */
   -1  4472     Common.isFunction = function(obj) {
   -1  4473         return typeof obj === "function";
   -1  4474     };
   -1  4475 
   -1  4476     /**
   -1  4477      * Returns true if the object is a plain object.
   -1  4478      * @method isPlainObject
   -1  4479      * @param {object} obj
   -1  4480      * @return {boolean} True if the object is a plain object, otherwise false
   -1  4481      */
   -1  4482     Common.isPlainObject = function(obj) {
   -1  4483         return typeof obj === 'object' && obj.constructor === Object;
   -1  4484     };
   -1  4485 
   -1  4486     /**
   -1  4487      * Returns true if the object is a string.
   -1  4488      * @method isString
   -1  4489      * @param {object} obj
   -1  4490      * @return {boolean} True if the object is a string, otherwise false
   -1  4491      */
   -1  4492     Common.isString = function(obj) {
   -1  4493         return toString.call(obj) === '[object String]';
   -1  4494     };
   -1  4495     
   -1  4496     /**
   -1  4497      * Returns the given value clamped between a minimum and maximum value.
   -1  4498      * @method clamp
   -1  4499      * @param {number} value
   -1  4500      * @param {number} min
   -1  4501      * @param {number} max
   -1  4502      * @return {number} The value clamped between min and max inclusive
   -1  4503      */
   -1  4504     Common.clamp = function(value, min, max) {
   -1  4505         if (value < min)
   -1  4506             return min;
   -1  4507         if (value > max)
   -1  4508             return max;
   -1  4509         return value;
   -1  4510     };
   -1  4511     
   -1  4512     /**
   -1  4513      * Returns the sign of the given value.
   -1  4514      * @method sign
   -1  4515      * @param {number} value
   -1  4516      * @return {number} -1 if negative, +1 if 0 or positive
   -1  4517      */
   -1  4518     Common.sign = function(value) {
   -1  4519         return value < 0 ? -1 : 1;
   -1  4520     };
   -1  4521     
   -1  4522     /**
   -1  4523      * Returns the current timestamp since the time origin (e.g. from page load).
   -1  4524      * The result will be high-resolution including decimal places if available.
   -1  4525      * @method now
   -1  4526      * @return {number} the current timestamp
   -1  4527      */
   -1  4528     Common.now = function() {
   -1  4529         if (window.performance) {
   -1  4530             if (window.performance.now) {
   -1  4531                 return window.performance.now();
   -1  4532             } else if (window.performance.webkitNow) {
   -1  4533                 return window.performance.webkitNow();
   -1  4534             }
   -1  4535         }
   -1  4536 
   -1  4537         return (new Date()) - Common._nowStartTime;
   -1  4538     };
   -1  4539     
   -1  4540     /**
   -1  4541      * Returns a random value between a minimum and a maximum value inclusive.
   -1  4542      * The function uses a seeded random generator.
   -1  4543      * @method random
   -1  4544      * @param {number} min
   -1  4545      * @param {number} max
   -1  4546      * @return {number} A random number between min and max inclusive
   -1  4547      */
   -1  4548     Common.random = function(min, max) {
   -1  4549         min = (typeof min !== "undefined") ? min : 0;
   -1  4550         max = (typeof max !== "undefined") ? max : 1;
   -1  4551         return min + _seededRandom() * (max - min);
   -1  4552     };
   -1  4553 
   -1  4554     var _seededRandom = function() {
   -1  4555         // https://en.wikipedia.org/wiki/Linear_congruential_generator
   -1  4556         Common._seed = (Common._seed * 9301 + 49297) % 233280;
   -1  4557         return Common._seed / 233280;
   -1  4558     };
   -1  4559 
   -1  4560     /**
   -1  4561      * Converts a CSS hex colour string into an integer.
   -1  4562      * @method colorToNumber
   -1  4563      * @param {string} colorString
   -1  4564      * @return {number} An integer representing the CSS hex string
   -1  4565      */
   -1  4566     Common.colorToNumber = function(colorString) {
   -1  4567         colorString = colorString.replace('#','');
   -1  4568 
   -1  4569         if (colorString.length == 3) {
   -1  4570             colorString = colorString.charAt(0) + colorString.charAt(0)
   -1  4571                         + colorString.charAt(1) + colorString.charAt(1)
   -1  4572                         + colorString.charAt(2) + colorString.charAt(2);
   -1  4573         }
   -1  4574 
   -1  4575         return parseInt(colorString, 16);
   -1  4576     };
   -1  4577 
   -1  4578     /**
   -1  4579      * The console logging level to use, where each level includes all levels above and excludes the levels below.
   -1  4580      * The default level is 'debug' which shows all console messages.  
   -1  4581      *
   -1  4582      * Possible level values are:
   -1  4583      * - 0 = None
   -1  4584      * - 1 = Debug
   -1  4585      * - 2 = Info
   -1  4586      * - 3 = Warn
   -1  4587      * - 4 = Error
   -1  4588      * @property Common.logLevel
   -1  4589      * @type {Number}
   -1  4590      * @default 1
   -1  4591      */
   -1  4592     Common.logLevel = 1;
   -1  4593 
   -1  4594     /**
   -1  4595      * Shows a `console.log` message only if the current `Common.logLevel` allows it.
   -1  4596      * The message will be prefixed with 'matter-js' to make it easily identifiable.
   -1  4597      * @method log
   -1  4598      * @param ...objs {} The objects to log.
   -1  4599      */
   -1  4600     Common.log = function() {
   -1  4601         if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
   -1  4602             console.log.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
   -1  4603         }
   -1  4604     };
   -1  4605 
   -1  4606     /**
   -1  4607      * Shows a `console.info` message only if the current `Common.logLevel` allows it.
   -1  4608      * The message will be prefixed with 'matter-js' to make it easily identifiable.
   -1  4609      * @method info
   -1  4610      * @param ...objs {} The objects to log.
   -1  4611      */
   -1  4612     Common.info = function() {
   -1  4613         if (console && Common.logLevel > 0 && Common.logLevel <= 2) {
   -1  4614             console.info.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
   -1  4615         }
   -1  4616     };
   -1  4617 
   -1  4618     /**
   -1  4619      * Shows a `console.warn` message only if the current `Common.logLevel` allows it.
   -1  4620      * The message will be prefixed with 'matter-js' to make it easily identifiable.
   -1  4621      * @method warn
   -1  4622      * @param ...objs {} The objects to log.
   -1  4623      */
   -1  4624     Common.warn = function() {
   -1  4625         if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
   -1  4626             console.warn.apply(console, ['matter-js:'].concat(Array.prototype.slice.call(arguments)));
   -1  4627         }
   -1  4628     };
   -1  4629 
   -1  4630     /**
   -1  4631      * Returns the next unique sequential ID.
   -1  4632      * @method nextId
   -1  4633      * @return {Number} Unique sequential ID
   -1  4634      */
   -1  4635     Common.nextId = function() {
   -1  4636         return Common._nextId++;
   -1  4637     };
   -1  4638 
   -1  4639     /**
   -1  4640      * A cross browser compatible indexOf implementation.
   -1  4641      * @method indexOf
   -1  4642      * @param {array} haystack
   -1  4643      * @param {object} needle
   -1  4644      * @return {number} The position of needle in haystack, otherwise -1.
   -1  4645      */
   -1  4646     Common.indexOf = function(haystack, needle) {
   -1  4647         if (haystack.indexOf)
   -1  4648             return haystack.indexOf(needle);
   -1  4649 
   -1  4650         for (var i = 0; i < haystack.length; i++) {
   -1  4651             if (haystack[i] === needle)
   -1  4652                 return i;
   -1  4653         }
   -1  4654 
   -1  4655         return -1;
   -1  4656     };
   -1  4657 
   -1  4658     /**
   -1  4659      * A cross browser compatible array map implementation.
   -1  4660      * @method map
   -1  4661      * @param {array} list
   -1  4662      * @param {function} func
   -1  4663      * @return {array} Values from list transformed by func.
   -1  4664      */
   -1  4665     Common.map = function(list, func) {
   -1  4666         if (list.map) {
   -1  4667             return list.map(func);
   -1  4668         }
   -1  4669 
   -1  4670         var mapped = [];
   -1  4671 
   -1  4672         for (var i = 0; i < list.length; i += 1) {
   -1  4673             mapped.push(func(list[i]));
   -1  4674         }
   -1  4675 
   -1  4676         return mapped;
   -1  4677     };
   -1  4678 
   -1  4679     /**
   -1  4680      * Takes a directed graph and returns the partially ordered set of vertices in topological order.
   -1  4681      * Circular dependencies are allowed.
   -1  4682      * @method topologicalSort
   -1  4683      * @param {object} graph
   -1  4684      * @return {array} Partially ordered set of vertices in topological order.
   -1  4685      */
   -1  4686     Common.topologicalSort = function(graph) {
   -1  4687         // https://github.com/mgechev/javascript-algorithms
   -1  4688         // Copyright (c) Minko Gechev (MIT license)
   -1  4689         // Modifications: tidy formatting and naming
   -1  4690         var result = [],
   -1  4691             visited = [],
   -1  4692             temp = [];
   -1  4693 
   -1  4694         for (var node in graph) {
   -1  4695             if (!visited[node] && !temp[node]) {
   -1  4696                 Common._topologicalSort(node, visited, temp, graph, result);
   -1  4697             }
   -1  4698         }
   -1  4699 
   -1  4700         return result;
   -1  4701     };
   -1  4702 
   -1  4703     Common._topologicalSort = function(node, visited, temp, graph, result) {
   -1  4704         var neighbors = graph[node] || [];
   -1  4705         temp[node] = true;
   -1  4706 
   -1  4707         for (var i = 0; i < neighbors.length; i += 1) {
   -1  4708             var neighbor = neighbors[i];
   -1  4709 
   -1  4710             if (temp[neighbor]) {
   -1  4711                 // skip circular dependencies
   -1  4712                 continue;
   -1  4713             }
   -1  4714 
   -1  4715             if (!visited[neighbor]) {
   -1  4716                 Common._topologicalSort(neighbor, visited, temp, graph, result);
   -1  4717             }
   -1  4718         }
   -1  4719 
   -1  4720         temp[node] = false;
   -1  4721         visited[node] = true;
   -1  4722 
   -1  4723         result.push(node);
   -1  4724     };
   -1  4725 
   -1  4726     /**
   -1  4727      * Takes _n_ functions as arguments and returns a new function that calls them in order.
   -1  4728      * The arguments applied when calling the new function will also be applied to every function passed.
   -1  4729      * The value of `this` refers to the last value returned in the chain that was not `undefined`.
   -1  4730      * Therefore if a passed function does not return a value, the previously returned value is maintained.
   -1  4731      * After all passed functions have been called the new function returns the last returned value (if any).
   -1  4732      * If any of the passed functions are a chain, then the chain will be flattened.
   -1  4733      * @method chain
   -1  4734      * @param ...funcs {function} The functions to chain.
   -1  4735      * @return {function} A new function that calls the passed functions in order.
   -1  4736      */
   -1  4737     Common.chain = function() {
   -1  4738         var funcs = [];
   -1  4739 
   -1  4740         for (var i = 0; i < arguments.length; i += 1) {
   -1  4741             var func = arguments[i];
   -1  4742 
   -1  4743             if (func._chained) {
   -1  4744                 // flatten already chained functions
   -1  4745                 funcs.push.apply(funcs, func._chained);
   -1  4746             } else {
   -1  4747                 funcs.push(func);
   -1  4748             }
   -1  4749         }
   -1  4750 
   -1  4751         var chain = function() {
   -1  4752             // https://github.com/GoogleChrome/devtools-docs/issues/53#issuecomment-51941358
   -1  4753             var lastResult,
   -1  4754                 args = new Array(arguments.length);
   -1  4755 
   -1  4756             for (var i = 0, l = arguments.length; i < l; i++) {
   -1  4757                 args[i] = arguments[i];
   -1  4758             }
   -1  4759 
   -1  4760             for (i = 0; i < funcs.length; i += 1) {
   -1  4761                 var result = funcs[i].apply(lastResult, args);
   -1  4762 
   -1  4763                 if (typeof result !== 'undefined') {
   -1  4764                     lastResult = result;
   -1  4765                 }
   -1  4766             }
   -1  4767 
   -1  4768             return lastResult;
   -1  4769         };
   -1  4770 
   -1  4771         chain._chained = funcs;
   -1  4772 
   -1  4773         return chain;
   -1  4774     };
   -1  4775 
   -1  4776     /**
   -1  4777      * Chains a function to excute before the original function on the given `path` relative to `base`.
   -1  4778      * See also docs for `Common.chain`.
   -1  4779      * @method chainPathBefore
   -1  4780      * @param {} base The base object
   -1  4781      * @param {string} path The path relative to `base`
   -1  4782      * @param {function} func The function to chain before the original
   -1  4783      * @return {function} The chained function that replaced the original
   -1  4784      */
   -1  4785     Common.chainPathBefore = function(base, path, func) {
   -1  4786         return Common.set(base, path, Common.chain(
   -1  4787             func,
   -1  4788             Common.get(base, path)
   -1  4789         ));
   -1  4790     };
   -1  4791 
   -1  4792     /**
   -1  4793      * Chains a function to excute after the original function on the given `path` relative to `base`.
   -1  4794      * See also docs for `Common.chain`.
   -1  4795      * @method chainPathAfter
   -1  4796      * @param {} base The base object
   -1  4797      * @param {string} path The path relative to `base`
   -1  4798      * @param {function} func The function to chain after the original
   -1  4799      * @return {function} The chained function that replaced the original
   -1  4800      */
   -1  4801     Common.chainPathAfter = function(base, path, func) {
   -1  4802         return Common.set(base, path, Common.chain(
   -1  4803             Common.get(base, path),
   -1  4804             func
   -1  4805         ));
   -1  4806     };
   -1  4807 
   -1  4808     /**
   -1  4809      * Used to require external libraries outside of the bundle.
   -1  4810      * It first looks for the `globalName` on the environment's global namespace.
   -1  4811      * If the global is not found, it will fall back to using the standard `require` using the `moduleName`.
   -1  4812      * @private
   -1  4813      * @method _requireGlobal
   -1  4814      * @param {string} globalName The global module name
   -1  4815      * @param {string} moduleName The fallback CommonJS module name
   -1  4816      * @return {} The loaded module
   -1  4817      */
   -1  4818     Common._requireGlobal = function(globalName, moduleName) {
   -1  4819         var obj = (typeof window !== 'undefined' ? window[globalName] : typeof global !== 'undefined' ? global[globalName] : null);
   -1  4820         return obj || _dereq_(moduleName);
   -1  4821     };
   -1  4822 })();
   -1  4823 
   -1  4824 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
   -1  4825 },{}],15:[function(_dereq_,module,exports){
   -1  4826 /**
   -1  4827 * The `Matter.Engine` module contains methods for creating and manipulating engines.
   -1  4828 * An engine is a controller that manages updating the simulation of the world.
   -1  4829 * See `Matter.Runner` for an optional game loop utility.
   -1  4830 *
   -1  4831 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  4832 *
   -1  4833 * @class Engine
   -1  4834 */
   -1  4835 
   -1  4836 var Engine = {};
   -1  4837 
   -1  4838 module.exports = Engine;
   -1  4839 
   -1  4840 var World = _dereq_('../body/World');
   -1  4841 var Sleeping = _dereq_('./Sleeping');
   -1  4842 var Resolver = _dereq_('../collision/Resolver');
   -1  4843 var Render = _dereq_('../render/Render');
   -1  4844 var Pairs = _dereq_('../collision/Pairs');
   -1  4845 var Metrics = _dereq_('./Metrics');
   -1  4846 var Grid = _dereq_('../collision/Grid');
   -1  4847 var Events = _dereq_('./Events');
   -1  4848 var Composite = _dereq_('../body/Composite');
   -1  4849 var Constraint = _dereq_('../constraint/Constraint');
   -1  4850 var Common = _dereq_('./Common');
   -1  4851 var Body = _dereq_('../body/Body');
   -1  4852 
   -1  4853 (function() {
   -1  4854 
   -1  4855     /**
   -1  4856      * Creates a new engine. The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  4857      * All properties have default values, and many are pre-calculated automatically based on other properties.
   -1  4858      * See the properties section below for detailed information on what you can pass via the `options` object.
   -1  4859      * @method create
   -1  4860      * @param {object} [options]
   -1  4861      * @return {engine} engine
   -1  4862      */
   -1  4863     Engine.create = function(element, options) {
   -1  4864         // options may be passed as the first (and only) argument
   -1  4865         options = Common.isElement(element) ? options : element;
   -1  4866         element = Common.isElement(element) ? element : null;
   -1  4867         options = options || {};
   -1  4868 
   -1  4869         if (element || options.render) {
   -1  4870             Common.warn('Engine.create: engine.render is deprecated (see docs)');
   -1  4871         }
   -1  4872 
   -1  4873         var defaults = {
   -1  4874             positionIterations: 6,
   -1  4875             velocityIterations: 4,
   -1  4876             constraintIterations: 2,
   -1  4877             enableSleeping: false,
   -1  4878             events: [],
   -1  4879             plugin: {},
   -1  4880             timing: {
   -1  4881                 timestamp: 0,
   -1  4882                 timeScale: 1
   -1  4883             },
   -1  4884             broadphase: {
   -1  4885                 controller: Grid
   -1  4886             }
   -1  4887         };
   -1  4888 
   -1  4889         var engine = Common.extend(defaults, options);
   -1  4890 
   -1  4891         // @deprecated
   -1  4892         if (element || engine.render) {
   -1  4893             var renderDefaults = {
   -1  4894                 element: element,
   -1  4895                 controller: Render
   -1  4896             };
   -1  4897             
   -1  4898             engine.render = Common.extend(renderDefaults, engine.render);
   -1  4899         }
   -1  4900 
   -1  4901         // @deprecated
   -1  4902         if (engine.render && engine.render.controller) {
   -1  4903             engine.render = engine.render.controller.create(engine.render);
   -1  4904         }
   -1  4905 
   -1  4906         // @deprecated
   -1  4907         if (engine.render) {
   -1  4908             engine.render.engine = engine;
   -1  4909         }
   -1  4910 
   -1  4911         engine.world = options.world || World.create(engine.world);
   -1  4912         engine.pairs = Pairs.create();
   -1  4913         engine.broadphase = engine.broadphase.controller.create(engine.broadphase);
   -1  4914         engine.metrics = engine.metrics || { extended: false };
   -1  4915 
   -1  4916 
   -1  4917         return engine;
   -1  4918     };
   -1  4919 
   -1  4920     /**
   -1  4921      * Moves the simulation forward in time by `delta` ms.
   -1  4922      * The `correction` argument is an optional `Number` that specifies the time correction factor to apply to the update.
   -1  4923      * This can help improve the accuracy of the simulation in cases where `delta` is changing between updates.
   -1  4924      * The value of `correction` is defined as `delta / lastDelta`, i.e. the percentage change of `delta` over the last step.
   -1  4925      * Therefore the value is always `1` (no correction) when `delta` constant (or when no correction is desired, which is the default).
   -1  4926      * See the paper on <a href="http://lonesock.net/article/verlet.html">Time Corrected Verlet</a> for more information.
   -1  4927      *
   -1  4928      * Triggers `beforeUpdate` and `afterUpdate` events.
   -1  4929      * Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
   -1  4930      * @method update
   -1  4931      * @param {engine} engine
   -1  4932      * @param {number} [delta=16.666]
   -1  4933      * @param {number} [correction=1]
   -1  4934      */
   -1  4935     Engine.update = function(engine, delta, correction) {
   -1  4936         delta = delta || 1000 / 60;
   -1  4937         correction = correction || 1;
   -1  4938 
   -1  4939         var world = engine.world,
   -1  4940             timing = engine.timing,
   -1  4941             broadphase = engine.broadphase,
   -1  4942             broadphasePairs = [],
   -1  4943             i;
   -1  4944 
   -1  4945         // increment timestamp
   -1  4946         timing.timestamp += delta * timing.timeScale;
   -1  4947 
   -1  4948         // create an event object
   -1  4949         var event = {
   -1  4950             timestamp: timing.timestamp
   -1  4951         };
   -1  4952 
   -1  4953         Events.trigger(engine, 'beforeUpdate', event);
   -1  4954 
   -1  4955         // get lists of all bodies and constraints, no matter what composites they are in
   -1  4956         var allBodies = Composite.allBodies(world),
   -1  4957             allConstraints = Composite.allConstraints(world);
   -1  4958 
   -1  4959 
   -1  4960         // if sleeping enabled, call the sleeping controller
   -1  4961         if (engine.enableSleeping)
   -1  4962             Sleeping.update(allBodies, timing.timeScale);
   -1  4963 
   -1  4964         // applies gravity to all bodies
   -1  4965         Engine._bodiesApplyGravity(allBodies, world.gravity);
   -1  4966 
   -1  4967         // update all body position and rotation by integration
   -1  4968         Engine._bodiesUpdate(allBodies, delta, timing.timeScale, correction, world.bounds);
   -1  4969 
   -1  4970         // update all constraints (first pass)
   -1  4971         Constraint.preSolveAll(allBodies);
   -1  4972         for (i = 0; i < engine.constraintIterations; i++) {
   -1  4973             Constraint.solveAll(allConstraints, timing.timeScale);
   -1  4974         }
   -1  4975         Constraint.postSolveAll(allBodies);
   -1  4976 
   -1  4977         // broadphase pass: find potential collision pairs
   -1  4978         if (broadphase.controller) {
   -1  4979             // if world is dirty, we must flush the whole grid
   -1  4980             if (world.isModified)
   -1  4981                 broadphase.controller.clear(broadphase);
   -1  4982 
   -1  4983             // update the grid buckets based on current bodies
   -1  4984             broadphase.controller.update(broadphase, allBodies, engine, world.isModified);
   -1  4985             broadphasePairs = broadphase.pairsList;
   -1  4986         } else {
   -1  4987             // if no broadphase set, we just pass all bodies
   -1  4988             broadphasePairs = allBodies;
   -1  4989         }
   -1  4990 
   -1  4991         // clear all composite modified flags
   -1  4992         if (world.isModified) {
   -1  4993             Composite.setModified(world, false, false, true);
   -1  4994         }
   -1  4995 
   -1  4996         // narrowphase pass: find actual collisions, then create or update collision pairs
   -1  4997         var collisions = broadphase.detector(broadphasePairs, engine);
   -1  4998 
   -1  4999         // update collision pairs
   -1  5000         var pairs = engine.pairs,
   -1  5001             timestamp = timing.timestamp;
   -1  5002         Pairs.update(pairs, collisions, timestamp);
   -1  5003         Pairs.removeOld(pairs, timestamp);
   -1  5004 
   -1  5005         // wake up bodies involved in collisions
   -1  5006         if (engine.enableSleeping)
   -1  5007             Sleeping.afterCollisions(pairs.list, timing.timeScale);
   -1  5008 
   -1  5009         // trigger collision events
   -1  5010         if (pairs.collisionStart.length > 0)
   -1  5011             Events.trigger(engine, 'collisionStart', { pairs: pairs.collisionStart });
   -1  5012 
   -1  5013         // iteratively resolve position between collisions
   -1  5014         Resolver.preSolvePosition(pairs.list);
   -1  5015         for (i = 0; i < engine.positionIterations; i++) {
   -1  5016             Resolver.solvePosition(pairs.list, timing.timeScale);
   -1  5017         }
   -1  5018         Resolver.postSolvePosition(allBodies);
   -1  5019 
   -1  5020         // update all constraints (second pass)
   -1  5021         Constraint.preSolveAll(allBodies);
   -1  5022         for (i = 0; i < engine.constraintIterations; i++) {
   -1  5023             Constraint.solveAll(allConstraints, timing.timeScale);
   -1  5024         }
   -1  5025         Constraint.postSolveAll(allBodies);
   -1  5026 
   -1  5027         // iteratively resolve velocity between collisions
   -1  5028         Resolver.preSolveVelocity(pairs.list);
   -1  5029         for (i = 0; i < engine.velocityIterations; i++) {
   -1  5030             Resolver.solveVelocity(pairs.list, timing.timeScale);
   -1  5031         }
   -1  5032 
   -1  5033         // trigger collision events
   -1  5034         if (pairs.collisionActive.length > 0)
   -1  5035             Events.trigger(engine, 'collisionActive', { pairs: pairs.collisionActive });
   -1  5036 
   -1  5037         if (pairs.collisionEnd.length > 0)
   -1  5038             Events.trigger(engine, 'collisionEnd', { pairs: pairs.collisionEnd });
   -1  5039 
   -1  5040 
   -1  5041         // clear force buffers
   -1  5042         Engine._bodiesClearForces(allBodies);
   -1  5043 
   -1  5044         Events.trigger(engine, 'afterUpdate', event);
   -1  5045 
   -1  5046         return engine;
   -1  5047     };
   -1  5048     
   -1  5049     /**
   -1  5050      * Merges two engines by keeping the configuration of `engineA` but replacing the world with the one from `engineB`.
   -1  5051      * @method merge
   -1  5052      * @param {engine} engineA
   -1  5053      * @param {engine} engineB
   -1  5054      */
   -1  5055     Engine.merge = function(engineA, engineB) {
   -1  5056         Common.extend(engineA, engineB);
   -1  5057         
   -1  5058         if (engineB.world) {
   -1  5059             engineA.world = engineB.world;
   -1  5060 
   -1  5061             Engine.clear(engineA);
   -1  5062 
   -1  5063             var bodies = Composite.allBodies(engineA.world);
   -1  5064 
   -1  5065             for (var i = 0; i < bodies.length; i++) {
   -1  5066                 var body = bodies[i];
   -1  5067                 Sleeping.set(body, false);
   -1  5068                 body.id = Common.nextId();
   -1  5069             }
   -1  5070         }
   -1  5071     };
   -1  5072 
   -1  5073     /**
   -1  5074      * Clears the engine including the world, pairs and broadphase.
   -1  5075      * @method clear
   -1  5076      * @param {engine} engine
   -1  5077      */
   -1  5078     Engine.clear = function(engine) {
   -1  5079         var world = engine.world;
   -1  5080         
   -1  5081         Pairs.clear(engine.pairs);
   -1  5082 
   -1  5083         var broadphase = engine.broadphase;
   -1  5084         if (broadphase.controller) {
   -1  5085             var bodies = Composite.allBodies(world);
   -1  5086             broadphase.controller.clear(broadphase);
   -1  5087             broadphase.controller.update(broadphase, bodies, engine, true);
   -1  5088         }
   -1  5089     };
   -1  5090 
   -1  5091     /**
   -1  5092      * Zeroes the `body.force` and `body.torque` force buffers.
   -1  5093      * @method _bodiesClearForces
   -1  5094      * @private
   -1  5095      * @param {body[]} bodies
   -1  5096      */
   -1  5097     Engine._bodiesClearForces = function(bodies) {
   -1  5098         for (var i = 0; i < bodies.length; i++) {
   -1  5099             var body = bodies[i];
   -1  5100 
   -1  5101             // reset force buffers
   -1  5102             body.force.x = 0;
   -1  5103             body.force.y = 0;
   -1  5104             body.torque = 0;
   -1  5105         }
   -1  5106     };
   -1  5107 
   -1  5108     /**
   -1  5109      * Applys a mass dependant force to all given bodies.
   -1  5110      * @method _bodiesApplyGravity
   -1  5111      * @private
   -1  5112      * @param {body[]} bodies
   -1  5113      * @param {vector} gravity
   -1  5114      */
   -1  5115     Engine._bodiesApplyGravity = function(bodies, gravity) {
   -1  5116         var gravityScale = typeof gravity.scale !== 'undefined' ? gravity.scale : 0.001;
   -1  5117 
   -1  5118         if ((gravity.x === 0 && gravity.y === 0) || gravityScale === 0) {
   -1  5119             return;
   -1  5120         }
   -1  5121         
   -1  5122         for (var i = 0; i < bodies.length; i++) {
   -1  5123             var body = bodies[i];
   -1  5124 
   -1  5125             if (body.isStatic || body.isSleeping)
   -1  5126                 continue;
   -1  5127 
   -1  5128             // apply gravity
   -1  5129             body.force.y += body.mass * gravity.y * gravityScale;
   -1  5130             body.force.x += body.mass * gravity.x * gravityScale;
   -1  5131         }
   -1  5132     };
   -1  5133 
   -1  5134     /**
   -1  5135      * Applys `Body.update` to all given `bodies`.
   -1  5136      * @method _bodiesUpdate
   -1  5137      * @private
   -1  5138      * @param {body[]} bodies
   -1  5139      * @param {number} deltaTime 
   -1  5140      * The amount of time elapsed between updates
   -1  5141      * @param {number} timeScale
   -1  5142      * @param {number} correction 
   -1  5143      * The Verlet correction factor (deltaTime / lastDeltaTime)
   -1  5144      * @param {bounds} worldBounds
   -1  5145      */
   -1  5146     Engine._bodiesUpdate = function(bodies, deltaTime, timeScale, correction, worldBounds) {
   -1  5147         for (var i = 0; i < bodies.length; i++) {
   -1  5148             var body = bodies[i];
   -1  5149 
   -1  5150             if (body.isStatic || body.isSleeping)
   -1  5151                 continue;
   -1  5152 
   -1  5153             Body.update(body, deltaTime, timeScale, correction);
   -1  5154         }
   -1  5155     };
   -1  5156 
   -1  5157     /**
   -1  5158      * An alias for `Runner.run`, see `Matter.Runner` for more information.
   -1  5159      * @method run
   -1  5160      * @param {engine} engine
   -1  5161      */
   -1  5162 
   -1  5163     /**
   -1  5164     * Fired just before an update
   -1  5165     *
   -1  5166     * @event beforeUpdate
   -1  5167     * @param {} event An event object
   -1  5168     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  5169     * @param {} event.source The source object of the event
   -1  5170     * @param {} event.name The name of the event
   -1  5171     */
   -1  5172 
   -1  5173     /**
   -1  5174     * Fired after engine update and all collision events
   -1  5175     *
   -1  5176     * @event afterUpdate
   -1  5177     * @param {} event An event object
   -1  5178     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  5179     * @param {} event.source The source object of the event
   -1  5180     * @param {} event.name The name of the event
   -1  5181     */
   -1  5182 
   -1  5183     /**
   -1  5184     * Fired after engine update, provides a list of all pairs that have started to collide in the current tick (if any)
   -1  5185     *
   -1  5186     * @event collisionStart
   -1  5187     * @param {} event An event object
   -1  5188     * @param {} event.pairs List of affected pairs
   -1  5189     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  5190     * @param {} event.source The source object of the event
   -1  5191     * @param {} event.name The name of the event
   -1  5192     */
   -1  5193 
   -1  5194     /**
   -1  5195     * Fired after engine update, provides a list of all pairs that are colliding in the current tick (if any)
   -1  5196     *
   -1  5197     * @event collisionActive
   -1  5198     * @param {} event An event object
   -1  5199     * @param {} event.pairs List of affected pairs
   -1  5200     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  5201     * @param {} event.source The source object of the event
   -1  5202     * @param {} event.name The name of the event
   -1  5203     */
   -1  5204 
   -1  5205     /**
   -1  5206     * Fired after engine update, provides a list of all pairs that have ended collision in the current tick (if any)
   -1  5207     *
   -1  5208     * @event collisionEnd
   -1  5209     * @param {} event An event object
   -1  5210     * @param {} event.pairs List of affected pairs
   -1  5211     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  5212     * @param {} event.source The source object of the event
   -1  5213     * @param {} event.name The name of the event
   -1  5214     */
   -1  5215 
   -1  5216     /*
   -1  5217     *
   -1  5218     *  Properties Documentation
   -1  5219     *
   -1  5220     */
   -1  5221 
   -1  5222     /**
   -1  5223      * An integer `Number` that specifies the number of position iterations to perform each update.
   -1  5224      * The higher the value, the higher quality the simulation will be at the expense of performance.
   -1  5225      *
   -1  5226      * @property positionIterations
   -1  5227      * @type number
   -1  5228      * @default 6
   -1  5229      */
   -1  5230 
   -1  5231     /**
   -1  5232      * An integer `Number` that specifies the number of velocity iterations to perform each update.
   -1  5233      * The higher the value, the higher quality the simulation will be at the expense of performance.
   -1  5234      *
   -1  5235      * @property velocityIterations
   -1  5236      * @type number
   -1  5237      * @default 4
   -1  5238      */
   -1  5239 
   -1  5240     /**
   -1  5241      * An integer `Number` that specifies the number of constraint iterations to perform each update.
   -1  5242      * The higher the value, the higher quality the simulation will be at the expense of performance.
   -1  5243      * The default value of `2` is usually very adequate.
   -1  5244      *
   -1  5245      * @property constraintIterations
   -1  5246      * @type number
   -1  5247      * @default 2
   -1  5248      */
   -1  5249 
   -1  5250     /**
   -1  5251      * A flag that specifies whether the engine should allow sleeping via the `Matter.Sleeping` module.
   -1  5252      * Sleeping can improve stability and performance, but often at the expense of accuracy.
   -1  5253      *
   -1  5254      * @property enableSleeping
   -1  5255      * @type boolean
   -1  5256      * @default false
   -1  5257      */
   -1  5258 
   -1  5259     /**
   -1  5260      * An `Object` containing properties regarding the timing systems of the engine. 
   -1  5261      *
   -1  5262      * @property timing
   -1  5263      * @type object
   -1  5264      */
   -1  5265 
   -1  5266     /**
   -1  5267      * A `Number` that specifies the global scaling factor of time for all bodies.
   -1  5268      * A value of `0` freezes the simulation.
   -1  5269      * A value of `0.1` gives a slow-motion effect.
   -1  5270      * A value of `1.2` gives a speed-up effect.
   -1  5271      *
   -1  5272      * @property timing.timeScale
   -1  5273      * @type number
   -1  5274      * @default 1
   -1  5275      */
   -1  5276 
   -1  5277     /**
   -1  5278      * A `Number` that specifies the current simulation-time in milliseconds starting from `0`. 
   -1  5279      * It is incremented on every `Engine.update` by the given `delta` argument. 
   -1  5280      *
   -1  5281      * @property timing.timestamp
   -1  5282      * @type number
   -1  5283      * @default 0
   -1  5284      */
   -1  5285 
   -1  5286     /**
   -1  5287      * An instance of a `Render` controller. The default value is a `Matter.Render` instance created by `Engine.create`.
   -1  5288      * One may also develop a custom renderer module based on `Matter.Render` and pass an instance of it to `Engine.create` via `options.render`.
   -1  5289      *
   -1  5290      * A minimal custom renderer object must define at least three functions: `create`, `clear` and `world` (see `Matter.Render`).
   -1  5291      * It is also possible to instead pass the _module_ reference via `options.render.controller` and `Engine.create` will instantiate one for you.
   -1  5292      *
   -1  5293      * @property render
   -1  5294      * @type render
   -1  5295      * @deprecated see Demo.js for an example of creating a renderer
   -1  5296      * @default a Matter.Render instance
   -1  5297      */
   -1  5298 
   -1  5299     /**
   -1  5300      * An instance of a broadphase controller. The default value is a `Matter.Grid` instance created by `Engine.create`.
   -1  5301      *
   -1  5302      * @property broadphase
   -1  5303      * @type grid
   -1  5304      * @default a Matter.Grid instance
   -1  5305      */
   -1  5306 
   -1  5307     /**
   -1  5308      * A `World` composite object that will contain all simulated bodies and constraints.
   -1  5309      *
   -1  5310      * @property world
   -1  5311      * @type world
   -1  5312      * @default a Matter.World instance
   -1  5313      */
   -1  5314 
   -1  5315     /**
   -1  5316      * An object reserved for storing plugin-specific properties.
   -1  5317      *
   -1  5318      * @property plugin
   -1  5319      * @type {}
   -1  5320      */
   -1  5321 
   -1  5322 })();
   -1  5323 
   -1  5324 },{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Grid":6,"../collision/Pairs":8,"../collision/Resolver":10,"../constraint/Constraint":12,"../render/Render":31,"./Common":14,"./Events":16,"./Metrics":18,"./Sleeping":22}],16:[function(_dereq_,module,exports){
   -1  5325 /**
   -1  5326 * The `Matter.Events` module contains methods to fire and listen to events on other objects.
   -1  5327 *
   -1  5328 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  5329 *
   -1  5330 * @class Events
   -1  5331 */
   -1  5332 
   -1  5333 var Events = {};
   -1  5334 
   -1  5335 module.exports = Events;
   -1  5336 
   -1  5337 var Common = _dereq_('./Common');
   -1  5338 
   -1  5339 (function() {
   -1  5340 
   -1  5341     /**
   -1  5342      * Subscribes a callback function to the given object's `eventName`.
   -1  5343      * @method on
   -1  5344      * @param {} object
   -1  5345      * @param {string} eventNames
   -1  5346      * @param {function} callback
   -1  5347      */
   -1  5348     Events.on = function(object, eventNames, callback) {
   -1  5349         var names = eventNames.split(' '),
   -1  5350             name;
   -1  5351 
   -1  5352         for (var i = 0; i < names.length; i++) {
   -1  5353             name = names[i];
   -1  5354             object.events = object.events || {};
   -1  5355             object.events[name] = object.events[name] || [];
   -1  5356             object.events[name].push(callback);
   -1  5357         }
   -1  5358 
   -1  5359         return callback;
   -1  5360     };
   -1  5361 
   -1  5362     /**
   -1  5363      * Removes the given event callback. If no callback, clears all callbacks in `eventNames`. If no `eventNames`, clears all events.
   -1  5364      * @method off
   -1  5365      * @param {} object
   -1  5366      * @param {string} eventNames
   -1  5367      * @param {function} callback
   -1  5368      */
   -1  5369     Events.off = function(object, eventNames, callback) {
   -1  5370         if (!eventNames) {
   -1  5371             object.events = {};
   -1  5372             return;
   -1  5373         }
   -1  5374 
   -1  5375         // handle Events.off(object, callback)
   -1  5376         if (typeof eventNames === 'function') {
   -1  5377             callback = eventNames;
   -1  5378             eventNames = Common.keys(object.events).join(' ');
   -1  5379         }
   -1  5380 
   -1  5381         var names = eventNames.split(' ');
   -1  5382 
   -1  5383         for (var i = 0; i < names.length; i++) {
   -1  5384             var callbacks = object.events[names[i]],
   -1  5385                 newCallbacks = [];
   -1  5386 
   -1  5387             if (callback && callbacks) {
   -1  5388                 for (var j = 0; j < callbacks.length; j++) {
   -1  5389                     if (callbacks[j] !== callback)
   -1  5390                         newCallbacks.push(callbacks[j]);
   -1  5391                 }
   -1  5392             }
   -1  5393 
   -1  5394             object.events[names[i]] = newCallbacks;
   -1  5395         }
   -1  5396     };
   -1  5397 
   -1  5398     /**
   -1  5399      * Fires all the callbacks subscribed to the given object's `eventName`, in the order they subscribed, if any.
   -1  5400      * @method trigger
   -1  5401      * @param {} object
   -1  5402      * @param {string} eventNames
   -1  5403      * @param {} event
   -1  5404      */
   -1  5405     Events.trigger = function(object, eventNames, event) {
   -1  5406         var names,
   -1  5407             name,
   -1  5408             callbacks,
   -1  5409             eventClone;
   -1  5410 
   -1  5411         if (object.events) {
   -1  5412             if (!event)
   -1  5413                 event = {};
   -1  5414 
   -1  5415             names = eventNames.split(' ');
   -1  5416 
   -1  5417             for (var i = 0; i < names.length; i++) {
   -1  5418                 name = names[i];
   -1  5419                 callbacks = object.events[name];
   -1  5420 
   -1  5421                 if (callbacks) {
   -1  5422                     eventClone = Common.clone(event, false);
   -1  5423                     eventClone.name = name;
   -1  5424                     eventClone.source = object;
   -1  5425 
   -1  5426                     for (var j = 0; j < callbacks.length; j++) {
   -1  5427                         callbacks[j].apply(object, [eventClone]);
   -1  5428                     }
   -1  5429                 }
   -1  5430             }
   -1  5431         }
   -1  5432     };
   -1  5433 
   -1  5434 })();
   -1  5435 
   -1  5436 },{"./Common":14}],17:[function(_dereq_,module,exports){
   -1  5437 /**
   -1  5438 * The `Matter` module is the top level namespace. It also includes a function for installing plugins on top of the library.
   -1  5439 *
   -1  5440 * @class Matter
   -1  5441 */
   -1  5442 
   -1  5443 var Matter = {};
   -1  5444 
   -1  5445 module.exports = Matter;
   -1  5446 
   -1  5447 var Plugin = _dereq_('./Plugin');
   -1  5448 var Common = _dereq_('./Common');
   -1  5449 
   -1  5450 (function() {
   -1  5451 
   -1  5452     /**
   -1  5453      * The library name.
   -1  5454      * @property name
   -1  5455      * @readOnly
   -1  5456      * @type {String}
   -1  5457      */
   -1  5458     Matter.name = 'matter-js';
   -1  5459 
   -1  5460     /**
   -1  5461      * The library version.
   -1  5462      * @property version
   -1  5463      * @readOnly
   -1  5464      * @type {String}
   -1  5465      */
   -1  5466     Matter.version = '0.14.2';
   -1  5467 
   -1  5468     /**
   -1  5469      * A list of plugin dependencies to be installed. These are normally set and installed through `Matter.use`.
   -1  5470      * Alternatively you may set `Matter.uses` manually and install them by calling `Plugin.use(Matter)`.
   -1  5471      * @property uses
   -1  5472      * @type {Array}
   -1  5473      */
   -1  5474     Matter.uses = [];
   -1  5475 
   -1  5476     /**
   -1  5477      * The plugins that have been installed through `Matter.Plugin.install`. Read only.
   -1  5478      * @property used
   -1  5479      * @readOnly
   -1  5480      * @type {Array}
   -1  5481      */
   -1  5482     Matter.used = [];
   -1  5483 
   -1  5484     /**
   -1  5485      * Installs the given plugins on the `Matter` namespace.
   -1  5486      * This is a short-hand for `Plugin.use`, see it for more information.
   -1  5487      * Call this function once at the start of your code, with all of the plugins you wish to install as arguments.
   -1  5488      * Avoid calling this function multiple times unless you intend to manually control installation order.
   -1  5489      * @method use
   -1  5490      * @param ...plugin {Function} The plugin(s) to install on `base` (multi-argument).
   -1  5491      */
   -1  5492     Matter.use = function() {
   -1  5493         Plugin.use(Matter, Array.prototype.slice.call(arguments));
   -1  5494     };
   -1  5495 
   -1  5496     /**
   -1  5497      * Chains a function to excute before the original function on the given `path` relative to `Matter`.
   -1  5498      * See also docs for `Common.chain`.
   -1  5499      * @method before
   -1  5500      * @param {string} path The path relative to `Matter`
   -1  5501      * @param {function} func The function to chain before the original
   -1  5502      * @return {function} The chained function that replaced the original
   -1  5503      */
   -1  5504     Matter.before = function(path, func) {
   -1  5505         path = path.replace(/^Matter./, '');
   -1  5506         return Common.chainPathBefore(Matter, path, func);
   -1  5507     };
   -1  5508 
   -1  5509     /**
   -1  5510      * Chains a function to excute after the original function on the given `path` relative to `Matter`.
   -1  5511      * See also docs for `Common.chain`.
   -1  5512      * @method after
   -1  5513      * @param {string} path The path relative to `Matter`
   -1  5514      * @param {function} func The function to chain after the original
   -1  5515      * @return {function} The chained function that replaced the original
   -1  5516      */
   -1  5517     Matter.after = function(path, func) {
   -1  5518         path = path.replace(/^Matter./, '');
   -1  5519         return Common.chainPathAfter(Matter, path, func);
   -1  5520     };
   -1  5521 
   -1  5522 })();
   -1  5523 
   -1  5524 },{"./Common":14,"./Plugin":20}],18:[function(_dereq_,module,exports){
   -1  5525 
   -1  5526 },{"../body/Composite":2,"./Common":14}],19:[function(_dereq_,module,exports){
   -1  5527 /**
   -1  5528 * The `Matter.Mouse` module contains methods for creating and manipulating mouse inputs.
   -1  5529 *
   -1  5530 * @class Mouse
   -1  5531 */
   -1  5532 
   -1  5533 var Mouse = {};
   -1  5534 
   -1  5535 module.exports = Mouse;
   -1  5536 
   -1  5537 var Common = _dereq_('../core/Common');
   -1  5538 
   -1  5539 (function() {
   -1  5540 
   -1  5541     /**
   -1  5542      * Creates a mouse input.
   -1  5543      * @method create
   -1  5544      * @param {HTMLElement} element
   -1  5545      * @return {mouse} A new mouse
   -1  5546      */
   -1  5547     Mouse.create = function(element) {
   -1  5548         var mouse = {};
   -1  5549 
   -1  5550         if (!element) {
   -1  5551             Common.log('Mouse.create: element was undefined, defaulting to document.body', 'warn');
   -1  5552         }
   -1  5553         
   -1  5554         mouse.element = element || document.body;
   -1  5555         mouse.absolute = { x: 0, y: 0 };
   -1  5556         mouse.position = { x: 0, y: 0 };
   -1  5557         mouse.mousedownPosition = { x: 0, y: 0 };
   -1  5558         mouse.mouseupPosition = { x: 0, y: 0 };
   -1  5559         mouse.offset = { x: 0, y: 0 };
   -1  5560         mouse.scale = { x: 1, y: 1 };
   -1  5561         mouse.wheelDelta = 0;
   -1  5562         mouse.button = -1;
   -1  5563         mouse.pixelRatio = mouse.element.getAttribute('data-pixel-ratio') || 1;
   -1  5564 
   -1  5565         mouse.sourceEvents = {
   -1  5566             mousemove: null,
   -1  5567             mousedown: null,
   -1  5568             mouseup: null,
   -1  5569             mousewheel: null
   -1  5570         };
   -1  5571         
   -1  5572         mouse.mousemove = function(event) { 
   -1  5573             var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
   -1  5574                 touches = event.changedTouches;
   -1  5575 
   -1  5576             if (touches) {
   -1  5577                 mouse.button = 0;
   -1  5578                 event.preventDefault();
   -1  5579             }
   -1  5580 
   -1  5581             mouse.absolute.x = position.x;
   -1  5582             mouse.absolute.y = position.y;
   -1  5583             mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
   -1  5584             mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
   -1  5585             mouse.sourceEvents.mousemove = event;
   -1  5586         };
   -1  5587         
   -1  5588         mouse.mousedown = function(event) {
   -1  5589             var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
   -1  5590                 touches = event.changedTouches;
   -1  5591 
   -1  5592             if (touches) {
   -1  5593                 mouse.button = 0;
   -1  5594                 event.preventDefault();
   -1  5595             } else {
   -1  5596                 mouse.button = event.button;
   -1  5597             }
   -1  5598 
   -1  5599             mouse.absolute.x = position.x;
   -1  5600             mouse.absolute.y = position.y;
   -1  5601             mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
   -1  5602             mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
   -1  5603             mouse.mousedownPosition.x = mouse.position.x;
   -1  5604             mouse.mousedownPosition.y = mouse.position.y;
   -1  5605             mouse.sourceEvents.mousedown = event;
   -1  5606         };
   -1  5607         
   -1  5608         mouse.mouseup = function(event) {
   -1  5609             var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio),
   -1  5610                 touches = event.changedTouches;
   -1  5611 
   -1  5612             if (touches) {
   -1  5613                 event.preventDefault();
   -1  5614             }
   -1  5615             
   -1  5616             mouse.button = -1;
   -1  5617             mouse.absolute.x = position.x;
   -1  5618             mouse.absolute.y = position.y;
   -1  5619             mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
   -1  5620             mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
   -1  5621             mouse.mouseupPosition.x = mouse.position.x;
   -1  5622             mouse.mouseupPosition.y = mouse.position.y;
   -1  5623             mouse.sourceEvents.mouseup = event;
   -1  5624         };
   -1  5625 
   -1  5626         mouse.mousewheel = function(event) {
   -1  5627             mouse.wheelDelta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail));
   -1  5628             event.preventDefault();
   -1  5629         };
   -1  5630 
   -1  5631         Mouse.setElement(mouse, mouse.element);
   -1  5632 
   -1  5633         return mouse;
   -1  5634     };
   -1  5635 
   -1  5636     /**
   -1  5637      * Sets the element the mouse is bound to (and relative to).
   -1  5638      * @method setElement
   -1  5639      * @param {mouse} mouse
   -1  5640      * @param {HTMLElement} element
   -1  5641      */
   -1  5642     Mouse.setElement = function(mouse, element) {
   -1  5643         mouse.element = element;
   -1  5644 
   -1  5645         element.addEventListener('mousemove', mouse.mousemove);
   -1  5646         element.addEventListener('mousedown', mouse.mousedown);
   -1  5647         element.addEventListener('mouseup', mouse.mouseup);
   -1  5648         
   -1  5649         element.addEventListener('mousewheel', mouse.mousewheel);
   -1  5650         element.addEventListener('DOMMouseScroll', mouse.mousewheel);
   -1  5651 
   -1  5652         element.addEventListener('touchmove', mouse.mousemove);
   -1  5653         element.addEventListener('touchstart', mouse.mousedown);
   -1  5654         element.addEventListener('touchend', mouse.mouseup);
   -1  5655     };
   -1  5656 
   -1  5657     /**
   -1  5658      * Clears all captured source events.
   -1  5659      * @method clearSourceEvents
   -1  5660      * @param {mouse} mouse
   -1  5661      */
   -1  5662     Mouse.clearSourceEvents = function(mouse) {
   -1  5663         mouse.sourceEvents.mousemove = null;
   -1  5664         mouse.sourceEvents.mousedown = null;
   -1  5665         mouse.sourceEvents.mouseup = null;
   -1  5666         mouse.sourceEvents.mousewheel = null;
   -1  5667         mouse.wheelDelta = 0;
   -1  5668     };
   -1  5669 
   -1  5670     /**
   -1  5671      * Sets the mouse position offset.
   -1  5672      * @method setOffset
   -1  5673      * @param {mouse} mouse
   -1  5674      * @param {vector} offset
   -1  5675      */
   -1  5676     Mouse.setOffset = function(mouse, offset) {
   -1  5677         mouse.offset.x = offset.x;
   -1  5678         mouse.offset.y = offset.y;
   -1  5679         mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
   -1  5680         mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
   -1  5681     };
   -1  5682 
   -1  5683     /**
   -1  5684      * Sets the mouse position scale.
   -1  5685      * @method setScale
   -1  5686      * @param {mouse} mouse
   -1  5687      * @param {vector} scale
   -1  5688      */
   -1  5689     Mouse.setScale = function(mouse, scale) {
   -1  5690         mouse.scale.x = scale.x;
   -1  5691         mouse.scale.y = scale.y;
   -1  5692         mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x;
   -1  5693         mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y;
   -1  5694     };
   -1  5695     
   -1  5696     /**
   -1  5697      * Gets the mouse position relative to an element given a screen pixel ratio.
   -1  5698      * @method _getRelativeMousePosition
   -1  5699      * @private
   -1  5700      * @param {} event
   -1  5701      * @param {} element
   -1  5702      * @param {number} pixelRatio
   -1  5703      * @return {}
   -1  5704      */
   -1  5705     Mouse._getRelativeMousePosition = function(event, element, pixelRatio) {
   -1  5706         var elementBounds = element.getBoundingClientRect(),
   -1  5707             rootNode = (document.documentElement || document.body.parentNode || document.body),
   -1  5708             scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : rootNode.scrollLeft,
   -1  5709             scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : rootNode.scrollTop,
   -1  5710             touches = event.changedTouches,
   -1  5711             x, y;
   -1  5712         
   -1  5713         if (touches) {
   -1  5714             x = touches[0].pageX - elementBounds.left - scrollX;
   -1  5715             y = touches[0].pageY - elementBounds.top - scrollY;
   -1  5716         } else {
   -1  5717             x = event.pageX - elementBounds.left - scrollX;
   -1  5718             y = event.pageY - elementBounds.top - scrollY;
   -1  5719         }
   -1  5720 
   -1  5721         return { 
   -1  5722             x: x / (element.clientWidth / (element.width || element.clientWidth) * pixelRatio),
   -1  5723             y: y / (element.clientHeight / (element.height || element.clientHeight) * pixelRatio)
   -1  5724         };
   -1  5725     };
   -1  5726 
   -1  5727 })();
   -1  5728 
   -1  5729 },{"../core/Common":14}],20:[function(_dereq_,module,exports){
   -1  5730 /**
   -1  5731 * The `Matter.Plugin` module contains functions for registering and installing plugins on modules.
   -1  5732 *
   -1  5733 * @class Plugin
   -1  5734 */
   -1  5735 
   -1  5736 var Plugin = {};
   -1  5737 
   -1  5738 module.exports = Plugin;
   -1  5739 
   -1  5740 var Common = _dereq_('./Common');
   -1  5741 
   -1  5742 (function() {
   -1  5743 
   -1  5744     Plugin._registry = {};
   -1  5745 
   -1  5746     /**
   -1  5747      * Registers a plugin object so it can be resolved later by name.
   -1  5748      * @method register
   -1  5749      * @param plugin {} The plugin to register.
   -1  5750      * @return {object} The plugin.
   -1  5751      */
   -1  5752     Plugin.register = function(plugin) {
   -1  5753         if (!Plugin.isPlugin(plugin)) {
   -1  5754             Common.warn('Plugin.register:', Plugin.toString(plugin), 'does not implement all required fields.');
   -1  5755         }
   -1  5756 
   -1  5757         if (plugin.name in Plugin._registry) {
   -1  5758             var registered = Plugin._registry[plugin.name],
   -1  5759                 pluginVersion = Plugin.versionParse(plugin.version).number,
   -1  5760                 registeredVersion = Plugin.versionParse(registered.version).number;
   -1  5761 
   -1  5762             if (pluginVersion > registeredVersion) {
   -1  5763                 Common.warn('Plugin.register:', Plugin.toString(registered), 'was upgraded to', Plugin.toString(plugin));
   -1  5764                 Plugin._registry[plugin.name] = plugin;
   -1  5765             } else if (pluginVersion < registeredVersion) {
   -1  5766                 Common.warn('Plugin.register:', Plugin.toString(registered), 'can not be downgraded to', Plugin.toString(plugin));
   -1  5767             } else if (plugin !== registered) {
   -1  5768                 Common.warn('Plugin.register:', Plugin.toString(plugin), 'is already registered to different plugin object');
   -1  5769             }
   -1  5770         } else {
   -1  5771             Plugin._registry[plugin.name] = plugin;
   -1  5772         }
   -1  5773 
   -1  5774         return plugin;
   -1  5775     };
   -1  5776 
   -1  5777     /**
   -1  5778      * Resolves a dependency to a plugin object from the registry if it exists. 
   -1  5779      * The `dependency` may contain a version, but only the name matters when resolving.
   -1  5780      * @method resolve
   -1  5781      * @param dependency {string} The dependency.
   -1  5782      * @return {object} The plugin if resolved, otherwise `undefined`.
   -1  5783      */
   -1  5784     Plugin.resolve = function(dependency) {
   -1  5785         return Plugin._registry[Plugin.dependencyParse(dependency).name];
   -1  5786     };
   -1  5787 
   -1  5788     /**
   -1  5789      * Returns a pretty printed plugin name and version.
   -1  5790      * @method toString
   -1  5791      * @param plugin {} The plugin.
   -1  5792      * @return {string} Pretty printed plugin name and version.
   -1  5793      */
   -1  5794     Plugin.toString = function(plugin) {
   -1  5795         return typeof plugin === 'string' ? plugin : (plugin.name || 'anonymous') + '@' + (plugin.version || plugin.range || '0.0.0');
   -1  5796     };
   -1  5797 
   -1  5798     /**
   -1  5799      * Returns `true` if the object meets the minimum standard to be considered a plugin.
   -1  5800      * This means it must define the following properties:
   -1  5801      * - `name`
   -1  5802      * - `version`
   -1  5803      * - `install`
   -1  5804      * @method isPlugin
   -1  5805      * @param obj {} The obj to test.
   -1  5806      * @return {boolean} `true` if the object can be considered a plugin otherwise `false`.
   -1  5807      */
   -1  5808     Plugin.isPlugin = function(obj) {
   -1  5809         return obj && obj.name && obj.version && obj.install;
   -1  5810     };
   -1  5811 
   -1  5812     /**
   -1  5813      * Returns `true` if a plugin with the given `name` been installed on `module`.
   -1  5814      * @method isUsed
   -1  5815      * @param module {} The module.
   -1  5816      * @param name {string} The plugin name.
   -1  5817      * @return {boolean} `true` if a plugin with the given `name` been installed on `module`, otherwise `false`.
   -1  5818      */
   -1  5819     Plugin.isUsed = function(module, name) {
   -1  5820         return module.used.indexOf(name) > -1;
   -1  5821     };
   -1  5822 
   -1  5823     /**
   -1  5824      * Returns `true` if `plugin.for` is applicable to `module` by comparing against `module.name` and `module.version`.
   -1  5825      * If `plugin.for` is not specified then it is assumed to be applicable.
   -1  5826      * The value of `plugin.for` is a string of the format `'module-name'` or `'module-name@version'`.
   -1  5827      * @method isFor
   -1  5828      * @param plugin {} The plugin.
   -1  5829      * @param module {} The module.
   -1  5830      * @return {boolean} `true` if `plugin.for` is applicable to `module`, otherwise `false`.
   -1  5831      */
   -1  5832     Plugin.isFor = function(plugin, module) {
   -1  5833         var parsed = plugin.for && Plugin.dependencyParse(plugin.for);
   -1  5834         return !plugin.for || (module.name === parsed.name && Plugin.versionSatisfies(module.version, parsed.range));
   -1  5835     };
   -1  5836 
   -1  5837     /**
   -1  5838      * Installs the plugins by calling `plugin.install` on each plugin specified in `plugins` if passed, otherwise `module.uses`.
   -1  5839      * For installing plugins on `Matter` see the convenience function `Matter.use`.
   -1  5840      * Plugins may be specified either by their name or a reference to the plugin object.
   -1  5841      * Plugins themselves may specify further dependencies, but each plugin is installed only once.
   -1  5842      * Order is important, a topological sort is performed to find the best resulting order of installation.
   -1  5843      * This sorting attempts to satisfy every dependency's requested ordering, but may not be exact in all cases.
   -1  5844      * This function logs the resulting status of each dependency in the console, along with any warnings.
   -1  5845      * - A green tick ✅ indicates a dependency was resolved and installed.
   -1  5846      * - An orange diamond 🔶 indicates a dependency was resolved but a warning was thrown for it or one if its dependencies.
   -1  5847      * - A red cross ❌ indicates a dependency could not be resolved.
   -1  5848      * Avoid calling this function multiple times on the same module unless you intend to manually control installation order.
   -1  5849      * @method use
   -1  5850      * @param module {} The module install plugins on.
   -1  5851      * @param [plugins=module.uses] {} The plugins to install on module (optional, defaults to `module.uses`).
   -1  5852      */
   -1  5853     Plugin.use = function(module, plugins) {
   -1  5854         module.uses = (module.uses || []).concat(plugins || []);
   -1  5855 
   -1  5856         if (module.uses.length === 0) {
   -1  5857             Common.warn('Plugin.use:', Plugin.toString(module), 'does not specify any dependencies to install.');
   -1  5858             return;
   -1  5859         }
   -1  5860 
   -1  5861         var dependencies = Plugin.dependencies(module),
   -1  5862             sortedDependencies = Common.topologicalSort(dependencies),
   -1  5863             status = [];
   -1  5864 
   -1  5865         for (var i = 0; i < sortedDependencies.length; i += 1) {
   -1  5866             if (sortedDependencies[i] === module.name) {
   -1  5867                 continue;
   -1  5868             }
   -1  5869 
   -1  5870             var plugin = Plugin.resolve(sortedDependencies[i]);
   -1  5871 
   -1  5872             if (!plugin) {
   -1  5873                 status.push('❌ ' + sortedDependencies[i]);
   -1  5874                 continue;
   -1  5875             }
   -1  5876 
   -1  5877             if (Plugin.isUsed(module, plugin.name)) {
   -1  5878                 continue;
   -1  5879             }
   -1  5880 
   -1  5881             if (!Plugin.isFor(plugin, module)) {
   -1  5882                 Common.warn('Plugin.use:', Plugin.toString(plugin), 'is for', plugin.for, 'but installed on', Plugin.toString(module) + '.');
   -1  5883                 plugin._warned = true;
   -1  5884             }
   -1  5885 
   -1  5886             if (plugin.install) {
   -1  5887                 plugin.install(module);
   -1  5888             } else {
   -1  5889                 Common.warn('Plugin.use:', Plugin.toString(plugin), 'does not specify an install function.');
   -1  5890                 plugin._warned = true;
   -1  5891             }
   -1  5892 
   -1  5893             if (plugin._warned) {
   -1  5894                 status.push('🔶 ' + Plugin.toString(plugin));
   -1  5895                 delete plugin._warned;
   -1  5896             } else {
   -1  5897                 status.push('✅ ' + Plugin.toString(plugin));
   -1  5898             }
   -1  5899 
   -1  5900             module.used.push(plugin.name);
   -1  5901         }
   -1  5902 
   -1  5903         if (status.length > 0) {
   -1  5904             Common.info(status.join('  '));
   -1  5905         }
   -1  5906     };
   -1  5907 
   -1  5908     /**
   -1  5909      * Recursively finds all of a module's dependencies and returns a flat dependency graph.
   -1  5910      * @method dependencies
   -1  5911      * @param module {} The module.
   -1  5912      * @return {object} A dependency graph.
   -1  5913      */
   -1  5914     Plugin.dependencies = function(module, tracked) {
   -1  5915         var parsedBase = Plugin.dependencyParse(module),
   -1  5916             name = parsedBase.name;
   -1  5917 
   -1  5918         tracked = tracked || {};
   -1  5919 
   -1  5920         if (name in tracked) {
   -1  5921             return;
   -1  5922         }
   -1  5923 
   -1  5924         module = Plugin.resolve(module) || module;
   -1  5925 
   -1  5926         tracked[name] = Common.map(module.uses || [], function(dependency) {
   -1  5927             if (Plugin.isPlugin(dependency)) {
   -1  5928                 Plugin.register(dependency);
   -1  5929             }
   -1  5930 
   -1  5931             var parsed = Plugin.dependencyParse(dependency),
   -1  5932                 resolved = Plugin.resolve(dependency);
   -1  5933 
   -1  5934             if (resolved && !Plugin.versionSatisfies(resolved.version, parsed.range)) {
   -1  5935                 Common.warn(
   -1  5936                     'Plugin.dependencies:', Plugin.toString(resolved), 'does not satisfy',
   -1  5937                     Plugin.toString(parsed), 'used by', Plugin.toString(parsedBase) + '.'
   -1  5938                 );
   -1  5939 
   -1  5940                 resolved._warned = true;
   -1  5941                 module._warned = true;
   -1  5942             } else if (!resolved) {
   -1  5943                 Common.warn(
   -1  5944                     'Plugin.dependencies:', Plugin.toString(dependency), 'used by',
   -1  5945                     Plugin.toString(parsedBase), 'could not be resolved.'
   -1  5946                 );
   -1  5947 
   -1  5948                 module._warned = true;
   -1  5949             }
   -1  5950 
   -1  5951             return parsed.name;
   -1  5952         });
   -1  5953 
   -1  5954         for (var i = 0; i < tracked[name].length; i += 1) {
   -1  5955             Plugin.dependencies(tracked[name][i], tracked);
   -1  5956         }
   -1  5957 
   -1  5958         return tracked;
   -1  5959     };
   -1  5960 
   -1  5961     /**
   -1  5962      * Parses a dependency string into its components.
   -1  5963      * The `dependency` is a string of the format `'module-name'` or `'module-name@version'`.
   -1  5964      * See documentation for `Plugin.versionParse` for a description of the format.
   -1  5965      * This function can also handle dependencies that are already resolved (e.g. a module object).
   -1  5966      * @method dependencyParse
   -1  5967      * @param dependency {string} The dependency of the format `'module-name'` or `'module-name@version'`.
   -1  5968      * @return {object} The dependency parsed into its components.
   -1  5969      */
   -1  5970     Plugin.dependencyParse = function(dependency) {
   -1  5971         if (Common.isString(dependency)) {
   -1  5972             var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?))?$/;
   -1  5973 
   -1  5974             if (!pattern.test(dependency)) {
   -1  5975                 Common.warn('Plugin.dependencyParse:', dependency, 'is not a valid dependency string.');
   -1  5976             }
   -1  5977 
   -1  5978             return {
   -1  5979                 name: dependency.split('@')[0],
   -1  5980                 range: dependency.split('@')[1] || '*'
   -1  5981             };
   -1  5982         }
   -1  5983 
   -1  5984         return {
   -1  5985             name: dependency.name,
   -1  5986             range: dependency.range || dependency.version
   -1  5987         };
   -1  5988     };
   -1  5989 
   -1  5990     /**
   -1  5991      * Parses a version string into its components.  
   -1  5992      * Versions are strictly of the format `x.y.z` (as in [semver](http://semver.org/)).
   -1  5993      * Versions may optionally have a prerelease tag in the format `x.y.z-alpha`.
   -1  5994      * Ranges are a strict subset of [npm ranges](https://docs.npmjs.com/misc/semver#advanced-range-syntax).
   -1  5995      * Only the following range types are supported:
   -1  5996      * - Tilde ranges e.g. `~1.2.3`
   -1  5997      * - Caret ranges e.g. `^1.2.3`
   -1  5998      * - Exact version e.g. `1.2.3`
   -1  5999      * - Any version `*`
   -1  6000      * @method versionParse
   -1  6001      * @param range {string} The version string.
   -1  6002      * @return {object} The version range parsed into its components.
   -1  6003      */
   -1  6004     Plugin.versionParse = function(range) {
   -1  6005         var pattern = /^\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-]+)?$/;
   -1  6006 
   -1  6007         if (!pattern.test(range)) {
   -1  6008             Common.warn('Plugin.versionParse:', range, 'is not a valid version or range.');
   -1  6009         }
   -1  6010 
   -1  6011         var identifiers = range.split('-');
   -1  6012         range = identifiers[0];
   -1  6013 
   -1  6014         var isRange = isNaN(Number(range[0])),
   -1  6015             version = isRange ? range.substr(1) : range,
   -1  6016             parts = Common.map(version.split('.'), function(part) {
   -1  6017                 return Number(part);
   -1  6018             });
   -1  6019 
   -1  6020         return {
   -1  6021             isRange: isRange,
   -1  6022             version: version,
   -1  6023             range: range,
   -1  6024             operator: isRange ? range[0] : '',
   -1  6025             parts: parts,
   -1  6026             prerelease: identifiers[1],
   -1  6027             number: parts[0] * 1e8 + parts[1] * 1e4 + parts[2]
   -1  6028         };
   -1  6029     };
   -1  6030 
   -1  6031     /**
   -1  6032      * Returns `true` if `version` satisfies the given `range`.
   -1  6033      * See documentation for `Plugin.versionParse` for a description of the format.
   -1  6034      * If a version or range is not specified, then any version (`*`) is assumed to satisfy.
   -1  6035      * @method versionSatisfies
   -1  6036      * @param version {string} The version string.
   -1  6037      * @param range {string} The range string.
   -1  6038      * @return {boolean} `true` if `version` satisfies `range`, otherwise `false`.
   -1  6039      */
   -1  6040     Plugin.versionSatisfies = function(version, range) {
   -1  6041         range = range || '*';
   -1  6042 
   -1  6043         var rangeParsed = Plugin.versionParse(range),
   -1  6044             rangeParts = rangeParsed.parts,
   -1  6045             versionParsed = Plugin.versionParse(version),
   -1  6046             versionParts = versionParsed.parts;
   -1  6047 
   -1  6048         if (rangeParsed.isRange) {
   -1  6049             if (rangeParsed.operator === '*' || version === '*') {
   -1  6050                 return true;
   -1  6051             }
   -1  6052 
   -1  6053             if (rangeParsed.operator === '~') {
   -1  6054                 return versionParts[0] === rangeParts[0] && versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
   -1  6055             }
   -1  6056 
   -1  6057             if (rangeParsed.operator === '^') {
   -1  6058                 if (rangeParts[0] > 0) {
   -1  6059                     return versionParts[0] === rangeParts[0] && versionParsed.number >= rangeParsed.number;
   -1  6060                 }
   -1  6061 
   -1  6062                 if (rangeParts[1] > 0) {
   -1  6063                     return versionParts[1] === rangeParts[1] && versionParts[2] >= rangeParts[2];
   -1  6064                 }
   -1  6065 
   -1  6066                 return versionParts[2] === rangeParts[2];
   -1  6067             }
   -1  6068         }
   -1  6069 
   -1  6070         return version === range || version === '*';
   -1  6071     };
   -1  6072 
   -1  6073 })();
   -1  6074 
   -1  6075 },{"./Common":14}],21:[function(_dereq_,module,exports){
   -1  6076 /**
   -1  6077 * The `Matter.Runner` module is an optional utility which provides a game loop, 
   -1  6078 * that handles continuously updating a `Matter.Engine` for you within a browser.
   -1  6079 * It is intended for development and debugging purposes, but may also be suitable for simple games.
   -1  6080 * If you are using your own game loop instead, then you do not need the `Matter.Runner` module.
   -1  6081 * Instead just call `Engine.update(engine, delta)` in your own loop.
   -1  6082 *
   -1  6083 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  6084 *
   -1  6085 * @class Runner
   -1  6086 */
   -1  6087 
   -1  6088 var Runner = {};
   -1  6089 
   -1  6090 module.exports = Runner;
   -1  6091 
   -1  6092 var Events = _dereq_('./Events');
   -1  6093 var Engine = _dereq_('./Engine');
   -1  6094 var Common = _dereq_('./Common');
   -1  6095 
   -1  6096 (function() {
   -1  6097 
   -1  6098     var _requestAnimationFrame,
   -1  6099         _cancelAnimationFrame;
   -1  6100 
   -1  6101     if (typeof window !== 'undefined') {
   -1  6102         _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
   -1  6103                                       || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
   -1  6104    
   -1  6105         _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame 
   -1  6106                                       || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
   -1  6107     }
   -1  6108 
   -1  6109     if (!_requestAnimationFrame) {
   -1  6110         var _frameTimeout;
   -1  6111 
   -1  6112         _requestAnimationFrame = function(callback){ 
   -1  6113             _frameTimeout = setTimeout(function() { 
   -1  6114                 callback(Common.now()); 
   -1  6115             }, 1000 / 60);
   -1  6116         };
   -1  6117 
   -1  6118         _cancelAnimationFrame = function() {
   -1  6119             clearTimeout(_frameTimeout);
   -1  6120         };
   -1  6121     }
   -1  6122 
   -1  6123     /**
   -1  6124      * Creates a new Runner. The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  6125      * @method create
   -1  6126      * @param {} options
   -1  6127      */
   -1  6128     Runner.create = function(options) {
   -1  6129         var defaults = {
   -1  6130             fps: 60,
   -1  6131             correction: 1,
   -1  6132             deltaSampleSize: 60,
   -1  6133             counterTimestamp: 0,
   -1  6134             frameCounter: 0,
   -1  6135             deltaHistory: [],
   -1  6136             timePrev: null,
   -1  6137             timeScalePrev: 1,
   -1  6138             frameRequestId: null,
   -1  6139             isFixed: false,
   -1  6140             enabled: true
   -1  6141         };
   -1  6142 
   -1  6143         var runner = Common.extend(defaults, options);
   -1  6144 
   -1  6145         runner.delta = runner.delta || 1000 / runner.fps;
   -1  6146         runner.deltaMin = runner.deltaMin || 1000 / runner.fps;
   -1  6147         runner.deltaMax = runner.deltaMax || 1000 / (runner.fps * 0.5);
   -1  6148         runner.fps = 1000 / runner.delta;
   -1  6149 
   -1  6150         return runner;
   -1  6151     };
   -1  6152 
   -1  6153     /**
   -1  6154      * Continuously ticks a `Matter.Engine` by calling `Runner.tick` on the `requestAnimationFrame` event.
   -1  6155      * @method run
   -1  6156      * @param {engine} engine
   -1  6157      */
   -1  6158     Runner.run = function(runner, engine) {
   -1  6159         // create runner if engine is first argument
   -1  6160         if (typeof runner.positionIterations !== 'undefined') {
   -1  6161             engine = runner;
   -1  6162             runner = Runner.create();
   -1  6163         }
   -1  6164 
   -1  6165         (function render(time){
   -1  6166             runner.frameRequestId = _requestAnimationFrame(render);
   -1  6167 
   -1  6168             if (time && runner.enabled) {
   -1  6169                 Runner.tick(runner, engine, time);
   -1  6170             }
   -1  6171         })();
   -1  6172 
   -1  6173         return runner;
   -1  6174     };
   -1  6175 
   -1  6176     /**
   -1  6177      * A game loop utility that updates the engine and renderer by one step (a 'tick').
   -1  6178      * Features delta smoothing, time correction and fixed or dynamic timing.
   -1  6179      * Triggers `beforeTick`, `tick` and `afterTick` events on the engine.
   -1  6180      * Consider just `Engine.update(engine, delta)` if you're using your own loop.
   -1  6181      * @method tick
   -1  6182      * @param {runner} runner
   -1  6183      * @param {engine} engine
   -1  6184      * @param {number} time
   -1  6185      */
   -1  6186     Runner.tick = function(runner, engine, time) {
   -1  6187         var timing = engine.timing,
   -1  6188             correction = 1,
   -1  6189             delta;
   -1  6190 
   -1  6191         // create an event object
   -1  6192         var event = {
   -1  6193             timestamp: timing.timestamp
   -1  6194         };
   -1  6195 
   -1  6196         Events.trigger(runner, 'beforeTick', event);
   -1  6197         Events.trigger(engine, 'beforeTick', event); // @deprecated
   -1  6198 
   -1  6199         if (runner.isFixed) {
   -1  6200             // fixed timestep
   -1  6201             delta = runner.delta;
   -1  6202         } else {
   -1  6203             // dynamic timestep based on wall clock between calls
   -1  6204             delta = (time - runner.timePrev) || runner.delta;
   -1  6205             runner.timePrev = time;
   -1  6206 
   -1  6207             // optimistically filter delta over a few frames, to improve stability
   -1  6208             runner.deltaHistory.push(delta);
   -1  6209             runner.deltaHistory = runner.deltaHistory.slice(-runner.deltaSampleSize);
   -1  6210             delta = Math.min.apply(null, runner.deltaHistory);
   -1  6211             
   -1  6212             // limit delta
   -1  6213             delta = delta < runner.deltaMin ? runner.deltaMin : delta;
   -1  6214             delta = delta > runner.deltaMax ? runner.deltaMax : delta;
   -1  6215 
   -1  6216             // correction for delta
   -1  6217             correction = delta / runner.delta;
   -1  6218 
   -1  6219             // update engine timing object
   -1  6220             runner.delta = delta;
   -1  6221         }
   -1  6222 
   -1  6223         // time correction for time scaling
   -1  6224         if (runner.timeScalePrev !== 0)
   -1  6225             correction *= timing.timeScale / runner.timeScalePrev;
   -1  6226 
   -1  6227         if (timing.timeScale === 0)
   -1  6228             correction = 0;
   -1  6229 
   -1  6230         runner.timeScalePrev = timing.timeScale;
   -1  6231         runner.correction = correction;
   -1  6232 
   -1  6233         // fps counter
   -1  6234         runner.frameCounter += 1;
   -1  6235         if (time - runner.counterTimestamp >= 1000) {
   -1  6236             runner.fps = runner.frameCounter * ((time - runner.counterTimestamp) / 1000);
   -1  6237             runner.counterTimestamp = time;
   -1  6238             runner.frameCounter = 0;
   -1  6239         }
   -1  6240 
   -1  6241         Events.trigger(runner, 'tick', event);
   -1  6242         Events.trigger(engine, 'tick', event); // @deprecated
   -1  6243 
   -1  6244         // if world has been modified, clear the render scene graph
   -1  6245         if (engine.world.isModified 
   -1  6246             && engine.render
   -1  6247             && engine.render.controller
   -1  6248             && engine.render.controller.clear) {
   -1  6249             engine.render.controller.clear(engine.render); // @deprecated
   -1  6250         }
   -1  6251 
   -1  6252         // update
   -1  6253         Events.trigger(runner, 'beforeUpdate', event);
   -1  6254         Engine.update(engine, delta, correction);
   -1  6255         Events.trigger(runner, 'afterUpdate', event);
   -1  6256 
   -1  6257         // render
   -1  6258         // @deprecated
   -1  6259         if (engine.render && engine.render.controller) {
   -1  6260             Events.trigger(runner, 'beforeRender', event);
   -1  6261             Events.trigger(engine, 'beforeRender', event); // @deprecated
   -1  6262 
   -1  6263             engine.render.controller.world(engine.render);
   -1  6264 
   -1  6265             Events.trigger(runner, 'afterRender', event);
   -1  6266             Events.trigger(engine, 'afterRender', event); // @deprecated
   -1  6267         }
   -1  6268 
   -1  6269         Events.trigger(runner, 'afterTick', event);
   -1  6270         Events.trigger(engine, 'afterTick', event); // @deprecated
   -1  6271     };
   -1  6272 
   -1  6273     /**
   -1  6274      * Ends execution of `Runner.run` on the given `runner`, by canceling the animation frame request event loop.
   -1  6275      * If you wish to only temporarily pause the engine, see `engine.enabled` instead.
   -1  6276      * @method stop
   -1  6277      * @param {runner} runner
   -1  6278      */
   -1  6279     Runner.stop = function(runner) {
   -1  6280         _cancelAnimationFrame(runner.frameRequestId);
   -1  6281     };
   -1  6282 
   -1  6283     /**
   -1  6284      * Alias for `Runner.run`.
   -1  6285      * @method start
   -1  6286      * @param {runner} runner
   -1  6287      * @param {engine} engine
   -1  6288      */
   -1  6289     Runner.start = function(runner, engine) {
   -1  6290         Runner.run(runner, engine);
   -1  6291     };
   -1  6292 
   -1  6293     /*
   -1  6294     *
   -1  6295     *  Events Documentation
   -1  6296     *
   -1  6297     */
   -1  6298 
   -1  6299     /**
   -1  6300     * Fired at the start of a tick, before any updates to the engine or timing
   -1  6301     *
   -1  6302     * @event beforeTick
   -1  6303     * @param {} event An event object
   -1  6304     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  6305     * @param {} event.source The source object of the event
   -1  6306     * @param {} event.name The name of the event
   -1  6307     */
   -1  6308 
   -1  6309     /**
   -1  6310     * Fired after engine timing updated, but just before update
   -1  6311     *
   -1  6312     * @event tick
   -1  6313     * @param {} event An event object
   -1  6314     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  6315     * @param {} event.source The source object of the event
   -1  6316     * @param {} event.name The name of the event
   -1  6317     */
   -1  6318 
   -1  6319     /**
   -1  6320     * Fired at the end of a tick, after engine update and after rendering
   -1  6321     *
   -1  6322     * @event afterTick
   -1  6323     * @param {} event An event object
   -1  6324     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  6325     * @param {} event.source The source object of the event
   -1  6326     * @param {} event.name The name of the event
   -1  6327     */
   -1  6328 
   -1  6329     /**
   -1  6330     * Fired before update
   -1  6331     *
   -1  6332     * @event beforeUpdate
   -1  6333     * @param {} event An event object
   -1  6334     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  6335     * @param {} event.source The source object of the event
   -1  6336     * @param {} event.name The name of the event
   -1  6337     */
   -1  6338 
   -1  6339     /**
   -1  6340     * Fired after update
   -1  6341     *
   -1  6342     * @event afterUpdate
   -1  6343     * @param {} event An event object
   -1  6344     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  6345     * @param {} event.source The source object of the event
   -1  6346     * @param {} event.name The name of the event
   -1  6347     */
   -1  6348 
   -1  6349     /**
   -1  6350     * Fired before rendering
   -1  6351     *
   -1  6352     * @event beforeRender
   -1  6353     * @param {} event An event object
   -1  6354     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  6355     * @param {} event.source The source object of the event
   -1  6356     * @param {} event.name The name of the event
   -1  6357     * @deprecated
   -1  6358     */
   -1  6359 
   -1  6360     /**
   -1  6361     * Fired after rendering
   -1  6362     *
   -1  6363     * @event afterRender
   -1  6364     * @param {} event An event object
   -1  6365     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  6366     * @param {} event.source The source object of the event
   -1  6367     * @param {} event.name The name of the event
   -1  6368     * @deprecated
   -1  6369     */
   -1  6370 
   -1  6371     /*
   -1  6372     *
   -1  6373     *  Properties Documentation
   -1  6374     *
   -1  6375     */
   -1  6376 
   -1  6377     /**
   -1  6378      * A flag that specifies whether the runner is running or not.
   -1  6379      *
   -1  6380      * @property enabled
   -1  6381      * @type boolean
   -1  6382      * @default true
   -1  6383      */
   -1  6384 
   -1  6385     /**
   -1  6386      * A `Boolean` that specifies if the runner should use a fixed timestep (otherwise it is variable).
   -1  6387      * If timing is fixed, then the apparent simulation speed will change depending on the frame rate (but behaviour will be deterministic).
   -1  6388      * If the timing is variable, then the apparent simulation speed will be constant (approximately, but at the cost of determininism).
   -1  6389      *
   -1  6390      * @property isFixed
   -1  6391      * @type boolean
   -1  6392      * @default false
   -1  6393      */
   -1  6394 
   -1  6395     /**
   -1  6396      * A `Number` that specifies the time step between updates in milliseconds.
   -1  6397      * If `engine.timing.isFixed` is set to `true`, then `delta` is fixed.
   -1  6398      * If it is `false`, then `delta` can dynamically change to maintain the correct apparent simulation speed.
   -1  6399      *
   -1  6400      * @property delta
   -1  6401      * @type number
   -1  6402      * @default 1000 / 60
   -1  6403      */
   -1  6404 
   -1  6405 })();
   -1  6406 
   -1  6407 },{"./Common":14,"./Engine":15,"./Events":16}],22:[function(_dereq_,module,exports){
   -1  6408 /**
   -1  6409 * The `Matter.Sleeping` module contains methods to manage the sleeping state of bodies.
   -1  6410 *
   -1  6411 * @class Sleeping
   -1  6412 */
   -1  6413 
   -1  6414 var Sleeping = {};
   -1  6415 
   -1  6416 module.exports = Sleeping;
   -1  6417 
   -1  6418 var Events = _dereq_('./Events');
   -1  6419 
   -1  6420 (function() {
   -1  6421 
   -1  6422     Sleeping._motionWakeThreshold = 0.18;
   -1  6423     Sleeping._motionSleepThreshold = 0.08;
   -1  6424     Sleeping._minBias = 0.9;
   -1  6425 
   -1  6426     /**
   -1  6427      * Puts bodies to sleep or wakes them up depending on their motion.
   -1  6428      * @method update
   -1  6429      * @param {body[]} bodies
   -1  6430      * @param {number} timeScale
   -1  6431      */
   -1  6432     Sleeping.update = function(bodies, timeScale) {
   -1  6433         var timeFactor = timeScale * timeScale * timeScale;
   -1  6434 
   -1  6435         // update bodies sleeping status
   -1  6436         for (var i = 0; i < bodies.length; i++) {
   -1  6437             var body = bodies[i],
   -1  6438                 motion = body.speed * body.speed + body.angularSpeed * body.angularSpeed;
   -1  6439 
   -1  6440             // wake up bodies if they have a force applied
   -1  6441             if (body.force.x !== 0 || body.force.y !== 0) {
   -1  6442                 Sleeping.set(body, false);
   -1  6443                 continue;
   -1  6444             }
   -1  6445 
   -1  6446             var minMotion = Math.min(body.motion, motion),
   -1  6447                 maxMotion = Math.max(body.motion, motion);
   -1  6448         
   -1  6449             // biased average motion estimation between frames
   -1  6450             body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion;
   -1  6451             
   -1  6452             if (body.sleepThreshold > 0 && body.motion < Sleeping._motionSleepThreshold * timeFactor) {
   -1  6453                 body.sleepCounter += 1;
   -1  6454                 
   -1  6455                 if (body.sleepCounter >= body.sleepThreshold)
   -1  6456                     Sleeping.set(body, true);
   -1  6457             } else if (body.sleepCounter > 0) {
   -1  6458                 body.sleepCounter -= 1;
   -1  6459             }
   -1  6460         }
   -1  6461     };
   -1  6462 
   -1  6463     /**
   -1  6464      * Given a set of colliding pairs, wakes the sleeping bodies involved.
   -1  6465      * @method afterCollisions
   -1  6466      * @param {pair[]} pairs
   -1  6467      * @param {number} timeScale
   -1  6468      */
   -1  6469     Sleeping.afterCollisions = function(pairs, timeScale) {
   -1  6470         var timeFactor = timeScale * timeScale * timeScale;
   -1  6471 
   -1  6472         // wake up bodies involved in collisions
   -1  6473         for (var i = 0; i < pairs.length; i++) {
   -1  6474             var pair = pairs[i];
   -1  6475             
   -1  6476             // don't wake inactive pairs
   -1  6477             if (!pair.isActive)
   -1  6478                 continue;
   -1  6479 
   -1  6480             var collision = pair.collision,
   -1  6481                 bodyA = collision.bodyA.parent, 
   -1  6482                 bodyB = collision.bodyB.parent;
   -1  6483         
   -1  6484             // don't wake if at least one body is static
   -1  6485             if ((bodyA.isSleeping && bodyB.isSleeping) || bodyA.isStatic || bodyB.isStatic)
   -1  6486                 continue;
   -1  6487         
   -1  6488             if (bodyA.isSleeping || bodyB.isSleeping) {
   -1  6489                 var sleepingBody = (bodyA.isSleeping && !bodyA.isStatic) ? bodyA : bodyB,
   -1  6490                     movingBody = sleepingBody === bodyA ? bodyB : bodyA;
   -1  6491 
   -1  6492                 if (!sleepingBody.isStatic && movingBody.motion > Sleeping._motionWakeThreshold * timeFactor) {
   -1  6493                     Sleeping.set(sleepingBody, false);
   -1  6494                 }
   -1  6495             }
   -1  6496         }
   -1  6497     };
   -1  6498   
   -1  6499     /**
   -1  6500      * Set a body as sleeping or awake.
   -1  6501      * @method set
   -1  6502      * @param {body} body
   -1  6503      * @param {boolean} isSleeping
   -1  6504      */
   -1  6505     Sleeping.set = function(body, isSleeping) {
   -1  6506         var wasSleeping = body.isSleeping;
   -1  6507 
   -1  6508         if (isSleeping) {
   -1  6509             body.isSleeping = true;
   -1  6510             body.sleepCounter = body.sleepThreshold;
   -1  6511 
   -1  6512             body.positionImpulse.x = 0;
   -1  6513             body.positionImpulse.y = 0;
   -1  6514 
   -1  6515             body.positionPrev.x = body.position.x;
   -1  6516             body.positionPrev.y = body.position.y;
   -1  6517 
   -1  6518             body.anglePrev = body.angle;
   -1  6519             body.speed = 0;
   -1  6520             body.angularSpeed = 0;
   -1  6521             body.motion = 0;
   -1  6522 
   -1  6523             if (!wasSleeping) {
   -1  6524                 Events.trigger(body, 'sleepStart');
   -1  6525             }
   -1  6526         } else {
   -1  6527             body.isSleeping = false;
   -1  6528             body.sleepCounter = 0;
   -1  6529 
   -1  6530             if (wasSleeping) {
   -1  6531                 Events.trigger(body, 'sleepEnd');
   -1  6532             }
   -1  6533         }
   -1  6534     };
   -1  6535 
   -1  6536 })();
   -1  6537 
   -1  6538 },{"./Events":16}],23:[function(_dereq_,module,exports){
   -1  6539 /**
   -1  6540 * The `Matter.Bodies` module contains factory methods for creating rigid body models 
   -1  6541 * with commonly used body configurations (such as rectangles, circles and other polygons).
   -1  6542 *
   -1  6543 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  6544 *
   -1  6545 * @class Bodies
   -1  6546 */
   -1  6547 
   -1  6548 // TODO: true circle bodies
   -1  6549 
   -1  6550 var Bodies = {};
   -1  6551 
   -1  6552 module.exports = Bodies;
   -1  6553 
   -1  6554 var Vertices = _dereq_('../geometry/Vertices');
   -1  6555 var Common = _dereq_('../core/Common');
   -1  6556 var Body = _dereq_('../body/Body');
   -1  6557 var Bounds = _dereq_('../geometry/Bounds');
   -1  6558 var Vector = _dereq_('../geometry/Vector');
   -1  6559 var decomp;
   -1  6560 
   -1  6561 (function() {
   -1  6562 
   -1  6563     /**
   -1  6564      * Creates a new rigid body model with a rectangle hull. 
   -1  6565      * The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  6566      * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
   -1  6567      * @method rectangle
   -1  6568      * @param {number} x
   -1  6569      * @param {number} y
   -1  6570      * @param {number} width
   -1  6571      * @param {number} height
   -1  6572      * @param {object} [options]
   -1  6573      * @return {body} A new rectangle body
   -1  6574      */
   -1  6575     Bodies.rectangle = function(x, y, width, height, options) {
   -1  6576         options = options || {};
   -1  6577 
   -1  6578         var rectangle = { 
   -1  6579             label: 'Rectangle Body',
   -1  6580             position: { x: x, y: y },
   -1  6581             vertices: Vertices.fromPath('L 0 0 L ' + width + ' 0 L ' + width + ' ' + height + ' L 0 ' + height)
   -1  6582         };
   -1  6583 
   -1  6584         if (options.chamfer) {
   -1  6585             var chamfer = options.chamfer;
   -1  6586             rectangle.vertices = Vertices.chamfer(rectangle.vertices, chamfer.radius, 
   -1  6587                                     chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
   -1  6588             delete options.chamfer;
   -1  6589         }
   -1  6590 
   -1  6591         return Body.create(Common.extend({}, rectangle, options));
   -1  6592     };
   -1  6593     
   -1  6594     /**
   -1  6595      * Creates a new rigid body model with a trapezoid hull. 
   -1  6596      * The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  6597      * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
   -1  6598      * @method trapezoid
   -1  6599      * @param {number} x
   -1  6600      * @param {number} y
   -1  6601      * @param {number} width
   -1  6602      * @param {number} height
   -1  6603      * @param {number} slope
   -1  6604      * @param {object} [options]
   -1  6605      * @return {body} A new trapezoid body
   -1  6606      */
   -1  6607     Bodies.trapezoid = function(x, y, width, height, slope, options) {
   -1  6608         options = options || {};
   -1  6609 
   -1  6610         slope *= 0.5;
   -1  6611         var roof = (1 - (slope * 2)) * width;
   -1  6612         
   -1  6613         var x1 = width * slope,
   -1  6614             x2 = x1 + roof,
   -1  6615             x3 = x2 + x1,
   -1  6616             verticesPath;
   -1  6617 
   -1  6618         if (slope < 0.5) {
   -1  6619             verticesPath = 'L 0 0 L ' + x1 + ' ' + (-height) + ' L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0';
   -1  6620         } else {
   -1  6621             verticesPath = 'L 0 0 L ' + x2 + ' ' + (-height) + ' L ' + x3 + ' 0';
   -1  6622         }
   -1  6623 
   -1  6624         var trapezoid = { 
   -1  6625             label: 'Trapezoid Body',
   -1  6626             position: { x: x, y: y },
   -1  6627             vertices: Vertices.fromPath(verticesPath)
   -1  6628         };
   -1  6629 
   -1  6630         if (options.chamfer) {
   -1  6631             var chamfer = options.chamfer;
   -1  6632             trapezoid.vertices = Vertices.chamfer(trapezoid.vertices, chamfer.radius, 
   -1  6633                                     chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
   -1  6634             delete options.chamfer;
   -1  6635         }
   -1  6636 
   -1  6637         return Body.create(Common.extend({}, trapezoid, options));
   -1  6638     };
   -1  6639 
   -1  6640     /**
   -1  6641      * Creates a new rigid body model with a circle hull. 
   -1  6642      * The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  6643      * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
   -1  6644      * @method circle
   -1  6645      * @param {number} x
   -1  6646      * @param {number} y
   -1  6647      * @param {number} radius
   -1  6648      * @param {object} [options]
   -1  6649      * @param {number} [maxSides]
   -1  6650      * @return {body} A new circle body
   -1  6651      */
   -1  6652     Bodies.circle = function(x, y, radius, options, maxSides) {
   -1  6653         options = options || {};
   -1  6654 
   -1  6655         var circle = {
   -1  6656             label: 'Circle Body',
   -1  6657             circleRadius: radius
   -1  6658         };
   -1  6659         
   -1  6660         // approximate circles with polygons until true circles implemented in SAT
   -1  6661         maxSides = maxSides || 25;
   -1  6662         var sides = Math.ceil(Math.max(10, Math.min(maxSides, radius)));
   -1  6663 
   -1  6664         // optimisation: always use even number of sides (half the number of unique axes)
   -1  6665         if (sides % 2 === 1)
   -1  6666             sides += 1;
   -1  6667 
   -1  6668         return Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options));
   -1  6669     };
   -1  6670 
   -1  6671     /**
   -1  6672      * Creates a new rigid body model with a regular polygon hull with the given number of sides. 
   -1  6673      * The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  6674      * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
   -1  6675      * @method polygon
   -1  6676      * @param {number} x
   -1  6677      * @param {number} y
   -1  6678      * @param {number} sides
   -1  6679      * @param {number} radius
   -1  6680      * @param {object} [options]
   -1  6681      * @return {body} A new regular polygon body
   -1  6682      */
   -1  6683     Bodies.polygon = function(x, y, sides, radius, options) {
   -1  6684         options = options || {};
   -1  6685 
   -1  6686         if (sides < 3)
   -1  6687             return Bodies.circle(x, y, radius, options);
   -1  6688 
   -1  6689         var theta = 2 * Math.PI / sides,
   -1  6690             path = '',
   -1  6691             offset = theta * 0.5;
   -1  6692 
   -1  6693         for (var i = 0; i < sides; i += 1) {
   -1  6694             var angle = offset + (i * theta),
   -1  6695                 xx = Math.cos(angle) * radius,
   -1  6696                 yy = Math.sin(angle) * radius;
   -1  6697 
   -1  6698             path += 'L ' + xx.toFixed(3) + ' ' + yy.toFixed(3) + ' ';
   -1  6699         }
   -1  6700 
   -1  6701         var polygon = { 
   -1  6702             label: 'Polygon Body',
   -1  6703             position: { x: x, y: y },
   -1  6704             vertices: Vertices.fromPath(path)
   -1  6705         };
   -1  6706 
   -1  6707         if (options.chamfer) {
   -1  6708             var chamfer = options.chamfer;
   -1  6709             polygon.vertices = Vertices.chamfer(polygon.vertices, chamfer.radius, 
   -1  6710                                     chamfer.quality, chamfer.qualityMin, chamfer.qualityMax);
   -1  6711             delete options.chamfer;
   -1  6712         }
   -1  6713 
   -1  6714         return Body.create(Common.extend({}, polygon, options));
   -1  6715     };
   -1  6716 
   -1  6717     /**
   -1  6718      * Creates a body using the supplied vertices (or an array containing multiple sets of vertices).
   -1  6719      * If the vertices are convex, they will pass through as supplied.
   -1  6720      * Otherwise if the vertices are concave, they will be decomposed if [poly-decomp.js](https://github.com/schteppe/poly-decomp.js) is available.
   -1  6721      * Note that this process is not guaranteed to support complex sets of vertices (e.g. those with holes may fail).
   -1  6722      * By default the decomposition will discard collinear edges (to improve performance).
   -1  6723      * It can also optionally discard any parts that have an area less than `minimumArea`.
   -1  6724      * If the vertices can not be decomposed, the result will fall back to using the convex hull.
   -1  6725      * The options parameter is an object that specifies any `Matter.Body` properties you wish to override the defaults.
   -1  6726      * See the properties section of the `Matter.Body` module for detailed information on what you can pass via the `options` object.
   -1  6727      * @method fromVertices
   -1  6728      * @param {number} x
   -1  6729      * @param {number} y
   -1  6730      * @param [[vector]] vertexSets
   -1  6731      * @param {object} [options]
   -1  6732      * @param {bool} [flagInternal=false]
   -1  6733      * @param {number} [removeCollinear=0.01]
   -1  6734      * @param {number} [minimumArea=10]
   -1  6735      * @return {body}
   -1  6736      */
   -1  6737     Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) {
   -1  6738         if (!decomp) {
   -1  6739             decomp = Common._requireGlobal('decomp', 'poly-decomp');
   -1  6740         }
   -1  6741 
   -1  6742         var body,
   -1  6743             parts,
   -1  6744             isConvex,
   -1  6745             vertices,
   -1  6746             i,
   -1  6747             j,
   -1  6748             k,
   -1  6749             v,
   -1  6750             z;
   -1  6751 
   -1  6752         options = options || {};
   -1  6753         parts = [];
   -1  6754 
   -1  6755         flagInternal = typeof flagInternal !== 'undefined' ? flagInternal : false;
   -1  6756         removeCollinear = typeof removeCollinear !== 'undefined' ? removeCollinear : 0.01;
   -1  6757         minimumArea = typeof minimumArea !== 'undefined' ? minimumArea : 10;
   -1  6758 
   -1  6759         if (!decomp) {
   -1  6760             Common.warn('Bodies.fromVertices: poly-decomp.js required. Could not decompose vertices. Fallback to convex hull.');
   -1  6761         }
   -1  6762 
   -1  6763         // ensure vertexSets is an array of arrays
   -1  6764         if (!Common.isArray(vertexSets[0])) {
   -1  6765             vertexSets = [vertexSets];
   -1  6766         }
   -1  6767 
   -1  6768         for (v = 0; v < vertexSets.length; v += 1) {
   -1  6769             vertices = vertexSets[v];
   -1  6770             isConvex = Vertices.isConvex(vertices);
   -1  6771 
   -1  6772             if (isConvex || !decomp) {
   -1  6773                 if (isConvex) {
   -1  6774                     vertices = Vertices.clockwiseSort(vertices);
   -1  6775                 } else {
   -1  6776                     // fallback to convex hull when decomposition is not possible
   -1  6777                     vertices = Vertices.hull(vertices);
   -1  6778                 }
   -1  6779 
   -1  6780                 parts.push({
   -1  6781                     position: { x: x, y: y },
   -1  6782                     vertices: vertices
   -1  6783                 });
   -1  6784             } else {
   -1  6785                 // initialise a decomposition
   -1  6786                 var concave = vertices.map(function(vertex) {
   -1  6787                     return [vertex.x, vertex.y];
   -1  6788                 });
   -1  6789 
   -1  6790                 // vertices are concave and simple, we can decompose into parts
   -1  6791                 decomp.makeCCW(concave);
   -1  6792                 if (removeCollinear !== false)
   -1  6793                     decomp.removeCollinearPoints(concave, removeCollinear);
   -1  6794 
   -1  6795                 // use the quick decomposition algorithm (Bayazit)
   -1  6796                 var decomposed = decomp.quickDecomp(concave);
   -1  6797 
   -1  6798                 // for each decomposed chunk
   -1  6799                 for (i = 0; i < decomposed.length; i++) {
   -1  6800                     var chunk = decomposed[i];
   -1  6801 
   -1  6802                     // convert vertices into the correct structure
   -1  6803                     var chunkVertices = chunk.map(function(vertices) {
   -1  6804                         return {
   -1  6805                             x: vertices[0],
   -1  6806                             y: vertices[1]
   -1  6807                         };
   -1  6808                     });
   -1  6809 
   -1  6810                     // skip small chunks
   -1  6811                     if (minimumArea > 0 && Vertices.area(chunkVertices) < minimumArea)
   -1  6812                         continue;
   -1  6813 
   -1  6814                     // create a compound part
   -1  6815                     parts.push({
   -1  6816                         position: Vertices.centre(chunkVertices),
   -1  6817                         vertices: chunkVertices
   -1  6818                     });
   -1  6819                 }
   -1  6820             }
   -1  6821         }
   -1  6822 
   -1  6823         // create body parts
   -1  6824         for (i = 0; i < parts.length; i++) {
   -1  6825             parts[i] = Body.create(Common.extend(parts[i], options));
   -1  6826         }
   -1  6827 
   -1  6828         // flag internal edges (coincident part edges)
   -1  6829         if (flagInternal) {
   -1  6830             var coincident_max_dist = 5;
   -1  6831 
   -1  6832             for (i = 0; i < parts.length; i++) {
   -1  6833                 var partA = parts[i];
   -1  6834 
   -1  6835                 for (j = i + 1; j < parts.length; j++) {
   -1  6836                     var partB = parts[j];
   -1  6837 
   -1  6838                     if (Bounds.overlaps(partA.bounds, partB.bounds)) {
   -1  6839                         var pav = partA.vertices,
   -1  6840                             pbv = partB.vertices;
   -1  6841 
   -1  6842                         // iterate vertices of both parts
   -1  6843                         for (k = 0; k < partA.vertices.length; k++) {
   -1  6844                             for (z = 0; z < partB.vertices.length; z++) {
   -1  6845                                 // find distances between the vertices
   -1  6846                                 var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])),
   -1  6847                                     db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length]));
   -1  6848 
   -1  6849                                 // if both vertices are very close, consider the edge concident (internal)
   -1  6850                                 if (da < coincident_max_dist && db < coincident_max_dist) {
   -1  6851                                     pav[k].isInternal = true;
   -1  6852                                     pbv[z].isInternal = true;
   -1  6853                                 }
   -1  6854                             }
   -1  6855                         }
   -1  6856 
   -1  6857                     }
   -1  6858                 }
   -1  6859             }
   -1  6860         }
   -1  6861 
   -1  6862         if (parts.length > 1) {
   -1  6863             // create the parent body to be returned, that contains generated compound parts
   -1  6864             body = Body.create(Common.extend({ parts: parts.slice(0) }, options));
   -1  6865             Body.setPosition(body, { x: x, y: y });
   -1  6866 
   -1  6867             return body;
   -1  6868         } else {
   -1  6869             return parts[0];
   -1  6870         }
   -1  6871     };
   -1  6872 
   -1  6873 })();
   -1  6874 
   -1  6875 },{"../body/Body":1,"../core/Common":14,"../geometry/Bounds":26,"../geometry/Vector":28,"../geometry/Vertices":29}],24:[function(_dereq_,module,exports){
   -1  6876 /**
   -1  6877 * The `Matter.Composites` module contains factory methods for creating composite bodies
   -1  6878 * with commonly used configurations (such as stacks and chains).
   -1  6879 *
   -1  6880 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  6881 *
   -1  6882 * @class Composites
   -1  6883 */
   -1  6884 
   -1  6885 var Composites = {};
   -1  6886 
   -1  6887 module.exports = Composites;
   -1  6888 
   -1  6889 var Composite = _dereq_('../body/Composite');
   -1  6890 var Constraint = _dereq_('../constraint/Constraint');
   -1  6891 var Common = _dereq_('../core/Common');
   -1  6892 var Body = _dereq_('../body/Body');
   -1  6893 var Bodies = _dereq_('./Bodies');
   -1  6894 
   -1  6895 (function() {
   -1  6896 
   -1  6897     /**
   -1  6898      * Create a new composite containing bodies created in the callback in a grid arrangement.
   -1  6899      * This function uses the body's bounds to prevent overlaps.
   -1  6900      * @method stack
   -1  6901      * @param {number} xx
   -1  6902      * @param {number} yy
   -1  6903      * @param {number} columns
   -1  6904      * @param {number} rows
   -1  6905      * @param {number} columnGap
   -1  6906      * @param {number} rowGap
   -1  6907      * @param {function} callback
   -1  6908      * @return {composite} A new composite containing objects created in the callback
   -1  6909      */
   -1  6910     Composites.stack = function(xx, yy, columns, rows, columnGap, rowGap, callback) {
   -1  6911         var stack = Composite.create({ label: 'Stack' }),
   -1  6912             x = xx,
   -1  6913             y = yy,
   -1  6914             lastBody,
   -1  6915             i = 0;
   -1  6916 
   -1  6917         for (var row = 0; row < rows; row++) {
   -1  6918             var maxHeight = 0;
   -1  6919             
   -1  6920             for (var column = 0; column < columns; column++) {
   -1  6921                 var body = callback(x, y, column, row, lastBody, i);
   -1  6922                     
   -1  6923                 if (body) {
   -1  6924                     var bodyHeight = body.bounds.max.y - body.bounds.min.y,
   -1  6925                         bodyWidth = body.bounds.max.x - body.bounds.min.x; 
   -1  6926 
   -1  6927                     if (bodyHeight > maxHeight)
   -1  6928                         maxHeight = bodyHeight;
   -1  6929                     
   -1  6930                     Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 });
   -1  6931 
   -1  6932                     x = body.bounds.max.x + columnGap;
   -1  6933 
   -1  6934                     Composite.addBody(stack, body);
   -1  6935                     
   -1  6936                     lastBody = body;
   -1  6937                     i += 1;
   -1  6938                 } else {
   -1  6939                     x += columnGap;
   -1  6940                 }
   -1  6941             }
   -1  6942             
   -1  6943             y += maxHeight + rowGap;
   -1  6944             x = xx;
   -1  6945         }
   -1  6946 
   -1  6947         return stack;
   -1  6948     };
   -1  6949     
   -1  6950     /**
   -1  6951      * Chains all bodies in the given composite together using constraints.
   -1  6952      * @method chain
   -1  6953      * @param {composite} composite
   -1  6954      * @param {number} xOffsetA
   -1  6955      * @param {number} yOffsetA
   -1  6956      * @param {number} xOffsetB
   -1  6957      * @param {number} yOffsetB
   -1  6958      * @param {object} options
   -1  6959      * @return {composite} A new composite containing objects chained together with constraints
   -1  6960      */
   -1  6961     Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) {
   -1  6962         var bodies = composite.bodies;
   -1  6963         
   -1  6964         for (var i = 1; i < bodies.length; i++) {
   -1  6965             var bodyA = bodies[i - 1],
   -1  6966                 bodyB = bodies[i],
   -1  6967                 bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y,
   -1  6968                 bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x, 
   -1  6969                 bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y,
   -1  6970                 bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x;
   -1  6971         
   -1  6972             var defaults = {
   -1  6973                 bodyA: bodyA,
   -1  6974                 pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA },
   -1  6975                 bodyB: bodyB,
   -1  6976                 pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB }
   -1  6977             };
   -1  6978             
   -1  6979             var constraint = Common.extend(defaults, options);
   -1  6980         
   -1  6981             Composite.addConstraint(composite, Constraint.create(constraint));
   -1  6982         }
   -1  6983 
   -1  6984         composite.label += ' Chain';
   -1  6985         
   -1  6986         return composite;
   -1  6987     };
   -1  6988 
   -1  6989     /**
   -1  6990      * Connects bodies in the composite with constraints in a grid pattern, with optional cross braces.
   -1  6991      * @method mesh
   -1  6992      * @param {composite} composite
   -1  6993      * @param {number} columns
   -1  6994      * @param {number} rows
   -1  6995      * @param {boolean} crossBrace
   -1  6996      * @param {object} options
   -1  6997      * @return {composite} The composite containing objects meshed together with constraints
   -1  6998      */
   -1  6999     Composites.mesh = function(composite, columns, rows, crossBrace, options) {
   -1  7000         var bodies = composite.bodies,
   -1  7001             row,
   -1  7002             col,
   -1  7003             bodyA,
   -1  7004             bodyB,
   -1  7005             bodyC;
   -1  7006         
   -1  7007         for (row = 0; row < rows; row++) {
   -1  7008             for (col = 1; col < columns; col++) {
   -1  7009                 bodyA = bodies[(col - 1) + (row * columns)];
   -1  7010                 bodyB = bodies[col + (row * columns)];
   -1  7011                 Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options)));
   -1  7012             }
   -1  7013 
   -1  7014             if (row > 0) {
   -1  7015                 for (col = 0; col < columns; col++) {
   -1  7016                     bodyA = bodies[col + ((row - 1) * columns)];
   -1  7017                     bodyB = bodies[col + (row * columns)];
   -1  7018                     Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyA, bodyB: bodyB }, options)));
   -1  7019 
   -1  7020                     if (crossBrace && col > 0) {
   -1  7021                         bodyC = bodies[(col - 1) + ((row - 1) * columns)];
   -1  7022                         Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options)));
   -1  7023                     }
   -1  7024 
   -1  7025                     if (crossBrace && col < columns - 1) {
   -1  7026                         bodyC = bodies[(col + 1) + ((row - 1) * columns)];
   -1  7027                         Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB: bodyB }, options)));
   -1  7028                     }
   -1  7029                 }
   -1  7030             }
   -1  7031         }
   -1  7032 
   -1  7033         composite.label += ' Mesh';
   -1  7034         
   -1  7035         return composite;
   -1  7036     };
   -1  7037     
   -1  7038     /**
   -1  7039      * Create a new composite containing bodies created in the callback in a pyramid arrangement.
   -1  7040      * This function uses the body's bounds to prevent overlaps.
   -1  7041      * @method pyramid
   -1  7042      * @param {number} xx
   -1  7043      * @param {number} yy
   -1  7044      * @param {number} columns
   -1  7045      * @param {number} rows
   -1  7046      * @param {number} columnGap
   -1  7047      * @param {number} rowGap
   -1  7048      * @param {function} callback
   -1  7049      * @return {composite} A new composite containing objects created in the callback
   -1  7050      */
   -1  7051     Composites.pyramid = function(xx, yy, columns, rows, columnGap, rowGap, callback) {
   -1  7052         return Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y, column, row, lastBody, i) {
   -1  7053             var actualRows = Math.min(rows, Math.ceil(columns / 2)),
   -1  7054                 lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0;
   -1  7055             
   -1  7056             if (row > actualRows)
   -1  7057                 return;
   -1  7058             
   -1  7059             // reverse row order
   -1  7060             row = actualRows - row;
   -1  7061             
   -1  7062             var start = row,
   -1  7063                 end = columns - 1 - row;
   -1  7064 
   -1  7065             if (column < start || column > end)
   -1  7066                 return;
   -1  7067             
   -1  7068             // retroactively fix the first body's position, since width was unknown
   -1  7069             if (i === 1) {
   -1  7070                 Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 });
   -1  7071             }
   -1  7072 
   -1  7073             var xOffset = lastBody ? column * lastBodyWidth : 0;
   -1  7074             
   -1  7075             return callback(xx + xOffset + column * columnGap, y, column, row, lastBody, i);
   -1  7076         });
   -1  7077     };
   -1  7078 
   -1  7079     /**
   -1  7080      * Creates a composite with a Newton's Cradle setup of bodies and constraints.
   -1  7081      * @method newtonsCradle
   -1  7082      * @param {number} xx
   -1  7083      * @param {number} yy
   -1  7084      * @param {number} number
   -1  7085      * @param {number} size
   -1  7086      * @param {number} length
   -1  7087      * @return {composite} A new composite newtonsCradle body
   -1  7088      */
   -1  7089     Composites.newtonsCradle = function(xx, yy, number, size, length) {
   -1  7090         var newtonsCradle = Composite.create({ label: 'Newtons Cradle' });
   -1  7091 
   -1  7092         for (var i = 0; i < number; i++) {
   -1  7093             var separation = 1.9,
   -1  7094                 circle = Bodies.circle(xx + i * (size * separation), yy + length, size, 
   -1  7095                             { inertia: Infinity, restitution: 1, friction: 0, frictionAir: 0.0001, slop: 1 }),
   -1  7096                 constraint = Constraint.create({ pointA: { x: xx + i * (size * separation), y: yy }, bodyB: circle });
   -1  7097 
   -1  7098             Composite.addBody(newtonsCradle, circle);
   -1  7099             Composite.addConstraint(newtonsCradle, constraint);
   -1  7100         }
   -1  7101 
   -1  7102         return newtonsCradle;
   -1  7103     };
   -1  7104     
   -1  7105     /**
   -1  7106      * Creates a composite with simple car setup of bodies and constraints.
   -1  7107      * @method car
   -1  7108      * @param {number} xx
   -1  7109      * @param {number} yy
   -1  7110      * @param {number} width
   -1  7111      * @param {number} height
   -1  7112      * @param {number} wheelSize
   -1  7113      * @return {composite} A new composite car body
   -1  7114      */
   -1  7115     Composites.car = function(xx, yy, width, height, wheelSize) {
   -1  7116         var group = Body.nextGroup(true),
   -1  7117             wheelBase = 20,
   -1  7118             wheelAOffset = -width * 0.5 + wheelBase,
   -1  7119             wheelBOffset = width * 0.5 - wheelBase,
   -1  7120             wheelYOffset = 0;
   -1  7121     
   -1  7122         var car = Composite.create({ label: 'Car' }),
   -1  7123             body = Bodies.rectangle(xx, yy, width, height, { 
   -1  7124                 collisionFilter: {
   -1  7125                     group: group
   -1  7126                 },
   -1  7127                 chamfer: {
   -1  7128                     radius: height * 0.5
   -1  7129                 },
   -1  7130                 density: 0.0002
   -1  7131             });
   -1  7132     
   -1  7133         var wheelA = Bodies.circle(xx + wheelAOffset, yy + wheelYOffset, wheelSize, { 
   -1  7134             collisionFilter: {
   -1  7135                 group: group
   -1  7136             },
   -1  7137             friction: 0.8
   -1  7138         });
   -1  7139                     
   -1  7140         var wheelB = Bodies.circle(xx + wheelBOffset, yy + wheelYOffset, wheelSize, { 
   -1  7141             collisionFilter: {
   -1  7142                 group: group
   -1  7143             },
   -1  7144             friction: 0.8
   -1  7145         });
   -1  7146                     
   -1  7147         var axelA = Constraint.create({
   -1  7148             bodyB: body,
   -1  7149             pointB: { x: wheelAOffset, y: wheelYOffset },
   -1  7150             bodyA: wheelA,
   -1  7151             stiffness: 1,
   -1  7152             length: 0
   -1  7153         });
   -1  7154                         
   -1  7155         var axelB = Constraint.create({
   -1  7156             bodyB: body,
   -1  7157             pointB: { x: wheelBOffset, y: wheelYOffset },
   -1  7158             bodyA: wheelB,
   -1  7159             stiffness: 1,
   -1  7160             length: 0
   -1  7161         });
   -1  7162         
   -1  7163         Composite.addBody(car, body);
   -1  7164         Composite.addBody(car, wheelA);
   -1  7165         Composite.addBody(car, wheelB);
   -1  7166         Composite.addConstraint(car, axelA);
   -1  7167         Composite.addConstraint(car, axelB);
   -1  7168 
   -1  7169         return car;
   -1  7170     };
   -1  7171 
   -1  7172     /**
   -1  7173      * Creates a simple soft body like object.
   -1  7174      * @method softBody
   -1  7175      * @param {number} xx
   -1  7176      * @param {number} yy
   -1  7177      * @param {number} columns
   -1  7178      * @param {number} rows
   -1  7179      * @param {number} columnGap
   -1  7180      * @param {number} rowGap
   -1  7181      * @param {boolean} crossBrace
   -1  7182      * @param {number} particleRadius
   -1  7183      * @param {} particleOptions
   -1  7184      * @param {} constraintOptions
   -1  7185      * @return {composite} A new composite softBody
   -1  7186      */
   -1  7187     Composites.softBody = function(xx, yy, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
   -1  7188         particleOptions = Common.extend({ inertia: Infinity }, particleOptions);
   -1  7189         constraintOptions = Common.extend({ stiffness: 0.2, render: { type: 'line', anchors: false } }, constraintOptions);
   -1  7190 
   -1  7191         var softBody = Composites.stack(xx, yy, columns, rows, columnGap, rowGap, function(x, y) {
   -1  7192             return Bodies.circle(x, y, particleRadius, particleOptions);
   -1  7193         });
   -1  7194 
   -1  7195         Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions);
   -1  7196 
   -1  7197         softBody.label = 'Soft Body';
   -1  7198 
   -1  7199         return softBody;
   -1  7200     };
   -1  7201 
   -1  7202 })();
   -1  7203 
   -1  7204 },{"../body/Body":1,"../body/Composite":2,"../constraint/Constraint":12,"../core/Common":14,"./Bodies":23}],25:[function(_dereq_,module,exports){
   -1  7205 /**
   -1  7206 * The `Matter.Axes` module contains methods for creating and manipulating sets of axes.
   -1  7207 *
   -1  7208 * @class Axes
   -1  7209 */
   -1  7210 
   -1  7211 var Axes = {};
   -1  7212 
   -1  7213 module.exports = Axes;
   -1  7214 
   -1  7215 var Vector = _dereq_('../geometry/Vector');
   -1  7216 var Common = _dereq_('../core/Common');
   -1  7217 
   -1  7218 (function() {
   -1  7219 
   -1  7220     /**
   -1  7221      * Creates a new set of axes from the given vertices.
   -1  7222      * @method fromVertices
   -1  7223      * @param {vertices} vertices
   -1  7224      * @return {axes} A new axes from the given vertices
   -1  7225      */
   -1  7226     Axes.fromVertices = function(vertices) {
   -1  7227         var axes = {};
   -1  7228 
   -1  7229         // find the unique axes, using edge normal gradients
   -1  7230         for (var i = 0; i < vertices.length; i++) {
   -1  7231             var j = (i + 1) % vertices.length, 
   -1  7232                 normal = Vector.normalise({ 
   -1  7233                     x: vertices[j].y - vertices[i].y, 
   -1  7234                     y: vertices[i].x - vertices[j].x
   -1  7235                 }),
   -1  7236                 gradient = (normal.y === 0) ? Infinity : (normal.x / normal.y);
   -1  7237             
   -1  7238             // limit precision
   -1  7239             gradient = gradient.toFixed(3).toString();
   -1  7240             axes[gradient] = normal;
   -1  7241         }
   -1  7242 
   -1  7243         return Common.values(axes);
   -1  7244     };
   -1  7245 
   -1  7246     /**
   -1  7247      * Rotates a set of axes by the given angle.
   -1  7248      * @method rotate
   -1  7249      * @param {axes} axes
   -1  7250      * @param {number} angle
   -1  7251      */
   -1  7252     Axes.rotate = function(axes, angle) {
   -1  7253         if (angle === 0)
   -1  7254             return;
   -1  7255         
   -1  7256         var cos = Math.cos(angle),
   -1  7257             sin = Math.sin(angle);
   -1  7258 
   -1  7259         for (var i = 0; i < axes.length; i++) {
   -1  7260             var axis = axes[i],
   -1  7261                 xx;
   -1  7262             xx = axis.x * cos - axis.y * sin;
   -1  7263             axis.y = axis.x * sin + axis.y * cos;
   -1  7264             axis.x = xx;
   -1  7265         }
   -1  7266     };
   -1  7267 
   -1  7268 })();
   -1  7269 
   -1  7270 },{"../core/Common":14,"../geometry/Vector":28}],26:[function(_dereq_,module,exports){
   -1  7271 /**
   -1  7272 * The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
   -1  7273 *
   -1  7274 * @class Bounds
   -1  7275 */
   -1  7276 
   -1  7277 var Bounds = {};
   -1  7278 
   -1  7279 module.exports = Bounds;
   -1  7280 
   -1  7281 (function() {
   -1  7282 
   -1  7283     /**
   -1  7284      * Creates a new axis-aligned bounding box (AABB) for the given vertices.
   -1  7285      * @method create
   -1  7286      * @param {vertices} vertices
   -1  7287      * @return {bounds} A new bounds object
   -1  7288      */
   -1  7289     Bounds.create = function(vertices) {
   -1  7290         var bounds = { 
   -1  7291             min: { x: 0, y: 0 }, 
   -1  7292             max: { x: 0, y: 0 }
   -1  7293         };
   -1  7294 
   -1  7295         if (vertices)
   -1  7296             Bounds.update(bounds, vertices);
   -1  7297         
   -1  7298         return bounds;
   -1  7299     };
   -1  7300 
   -1  7301     /**
   -1  7302      * Updates bounds using the given vertices and extends the bounds given a velocity.
   -1  7303      * @method update
   -1  7304      * @param {bounds} bounds
   -1  7305      * @param {vertices} vertices
   -1  7306      * @param {vector} velocity
   -1  7307      */
   -1  7308     Bounds.update = function(bounds, vertices, velocity) {
   -1  7309         bounds.min.x = Infinity;
   -1  7310         bounds.max.x = -Infinity;
   -1  7311         bounds.min.y = Infinity;
   -1  7312         bounds.max.y = -Infinity;
   -1  7313 
   -1  7314         for (var i = 0; i < vertices.length; i++) {
   -1  7315             var vertex = vertices[i];
   -1  7316             if (vertex.x > bounds.max.x) bounds.max.x = vertex.x;
   -1  7317             if (vertex.x < bounds.min.x) bounds.min.x = vertex.x;
   -1  7318             if (vertex.y > bounds.max.y) bounds.max.y = vertex.y;
   -1  7319             if (vertex.y < bounds.min.y) bounds.min.y = vertex.y;
   -1  7320         }
   -1  7321         
   -1  7322         if (velocity) {
   -1  7323             if (velocity.x > 0) {
   -1  7324                 bounds.max.x += velocity.x;
   -1  7325             } else {
   -1  7326                 bounds.min.x += velocity.x;
   -1  7327             }
   -1  7328             
   -1  7329             if (velocity.y > 0) {
   -1  7330                 bounds.max.y += velocity.y;
   -1  7331             } else {
   -1  7332                 bounds.min.y += velocity.y;
   -1  7333             }
   -1  7334         }
   -1  7335     };
   -1  7336 
   -1  7337     /**
   -1  7338      * Returns true if the bounds contains the given point.
   -1  7339      * @method contains
   -1  7340      * @param {bounds} bounds
   -1  7341      * @param {vector} point
   -1  7342      * @return {boolean} True if the bounds contain the point, otherwise false
   -1  7343      */
   -1  7344     Bounds.contains = function(bounds, point) {
   -1  7345         return point.x >= bounds.min.x && point.x <= bounds.max.x 
   -1  7346                && point.y >= bounds.min.y && point.y <= bounds.max.y;
   -1  7347     };
   -1  7348 
   -1  7349     /**
   -1  7350      * Returns true if the two bounds intersect.
   -1  7351      * @method overlaps
   -1  7352      * @param {bounds} boundsA
   -1  7353      * @param {bounds} boundsB
   -1  7354      * @return {boolean} True if the bounds overlap, otherwise false
   -1  7355      */
   -1  7356     Bounds.overlaps = function(boundsA, boundsB) {
   -1  7357         return (boundsA.min.x <= boundsB.max.x && boundsA.max.x >= boundsB.min.x
   -1  7358                 && boundsA.max.y >= boundsB.min.y && boundsA.min.y <= boundsB.max.y);
   -1  7359     };
   -1  7360 
   -1  7361     /**
   -1  7362      * Translates the bounds by the given vector.
   -1  7363      * @method translate
   -1  7364      * @param {bounds} bounds
   -1  7365      * @param {vector} vector
   -1  7366      */
   -1  7367     Bounds.translate = function(bounds, vector) {
   -1  7368         bounds.min.x += vector.x;
   -1  7369         bounds.max.x += vector.x;
   -1  7370         bounds.min.y += vector.y;
   -1  7371         bounds.max.y += vector.y;
   -1  7372     };
   -1  7373 
   -1  7374     /**
   -1  7375      * Shifts the bounds to the given position.
   -1  7376      * @method shift
   -1  7377      * @param {bounds} bounds
   -1  7378      * @param {vector} position
   -1  7379      */
   -1  7380     Bounds.shift = function(bounds, position) {
   -1  7381         var deltaX = bounds.max.x - bounds.min.x,
   -1  7382             deltaY = bounds.max.y - bounds.min.y;
   -1  7383             
   -1  7384         bounds.min.x = position.x;
   -1  7385         bounds.max.x = position.x + deltaX;
   -1  7386         bounds.min.y = position.y;
   -1  7387         bounds.max.y = position.y + deltaY;
   -1  7388     };
   -1  7389     
   -1  7390 })();
   -1  7391 
   -1  7392 },{}],27:[function(_dereq_,module,exports){
   -1  7393 /**
   -1  7394 * The `Matter.Svg` module contains methods for converting SVG images into an array of vector points.
   -1  7395 *
   -1  7396 * To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg
   -1  7397 *
   -1  7398 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  7399 *
   -1  7400 * @class Svg
   -1  7401 */
   -1  7402 
   -1  7403 var Svg = {};
   -1  7404 
   -1  7405 module.exports = Svg;
   -1  7406 
   -1  7407 var Bounds = _dereq_('../geometry/Bounds');
   -1  7408 var Common = _dereq_('../core/Common');
   -1  7409 
   -1  7410 (function() {
   -1  7411 
   -1  7412     /**
   -1  7413      * Converts an SVG path into an array of vector points.
   -1  7414      * If the input path forms a concave shape, you must decompose the result into convex parts before use.
   -1  7415      * See `Bodies.fromVertices` which provides support for this.
   -1  7416      * Note that this function is not guaranteed to support complex paths (such as those with holes).
   -1  7417      * You must load the `pathseg.js` polyfill on newer browsers.
   -1  7418      * @method pathToVertices
   -1  7419      * @param {SVGPathElement} path
   -1  7420      * @param {Number} [sampleLength=15]
   -1  7421      * @return {Vector[]} points
   -1  7422      */
   -1  7423     Svg.pathToVertices = function(path, sampleLength) {
   -1  7424         if (typeof window !== 'undefined' && !('SVGPathSeg' in window)) {
   -1  7425             Common.warn('Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.');
   -1  7426         }
   -1  7427 
   -1  7428         // https://github.com/wout/svg.topoly.js/blob/master/svg.topoly.js
   -1  7429         var i, il, total, point, segment, segments, 
   -1  7430             segmentsQueue, lastSegment, 
   -1  7431             lastPoint, segmentIndex, points = [],
   -1  7432             lx, ly, length = 0, x = 0, y = 0;
   -1  7433 
   -1  7434         sampleLength = sampleLength || 15;
   -1  7435 
   -1  7436         var addPoint = function(px, py, pathSegType) {
   -1  7437             // all odd-numbered path types are relative except PATHSEG_CLOSEPATH (1)
   -1  7438             var isRelative = pathSegType % 2 === 1 && pathSegType > 1;
   -1  7439 
   -1  7440             // when the last point doesn't equal the current point add the current point
   -1  7441             if (!lastPoint || px != lastPoint.x || py != lastPoint.y) {
   -1  7442                 if (lastPoint && isRelative) {
   -1  7443                     lx = lastPoint.x;
   -1  7444                     ly = lastPoint.y;
   -1  7445                 } else {
   -1  7446                     lx = 0;
   -1  7447                     ly = 0;
   -1  7448                 }
   -1  7449 
   -1  7450                 var point = {
   -1  7451                     x: lx + px,
   -1  7452                     y: ly + py
   -1  7453                 };
   -1  7454 
   -1  7455                 // set last point
   -1  7456                 if (isRelative || !lastPoint) {
   -1  7457                     lastPoint = point;
   -1  7458                 }
   -1  7459 
   -1  7460                 points.push(point);
   -1  7461 
   -1  7462                 x = lx + px;
   -1  7463                 y = ly + py;
   -1  7464             }
   -1  7465         };
   -1  7466 
   -1  7467         var addSegmentPoint = function(segment) {
   -1  7468             var segType = segment.pathSegTypeAsLetter.toUpperCase();
   -1  7469 
   -1  7470             // skip path ends
   -1  7471             if (segType === 'Z') 
   -1  7472                 return;
   -1  7473 
   -1  7474             // map segment to x and y
   -1  7475             switch (segType) {
   -1  7476 
   -1  7477             case 'M':
   -1  7478             case 'L':
   -1  7479             case 'T':
   -1  7480             case 'C':
   -1  7481             case 'S':
   -1  7482             case 'Q':
   -1  7483                 x = segment.x;
   -1  7484                 y = segment.y;
   -1  7485                 break;
   -1  7486             case 'H':
   -1  7487                 x = segment.x;
   -1  7488                 break;
   -1  7489             case 'V':
   -1  7490                 y = segment.y;
   -1  7491                 break;
   -1  7492             }
   -1  7493 
   -1  7494             addPoint(x, y, segment.pathSegType);
   -1  7495         };
   -1  7496 
   -1  7497         // ensure path is absolute
   -1  7498         Svg._svgPathToAbsolute(path);
   -1  7499 
   -1  7500         // get total length
   -1  7501         total = path.getTotalLength();
   -1  7502 
   -1  7503         // queue segments
   -1  7504         segments = [];
   -1  7505         for (i = 0; i < path.pathSegList.numberOfItems; i += 1)
   -1  7506             segments.push(path.pathSegList.getItem(i));
   -1  7507 
   -1  7508         segmentsQueue = segments.concat();
   -1  7509 
   -1  7510         // sample through path
   -1  7511         while (length < total) {
   -1  7512             // get segment at position
   -1  7513             segmentIndex = path.getPathSegAtLength(length);
   -1  7514             segment = segments[segmentIndex];
   -1  7515 
   -1  7516             // new segment
   -1  7517             if (segment != lastSegment) {
   -1  7518                 while (segmentsQueue.length && segmentsQueue[0] != segment)
   -1  7519                     addSegmentPoint(segmentsQueue.shift());
   -1  7520 
   -1  7521                 lastSegment = segment;
   -1  7522             }
   -1  7523 
   -1  7524             // add points in between when curving
   -1  7525             // TODO: adaptive sampling
   -1  7526             switch (segment.pathSegTypeAsLetter.toUpperCase()) {
   -1  7527 
   -1  7528             case 'C':
   -1  7529             case 'T':
   -1  7530             case 'S':
   -1  7531             case 'Q':
   -1  7532             case 'A':
   -1  7533                 point = path.getPointAtLength(length);
   -1  7534                 addPoint(point.x, point.y, 0);
   -1  7535                 break;
   -1  7536 
   -1  7537             }
   -1  7538 
   -1  7539             // increment by sample value
   -1  7540             length += sampleLength;
   -1  7541         }
   -1  7542 
   -1  7543         // add remaining segments not passed by sampling
   -1  7544         for (i = 0, il = segmentsQueue.length; i < il; ++i)
   -1  7545             addSegmentPoint(segmentsQueue[i]);
   -1  7546 
   -1  7547         return points;
   -1  7548     };
   -1  7549 
   -1  7550     Svg._svgPathToAbsolute = function(path) {
   -1  7551         // http://phrogz.net/convert-svg-path-to-all-absolute-commands
   -1  7552         // Copyright (c) Gavin Kistner
   -1  7553         // http://phrogz.net/js/_ReuseLicense.txt
   -1  7554         // Modifications: tidy formatting and naming
   -1  7555         var x0, y0, x1, y1, x2, y2, segs = path.pathSegList,
   -1  7556             x = 0, y = 0, len = segs.numberOfItems;
   -1  7557 
   -1  7558         for (var i = 0; i < len; ++i) {
   -1  7559             var seg = segs.getItem(i),
   -1  7560                 segType = seg.pathSegTypeAsLetter;
   -1  7561 
   -1  7562             if (/[MLHVCSQTA]/.test(segType)) {
   -1  7563                 if ('x' in seg) x = seg.x;
   -1  7564                 if ('y' in seg) y = seg.y;
   -1  7565             } else {
   -1  7566                 if ('x1' in seg) x1 = x + seg.x1;
   -1  7567                 if ('x2' in seg) x2 = x + seg.x2;
   -1  7568                 if ('y1' in seg) y1 = y + seg.y1;
   -1  7569                 if ('y2' in seg) y2 = y + seg.y2;
   -1  7570                 if ('x' in seg) x += seg.x;
   -1  7571                 if ('y' in seg) y += seg.y;
   -1  7572 
   -1  7573                 switch (segType) {
   -1  7574 
   -1  7575                 case 'm':
   -1  7576                     segs.replaceItem(path.createSVGPathSegMovetoAbs(x, y), i);
   -1  7577                     break;
   -1  7578                 case 'l':
   -1  7579                     segs.replaceItem(path.createSVGPathSegLinetoAbs(x, y), i);
   -1  7580                     break;
   -1  7581                 case 'h':
   -1  7582                     segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x), i);
   -1  7583                     break;
   -1  7584                 case 'v':
   -1  7585                     segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y), i);
   -1  7586                     break;
   -1  7587                 case 'c':
   -1  7588                     segs.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i);
   -1  7589                     break;
   -1  7590                 case 's':
   -1  7591                     segs.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i);
   -1  7592                     break;
   -1  7593                 case 'q':
   -1  7594                     segs.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i);
   -1  7595                     break;
   -1  7596                 case 't':
   -1  7597                     segs.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i);
   -1  7598                     break;
   -1  7599                 case 'a':
   -1  7600                     segs.replaceItem(path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle, seg.largeArcFlag, seg.sweepFlag), i);
   -1  7601                     break;
   -1  7602                 case 'z':
   -1  7603                 case 'Z':
   -1  7604                     x = x0;
   -1  7605                     y = y0;
   -1  7606                     break;
   -1  7607 
   -1  7608                 }
   -1  7609             }
   -1  7610 
   -1  7611             if (segType == 'M' || segType == 'm') {
   -1  7612                 x0 = x;
   -1  7613                 y0 = y;
   -1  7614             }
   -1  7615         }
   -1  7616     };
   -1  7617 
   -1  7618 })();
   -1  7619 },{"../core/Common":14,"../geometry/Bounds":26}],28:[function(_dereq_,module,exports){
   -1  7620 /**
   -1  7621 * The `Matter.Vector` module contains methods for creating and manipulating vectors.
   -1  7622 * Vectors are the basis of all the geometry related operations in the engine.
   -1  7623 * A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`.
   -1  7624 *
   -1  7625 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  7626 *
   -1  7627 * @class Vector
   -1  7628 */
   -1  7629 
   -1  7630 // TODO: consider params for reusing vector objects
   -1  7631 
   -1  7632 var Vector = {};
   -1  7633 
   -1  7634 module.exports = Vector;
   -1  7635 
   -1  7636 (function() {
   -1  7637 
   -1  7638     /**
   -1  7639      * Creates a new vector.
   -1  7640      * @method create
   -1  7641      * @param {number} x
   -1  7642      * @param {number} y
   -1  7643      * @return {vector} A new vector
   -1  7644      */
   -1  7645     Vector.create = function(x, y) {
   -1  7646         return { x: x || 0, y: y || 0 };
   -1  7647     };
   -1  7648 
   -1  7649     /**
   -1  7650      * Returns a new vector with `x` and `y` copied from the given `vector`.
   -1  7651      * @method clone
   -1  7652      * @param {vector} vector
   -1  7653      * @return {vector} A new cloned vector
   -1  7654      */
   -1  7655     Vector.clone = function(vector) {
   -1  7656         return { x: vector.x, y: vector.y };
   -1  7657     };
   -1  7658 
   -1  7659     /**
   -1  7660      * Returns the magnitude (length) of a vector.
   -1  7661      * @method magnitude
   -1  7662      * @param {vector} vector
   -1  7663      * @return {number} The magnitude of the vector
   -1  7664      */
   -1  7665     Vector.magnitude = function(vector) {
   -1  7666         return Math.sqrt((vector.x * vector.x) + (vector.y * vector.y));
   -1  7667     };
   -1  7668 
   -1  7669     /**
   -1  7670      * Returns the magnitude (length) of a vector (therefore saving a `sqrt` operation).
   -1  7671      * @method magnitudeSquared
   -1  7672      * @param {vector} vector
   -1  7673      * @return {number} The squared magnitude of the vector
   -1  7674      */
   -1  7675     Vector.magnitudeSquared = function(vector) {
   -1  7676         return (vector.x * vector.x) + (vector.y * vector.y);
   -1  7677     };
   -1  7678 
   -1  7679     /**
   -1  7680      * Rotates the vector about (0, 0) by specified angle.
   -1  7681      * @method rotate
   -1  7682      * @param {vector} vector
   -1  7683      * @param {number} angle
   -1  7684      * @param {vector} [output]
   -1  7685      * @return {vector} The vector rotated about (0, 0)
   -1  7686      */
   -1  7687     Vector.rotate = function(vector, angle, output) {
   -1  7688         var cos = Math.cos(angle), sin = Math.sin(angle);
   -1  7689         if (!output) output = {};
   -1  7690         var x = vector.x * cos - vector.y * sin;
   -1  7691         output.y = vector.x * sin + vector.y * cos;
   -1  7692         output.x = x;
   -1  7693         return output;
   -1  7694     };
   -1  7695 
   -1  7696     /**
   -1  7697      * Rotates the vector about a specified point by specified angle.
   -1  7698      * @method rotateAbout
   -1  7699      * @param {vector} vector
   -1  7700      * @param {number} angle
   -1  7701      * @param {vector} point
   -1  7702      * @param {vector} [output]
   -1  7703      * @return {vector} A new vector rotated about the point
   -1  7704      */
   -1  7705     Vector.rotateAbout = function(vector, angle, point, output) {
   -1  7706         var cos = Math.cos(angle), sin = Math.sin(angle);
   -1  7707         if (!output) output = {};
   -1  7708         var x = point.x + ((vector.x - point.x) * cos - (vector.y - point.y) * sin);
   -1  7709         output.y = point.y + ((vector.x - point.x) * sin + (vector.y - point.y) * cos);
   -1  7710         output.x = x;
   -1  7711         return output;
   -1  7712     };
   -1  7713 
   -1  7714     /**
   -1  7715      * Normalises a vector (such that its magnitude is `1`).
   -1  7716      * @method normalise
   -1  7717      * @param {vector} vector
   -1  7718      * @return {vector} A new vector normalised
   -1  7719      */
   -1  7720     Vector.normalise = function(vector) {
   -1  7721         var magnitude = Vector.magnitude(vector);
   -1  7722         if (magnitude === 0)
   -1  7723             return { x: 0, y: 0 };
   -1  7724         return { x: vector.x / magnitude, y: vector.y / magnitude };
   -1  7725     };
   -1  7726 
   -1  7727     /**
   -1  7728      * Returns the dot-product of two vectors.
   -1  7729      * @method dot
   -1  7730      * @param {vector} vectorA
   -1  7731      * @param {vector} vectorB
   -1  7732      * @return {number} The dot product of the two vectors
   -1  7733      */
   -1  7734     Vector.dot = function(vectorA, vectorB) {
   -1  7735         return (vectorA.x * vectorB.x) + (vectorA.y * vectorB.y);
   -1  7736     };
   -1  7737 
   -1  7738     /**
   -1  7739      * Returns the cross-product of two vectors.
   -1  7740      * @method cross
   -1  7741      * @param {vector} vectorA
   -1  7742      * @param {vector} vectorB
   -1  7743      * @return {number} The cross product of the two vectors
   -1  7744      */
   -1  7745     Vector.cross = function(vectorA, vectorB) {
   -1  7746         return (vectorA.x * vectorB.y) - (vectorA.y * vectorB.x);
   -1  7747     };
   -1  7748 
   -1  7749     /**
   -1  7750      * Returns the cross-product of three vectors.
   -1  7751      * @method cross3
   -1  7752      * @param {vector} vectorA
   -1  7753      * @param {vector} vectorB
   -1  7754      * @param {vector} vectorC
   -1  7755      * @return {number} The cross product of the three vectors
   -1  7756      */
   -1  7757     Vector.cross3 = function(vectorA, vectorB, vectorC) {
   -1  7758         return (vectorB.x - vectorA.x) * (vectorC.y - vectorA.y) - (vectorB.y - vectorA.y) * (vectorC.x - vectorA.x);
   -1  7759     };
   -1  7760 
   -1  7761     /**
   -1  7762      * Adds the two vectors.
   -1  7763      * @method add
   -1  7764      * @param {vector} vectorA
   -1  7765      * @param {vector} vectorB
   -1  7766      * @param {vector} [output]
   -1  7767      * @return {vector} A new vector of vectorA and vectorB added
   -1  7768      */
   -1  7769     Vector.add = function(vectorA, vectorB, output) {
   -1  7770         if (!output) output = {};
   -1  7771         output.x = vectorA.x + vectorB.x;
   -1  7772         output.y = vectorA.y + vectorB.y;
   -1  7773         return output;
   -1  7774     };
   -1  7775 
   -1  7776     /**
   -1  7777      * Subtracts the two vectors.
   -1  7778      * @method sub
   -1  7779      * @param {vector} vectorA
   -1  7780      * @param {vector} vectorB
   -1  7781      * @param {vector} [output]
   -1  7782      * @return {vector} A new vector of vectorA and vectorB subtracted
   -1  7783      */
   -1  7784     Vector.sub = function(vectorA, vectorB, output) {
   -1  7785         if (!output) output = {};
   -1  7786         output.x = vectorA.x - vectorB.x;
   -1  7787         output.y = vectorA.y - vectorB.y;
   -1  7788         return output;
   -1  7789     };
   -1  7790 
   -1  7791     /**
   -1  7792      * Multiplies a vector and a scalar.
   -1  7793      * @method mult
   -1  7794      * @param {vector} vector
   -1  7795      * @param {number} scalar
   -1  7796      * @return {vector} A new vector multiplied by scalar
   -1  7797      */
   -1  7798     Vector.mult = function(vector, scalar) {
   -1  7799         return { x: vector.x * scalar, y: vector.y * scalar };
   -1  7800     };
   -1  7801 
   -1  7802     /**
   -1  7803      * Divides a vector and a scalar.
   -1  7804      * @method div
   -1  7805      * @param {vector} vector
   -1  7806      * @param {number} scalar
   -1  7807      * @return {vector} A new vector divided by scalar
   -1  7808      */
   -1  7809     Vector.div = function(vector, scalar) {
   -1  7810         return { x: vector.x / scalar, y: vector.y / scalar };
   -1  7811     };
   -1  7812 
   -1  7813     /**
   -1  7814      * Returns the perpendicular vector. Set `negate` to true for the perpendicular in the opposite direction.
   -1  7815      * @method perp
   -1  7816      * @param {vector} vector
   -1  7817      * @param {bool} [negate=false]
   -1  7818      * @return {vector} The perpendicular vector
   -1  7819      */
   -1  7820     Vector.perp = function(vector, negate) {
   -1  7821         negate = negate === true ? -1 : 1;
   -1  7822         return { x: negate * -vector.y, y: negate * vector.x };
   -1  7823     };
   -1  7824 
   -1  7825     /**
   -1  7826      * Negates both components of a vector such that it points in the opposite direction.
   -1  7827      * @method neg
   -1  7828      * @param {vector} vector
   -1  7829      * @return {vector} The negated vector
   -1  7830      */
   -1  7831     Vector.neg = function(vector) {
   -1  7832         return { x: -vector.x, y: -vector.y };
   -1  7833     };
   -1  7834 
   -1  7835     /**
   -1  7836      * Returns the angle between the vector `vectorB - vectorA` and the x-axis in radians.
   -1  7837      * @method angle
   -1  7838      * @param {vector} vectorA
   -1  7839      * @param {vector} vectorB
   -1  7840      * @return {number} The angle in radians
   -1  7841      */
   -1  7842     Vector.angle = function(vectorA, vectorB) {
   -1  7843         return Math.atan2(vectorB.y - vectorA.y, vectorB.x - vectorA.x);
   -1  7844     };
   -1  7845 
   -1  7846     /**
   -1  7847      * Temporary vector pool (not thread-safe).
   -1  7848      * @property _temp
   -1  7849      * @type {vector[]}
   -1  7850      * @private
   -1  7851      */
   -1  7852     Vector._temp = [
   -1  7853         Vector.create(), Vector.create(), 
   -1  7854         Vector.create(), Vector.create(), 
   -1  7855         Vector.create(), Vector.create()
   -1  7856     ];
   -1  7857 
   -1  7858 })();
   -1  7859 },{}],29:[function(_dereq_,module,exports){
   -1  7860 /**
   -1  7861 * The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
   -1  7862 * A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
   -1  7863 * A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
   -1  7864 *
   -1  7865 * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
   -1  7866 *
   -1  7867 * @class Vertices
   -1  7868 */
   -1  7869 
   -1  7870 var Vertices = {};
   -1  7871 
   -1  7872 module.exports = Vertices;
   -1  7873 
   -1  7874 var Vector = _dereq_('../geometry/Vector');
   -1  7875 var Common = _dereq_('../core/Common');
   -1  7876 
   -1  7877 (function() {
   -1  7878 
   -1  7879     /**
   -1  7880      * Creates a new set of `Matter.Body` compatible vertices.
   -1  7881      * The `points` argument accepts an array of `Matter.Vector` points orientated around the origin `(0, 0)`, for example:
   -1  7882      *
   -1  7883      *     [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]
   -1  7884      *
   -1  7885      * The `Vertices.create` method returns a new array of vertices, which are similar to Matter.Vector objects,
   -1  7886      * but with some additional references required for efficient collision detection routines.
   -1  7887      *
   -1  7888      * Vertices must be specified in clockwise order.
   -1  7889      *
   -1  7890      * Note that the `body` argument is not optional, a `Matter.Body` reference must be provided.
   -1  7891      *
   -1  7892      * @method create
   -1  7893      * @param {vector[]} points
   -1  7894      * @param {body} body
   -1  7895      */
   -1  7896     Vertices.create = function(points, body) {
   -1  7897         var vertices = [];
   -1  7898 
   -1  7899         for (var i = 0; i < points.length; i++) {
   -1  7900             var point = points[i],
   -1  7901                 vertex = {
   -1  7902                     x: point.x,
   -1  7903                     y: point.y,
   -1  7904                     index: i,
   -1  7905                     body: body,
   -1  7906                     isInternal: false
   -1  7907                 };
   -1  7908 
   -1  7909             vertices.push(vertex);
   -1  7910         }
   -1  7911 
   -1  7912         return vertices;
   -1  7913     };
   -1  7914 
   -1  7915     /**
   -1  7916      * Parses a string containing ordered x y pairs separated by spaces (and optionally commas), 
   -1  7917      * into a `Matter.Vertices` object for the given `Matter.Body`.
   -1  7918      * For parsing SVG paths, see `Svg.pathToVertices`.
   -1  7919      * @method fromPath
   -1  7920      * @param {string} path
   -1  7921      * @param {body} body
   -1  7922      * @return {vertices} vertices
   -1  7923      */
   -1  7924     Vertices.fromPath = function(path, body) {
   -1  7925         var pathPattern = /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig,
   -1  7926             points = [];
   -1  7927 
   -1  7928         path.replace(pathPattern, function(match, x, y) {
   -1  7929             points.push({ x: parseFloat(x), y: parseFloat(y) });
   -1  7930         });
   -1  7931 
   -1  7932         return Vertices.create(points, body);
   -1  7933     };
   -1  7934 
   -1  7935     /**
   -1  7936      * Returns the centre (centroid) of the set of vertices.
   -1  7937      * @method centre
   -1  7938      * @param {vertices} vertices
   -1  7939      * @return {vector} The centre point
   -1  7940      */
   -1  7941     Vertices.centre = function(vertices) {
   -1  7942         var area = Vertices.area(vertices, true),
   -1  7943             centre = { x: 0, y: 0 },
   -1  7944             cross,
   -1  7945             temp,
   -1  7946             j;
   -1  7947 
   -1  7948         for (var i = 0; i < vertices.length; i++) {
   -1  7949             j = (i + 1) % vertices.length;
   -1  7950             cross = Vector.cross(vertices[i], vertices[j]);
   -1  7951             temp = Vector.mult(Vector.add(vertices[i], vertices[j]), cross);
   -1  7952             centre = Vector.add(centre, temp);
   -1  7953         }
   -1  7954 
   -1  7955         return Vector.div(centre, 6 * area);
   -1  7956     };
   -1  7957 
   -1  7958     /**
   -1  7959      * Returns the average (mean) of the set of vertices.
   -1  7960      * @method mean
   -1  7961      * @param {vertices} vertices
   -1  7962      * @return {vector} The average point
   -1  7963      */
   -1  7964     Vertices.mean = function(vertices) {
   -1  7965         var average = { x: 0, y: 0 };
   -1  7966 
   -1  7967         for (var i = 0; i < vertices.length; i++) {
   -1  7968             average.x += vertices[i].x;
   -1  7969             average.y += vertices[i].y;
   -1  7970         }
   -1  7971 
   -1  7972         return Vector.div(average, vertices.length);
   -1  7973     };
   -1  7974 
   -1  7975     /**
   -1  7976      * Returns the area of the set of vertices.
   -1  7977      * @method area
   -1  7978      * @param {vertices} vertices
   -1  7979      * @param {bool} signed
   -1  7980      * @return {number} The area
   -1  7981      */
   -1  7982     Vertices.area = function(vertices, signed) {
   -1  7983         var area = 0,
   -1  7984             j = vertices.length - 1;
   -1  7985 
   -1  7986         for (var i = 0; i < vertices.length; i++) {
   -1  7987             area += (vertices[j].x - vertices[i].x) * (vertices[j].y + vertices[i].y);
   -1  7988             j = i;
   -1  7989         }
   -1  7990 
   -1  7991         if (signed)
   -1  7992             return area / 2;
   -1  7993 
   -1  7994         return Math.abs(area) / 2;
   -1  7995     };
   -1  7996 
   -1  7997     /**
   -1  7998      * Returns the moment of inertia (second moment of area) of the set of vertices given the total mass.
   -1  7999      * @method inertia
   -1  8000      * @param {vertices} vertices
   -1  8001      * @param {number} mass
   -1  8002      * @return {number} The polygon's moment of inertia
   -1  8003      */
   -1  8004     Vertices.inertia = function(vertices, mass) {
   -1  8005         var numerator = 0,
   -1  8006             denominator = 0,
   -1  8007             v = vertices,
   -1  8008             cross,
   -1  8009             j;
   -1  8010 
   -1  8011         // find the polygon's moment of inertia, using second moment of area
   -1  8012         // from equations at http://www.physicsforums.com/showthread.php?t=25293
   -1  8013         for (var n = 0; n < v.length; n++) {
   -1  8014             j = (n + 1) % v.length;
   -1  8015             cross = Math.abs(Vector.cross(v[j], v[n]));
   -1  8016             numerator += cross * (Vector.dot(v[j], v[j]) + Vector.dot(v[j], v[n]) + Vector.dot(v[n], v[n]));
   -1  8017             denominator += cross;
   -1  8018         }
   -1  8019 
   -1  8020         return (mass / 6) * (numerator / denominator);
   -1  8021     };
   -1  8022 
   -1  8023     /**
   -1  8024      * Translates the set of vertices in-place.
   -1  8025      * @method translate
   -1  8026      * @param {vertices} vertices
   -1  8027      * @param {vector} vector
   -1  8028      * @param {number} scalar
   -1  8029      */
   -1  8030     Vertices.translate = function(vertices, vector, scalar) {
   -1  8031         var i;
   -1  8032         if (scalar) {
   -1  8033             for (i = 0; i < vertices.length; i++) {
   -1  8034                 vertices[i].x += vector.x * scalar;
   -1  8035                 vertices[i].y += vector.y * scalar;
   -1  8036             }
   -1  8037         } else {
   -1  8038             for (i = 0; i < vertices.length; i++) {
   -1  8039                 vertices[i].x += vector.x;
   -1  8040                 vertices[i].y += vector.y;
   -1  8041             }
   -1  8042         }
   -1  8043 
   -1  8044         return vertices;
   -1  8045     };
   -1  8046 
   -1  8047     /**
   -1  8048      * Rotates the set of vertices in-place.
   -1  8049      * @method rotate
   -1  8050      * @param {vertices} vertices
   -1  8051      * @param {number} angle
   -1  8052      * @param {vector} point
   -1  8053      */
   -1  8054     Vertices.rotate = function(vertices, angle, point) {
   -1  8055         if (angle === 0)
   -1  8056             return;
   -1  8057 
   -1  8058         var cos = Math.cos(angle),
   -1  8059             sin = Math.sin(angle);
   -1  8060 
   -1  8061         for (var i = 0; i < vertices.length; i++) {
   -1  8062             var vertice = vertices[i],
   -1  8063                 dx = vertice.x - point.x,
   -1  8064                 dy = vertice.y - point.y;
   -1  8065                 
   -1  8066             vertice.x = point.x + (dx * cos - dy * sin);
   -1  8067             vertice.y = point.y + (dx * sin + dy * cos);
   -1  8068         }
   -1  8069 
   -1  8070         return vertices;
   -1  8071     };
   -1  8072 
   -1  8073     /**
   -1  8074      * Returns `true` if the `point` is inside the set of `vertices`.
   -1  8075      * @method contains
   -1  8076      * @param {vertices} vertices
   -1  8077      * @param {vector} point
   -1  8078      * @return {boolean} True if the vertices contains point, otherwise false
   -1  8079      */
   -1  8080     Vertices.contains = function(vertices, point) {
   -1  8081         for (var i = 0; i < vertices.length; i++) {
   -1  8082             var vertice = vertices[i],
   -1  8083                 nextVertice = vertices[(i + 1) % vertices.length];
   -1  8084             if ((point.x - vertice.x) * (nextVertice.y - vertice.y) + (point.y - vertice.y) * (vertice.x - nextVertice.x) > 0) {
   -1  8085                 return false;
   -1  8086             }
   -1  8087         }
   -1  8088 
   -1  8089         return true;
   -1  8090     };
   -1  8091 
   -1  8092     /**
   -1  8093      * Scales the vertices from a point (default is centre) in-place.
   -1  8094      * @method scale
   -1  8095      * @param {vertices} vertices
   -1  8096      * @param {number} scaleX
   -1  8097      * @param {number} scaleY
   -1  8098      * @param {vector} point
   -1  8099      */
   -1  8100     Vertices.scale = function(vertices, scaleX, scaleY, point) {
   -1  8101         if (scaleX === 1 && scaleY === 1)
   -1  8102             return vertices;
   -1  8103 
   -1  8104         point = point || Vertices.centre(vertices);
   -1  8105 
   -1  8106         var vertex,
   -1  8107             delta;
   -1  8108 
   -1  8109         for (var i = 0; i < vertices.length; i++) {
   -1  8110             vertex = vertices[i];
   -1  8111             delta = Vector.sub(vertex, point);
   -1  8112             vertices[i].x = point.x + delta.x * scaleX;
   -1  8113             vertices[i].y = point.y + delta.y * scaleY;
   -1  8114         }
   -1  8115 
   -1  8116         return vertices;
   -1  8117     };
   -1  8118 
   -1  8119     /**
   -1  8120      * Chamfers a set of vertices by giving them rounded corners, returns a new set of vertices.
   -1  8121      * The radius parameter is a single number or an array to specify the radius for each vertex.
   -1  8122      * @method chamfer
   -1  8123      * @param {vertices} vertices
   -1  8124      * @param {number[]} radius
   -1  8125      * @param {number} quality
   -1  8126      * @param {number} qualityMin
   -1  8127      * @param {number} qualityMax
   -1  8128      */
   -1  8129     Vertices.chamfer = function(vertices, radius, quality, qualityMin, qualityMax) {
   -1  8130         if (typeof radius === 'number') {
   -1  8131             radius = [radius];
   -1  8132         } else {
   -1  8133             radius = radius || [8];
   -1  8134         }
   -1  8135 
   -1  8136         // quality defaults to -1, which is auto
   -1  8137         quality = (typeof quality !== 'undefined') ? quality : -1;
   -1  8138         qualityMin = qualityMin || 2;
   -1  8139         qualityMax = qualityMax || 14;
   -1  8140 
   -1  8141         var newVertices = [];
   -1  8142 
   -1  8143         for (var i = 0; i < vertices.length; i++) {
   -1  8144             var prevVertex = vertices[i - 1 >= 0 ? i - 1 : vertices.length - 1],
   -1  8145                 vertex = vertices[i],
   -1  8146                 nextVertex = vertices[(i + 1) % vertices.length],
   -1  8147                 currentRadius = radius[i < radius.length ? i : radius.length - 1];
   -1  8148 
   -1  8149             if (currentRadius === 0) {
   -1  8150                 newVertices.push(vertex);
   -1  8151                 continue;
   -1  8152             }
   -1  8153 
   -1  8154             var prevNormal = Vector.normalise({ 
   -1  8155                 x: vertex.y - prevVertex.y, 
   -1  8156                 y: prevVertex.x - vertex.x
   -1  8157             });
   -1  8158 
   -1  8159             var nextNormal = Vector.normalise({ 
   -1  8160                 x: nextVertex.y - vertex.y, 
   -1  8161                 y: vertex.x - nextVertex.x
   -1  8162             });
   -1  8163 
   -1  8164             var diagonalRadius = Math.sqrt(2 * Math.pow(currentRadius, 2)),
   -1  8165                 radiusVector = Vector.mult(Common.clone(prevNormal), currentRadius),
   -1  8166                 midNormal = Vector.normalise(Vector.mult(Vector.add(prevNormal, nextNormal), 0.5)),
   -1  8167                 scaledVertex = Vector.sub(vertex, Vector.mult(midNormal, diagonalRadius));
   -1  8168 
   -1  8169             var precision = quality;
   -1  8170 
   -1  8171             if (quality === -1) {
   -1  8172                 // automatically decide precision
   -1  8173                 precision = Math.pow(currentRadius, 0.32) * 1.75;
   -1  8174             }
   -1  8175 
   -1  8176             precision = Common.clamp(precision, qualityMin, qualityMax);
   -1  8177 
   -1  8178             // use an even value for precision, more likely to reduce axes by using symmetry
   -1  8179             if (precision % 2 === 1)
   -1  8180                 precision += 1;
   -1  8181 
   -1  8182             var alpha = Math.acos(Vector.dot(prevNormal, nextNormal)),
   -1  8183                 theta = alpha / precision;
   -1  8184 
   -1  8185             for (var j = 0; j < precision; j++) {
   -1  8186                 newVertices.push(Vector.add(Vector.rotate(radiusVector, theta * j), scaledVertex));
   -1  8187             }
   -1  8188         }
   -1  8189 
   -1  8190         return newVertices;
   -1  8191     };
   -1  8192 
   -1  8193     /**
   -1  8194      * Sorts the input vertices into clockwise order in place.
   -1  8195      * @method clockwiseSort
   -1  8196      * @param {vertices} vertices
   -1  8197      * @return {vertices} vertices
   -1  8198      */
   -1  8199     Vertices.clockwiseSort = function(vertices) {
   -1  8200         var centre = Vertices.mean(vertices);
   -1  8201 
   -1  8202         vertices.sort(function(vertexA, vertexB) {
   -1  8203             return Vector.angle(centre, vertexA) - Vector.angle(centre, vertexB);
   -1  8204         });
   -1  8205 
   -1  8206         return vertices;
   -1  8207     };
   -1  8208 
   -1  8209     /**
   -1  8210      * Returns true if the vertices form a convex shape (vertices must be in clockwise order).
   -1  8211      * @method isConvex
   -1  8212      * @param {vertices} vertices
   -1  8213      * @return {bool} `true` if the `vertices` are convex, `false` if not (or `null` if not computable).
   -1  8214      */
   -1  8215     Vertices.isConvex = function(vertices) {
   -1  8216         // http://paulbourke.net/geometry/polygonmesh/
   -1  8217         // Copyright (c) Paul Bourke (use permitted)
   -1  8218 
   -1  8219         var flag = 0,
   -1  8220             n = vertices.length,
   -1  8221             i,
   -1  8222             j,
   -1  8223             k,
   -1  8224             z;
   -1  8225 
   -1  8226         if (n < 3)
   -1  8227             return null;
   -1  8228 
   -1  8229         for (i = 0; i < n; i++) {
   -1  8230             j = (i + 1) % n;
   -1  8231             k = (i + 2) % n;
   -1  8232             z = (vertices[j].x - vertices[i].x) * (vertices[k].y - vertices[j].y);
   -1  8233             z -= (vertices[j].y - vertices[i].y) * (vertices[k].x - vertices[j].x);
   -1  8234 
   -1  8235             if (z < 0) {
   -1  8236                 flag |= 1;
   -1  8237             } else if (z > 0) {
   -1  8238                 flag |= 2;
   -1  8239             }
   -1  8240 
   -1  8241             if (flag === 3) {
   -1  8242                 return false;
   -1  8243             }
   -1  8244         }
   -1  8245 
   -1  8246         if (flag !== 0){
   -1  8247             return true;
   -1  8248         } else {
   -1  8249             return null;
   -1  8250         }
   -1  8251     };
   -1  8252 
   -1  8253     /**
   -1  8254      * Returns the convex hull of the input vertices as a new array of points.
   -1  8255      * @method hull
   -1  8256      * @param {vertices} vertices
   -1  8257      * @return [vertex] vertices
   -1  8258      */
   -1  8259     Vertices.hull = function(vertices) {
   -1  8260         // http://geomalgorithms.com/a10-_hull-1.html
   -1  8261 
   -1  8262         var upper = [],
   -1  8263             lower = [], 
   -1  8264             vertex,
   -1  8265             i;
   -1  8266 
   -1  8267         // sort vertices on x-axis (y-axis for ties)
   -1  8268         vertices = vertices.slice(0);
   -1  8269         vertices.sort(function(vertexA, vertexB) {
   -1  8270             var dx = vertexA.x - vertexB.x;
   -1  8271             return dx !== 0 ? dx : vertexA.y - vertexB.y;
   -1  8272         });
   -1  8273 
   -1  8274         // build lower hull
   -1  8275         for (i = 0; i < vertices.length; i += 1) {
   -1  8276             vertex = vertices[i];
   -1  8277 
   -1  8278             while (lower.length >= 2 
   -1  8279                    && Vector.cross3(lower[lower.length - 2], lower[lower.length - 1], vertex) <= 0) {
   -1  8280                 lower.pop();
   -1  8281             }
   -1  8282 
   -1  8283             lower.push(vertex);
   -1  8284         }
   -1  8285 
   -1  8286         // build upper hull
   -1  8287         for (i = vertices.length - 1; i >= 0; i -= 1) {
   -1  8288             vertex = vertices[i];
   -1  8289 
   -1  8290             while (upper.length >= 2 
   -1  8291                    && Vector.cross3(upper[upper.length - 2], upper[upper.length - 1], vertex) <= 0) {
   -1  8292                 upper.pop();
   -1  8293             }
   -1  8294 
   -1  8295             upper.push(vertex);
   -1  8296         }
   -1  8297 
   -1  8298         // concatenation of the lower and upper hulls gives the convex hull
   -1  8299         // omit last points because they are repeated at the beginning of the other list
   -1  8300         upper.pop();
   -1  8301         lower.pop();
   -1  8302 
   -1  8303         return upper.concat(lower);
   -1  8304     };
   -1  8305 
   -1  8306 })();
   -1  8307 
   -1  8308 },{"../core/Common":14,"../geometry/Vector":28}],30:[function(_dereq_,module,exports){
   -1  8309 var Matter = module.exports = _dereq_('../core/Matter');
   -1  8310 
   -1  8311 Matter.Body = _dereq_('../body/Body');
   -1  8312 Matter.Composite = _dereq_('../body/Composite');
   -1  8313 Matter.World = _dereq_('../body/World');
   -1  8314 
   -1  8315 Matter.Contact = _dereq_('../collision/Contact');
   -1  8316 Matter.Detector = _dereq_('../collision/Detector');
   -1  8317 Matter.Grid = _dereq_('../collision/Grid');
   -1  8318 Matter.Pairs = _dereq_('../collision/Pairs');
   -1  8319 Matter.Pair = _dereq_('../collision/Pair');
   -1  8320 Matter.Query = _dereq_('../collision/Query');
   -1  8321 Matter.Resolver = _dereq_('../collision/Resolver');
   -1  8322 Matter.SAT = _dereq_('../collision/SAT');
   -1  8323 
   -1  8324 Matter.Constraint = _dereq_('../constraint/Constraint');
   -1  8325 Matter.MouseConstraint = _dereq_('../constraint/MouseConstraint');
   -1  8326 
   -1  8327 Matter.Common = _dereq_('../core/Common');
   -1  8328 Matter.Engine = _dereq_('../core/Engine');
   -1  8329 Matter.Events = _dereq_('../core/Events');
   -1  8330 Matter.Mouse = _dereq_('../core/Mouse');
   -1  8331 Matter.Runner = _dereq_('../core/Runner');
   -1  8332 Matter.Sleeping = _dereq_('../core/Sleeping');
   -1  8333 Matter.Plugin = _dereq_('../core/Plugin');
   -1  8334 
   -1  8335 
   -1  8336 Matter.Bodies = _dereq_('../factory/Bodies');
   -1  8337 Matter.Composites = _dereq_('../factory/Composites');
   -1  8338 
   -1  8339 Matter.Axes = _dereq_('../geometry/Axes');
   -1  8340 Matter.Bounds = _dereq_('../geometry/Bounds');
   -1  8341 Matter.Svg = _dereq_('../geometry/Svg');
   -1  8342 Matter.Vector = _dereq_('../geometry/Vector');
   -1  8343 Matter.Vertices = _dereq_('../geometry/Vertices');
   -1  8344 
   -1  8345 Matter.Render = _dereq_('../render/Render');
   -1  8346 Matter.RenderPixi = _dereq_('../render/RenderPixi');
   -1  8347 
   -1  8348 // aliases
   -1  8349 
   -1  8350 Matter.World.add = Matter.Composite.add;
   -1  8351 Matter.World.remove = Matter.Composite.remove;
   -1  8352 Matter.World.addComposite = Matter.Composite.addComposite;
   -1  8353 Matter.World.addBody = Matter.Composite.addBody;
   -1  8354 Matter.World.addConstraint = Matter.Composite.addConstraint;
   -1  8355 Matter.World.clear = Matter.Composite.clear;
   -1  8356 Matter.Engine.run = Matter.Runner.run;
   -1  8357 
   -1  8358 },{"../body/Body":1,"../body/Composite":2,"../body/World":3,"../collision/Contact":4,"../collision/Detector":5,"../collision/Grid":6,"../collision/Pair":7,"../collision/Pairs":8,"../collision/Query":9,"../collision/Resolver":10,"../collision/SAT":11,"../constraint/Constraint":12,"../constraint/MouseConstraint":13,"../core/Common":14,"../core/Engine":15,"../core/Events":16,"../core/Matter":17,"../core/Metrics":18,"../core/Mouse":19,"../core/Plugin":20,"../core/Runner":21,"../core/Sleeping":22,"../factory/Bodies":23,"../factory/Composites":24,"../geometry/Axes":25,"../geometry/Bounds":26,"../geometry/Svg":27,"../geometry/Vector":28,"../geometry/Vertices":29,"../render/Render":31,"../render/RenderPixi":32}],31:[function(_dereq_,module,exports){
   -1  8359 /**
   -1  8360 * The `Matter.Render` module is a simple HTML5 canvas based renderer for visualising instances of `Matter.Engine`.
   -1  8361 * It is intended for development and debugging purposes, but may also be suitable for simple games.
   -1  8362 * It includes a number of drawing options including wireframe, vector with support for sprites and viewports.
   -1  8363 *
   -1  8364 * @class Render
   -1  8365 */
   -1  8366 
   -1  8367 var Render = {};
   -1  8368 
   -1  8369 module.exports = Render;
   -1  8370 
   -1  8371 var Common = _dereq_('../core/Common');
   -1  8372 var Composite = _dereq_('../body/Composite');
   -1  8373 var Bounds = _dereq_('../geometry/Bounds');
   -1  8374 var Events = _dereq_('../core/Events');
   -1  8375 var Grid = _dereq_('../collision/Grid');
   -1  8376 var Vector = _dereq_('../geometry/Vector');
   -1  8377 var Mouse = _dereq_('../core/Mouse');
   -1  8378 
   -1  8379 (function() {
   -1  8380 
   -1  8381     var _requestAnimationFrame,
   -1  8382         _cancelAnimationFrame;
   -1  8383 
   -1  8384     if (typeof window !== 'undefined') {
   -1  8385         _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
   -1  8386                                       || window.mozRequestAnimationFrame || window.msRequestAnimationFrame
   -1  8387                                       || function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
   -1  8388 
   -1  8389         _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
   -1  8390                                       || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
   -1  8391     }
   -1  8392 
   -1  8393     /**
   -1  8394      * Creates a new renderer. The options parameter is an object that specifies any properties you wish to override the defaults.
   -1  8395      * All properties have default values, and many are pre-calculated automatically based on other properties.
   -1  8396      * See the properties section below for detailed information on what you can pass via the `options` object.
   -1  8397      * @method create
   -1  8398      * @param {object} [options]
   -1  8399      * @return {render} A new renderer
   -1  8400      */
   -1  8401     Render.create = function(options) {
   -1  8402         var defaults = {
   -1  8403             controller: Render,
   -1  8404             engine: null,
   -1  8405             element: null,
   -1  8406             canvas: null,
   -1  8407             mouse: null,
   -1  8408             frameRequestId: null,
   -1  8409             options: {
   -1  8410                 width: 800,
   -1  8411                 height: 600,
   -1  8412                 pixelRatio: 1,
   -1  8413                 background: '#18181d',
   -1  8414                 wireframeBackground: '#0f0f13',
   -1  8415                 hasBounds: !!options.bounds,
   -1  8416                 enabled: true,
   -1  8417                 wireframes: true,
   -1  8418                 showSleeping: true,
   -1  8419                 showDebug: false,
   -1  8420                 showBroadphase: false,
   -1  8421                 showBounds: false,
   -1  8422                 showVelocity: false,
   -1  8423                 showCollisions: false,
   -1  8424                 showSeparations: false,
   -1  8425                 showAxes: false,
   -1  8426                 showPositions: false,
   -1  8427                 showAngleIndicator: false,
   -1  8428                 showIds: false,
   -1  8429                 showShadows: false,
   -1  8430                 showVertexNumbers: false,
   -1  8431                 showConvexHulls: false,
   -1  8432                 showInternalEdges: false,
   -1  8433                 showMousePosition: false
   -1  8434             }
   -1  8435         };
   -1  8436 
   -1  8437         var render = Common.extend(defaults, options);
   -1  8438 
   -1  8439         if (render.canvas) {
   -1  8440             render.canvas.width = render.options.width || render.canvas.width;
   -1  8441             render.canvas.height = render.options.height || render.canvas.height;
   -1  8442         }
   -1  8443 
   -1  8444         render.mouse = options.mouse;
   -1  8445         render.engine = options.engine;
   -1  8446         render.canvas = render.canvas || _createCanvas(render.options.width, render.options.height);
   -1  8447         render.context = render.canvas.getContext('2d');
   -1  8448         render.textures = {};
   -1  8449 
   -1  8450         render.bounds = render.bounds || {
   -1  8451             min: {
   -1  8452                 x: 0,
   -1  8453                 y: 0
   -1  8454             },
   -1  8455             max: {
   -1  8456                 x: render.canvas.width,
   -1  8457                 y: render.canvas.height
   -1  8458             }
   -1  8459         };
   -1  8460 
   -1  8461         if (render.options.pixelRatio !== 1) {
   -1  8462             Render.setPixelRatio(render, render.options.pixelRatio);
   -1  8463         }
   -1  8464 
   -1  8465         if (Common.isElement(render.element)) {
   -1  8466             render.element.appendChild(render.canvas);
   -1  8467         } else if (!render.canvas.parentNode) {
   -1  8468             Common.log('Render.create: options.element was undefined, render.canvas was created but not appended', 'warn');
   -1  8469         }
   -1  8470 
   -1  8471         return render;
   -1  8472     };
   -1  8473 
   -1  8474     /**
   -1  8475      * Continuously updates the render canvas on the `requestAnimationFrame` event.
   -1  8476      * @method run
   -1  8477      * @param {render} render
   -1  8478      */
   -1  8479     Render.run = function(render) {
   -1  8480         (function loop(time){
   -1  8481             render.frameRequestId = _requestAnimationFrame(loop);
   -1  8482             Render.world(render);
   -1  8483         })();
   -1  8484     };
   -1  8485 
   -1  8486     /**
   -1  8487      * Ends execution of `Render.run` on the given `render`, by canceling the animation frame request event loop.
   -1  8488      * @method stop
   -1  8489      * @param {render} render
   -1  8490      */
   -1  8491     Render.stop = function(render) {
   -1  8492         _cancelAnimationFrame(render.frameRequestId);
   -1  8493     };
   -1  8494 
   -1  8495     /**
   -1  8496      * Sets the pixel ratio of the renderer and updates the canvas.
   -1  8497      * To automatically detect the correct ratio, pass the string `'auto'` for `pixelRatio`.
   -1  8498      * @method setPixelRatio
   -1  8499      * @param {render} render
   -1  8500      * @param {number} pixelRatio
   -1  8501      */
   -1  8502     Render.setPixelRatio = function(render, pixelRatio) {
   -1  8503         var options = render.options,
   -1  8504             canvas = render.canvas;
   -1  8505 
   -1  8506         if (pixelRatio === 'auto') {
   -1  8507             pixelRatio = _getPixelRatio(canvas);
   -1  8508         }
   -1  8509 
   -1  8510         options.pixelRatio = pixelRatio;
   -1  8511         canvas.setAttribute('data-pixel-ratio', pixelRatio);
   -1  8512         canvas.width = options.width * pixelRatio;
   -1  8513         canvas.height = options.height * pixelRatio;
   -1  8514         canvas.style.width = options.width + 'px';
   -1  8515         canvas.style.height = options.height + 'px';
   -1  8516         render.context.scale(pixelRatio, pixelRatio);
   -1  8517     };
   -1  8518 
   -1  8519     /**
   -1  8520      * Positions and sizes the viewport around the given object bounds.
   -1  8521      * Objects must have at least one of the following properties:
   -1  8522      * - `object.bounds`
   -1  8523      * - `object.position`
   -1  8524      * - `object.min` and `object.max`
   -1  8525      * - `object.x` and `object.y`
   -1  8526      * @method lookAt
   -1  8527      * @param {render} render
   -1  8528      * @param {object[]} objects
   -1  8529      * @param {vector} [padding]
   -1  8530      * @param {bool} [center=true]
   -1  8531      */
   -1  8532     Render.lookAt = function(render, objects, padding, center) {
   -1  8533         center = typeof center !== 'undefined' ? center : true;
   -1  8534         objects = Common.isArray(objects) ? objects : [objects];
   -1  8535         padding = padding || {
   -1  8536             x: 0,
   -1  8537             y: 0
   -1  8538         };
   -1  8539 
   -1  8540         // find bounds of all objects
   -1  8541         var bounds = {
   -1  8542             min: { x: Infinity, y: Infinity },
   -1  8543             max: { x: -Infinity, y: -Infinity }
   -1  8544         };
   -1  8545 
   -1  8546         for (var i = 0; i < objects.length; i += 1) {
   -1  8547             var object = objects[i],
   -1  8548                 min = object.bounds ? object.bounds.min : (object.min || object.position || object),
   -1  8549                 max = object.bounds ? object.bounds.max : (object.max || object.position || object);
   -1  8550 
   -1  8551             if (min && max) {
   -1  8552                 if (min.x < bounds.min.x)
   -1  8553                     bounds.min.x = min.x;
   -1  8554 
   -1  8555                 if (max.x > bounds.max.x)
   -1  8556                     bounds.max.x = max.x;
   -1  8557 
   -1  8558                 if (min.y < bounds.min.y)
   -1  8559                     bounds.min.y = min.y;
   -1  8560 
   -1  8561                 if (max.y > bounds.max.y)
   -1  8562                     bounds.max.y = max.y;
   -1  8563             }
   -1  8564         }
   -1  8565 
   -1  8566         // find ratios
   -1  8567         var width = (bounds.max.x - bounds.min.x) + 2 * padding.x,
   -1  8568             height = (bounds.max.y - bounds.min.y) + 2 * padding.y,
   -1  8569             viewHeight = render.canvas.height,
   -1  8570             viewWidth = render.canvas.width,
   -1  8571             outerRatio = viewWidth / viewHeight,
   -1  8572             innerRatio = width / height,
   -1  8573             scaleX = 1,
   -1  8574             scaleY = 1;
   -1  8575 
   -1  8576         // find scale factor
   -1  8577         if (innerRatio > outerRatio) {
   -1  8578             scaleY = innerRatio / outerRatio;
   -1  8579         } else {
   -1  8580             scaleX = outerRatio / innerRatio;
   -1  8581         }
   -1  8582 
   -1  8583         // enable bounds
   -1  8584         render.options.hasBounds = true;
   -1  8585 
   -1  8586         // position and size
   -1  8587         render.bounds.min.x = bounds.min.x;
   -1  8588         render.bounds.max.x = bounds.min.x + width * scaleX;
   -1  8589         render.bounds.min.y = bounds.min.y;
   -1  8590         render.bounds.max.y = bounds.min.y + height * scaleY;
   -1  8591 
   -1  8592         // center
   -1  8593         if (center) {
   -1  8594             render.bounds.min.x += width * 0.5 - (width * scaleX) * 0.5;
   -1  8595             render.bounds.max.x += width * 0.5 - (width * scaleX) * 0.5;
   -1  8596             render.bounds.min.y += height * 0.5 - (height * scaleY) * 0.5;
   -1  8597             render.bounds.max.y += height * 0.5 - (height * scaleY) * 0.5;
   -1  8598         }
   -1  8599 
   -1  8600         // padding
   -1  8601         render.bounds.min.x -= padding.x;
   -1  8602         render.bounds.max.x -= padding.x;
   -1  8603         render.bounds.min.y -= padding.y;
   -1  8604         render.bounds.max.y -= padding.y;
   -1  8605 
   -1  8606         // update mouse
   -1  8607         if (render.mouse) {
   -1  8608             Mouse.setScale(render.mouse, {
   -1  8609                 x: (render.bounds.max.x - render.bounds.min.x) / render.canvas.width,
   -1  8610                 y: (render.bounds.max.y - render.bounds.min.y) / render.canvas.height
   -1  8611             });
   -1  8612 
   -1  8613             Mouse.setOffset(render.mouse, render.bounds.min);
   -1  8614         }
   -1  8615     };
   -1  8616 
   -1  8617     /**
   -1  8618      * Applies viewport transforms based on `render.bounds` to a render context.
   -1  8619      * @method startViewTransform
   -1  8620      * @param {render} render
   -1  8621      */
   -1  8622     Render.startViewTransform = function(render) {
   -1  8623         var boundsWidth = render.bounds.max.x - render.bounds.min.x,
   -1  8624             boundsHeight = render.bounds.max.y - render.bounds.min.y,
   -1  8625             boundsScaleX = boundsWidth / render.options.width,
   -1  8626             boundsScaleY = boundsHeight / render.options.height;
   -1  8627 
   -1  8628         render.context.scale(1 / boundsScaleX, 1 / boundsScaleY);
   -1  8629         render.context.translate(-render.bounds.min.x, -render.bounds.min.y);
   -1  8630     };
   -1  8631 
   -1  8632     /**
   -1  8633      * Resets all transforms on the render context.
   -1  8634      * @method endViewTransform
   -1  8635      * @param {render} render
   -1  8636      */
   -1  8637     Render.endViewTransform = function(render) {
   -1  8638         render.context.setTransform(render.options.pixelRatio, 0, 0, render.options.pixelRatio, 0, 0);
   -1  8639     };
   -1  8640 
   -1  8641     /**
   -1  8642      * Renders the given `engine`'s `Matter.World` object.
   -1  8643      * This is the entry point for all rendering and should be called every time the scene changes.
   -1  8644      * @method world
   -1  8645      * @param {render} render
   -1  8646      */
   -1  8647     Render.world = function(render) {
   -1  8648         var engine = render.engine,
   -1  8649             world = engine.world,
   -1  8650             canvas = render.canvas,
   -1  8651             context = render.context,
   -1  8652             options = render.options,
   -1  8653             allBodies = Composite.allBodies(world),
   -1  8654             allConstraints = Composite.allConstraints(world),
   -1  8655             background = options.wireframes ? options.wireframeBackground : options.background,
   -1  8656             bodies = [],
   -1  8657             constraints = [],
   -1  8658             i;
   -1  8659 
   -1  8660         var event = {
   -1  8661             timestamp: engine.timing.timestamp
   -1  8662         };
   -1  8663 
   -1  8664         Events.trigger(render, 'beforeRender', event);
   -1  8665 
   -1  8666         // apply background if it has changed
   -1  8667         if (render.currentBackground !== background)
   -1  8668             _applyBackground(render, background);
   -1  8669 
   -1  8670         // clear the canvas with a transparent fill, to allow the canvas background to show
   -1  8671         context.globalCompositeOperation = 'source-in';
   -1  8672         context.fillStyle = "transparent";
   -1  8673         context.fillRect(0, 0, canvas.width, canvas.height);
   -1  8674         context.globalCompositeOperation = 'source-over';
   -1  8675 
   -1  8676         // handle bounds
   -1  8677         if (options.hasBounds) {
   -1  8678             // filter out bodies that are not in view
   -1  8679             for (i = 0; i < allBodies.length; i++) {
   -1  8680                 var body = allBodies[i];
   -1  8681                 if (Bounds.overlaps(body.bounds, render.bounds))
   -1  8682                     bodies.push(body);
   -1  8683             }
   -1  8684 
   -1  8685             // filter out constraints that are not in view
   -1  8686             for (i = 0; i < allConstraints.length; i++) {
   -1  8687                 var constraint = allConstraints[i],
   -1  8688                     bodyA = constraint.bodyA,
   -1  8689                     bodyB = constraint.bodyB,
   -1  8690                     pointAWorld = constraint.pointA,
   -1  8691                     pointBWorld = constraint.pointB;
   -1  8692 
   -1  8693                 if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA);
   -1  8694                 if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB);
   -1  8695 
   -1  8696                 if (!pointAWorld || !pointBWorld)
   -1  8697                     continue;
   -1  8698 
   -1  8699                 if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld))
   -1  8700                     constraints.push(constraint);
   -1  8701             }
   -1  8702 
   -1  8703             // transform the view
   -1  8704             Render.startViewTransform(render);
   -1  8705 
   -1  8706             // update mouse
   -1  8707             if (render.mouse) {
   -1  8708                 Mouse.setScale(render.mouse, {
   -1  8709                     x: (render.bounds.max.x - render.bounds.min.x) / render.canvas.width,
   -1  8710                     y: (render.bounds.max.y - render.bounds.min.y) / render.canvas.height
   -1  8711                 });
   -1  8712 
   -1  8713                 Mouse.setOffset(render.mouse, render.bounds.min);
   -1  8714             }
   -1  8715         } else {
   -1  8716             constraints = allConstraints;
   -1  8717             bodies = allBodies;
   -1  8718         }
   -1  8719 
   -1  8720         if (!options.wireframes || (engine.enableSleeping && options.showSleeping)) {
   -1  8721             // fully featured rendering of bodies
   -1  8722             Render.bodies(render, bodies, context);
   -1  8723         } else {
   -1  8724             if (options.showConvexHulls)
   -1  8725                 Render.bodyConvexHulls(render, bodies, context);
   -1  8726 
   -1  8727             // optimised method for wireframes only
   -1  8728             Render.bodyWireframes(render, bodies, context);
   -1  8729         }
   -1  8730 
   -1  8731         if (options.showBounds)
   -1  8732             Render.bodyBounds(render, bodies, context);
   -1  8733 
   -1  8734         if (options.showAxes || options.showAngleIndicator)
   -1  8735             Render.bodyAxes(render, bodies, context);
   -1  8736 
   -1  8737         if (options.showPositions)
   -1  8738             Render.bodyPositions(render, bodies, context);
   -1  8739 
   -1  8740         if (options.showVelocity)
   -1  8741             Render.bodyVelocity(render, bodies, context);
   -1  8742 
   -1  8743         if (options.showIds)
   -1  8744             Render.bodyIds(render, bodies, context);
   -1  8745 
   -1  8746         if (options.showSeparations)
   -1  8747             Render.separations(render, engine.pairs.list, context);
   -1  8748 
   -1  8749         if (options.showCollisions)
   -1  8750             Render.collisions(render, engine.pairs.list, context);
   -1  8751 
   -1  8752         if (options.showVertexNumbers)
   -1  8753             Render.vertexNumbers(render, bodies, context);
   -1  8754 
   -1  8755         if (options.showMousePosition)
   -1  8756             Render.mousePosition(render, render.mouse, context);
   -1  8757 
   -1  8758         Render.constraints(constraints, context);
   -1  8759 
   -1  8760         if (options.showBroadphase && engine.broadphase.controller === Grid)
   -1  8761             Render.grid(render, engine.broadphase, context);
   -1  8762 
   -1  8763         if (options.showDebug)
   -1  8764             Render.debug(render, context);
   -1  8765 
   -1  8766         if (options.hasBounds) {
   -1  8767             // revert view transforms
   -1  8768             Render.endViewTransform(render);
   -1  8769         }
   -1  8770 
   -1  8771         Events.trigger(render, 'afterRender', event);
   -1  8772     };
   -1  8773 
   -1  8774     /**
   -1  8775      * Description
   -1  8776      * @private
   -1  8777      * @method debug
   -1  8778      * @param {render} render
   -1  8779      * @param {RenderingContext} context
   -1  8780      */
   -1  8781     Render.debug = function(render, context) {
   -1  8782         var c = context,
   -1  8783             engine = render.engine,
   -1  8784             world = engine.world,
   -1  8785             metrics = engine.metrics,
   -1  8786             options = render.options,
   -1  8787             bodies = Composite.allBodies(world),
   -1  8788             space = "    ";
   -1  8789 
   -1  8790         if (engine.timing.timestamp - (render.debugTimestamp || 0) >= 500) {
   -1  8791             var text = "";
   -1  8792 
   -1  8793             if (metrics.timing) {
   -1  8794                 text += "fps: " + Math.round(metrics.timing.fps) + space;
   -1  8795             }
   -1  8796 
   -1  8797 
   -1  8798             render.debugString = text;
   -1  8799             render.debugTimestamp = engine.timing.timestamp;
   -1  8800         }
   -1  8801 
   -1  8802         if (render.debugString) {
   -1  8803             c.font = "12px Arial";
   -1  8804 
   -1  8805             if (options.wireframes) {
   -1  8806                 c.fillStyle = 'rgba(255,255,255,0.5)';
   -1  8807             } else {
   -1  8808                 c.fillStyle = 'rgba(0,0,0,0.5)';
   -1  8809             }
   -1  8810 
   -1  8811             var split = render.debugString.split('\n');
   -1  8812 
   -1  8813             for (var i = 0; i < split.length; i++) {
   -1  8814                 c.fillText(split[i], 50, 50 + i * 18);
   -1  8815             }
   -1  8816         }
   -1  8817     };
   -1  8818 
   -1  8819     /**
   -1  8820      * Description
   -1  8821      * @private
   -1  8822      * @method constraints
   -1  8823      * @param {constraint[]} constraints
   -1  8824      * @param {RenderingContext} context
   -1  8825      */
   -1  8826     Render.constraints = function(constraints, context) {
   -1  8827         var c = context;
   -1  8828 
   -1  8829         for (var i = 0; i < constraints.length; i++) {
   -1  8830             var constraint = constraints[i];
   -1  8831 
   -1  8832             if (!constraint.render.visible || !constraint.pointA || !constraint.pointB)
   -1  8833                 continue;
   -1  8834 
   -1  8835             var bodyA = constraint.bodyA,
   -1  8836                 bodyB = constraint.bodyB,
   -1  8837                 start,
   -1  8838                 end;
   -1  8839 
   -1  8840             if (bodyA) {
   -1  8841                 start = Vector.add(bodyA.position, constraint.pointA);
   -1  8842             } else {
   -1  8843                 start = constraint.pointA;
   -1  8844             }
   -1  8845 
   -1  8846             if (constraint.render.type === 'pin') {
   -1  8847                 c.beginPath();
   -1  8848                 c.arc(start.x, start.y, 3, 0, 2 * Math.PI);
   -1  8849                 c.closePath();
   -1  8850             } else {
   -1  8851                 if (bodyB) {
   -1  8852                     end = Vector.add(bodyB.position, constraint.pointB);
   -1  8853                 } else {
   -1  8854                     end = constraint.pointB;
   -1  8855                 }
   -1  8856 
   -1  8857                 c.beginPath();
   -1  8858                 c.moveTo(start.x, start.y);
   -1  8859 
   -1  8860                 if (constraint.render.type === 'spring') {
   -1  8861                     var delta = Vector.sub(end, start),
   -1  8862                         normal = Vector.perp(Vector.normalise(delta)),
   -1  8863                         coils = Math.ceil(Common.clamp(constraint.length / 5, 12, 20)),
   -1  8864                         offset;
   -1  8865 
   -1  8866                     for (var j = 1; j < coils; j += 1) {
   -1  8867                         offset = j % 2 === 0 ? 1 : -1;
   -1  8868 
   -1  8869                         c.lineTo(
   -1  8870                             start.x + delta.x * (j / coils) + normal.x * offset * 4,
   -1  8871                             start.y + delta.y * (j / coils) + normal.y * offset * 4
   -1  8872                         );
   -1  8873                     }
   -1  8874                 }
   -1  8875 
   -1  8876                 c.lineTo(end.x, end.y);
   -1  8877             }
   -1  8878 
   -1  8879             if (constraint.render.lineWidth) {
   -1  8880                 c.lineWidth = constraint.render.lineWidth;
   -1  8881                 c.strokeStyle = constraint.render.strokeStyle;
   -1  8882                 c.stroke();
   -1  8883             }
   -1  8884 
   -1  8885             if (constraint.render.anchors) {
   -1  8886                 c.fillStyle = constraint.render.strokeStyle;
   -1  8887                 c.beginPath();
   -1  8888                 c.arc(start.x, start.y, 3, 0, 2 * Math.PI);
   -1  8889                 c.arc(end.x, end.y, 3, 0, 2 * Math.PI);
   -1  8890                 c.closePath();
   -1  8891                 c.fill();
   -1  8892             }
   -1  8893         }
   -1  8894     };
   -1  8895 
   -1  8896     /**
   -1  8897      * Description
   -1  8898      * @private
   -1  8899      * @method bodyShadows
   -1  8900      * @param {render} render
   -1  8901      * @param {body[]} bodies
   -1  8902      * @param {RenderingContext} context
   -1  8903      */
   -1  8904     Render.bodyShadows = function(render, bodies, context) {
   -1  8905         var c = context,
   -1  8906             engine = render.engine;
   -1  8907 
   -1  8908         for (var i = 0; i < bodies.length; i++) {
   -1  8909             var body = bodies[i];
   -1  8910 
   -1  8911             if (!body.render.visible)
   -1  8912                 continue;
   -1  8913 
   -1  8914             if (body.circleRadius) {
   -1  8915                 c.beginPath();
   -1  8916                 c.arc(body.position.x, body.position.y, body.circleRadius, 0, 2 * Math.PI);
   -1  8917                 c.closePath();
   -1  8918             } else {
   -1  8919                 c.beginPath();
   -1  8920                 c.moveTo(body.vertices[0].x, body.vertices[0].y);
   -1  8921                 for (var j = 1; j < body.vertices.length; j++) {
   -1  8922                     c.lineTo(body.vertices[j].x, body.vertices[j].y);
   -1  8923                 }
   -1  8924                 c.closePath();
   -1  8925             }
   -1  8926 
   -1  8927             var distanceX = body.position.x - render.options.width * 0.5,
   -1  8928                 distanceY = body.position.y - render.options.height * 0.2,
   -1  8929                 distance = Math.abs(distanceX) + Math.abs(distanceY);
   -1  8930 
   -1  8931             c.shadowColor = 'rgba(0,0,0,0.15)';
   -1  8932             c.shadowOffsetX = 0.05 * distanceX;
   -1  8933             c.shadowOffsetY = 0.05 * distanceY;
   -1  8934             c.shadowBlur = 1 + 12 * Math.min(1, distance / 1000);
   -1  8935 
   -1  8936             c.fill();
   -1  8937 
   -1  8938             c.shadowColor = null;
   -1  8939             c.shadowOffsetX = null;
   -1  8940             c.shadowOffsetY = null;
   -1  8941             c.shadowBlur = null;
   -1  8942         }
   -1  8943     };
   -1  8944 
   -1  8945     /**
   -1  8946      * Description
   -1  8947      * @private
   -1  8948      * @method bodies
   -1  8949      * @param {render} render
   -1  8950      * @param {body[]} bodies
   -1  8951      * @param {RenderingContext} context
   -1  8952      */
   -1  8953     Render.bodies = function(render, bodies, context) {
   -1  8954         var c = context,
   -1  8955             engine = render.engine,
   -1  8956             options = render.options,
   -1  8957             showInternalEdges = options.showInternalEdges || !options.wireframes,
   -1  8958             body,
   -1  8959             part,
   -1  8960             i,
   -1  8961             k;
   -1  8962 
   -1  8963         for (i = 0; i < bodies.length; i++) {
   -1  8964             body = bodies[i];
   -1  8965 
   -1  8966             if (!body.render.visible)
   -1  8967                 continue;
   -1  8968 
   -1  8969             // handle compound parts
   -1  8970             for (k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
   -1  8971                 part = body.parts[k];
   -1  8972 
   -1  8973                 if (!part.render.visible)
   -1  8974                     continue;
   -1  8975 
   -1  8976                 if (options.showSleeping && body.isSleeping) {
   -1  8977                     c.globalAlpha = 0.5 * part.render.opacity;
   -1  8978                 } else if (part.render.opacity !== 1) {
   -1  8979                     c.globalAlpha = part.render.opacity;
   -1  8980                 }
   -1  8981 
   -1  8982                 if (part.render.sprite && part.render.sprite.texture && !options.wireframes) {
   -1  8983                     // part sprite
   -1  8984                     var sprite = part.render.sprite,
   -1  8985                         texture = _getTexture(render, sprite.texture);
   -1  8986 
   -1  8987                     c.translate(part.position.x, part.position.y);
   -1  8988                     c.rotate(part.angle);
   -1  8989 
   -1  8990                     c.drawImage(
   -1  8991                         texture,
   -1  8992                         texture.width * -sprite.xOffset * sprite.xScale,
   -1  8993                         texture.height * -sprite.yOffset * sprite.yScale,
   -1  8994                         texture.width * sprite.xScale,
   -1  8995                         texture.height * sprite.yScale
   -1  8996                     );
   -1  8997 
   -1  8998                     // revert translation, hopefully faster than save / restore
   -1  8999                     c.rotate(-part.angle);
   -1  9000                     c.translate(-part.position.x, -part.position.y);
   -1  9001                 } else {
   -1  9002                     // part polygon
   -1  9003                     if (part.circleRadius) {
   -1  9004                         c.beginPath();
   -1  9005                         c.arc(part.position.x, part.position.y, part.circleRadius, 0, 2 * Math.PI);
   -1  9006                     } else {
   -1  9007                         c.beginPath();
   -1  9008                         c.moveTo(part.vertices[0].x, part.vertices[0].y);
   -1  9009 
   -1  9010                         for (var j = 1; j < part.vertices.length; j++) {
   -1  9011                             if (!part.vertices[j - 1].isInternal || showInternalEdges) {
   -1  9012                                 c.lineTo(part.vertices[j].x, part.vertices[j].y);
   -1  9013                             } else {
   -1  9014                                 c.moveTo(part.vertices[j].x, part.vertices[j].y);
   -1  9015                             }
   -1  9016 
   -1  9017                             if (part.vertices[j].isInternal && !showInternalEdges) {
   -1  9018                                 c.moveTo(part.vertices[(j + 1) % part.vertices.length].x, part.vertices[(j + 1) % part.vertices.length].y);
   -1  9019                             }
   -1  9020                         }
   -1  9021 
   -1  9022                         c.lineTo(part.vertices[0].x, part.vertices[0].y);
   -1  9023                         c.closePath();
   -1  9024                     }
   -1  9025 
   -1  9026                     if (!options.wireframes) {
   -1  9027                         c.fillStyle = part.render.fillStyle;
   -1  9028 
   -1  9029                         if (part.render.lineWidth) {
   -1  9030                             c.lineWidth = part.render.lineWidth;
   -1  9031                             c.strokeStyle = part.render.strokeStyle;
   -1  9032                             c.stroke();
   -1  9033                         }
   -1  9034 
   -1  9035                         c.fill();
   -1  9036                     } else {
   -1  9037                         c.lineWidth = 1;
   -1  9038                         c.strokeStyle = '#bbb';
   -1  9039                         c.stroke();
   -1  9040                     }
   -1  9041                 }
   -1  9042 
   -1  9043                 c.globalAlpha = 1;
   -1  9044             }
   -1  9045         }
   -1  9046     };
   -1  9047 
   -1  9048     /**
   -1  9049      * Optimised method for drawing body wireframes in one pass
   -1  9050      * @private
   -1  9051      * @method bodyWireframes
   -1  9052      * @param {render} render
   -1  9053      * @param {body[]} bodies
   -1  9054      * @param {RenderingContext} context
   -1  9055      */
   -1  9056     Render.bodyWireframes = function(render, bodies, context) {
   -1  9057         var c = context,
   -1  9058             showInternalEdges = render.options.showInternalEdges,
   -1  9059             body,
   -1  9060             part,
   -1  9061             i,
   -1  9062             j,
   -1  9063             k;
   -1  9064 
   -1  9065         c.beginPath();
   -1  9066 
   -1  9067         // render all bodies
   -1  9068         for (i = 0; i < bodies.length; i++) {
   -1  9069             body = bodies[i];
   -1  9070 
   -1  9071             if (!body.render.visible)
   -1  9072                 continue;
   -1  9073 
   -1  9074             // handle compound parts
   -1  9075             for (k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
   -1  9076                 part = body.parts[k];
   -1  9077 
   -1  9078                 c.moveTo(part.vertices[0].x, part.vertices[0].y);
   -1  9079 
   -1  9080                 for (j = 1; j < part.vertices.length; j++) {
   -1  9081                     if (!part.vertices[j - 1].isInternal || showInternalEdges) {
   -1  9082                         c.lineTo(part.vertices[j].x, part.vertices[j].y);
   -1  9083                     } else {
   -1  9084                         c.moveTo(part.vertices[j].x, part.vertices[j].y);
   -1  9085                     }
   -1  9086 
   -1  9087                     if (part.vertices[j].isInternal && !showInternalEdges) {
   -1  9088                         c.moveTo(part.vertices[(j + 1) % part.vertices.length].x, part.vertices[(j + 1) % part.vertices.length].y);
   -1  9089                     }
   -1  9090                 }
   -1  9091 
   -1  9092                 c.lineTo(part.vertices[0].x, part.vertices[0].y);
   -1  9093             }
   -1  9094         }
   -1  9095 
   -1  9096         c.lineWidth = 1;
   -1  9097         c.strokeStyle = '#bbb';
   -1  9098         c.stroke();
   -1  9099     };
   -1  9100 
   -1  9101     /**
   -1  9102      * Optimised method for drawing body convex hull wireframes in one pass
   -1  9103      * @private
   -1  9104      * @method bodyConvexHulls
   -1  9105      * @param {render} render
   -1  9106      * @param {body[]} bodies
   -1  9107      * @param {RenderingContext} context
   -1  9108      */
   -1  9109     Render.bodyConvexHulls = function(render, bodies, context) {
   -1  9110         var c = context,
   -1  9111             body,
   -1  9112             part,
   -1  9113             i,
   -1  9114             j,
   -1  9115             k;
   -1  9116 
   -1  9117         c.beginPath();
   -1  9118 
   -1  9119         // render convex hulls
   -1  9120         for (i = 0; i < bodies.length; i++) {
   -1  9121             body = bodies[i];
   -1  9122 
   -1  9123             if (!body.render.visible || body.parts.length === 1)
   -1  9124                 continue;
   -1  9125 
   -1  9126             c.moveTo(body.vertices[0].x, body.vertices[0].y);
   -1  9127 
   -1  9128             for (j = 1; j < body.vertices.length; j++) {
   -1  9129                 c.lineTo(body.vertices[j].x, body.vertices[j].y);
   -1  9130             }
   -1  9131 
   -1  9132             c.lineTo(body.vertices[0].x, body.vertices[0].y);
   -1  9133         }
   -1  9134 
   -1  9135         c.lineWidth = 1;
   -1  9136         c.strokeStyle = 'rgba(255,255,255,0.2)';
   -1  9137         c.stroke();
   -1  9138     };
   -1  9139 
   -1  9140     /**
   -1  9141      * Renders body vertex numbers.
   -1  9142      * @private
   -1  9143      * @method vertexNumbers
   -1  9144      * @param {render} render
   -1  9145      * @param {body[]} bodies
   -1  9146      * @param {RenderingContext} context
   -1  9147      */
   -1  9148     Render.vertexNumbers = function(render, bodies, context) {
   -1  9149         var c = context,
   -1  9150             i,
   -1  9151             j,
   -1  9152             k;
   -1  9153 
   -1  9154         for (i = 0; i < bodies.length; i++) {
   -1  9155             var parts = bodies[i].parts;
   -1  9156             for (k = parts.length > 1 ? 1 : 0; k < parts.length; k++) {
   -1  9157                 var part = parts[k];
   -1  9158                 for (j = 0; j < part.vertices.length; j++) {
   -1  9159                     c.fillStyle = 'rgba(255,255,255,0.2)';
   -1  9160                     c.fillText(i + '_' + j, part.position.x + (part.vertices[j].x - part.position.x) * 0.8, part.position.y + (part.vertices[j].y - part.position.y) * 0.8);
   -1  9161                 }
   -1  9162             }
   -1  9163         }
   -1  9164     };
   -1  9165 
   -1  9166     /**
   -1  9167      * Renders mouse position.
   -1  9168      * @private
   -1  9169      * @method mousePosition
   -1  9170      * @param {render} render
   -1  9171      * @param {mouse} mouse
   -1  9172      * @param {RenderingContext} context
   -1  9173      */
   -1  9174     Render.mousePosition = function(render, mouse, context) {
   -1  9175         var c = context;
   -1  9176         c.fillStyle = 'rgba(255,255,255,0.8)';
   -1  9177         c.fillText(mouse.position.x + '  ' + mouse.position.y, mouse.position.x + 5, mouse.position.y - 5);
   -1  9178     };
   -1  9179 
   -1  9180     /**
   -1  9181      * Draws body bounds
   -1  9182      * @private
   -1  9183      * @method bodyBounds
   -1  9184      * @param {render} render
   -1  9185      * @param {body[]} bodies
   -1  9186      * @param {RenderingContext} context
   -1  9187      */
   -1  9188     Render.bodyBounds = function(render, bodies, context) {
   -1  9189         var c = context,
   -1  9190             engine = render.engine,
   -1  9191             options = render.options;
   -1  9192 
   -1  9193         c.beginPath();
   -1  9194 
   -1  9195         for (var i = 0; i < bodies.length; i++) {
   -1  9196             var body = bodies[i];
   -1  9197 
   -1  9198             if (body.render.visible) {
   -1  9199                 var parts = bodies[i].parts;
   -1  9200                 for (var j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
   -1  9201                     var part = parts[j];
   -1  9202                     c.rect(part.bounds.min.x, part.bounds.min.y, part.bounds.max.x - part.bounds.min.x, part.bounds.max.y - part.bounds.min.y);
   -1  9203                 }
   -1  9204             }
   -1  9205         }
   -1  9206 
   -1  9207         if (options.wireframes) {
   -1  9208             c.strokeStyle = 'rgba(255,255,255,0.08)';
   -1  9209         } else {
   -1  9210             c.strokeStyle = 'rgba(0,0,0,0.1)';
   -1  9211         }
   -1  9212 
   -1  9213         c.lineWidth = 1;
   -1  9214         c.stroke();
   -1  9215     };
   -1  9216 
   -1  9217     /**
   -1  9218      * Draws body angle indicators and axes
   -1  9219      * @private
   -1  9220      * @method bodyAxes
   -1  9221      * @param {render} render
   -1  9222      * @param {body[]} bodies
   -1  9223      * @param {RenderingContext} context
   -1  9224      */
   -1  9225     Render.bodyAxes = function(render, bodies, context) {
   -1  9226         var c = context,
   -1  9227             engine = render.engine,
   -1  9228             options = render.options,
   -1  9229             part,
   -1  9230             i,
   -1  9231             j,
   -1  9232             k;
   -1  9233 
   -1  9234         c.beginPath();
   -1  9235 
   -1  9236         for (i = 0; i < bodies.length; i++) {
   -1  9237             var body = bodies[i],
   -1  9238                 parts = body.parts;
   -1  9239 
   -1  9240             if (!body.render.visible)
   -1  9241                 continue;
   -1  9242 
   -1  9243             if (options.showAxes) {
   -1  9244                 // render all axes
   -1  9245                 for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
   -1  9246                     part = parts[j];
   -1  9247                     for (k = 0; k < part.axes.length; k++) {
   -1  9248                         var axis = part.axes[k];
   -1  9249                         c.moveTo(part.position.x, part.position.y);
   -1  9250                         c.lineTo(part.position.x + axis.x * 20, part.position.y + axis.y * 20);
   -1  9251                     }
   -1  9252                 }
   -1  9253             } else {
   -1  9254                 for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
   -1  9255                     part = parts[j];
   -1  9256                     for (k = 0; k < part.axes.length; k++) {
   -1  9257                         // render a single axis indicator
   -1  9258                         c.moveTo(part.position.x, part.position.y);
   -1  9259                         c.lineTo((part.vertices[0].x + part.vertices[part.vertices.length-1].x) / 2,
   -1  9260                                  (part.vertices[0].y + part.vertices[part.vertices.length-1].y) / 2);
   -1  9261                     }
   -1  9262                 }
   -1  9263             }
   -1  9264         }
   -1  9265 
   -1  9266         if (options.wireframes) {
   -1  9267             c.strokeStyle = 'indianred';
   -1  9268             c.lineWidth = 1;
   -1  9269         } else {
   -1  9270             c.strokeStyle = 'rgba(255, 255, 255, 0.4)';
   -1  9271             c.globalCompositeOperation = 'overlay';
   -1  9272             c.lineWidth = 2;
   -1  9273         }
   -1  9274 
   -1  9275         c.stroke();
   -1  9276         c.globalCompositeOperation = 'source-over';
   -1  9277     };
   -1  9278 
   -1  9279     /**
   -1  9280      * Draws body positions
   -1  9281      * @private
   -1  9282      * @method bodyPositions
   -1  9283      * @param {render} render
   -1  9284      * @param {body[]} bodies
   -1  9285      * @param {RenderingContext} context
   -1  9286      */
   -1  9287     Render.bodyPositions = function(render, bodies, context) {
   -1  9288         var c = context,
   -1  9289             engine = render.engine,
   -1  9290             options = render.options,
   -1  9291             body,
   -1  9292             part,
   -1  9293             i,
   -1  9294             k;
   -1  9295 
   -1  9296         c.beginPath();
   -1  9297 
   -1  9298         // render current positions
   -1  9299         for (i = 0; i < bodies.length; i++) {
   -1  9300             body = bodies[i];
   -1  9301 
   -1  9302             if (!body.render.visible)
   -1  9303                 continue;
   -1  9304 
   -1  9305             // handle compound parts
   -1  9306             for (k = 0; k < body.parts.length; k++) {
   -1  9307                 part = body.parts[k];
   -1  9308                 c.arc(part.position.x, part.position.y, 3, 0, 2 * Math.PI, false);
   -1  9309                 c.closePath();
   -1  9310             }
   -1  9311         }
   -1  9312 
   -1  9313         if (options.wireframes) {
   -1  9314             c.fillStyle = 'indianred';
   -1  9315         } else {
   -1  9316             c.fillStyle = 'rgba(0,0,0,0.5)';
   -1  9317         }
   -1  9318         c.fill();
   -1  9319 
   -1  9320         c.beginPath();
   -1  9321 
   -1  9322         // render previous positions
   -1  9323         for (i = 0; i < bodies.length; i++) {
   -1  9324             body = bodies[i];
   -1  9325             if (body.render.visible) {
   -1  9326                 c.arc(body.positionPrev.x, body.positionPrev.y, 2, 0, 2 * Math.PI, false);
   -1  9327                 c.closePath();
   -1  9328             }
   -1  9329         }
   -1  9330 
   -1  9331         c.fillStyle = 'rgba(255,165,0,0.8)';
   -1  9332         c.fill();
   -1  9333     };
   -1  9334 
   -1  9335     /**
   -1  9336      * Draws body velocity
   -1  9337      * @private
   -1  9338      * @method bodyVelocity
   -1  9339      * @param {render} render
   -1  9340      * @param {body[]} bodies
   -1  9341      * @param {RenderingContext} context
   -1  9342      */
   -1  9343     Render.bodyVelocity = function(render, bodies, context) {
   -1  9344         var c = context;
   -1  9345 
   -1  9346         c.beginPath();
   -1  9347 
   -1  9348         for (var i = 0; i < bodies.length; i++) {
   -1  9349             var body = bodies[i];
   -1  9350 
   -1  9351             if (!body.render.visible)
   -1  9352                 continue;
   -1  9353 
   -1  9354             c.moveTo(body.position.x, body.position.y);
   -1  9355             c.lineTo(body.position.x + (body.position.x - body.positionPrev.x) * 2, body.position.y + (body.position.y - body.positionPrev.y) * 2);
   -1  9356         }
   -1  9357 
   -1  9358         c.lineWidth = 3;
   -1  9359         c.strokeStyle = 'cornflowerblue';
   -1  9360         c.stroke();
   -1  9361     };
   -1  9362 
   -1  9363     /**
   -1  9364      * Draws body ids
   -1  9365      * @private
   -1  9366      * @method bodyIds
   -1  9367      * @param {render} render
   -1  9368      * @param {body[]} bodies
   -1  9369      * @param {RenderingContext} context
   -1  9370      */
   -1  9371     Render.bodyIds = function(render, bodies, context) {
   -1  9372         var c = context,
   -1  9373             i,
   -1  9374             j;
   -1  9375 
   -1  9376         for (i = 0; i < bodies.length; i++) {
   -1  9377             if (!bodies[i].render.visible)
   -1  9378                 continue;
   -1  9379 
   -1  9380             var parts = bodies[i].parts;
   -1  9381             for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
   -1  9382                 var part = parts[j];
   -1  9383                 c.font = "12px Arial";
   -1  9384                 c.fillStyle = 'rgba(255,255,255,0.5)';
   -1  9385                 c.fillText(part.id, part.position.x + 10, part.position.y - 10);
   -1  9386             }
   -1  9387         }
   -1  9388     };
   -1  9389 
   -1  9390     /**
   -1  9391      * Description
   -1  9392      * @private
   -1  9393      * @method collisions
   -1  9394      * @param {render} render
   -1  9395      * @param {pair[]} pairs
   -1  9396      * @param {RenderingContext} context
   -1  9397      */
   -1  9398     Render.collisions = function(render, pairs, context) {
   -1  9399         var c = context,
   -1  9400             options = render.options,
   -1  9401             pair,
   -1  9402             collision,
   -1  9403             corrected,
   -1  9404             bodyA,
   -1  9405             bodyB,
   -1  9406             i,
   -1  9407             j;
   -1  9408 
   -1  9409         c.beginPath();
   -1  9410 
   -1  9411         // render collision positions
   -1  9412         for (i = 0; i < pairs.length; i++) {
   -1  9413             pair = pairs[i];
   -1  9414 
   -1  9415             if (!pair.isActive)
   -1  9416                 continue;
   -1  9417 
   -1  9418             collision = pair.collision;
   -1  9419             for (j = 0; j < pair.activeContacts.length; j++) {
   -1  9420                 var contact = pair.activeContacts[j],
   -1  9421                     vertex = contact.vertex;
   -1  9422                 c.rect(vertex.x - 1.5, vertex.y - 1.5, 3.5, 3.5);
   -1  9423             }
   -1  9424         }
   -1  9425 
   -1  9426         if (options.wireframes) {
   -1  9427             c.fillStyle = 'rgba(255,255,255,0.7)';
   -1  9428         } else {
   -1  9429             c.fillStyle = 'orange';
   -1  9430         }
   -1  9431         c.fill();
   -1  9432 
   -1  9433         c.beginPath();
   -1  9434 
   -1  9435         // render collision normals
   -1  9436         for (i = 0; i < pairs.length; i++) {
   -1  9437             pair = pairs[i];
   -1  9438 
   -1  9439             if (!pair.isActive)
   -1  9440                 continue;
   -1  9441 
   -1  9442             collision = pair.collision;
   -1  9443 
   -1  9444             if (pair.activeContacts.length > 0) {
   -1  9445                 var normalPosX = pair.activeContacts[0].vertex.x,
   -1  9446                     normalPosY = pair.activeContacts[0].vertex.y;
   -1  9447 
   -1  9448                 if (pair.activeContacts.length === 2) {
   -1  9449                     normalPosX = (pair.activeContacts[0].vertex.x + pair.activeContacts[1].vertex.x) / 2;
   -1  9450                     normalPosY = (pair.activeContacts[0].vertex.y + pair.activeContacts[1].vertex.y) / 2;
   -1  9451                 }
   -1  9452 
   -1  9453                 if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic === true) {
   -1  9454                     c.moveTo(normalPosX - collision.normal.x * 8, normalPosY - collision.normal.y * 8);
   -1  9455                 } else {
   -1  9456                     c.moveTo(normalPosX + collision.normal.x * 8, normalPosY + collision.normal.y * 8);
   -1  9457                 }
   -1  9458 
   -1  9459                 c.lineTo(normalPosX, normalPosY);
   -1  9460             }
   -1  9461         }
   -1  9462 
   -1  9463         if (options.wireframes) {
   -1  9464             c.strokeStyle = 'rgba(255,165,0,0.7)';
   -1  9465         } else {
   -1  9466             c.strokeStyle = 'orange';
   -1  9467         }
   -1  9468 
   -1  9469         c.lineWidth = 1;
   -1  9470         c.stroke();
   -1  9471     };
   -1  9472 
   -1  9473     /**
   -1  9474      * Description
   -1  9475      * @private
   -1  9476      * @method separations
   -1  9477      * @param {render} render
   -1  9478      * @param {pair[]} pairs
   -1  9479      * @param {RenderingContext} context
   -1  9480      */
   -1  9481     Render.separations = function(render, pairs, context) {
   -1  9482         var c = context,
   -1  9483             options = render.options,
   -1  9484             pair,
   -1  9485             collision,
   -1  9486             corrected,
   -1  9487             bodyA,
   -1  9488             bodyB,
   -1  9489             i,
   -1  9490             j;
   -1  9491 
   -1  9492         c.beginPath();
   -1  9493 
   -1  9494         // render separations
   -1  9495         for (i = 0; i < pairs.length; i++) {
   -1  9496             pair = pairs[i];
   -1  9497 
   -1  9498             if (!pair.isActive)
   -1  9499                 continue;
   -1  9500 
   -1  9501             collision = pair.collision;
   -1  9502             bodyA = collision.bodyA;
   -1  9503             bodyB = collision.bodyB;
   -1  9504 
   -1  9505             var k = 1;
   -1  9506 
   -1  9507             if (!bodyB.isStatic && !bodyA.isStatic) k = 0.5;
   -1  9508             if (bodyB.isStatic) k = 0;
   -1  9509 
   -1  9510             c.moveTo(bodyB.position.x, bodyB.position.y);
   -1  9511             c.lineTo(bodyB.position.x - collision.penetration.x * k, bodyB.position.y - collision.penetration.y * k);
   -1  9512 
   -1  9513             k = 1;
   -1  9514 
   -1  9515             if (!bodyB.isStatic && !bodyA.isStatic) k = 0.5;
   -1  9516             if (bodyA.isStatic) k = 0;
   -1  9517 
   -1  9518             c.moveTo(bodyA.position.x, bodyA.position.y);
   -1  9519             c.lineTo(bodyA.position.x + collision.penetration.x * k, bodyA.position.y + collision.penetration.y * k);
   -1  9520         }
   -1  9521 
   -1  9522         if (options.wireframes) {
   -1  9523             c.strokeStyle = 'rgba(255,165,0,0.5)';
   -1  9524         } else {
   -1  9525             c.strokeStyle = 'orange';
   -1  9526         }
   -1  9527         c.stroke();
   -1  9528     };
   -1  9529 
   -1  9530     /**
   -1  9531      * Description
   -1  9532      * @private
   -1  9533      * @method grid
   -1  9534      * @param {render} render
   -1  9535      * @param {grid} grid
   -1  9536      * @param {RenderingContext} context
   -1  9537      */
   -1  9538     Render.grid = function(render, grid, context) {
   -1  9539         var c = context,
   -1  9540             options = render.options;
   -1  9541 
   -1  9542         if (options.wireframes) {
   -1  9543             c.strokeStyle = 'rgba(255,180,0,0.1)';
   -1  9544         } else {
   -1  9545             c.strokeStyle = 'rgba(255,180,0,0.5)';
   -1  9546         }
   -1  9547 
   -1  9548         c.beginPath();
   -1  9549 
   -1  9550         var bucketKeys = Common.keys(grid.buckets);
   -1  9551 
   -1  9552         for (var i = 0; i < bucketKeys.length; i++) {
   -1  9553             var bucketId = bucketKeys[i];
   -1  9554 
   -1  9555             if (grid.buckets[bucketId].length < 2)
   -1  9556                 continue;
   -1  9557 
   -1  9558             var region = bucketId.split(/C|R/);
   -1  9559             c.rect(0.5 + parseInt(region[1], 10) * grid.bucketWidth,
   -1  9560                     0.5 + parseInt(region[2], 10) * grid.bucketHeight,
   -1  9561                     grid.bucketWidth,
   -1  9562                     grid.bucketHeight);
   -1  9563         }
   -1  9564 
   -1  9565         c.lineWidth = 1;
   -1  9566         c.stroke();
   -1  9567     };
   -1  9568 
   -1  9569     /**
   -1  9570      * Description
   -1  9571      * @private
   -1  9572      * @method inspector
   -1  9573      * @param {inspector} inspector
   -1  9574      * @param {RenderingContext} context
   -1  9575      */
   -1  9576     Render.inspector = function(inspector, context) {
   -1  9577         var engine = inspector.engine,
   -1  9578             selected = inspector.selected,
   -1  9579             render = inspector.render,
   -1  9580             options = render.options,
   -1  9581             bounds;
   -1  9582 
   -1  9583         if (options.hasBounds) {
   -1  9584             var boundsWidth = render.bounds.max.x - render.bounds.min.x,
   -1  9585                 boundsHeight = render.bounds.max.y - render.bounds.min.y,
   -1  9586                 boundsScaleX = boundsWidth / render.options.width,
   -1  9587                 boundsScaleY = boundsHeight / render.options.height;
   -1  9588 
   -1  9589             context.scale(1 / boundsScaleX, 1 / boundsScaleY);
   -1  9590             context.translate(-render.bounds.min.x, -render.bounds.min.y);
   -1  9591         }
   -1  9592 
   -1  9593         for (var i = 0; i < selected.length; i++) {
   -1  9594             var item = selected[i].data;
   -1  9595 
   -1  9596             context.translate(0.5, 0.5);
   -1  9597             context.lineWidth = 1;
   -1  9598             context.strokeStyle = 'rgba(255,165,0,0.9)';
   -1  9599             context.setLineDash([1,2]);
   -1  9600 
   -1  9601             switch (item.type) {
   -1  9602 
   -1  9603             case 'body':
   -1  9604 
   -1  9605                 // render body selections
   -1  9606                 bounds = item.bounds;
   -1  9607                 context.beginPath();
   -1  9608                 context.rect(Math.floor(bounds.min.x - 3), Math.floor(bounds.min.y - 3),
   -1  9609                              Math.floor(bounds.max.x - bounds.min.x + 6), Math.floor(bounds.max.y - bounds.min.y + 6));
   -1  9610                 context.closePath();
   -1  9611                 context.stroke();
   -1  9612 
   -1  9613                 break;
   -1  9614 
   -1  9615             case 'constraint':
   -1  9616 
   -1  9617                 // render constraint selections
   -1  9618                 var point = item.pointA;
   -1  9619                 if (item.bodyA)
   -1  9620                     point = item.pointB;
   -1  9621                 context.beginPath();
   -1  9622                 context.arc(point.x, point.y, 10, 0, 2 * Math.PI);
   -1  9623                 context.closePath();
   -1  9624                 context.stroke();
   -1  9625 
   -1  9626                 break;
   -1  9627 
   -1  9628             }
   -1  9629 
   -1  9630             context.setLineDash([]);
   -1  9631             context.translate(-0.5, -0.5);
   -1  9632         }
   -1  9633 
   -1  9634         // render selection region
   -1  9635         if (inspector.selectStart !== null) {
   -1  9636             context.translate(0.5, 0.5);
   -1  9637             context.lineWidth = 1;
   -1  9638             context.strokeStyle = 'rgba(255,165,0,0.6)';
   -1  9639             context.fillStyle = 'rgba(255,165,0,0.1)';
   -1  9640             bounds = inspector.selectBounds;
   -1  9641             context.beginPath();
   -1  9642             context.rect(Math.floor(bounds.min.x), Math.floor(bounds.min.y),
   -1  9643                          Math.floor(bounds.max.x - bounds.min.x), Math.floor(bounds.max.y - bounds.min.y));
   -1  9644             context.closePath();
   -1  9645             context.stroke();
   -1  9646             context.fill();
   -1  9647             context.translate(-0.5, -0.5);
   -1  9648         }
   -1  9649 
   -1  9650         if (options.hasBounds)
   -1  9651             context.setTransform(1, 0, 0, 1, 0, 0);
   -1  9652     };
   -1  9653 
   -1  9654     /**
   -1  9655      * Description
   -1  9656      * @method _createCanvas
   -1  9657      * @private
   -1  9658      * @param {} width
   -1  9659      * @param {} height
   -1  9660      * @return canvas
   -1  9661      */
   -1  9662     var _createCanvas = function(width, height) {
   -1  9663         var canvas = document.createElement('canvas');
   -1  9664         canvas.width = width;
   -1  9665         canvas.height = height;
   -1  9666         canvas.oncontextmenu = function() { return false; };
   -1  9667         canvas.onselectstart = function() { return false; };
   -1  9668         return canvas;
   -1  9669     };
   -1  9670 
   -1  9671     /**
   -1  9672      * Gets the pixel ratio of the canvas.
   -1  9673      * @method _getPixelRatio
   -1  9674      * @private
   -1  9675      * @param {HTMLElement} canvas
   -1  9676      * @return {Number} pixel ratio
   -1  9677      */
   -1  9678     var _getPixelRatio = function(canvas) {
   -1  9679         var context = canvas.getContext('2d'),
   -1  9680             devicePixelRatio = window.devicePixelRatio || 1,
   -1  9681             backingStorePixelRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio
   -1  9682                                       || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio
   -1  9683                                       || context.backingStorePixelRatio || 1;
   -1  9684 
   -1  9685         return devicePixelRatio / backingStorePixelRatio;
   -1  9686     };
   -1  9687 
   -1  9688     /**
   -1  9689      * Gets the requested texture (an Image) via its path
   -1  9690      * @method _getTexture
   -1  9691      * @private
   -1  9692      * @param {render} render
   -1  9693      * @param {string} imagePath
   -1  9694      * @return {Image} texture
   -1  9695      */
   -1  9696     var _getTexture = function(render, imagePath) {
   -1  9697         var image = render.textures[imagePath];
   -1  9698 
   -1  9699         if (image)
   -1  9700             return image;
   -1  9701 
   -1  9702         image = render.textures[imagePath] = new Image();
   -1  9703         image.src = imagePath;
   -1  9704 
   -1  9705         return image;
   -1  9706     };
   -1  9707 
   -1  9708     /**
   -1  9709      * Applies the background to the canvas using CSS.
   -1  9710      * @method applyBackground
   -1  9711      * @private
   -1  9712      * @param {render} render
   -1  9713      * @param {string} background
   -1  9714      */
   -1  9715     var _applyBackground = function(render, background) {
   -1  9716         var cssBackground = background;
   -1  9717 
   -1  9718         if (/(jpg|gif|png)$/.test(background))
   -1  9719             cssBackground = 'url(' + background + ')';
   -1  9720 
   -1  9721         render.canvas.style.background = cssBackground;
   -1  9722         render.canvas.style.backgroundSize = "contain";
   -1  9723         render.currentBackground = background;
   -1  9724     };
   -1  9725 
   -1  9726     /*
   -1  9727     *
   -1  9728     *  Events Documentation
   -1  9729     *
   -1  9730     */
   -1  9731 
   -1  9732     /**
   -1  9733     * Fired before rendering
   -1  9734     *
   -1  9735     * @event beforeRender
   -1  9736     * @param {} event An event object
   -1  9737     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  9738     * @param {} event.source The source object of the event
   -1  9739     * @param {} event.name The name of the event
   -1  9740     */
   -1  9741 
   -1  9742     /**
   -1  9743     * Fired after rendering
   -1  9744     *
   -1  9745     * @event afterRender
   -1  9746     * @param {} event An event object
   -1  9747     * @param {number} event.timestamp The engine.timing.timestamp of the event
   -1  9748     * @param {} event.source The source object of the event
   -1  9749     * @param {} event.name The name of the event
   -1  9750     */
   -1  9751 
   -1  9752     /*
   -1  9753     *
   -1  9754     *  Properties Documentation
   -1  9755     *
   -1  9756     */
   -1  9757 
   -1  9758     /**
   -1  9759      * A back-reference to the `Matter.Render` module.
   -1  9760      *
   -1  9761      * @property controller
   -1  9762      * @type render
   -1  9763      */
   -1  9764 
   -1  9765     /**
   -1  9766      * A reference to the `Matter.Engine` instance to be used.
   -1  9767      *
   -1  9768      * @property engine
   -1  9769      * @type engine
   -1  9770      */
   -1  9771 
   -1  9772     /**
   -1  9773      * A reference to the element where the canvas is to be inserted (if `render.canvas` has not been specified)
   -1  9774      *
   -1  9775      * @property element
   -1  9776      * @type HTMLElement
   -1  9777      * @default null
   -1  9778      */
   -1  9779 
   -1  9780     /**
   -1  9781      * The canvas element to render to. If not specified, one will be created if `render.element` has been specified.
   -1  9782      *
   -1  9783      * @property canvas
   -1  9784      * @type HTMLCanvasElement
   -1  9785      * @default null
   -1  9786      */
   -1  9787 
   -1  9788     /**
   -1  9789      * The configuration options of the renderer.
   -1  9790      *
   -1  9791      * @property options
   -1  9792      * @type {}
   -1  9793      */
   -1  9794 
   -1  9795     /**
   -1  9796      * The target width in pixels of the `render.canvas` to be created.
   -1  9797      *
   -1  9798      * @property options.width
   -1  9799      * @type number
   -1  9800      * @default 800
   -1  9801      */
   -1  9802 
   -1  9803     /**
   -1  9804      * The target height in pixels of the `render.canvas` to be created.
   -1  9805      *
   -1  9806      * @property options.height
   -1  9807      * @type number
   -1  9808      * @default 600
   -1  9809      */
   -1  9810 
   -1  9811     /**
   -1  9812      * A flag that specifies if `render.bounds` should be used when rendering.
   -1  9813      *
   -1  9814      * @property options.hasBounds
   -1  9815      * @type boolean
   -1  9816      * @default false
   -1  9817      */
   -1  9818 
   -1  9819     /**
   -1  9820      * A `Bounds` object that specifies the drawing view region.
   -1  9821      * Rendering will be automatically transformed and scaled to fit within the canvas size (`render.options.width` and `render.options.height`).
   -1  9822      * This allows for creating views that can pan or zoom around the scene.
   -1  9823      * You must also set `render.options.hasBounds` to `true` to enable bounded rendering.
   -1  9824      *
   -1  9825      * @property bounds
   -1  9826      * @type bounds
   -1  9827      */
   -1  9828 
   -1  9829     /**
   -1  9830      * The 2d rendering context from the `render.canvas` element.
   -1  9831      *
   -1  9832      * @property context
   -1  9833      * @type CanvasRenderingContext2D
   -1  9834      */
   -1  9835 
   -1  9836     /**
   -1  9837      * The sprite texture cache.
   -1  9838      *
   -1  9839      * @property textures
   -1  9840      * @type {}
   -1  9841      */
   -1  9842 
   -1  9843 })();
   -1  9844 
   -1  9845 },{"../body/Composite":2,"../collision/Grid":6,"../core/Common":14,"../core/Events":16,"../core/Mouse":19,"../geometry/Bounds":26,"../geometry/Vector":28}],32:[function(_dereq_,module,exports){
   -1  9846 /**
   -1  9847 * The `Matter.RenderPixi` module is an example renderer using pixi.js.
   -1  9848 * See also `Matter.Render` for a canvas based renderer.
   -1  9849 *
   -1  9850 * @class RenderPixi
   -1  9851 * @deprecated the Matter.RenderPixi module will soon be removed from the Matter.js core.
   -1  9852 * It will likely be moved to its own repository (but maintenance will be limited).
   -1  9853 */
   -1  9854 
   -1  9855 var RenderPixi = {};
   -1  9856 
   -1  9857 module.exports = RenderPixi;
   -1  9858 
   -1  9859 var Bounds = _dereq_('../geometry/Bounds');
   -1  9860 var Composite = _dereq_('../body/Composite');
   -1  9861 var Common = _dereq_('../core/Common');
   -1  9862 var Events = _dereq_('../core/Events');
   -1  9863 var Vector = _dereq_('../geometry/Vector');
   -1  9864 
   -1  9865 (function() {
   -1  9866 
   -1  9867     var _requestAnimationFrame,
   -1  9868         _cancelAnimationFrame;
   -1  9869 
   -1  9870     if (typeof window !== 'undefined') {
   -1  9871         _requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame
   -1  9872                                       || window.mozRequestAnimationFrame || window.msRequestAnimationFrame 
   -1  9873                                       || function(callback){ window.setTimeout(function() { callback(Common.now()); }, 1000 / 60); };
   -1  9874    
   -1  9875         _cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame 
   -1  9876                                       || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame;
   -1  9877     }
   -1  9878     
   -1  9879     /**
   -1  9880      * Creates a new Pixi.js WebGL renderer
   -1  9881      * @method create
   -1  9882      * @param {object} options
   -1  9883      * @return {RenderPixi} A new renderer
   -1  9884      * @deprecated
   -1  9885      */
   -1  9886     RenderPixi.create = function(options) {
   -1  9887         Common.warn('RenderPixi.create: Matter.RenderPixi is deprecated (see docs)');
   -1  9888 
   -1  9889         var defaults = {
   -1  9890             controller: RenderPixi,
   -1  9891             engine: null,
   -1  9892             element: null,
   -1  9893             frameRequestId: null,
   -1  9894             canvas: null,
   -1  9895             renderer: null,
   -1  9896             container: null,
   -1  9897             spriteContainer: null,
   -1  9898             pixiOptions: null,
   -1  9899             options: {
   -1  9900                 width: 800,
   -1  9901                 height: 600,
   -1  9902                 background: '#fafafa',
   -1  9903                 wireframeBackground: '#222',
   -1  9904                 hasBounds: false,
   -1  9905                 enabled: true,
   -1  9906                 wireframes: true,
   -1  9907                 showSleeping: true,
   -1  9908                 showDebug: false,
   -1  9909                 showBroadphase: false,
   -1  9910                 showBounds: false,
   -1  9911                 showVelocity: false,
   -1  9912                 showCollisions: false,
   -1  9913                 showAxes: false,
   -1  9914                 showPositions: false,
   -1  9915                 showAngleIndicator: false,
   -1  9916                 showIds: false,
   -1  9917                 showShadows: false
   -1  9918             }
   -1  9919         };
   -1  9920 
   -1  9921         var render = Common.extend(defaults, options),
   -1  9922             transparent = !render.options.wireframes && render.options.background === 'transparent';
   -1  9923 
   -1  9924         // init pixi
   -1  9925         render.pixiOptions = render.pixiOptions || {
   -1  9926             view: render.canvas,
   -1  9927             transparent: transparent,
   -1  9928             antialias: true,
   -1  9929             backgroundColor: options.background
   -1  9930         };
   -1  9931 
   -1  9932         render.mouse = options.mouse;
   -1  9933         render.engine = options.engine;
   -1  9934         render.renderer = render.renderer || new PIXI.WebGLRenderer(render.options.width, render.options.height, render.pixiOptions);
   -1  9935         render.container = render.container || new PIXI.Container();
   -1  9936         render.spriteContainer = render.spriteContainer || new PIXI.Container();
   -1  9937         render.canvas = render.canvas || render.renderer.view;
   -1  9938         render.bounds = render.bounds || { 
   -1  9939             min: {
   -1  9940                 x: 0,
   -1  9941                 y: 0
   -1  9942             }, 
   -1  9943             max: { 
   -1  9944                 x: render.options.width,
   -1  9945                 y: render.options.height
   -1  9946             }
   -1  9947         };
   -1  9948 
   -1  9949         // event listeners
   -1  9950         Events.on(render.engine, 'beforeUpdate', function() {
   -1  9951             RenderPixi.clear(render);
   -1  9952         });
   -1  9953 
   -1  9954         // caches
   -1  9955         render.textures = {};
   -1  9956         render.sprites = {};
   -1  9957         render.primitives = {};
   -1  9958 
   -1  9959         // use a sprite batch for performance
   -1  9960         render.container.addChild(render.spriteContainer);
   -1  9961 
   -1  9962         // insert canvas
   -1  9963         if (Common.isElement(render.element)) {
   -1  9964             render.element.appendChild(render.canvas);
   -1  9965         } else {
   -1  9966             Common.warn('No "render.element" passed, "render.canvas" was not inserted into document.');
   -1  9967         }
   -1  9968 
   -1  9969         // prevent menus on canvas
   -1  9970         render.canvas.oncontextmenu = function() { return false; };
   -1  9971         render.canvas.onselectstart = function() { return false; };
   -1  9972 
   -1  9973         return render;
   -1  9974     };
   -1  9975 
   -1  9976     /**
   -1  9977      * Continuously updates the render canvas on the `requestAnimationFrame` event.
   -1  9978      * @method run
   -1  9979      * @param {render} render
   -1  9980      * @deprecated
   -1  9981      */
   -1  9982     RenderPixi.run = function(render) {
   -1  9983         (function loop(time){
   -1  9984             render.frameRequestId = _requestAnimationFrame(loop);
   -1  9985             RenderPixi.world(render);
   -1  9986         })();
   -1  9987     };
   -1  9988 
   -1  9989     /**
   -1  9990      * Ends execution of `Render.run` on the given `render`, by canceling the animation frame request event loop.
   -1  9991      * @method stop
   -1  9992      * @param {render} render
   -1  9993      * @deprecated
   -1  9994      */
   -1  9995     RenderPixi.stop = function(render) {
   -1  9996         _cancelAnimationFrame(render.frameRequestId);
   -1  9997     };
   -1  9998 
   -1  9999     /**
   -1 10000      * Clears the scene graph
   -1 10001      * @method clear
   -1 10002      * @param {RenderPixi} render
   -1 10003      * @deprecated
   -1 10004      */
   -1 10005     RenderPixi.clear = function(render) {
   -1 10006         var container = render.container,
   -1 10007             spriteContainer = render.spriteContainer;
   -1 10008 
   -1 10009         // clear stage container
   -1 10010         while (container.children[0]) { 
   -1 10011             container.removeChild(container.children[0]); 
   -1 10012         }
   -1 10013 
   -1 10014         // clear sprite batch
   -1 10015         while (spriteContainer.children[0]) { 
   -1 10016             spriteContainer.removeChild(spriteContainer.children[0]); 
   -1 10017         }
   -1 10018 
   -1 10019         var bgSprite = render.sprites['bg-0'];
   -1 10020 
   -1 10021         // clear caches
   -1 10022         render.textures = {};
   -1 10023         render.sprites = {};
   -1 10024         render.primitives = {};
   -1 10025 
   -1 10026         // set background sprite
   -1 10027         render.sprites['bg-0'] = bgSprite;
   -1 10028         if (bgSprite)
   -1 10029             container.addChildAt(bgSprite, 0);
   -1 10030 
   -1 10031         // add sprite batch back into container
   -1 10032         render.container.addChild(render.spriteContainer);
   -1 10033 
   -1 10034         // reset background state
   -1 10035         render.currentBackground = null;
   -1 10036 
   -1 10037         // reset bounds transforms
   -1 10038         container.scale.set(1, 1);
   -1 10039         container.position.set(0, 0);
   -1 10040     };
   -1 10041 
   -1 10042     /**
   -1 10043      * Sets the background of the canvas 
   -1 10044      * @method setBackground
   -1 10045      * @param {RenderPixi} render
   -1 10046      * @param {string} background
   -1 10047      * @deprecated
   -1 10048      */
   -1 10049     RenderPixi.setBackground = function(render, background) {
   -1 10050         if (render.currentBackground !== background) {
   -1 10051             var isColor = background.indexOf && background.indexOf('#') !== -1,
   -1 10052                 bgSprite = render.sprites['bg-0'];
   -1 10053 
   -1 10054             if (isColor) {
   -1 10055                 // if solid background color
   -1 10056                 var color = Common.colorToNumber(background);
   -1 10057                 render.renderer.backgroundColor = color;
   -1 10058 
   -1 10059                 // remove background sprite if existing
   -1 10060                 if (bgSprite)
   -1 10061                     render.container.removeChild(bgSprite); 
   -1 10062             } else {
   -1 10063                 // initialise background sprite if needed
   -1 10064                 if (!bgSprite) {
   -1 10065                     var texture = _getTexture(render, background);
   -1 10066 
   -1 10067                     bgSprite = render.sprites['bg-0'] = new PIXI.Sprite(texture);
   -1 10068                     bgSprite.position.x = 0;
   -1 10069                     bgSprite.position.y = 0;
   -1 10070                     render.container.addChildAt(bgSprite, 0);
   -1 10071                 }
   -1 10072             }
   -1 10073 
   -1 10074             render.currentBackground = background;
   -1 10075         }
   -1 10076     };
   -1 10077 
   -1 10078     /**
   -1 10079      * Description
   -1 10080      * @method world
   -1 10081      * @param {engine} engine
   -1 10082      * @deprecated
   -1 10083      */
   -1 10084     RenderPixi.world = function(render) {
   -1 10085         var engine = render.engine,
   -1 10086             world = engine.world,
   -1 10087             renderer = render.renderer,
   -1 10088             container = render.container,
   -1 10089             options = render.options,
   -1 10090             bodies = Composite.allBodies(world),
   -1 10091             allConstraints = Composite.allConstraints(world),
   -1 10092             constraints = [],
   -1 10093             i;
   -1 10094 
   -1 10095         if (options.wireframes) {
   -1 10096             RenderPixi.setBackground(render, options.wireframeBackground);
   -1 10097         } else {
   -1 10098             RenderPixi.setBackground(render, options.background);
   -1 10099         }
   -1 10100 
   -1 10101         // handle bounds
   -1 10102         var boundsWidth = render.bounds.max.x - render.bounds.min.x,
   -1 10103             boundsHeight = render.bounds.max.y - render.bounds.min.y,
   -1 10104             boundsScaleX = boundsWidth / render.options.width,
   -1 10105             boundsScaleY = boundsHeight / render.options.height;
   -1 10106 
   -1 10107         if (options.hasBounds) {
   -1 10108             // Hide bodies that are not in view
   -1 10109             for (i = 0; i < bodies.length; i++) {
   -1 10110                 var body = bodies[i];
   -1 10111                 body.render.sprite.visible = Bounds.overlaps(body.bounds, render.bounds);
   -1 10112             }
   -1 10113 
   -1 10114             // filter out constraints that are not in view
   -1 10115             for (i = 0; i < allConstraints.length; i++) {
   -1 10116                 var constraint = allConstraints[i],
   -1 10117                     bodyA = constraint.bodyA,
   -1 10118                     bodyB = constraint.bodyB,
   -1 10119                     pointAWorld = constraint.pointA,
   -1 10120                     pointBWorld = constraint.pointB;
   -1 10121 
   -1 10122                 if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA);
   -1 10123                 if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB);
   -1 10124 
   -1 10125                 if (!pointAWorld || !pointBWorld)
   -1 10126                     continue;
   -1 10127 
   -1 10128                 if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld))
   -1 10129                     constraints.push(constraint);
   -1 10130             }
   -1 10131 
   -1 10132             // transform the view
   -1 10133             container.scale.set(1 / boundsScaleX, 1 / boundsScaleY);
   -1 10134             container.position.set(-render.bounds.min.x * (1 / boundsScaleX), -render.bounds.min.y * (1 / boundsScaleY));
   -1 10135         } else {
   -1 10136             constraints = allConstraints;
   -1 10137         }
   -1 10138 
   -1 10139         for (i = 0; i < bodies.length; i++)
   -1 10140             RenderPixi.body(render, bodies[i]);
   -1 10141 
   -1 10142         for (i = 0; i < constraints.length; i++)
   -1 10143             RenderPixi.constraint(render, constraints[i]);
   -1 10144 
   -1 10145         renderer.render(container);
   -1 10146     };
   -1 10147 
   -1 10148 
   -1 10149     /**
   -1 10150      * Description
   -1 10151      * @method constraint
   -1 10152      * @param {engine} engine
   -1 10153      * @param {constraint} constraint
   -1 10154      * @deprecated
   -1 10155      */
   -1 10156     RenderPixi.constraint = function(render, constraint) {
   -1 10157         var engine = render.engine,
   -1 10158             bodyA = constraint.bodyA,
   -1 10159             bodyB = constraint.bodyB,
   -1 10160             pointA = constraint.pointA,
   -1 10161             pointB = constraint.pointB,
   -1 10162             container = render.container,
   -1 10163             constraintRender = constraint.render,
   -1 10164             primitiveId = 'c-' + constraint.id,
   -1 10165             primitive = render.primitives[primitiveId];
   -1 10166 
   -1 10167         // initialise constraint primitive if not existing
   -1 10168         if (!primitive)
   -1 10169             primitive = render.primitives[primitiveId] = new PIXI.Graphics();
   -1 10170 
   -1 10171         // don't render if constraint does not have two end points
   -1 10172         if (!constraintRender.visible || !constraint.pointA || !constraint.pointB) {
   -1 10173             primitive.clear();
   -1 10174             return;
   -1 10175         }
   -1 10176 
   -1 10177         // add to scene graph if not already there
   -1 10178         if (Common.indexOf(container.children, primitive) === -1)
   -1 10179             container.addChild(primitive);
   -1 10180 
   -1 10181         // render the constraint on every update, since they can change dynamically
   -1 10182         primitive.clear();
   -1 10183         primitive.beginFill(0, 0);
   -1 10184         primitive.lineStyle(constraintRender.lineWidth, Common.colorToNumber(constraintRender.strokeStyle), 1);
   -1 10185         
   -1 10186         if (bodyA) {
   -1 10187             primitive.moveTo(bodyA.position.x + pointA.x, bodyA.position.y + pointA.y);
   -1 10188         } else {
   -1 10189             primitive.moveTo(pointA.x, pointA.y);
   -1 10190         }
   -1 10191 
   -1 10192         if (bodyB) {
   -1 10193             primitive.lineTo(bodyB.position.x + pointB.x, bodyB.position.y + pointB.y);
   -1 10194         } else {
   -1 10195             primitive.lineTo(pointB.x, pointB.y);
   -1 10196         }
   -1 10197 
   -1 10198         primitive.endFill();
   -1 10199     };
   -1 10200     
   -1 10201     /**
   -1 10202      * Description
   -1 10203      * @method body
   -1 10204      * @param {engine} engine
   -1 10205      * @param {body} body
   -1 10206      * @deprecated
   -1 10207      */
   -1 10208     RenderPixi.body = function(render, body) {
   -1 10209         var engine = render.engine,
   -1 10210             bodyRender = body.render;
   -1 10211 
   -1 10212         if (!bodyRender.visible)
   -1 10213             return;
   -1 10214 
   -1 10215         if (bodyRender.sprite && bodyRender.sprite.texture) {
   -1 10216             var spriteId = 'b-' + body.id,
   -1 10217                 sprite = render.sprites[spriteId],
   -1 10218                 spriteContainer = render.spriteContainer;
   -1 10219 
   -1 10220             // initialise body sprite if not existing
   -1 10221             if (!sprite)
   -1 10222                 sprite = render.sprites[spriteId] = _createBodySprite(render, body);
   -1 10223 
   -1 10224             // add to scene graph if not already there
   -1 10225             if (Common.indexOf(spriteContainer.children, sprite) === -1)
   -1 10226                 spriteContainer.addChild(sprite);
   -1 10227 
   -1 10228             // update body sprite
   -1 10229             sprite.position.x = body.position.x;
   -1 10230             sprite.position.y = body.position.y;
   -1 10231             sprite.rotation = body.angle;
   -1 10232             sprite.scale.x = bodyRender.sprite.xScale || 1;
   -1 10233             sprite.scale.y = bodyRender.sprite.yScale || 1;
   -1 10234         } else {
   -1 10235             var primitiveId = 'b-' + body.id,
   -1 10236                 primitive = render.primitives[primitiveId],
   -1 10237                 container = render.container;
   -1 10238 
   -1 10239             // initialise body primitive if not existing
   -1 10240             if (!primitive) {
   -1 10241                 primitive = render.primitives[primitiveId] = _createBodyPrimitive(render, body);
   -1 10242                 primitive.initialAngle = body.angle;
   -1 10243             }
   -1 10244 
   -1 10245             // add to scene graph if not already there
   -1 10246             if (Common.indexOf(container.children, primitive) === -1)
   -1 10247                 container.addChild(primitive);
   -1 10248 
   -1 10249             // update body primitive
   -1 10250             primitive.position.x = body.position.x;
   -1 10251             primitive.position.y = body.position.y;
   -1 10252             primitive.rotation = body.angle - primitive.initialAngle;
   -1 10253         }
   -1 10254     };
   -1 10255 
   -1 10256     /**
   -1 10257      * Creates a body sprite
   -1 10258      * @method _createBodySprite
   -1 10259      * @private
   -1 10260      * @param {RenderPixi} render
   -1 10261      * @param {body} body
   -1 10262      * @return {PIXI.Sprite} sprite
   -1 10263      * @deprecated
   -1 10264      */
   -1 10265     var _createBodySprite = function(render, body) {
   -1 10266         var bodyRender = body.render,
   -1 10267             texturePath = bodyRender.sprite.texture,
   -1 10268             texture = _getTexture(render, texturePath),
   -1 10269             sprite = new PIXI.Sprite(texture);
   -1 10270 
   -1 10271         sprite.anchor.x = body.render.sprite.xOffset;
   -1 10272         sprite.anchor.y = body.render.sprite.yOffset;
   -1 10273 
   -1 10274         return sprite;
   -1 10275     };
   -1 10276 
   -1 10277     /**
   -1 10278      * Creates a body primitive
   -1 10279      * @method _createBodyPrimitive
   -1 10280      * @private
   -1 10281      * @param {RenderPixi} render
   -1 10282      * @param {body} body
   -1 10283      * @return {PIXI.Graphics} graphics
   -1 10284      * @deprecated
   -1 10285      */
   -1 10286     var _createBodyPrimitive = function(render, body) {
   -1 10287         var bodyRender = body.render,
   -1 10288             options = render.options,
   -1 10289             primitive = new PIXI.Graphics(),
   -1 10290             fillStyle = Common.colorToNumber(bodyRender.fillStyle),
   -1 10291             strokeStyle = Common.colorToNumber(bodyRender.strokeStyle),
   -1 10292             strokeStyleIndicator = Common.colorToNumber(bodyRender.strokeStyle),
   -1 10293             strokeStyleWireframe = Common.colorToNumber('#bbb'),
   -1 10294             strokeStyleWireframeIndicator = Common.colorToNumber('#CD5C5C'),
   -1 10295             part;
   -1 10296 
   -1 10297         primitive.clear();
   -1 10298 
   -1 10299         // handle compound parts
   -1 10300         for (var k = body.parts.length > 1 ? 1 : 0; k < body.parts.length; k++) {
   -1 10301             part = body.parts[k];
   -1 10302 
   -1 10303             if (!options.wireframes) {
   -1 10304                 primitive.beginFill(fillStyle, 1);
   -1 10305                 primitive.lineStyle(bodyRender.lineWidth, strokeStyle, 1);
   -1 10306             } else {
   -1 10307                 primitive.beginFill(0, 0);
   -1 10308                 primitive.lineStyle(1, strokeStyleWireframe, 1);
   -1 10309             }
   -1 10310 
   -1 10311             primitive.moveTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
   -1 10312 
   -1 10313             for (var j = 1; j < part.vertices.length; j++) {
   -1 10314                 primitive.lineTo(part.vertices[j].x - body.position.x, part.vertices[j].y - body.position.y);
   -1 10315             }
   -1 10316 
   -1 10317             primitive.lineTo(part.vertices[0].x - body.position.x, part.vertices[0].y - body.position.y);
   -1 10318 
   -1 10319             primitive.endFill();
   -1 10320 
   -1 10321             // angle indicator
   -1 10322             if (options.showAngleIndicator || options.showAxes) {
   -1 10323                 primitive.beginFill(0, 0);
   -1 10324 
   -1 10325                 if (options.wireframes) {
   -1 10326                     primitive.lineStyle(1, strokeStyleWireframeIndicator, 1);
   -1 10327                 } else {
   -1 10328                     primitive.lineStyle(1, strokeStyleIndicator);
   -1 10329                 }
   -1 10330 
   -1 10331                 primitive.moveTo(part.position.x - body.position.x, part.position.y - body.position.y);
   -1 10332                 primitive.lineTo(((part.vertices[0].x + part.vertices[part.vertices.length-1].x) / 2 - body.position.x), 
   -1 10333                                  ((part.vertices[0].y + part.vertices[part.vertices.length-1].y) / 2 - body.position.y));
   -1 10334 
   -1 10335                 primitive.endFill();
   -1 10336             }
   -1 10337         }
   -1 10338 
   -1 10339         return primitive;
   -1 10340     };
   -1 10341 
   -1 10342     /**
   -1 10343      * Gets the requested texture (a PIXI.Texture) via its path
   -1 10344      * @method _getTexture
   -1 10345      * @private
   -1 10346      * @param {RenderPixi} render
   -1 10347      * @param {string} imagePath
   -1 10348      * @return {PIXI.Texture} texture
   -1 10349      * @deprecated
   -1 10350      */
   -1 10351     var _getTexture = function(render, imagePath) {
   -1 10352         var texture = render.textures[imagePath];
   -1 10353 
   -1 10354         if (!texture)
   -1 10355             texture = render.textures[imagePath] = PIXI.Texture.fromImage(imagePath);
   -1 10356 
   -1 10357         return texture;
   -1 10358     };
   -1 10359 
   -1 10360 })();
   -1 10361 
   -1 10362 },{"../body/Composite":2,"../core/Common":14,"../core/Events":16,"../geometry/Bounds":26,"../geometry/Vector":28}]},{},[30])(30)
   -1 10363 });
   -1 10364 
   -1 10365 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
   -1 10366 },{}],2:[function(require,module,exports){
   -1 10367 var Matter = require('matter-js');
   -1 10368 
   -1 10369 var TILE_SIZE = 20;
   -1 10370 var WIDTH = 10 * TILE_SIZE;
   -1 10371 var HEIGHT = 30 * TILE_SIZE;
   -1 10372 
   -1 10373 var BLOCKS = [{
   -1 10374     label: 'I',
   -1 10375     color: 'cyan',
   -1 10376     points: [{x: -2, y: 0}, {x: -1, y: 0}, {x: 0, y: 0}, {x: 1, y: 0}],
   -1 10377 }, {
   -1 10378     label: 'J',
   -1 10379     color: 'blue',
   -1 10380     points: [{x: -2, y: 0}, {x: -1, y: 0}, {x: 0, y: 0}, {x: 0, y: 1}],
   -1 10381 }, {
   -1 10382     label: 'L',
   -1 10383     color: 'orange',
   -1 10384     points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: 1, y: 0}, {x: -1, y: 1}],
   -1 10385 }, {
   -1 10386     label: 'O',
   -1 10387     color: 'yellow',
   -1 10388     points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: -1, y: 1}, {x: 0, y: 1}],
   -1 10389 }, {
   -1 10390     label: 'S',
   -1 10391     color: 'green',
   -1 10392     points: [{x: 0, y: 0}, {x: 1, y: 0}, {x: -1, y: 1}, {x: 0, y: 1}],
   -1 10393 }, {
   -1 10394     label: 'T',
   -1 10395     color: 'purple',
   -1 10396     points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: 1, y: 0}, {x: 0, y: 1}],
   -1 10397 }, {
   -1 10398     label: 'Z',
   -1 10399     color: 'red',
   -1 10400     points: [{x: -1, y: 0}, {x: 0, y: 0}, {x: 0, y: 1}, {x: 1, y: 1}],
   -1 10401 }];
   -1 10402 
   -1 10403 var engine = Matter.Engine.create();
   -1 10404 var runner = Matter.Runner.create();
   -1 10405 
   -1 10406 var ground = Matter.Bodies.rectangle(WIDTH / 2, HEIGHT + 50, WIDTH, 100, {isStatic: true});
   -1 10407 Matter.World.add(engine.world, [ground]);
   -1 10408 
   -1 10409 var falling;
   -1 10410 var control = true;
   -1 10411 
   -1 10412 var spawn = function() {
   -1 10413     var block = BLOCKS[Math.floor(Math.random() * BLOCKS.length)];
   -1 10414     var parts = block.points.map(function(d) {
   -1 10415         return Matter.Bodies.rectangle(
   -1 10416             WIDTH / 2 + d.x * TILE_SIZE,
   -1 10417             d.y * TILE_SIZE,
   -1 10418             TILE_SIZE,
   -1 10419             TILE_SIZE,
   -1 10420             {render: {fillStyle: block.color}});
   -1 10421     });
   -1 10422     falling = Matter.Body.create({
   -1 10423         density: 0.001,
   -1 10424         friction: 0.1,
   -1 10425         restitution: 0,
   -1 10426         parts: parts,
   -1 10427     });
   -1 10428     control = true;
   -1 10429     Matter.World.add(engine.world, [falling]);
   -1 10430 };
   -1 10431 
   -1 10432 Matter.Events.on(engine, 'collisionStart', function(event) {
   -1 10433     event.pairs.forEach(function(pair) {
   -1 10434         if (falling.parts.includes(pair.bodyA) ||
   -1 10435             falling.parts.includes(pair.bodyB)) {
   -1 10436             spawn();
   -1 10437         }
   -1 10438     });
   -1 10439 });
   -1 10440 
   -1 10441 var previousTimestamp;
   -1 10442 Matter.Events.on(engine, 'beforeUpdate', function(event) {
   -1 10443     if (previousTimestamp && control) {
   -1 10444         var dt = event.timestamp - previousTimestamp;
   -1 10445         var dy = dt * 0.1;
   -1 10446         Matter.Body.setVelocity(falling, {x: 0, y: dy});
   -1 10447         Matter.Body.setPosition(falling, {
   -1 10448             x: falling.position.x,
   -1 10449             y: falling.position.y + dy,
   -1 10450         });
   -1 10451     }
   -1 10452     previousTimestamp = event.timestamp;
   -1 10453 });
   -1 10454 
   -1 10455 Matter.Events.on(engine, 'afterUpdate', function() {
   -1 10456     var allBodies = Matter.Composite.allBodies(engine.world);
   -1 10457     allBodies.forEach(function(body) {
   -1 10458         if (!body.isStatic && body.position.y > HEIGHT) {
   -1 10459             Matter.Composite.remove(engine.world, body, true);
   -1 10460             if (body == falling) {
   -1 10461                 spawn();
   -1 10462             }
   -1 10463         }
   -1 10464     });
   -1 10465 });
   -1 10466 
   -1 10467 document.addEventListener('keydown', function(event) {
   -1 10468     if (event.key == 'ArrowLeft') {
   -1 10469         event.preventDefault();
   -1 10470         Matter.Body.setPosition(falling, {
   -1 10471             x: falling.position.x - TILE_SIZE / 2,
   -1 10472             y: falling.position.y,
   -1 10473         });
   -1 10474     } else if (event.key == 'ArrowRight') {
   -1 10475         event.preventDefault();
   -1 10476         Matter.Body.setPosition(falling, {
   -1 10477             x: falling.position.x + TILE_SIZE / 2,
   -1 10478             y: falling.position.y,
   -1 10479         });
   -1 10480     } else if (event.key == 'ArrowUp') {
   -1 10481         event.preventDefault();
   -1 10482         Matter.Body.rotate(falling, -Math.PI / 2);
   -1 10483     } else if (event.key == 'ArrowDown') {
   -1 10484         event.preventDefault();
   -1 10485         control = false;
   -1 10486         Matter.Body.setVelocity(falling, {x: 0, y: falling.velocity.y * 2});
   -1 10487     } else if (event.key == 'Escape') {
   -1 10488         event.preventDefault();
   -1 10489         Matter.Composite.clear(engine.world, true);
   -1 10490         spawn();
   -1 10491     } else if (event.key == 'p') {
   -1 10492         event.preventDefault();
   -1 10493         runner.enabled = !runner.enabled;
   -1 10494     }
   -1 10495 });
   -1 10496 
   -1 10497 document.addEventListener('DOMContentLoaded', function() {
   -1 10498     var render = Matter.Render.create({
   -1 10499         element: document.body,
   -1 10500         engine: engine,
   -1 10501         options: {
   -1 10502             width: WIDTH,
   -1 10503             height: HEIGHT,
   -1 10504             wireframes: false,
   -1 10505         },
   -1 10506     });
   -1 10507     Matter.Render.run(render);
   -1 10508     Matter.Runner.run(runner, engine);
   -1 10509 
   -1 10510     render.canvas.style.background = 'linear-gradient(90deg, transparent 50%, rgba(255,255,255,.5) 50%)';
   -1 10511     render.canvas.style.backgroundSize = TILE_SIZE * 2 + 'px';
   -1 10512 
   -1 10513     spawn();
   -1 10514 }, 100);
   -1 10515 
   -1 10516 },{"matter-js":1}]},{},[2]);

diff --git a/docs/index.html b/docs/index.html

@@ -0,0 +1,16 @@
   -1     1 <!DOCTYPE html>
   -1     2 <meta charset="utf-8" />
   -1     3 <meta name="viewport" content="width=device-width">
   -1     4 <title>Tricky Towers</title>
   -1     5 <style type="text/css">body{margin: 2em auto; max-width: 38em; line-height: 1.5; color: #333; padding: 0 1em} h1, h2, h3 {line-height: 1.2}</style>
   -1     6 <h1 id="tricky-towers">Tricky Towers</h1>
   -1     7 <p>This is a simple <a href="http://trickytowers.com/">tricky towers</a> clone using <a href="http://brm.io/matter-js/">matter.js</a>. If you do not know the game: It is basically tetris with physics.</p>
   -1     8 <h2 id="controls">Controls</h2>
   -1     9 <ul>
   -1    10 <li>Left/Right/Up/Down - control falling block</li>
   -1    11 <li>P - pause</li>
   -1    12 <li>Esc - Restart</li>
   -1    13 </ul>
   -1    14 <h2 id="code">Code</h2>
   -1    15 <p><a href="https://github.com/xi/trickytowers" class="uri">https://github.com/xi/trickytowers</a></p>
   -1    16 <script src="./build.js"></script>