text: pc.extend(pc, function () {
      'use strict';
  
      /**
       * @private
       * @constructor
       * @name pc.TextureAtlas
       * @classdesc A pc.TextureAtlas contains a number of frames from a texture. Each frame defines a region in
       * a texture. The pc.TextureAtlas is referenced by {@link pc.Sprite}s.
       * @property {pc.Texture} texture The texture atlas.
       * @property {Object} frames Contains frames which define portions of the texture atlas.
       * @example
       * var atlas = new pc.TextureAtlas();
       * atlas.frames = {
       *   '0': {
       *       // rect has u, v, width and height in pixels
       *       rect: new pc.Vec4(0, 0, 256, 256),
       *       // pivot has x, y values between 0-1 which define the point
       *       // within the frame around which rotation and scale is calculated
       *       pivot: new pc.Vec2(0.5, 0.5),
       * .      // border has left, bottom, right and top in pixels defining regions for 9-slicing
       * .      border: new pc.Vec4(5, 5, 5, 5)
       *   },
       *   '1': {
       *       rect: new pc.Vec4(256, 0, 256, 256),
       *       pivot: new pc.Vec2(0.5, 0.5),
       *       border: new pc.Vec4(5, 5, 5, 5)
       *   },
       *   ...
       * };
       */
      var TextureAtlas = function () {
          this._texture = null;
          this._frames = null;
          pc.events.attach(this);
      };
  
      /**
       * @private
       * @name pc.TextureAtlas#setFrame
       * @param {String} key The key of the frame.
       * @param {Object} data The properties of the frame.
       * @param {pc.Vec4} [data.rect] The u, v, width, height properties of the frame in pixels.
       * @param {pc.Vec2} [data.pivot] The pivot of the frame - values are between 0-1.
       * @param {pc.Vec4} [data.border] The border of the frame for 9-slicing. Values are left, bottom, right, top border in pixels.
       * @example
       * atlas.setFrame('1', {
       *    rect: new pc.Vec4(0,0,128,128),
       *    pivot: new pc.Vec2(0.5, 0.5),
       *    border: new pc.Vec4(5, 5, 5, 5)
       * });
       */
      TextureAtlas.prototype.setFrame = function (key, data) {
          var frame = this._frames[key];
          if (! frame) {
              frame = {
                  rect: data.rect.clone(),
                  pivot: data.pivot.clone(),
                  border: data.border.clone()
              };
              this._frames[key] = frame;
          } else {
              frame.rect.copy(data.rect);
              frame.pivot.copy(data.pivot);
              frame.border.copy(data.border);
          }
  
          this.fire('set:frame', key.toString(), frame);
      };
  
      /**
       * @private
       * @name pc.TextureAtlas#removeFrame
       * @param {String} key The key of the frame.
       * @example
       * atlas.removeFrame('1');
       */
      TextureAtlas.prototype.removeFrame = function (key) {
          var frame = this._frames[key];
          if (frame) {
              delete this._frames[key];
              this.fire('remove:frame', key.toString(), frame);
          }
      };
  
      /**
       * @private
       * @function
       * @name pc.TextureAtlas#destroy
       * @description Free up the underlying WebGL resource owned by the texture.
       */
      TextureAtlas.prototype.destroy = function () {
          if (this._texture) {
              this._texture.destroy();
          }
      };
  
      Object.defineProperty(TextureAtlas.prototype, 'texture', {
          get: function () {
              return this._texture;
          },
          set: function (value) {
              this._texture = value;
              this.fire('set:texture', value);
          }
      });
  
      Object.defineProperty(TextureAtlas.prototype, 'frames', {
          get: function () {
              return this._frames;
          },
          set: function (value) {
              this._frames = value;
              this.fire('set:frames', value);
          }
      });
  
      return {
          TextureAtlas: TextureAtlas
      };
  }());
  