function keyup($self, e) {
  if ($self.options.firingOnlyAtTarget && e.target !== $self.target && !$self.target.contains(e.target))
    return;
  var match;
  try {
    match = $self.options.exclude && e.target.matches($self.options.exclude)
  } catch (e) {
  }
  if (match)
    return;
  if ($self.options.preventDefault)
    e.preventDefault();
  else if ($self.options.preventDefaultOnMeta &&
    (e.altKey ||
      e.ctrlKey ||
      e.shiftKey ||
      e.metaKey)
  )
    e.preventDefault();
  if (e.ctrlKey || e.metaKey)
    switch (e.key) {
      case "c":
      case "C":
        $self.events.dispatch("copy", e);
        break;
      case "v":
      case "V":
        $self.events.dispatch("paste", e);
        break;
      case "x":
      case "X":
        $self.events.dispatch("cut", e);
        break;
      case "y":
      case "Y":
        $self.events.dispatch("redo", e);
        break;
      case "z":
      case "Z":
        $self.events.dispatch("undo", e);
        break;
      default:
        break;
    }
  if (e.altKey)
    switch (e.key) {
      case "ArrowLeft":
        $self.events.dispatch("redo", e);
        break;
      case "ArrowRight":
        $self.events.dispatch("undo", e);
        break;
      default:
        break;
    }
  if (!e.altKey && !e.ctrlKey)
    switch (e.key) {
      case "Delete":
        $self.events.dispatch("delete", e);
        break;
      case "Enter":
        $self.events.dispatch("enter", e);
        break;
      case "Tab":
        $self.events.dispatch("tab", e);
        break;
      case "Backspace":
        $self.events.dispatch("backspace", e);
      default:
        break;
    }
  $self.events.dispatch("up", e);
}