text: /**
  * @author       Mat Groves http://matgroves.com @Doormat23
  * @author       Richard Davey <rich@photonstorm.com>
  * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
  */
  
  /**
  * The base class for all objects that are rendered. Contains properties for position, scaling,
  * rotation, masks and cache handling.
  * 
  * This is an abstract class and should not be used on its own, rather it should be extended.
  *
  * It is used internally by the likes of PIXI.Sprite.
  *
  * @class DisplayObject
  * @constructor
  */
  PIXI.DisplayObject = function () {
  
      /**
      * The coordinates, in pixels, of this DisplayObject, relative to its parent container.
      * 
      * The value of this property does not reflect any positioning happening further up the display list.
      * To obtain that value please see the `worldPosition` property.
      * 
      * @property {PIXI.Point} position
      * @default
      */
      this.position = new PIXI.Point(0, 0);
  
      /**
      * The scale of this DisplayObject. A scale of 1:1 represents the DisplayObject
      * at its default size. A value of 0.5 would scale this DisplayObject by half, and so on.
      * 
      * The value of this property does not reflect any scaling happening further up the display list.
      * To obtain that value please see the `worldScale` property.
      * 
      * @property {PIXI.Point} scale
      * @default
      */
      this.scale = new PIXI.Point(1, 1);
  
      /**
      * The pivot point of this DisplayObject that it rotates around. The values are expressed
      * in pixel values.
      * @property {PIXI.Point} pivot
      * @default
      */
      this.pivot = new PIXI.Point(0, 0);
  
      /**
      * The rotation of this DisplayObject. The value is given, and expressed, in radians, and is based on
      * a right-handed orientation.
      * 
      * The value of this property does not reflect any rotation happening further up the display list.
      * To obtain that value please see the `worldRotation` property.
      * 
      * @property {number} rotation
      * @default
      */
      this.rotation = 0;
  
      /**
      * The alpha value of this DisplayObject. A value of 1 is fully opaque. A value of 0 is transparent.
      * Please note that an object with an alpha value of 0 is skipped during the render pass.
      * 
      * The value of this property does not reflect any alpha values set further up the display list.
      * To obtain that value please see the `worldAlpha` property.
      * 
      * @property {number} alpha
      * @default
      */
      this.alpha = 1;
  
      /**
      * The visibility of this DisplayObject. A value of `false` makes the object invisible.
      * A value of `true` makes it visible. Please note that an object with a visible value of
      * `false` is skipped during the render pass. Equally a DisplayObject with visible false will
      * not render any of its children.
      * 
      * The value of this property does not reflect any visible values set further up the display list.
      * To obtain that value please see the `worldVisible` property.
      * 
      * @property {boolean} visible
      * @default
      */
      this.visible = true;
  
      /**
       * This is the defined area that will pick up mouse / touch events. It is null by default.
       * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children)
       *
       * @property hitArea
       * @type Rectangle|Circle|Ellipse|Polygon
       */
      this.hitArea = null;
  
      /**
      * Should this DisplayObject be rendered by the renderer? An object with a renderable value of
      * `false` is skipped during the render pass.
      * 
      * @property {boolean} renderable
      * @default
      */
      this.renderable = false;
  
      /**
      * The parent DisplayObjectContainer that this DisplayObject is a child of.
      * All DisplayObjects must belong to a parent in order to be rendered.
      * The root parent is the Stage object. This property is set automatically when the
      * DisplayObject is added to, or removed from, a DisplayObjectContainer.
      * 
      * @property {PIXI.DisplayObjectContainer} parent
      * @default
      * @readOnly
      */
      this.parent = null;
  
      /**
      * The multiplied alpha value of this DisplayObject. A value of 1 is fully opaque. A value of 0 is transparent.
      * This value is the calculated total, based on the alpha values of all parents of this DisplayObjects 
      * in the display list.
      * 
      * To obtain, and set, the local alpha value, see the `alpha` property.
      *
      * Note: This property is only updated at the end of the `updateTransform` call, once per render. Until 
      * that happens this property will contain values based on the previous frame. Be mindful of this if
      * accessing this property outside of the normal game flow, i.e. from an asynchronous event callback.
      * 
      * @property {number} worldAlpha
      * @readOnly
      */
      this.worldAlpha = 1;
  
      /**
      * The current transform of this DisplayObject.
      * 
      * This property contains the calculated total, based on the transforms of all parents of this 
      * DisplayObject in the display list.
      *
      * Note: This property is only updated at the end of the `updateTransform` call, once per render. Until 
      * that happens this property will contain values based on the previous frame. Be mindful of this if
      * accessing this property outside of the normal game flow, i.e. from an asynchronous event callback.
      *
      * @property {PIXI.Matrix} worldTransform
      * @readOnly
      */
      this.worldTransform = new PIXI.Matrix();
  
      /**
      * The coordinates, in pixels, of this DisplayObject within the world.
      * 
      * This property contains the calculated total, based on the positions of all parents of this 
      * DisplayObject in the display list.
      *
      * Note: This property is only updated at the end of the `updateTransform` call, once per render. Until 
      * that happens this property will contain values based on the previous frame. Be mindful of this if
      * accessing this property outside of the normal game flow, i.e. from an asynchronous event callback.
      * 
      * @property {PIXI.Point} worldPosition
      * @readOnly
      */
      this.worldPosition = new PIXI.Point(0, 0);
  
      /**
      * The global scale of this DisplayObject.
      * 
      * This property contains the calculated total, based on the scales of all parents of this 
      * DisplayObject in the display list.
      *
      * Note: This property is only updated at the end of the `updateTransform` call, once per render. Until 
      * that happens this property will contain values based on the previous frame. Be mindful of this if
      * accessing this property outside of the normal game flow, i.e. from an asynchronous event callback.
      * 
      * @property {PIXI.Point} worldScale
      * @readOnly
      */
      this.worldScale = new PIXI.Point(1, 1);
  
      /**
      * The rotation, in radians, of this DisplayObject.
      * 
      * This property contains the calculated total, based on the rotations of all parents of this 
      * DisplayObject in the display list.
      *
      * Note: This property is only updated at the end of the `updateTransform` call, once per render. Until 
      * that happens this property will contain values based on the previous frame. Be mindful of this if
      * accessing this property outside of the normal game flow, i.e. from an asynchronous event callback.
      * 
      * @property {number} worldRotation
      * @readOnly
      */
      this.worldRotation = 0;
  
      /**
      * The rectangular area used by filters when rendering a shader for this DisplayObject.
      *
      * @property {PIXI.Rectangle} filterArea
      * @type Rectangle
      * @default
      */
      this.filterArea = null;
  
      /**
      * @property {number} _sr - Cached rotation value.
      * @private
      */
      this._sr = 0;
  
      /**
      * @property {number} _cr - Cached rotation value.
      * @private
      */
      this._cr = 1;
  
      /**
      * @property {PIXI.Rectangle} _bounds - The cached bounds of this object.
      * @private
      */
      this._bounds = new PIXI.Rectangle(0, 0, 0, 0);
  
      /**
      * @property {PIXI.Rectangle} _currentBounds - The most recently calculated bounds of this object.
      * @private
      */
      this._currentBounds = null;
  
      /**
      * @property {PIXI.Rectangle} _mask - The cached mask of this object.
      * @private
      */
      this._mask = null;
  
      /**
      * @property {boolean} _cacheAsBitmap - Internal cache as bitmap flag.
      * @private
      */
      this._cacheAsBitmap = false;
  
      /**
      * @property {boolean} _cacheIsDirty - Internal dirty cache flag.
      * @private
      */
      this._cacheIsDirty = false;
  
  };
  
  PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
  
  PIXI.DisplayObject.prototype = {
  
      /**
      * Destroy this DisplayObject.
      *
      * Removes any cached sprites, sets renderable flag to false, and nulls filters, bounds and mask.
      *
      * Also iteratively calls `destroy` on any children.
      *
      * @method PIXI.DisplayObject#destroy
      */
      destroy: function () {
  
          if (this.children)
          {
              var i = this.children.length;
  
              while (i--)
              {
                  this.children[i].destroy();
              }
  
              this.children = [];
          }
  
          this.hitArea = null;
          this.parent = null;
          this.worldTransform = null;
          this.filterArea = null;
          this.renderable = false;
  
          this._bounds = null;
          this._currentBounds = null;
          this._mask = null;
  
          this._destroyCachedSprite();
  
      },
  
      /*
      * Updates the transform matrix this DisplayObject uses for rendering.
      *
      * If the object has no parent, and no parent parameter is provided, it will default to 
      * Phaser.Game.World as the parent transform to use. If that is unavailable the transform fails to take place.
      *
      * The `parent` parameter has priority over the actual parent. Use it as a parent override.
      * Setting it does **not** change the actual parent of this DisplayObject.
      *
      * Calling this method updates the `worldTransform`, `worldAlpha`, `worldPosition`, `worldScale` 
      * and `worldRotation` properties.
      *
      * If a `transformCallback` has been specified, it is called at the end of this method, and is passed
      * the new, updated, worldTransform property, along with the parent transform used.
      *
      * @method PIXI.DisplayObject#updateTransform
      * @param {PIXI.DisplayObjectContainer} [parent] - Optional parent to calculate this DisplayObjects transform from.
      * @return {PIXI.DisplayObject} - A reference to this DisplayObject.
      */
      updateTransform: function (parent) {
  
          if (!parent && !this.parent && !this.game)
          {
              return this;
          }
  
          var p = this.parent;
  
          if (parent)
          {
              p = parent;
          }
          else if (!this.parent)
          {
              p = this.game.world;
          }
  
          // create some matrix refs for easy access
          var pt = p.worldTransform;
          var wt = this.worldTransform;
  
          // temporary matrix variables
          var a, b, c, d, tx, ty;
  
          // so if rotation is between 0 then we can simplify the multiplication process..
          if (this.rotation % Phaser.Math.PI2)
          {
              // check to see if the rotation is the same as the previous render. This means we only need to use sin and cos when rotation actually changes
              if (this.rotation !== this.rotationCache)
              {
                  this.rotationCache = this.rotation;
                  this._sr = Math.sin(this.rotation);
                  this._cr = Math.cos(this.rotation);
              }
  
              // get the matrix values of the displayobject based on its transform properties..
              a  =  this._cr * this.scale.x;
              b  =  this._sr * this.scale.x;
              c  = -this._sr * this.scale.y;
              d  =  this._cr * this.scale.y;
              tx =  this.position.x;
              ty =  this.position.y;
              
              // check for pivot.. not often used so geared towards that fact!
              if (this.pivot.x || this.pivot.y)
              {
                  tx -= this.pivot.x * a + this.pivot.y * c;
                  ty -= this.pivot.x * b + this.pivot.y * d;
              }
  
              // concat the parent matrix with the objects transform.
              wt.a  = a  * pt.a + b  * pt.c;
              wt.b  = a  * pt.b + b  * pt.d;
              wt.c  = c  * pt.a + d  * pt.c;
              wt.d  = c  * pt.b + d  * pt.d;
              wt.tx = tx * pt.a + ty * pt.c + pt.tx;
              wt.ty = tx * pt.b + ty * pt.d + pt.ty;
          }
          else
          {
              // lets do the fast version as we know there is no rotation..
              a  = this.scale.x;
              d  = this.scale.y;
  
              tx = this.position.x - this.pivot.x * a;
              ty = this.position.y - this.pivot.y * d;
  
              wt.a  = a  * pt.a;
              wt.b  = a  * pt.b;
              wt.c  = d  * pt.c;
              wt.d  = d  * pt.d;
              wt.tx = tx * pt.a + ty * pt.c + pt.tx;
              wt.ty = tx * pt.b + ty * pt.d + pt.ty;
          }
  
          //  Set the World values
          this.worldAlpha = this.alpha * p.worldAlpha;
          this.worldPosition.set(wt.tx, wt.ty);
          this.worldScale.set(this.scale.x * Math.sqrt(wt.a * wt.a + wt.c * wt.c), this.scale.y * Math.sqrt(wt.b * wt.b + wt.d * wt.d));
          this.worldRotation = Math.atan2(-wt.c, wt.d);
  
          // reset the bounds each time this is called!
          this._currentBounds = null;
  
          //  Custom callback?
          if (this.transformCallback)
          {
              this.transformCallback.call(this.transformCallbackContext, wt, pt);
          }
  
          return this;
  
      },
  
      /**
      * To be overridden by classes that require it.
      *
      * @method PIXI.DisplayObject#preUpdate
      */
      preUpdate: function () {
  
      },
  
      /**
      * Generates a RenderTexture based on this DisplayObject, which can they be used to texture other Sprites.
      * This can be useful if your DisplayObject is static, or complicated, and needs to be reused multiple times.
      *
      * Please note that no garbage collection takes place on old textures. It is up to you to destroy old textures,
      * and references to them, so they don't linger in memory.
      *
      * @method PIXI.DisplayObject#generateTexture
      * @param {number} [resolution=1] - The resolution of the texture being generated.
      * @param {number} [scaleMode=PIXI.scaleModes.DEFAULT] - See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values.
      * @param {PIXI.CanvasRenderer|PIXI.WebGLRenderer} renderer - The renderer used to generate the texture.
      * @return {Phaser.RenderTexture} - A RenderTexture containing an image of this DisplayObject at the time it was invoked.
      */
      generateTexture: function (resolution, scaleMode, renderer) {
  
          var bounds = this.getLocalBounds();
  
          var renderTexture = new Phaser.RenderTexture(this.game, bounds.width | 0, bounds.height | 0, renderer, scaleMode, resolution);
          
          PIXI.DisplayObject._tempMatrix.tx = -bounds.x;
          PIXI.DisplayObject._tempMatrix.ty = -bounds.y;
          
          renderTexture.render(this, PIXI.DisplayObject._tempMatrix);
  
          return renderTexture;
  
      },
  
      /**
      * If this DisplayObject has a cached Sprite, this method generates and updates it.
      *
      * @method PIXI.DisplayObject#updateCache
      * @return {PIXI.DisplayObject} - A reference to this DisplayObject.
      */
      updateCache: function () {
  
          this._generateCachedSprite();
  
          return this;
  
      },
  
      /**
      * Calculates the global position of this DisplayObject, based on the position given.
      *
      * @method PIXI.DisplayObject#toGlobal
      * @param {PIXI.Point} position - The global position to calculate from.
      * @return {PIXI.Point} - A point object representing the position of this DisplayObject based on the global position given.
      */
      toGlobal: function (position) {
  
          this.updateTransform();
  
          return this.worldTransform.apply(position);
  
      },
  
      /**
      * Calculates the local position of this DisplayObject, relative to another point.
      *
      * @method PIXI.DisplayObject#toLocal
      * @param {PIXI.Point} position - The world origin to calculate from.
      * @param {PIXI.DisplayObject} [from] - An optional DisplayObject to calculate the global position from.
      * @return {PIXI.Point} - A point object representing the position of this DisplayObject based on the global position given.
      */
      toLocal: function (position, from) {
  
          if (from)
          {
              position = from.toGlobal(position);
          }
  
          this.updateTransform();
  
          return this.worldTransform.applyInverse(position);
  
      },
  
      /**
      * Internal method.
      *
      * @method PIXI.DisplayObject#_renderCachedSprite
      * @private
      * @param {Object} renderSession - The render session
      */
      _renderCachedSprite: function (renderSession) {
  
          this._cachedSprite.worldAlpha = this.worldAlpha;
  
          if (renderSession.gl)
          {
              PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession);
          }
          else
          {
              PIXI.Sprite.prototype._renderCanvas.call(this._cachedSprite, renderSession);
          }
  
      },
  
      /**
      * Internal method.
      *
      * @method PIXI.DisplayObject#_generateCachedSprite
      * @private
      */
      _generateCachedSprite: function () {
  
          this._cacheAsBitmap = false;
  
          var bounds = this.getLocalBounds();
  
          //  Round it off and force non-zero dimensions
          bounds.width = Math.max(1, Math.ceil(bounds.width));
          bounds.height = Math.max(1, Math.ceil(bounds.height));
  
          this.updateTransform();
  
          if (!this._cachedSprite)
          {
              var textureUnit = 0;
              if (this.texture && this.texture.baseTexture && PIXI._enableMultiTextureToggle)
                  textureUnit = this.texture.baseTexture.textureIndex;
              var renderTexture = new Phaser.RenderTexture(bounds.width, bounds.height, null, null, null, textureUnit);
              this._cachedSprite = new PIXI.Sprite(renderTexture);
              this._cachedSprite.worldTransform = this.worldTransform;
          }
          else
          {
              this._cachedSprite.texture.resize(bounds.width, bounds.height);
          }
  
          //  Remove filters
          var tempFilters = this._filters;
  
          this._filters = null;
          this._cachedSprite.filters = tempFilters;
  
          PIXI.DisplayObject._tempMatrix.tx = -bounds.x;
          PIXI.DisplayObject._tempMatrix.ty = -bounds.y;
          this._cachedSprite.texture.render(this, PIXI.DisplayObject._tempMatrix, true);
          this._cachedSprite.anchor.x = -(bounds.x / bounds.width);
          this._cachedSprite.anchor.y = -(bounds.y / bounds.height);
  
          this._filters = tempFilters;
  
          this._cacheAsBitmap = true;
  
      },
  
      /**
      * Destroys a cached Sprite.
      *
      * @method PIXI.DisplayObject#_destroyCachedSprite
      * @private
      */
      _destroyCachedSprite: function () {
  
          if (!this._cachedSprite)
          {
              return;
          }
  
          this._cachedSprite.texture.destroy(true);
  
          this._cachedSprite = null;
  
      }
  
  };
  
  //  Alias for updateTransform. As used in DisplayObject container, etc.
  PIXI.DisplayObject.prototype.displayObjectUpdateTransform = PIXI.DisplayObject.prototype.updateTransform;
  
  Object.defineProperties(PIXI.DisplayObject.prototype, {
  
      /**
      * The horizontal position of the DisplayObject, in pixels, relative to its parent.
      * If you need the world position of the DisplayObject, use `DisplayObject.worldPosition` instead.
      * @name PIXI.DisplayObject#x
      * @property {number} x - The horizontal position of the DisplayObject, in pixels, relative to its parent.
      */
      'x': {
  
          get: function () {
  
              return this.position.x;
  
          },
  
          set: function (value) {
  
              this.position.x = value;
  
          }
  
      },
  
      /**
      * The vertical position of the DisplayObject, in pixels, relative to its parent.
      * If you need the world position of the DisplayObject, use `DisplayObject.worldPosition` instead.
      * @name PIXI.DisplayObject#y
      * @property {number} y - The vertical position of the DisplayObject, in pixels, relative to its parent.
      */
      'y': {
  
          get: function () {
  
              return this.position.y;
  
          },
  
          set: function (value) {
  
              this.position.y = value;
  
          }
  
      },
  
      /**
      * Indicates if this DisplayObject is visible, based on it, and all of its parents, `visible` property values.
      * @name PIXI.DisplayObject#worldVisible
      * @property {boolean} worldVisible - Indicates if this DisplayObject is visible, based on it, and all of its parents, `visible` property values.
      */
      'worldVisible': {
  
          get: function () {
  
              if (!this.visible)
              {
                  return false;
              }
              else
              {
                  var item = this.parent;
  
                  if (!item)
                  {
                      return this.visible;
                  }
                  else
                  {
                      do
                      {
                          if (!item.visible)
                          {
                              return false;
                          }
  
                          item = item.parent;
                      }
                      while (item);
  
                  }
  
                  return true;
              }
  
          }
  
      },
  
      /**
      * Sets a mask for this DisplayObject. A mask is an instance of a Graphics object.
      * When applied it limits the visible area of this DisplayObject to the shape of the mask.
      * Under a Canvas renderer it uses shape clipping. Under a WebGL renderer it uses a Stencil Buffer.
      * To remove a mask, set this property to `null`.
      * 
      * @name PIXI.DisplayObject#mask
      * @property {PIXI.Graphics} mask - The mask applied to this DisplayObject. Set to `null` to remove an existing mask.
      */
      'mask': {
  
          get: function () {
  
              return this._mask;
  
          },
  
          set: function (value) {
  
              if (this._mask)
              {
                  this._mask.isMask = false;
              }
  
              this._mask = value;
  
              if (value)
              {
                  this._mask.isMask = true;
              }
  
          }
  
      },
  
      /**
      * Sets the filters for this DisplayObject. This is a WebGL only feature, and is ignored by the Canvas
      * Renderer. A filter is a shader applied to this DisplayObject. You can modify the placement of the filter
      * using `DisplayObject.filterArea`.
      * 
      * To remove filters, set this property to `null`.
      *
      * Note: You cannot have a filter set, and a MULTIPLY Blend Mode active, at the same time. Setting a 
      * filter will reset this DisplayObjects blend mode to NORMAL.
      * 
      * @name PIXI.DisplayObject#filters
      * @property {Array} filters - An Array of Phaser.Filter objects, or objects that extend them.
      */
      'filters': {
  
          get: function () {
  
              return this._filters;
  
          },
  
          set: function (value) {
  
              if (Array.isArray(value))
              {
                  //  Put all the passes in one place.
                  var passes = [];
  
                  for (var i = 0; i < value.length; i++)
                  {
                      var filterPasses = value[i].passes;
  
                      for (var j = 0; j < filterPasses.length; j++)
                      {
                          passes.push(filterPasses[j]);
                      }
                  }
  
                  //  Needed any more?
                  this._filterBlock = { target: this, filterPasses: passes };
              }
  
              this._filters = value;
  
              if (this.blendMode && this.blendMode === PIXI.blendModes.MULTIPLY)
              {
                  this.blendMode = PIXI.blendModes.NORMAL;
              }
  
          }
  
      },
  
      /**
      * Sets if this DisplayObject should be cached as a bitmap.
      *
      * When invoked it will take a snapshot of the DisplayObject, as it is at that moment, and store it 
      * in a RenderTexture. This is then used whenever this DisplayObject is rendered. It can provide a
      * performance benefit for complex, but static, DisplayObjects. I.e. those with lots of children.
      *
      * Cached Bitmaps do not track their parents. If you update a property of this DisplayObject, it will not
      * re-generate the cached bitmap automatically. To do that you need to call `DisplayObject.updateCache`.
      * 
      * To remove a cached bitmap, set this property to `null`.
      * 
      * @name PIXI.DisplayObject#cacheAsBitmap
      * @property {boolean} cacheAsBitmap - Cache this DisplayObject as a Bitmap. Set to `null` to remove an existing cached bitmap.
      */
      'cacheAsBitmap': {
  
          get: function () {
  
              return this._cacheAsBitmap;
  
          },
  
          set: function (value) {
  
              if (this._cacheAsBitmap === value)
              {
                  return;
              }
  
              if (value)
              {
                  this._generateCachedSprite();
              }
              else
              {
                  this._destroyCachedSprite();
              }
  
              this._cacheAsBitmap = value;
  
          }
  
      }
  
  });
  