var shift = false;
var down = 0;
var button = 0;
var drag = false;
var prev;

// Get objects by mouse position
function get_objs(e) {
  var rect = e.target.getBoundingClientRect();
  var mouseX = e.clientX - rect.left;
  var mouseY = e.clientY - rect.top;
  mouseX = (mouseX / w) * 2 - 1;
  mouseY = -(mouseY / h) * 2 + 1;
  var pos = new THREE.Vector3(mouseX, mouseY, 1);
  pos.unproject(camera);
  var ray = new THREE.Raycaster(camera.position, pos.sub(camera.position).normalize());
  return ray.intersectObjects(models);
}

window.addEventListener("click", function(e) {
  if (!drag && e.button == 0) {
    var objs = get_objs(e);
    if (!shift) {
      control.detach();
    }
    if (objs.length > 0) {
      control.attach(objs[0].object);
    }
  }
}, false);

window.addEventListener('keydown', function(e) {
  down = e.keyCode;
  switch ( event.keyCode ) {
    case 81: // Q
      control.setSpace( control.space === "local" ? "world" : "local" );
      break;
    case 16: // shift
      shift = true;
      break;
    case 17: // Ctrl
      control.setTranslationSnap( 100 );
      control.setRotationSnap( THREE.Math.degToRad( 15 ) );
      break;
    case 87: // W
      control.setMode( "translate" );
      break;
    case 69: // E
      control.setMode( "rotate" );
      break;
    case 82: // R
      control.setMode( "scale" );
      break;
    case 187:
    case 107: // +, =, num+
      control.setSize( control.size + 0.1 );
      break;
    case 189:
    case 109: // -, _, num-
      control.setSize( Math.max( control.size - 0.1, 0.1 ) );
      break;
  }
}, false);

window.addEventListener('keyup',   function(e) {
  down = 0;
  switch ( event.keyCode ) {
    case 16: // shift
      shift = false;
      break;
    case 17: // Ctrl
      control.setTranslationSnap( null );
      control.setRotationSnap( null );
      break;
  }
}, false);

window.addEventListener('mousedown', function(e) {
  prev = new THREE.Vector2(e.offsetX, e.offsetY);
  button = e.button;
}, false);

window.addEventListener('mouseup',   function(e) {
  button = -1;
  delete prev;
}, false);

window.addEventListener("mousemove", function(e) {
  if (button >= 0) {
    var curr = new THREE.Vector2(e.offsetX, e.offsetY);
    var dist = typeof(prev) != 'undefined' ? curr.distanceTo(prev) : 0;
    drag = dist > 2;
  }
  else {
    drag = false;
  }
}, false);


@@ -15,66 +15,8 @@
 lse;
-%0Avar down = 0;%0Avar button = 0;%0Avar drag = false;%0Avar prev;
 %0A%0A//
@@ -467,248 +467,21 @@
 %0A%7D%0A%0A
-window.addEventListener(%22click%22, function(e) %7B%0A  if (!drag && e.button == 0) %7B%0A    var objs = get_objs(e);%0A    if (!shift) %7B%0A      control.detach();%0A    %7D%0A    if (objs.length %3E 0) %7B%0A      control.attach(objs%5B0%5D.object);%0A    %7D%0A  %7D%0A%7D, false);
+// Key events
 %0A%0Awi
@@ -1572,32 +1572,68 @@
   %7D%0A%7D, false);%0A%0A
+// Mouse events%0A%0Avar down = false;%0A%0A
 window.addEventL
@@ -1673,75 +1673,19 @@
 %7B%0A  
-prev = new THREE.Vector2(e.offsetX, e.offsetY);%0A  button = e.button
+down = true
 ;%0A%7D,
@@ -1722,20 +1722,20 @@
 ner(
-'
+%22
 mouse
-up',  
+move%22,
  fun
@@ -1751,34 +1751,19 @@
 %7B%0A  
-button = -1;%0A  delete prev
+drag = down
 ;%0A%7D,
@@ -1792,36 +1792,36 @@
 entListener(
-%22
+'
 mouse
-move%22,
+up',  
  function(e)
@@ -1833,193 +1833,182 @@
 if (
-button %3E= 0) %7B%0A    var curr = new THREE.Vector2(e.offsetX, e.offsetY);%0A    var dist = typeof(prev) != 'undefined' ? curr.distanceTo(prev) : 0;%0A    drag = dist %3E 2;%0A  %7D%0A  else %7B
+!drag && down) %7B%0A    var objs = get_objs(e);%0A    if (!shift) %7B%0A      control.detach();%0A    %7D%0A    if (objs.length %3E 0) %7B%0A      control.attach(objs%5B0%5D.object);%0A    %7D
 %0A  
+%7D%0A
   d
-rag
+own
  = f
@@ -2013,20 +2013,16 @@
  false;%0A
-  %7D%0A
 %7D, false

Fix selection.