docs: function (e) {
  		
  		if (!Crafty.mouseObjs) return;
  		Crafty.lastEvent = e;
  
  		var maxz = -1,
  			closest,
  			q,
  			i = 0, l,
  			pos = Crafty.DOM.translate(e.clientX, e.clientY),
  			x, y,
  			dupes = {},
  			tar = e.target ? e.target : e.srcElement,
  			type = e.type;
  
  		//Normalize button according to http://unixpapa.com/js/mouse.html
  		if (e.which == null) {
  			e.mouseButton = (e.button < 2) ? Crafty.mouseButtons.LEFT : ((e.button == 4) ? Crafty.mouseButtons.MIDDLE : Crafty.mouseButtons.RIGHT);
  		} else {
  			e.mouseButton = (e.which < 2) ? Crafty.mouseButtons.LEFT : ((e.which == 2) ? Crafty.mouseButtons.MIDDLE : Crafty.mouseButtons.RIGHT);
  		}
  
  		e.realX = x = Crafty.mousePos.x = pos.x;
  		e.realY = y = Crafty.mousePos.y = pos.y;
  
  		//if it's a DOM element with Mouse component we are done
  		if (tar.nodeName != "CANVAS") {
  			while (typeof (tar.id) != 'string' && tar.id.indexOf('ent') == -1) {
  				tar = tar.parentNode;
  			}
  			ent = Crafty(parseInt(tar.id.replace('ent', '')))
  			if (ent.has('Mouse') && ent.isAt(x, y))
  				closest = ent;
  		}
  		//else we search for an entity with Mouse component
  		if (!closest) {
  			q = Crafty.map.search({ _x: x, _y: y, _w: 1, _h: 1 }, false);
  
  			for (l = q.length; i < l; ++i) {
  				if (!q[i].__c.Mouse || !q[i]._visible) continue;
  
  				var current = q[i],
  					flag = false;
  
  				//weed out duplicates
  				if (dupes[current[0]]) continue;
  				else dupes[current[0]] = true;
  
  				if (current.mapArea) {
  					if (current.mapArea.containsPoint(x, y)) {
  						flag = true;
  					}
  				} else if (current.isAt(x, y)) flag = true;
  
  				if (flag && (current._z >= maxz || maxz === -1)) {
  					//if the Z is the same, select the closest GUID
  					if (current._z === maxz && current[0] < closest[0]) {
  						continue;
  					}
  					maxz = current._z;
  					closest = current;
  				}
  			}
  		}
  
  		//found closest object to mouse
  		if (closest) {
  			//click must mousedown and out on tile
  			if (type === "mousedown") {
  				closest.trigger("MouseDown", e);
              } else if (type === "mouseup") {
  				closest.trigger("MouseUp", e);
  			} else if (type == "dblclick") {
  				closest.trigger("DoubleClick", e);
  			} else if (type == "click") {
  				closest.trigger("Click", e);
  			}else if (type === "mousemove") {
  				closest.trigger("MouseMove", e);
  				if (this.over !== closest) { //if new mousemove, it is over
  					if (this.over) {
  						this.over.trigger("MouseOut", e); //if over wasn't null, send mouseout
  						this.over = null;
  					}
  					this.over = closest;
  					closest.trigger("MouseOver", e);
  				}
  			} else closest.trigger(type, e); //trigger whatever it is
  		} else {
  			if (type === "mousemove" && this.over) {
  				this.over.trigger("MouseOut", e);
  				this.over = null;
  			}
  			if (type === "mousedown") {
  				Crafty.viewport.mouselook('start', e);
  			}
  			else if (type === "mousemove") {
  				Crafty.viewport.mouselook('drag', e);
  			}
  			else if (type == "mouseup") {
  				Crafty.viewport.mouselook('stop');
  			}
  		}
  
  		if (type === "mousemove") {
  			this.lastEvent = e;
  		}
  
  	}