/*!
 * typeahead.js 0.11.1-patched-with-1212 (including patch https://github.com/twitter/typeahead.js/pull/1212)
 * https://github.com/twitter/typeahead.js
 * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
 */

(function(root, factory) {
  if (typeof define === "function" && define.amd) {
    define("typeahead.js", [ "jquery" ], function(a0) {
      return factory(a0);
    });
  } else if (typeof exports === "object") {
    module.exports = factory(require("jquery"));
  } else {
    factory(jQuery);
  }
})(this, function($) {
  var _ = function() {
    "use strict";
    return {
      isMsie: function() {
        return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
      },
      isBlankString: function(str) {
        return !str || /^\s*$/.test(str);
      },
      escapeRegExChars: function(str) {
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
      },
      isString: function(obj) {
        return typeof obj === "string";
      },
      isNumber: function(obj) {
        return typeof obj === "number";
      },
      isArray: $.isArray,
      isFunction: $.isFunction,
      isObject: $.isPlainObject,
      isUndefined: function(obj) {
        return typeof obj === "undefined";
      },
      isElement: function(obj) {
        return !!(obj && obj.nodeType === 1);
      },
      isJQuery: function(obj) {
        return obj instanceof $;
      },
      toStr: function toStr(s) {
        return _.isUndefined(s) || s === null ? "" : s + "";
      },
      bind: $.proxy,
      each: function(collection, cb) {
        $.each(collection, reverseArgs);
        function reverseArgs(index, value) {
          return cb(value, index);
        }
      },
      map: $.map,
      filter: $.grep,
      every: function(obj, test) {
        var result = true;
        if (!obj) {
          return result;
        }
        $.each(obj, function(key, val) {
          if (!(result = test.call(null, val, key, obj))) {
            return false;
          }
        });
        return !!result;
      },
      some: function(obj, test) {
        var result = false;
        if (!obj) {
          return result;
        }
        $.each(obj, function(key, val) {
          if (result = test.call(null, val, key, obj)) {
            return false;
          }
        });
        return !!result;
      },
      mixin: $.extend,
      identity: function(x) {
        return x;
      },
      clone: function(obj) {
        return $.extend(true, {}, obj);
      },
      getIdGenerator: function() {
        var counter = 0;
        return function() {
          return counter++;
        };
      },
      templatify: function templatify(obj) {
        return $.isFunction(obj) ? obj : template;
        function template() {
          return String(obj);
        }
      },
      defer: function(fn) {
        setTimeout(fn, 0);
      },
      debounce: function(func, wait, immediate) {
        var timeout, result;
        return function() {
          var context = this, args = arguments, later, callNow;
          later = function() {
            timeout = null;
            if (!immediate) {
              result = func.apply(context, args);
            }
          };
          callNow = immediate && !timeout;
          clearTimeout(timeout);
          timeout = setTimeout(later, wait);
          if (callNow) {
            result = func.apply(context, args);
          }
          return result;
        };
      },
      throttle: function(func, wait) {
        var context, args, timeout, result, previous, later;
        previous = 0;
        later = function() {
          previous = new Date();
          timeout = null;
          result = func.apply(context, args);
        };
        return function() {
          var now = new Date(), remaining = wait - (now - previous);
          context = this;
          args = arguments;
          if (remaining <= 0) {
            clearTimeout(timeout);
            timeout = null;
            previous = now;
            result = func.apply(context, args);
          } else if (!timeout) {
            timeout = setTimeout(later, remaining);
          }
          return result;
        };
      },
      stringify: function(val) {
        return _.isString(val) ? val : JSON.stringify(val);
      },
      noop: function() {}
    };
  }();
  var WWW = function() {
    "use strict";
    var defaultClassNames = {
      wrapper: "twitter-typeahead",
      input: "tt-input",
      hint: "tt-hint",
      menu: "tt-menu",
      dataset: "tt-dataset",
      suggestion: "tt-suggestion",
      selectable: "tt-selectable",
      empty: "tt-empty",
      open: "tt-open",
      cursor: "tt-cursor",
      highlight: "tt-highlight"
    };
    return build;
    function build(o) {
      var www, classes;
      classes = _.mixin({}, defaultClassNames, o);
      www = {
        css: buildCss(),
        classes: classes,
        html: buildHtml(classes),
        selectors: buildSelectors(classes)
      };
      return {
        css: www.css,
        html: www.html,
        classes: www.classes,
        selectors: www.selectors,
        mixin: function(o) {
          _.mixin(o, www);
        }
      };
    }
    function buildHtml(c) {
      return {
        wrapper: '<span class="' + c.wrapper + '"></span>',
        menu: '<div class="' + c.menu + '"></div>'
      };
    }
    function buildSelectors(classes) {
      var selectors = {};
      _.each(classes, function(v, k) {
        selectors[k] = "." + v;
      });
      return selectors;
    }
    function buildCss() {
      var css = {
        wrapper: {
          position: "relative",
          display: "inline-block"
        },
        hint: {
          position: "absolute",
          top: "0",
          left: "0",
          borderColor: "transparent",
          boxShadow: "none",
          opacity: "1"
        },
        input: {
          position: "relative",
          verticalAlign: "top",
          backgroundColor: "transparent"
        },
        inputWithNoHint: {
          position: "relative",
          verticalAlign: "top"
        },
        menu: {
          position: "absolute",
          top: "100%",
          left: "0",
          zIndex: "100",
          display: "none"
        },
        ltr: {
          left: "0",
          right: "auto"
        },
        rtl: {
          left: "auto",
          right: " 0"
        }
      };
      if (_.isMsie()) {
        _.mixin(css.input, {
          backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
        });
      }
      return css;
    }
  }();
  var EventBus = function() {
    "use strict";
    var namespace, deprecationMap;
    namespace = "typeahead:";
    deprecationMap = {
      render: "rendered",
      cursorchange: "cursorchanged",
      select: "selected",
      autocomplete: "autocompleted"
    };
    function EventBus(o) {
      if (!o || !o.el) {
        $.error("EventBus initialized without el");
      }
      this.$el = $(o.el);
    }
    _.mixin(EventBus.prototype, {
      _trigger: function(type, args) {
        var $e;
        $e = $.Event(namespace + type);
        (args = args || []).unshift($e);
        this.$el.trigger.apply(this.$el, args);
        return $e;
      },
      before: function(type) {
        var args, $e;
        args = [].slice.call(arguments, 1);
        $e = this._trigger("before" + type, args);
        return $e.isDefaultPrevented();
      },
      trigger: function(type) {
        var deprecatedType;
        this._trigger(type, [].slice.call(arguments, 1));
        if (deprecatedType = deprecationMap[type]) {
          this._trigger(deprecatedType, [].slice.call(arguments, 1));
        }
      }
    });
    return EventBus;
  }();
  var EventEmitter = function() {
    "use strict";
    var splitter = /\s+/, nextTick = getNextTick();
    return {
      onSync: onSync,
      onAsync: onAsync,
      off: off,
      trigger: trigger
    };
    function on(method, types, cb, context) {
      var type;
      if (!cb) {
        return this;
      }
      types = types.split(splitter);
      cb = context ? bindContext(cb, context) : cb;
      this._callbacks = this._callbacks || {};
      while (type = types.shift()) {
        this._callbacks[type] = this._callbacks[type] || {
              sync: [],
              async: []
            };
        this._callbacks[type][method].push(cb);
      }
      return this;
    }
    function onAsync(types, cb, context) {
      return on.call(this, "async", types, cb, context);
    }
    function onSync(types, cb, context) {
      return on.call(this, "sync", types, cb, context);
    }
    function off(types) {
      var type;
      if (!this._callbacks) {
        return this;
      }
      types = types.split(splitter);
      while (type = types.shift()) {
        delete this._callbacks[type];
      }
      return this;
    }
    function trigger(types) {
      var type, callbacks, args, syncFlush, asyncFlush;
      if (!this._callbacks) {
        return this;
      }
      types = types.split(splitter);
      args = [].slice.call(arguments, 1);
      while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
        syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
        asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
        syncFlush() && nextTick(asyncFlush);
      }
      return this;
    }
    function getFlush(callbacks, context, args) {
      return flush;
      function flush() {
        var cancelled;
        for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
          cancelled = callbacks[i].apply(context, args) === false;
        }
        return !cancelled;
      }
    }
    function getNextTick() {
      var nextTickFn;
      if (window.setImmediate) {
        nextTickFn = function nextTickSetImmediate(fn) {
          setImmediate(function() {
            fn();
          });
        };
      } else {
        nextTickFn = function nextTickSetTimeout(fn) {
          setTimeout(function() {
            fn();
          }, 0);
        };
      }
      return nextTickFn;
    }
    function bindContext(fn, context) {
      return fn.bind ? fn.bind(context) : function() {
        fn.apply(context, [].slice.call(arguments, 0));
      };
    }
  }();
  var highlight = function(doc) {
    "use strict";
    var defaults = {
      node: null,
      pattern: null,
      tagName: "strong",
      className: null,
      wordsOnly: false,
      caseSensitive: false
    };
    return function hightlight(o) {
      var regex;
      o = _.mixin({}, defaults, o);
      if (!o.node || !o.pattern) {
        return;
      }
      o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
      regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
      traverse(o.node, hightlightTextNode);
      function hightlightTextNode(textNode) {
        var match, patternNode, wrapperNode;
        if (match = regex.exec(textNode.data)) {
          wrapperNode = doc.createElement(o.tagName);
          o.className && (wrapperNode.className = o.className);
          patternNode = textNode.splitText(match.index);
          patternNode.splitText(match[0].length);
          wrapperNode.appendChild(patternNode.cloneNode(true));
          textNode.parentNode.replaceChild(wrapperNode, patternNode);
        }
        return !!match;
      }
      function traverse(el, hightlightTextNode) {
        var childNode, TEXT_NODE_TYPE = 3;
        for (var i = 0; i < el.childNodes.length; i++) {
          childNode = el.childNodes[i];
          if (childNode.nodeType === TEXT_NODE_TYPE) {
            i += hightlightTextNode(childNode) ? 1 : 0;
          } else {
            traverse(childNode, hightlightTextNode);
          }
        }
      }
    };
    function getRegex(patterns, caseSensitive, wordsOnly) {
      var escapedPatterns = [], regexStr;
      for (var i = 0, len = patterns.length; i < len; i++) {
        escapedPatterns.push(_.escapeRegExChars(patterns[i]));
      }
      regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
      return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
    }
  }(window.document);
  var Input = function() {
    "use strict";
    var specialKeyCodeMap;
    specialKeyCodeMap = {
      9: "tab",
      27: "esc",
      37: "left",
      39: "right",
      13: "enter",
      38: "up",
      40: "down"
    };
    function Input(o, www) {
      o = o || {};
      if (!o.input) {
        $.error("input is missing");
      }
      www.mixin(this);
      this.$hint = $(o.hint);
      this.$input = $(o.input);
      this.query = this.$input.val();
      this.queryWhenFocused = this.hasFocus() ? this.query : null;
      this.$overflowHelper = buildOverflowHelper(this.$input);
      this._checkLanguageDirection();
      if (this.$hint.length === 0) {
        this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
      }
    }
    Input.normalizeQuery = function(str) {
      return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
    };
    _.mixin(Input.prototype, EventEmitter, {
      _onBlur: function onBlur() {
        this.resetInputValue();
        this.trigger("blurred");
      },
      _onFocus: function onFocus() {
        this.queryWhenFocused = this.query;
        this.trigger("focused");
      },
      _onKeydown: function onKeydown($e) {
        var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
        this._managePreventDefault(keyName, $e);
        if (keyName && this._shouldTrigger(keyName, $e)) {
          this.trigger(keyName + "Keyed", $e);
        }
      },
      _onInput: function onInput() {
        this._setQuery(this.getInputValue());
        this.clearHintIfInvalid();
        this._checkLanguageDirection();
      },
      _managePreventDefault: function managePreventDefault(keyName, $e) {
        var preventDefault;
        switch (keyName) {
          case "up":
          case "down":
            preventDefault = !withModifier($e);
            break;

          default:
            preventDefault = false;
        }
        preventDefault && $e.preventDefault();
      },
      _shouldTrigger: function shouldTrigger(keyName, $e) {
        var trigger;
        switch (keyName) {
          case "tab":
            trigger = !withModifier($e);
            break;

          default:
            trigger = true;
        }
        return trigger;
      },
      _checkLanguageDirection: function checkLanguageDirection() {
        var dir = (this.$input.css("direction") || "ltr").toLowerCase();
        if (this.dir !== dir) {
          this.dir = dir;
          this.$hint.attr("dir", dir);
          this.trigger("langDirChanged", dir);
        }
      },
      _setQuery: function setQuery(val, silent) {
        var areEquivalent, hasDifferentWhitespace;
        areEquivalent = areQueriesEquivalent(val, this.query);
        hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
        this.query = val;
        if (!silent && !areEquivalent) {
          this.trigger("queryChanged", this.query);
        } else if (!silent && hasDifferentWhitespace) {
          this.trigger("whitespaceChanged", this.query);
        }
      },
      bind: function() {
        var that = this, onBlur, onFocus, onKeydown, onInput;
        onBlur = _.bind(this._onBlur, this);
        onFocus = _.bind(this._onFocus, this);
        onKeydown = _.bind(this._onKeydown, this);
        onInput = _.bind(this._onInput, this);
        this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
        if (!_.isMsie() || _.isMsie() > 9) {
          this.$input.on("input.tt", onInput);
        } else {
          this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
            if (specialKeyCodeMap[$e.which || $e.keyCode]) {
              return;
            }
            _.defer(_.bind(that._onInput, that, $e));
          });
        }
        return this;
      },
      focus: function focus() {
        this.$input.focus();
      },
      blur: function blur() {
        this.$input.blur();
      },
      getLangDir: function getLangDir() {
        return this.dir;
      },
      getQuery: function getQuery() {
        return this.query || "";
      },
      setQuery: function setQuery(val, silent) {
        this.setInputValue(val);
        this._setQuery(val, silent);
      },
      hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
        return this.query !== this.queryWhenFocused;
      },
      getInputValue: function getInputValue() {
        return this.$input.val();
      },
      setInputValue: function setInputValue(value) {
        this.$input.val(value);
        this.clearHintIfInvalid();
        this._checkLanguageDirection();
      },
      resetInputValue: function resetInputValue() {
        this.setInputValue(this.query);
      },
      getHint: function getHint() {
        return this.$hint.val();
      },
      setHint: function setHint(value) {
        this.$hint.val(value);
      },
      clearHint: function clearHint() {
        this.setHint("");
      },
      clearHintIfInvalid: function clearHintIfInvalid() {
        var val, hint, valIsPrefixOfHint, isValid;
        val = this.getInputValue();
        hint = this.getHint();
        valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
        isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
        !isValid && this.clearHint();
      },
      hasFocus: function hasFocus() {
        return this.$input.is(":focus");
      },
      hasOverflow: function hasOverflow() {
        var constraint = this.$input.width() - 2;
        this.$overflowHelper.text(this.getInputValue());
        return this.$overflowHelper.width() >= constraint;
      },
      isCursorAtEnd: function() {
        var valueLength, selectionStart, range;
        valueLength = this.$input.val().length;
        selectionStart = this.$input[0].selectionStart;
        if (_.isNumber(selectionStart)) {
          return selectionStart === valueLength;
        } else if (document.selection) {
          range = document.selection.createRange();
          range.moveStart("character", -valueLength);
          return valueLength === range.text.length;
        }
        return true;
      },
      destroy: function destroy() {
        this.$hint.off(".tt");
        this.$input.off(".tt");
        this.$overflowHelper.remove();
        this.$hint = this.$input = this.$overflowHelper = $("<div>");
      }
    });
    return Input;
    function buildOverflowHelper($input) {
      return $('<pre aria-hidden="true"></pre>').css({
        position: "absolute",
        visibility: "hidden",
        whiteSpace: "pre",
        fontFamily: $input.css("font-family"),
        fontSize: $input.css("font-size"),
        fontStyle: $input.css("font-style"),
        fontVariant: $input.css("font-variant"),
        fontWeight: $input.css("font-weight"),
        wordSpacing: $input.css("word-spacing"),
        letterSpacing: $input.css("letter-spacing"),
        textIndent: $input.css("text-indent"),
        textRendering: $input.css("text-rendering"),
        textTransform: $input.css("text-transform")
      }).insertAfter($input);
    }
    function areQueriesEquivalent(a, b) {
      return Input.normalizeQuery(a) === Input.normalizeQuery(b);
    }
    function withModifier($e) {
      return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
    }
  }();
  var Dataset = function() {
    "use strict";
    var keys, nameGenerator;
    keys = {
      val: "tt-selectable-display",
      obj: "tt-selectable-object"
    };
    nameGenerator = _.getIdGenerator();
    function Dataset(o, www) {
      o = o || {};
      o.templates = o.templates || {};
      o.templates.notFound = o.templates.notFound || o.templates.empty;
      if (!o.source) {
        $.error("missing source");
      }
      if (!o.node) {
        $.error("missing node");
      }
      if (o.name && !isValidName(o.name)) {
        $.error("invalid dataset name: " + o.name);
      }
      www.mixin(this);
      this.highlight = !!o.highlight;
      this.name = o.name || nameGenerator();
      this.limit = o.limit || 5;
      this.displayFn = getDisplayFn(o.display || o.displayKey);
      this.templates = getTemplates(o.templates, this.displayFn);
      this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
      this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
      this._resetLastSuggestion();
      this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
    }
    Dataset.extractData = function extractData(el) {
      var $el = $(el);
      if ($el.data(keys.obj)) {
        return {
          val: $el.data(keys.val) || "",
          obj: $el.data(keys.obj) || null
        };
      }
      return null;
    };
    _.mixin(Dataset.prototype, EventEmitter, {
      _overwrite: function overwrite(query, suggestions) {
        suggestions = suggestions || [];
        if (suggestions.length) {
          this._renderSuggestions(query, suggestions);
        } else if (this.async && this.templates.pending) {
          this._renderPending(query);
        } else if (!this.async && this.templates.notFound) {
          this._renderNotFound(query);
        } else {
          this._empty();
        }
        this.trigger("rendered", this.name, suggestions, false);
      },
      _append: function append(query, suggestions) {
        suggestions = suggestions || [];
        if (suggestions.length && this.$lastSuggestion.length) {
          this._appendSuggestions(query, suggestions);
        } else if (suggestions.length) {
          this._renderSuggestions(query, suggestions);
        } else if (!this.$lastSuggestion.length && this.templates.notFound) {
          this._renderNotFound(query);
        }
        this.trigger("rendered", this.name, suggestions, true);
      },
      _renderSuggestions: function renderSuggestions(query, suggestions) {
        var $fragment;
        $fragment = this._getSuggestionsFragment(query, suggestions);
        this.$lastSuggestion = $fragment.children().last();
        this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
      },
      _appendSuggestions: function appendSuggestions(query, suggestions) {
        var $fragment, $lastSuggestion;
        $fragment = this._getSuggestionsFragment(query, suggestions);
        $lastSuggestion = $fragment.children().last();
        this.$lastSuggestion.after($fragment);
        this.$lastSuggestion = $lastSuggestion;
      },
      _renderPending: function renderPending(query) {
        var template = this.templates.pending;
        this._resetLastSuggestion();
        template && this.$el.html(template({
          query: query,
          dataset: this.name
        }));
      },
      _renderNotFound: function renderNotFound(query) {
        var template = this.templates.notFound;
        this._resetLastSuggestion();
        template && this.$el.html(template({
          query: query,
          dataset: this.name
        }));
      },
      _empty: function empty() {
        this.$el.empty();
        this._resetLastSuggestion();
      },
      _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
        var that = this, fragment;
        fragment = document.createDocumentFragment();
        _.each(suggestions, function getSuggestionNode(suggestion) {
          var $el, context;
          context = that._injectQuery(query, suggestion);
          $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
          fragment.appendChild($el[0]);
        });
        this.highlight && highlight({
          className: this.classes.highlight,
          node: fragment,
          pattern: query
        });
        return $(fragment);
      },
      _getFooter: function getFooter(query, suggestions) {
        return this.templates.footer ? this.templates.footer({
          query: query,
          suggestions: suggestions,
          dataset: this.name
        }) : null;
      },
      _getHeader: function getHeader(query, suggestions) {
        return this.templates.header ? this.templates.header({
          query: query,
          suggestions: suggestions,
          dataset: this.name
        }) : null;
      },
      _resetLastSuggestion: function resetLastSuggestion() {
        this.$lastSuggestion = $();
      },
      _injectQuery: function injectQuery(query, obj) {
        return _.isObject(obj) ? _.mixin({
          _query: query
        }, obj) : obj;
      },
      update: function update(query) {
        var that = this, canceled = false, syncCalled = false, rendered = 0;
        this.cancel();
        this.cancel = function cancel() {
          canceled = true;
          that.cancel = $.noop;
          that.async && that.trigger("asyncCanceled", query);
        };
        this.source(query, sync, async);
        !syncCalled && sync([]);
        function sync(suggestions) {
          if (syncCalled) {
            return;
          }
          syncCalled = true;
          suggestions = (suggestions || []).slice(0, that.limit);
          rendered = suggestions.length;
          that._overwrite(query, suggestions);
          if (rendered < that.limit && that.async) {
            that.trigger("asyncRequested", query);
          }
        }
        function async(suggestions) {
          suggestions = suggestions || [];
          if (!canceled && rendered < that.limit) {
            that.cancel = $.noop;
            // patch rendered += suggestions.length;
            that._append(query, suggestions.slice(0, that.limit - rendered));
            // patch: https://github.com/twitter/typeahead.js/pull/1212
            rendered += suggestions.length;
            that.async && that.trigger("asyncReceived", query);
          }
        }
      },
      cancel: $.noop,
      clear: function clear() {
        this._empty();
        this.cancel();
        this.trigger("cleared");
      },
      isEmpty: function isEmpty() {
        return this.$el.is(":empty");
      },
      destroy: function destroy() {
        this.$el = $("<div>");
      }
    });
    return Dataset;
    function getDisplayFn(display) {
      display = display || _.stringify;
      return _.isFunction(display) ? display : displayFn;
      function displayFn(obj) {
        return obj[display];
      }
    }
    function getTemplates(templates, displayFn) {
      return {
        notFound: templates.notFound && _.templatify(templates.notFound),
        pending: templates.pending && _.templatify(templates.pending),
        header: templates.header && _.templatify(templates.header),
        footer: templates.footer && _.templatify(templates.footer),
        suggestion: templates.suggestion || suggestionTemplate
      };
      function suggestionTemplate(context) {
        return $("<div>").text(displayFn(context));
      }
    }
    function isValidName(str) {
      return /^[_a-zA-Z0-9-]+$/.test(str);
    }
  }();
  var Menu = function() {
    "use strict";
    function Menu(o, www) {
      var that = this;
      o = o || {};
      if (!o.node) {
        $.error("node is required");
      }
      www.mixin(this);
      this.$node = $(o.node);
      this.query = null;
      this.datasets = _.map(o.datasets, initializeDataset);
      function initializeDataset(oDataset) {
        var node = that.$node.find(oDataset.node).first();
        oDataset.node = node.length ? node : $("<div>").appendTo(that.$node);
        return new Dataset(oDataset, www);
      }
    }
    _.mixin(Menu.prototype, EventEmitter, {
      _onSelectableClick: function onSelectableClick($e) {
        this.trigger("selectableClicked", $($e.currentTarget));
      },
      _onRendered: function onRendered(type, dataset, suggestions, async) {
        this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
        this.trigger("datasetRendered", dataset, suggestions, async);
      },
      _onCleared: function onCleared() {
        this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
        this.trigger("datasetCleared");
      },
      _propagate: function propagate() {
        this.trigger.apply(this, arguments);
      },
      _allDatasetsEmpty: function allDatasetsEmpty() {
        return _.every(this.datasets, isDatasetEmpty);
        function isDatasetEmpty(dataset) {
          return dataset.isEmpty();
        }
      },
      _getSelectables: function getSelectables() {
        return this.$node.find(this.selectors.selectable);
      },
      _removeCursor: function _removeCursor() {
        var $selectable = this.getActiveSelectable();
        $selectable && $selectable.removeClass(this.classes.cursor);
      },
      _ensureVisible: function ensureVisible($el) {
        var elTop, elBottom, nodeScrollTop, nodeHeight;
        elTop = $el.position().top;
        elBottom = elTop + $el.outerHeight(true);
        nodeScrollTop = this.$node.scrollTop();
        nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
        if (elTop < 0) {
          this.$node.scrollTop(nodeScrollTop + elTop);
        } else if (nodeHeight < elBottom) {
          this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
        }
      },
      bind: function() {
        var that = this, onSelectableClick;
        onSelectableClick = _.bind(this._onSelectableClick, this);
        this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
        _.each(this.datasets, function(dataset) {
          dataset.onSync("asyncRequested", that._propagate, that).onSync("asyncCanceled", that._propagate, that).onSync("asyncReceived", that._propagate, that).onSync("rendered", that._onRendered, that).onSync("cleared", that._onCleared, that);
        });
        return this;
      },
      isOpen: function isOpen() {
        return this.$node.hasClass(this.classes.open);
      },
      open: function open() {
        this.$node.addClass(this.classes.open);
      },
      close: function close() {
        this.$node.removeClass(this.classes.open);
        this._removeCursor();
      },
      setLanguageDirection: function setLanguageDirection(dir) {
        this.$node.attr("dir", dir);
      },
      selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
        var $selectables, $oldCursor, oldIndex, newIndex;
        $oldCursor = this.getActiveSelectable();
        $selectables = this._getSelectables();
        oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
        newIndex = oldIndex + delta;
        newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
        newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
        return newIndex === -1 ? null : $selectables.eq(newIndex);
      },
      setCursor: function setCursor($selectable) {
        this._removeCursor();
        if ($selectable = $selectable && $selectable.first()) {
          $selectable.addClass(this.classes.cursor);
          this._ensureVisible($selectable);
        }
      },
      getSelectableData: function getSelectableData($el) {
        return $el && $el.length ? Dataset.extractData($el) : null;
      },
      getActiveSelectable: function getActiveSelectable() {
        var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
        return $selectable.length ? $selectable : null;
      },
      getTopSelectable: function getTopSelectable() {
        var $selectable = this._getSelectables().first();
        return $selectable.length ? $selectable : null;
      },
      update: function update(query) {
        var isValidUpdate = query !== this.query;
        if (isValidUpdate) {
          this.query = query;
          _.each(this.datasets, updateDataset);
        }
        return isValidUpdate;
        function updateDataset(dataset) {
          dataset.update(query);
        }
      },
      empty: function empty() {
        _.each(this.datasets, clearDataset);
        this.query = null;
        this.$node.addClass(this.classes.empty);
        function clearDataset(dataset) {
          dataset.clear();
        }
      },
      destroy: function destroy() {
        this.$node.off(".tt");
        this.$node = $("<div>");
        _.each(this.datasets, destroyDataset);
        function destroyDataset(dataset) {
          dataset.destroy();
        }
      }
    });
    return Menu;
  }();
  var DefaultMenu = function() {
    "use strict";
    var s = Menu.prototype;
    function DefaultMenu() {
      Menu.apply(this, [].slice.call(arguments, 0));
    }
    _.mixin(DefaultMenu.prototype, Menu.prototype, {
      open: function open() {
        !this._allDatasetsEmpty() && this._show();
        return s.open.apply(this, [].slice.call(arguments, 0));
      },
      close: function close() {
        this._hide();
        return s.close.apply(this, [].slice.call(arguments, 0));
      },
      _onRendered: function onRendered() {
        if (this._allDatasetsEmpty()) {
          this._hide();
        } else {
          this.isOpen() && this._show();
        }
        return s._onRendered.apply(this, [].slice.call(arguments, 0));
      },
      _onCleared: function onCleared() {
        if (this._allDatasetsEmpty()) {
          this._hide();
        } else {
          this.isOpen() && this._show();
        }
        return s._onCleared.apply(this, [].slice.call(arguments, 0));
      },
      setLanguageDirection: function setLanguageDirection(dir) {
        this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
        return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
      },
      _hide: function hide() {
        this.$node.hide();
      },
      _show: function show() {
        this.$node.css("display", "block");
      }
    });
    return DefaultMenu;
  }();
  var Typeahead = function() {
    "use strict";
    function Typeahead(o, www) {
      var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
      o = o || {};
      if (!o.input) {
        $.error("missing input");
      }
      if (!o.menu) {
        $.error("missing menu");
      }
      if (!o.eventBus) {
        $.error("missing event bus");
      }
      www.mixin(this);
      this.eventBus = o.eventBus;
      this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
      this.input = o.input;
      this.menu = o.menu;
      this.enabled = true;
      this.active = false;
      this.input.hasFocus() && this.activate();
      this.dir = this.input.getLangDir();
      this._hacks();
      this.menu.bind().onSync("selectableClicked", this._onSelectableClicked, this).onSync("asyncRequested", this._onAsyncRequested, this).onSync("asyncCanceled", this._onAsyncCanceled, this).onSync("asyncReceived", this._onAsyncReceived, this).onSync("datasetRendered", this._onDatasetRendered, this).onSync("datasetCleared", this._onDatasetCleared, this);
      onFocused = c(this, "activate", "open", "_onFocused");
      onBlurred = c(this, "deactivate", "_onBlurred");
      onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
      onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
      onEscKeyed = c(this, "isActive", "_onEscKeyed");
      onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
      onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
      onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
      onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
      onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
      onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
      this.input.bind().onSync("focused", onFocused, this).onSync("blurred", onBlurred, this).onSync("enterKeyed", onEnterKeyed, this).onSync("tabKeyed", onTabKeyed, this).onSync("escKeyed", onEscKeyed, this).onSync("upKeyed", onUpKeyed, this).onSync("downKeyed", onDownKeyed, this).onSync("leftKeyed", onLeftKeyed, this).onSync("rightKeyed", onRightKeyed, this).onSync("queryChanged", onQueryChanged, this).onSync("whitespaceChanged", onWhitespaceChanged, this).onSync("langDirChanged", this._onLangDirChanged, this);
    }
    _.mixin(Typeahead.prototype, {
      _hacks: function hacks() {
        var $input, $menu;
        $input = this.input.$input || $("<div>");
        $menu = this.menu.$node || $("<div>");
        $input.on("blur.tt", function($e) {
          var active, isActive, hasActive;
          active = document.activeElement;
          isActive = $menu.is(active);
          hasActive = $menu.has(active).length > 0;
          if (_.isMsie() && (isActive || hasActive)) {
            $e.preventDefault();
            $e.stopImmediatePropagation();
            _.defer(function() {
              $input.focus();
            });
          }
        });
        $menu.on("mousedown.tt", function($e) {
          $e.preventDefault();
        });
      },
      _onSelectableClicked: function onSelectableClicked(type, $el) {
        this.select($el);
      },
      _onDatasetCleared: function onDatasetCleared() {
        this._updateHint();
      },
      _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
        this._updateHint();
        this.eventBus.trigger("render", suggestions, async, dataset);
      },
      _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
        this.eventBus.trigger("asyncrequest", query, dataset);
      },
      _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
        this.eventBus.trigger("asynccancel", query, dataset);
      },
      _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
        this.eventBus.trigger("asyncreceive", query, dataset);
      },
      _onFocused: function onFocused() {
        this._minLengthMet() && this.menu.update(this.input.getQuery());
      },
      _onBlurred: function onBlurred() {
        if (this.input.hasQueryChangedSinceLastFocus()) {
          this.eventBus.trigger("change", this.input.getQuery());
        }
      },
      _onEnterKeyed: function onEnterKeyed(type, $e) {
        var $selectable;
        if ($selectable = this.menu.getActiveSelectable()) {
          this.select($selectable) && $e.preventDefault();
        }
      },
      _onTabKeyed: function onTabKeyed(type, $e) {
        var $selectable;
        if ($selectable = this.menu.getActiveSelectable()) {
          this.select($selectable) && $e.preventDefault();
        } else if ($selectable = this.menu.getTopSelectable()) {
          this.autocomplete($selectable) && $e.preventDefault();
        }
      },
      _onEscKeyed: function onEscKeyed() {
        this.close();
      },
      _onUpKeyed: function onUpKeyed() {
        this.moveCursor(-1);
      },
      _onDownKeyed: function onDownKeyed() {
        this.moveCursor(+1);
      },
      _onLeftKeyed: function onLeftKeyed() {
        if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
          this.autocomplete(this.menu.getTopSelectable());
        }
      },
      _onRightKeyed: function onRightKeyed() {
        if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
          this.autocomplete(this.menu.getTopSelectable());
        }
      },
      _onQueryChanged: function onQueryChanged(e, query) {
        this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
      },
      _onWhitespaceChanged: function onWhitespaceChanged() {
        this._updateHint();
      },
      _onLangDirChanged: function onLangDirChanged(e, dir) {
        if (this.dir !== dir) {
          this.dir = dir;
          this.menu.setLanguageDirection(dir);
        }
      },
      _openIfActive: function openIfActive() {
        this.isActive() && this.open();
      },
      _minLengthMet: function minLengthMet(query) {
        query = _.isString(query) ? query : this.input.getQuery() || "";
        return query.length >= this.minLength;
      },
      _updateHint: function updateHint() {
        var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
        $selectable = this.menu.getTopSelectable();
        data = this.menu.getSelectableData($selectable);
        val = this.input.getInputValue();
        if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
          query = Input.normalizeQuery(val);
          escapedQuery = _.escapeRegExChars(query);
          frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
          match = frontMatchRegEx.exec(data.val);
          match && this.input.setHint(val + match[1]);
        } else {
          this.input.clearHint();
        }
      },
      isEnabled: function isEnabled() {
        return this.enabled;
      },
      enable: function enable() {
        this.enabled = true;
      },
      disable: function disable() {
        this.enabled = false;
      },
      isActive: function isActive() {
        return this.active;
      },
      activate: function activate() {
        if (this.isActive()) {
          return true;
        } else if (!this.isEnabled() || this.eventBus.before("active")) {
          return false;
        } else {
          this.active = true;
          this.eventBus.trigger("active");
          return true;
        }
      },
      deactivate: function deactivate() {
        if (!this.isActive()) {
          return true;
        } else if (this.eventBus.before("idle")) {
          return false;
        } else {
          this.active = false;
          this.close();
          this.eventBus.trigger("idle");
          return true;
        }
      },
      isOpen: function isOpen() {
        return this.menu.isOpen();
      },
      open: function open() {
        if (!this.isOpen() && !this.eventBus.before("open")) {
          this.menu.open();
          this._updateHint();
          this.eventBus.trigger("open");
        }
        return this.isOpen();
      },
      close: function close() {
        if (this.isOpen() && !this.eventBus.before("close")) {
          this.menu.close();
          this.input.clearHint();
          this.input.resetInputValue();
          this.eventBus.trigger("close");
        }
        return !this.isOpen();
      },
      setVal: function setVal(val) {
        this.input.setQuery(_.toStr(val));
      },
      getVal: function getVal() {
        return this.input.getQuery();
      },
      select: function select($selectable) {
        var data = this.menu.getSelectableData($selectable);
        if (data && !this.eventBus.before("select", data.obj)) {
          this.input.setQuery(data.val, true);
          this.eventBus.trigger("select", data.obj);
          this.close();
          return true;
        }
        return false;
      },
      autocomplete: function autocomplete($selectable) {
        var query, data, isValid;
        query = this.input.getQuery();
        data = this.menu.getSelectableData($selectable);
        isValid = data && query !== data.val;
        if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
          this.input.setQuery(data.val);
          this.eventBus.trigger("autocomplete", data.obj);
          return true;
        }
        return false;
      },
      moveCursor: function moveCursor(delta) {
        var query, $candidate, data, payload, cancelMove;
        query = this.input.getQuery();
        $candidate = this.menu.selectableRelativeToCursor(delta);
        data = this.menu.getSelectableData($candidate);
        payload = data ? data.obj : null;
        cancelMove = this._minLengthMet() && this.menu.update(query);
        if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
          this.menu.setCursor($candidate);
          if (data) {
            this.input.setInputValue(data.val);
          } else {
            this.input.resetInputValue();
            this._updateHint();
          }
          this.eventBus.trigger("cursorchange", payload);
          return true;
        }
        return false;
      },
      destroy: function destroy() {
        this.input.destroy();
        this.menu.destroy();
      }
    });
    return Typeahead;
    function c(ctx) {
      var methods = [].slice.call(arguments, 1);
      return function() {
        var args = [].slice.call(arguments);
        _.each(methods, function(method) {
          return ctx[method].apply(ctx, args);
        });
      };
    }
  }();
  (function() {
    "use strict";
    var old, keys, methods;
    old = $.fn.typeahead;
    keys = {
      www: "tt-www",
      attrs: "tt-attrs",
      typeahead: "tt-typeahead"
    };
    methods = {
      initialize: function initialize(o, datasets) {
        var www;
        datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
        o = o || {};
        www = WWW(o.classNames);
        return this.each(attach);
        function attach() {
          var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
          _.each(datasets, function(d) {
            d.highlight = !!o.highlight;
          });
          $input = $(this);
          $wrapper = $(www.html.wrapper);
          $hint = $elOrNull(o.hint);
          $menu = $elOrNull(o.menu);
          defaultHint = o.hint !== false && !$hint;
          defaultMenu = o.menu !== false && !$menu;
          defaultHint && ($hint = buildHintFromInput($input, www));
          defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
          $hint && $hint.val("");
          $input = prepInput($input, www);
          if (defaultHint || defaultMenu) {
            $wrapper.css(www.css.wrapper);
            $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
            $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
          }
          MenuConstructor = defaultMenu ? DefaultMenu : Menu;
          eventBus = new EventBus({
            el: $input
          });
          input = new Input({
            hint: $hint,
            input: $input
          }, www);
          menu = new MenuConstructor({
            node: $menu,
            datasets: datasets
          }, www);
          typeahead = new Typeahead({
            input: input,
            menu: menu,
            eventBus: eventBus,
            minLength: o.minLength
          }, www);
          $input.data(keys.www, www);
          $input.data(keys.typeahead, typeahead);
        }
      },
      isEnabled: function isEnabled() {
        var enabled;
        ttEach(this.first(), function(t) {
          enabled = t.isEnabled();
        });
        return enabled;
      },
      enable: function enable() {
        ttEach(this, function(t) {
          t.enable();
        });
        return this;
      },
      disable: function disable() {
        ttEach(this, function(t) {
          t.disable();
        });
        return this;
      },
      isActive: function isActive() {
        var active;
        ttEach(this.first(), function(t) {
          active = t.isActive();
        });
        return active;
      },
      activate: function activate() {
        ttEach(this, function(t) {
          t.activate();
        });
        return this;
      },
      deactivate: function deactivate() {
        ttEach(this, function(t) {
          t.deactivate();
        });
        return this;
      },
      isOpen: function isOpen() {
        var open;
        ttEach(this.first(), function(t) {
          open = t.isOpen();
        });
        return open;
      },
      open: function open() {
        ttEach(this, function(t) {
          t.open();
        });
        return this;
      },
      close: function close() {
        ttEach(this, function(t) {
          t.close();
        });
        return this;
      },
      select: function select(el) {
        var success = false, $el = $(el);
        ttEach(this.first(), function(t) {
          success = t.select($el);
        });
        return success;
      },
      autocomplete: function autocomplete(el) {
        var success = false, $el = $(el);
        ttEach(this.first(), function(t) {
          success = t.autocomplete($el);
        });
        return success;
      },
      moveCursor: function moveCursoe(delta) {
        var success = false;
        ttEach(this.first(), function(t) {
          success = t.moveCursor(delta);
        });
        return success;
      },
      val: function val(newVal) {
        var query;
        if (!arguments.length) {
          ttEach(this.first(), function(t) {
            query = t.getVal();
          });
          return query;
        } else {
          ttEach(this, function(t) {
            t.setVal(newVal);
          });
          return this;
        }
      },
      destroy: function destroy() {
        ttEach(this, function(typeahead, $input) {
          revert($input);
          typeahead.destroy();
        });
        return this;
      }
    };
    $.fn.typeahead = function(method) {
      if (methods[method]) {
        return methods[method].apply(this, [].slice.call(arguments, 1));
      } else {
        return methods.initialize.apply(this, arguments);
      }
    };
    $.fn.typeahead.noConflict = function noConflict() {
      $.fn.typeahead = old;
      return this;
    };
    function ttEach($els, fn) {
      $els.each(function() {
        var $input = $(this), typeahead;
        (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
      });
    }
    function buildHintFromInput($input, www) {
      return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
        autocomplete: "off",
        spellcheck: "false",
        tabindex: -1
      });
    }
    function prepInput($input, www) {
      $input.data(keys.attrs, {
        dir: $input.attr("dir"),
        autocomplete: $input.attr("autocomplete"),
        spellcheck: $input.attr("spellcheck"),
        style: $input.attr("style")
      });
      $input.addClass(www.classes.input).attr({
        autocomplete: "off",
        spellcheck: false
      });
      try {
        !$input.attr("dir") && $input.attr("dir", "auto");
      } catch (e) {}
      return $input;
    }
    function getBackgroundStyles($el) {
      return {
        backgroundAttachment: $el.css("background-attachment"),
        backgroundClip: $el.css("background-clip"),
        backgroundColor: $el.css("background-color"),
        backgroundImage: $el.css("background-image"),
        backgroundOrigin: $el.css("background-origin"),
        backgroundPosition: $el.css("background-position"),
        backgroundRepeat: $el.css("background-repeat"),
        backgroundSize: $el.css("background-size")
      };
    }
    function revert($input) {
      var www, $wrapper;
      www = $input.data(keys.www);
      $wrapper = $input.parent().filter(www.selectors.wrapper);
      _.each($input.data(keys.attrs), function(val, key) {
        _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
      });
      $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
      if ($wrapper.length) {
        $input.detach().insertAfter($wrapper);
        $wrapper.remove();
      }
    }
    function $elOrNull(obj) {
      var isValid, $el;
      isValid = _.isJQuery(obj) || _.isElement(obj);
      $el = isValid ? $(obj).first() : [];
      return $el.length ? $el : null;
    }
  })();
});