code: function(e) {
          var type,
              lastEvent = Crafty.lastEvent;
  
          if (e.type === "touchstart") type = "mousedown";
          else if (e.type === "touchmove") type = "mousemove";
          else if (e.type === "touchend") type = "mouseup";
          else if (e.type === "touchcancel") type = "mouseup";
          else if (e.type === "touchleave") type = "mouseup";
          
          if(e.touches && e.touches.length) {
              first = e.touches[0];
          } else if(e.changedTouches && e.changedTouches.length) {
              first = e.changedTouches[0];
          }
  
          var simulatedEvent = document.createEvent("MouseEvent");
          simulatedEvent.initMouseEvent(type, true, true, window, 1,
              first.screenX, 
              first.screenY,
              first.clientX, 
              first.clientY, 
              false, false, false, false, 0, e.relatedTarget
          );
  
          first.target.dispatchEvent(simulatedEvent);
  
          // trigger click when it should be triggered
          if (lastEvent != null && lastEvent.type == 'mousedown' && type == 'mouseup') {
              type = 'click';
  
              var simulatedEvent = document.createEvent("MouseEvent");
              simulatedEvent.initMouseEvent(type, true, true, window, 1,
                  first.screenX, 
                  first.screenY,
                  first.clientX, 
                  first.clientY, 
                  false, false, false, false, 0, e.relatedTarget
              );
              first.target.dispatchEvent(simulatedEvent);
          }
  
          if(e.preventDefault) e.preventDefault();
          else e.returnValue = false;
      }
docs: @
  #Crafty.touchDispatch
  @category Input
  
  TouchEvents have a different structure then MouseEvents.
  The relevant data lives in e.changedTouches[0].
  To normalize TouchEvents we catch em and dispatch a mock MouseEvent instead.
  
  @see Crafty.mouseDispatch