text: /**
  * The `Matter.Body` module contains methods for creating and manipulating body models.
  * A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`.
  * Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the module `Matter.Bodies`.
  *
  * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples).
  
  * @class Body
  */
  
  var Body = {};
  
  module.exports = Body;
  
  var Vertices = require('../geometry/Vertices');
  var Vector = require('../geometry/Vector');
  var Sleeping = require('../core/Sleeping');
  var Common = require('../core/Common');
  var Bounds = require('../geometry/Bounds');
  var Axes = require('../geometry/Axes');
  
  (function() {
  
      Body._inertiaScale = 4;
      Body._nextCollidingGroupId = 1;
      Body._nextNonCollidingGroupId = -1;
      Body._nextCategory = 0x0001;
  
      /**
       * Creates a new rigid body model. The options parameter is an object that specifies any properties you wish to override the defaults.
       * All properties have default values, and many are pre-calculated automatically based on other properties.
       * Vertices must be specified in clockwise order.
       * See the properties section below for detailed information on what you can pass via the `options` object.
       * @method create
       * @param {} options
       * @return {body} body
       */
      Body.create = function(options) {
          var defaults = {
              id: Common.nextId(),
              type: 'body',
              label: 'Body',
              gameObject: null,
              parts: [],
              plugin: {},
              angle: 0,
              vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'),
              position: { x: 0, y: 0 },
              force: { x: 0, y: 0 },
              torque: 0,
              positionImpulse: { x: 0, y: 0 },
              previousPositionImpulse: { x: 0, y: 0 },
              constraintImpulse: { x: 0, y: 0, angle: 0 },
              totalContacts: 0,
              speed: 0,
              angularSpeed: 0,
              velocity: { x: 0, y: 0 },
              angularVelocity: 0,
              isSensor: false,
              isStatic: false,
              isSleeping: false,
              ignoreGravity: false,
              ignorePointer: false,
              motion: 0,
              sleepThreshold: 60,
              density: 0.001,
              restitution: 0,
              friction: 0.1,
              frictionStatic: 0.5,
              frictionAir: 0.01,
              collisionFilter: {
                  category: 0x0001,
                  mask: 0xFFFFFFFF,
                  group: 0
              },
              slop: 0.05,
              timeScale: 1,
              render: {
                  visible: true,
                  opacity: 1,
                  sprite: {
                      xScale: 1,
                      yScale: 1,
                      xOffset: 0,
                      yOffset: 0
                  },
                  lineWidth: 0
              },
  
              events: null,
              bounds: null,
              chamfer: null,
              circleRadius: 0,
              positionPrev: null,
              anglePrev: 0,
              parent: null,
  
              axes: null,
              area: 0,
              mass: 0,
              inertia: 0,
  
              _original: null
          };
  
          var body = Common.extend(defaults, options);
  
          _initProperties(body, options);
  
          return body;
      };
  
      /**
       * Returns the next unique group index for which bodies will collide.
       * If `isNonColliding` is `true`, returns the next unique group index for which bodies will _not_ collide.
       * See `body.collisionFilter` for more information.
       * @method nextGroup
       * @param {bool} [isNonColliding=false]
       * @return {Number} Unique group index
       */
      Body.nextGroup = function(isNonColliding) {
          if (isNonColliding)
              return Body._nextNonCollidingGroupId--;
  
          return Body._nextCollidingGroupId++;
      };
  
      /**
       * Returns the next unique category bitfield (starting after the initial default category `0x0001`).
       * There are 32 available. See `body.collisionFilter` for more information.
       * @method nextCategory
       * @return {Number} Unique category bitfield
       */
      Body.nextCategory = function() {
          Body._nextCategory = Body._nextCategory << 1;
          return Body._nextCategory;
      };
  
      /**
       * Initialises body properties.
       * @method _initProperties
       * @private
       * @param {body} body
       * @param {} [options]
       */
      var _initProperties = function(body, options) {
          options = options || {};
  
          // init required properties (order is important)
          Body.set(body, {
              bounds: body.bounds || Bounds.create(body.vertices),
              positionPrev: body.positionPrev || Vector.clone(body.position),
              anglePrev: body.anglePrev || body.angle,
              vertices: body.vertices,
              parts: body.parts || [body],
              isStatic: body.isStatic,
              isSleeping: body.isSleeping,
              parent: body.parent || body
          });
  
          Vertices.rotate(body.vertices, body.angle, body.position);
          Axes.rotate(body.axes, body.angle);
          Bounds.update(body.bounds, body.vertices, body.velocity);
  
          // allow options to override the automatically calculated properties
          Body.set(body, {
              axes: options.axes || body.axes,
              area: options.area || body.area,
              mass: options.mass || body.mass,
              inertia: options.inertia || body.inertia
          });
  
          // render properties
          var defaultFillStyle = (body.isStatic ? '#2e2b44' : Common.choose(['#006BA6', '#0496FF', '#FFBC42', '#D81159', '#8F2D56'])),
              defaultStrokeStyle = '#000';
          body.render.fillStyle = body.render.fillStyle || defaultFillStyle;
          body.render.strokeStyle = body.render.strokeStyle || defaultStrokeStyle;
          body.render.sprite.xOffset += -(body.bounds.min.x - body.position.x) / (body.bounds.max.x - body.bounds.min.x);
          body.render.sprite.yOffset += -(body.bounds.min.y - body.position.y) / (body.bounds.max.y - body.bounds.min.y);
      };
  
      /**
       * Given a property and a value (or map of), sets the property(s) on the body, using the appropriate setter functions if they exist.
       * Prefer to use the actual setter functions in performance critical situations.
       * @method set
       * @param {body} body
       * @param {} settings A property name (or map of properties and values) to set on the body.
       * @param {} value The value to set if `settings` is a single property name.
       */
      Body.set = function(body, settings, value) {
          var property;
  
          if (typeof settings === 'string') {
              property = settings;
              settings = {};
              settings[property] = value;
          }
  
          for (property in settings) {
  
              if (!settings.hasOwnProperty(property))
                  continue;
  
              value = settings[property];
              switch (property) {
  
              case 'isStatic':
                  Body.setStatic(body, value);
                  break;
              case 'isSleeping':
                  Sleeping.set(body, value);
                  break;
              case 'mass':
                  Body.setMass(body, value);
                  break;
              case 'density':
                  Body.setDensity(body, value);
                  break;
              case 'inertia':
                  Body.setInertia(body, value);
                  break;
              case 'vertices':
                  Body.setVertices(body, value);
                  break;
              case 'position':
                  Body.setPosition(body, value);
                  break;
              case 'angle':
                  Body.setAngle(body, value);
                  break;
              case 'velocity':
                  Body.setVelocity(body, value);
                  break;
              case 'angularVelocity':
                  Body.setAngularVelocity(body, value);
                  break;
              case 'parts':
                  Body.setParts(body, value);
                  break;
              default:
                  body[property] = value;
  
              }
          }
      };
  
      /**
       * Sets the body as static, including isStatic flag and setting mass and inertia to Infinity.
       * @method setStatic
       * @param {body} body
       * @param {bool} isStatic
       */
      Body.setStatic = function(body, isStatic) {
          for (var i = 0; i < body.parts.length; i++) {
              var part = body.parts[i];
              part.isStatic = isStatic;
  
              if (isStatic) {
                  part._original = {
                      restitution: part.restitution,
                      friction: part.friction,
                      mass: part.mass,
                      inertia: part.inertia,
                      density: part.density,
                      inverseMass: part.inverseMass,
                      inverseInertia: part.inverseInertia
                  };
  
                  part.restitution = 0;
                  part.friction = 1;
                  part.mass = part.inertia = part.density = Infinity;
                  part.inverseMass = part.inverseInertia = 0;
  
                  part.positionPrev.x = part.position.x;
                  part.positionPrev.y = part.position.y;
                  part.anglePrev = part.angle;
                  part.angularVelocity = 0;
                  part.speed = 0;
                  part.angularSpeed = 0;
                  part.motion = 0;
              } else if (part._original) {
                  part.restitution = part._original.restitution;
                  part.friction = part._original.friction;
                  part.mass = part._original.mass;
                  part.inertia = part._original.inertia;
                  part.density = part._original.density;
                  part.inverseMass = part._original.inverseMass;
                  part.inverseInertia = part._original.inverseInertia;
  
                  part._original = null;
              }
          }
      };
  
      /**
       * Sets the mass of the body. Inverse mass, density and inertia are automatically updated to reflect the change.
       * @method setMass
       * @param {body} body
       * @param {number} mass
       */
      Body.setMass = function(body, mass) {
          var moment = body.inertia / (body.mass / 6);
          body.inertia = moment * (mass / 6);
          body.inverseInertia = 1 / body.inertia;
  
          body.mass = mass;
          body.inverseMass = 1 / body.mass;
          body.density = body.mass / body.area;
      };
  
      /**
       * Sets the density of the body. Mass and inertia are automatically updated to reflect the change.
       * @method setDensity
       * @param {body} body
       * @param {number} density
       */
      Body.setDensity = function(body, density) {
          Body.setMass(body, density * body.area);
          body.density = density;
      };
  
      /**
       * Sets the moment of inertia (i.e. second moment of area) of the body of the body. 
       * Inverse inertia is automatically updated to reflect the change. Mass is not changed.
       * @method setInertia
       * @param {body} body
       * @param {number} inertia
       */
      Body.setInertia = function(body, inertia) {
          body.inertia = inertia;
          body.inverseInertia = 1 / body.inertia;
      };
  
      /**
       * Sets the body's vertices and updates body properties accordingly, including inertia, area and mass (with respect to `body.density`).
       * Vertices will be automatically transformed to be orientated around their centre of mass as the origin.
       * They are then automatically translated to world space based on `body.position`.
       *
       * The `vertices` argument should be passed as an array of `Matter.Vector` points (or a `Matter.Vertices` array).
       * Vertices must form a convex hull, concave hulls are not supported.
       *
       * @method setVertices
       * @param {body} body
       * @param {vector[]} vertices
       */
      Body.setVertices = function(body, vertices) {
          // change vertices
          if (vertices[0].body === body) {
              body.vertices = vertices;
          } else {
              body.vertices = Vertices.create(vertices, body);
          }
  
          // update properties
          body.axes = Axes.fromVertices(body.vertices);
          body.area = Vertices.area(body.vertices);
          Body.setMass(body, body.density * body.area);
  
          // orient vertices around the centre of mass at origin (0, 0)
          var centre = Vertices.centre(body.vertices);
          Vertices.translate(body.vertices, centre, -1);
  
          // update inertia while vertices are at origin (0, 0)
          Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass));
  
          // update geometry
          Vertices.translate(body.vertices, body.position);
          Bounds.update(body.bounds, body.vertices, body.velocity);
      };
  
      /**
       * Sets the parts of the `body` and updates mass, inertia and centroid.
       * Each part will have its parent set to `body`.
       * By default the convex hull will be automatically computed and set on `body`, unless `autoHull` is set to `false.`
       * Note that this method will ensure that the first part in `body.parts` will always be the `body`.
       * @method setParts
       * @param {body} body
       * @param [body] parts
       * @param {bool} [autoHull=true]
       */
      Body.setParts = function(body, parts, autoHull) {
          var i;
  
          // add all the parts, ensuring that the first part is always the parent body
          parts = parts.slice(0);
          body.parts.length = 0;
          body.parts.push(body);
          body.parent = body;
  
          for (i = 0; i < parts.length; i++) {
              var part = parts[i];
              if (part !== body) {
                  part.parent = body;
                  body.parts.push(part);
              }
          }
  
          if (body.parts.length === 1)
              return;
  
          autoHull = typeof autoHull !== 'undefined' ? autoHull : true;
  
          // find the convex hull of all parts to set on the parent body
          if (autoHull) {
              var vertices = [];
              for (i = 0; i < parts.length; i++) {
                  vertices = vertices.concat(parts[i].vertices);
              }
  
              Vertices.clockwiseSort(vertices);
  
              var hull = Vertices.hull(vertices),
                  hullCentre = Vertices.centre(hull);
  
              Body.setVertices(body, hull);
              Vertices.translate(body.vertices, hullCentre);
          }
  
          // sum the properties of all compound parts of the parent body
          var total = Body._totalProperties(body);
  
          body.area = total.area;
          body.parent = body;
          body.position.x = total.centre.x;
          body.position.y = total.centre.y;
          body.positionPrev.x = total.centre.x;
          body.positionPrev.y = total.centre.y;
  
          Body.setMass(body, total.mass);
          Body.setInertia(body, total.inertia);
          Body.setPosition(body, total.centre);
      };
  
      /**
       * Sets the position of the body instantly. Velocity, angle, force etc. are unchanged.
       * @method setPosition
       * @param {body} body
       * @param {vector} position
       */
      Body.setPosition = function(body, position) {
          var delta = Vector.sub(position, body.position);
          body.positionPrev.x += delta.x;
          body.positionPrev.y += delta.y;
  
          for (var i = 0; i < body.parts.length; i++) {
              var part = body.parts[i];
              part.position.x += delta.x;
              part.position.y += delta.y;
              Vertices.translate(part.vertices, delta);
              Bounds.update(part.bounds, part.vertices, body.velocity);
          }
      };
  
      /**
       * Sets the angle of the body instantly. Angular velocity, position, force etc. are unchanged.
       * @method setAngle
       * @param {body} body
       * @param {number} angle
       */
      Body.setAngle = function(body, angle) {
          var delta = angle - body.angle;
          body.anglePrev += delta;
  
          for (var i = 0; i < body.parts.length; i++) {
              var part = body.parts[i];
              part.angle += delta;
              Vertices.rotate(part.vertices, delta, body.position);
              Axes.rotate(part.axes, delta);
              Bounds.update(part.bounds, part.vertices, body.velocity);
              if (i > 0) {
                  Vector.rotateAbout(part.position, delta, body.position, part.position);
              }
          }
      };
  
      /**
       * Sets the linear velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
       * @method setVelocity
       * @param {body} body
       * @param {vector} velocity
       */
      Body.setVelocity = function(body, velocity) {
          body.positionPrev.x = body.position.x - velocity.x;
          body.positionPrev.y = body.position.y - velocity.y;
          body.velocity.x = velocity.x;
          body.velocity.y = velocity.y;
          body.speed = Vector.magnitude(body.velocity);
      };
  
      /**
       * Sets the angular velocity of the body instantly. Position, angle, force etc. are unchanged. See also `Body.applyForce`.
       * @method setAngularVelocity
       * @param {body} body
       * @param {number} velocity
       */
      Body.setAngularVelocity = function(body, velocity) {
          body.anglePrev = body.angle - velocity;
          body.angularVelocity = velocity;
          body.angularSpeed = Math.abs(body.angularVelocity);
      };
  
      /**
       * Moves a body by a given vector relative to its current position, without imparting any velocity.
       * @method translate
       * @param {body} body
       * @param {vector} translation
       */
      Body.translate = function(body, translation) {
          Body.setPosition(body, Vector.add(body.position, translation));
      };
  
      /**
       * Rotates a body by a given angle relative to its current angle, without imparting any angular velocity.
       * @method rotate
       * @param {body} body
       * @param {number} rotation
       * @param {vector} [point]
       */
      Body.rotate = function(body, rotation, point) {
          if (!point) {
              Body.setAngle(body, body.angle + rotation);
          } else {
              var cos = Math.cos(rotation),
                  sin = Math.sin(rotation),
                  dx = body.position.x - point.x,
                  dy = body.position.y - point.y;
                  
              Body.setPosition(body, {
                  x: point.x + (dx * cos - dy * sin),
                  y: point.y + (dx * sin + dy * cos)
              });
  
              Body.setAngle(body, body.angle + rotation);
          }
      };
  
      /**
       * Scales the body, including updating physical properties (mass, area, axes, inertia), from a world-space point (default is body centre).
       * @method scale
       * @param {body} body
       * @param {number} scaleX
       * @param {number} scaleY
       * @param {vector} [point]
       */
      Body.scale = function(body, scaleX, scaleY, point) {
          var totalArea = 0,
              totalInertia = 0;
  
          point = point || body.position;
  
          for (var i = 0; i < body.parts.length; i++) {
              var part = body.parts[i];
  
              // scale vertices
              Vertices.scale(part.vertices, scaleX, scaleY, point);
  
              // update properties
              part.axes = Axes.fromVertices(part.vertices);
              part.area = Vertices.area(part.vertices);
              Body.setMass(part, body.density * part.area);
  
              // update inertia (requires vertices to be at origin)
              Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y });
              Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass));
              Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y });
  
              if (i > 0) {
                  totalArea += part.area;
                  totalInertia += part.inertia;
              }
  
              // scale position
              part.position.x = point.x + (part.position.x - point.x) * scaleX;
              part.position.y = point.y + (part.position.y - point.y) * scaleY;
  
              // update bounds
              Bounds.update(part.bounds, part.vertices, body.velocity);
          }
  
          // handle parent body
          if (body.parts.length > 1) {
              body.area = totalArea;
  
              if (!body.isStatic) {
                  Body.setMass(body, body.density * totalArea);
                  Body.setInertia(body, totalInertia);
              }
          }
  
          // handle circles
          if (body.circleRadius) { 
              if (scaleX === scaleY) {
                  body.circleRadius *= scaleX;
              } else {
                  // body is no longer a circle
                  body.circleRadius = null;
              }
          }
      };
  
      /**
       * Performs a simulation step for the given `body`, including updating position and angle using Verlet integration.
       * @method update
       * @param {body} body
       * @param {number} deltaTime
       * @param {number} timeScale
       * @param {number} correction
       */
      Body.update = function(body, deltaTime, timeScale, correction) {
          var deltaTimeSquared = Math.pow(deltaTime * timeScale * body.timeScale, 2);
  
          // from the previous step
          var frictionAir = 1 - body.frictionAir * timeScale * body.timeScale,
              velocityPrevX = body.position.x - body.positionPrev.x,
              velocityPrevY = body.position.y - body.positionPrev.y;
  
          // update velocity with Verlet integration
          body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared;
          body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared;
  
          body.positionPrev.x = body.position.x;
          body.positionPrev.y = body.position.y;
          body.position.x += body.velocity.x;
          body.position.y += body.velocity.y;
  
          // update angular velocity with Verlet integration
          body.angularVelocity = ((body.angle - body.anglePrev) * frictionAir * correction) + (body.torque / body.inertia) * deltaTimeSquared;
          body.anglePrev = body.angle;
          body.angle += body.angularVelocity;
  
          // track speed and acceleration
          body.speed = Vector.magnitude(body.velocity);
          body.angularSpeed = Math.abs(body.angularVelocity);
  
          // transform the body geometry
          for (var i = 0; i < body.parts.length; i++) {
              var part = body.parts[i];
  
              Vertices.translate(part.vertices, body.velocity);
              
              if (i > 0) {
                  part.position.x += body.velocity.x;
                  part.position.y += body.velocity.y;
              }
  
              if (body.angularVelocity !== 0) {
                  Vertices.rotate(part.vertices, body.angularVelocity, body.position);
                  Axes.rotate(part.axes, body.angularVelocity);
                  if (i > 0) {
                      Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position);
                  }
              }
  
              Bounds.update(part.bounds, part.vertices, body.velocity);
          }
      };
  
      /**
       * Applies a force to a body from a given world-space position, including resulting torque.
       * @method applyForce
       * @param {body} body
       * @param {vector} position
       * @param {vector} force
       */
      Body.applyForce = function(body, position, force) {
          body.force.x += force.x;
          body.force.y += force.y;
          var offset = { x: position.x - body.position.x, y: position.y - body.position.y };
          body.torque += offset.x * force.y - offset.y * force.x;
      };
  
      /**
       * Returns the sums of the properties of all compound parts of the parent body.
       * @method _totalProperties
       * @private
       * @param {body} body
       * @return {}
       */
      Body._totalProperties = function(body) {
          // from equations at:
          // https://ecourses.ou.edu/cgi-bin/ebook.cgi?doc=&topic=st&chap_sec=07.2&page=theory
          // http://output.to/sideway/default.asp?qno=121100087
  
          var properties = {
              mass: 0,
              area: 0,
              inertia: 0,
              centre: { x: 0, y: 0 }
          };
  
          // sum the properties of all compound parts of the parent body
          for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) {
              var part = body.parts[i],
                  mass = part.mass !== Infinity ? part.mass : 1;
  
              properties.mass += mass;
              properties.area += part.area;
              properties.inertia += part.inertia;
              properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass));
          }
  
          properties.centre = Vector.div(properties.centre, properties.mass);
  
          return properties;
      };
  
      /*
      *
      *  Events Documentation
      *
      */
  
      /**
      * Fired when a body starts sleeping (where `this` is the body).
      *
      * @event sleepStart
      * @this {body} The body that has started sleeping
      * @param {} event An event object
      * @param {} event.source The source object of the event
      * @param {} event.name The name of the event
      */
  
      /**
      * Fired when a body ends sleeping (where `this` is the body).
      *
      * @event sleepEnd
      * @this {body} The body that has ended sleeping
      * @param {} event An event object
      * @param {} event.source The source object of the event
      * @param {} event.name The name of the event
      */
  
      /*
      *
      *  Properties Documentation
      *
      */
  
      /**
       * An integer `Number` uniquely identifying number generated in `Body.create` by `Common.nextId`.
       *
       * @property id
       * @type number
       */
  
      /**
       * A `String` denoting the type of object.
       *
       * @property type
       * @type string
       * @default "body"
       * @readOnly
       */
  
      /**
       * An arbitrary `String` name to help the user identify and manage bodies.
       *
       * @property label
       * @type string
       * @default "Body"
       */
  
      /**
       * An array of bodies that make up this body. 
       * The first body in the array must always be a self reference to the current body instance.
       * All bodies in the `parts` array together form a single rigid compound body.
       * Parts are allowed to overlap, have gaps or holes or even form concave bodies.
       * Parts themselves should never be added to a `World`, only the parent body should be.
       * Use `Body.setParts` when setting parts to ensure correct updates of all properties.
       *
       * @property parts
       * @type body[]
       */
  
      /**
       * An object reserved for storing plugin-specific properties.
       *
       * @property plugin
       * @type {}
       */
  
      /**
       * A self reference if the body is _not_ a part of another body.
       * Otherwise this is a reference to the body that this is a part of.
       * See `body.parts`.
       *
       * @property parent
       * @type body
       */
  
      /**
       * A `Number` specifying the angle of the body, in radians.
       *
       * @property angle
       * @type number
       * @default 0
       */
  
      /**
       * An array of `Vector` objects that specify the convex hull of the rigid body.
       * These should be provided about the origin `(0, 0)`. E.g.
       *
       *     [{ x: 0, y: 0 }, { x: 25, y: 50 }, { x: 50, y: 0 }]
       *
       * 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).
       * The `Vector` objects are also augmented with additional properties required for efficient collision detection. 
       *
       * Other properties such as `inertia` and `bounds` are automatically calculated from the passed vertices (unless provided via `options`).
       * Concave hulls are not currently supported. The module `Matter.Vertices` contains useful methods for working with vertices.
       *
       * @property vertices
       * @type vector[]
       */
  
      /**
       * A `Vector` that specifies the current world-space position of the body.
       *
       * @property position
       * @type vector
       * @default { x: 0, y: 0 }
       */
  
      /**
       * A `Vector` that specifies the force to apply in the current step. It is zeroed after every `Body.update`. See also `Body.applyForce`.
       *
       * @property force
       * @type vector
       * @default { x: 0, y: 0 }
       */
  
      /**
       * A `Number` that specifies the torque (turning force) to apply in the current step. It is zeroed after every `Body.update`.
       *
       * @property torque
       * @type number
       * @default 0
       */
  
      /**
       * 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`).
       *
       * @readOnly
       * @property speed
       * @type number
       * @default 0
       */
  
      /**
       * 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`).
       *
       * @readOnly
       * @property angularSpeed
       * @type number
       * @default 0
       */
  
      /**
       * A `Vector` that _measures_ the current velocity of the body after the last `Body.update`. It is read-only. 
       * 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).
       *
       * @readOnly
       * @property velocity
       * @type vector
       * @default { x: 0, y: 0 }
       */
  
      /**
       * A `Number` that _measures_ the current angular velocity of the body after the last `Body.update`. It is read-only. 
       * 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).
       *
       * @readOnly
       * @property angularVelocity
       * @type number
       * @default 0
       */
  
      /**
       * A flag that indicates whether a body is considered static. A static body can never change position or angle and is completely fixed.
       * 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.
       *
       * @property isStatic
       * @type boolean
       * @default false
       */
  
      /**
       * A flag that indicates whether a body is a sensor. Sensor triggers collision events, but doesn't react with colliding body physically.
       *
       * @property isSensor
       * @type boolean
       * @default false
       */
  
      /**
       * 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.
       * If you need to set a body as sleeping, you should use `Sleeping.set` as this requires more than just setting this flag.
       *
       * @property isSleeping
       * @type boolean
       * @default false
       */
  
      /**
       * 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.
       * It is used and updated by the `Matter.Sleeping` module during simulation to decide if a body has come to rest.
       *
       * @readOnly
       * @property motion
       * @type number
       * @default 0
       */
  
      /**
       * 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).
       *
       * @property sleepThreshold
       * @type number
       * @default 60
       */
  
      /**
       * A `Number` that defines the density of the body, that is its mass per unit area.
       * If you pass the density via `Body.create` the `mass` property is automatically calculated for you based on the size (area) of the object.
       * 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).
       *
       * @property density
       * @type number
       * @default 0.001
       */
  
      /**
       * A `Number` that defines the mass of the body, although it may be more appropriate to specify the `density` property instead.
       * If you modify this value, you must also modify the `body.inverseMass` property (`1 / mass`).
       *
       * @property mass
       * @type number
       */
  
      /**
       * A `Number` that defines the inverse mass of the body (`1 / mass`).
       * If you modify this value, you must also modify the `body.mass` property.
       *
       * @property inverseMass
       * @type number
       */
  
      /**
       * A `Number` that defines the moment of inertia (i.e. second moment of area) of the body.
       * It is automatically calculated from the given convex hull (`vertices` array) and density in `Body.create`.
       * If you modify this value, you must also modify the `body.inverseInertia` property (`1 / inertia`).
       *
       * @property inertia
       * @type number
       */
  
      /**
       * A `Number` that defines the inverse moment of inertia of the body (`1 / inertia`).
       * If you modify this value, you must also modify the `body.inertia` property.
       *
       * @property inverseInertia
       * @type number
       */
  
      /**
       * A `Number` that defines the restitution (elasticity) of the body. The value is always positive and is in the range `(0, 1)`.
       * A value of `0` means collisions may be perfectly inelastic and no bouncing may occur. 
       * A value of `0.8` means the body may bounce back with approximately 80% of its kinetic energy.
       * Note that collision response is based on _pairs_ of bodies, and that `restitution` values are _combined_ with the following formula:
       *
       *     Math.max(bodyA.restitution, bodyB.restitution)
       *
       * @property restitution
       * @type number
       * @default 0
       */
  
      /**
       * A `Number` that defines the friction of the body. The value is always positive and is in the range `(0, 1)`.
       * A value of `0` means that the body may slide indefinitely.
       * A value of `1` means the body may come to a stop almost instantly after a force is applied.
       *
       * The effects of the value may be non-linear. 
       * High values may be unstable depending on the body.
       * The engine uses a Coulomb friction model including static and kinetic friction.
       * Note that collision response is based on _pairs_ of bodies, and that `friction` values are _combined_ with the following formula:
       *
       *     Math.min(bodyA.friction, bodyB.friction)
       *
       * @property friction
       * @type number
       * @default 0.1
       */
  
      /**
       * A `Number` that defines the static friction of the body (in the Coulomb friction model). 
       * A value of `0` means the body will never 'stick' when it is nearly stationary and only dynamic `friction` is used.
       * The higher the value (e.g. `10`), the more force it will take to initially get the body moving when nearly stationary.
       * This value is multiplied with the `friction` property to make it easier to change `friction` and maintain an appropriate amount of static friction.
       *
       * @property frictionStatic
       * @type number
       * @default 0.5
       */
  
      /**
       * A `Number` that defines the air friction of the body (air resistance). 
       * A value of `0` means the body will never slow as it moves through space.
       * The higher the value, the faster a body slows when moving through space.
       * The effects of the value are non-linear. 
       *
       * @property frictionAir
       * @type number
       * @default 0.01
       */
  
      /**
       * An `Object` that specifies the collision filtering properties of this body.
       *
       * Collisions between two bodies will obey the following rules:
       * - If the two bodies have the same non-zero value of `collisionFilter.group`,
       *   they will always collide if the value is positive, and they will never collide
       *   if the value is negative.
       * - If the two bodies have different values of `collisionFilter.group` or if one
       *   (or both) of the bodies has a value of 0, then the category/mask rules apply as follows:
       *
       * Each body belongs to a collision category, given by `collisionFilter.category`. This
       * value is used as a bit field and the category should have only one bit set, meaning that
       * the value of this property is a power of two in the range [1, 2^31]. Thus, there are 32
       * different collision categories available.
       *
       * Each body also defines a collision bitmask, given by `collisionFilter.mask` which specifies
       * the categories it collides with (the value is the bitwise AND value of all these categories).
       *
       * Using the category/mask rules, two bodies `A` and `B` collide if each includes the other's
       * category in its mask, i.e. `(categoryA & maskB) !== 0` and `(categoryB & maskA) !== 0`
       * are both true.
       *
       * @property collisionFilter
       * @type object
       */
  
      /**
       * An Integer `Number`, that specifies the collision group this body belongs to.
       * See `body.collisionFilter` for more information.
       *
       * @property collisionFilter.group
       * @type object
       * @default 0
       */
  
      /**
       * A bit field that specifies the collision category this body belongs to.
       * The category value should have only one bit set, for example `0x0001`.
       * This means there are up to 32 unique collision categories available.
       * See `body.collisionFilter` for more information.
       *
       * @property collisionFilter.category
       * @type object
       * @default 1
       */
  
      /**
       * A bit mask that specifies the collision categories this body may collide with.
       * See `body.collisionFilter` for more information.
       *
       * @property collisionFilter.mask
       * @type object
       * @default -1
       */
  
      /**
       * A `Number` that specifies a tolerance on how far a body is allowed to 'sink' or rotate into other bodies.
       * Avoid changing this value unless you understand the purpose of `slop` in physics engines.
       * The default should generally suffice, although very large bodies may require larger values for stable stacking.
       *
       * @property slop
       * @type number
       * @default 0.05
       */
  
      /**
       * 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.
       *
       * @property timeScale
       * @type number
       * @default 1
       */
  
      /**
       * An `Object` that defines the rendering properties to be consumed by the module `Matter.Render`.
       *
       * @property render
       * @type object
       */
  
      /**
       * A flag that indicates if the body should be rendered.
       *
       * @property render.visible
       * @type boolean
       * @default true
       */
  
      /**
       * Sets the opacity to use when rendering.
       *
       * @property render.opacity
       * @type number
       * @default 1
      */
  
      /**
       * An `Object` that defines the sprite properties to use when rendering, if any.
       *
       * @property render.sprite
       * @type object
       */
  
      /**
       * An `String` that defines the path to the image to use as the sprite texture, if any.
       *
       * @property render.sprite.texture
       * @type string
       */
       
      /**
       * A `Number` that defines the scaling in the x-axis for the sprite, if any.
       *
       * @property render.sprite.xScale
       * @type number
       * @default 1
       */
  
      /**
       * A `Number` that defines the scaling in the y-axis for the sprite, if any.
       *
       * @property render.sprite.yScale
       * @type number
       * @default 1
       */
  
       /**
        * A `Number` that defines the offset in the x-axis for the sprite (normalised by texture width).
        *
        * @property render.sprite.xOffset
        * @type number
        * @default 0
        */
  
       /**
        * A `Number` that defines the offset in the y-axis for the sprite (normalised by texture height).
        *
        * @property render.sprite.yOffset
        * @type number
        * @default 0
        */
  
      /**
       * A `Number` that defines the line width to use when rendering the body outline (if a sprite is not defined).
       * A value of `0` means no outline will be rendered.
       *
       * @property render.lineWidth
       * @type number
       * @default 0
       */
  
      /**
       * A `String` that defines the fill style to use when rendering the body (if a sprite is not defined).
       * It is the same as when using a canvas, so it accepts CSS style property values.
       *
       * @property render.fillStyle
       * @type string
       * @default a random colour
       */
  
      /**
       * A `String` that defines the stroke style to use when rendering the body outline (if a sprite is not defined).
       * It is the same as when using a canvas, so it accepts CSS style property values.
       *
       * @property render.strokeStyle
       * @type string
       * @default a random colour
       */
  
      /**
       * An array of unique axis vectors (edge normals) used for collision detection.
       * These are automatically calculated from the given convex hull (`vertices` array) in `Body.create`.
       * They are constantly updated by `Body.update` during the simulation.
       *
       * @property axes
       * @type vector[]
       */
       
      /**
       * A `Number` that _measures_ the area of the body's convex hull, calculated at creation by `Body.create`.
       *
       * @property area
       * @type string
       * @default 
       */
  
      /**
       * A `Bounds` object that defines the AABB region for the body.
       * It is automatically calculated from the given convex hull (`vertices` array) in `Body.create` and constantly updated by `Body.update` during simulation.
       *
       * @property bounds
       * @type bounds
       */
  
  })();
  