text: (function() {
  
    var Vector = Two.Vector = function(x, y) {
  
      this.x = x || 0;
      this.y = y || 0;
  
    };
  
    _.extend(Vector, {
  
      zero: new Two.Vector()
  
    });
  
    _.extend(Vector.prototype, Backbone.Events, {
  
      set: function(x, y) {
        this.x = x;
        this.y = y;
        return this;
      },
  
      copy: function(v) {
        this.x = v.x;
        this.y = v.y;
        return this;
      },
  
      clear: function() {
        this.x = 0;
        this.y = 0;
        return this;
      },
  
      clone: function() {
        return new Vector(this.x, this.y);
      },
  
      add: function(v1, v2) {
        this.x = v1.x + v2.x;
        this.y = v1.y + v2.y;
        return this;
      },
  
      addSelf: function(v) {
        this.x += v.x;
        this.y += v.y;
        return this;
      },
  
      sub: function(v1, v2) {
        this.x = v1.x - v2.x;
        this.y = v1.y - v2.y;
        return this;
      },
  
      subSelf: function(v) {
        this.x -= v.x;
        this.y -= v.y;
        return this;
      },
  
      multiplySelf: function(v) {
        this.x *= v.x;
        this.y *= v.y;
        return this;
      },
  
      multiplyScalar: function(s) {
        this.x *= s;
        this.y *= s;
        return this;
      },
  
      divideScalar: function(s) {
        if (s) {
          this.x /= s;
          this.y /= s;
        } else {
          this.set(0, 0);
        }
        return this;
      },
  
      negate: function() {
        return this.multiplyScalar(-1);
      },
  
      dot: function(v) {
        return this.x * v.x + this.y * v.y;
      },
  
      lengthSquared: function() {
        return this.x * this.x + this.y * this.y;
      },
  
      length: function() {
        return Math.sqrt(this.lengthSquared());
      },
  
      normalize: function() {
        return this.divideScalar(this.length());
      },
  
      distanceTo: function(v) {
        return Math.sqrt(this.distanceToSquared(v));
      },
  
      distanceToSquared: function(v) {
        var dx = this.x - v.x, 
            dy = this.y - v.y;
        return dx * dx + dy * dy;
      },
  
      setLength: function(l) {
        return this.normalize().multiplyScalar(l);
      },
  
      equals: function(v) {
        return (this.distanceTo(v) < 0.0001 /* almost same position */);
      },
  
      lerp: function(v, t) {
        var x = (v.x - this.x) * t + this.x;
        var y = (v.y - this.y) * t + this.y;
        return this.set(x, y);
      },
  
      isZero: function() {
        return (this.length() < 0.0001 /* almost zero */ );
      },
  
      toString: function() {
        return this.x + ',' + this.y;
      },
  
      toObject: function() {
        return { x: this.x, y: this.y };
      }
  
    });
  
    var BoundProto = {
  
      set: function(x, y) {
        this._x = x;
        this._y = y;
        return this.trigger(Two.Events.change);
      },
  
      copy: function(v) {
        this._x = v.x;
        this._y = v.y;
        return this.trigger(Two.Events.change);
      },
  
      clear: function() {
        this._x = 0;
        this._y = 0;
        return this.trigger(Two.Events.change);
      },
  
      clone: function() {
        return new Vector(this._x, this._y);
      },
  
      add: function(v1, v2) {
        this._x = v1.x + v2.x;
        this._y = v1.y + v2.y;
        return this.trigger(Two.Events.change);
      },
  
      addSelf: function(v) {
        this._x += v.x;
        this._y += v.y;
        return this.trigger(Two.Events.change);
      },
  
      sub: function(v1, v2) {
        this._x = v1.x - v2.x;
        this._y = v1.y - v2.y;
        return this.trigger(Two.Events.change);
      },
  
      subSelf: function(v) {
        this._x -= v.x;
        this._y -= v.y;
        return this.trigger(Two.Events.change);
      },
  
      multiplySelf: function(v) {
        this._x *= v.x;
        this._y *= v.y;
        return this.trigger(Two.Events.change);
      },
  
      multiplyScalar: function(s) {
        this._x *= s;
        this._y *= s;
        return this.trigger(Two.Events.change);
      },
  
      divideScalar: function(s) {
        if (s) {
          this._x /= s;
          this._y /= s;
          return this.trigger(Two.Events.change);
        }
        return this.clear();
      },
  
      negate: function() {
        return this.multiplyScalar(-1);
      },
  
      dot: function(v) {
        return this._x * v.x + this._y * v.y;
      },
  
      lengthSquared: function() {
        return this._x * this._x + this._y * this._y;
      },
  
      length: function() {
        return Math.sqrt(this.lengthSquared());
      },
  
      normalize: function() {
        return this.divideScalar(this.length());
      },
  
      distanceTo: function(v) {
        return Math.sqrt(this.distanceToSquared(v));
      },
  
      distanceToSquared: function(v) {
        var dx = this._x - v.x,
            dy = this._y - v.y;
        return dx * dx + dy * dy;
      },
  
      setLength: function(l) {
        return this.normalize().multiplyScalar(l);
      },
  
      equals: function(v) {
        return (this.distanceTo(v) < 0.0001 /* almost same position */);
      },
  
      lerp: function(v, t) {
        var x = (v.x - this._x) * t + this._x;
        var y = (v.y - this._y) * t + this._y;
        return this.set(x, y);
      },
  
      isZero: function() {
        return (this.length() < 0.0001 /* almost zero */ );
      },
  
      toString: function() {
        return this._x + ',' + this._y;
      },
  
      toObject: function() {
        return { x: this._x, y: this._y };
      }
  
    };
  
    var xgs = {
      get: function() {
        return this._x;
      },
      set: function(v) {
        this._x = v;
        this.trigger(Two.Events.change, 'x');
      }
    };
  
    var ygs = {
      get: function() {
        return this._y;
      },
      set: function(v) {
        this._y = v;
        this.trigger(Two.Events.change, 'y');
      }
    };
  
    /**
     * Override Backbone bind / on in order to add properly broadcasting.
     * This allows Two.Vector to not broadcast events unless event listeners
     * are explicity bound to it.
     */
  
    Two.Vector.prototype.bind = Two.Vector.prototype.on = function() {
  
      if (!this._bound) {
        this._x = this.x;
        this._y = this.y;
        Object.defineProperty(this, 'x', xgs);
        Object.defineProperty(this, 'y', ygs);
        _.extend(this, BoundProto);
        this._bound = true; // Reserved for event initialization check
      }
  
      Backbone.Events.bind.apply(this, arguments);
  
      return this;
  
    };
  
  })();
  