text: //     Zepto.js
  //     (c) 2010-2012 Thomas Fuchs
  //     Zepto.js may be freely distributed under the MIT license.
  
  ;(function($){
    var $$ = $.zepto.qsa, handlers = {}, _zid = 1, specialEvents={}
  
    specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'
  
    function zid(element) {
      return element._zid || (element._zid = _zid++)
    }
    function findHandlers(element, event, fn, selector) {
      event = parse(event)
      if (event.ns) var matcher = matcherFor(event.ns)
      return (handlers[zid(element)] || []).filter(function(handler) {
        return handler
          && (!event.e  || handler.e == event.e)
          && (!event.ns || matcher.test(handler.ns))
          && (!fn       || zid(handler.fn) === zid(fn))
          && (!selector || handler.sel == selector)
      })
    }
    function parse(event) {
      var parts = ('' + event).split('.')
      return {e: parts[0], ns: parts.slice(1).sort().join(' ')}
    }
    function matcherFor(ns) {
      return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')
    }
  
    function eachEvent(events, fn, iterator){
      if ($.isObject(events)) $.each(events, iterator)
      else events.split(/\s/).forEach(function(type){ iterator(type, fn) })
    }
  
    function add(element, events, fn, selector, getDelegate, capture){
      capture = !!capture
      var id = zid(element), set = (handlers[id] || (handlers[id] = []))
      eachEvent(events, fn, function(event, fn){
        var delegate = getDelegate && getDelegate(fn, event),
          callback = delegate || fn
        var proxyfn = function (event) {
          var result = callback.apply(element, [event].concat(event.data))
          if (result === false) event.preventDefault()
          return result
        }
        var handler = $.extend(parse(event), {fn: fn, proxy: proxyfn, sel: selector, del: delegate, i: set.length})
        set.push(handler)
        element.addEventListener(handler.e, proxyfn, capture)
      })
    }
    function remove(element, events, fn, selector){
      var id = zid(element)
      eachEvent(events || '', fn, function(event, fn){
        findHandlers(element, event, fn, selector).forEach(function(handler){
          delete handlers[id][handler.i]
          element.removeEventListener(handler.e, handler.proxy, false)
        })
      })
    }
  
    $.event = { add: add, remove: remove }
  
    $.proxy = function(fn, context) {
      if ($.isFunction(fn)) {
        var proxyFn = function(){ return fn.apply(context, arguments) }
        proxyFn._zid = zid(fn)
        return proxyFn
      } else if (typeof context == 'string') {
        return $.proxy(fn[context], fn)
      } else {
        throw new TypeError("expected function")
      }
    }
  
    $.fn.bind = function(event, callback){
      return this.each(function(){
        add(this, event, callback)
      })
    }
    $.fn.unbind = function(event, callback){
      return this.each(function(){
        remove(this, event, callback)
      })
    }
    $.fn.one = function(event, callback){
      return this.each(function(i, element){
        add(this, event, callback, null, function(fn, type){
          return function(){
            var result = fn.apply(element, arguments)
            remove(element, type, fn)
            return result
          }
        })
      })
    }
  
    var returnTrue = function(){return true},
        returnFalse = function(){return false},
        eventMethods = {
          preventDefault: 'isDefaultPrevented',
          stopImmediatePropagation: 'isImmediatePropagationStopped',
          stopPropagation: 'isPropagationStopped'
        }
    function createProxy(event) {
      var proxy = $.extend({originalEvent: event}, event)
      $.each(eventMethods, function(name, predicate) {
        proxy[name] = function(){
          this[predicate] = returnTrue
          return event[name].apply(event, arguments)
        }
        proxy[predicate] = returnFalse
      })
      return proxy
    }
  
    // emulates the 'defaultPrevented' property for browsers that have none
    function fix(event) {
      if (!('defaultPrevented' in event)) {
        event.defaultPrevented = false
        var prevent = event.preventDefault
        event.preventDefault = function() {
          this.defaultPrevented = true
          prevent.call(this)
        }
      }
    }
  
    $.fn.delegate = function(selector, event, callback){
      var capture = false
      if(event == 'blur' || event == 'focus'){
        if($.iswebkit)
          event = event == 'blur' ? 'focusout' : event == 'focus' ? 'focusin' : event
        else
          capture = true
      }
  
      return this.each(function(i, element){
        add(element, event, callback, selector, function(fn){
          return function(e){
            var evt, match = $(e.target).closest(selector, element).get(0)
            if (match) {
              evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})
              return fn.apply(match, [evt].concat([].slice.call(arguments, 1)))
            }
          }
        }, capture)
      })
    }
    $.fn.undelegate = function(selector, event, callback){
      return this.each(function(){
        remove(this, event, callback, selector)
      })
    }
  
    $.fn.live = function(event, callback){
      $(document.body).delegate(this.selector, event, callback)
      return this
    }
    $.fn.die = function(event, callback){
      $(document.body).undelegate(this.selector, event, callback)
      return this
    }
  
    $.fn.on = function(event, selector, callback){
      return selector == undefined || $.isFunction(selector) ?
        this.bind(event, selector || callback) : this.delegate(selector, event, callback)
    }
    $.fn.off = function(event, selector, callback){
      return selector == undefined || $.isFunction(selector) ?
        this.unbind(event, selector || callback) : this.undelegate(selector, event, callback)
    }
  
    $.fn.trigger = function(event, data){
      if (typeof event == 'string') event = $.Event(event)
      fix(event)
      event.data = data
      return this.each(function(){
        // items in the collection might not be DOM elements
        // (todo: possibly support events on plain old objects)
        if('dispatchEvent' in this) this.dispatchEvent(event)
      })
    }
  
    // triggers event handlers on current element just as if an event occurred,
    // doesn't trigger an actual event, doesn't bubble
    $.fn.triggerHandler = function(event, data){
      var e, result
      this.each(function(i, element){
        e = createProxy(typeof event == 'string' ? $.Event(event) : event)
        e.data = data
        e.target = element
        $.each(findHandlers(element, event.type || event), function(i, handler){
          result = handler.proxy(e)
          if (e.isImmediatePropagationStopped()) return false
        })
      })
      return result
    }
  
    // shortcut methods for `.bind(event, fn)` for each event type
    ;('focusin focusout load resize scroll unload click dblclick '+
    'mousedown mouseup mousemove mouseover mouseout '+
    'change select keydown keypress keyup error').split(' ').forEach(function(event) {
      $.fn[event] = function(callback){ return this.bind(event, callback) }
    })
  
    ;['focus', 'blur'].forEach(function(name) {
      $.fn[name] = function(callback) {
        if (callback) this.bind(name, callback)
        else if (this.length) try { this.get(0)[name]() } catch(e){}
        return this
      }
    })
  
    $.Event = function(type, props) {
      var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true
      if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])
      event.initEvent(type, bubbles, true, null, null, null, null, null, null, null, null, null, null, null, null)
      return event
    }
  
  })(Zepto)
  