PageSourceSearch

https://www.confidas.ro/js/typeahead.jquery.js

js confidas.ro collected 2026-10-07 19:52:57 UTC 63,136 bytes, 1,538 lines download raw bytes

vendor: 63,136 bytes, lines 1-1538
1/*!
2 * typeahead.js 0.11.1
3 * https://github.com/twitter/typeahead.js
4 * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
5 */
6
7(function(root, factory) {
8    if (typeof define === "function" && define.amd) {
9        define("typeahead.js", [ "jquery" ], function(a0) {
10            return factory(a0);
11        });
12    } else if (typeof exports === "object") {
13        module.exports = factory(require("jquery"));
14    } else {
15        factory(jQuery);
16    }
17})(this, function($) {
18    var _ = function() {
19        "use strict";
20        return {
21            isMsie: function() {
22                return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
23            },
24            isBlankString: function(str) {
25                return !str || /^\s*$/.test(str);
26            },
27            escapeRegExChars: function(str) {
28                return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
29            },
30            isString: function(obj) {
31                return typeof obj === "string";
32            },
33            isNumber: function(obj) {
34                return typeof obj === "number";
35            },
36            isArray: $.isArray,
37            isFunction: $.isFunction,
38            isObject: $.isPlainObject,
39            isUndefined: function(obj) {
40                return typeof obj === "undefined";
41            },
42            isElement: function(obj) {
43                return !!(obj && obj.nodeType === 1);
44            },
45            isJQuery: function(obj) {
46                return obj instanceof $;
47            },
48            toStr: function toStr(s) {
49                return _.isUndefined(s) || s === null ? "" : s + "";
50            },
51            bind: $.proxy,
52            each: function(collection, cb) {
53                $.each(collection, reverseArgs);
54                function reverseArgs(index, value) {
55                    return cb(value, index);
56                }
57            },
58            map: $.map,
59            filter: $.grep,
60            every: function(obj, test) {
61                var result = true;
62                if (!obj) {
63                    return result;
64                }
65                $.each(obj, function(key, val) {
66                    if (!(result = test.call(null, val, key, obj))) {
67                        return false;
68                    }
69                });
70                return !!result;
71            },
72            some: function(obj, test) {
73                var result = false;
74                if (!obj) {
75                    return result;
76                }
77                $.each(obj, function(key, val) {
78                    if (result = test.call(null, val, key, obj)) {
79                        return false;
80                    }
81                });
82                return !!result;
83            },
84            mixin: $.extend,
85            identity: function(x) {
86                return x;
87            },
88            clone: function(obj) {
89                return $.extend(true, {}, obj);
90            },
91            getIdGenerator: function() {
92                var counter = 0;
93                return function() {
94                    return counter++;
95                };
96            },
97            templatify: function templatify(obj) {
98                return $.isFunction(obj) ? obj : template;
99                function template() {
100                    return String(obj);
101                }
102            },
103            defer: function(fn) {
104                setTimeout(fn, 0);
105            },
106            debounce: function(func, wait, immediate) {
107                var timeout, result;
108                return function() {
109                    var context = this, args = arguments, later, callNow;
110                    later = function() {
111                        timeout = null;
112                        if (!immediate) {
113                            result = func.apply(context, args);
114                        }
115                    };
116                    callNow = immediate && !timeout;
117                    clearTimeout(timeout);
118                    timeout = setTimeout(later, wait);
119                    if (callNow) {
120                        result = func.apply(context, args);
121                    }
122                    return result;
123                };
124            },
125            throttle: function(func, wait) {
126                var context, args, timeout, result, previous, later;
127                previous = 0;
128                later = function() {
129                    previous = new Date();
130                    timeout = null;
131                    result = func.apply(context, args);
132                };
133                return function() {
134                    var now = new Date(), remaining = wait - (now - previous);
135                    context = this;
136                    args = arguments;
137                    if (remaining <= 0) {
138                        clearTimeout(timeout);
139                        timeout = null;
140                        previous = now;
141                        result = func.apply(context, args);
142                    } else if (!timeout) {
143                        timeout = setTimeout(later, remaining);
144                    }
145                    return result;
146                };
147            },
148            stringify: function(val) {
149                return _.isString(val) ? val : JSON.stringify(val);
150            },
151            noop: function() {}
152        };
153    }();
154    var WWW = function() {
155        "use strict";
156        var defaultClassNames = {
157            wrapper: "twitter-typeahead",
158            input: "tt-input",
159            hint: "tt-hint",
160            menu: "tt-menu",
161            dataset: "tt-dataset",
162            suggestion: "tt-suggestion",
163            selectable: "tt-selectable",
164            empty: "tt-empty",
165            open: "tt-open",
166            cursor: "tt-cursor",
167            highlight: "tt-highlight"
168        };
169        return build;
170        function build(o) {
171            var www, classes;
172            classes = _.mixin({}, defaultClassNames, o);
173            www = {
174                css: buildCss(),
175                classes: classes,
176                html: buildHtml(classes),
177                selectors: buildSelectors(classes)
178            };
179            return {
180                css: www.css,
181                html: www.html,
182                classes: www.classes,
183                selectors: www.selectors,
184                mixin: function(o) {
185                    _.mixin(o, www);
186                }
187            };
188        }
189        function buildHtml(c) {
190            return {
191                wrapper: '<span class="' + c.wrapper + '"></span>',
192                menu: '<div class="' + c.menu + '"></div>'
193            };
194        }
195        function buildSelectors(classes) {
196            var selectors = {};
197            _.each(classes, function(v, k) {
198                selectors[k] = "." + v;
199            });
200            return selectors;
201        }
202        function buildCss() {
203            var css = {
204                wrapper: {
205                    position: "relative",
206                    display: "inline-block"
207                },
208                hint: {
209                    position: "absolute",
210                    top: "0",
211                    left: "0",
212                    borderColor: "transparent",
213                    boxShadow: "none",
214                    opacity: "1"
215                },
216                input: {
217                    position: "relative",
218                    verticalAlign: "top",
219                    backgroundColor: "transparent"
220                },
221                inputWithNoHint: {
222                    position: "relative",
223                    verticalAlign: "top"
224                },
225                menu: {
226                    position: "absolute",
227                    top: "100%",
228                    left: "0",
229                    zIndex: "100",
230                    display: "none"
231                },
232                ltr: {
233                    left: "0",
234                    right: "auto"
235                },
236                rtl: {
237                    left: "auto",
238                    right: " 0"
239                }
240            };
241            if (_.isMsie()) {
242                _.mixin(css.input, {
243                    backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"
244                });
245            }
246            return css;
247        }
248    }();
249    var EventBus = function() {
250        "use strict";
251        var namespace, deprecationMap;
252        namespace = "typeahead:";
253        deprecationMap = {
254            render: "rendered",
255            cursorchange: "cursorchanged",
256            select: "selected",
257            autocomplete: "autocompleted"
258        };
259        function EventBus(o) {
260            if (!o || !o.el) {
261                $.error("EventBus initialized without el");
262            }
263            this.$el = $(o.el);
264        }
265        _.mixin(EventBus.prototype, {
266            _trigger: function(type, args) {
267                var $e;
268                $e = $.Event(namespace + type);
269                (args = args || []).unshift($e);
270                this.$el.trigger.apply(this.$el, args);
271                return $e;
272            },
273            before: function(type) {
274                var args, $e;
275                args = [].slice.call(arguments, 1);
276                $e = this._trigger("before" + type, args);
277                return $e.isDefaultPrevented();
278            },
279            trigger: function(type) {
280                var deprecatedType;
281                this._trigger(type, [].slice.call(arguments, 1));
282                if (deprecatedType = deprecationMap[type]) {
283                    this._trigger(deprecatedType, [].slice.call(arguments, 1));
284                }
285            }
286        });
287        return EventBus;
288    }();
289    var EventEmitter = function() {
290        "use strict";
291        var splitter = /\s+/, nextTick = getNextTick();
292        return {
293            onSync: onSync,
294            onAsync: onAsync,
295            off: off,
296            trigger: trigger
297        };
298        function on(method, types, cb, context) {
299            var type;
300            if (!cb) {
301                return this;
302            }
303            types = types.split(splitter);
304            cb = context ? bindContext(cb, context) : cb;
305            this._callbacks = this._callbacks || {};
306            while (type = types.shift()) {
307                this._callbacks[type] = this._callbacks[type] || {
308                    sync: [],
309                    async: []
310                };
311                this._callbacks[type][method].push(cb);
312            }
313            return this;
314        }
315        function onAsync(types, cb, context) {
316            return on.call(this, "async", types, cb, context);
317        }
318        function onSync(types, cb, context) {
319            return on.call(this, "sync", types, cb, context);
320        }
321        function off(types) {
322            var type;
323            if (!this._callbacks) {
324                return this;
325            }
326            types = types.split(splitter);
327            while (type = types.shift()) {
328                delete this._callbacks[type];
329            }
330            return this;
331        }
332        function trigger(types) {
333            var type, callbacks, args, syncFlush, asyncFlush;
334            if (!this._callbacks) {
335                return this;
336            }
337            types = types.split(splitter);
338            args = [].slice.call(arguments, 1);
339            while ((type = types.shift()) && (callbacks = this._callbacks[type])) {
340                syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));
341                asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));
342                syncFlush() && nextTick(asyncFlush);
343            }
344            return this;
345        }
346        function getFlush(callbacks, context, args) {
347            return flush;
348            function flush() {
349                var cancelled;
350                for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {
351                    cancelled = callbacks[i].apply(context, args) === false;
352                }
353                return !cancelled;
354            }
355        }
356        function getNextTick() {
357            var nextTickFn;
358            if (window.setImmediate) {
359                nextTickFn = function nextTickSetImmediate(fn) {
360                    setImmediate(function() {
361                        fn();
362                    });
363                };
364            } else {
365                nextTickFn = function nextTickSetTimeout(fn) {
366                    setTimeout(function() {
367                        fn();
368                    }, 0);
369                };
370            }
371            return nextTickFn;
372        }
373        function bindContext(fn, context) {
374            return fn.bind ? fn.bind(context) : function() {
375                fn.apply(context, [].slice.call(arguments, 0));
376            };
377        }
378    }();
379    var highlight = function(doc) {
380        "use strict";
381        var defaults = {
382            node: null,
383            pattern: null,
384            tagName: "strong",
385            className: null,
386            wordsOnly: false,
387            caseSensitive: false
388        };
389        return function hightlight(o) {
390            var regex;
391            o = _.mixin({}, defaults, o);
392            if (!o.node || !o.pattern) {
393                return;
394            }
395            o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];
396            regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);
397            traverse(o.node, hightlightTextNode);
398            function hightlightTextNode(textNode) {
399                var match, patternNode, wrapperNode;
400                if (match = regex.exec(textNode.data)) {
401                    wrapperNode = doc.createElement(o.tagName);
402                    o.className && (wrapperNode.className = o.className);
403                    patternNode = textNode.splitText(match.index);
404                    patternNode.splitText(match[0].length);
405                    wrapperNode.appendChild(patternNode.cloneNode(true));
406                    textNode.parentNode.replaceChild(wrapperNode, patternNode);
407                }
408                return !!match;
409            }
410            function traverse(el, hightlightTextNode) {
411                var childNode, TEXT_NODE_TYPE = 3;
412                for (var i = 0; i < el.childNodes.length; i++) {
413                    childNode = el.childNodes[i];
414                    if (childNode.nodeType === TEXT_NODE_TYPE) {
415                        i += hightlightTextNode(childNode) ? 1 : 0;
416                    } else {
417                        traverse(childNode, hightlightTextNode);
418                    }
419                }
420            }
421        };
422        function getRegex(patterns, caseSensitive, wordsOnly) {
423            var escapedPatterns = [], regexStr;
424            for (var i = 0, len = patterns.length; i < len; i++) {
425                escapedPatterns.push(_.escapeRegExChars(patterns[i]));
426            }
427            regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")";
428            return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i");
429        }
430    }(window.document);
431    var Input = function() {
432        "use strict";
433        var specialKeyCodeMap;
434        specialKeyCodeMap = {
435            9: "tab",
436            27: "esc",
437            37: "left",
438            39: "right",
439            13: "enter",
440            38: "up",
441            40: "down"
442        };
443        function Input(o, www) {
444            o = o || {};
445            if (!o.input) {
446                $.error("input is missing");
447            }
448            www.mixin(this);
449            this.$hint = $(o.hint);
450            this.$input = $(o.input);
451            this.query = this.$input.val();
452            this.queryWhenFocused = this.hasFocus() ? this.query : null;
453            this.$overflowHelper = buildOverflowHelper(this.$input);
454            this._checkLanguageDirection();
455            if (this.$hint.length === 0) {
456                this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;
457            }
458        }
459        Input.normalizeQuery = function(str) {
460            return _.toStr(str).replace(/^\s*/g, "").replace(/\s{2,}/g, " ");
461        };
462        _.mixin(Input.prototype, EventEmitter, {
463            _onBlur: function onBlur() {
464                this.resetInputValue();
465                this.trigger("blurred");
466            },
467            _onFocus: function onFocus() {
468                this.queryWhenFocused = this.query;
469                this.trigger("focused");
470            },
471            _onKeydown: function onKeydown($e) {
472                var keyName = specialKeyCodeMap[$e.which || $e.keyCode];
473                this._managePreventDefault(keyName, $e);
474                if (keyName && this._shouldTrigger(keyName, $e)) {
475                    this.trigger(keyName + "Keyed", $e);
476                }
477            },
478            _onInput: function onInput() {
479                this._setQuery(this.getInputValue());
480                this.clearHintIfInvalid();
481                this._checkLanguageDirection();
482            },
483            _managePreventDefault: function managePreventDefault(keyName, $e) {
484                var preventDefault;
485                switch (keyName) {
486                  case "up":
487                  case "down":
488                    preventDefault = !withModifier($e);
489                    break;
490
491                  default:
492                    preventDefault = false;
493                }
494                preventDefault && $e.preventDefault();
495            },
496            _shouldTrigger: function shouldTrigger(keyName, $e) {
497                var trigger;
498                switch (keyName) {
499                  case "tab":
500                    trigger = !withModifier($e);
501                    break;
502
503                  default:
504                    trigger = true;
505                }
506                return trigger;
507            },
508            _checkLanguageDirection: function checkLanguageDirection() {
509                var dir = (this.$input.css("direction") || "ltr").toLowerCase();
510                if (this.dir !== dir) {
511                    this.dir = dir;
512                    this.$hint.attr("dir", dir);
513                    this.trigger("langDirChanged", dir);
514                }
515            },
516            _setQuery: function setQuery(val, silent) {
517                var areEquivalent, hasDifferentWhitespace;
518                areEquivalent = areQueriesEquivalent(val, this.query);
519                hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;
520                this.query = val;
521                if (!silent && !areEquivalent) {
522                    this.trigger("queryChanged", this.query);
523                } else if (!silent && hasDifferentWhitespace) {
524                    this.trigger("whitespaceChanged", this.query);
525                }
526            },
527            bind: function() {
528                var that = this, onBlur, onFocus, onKeydown, onInput;
529                onBlur = _.bind(this._onBlur, this);
530                onFocus = _.bind(this._onFocus, this);
531                onKeydown = _.bind(this._onKeydown, this);
532                onInput = _.bind(this._onInput, this);
533                this.$input.on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown);
534                if (!_.isMsie() || _.isMsie() > 9) {
535                    this.$input.on("input.tt", onInput);
536                } else {
537                    this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) {
538                        if (specialKeyCodeMap[$e.which || $e.keyCode]) {
539                            return;
540                        }
541                        _.defer(_.bind(that._onInput, that, $e));
542                    });
543                }
544                return this;
545            },
546            focus: function focus() {
547                this.$input.focus();
548            },
549            blur: function blur() {
550                this.$input.blur();
551            },
552            getLangDir: function getLangDir() {
553                return this.dir;
554            },
555            getQuery: function getQuery() {
556                return this.query || "";
557            },
558            setQuery: function setQuery(val, silent) {
559                this.setInputValue(val);
560                this._setQuery(val, silent);
561            },
562            hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {
563                return this.query !== this.queryWhenFocused;
564            },
565            getInputValue: function getInputValue() {
566                return this.$input.val();
567            },
568            setInputValue: function setInputValue(value) {
569                this.$input.val(value);
570                this.clearHintIfInvalid();
571                this._checkLanguageDirection();
572            },
573            resetInputValue: function resetInputValue() {
574                this.setInputValue(this.query);
575            },
576            getHint: function getHint() {
577                return this.$hint.val();
578            },
579            setHint: function setHint(value) {
580                this.$hint.val(value);
581            },
582            clearHint: function clearHint() {
583                this.setHint("");
584            },
585            clearHintIfInvalid: function clearHintIfInvalid() {
586                var val, hint, valIsPrefixOfHint, isValid;
587                val = this.getInputValue();
588                hint = this.getHint();
589                valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;
590                isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow();
591                !isValid && this.clearHint();
592            },
593            hasFocus: function hasFocus() {
594                return this.$input.is(":focus");
595            },
596            hasOverflow: function hasOverflow() {
597                var constraint = this.$input.width() - 2;
598                this.$overflowHelper.text(this.getInputValue());
599                return this.$overflowHelper.width() >= constraint;
600            },
601            isCursorAtEnd: function() {
602                var valueLength, selectionStart, range;
603                valueLength = this.$input.val().length;
604                selectionStart = this.$input[0].selectionStart;
605                if (_.isNumber(selectionStart)) {
606                    return selectionStart === valueLength;
607                } else if (document.selection) {
608                    range = document.selection.createRange();
609                    range.moveStart("character", -valueLength);
610                    return valueLength === range.text.length;
611                }
612                return true;
613            },
614            destroy: function destroy() {
615                this.$hint.off(".tt");
616                this.$input.off(".tt");
617                this.$overflowHelper.remove();
618                this.$hint = this.$input = this.$overflowHelper = $("<div>");
619            }
620        });
621        return Input;
622        function buildOverflowHelper($input) {
623            return $('<pre aria-hidden="true"></pre>').css({
624                position: "absolute",
625                visibility: "hidden",
626                whiteSpace: "pre",
627                fontFamily: $input.css("font-family"),
628                fontSize: $input.css("font-size"),
629                fontStyle: $input.css("font-style"),
630                fontVariant: $input.css("font-variant"),
631                fontWeight: $input.css("font-weight"),
632                wordSpacing: $input.css("word-spacing"),
633                letterSpacing: $input.css("letter-spacing"),
634                textIndent: $input.css("text-indent"),
635                textRendering: $input.css("text-rendering"),
636                textTransform: $input.css("text-transform")
637            }).insertAfter($input);
638        }
639        function areQueriesEquivalent(a, b) {
640            return Input.normalizeQuery(a) === Input.normalizeQuery(b);
641        }
642        function withModifier($e) {
643            return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;
644        }
645    }();
646    var Dataset = function() {
647        "use strict";
648        var keys, nameGenerator;
649        keys = {
650            val: "tt-selectable-display",
651            obj: "tt-selectable-object"
652        };
653        nameGenerator = _.getIdGenerator();
654        function Dataset(o, www) {
655            o = o || {};
656            o.templates = o.templates || {};
657            o.templates.notFound = o.templates.notFound || o.templates.empty;
658            if (!o.source) {
659                $.error("missing source");
660            }
661            if (!o.node) {
662                $.error("missing node");
663            }
664            if (o.name && !isValidName(o.name)) {
665                $.error("invalid dataset name: " + o.name);
666            }
667            www.mixin(this);
668            this.highlight = !!o.highlight;
669            this.name = o.name || nameGenerator();
670            this.limit = o.limit || 5;
671            this.displayFn = getDisplayFn(o.display || o.displayKey);
672            this.templates = getTemplates(o.templates, this.displayFn);
673            this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;
674            this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;
675            this._resetLastSuggestion();
676            this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + "-" + this.name);
677        }
678        Dataset.extractData = function extractData(el) {
679            var $el = $(el);
680            if ($el.data(keys.obj)) {
681                return {
682                    val: $el.data(keys.val) || "",
683                    obj: $el.data(keys.obj) || null
684                };
685            }
686            return null;
687        };
688        _.mixin(Dataset.prototype, EventEmitter, {
689            _overwrite: function overwrite(query, suggestions) {
690                suggestions = suggestions || [];
691                if (suggestions.length) {
692                    this._renderSuggestions(query, suggestions);
693                } else if (this.async && this.templates.pending) {
694                    this._renderPending(query);
695                } else if (!this.async && this.templates.notFound) {
696                    this._renderNotFound(query);
697                } else {
698                    this._empty();
699                }
700                this.trigger("rendered", this.name, suggestions, false);
701            },
702            _append: function append(query, suggestions) {
703                suggestions = suggestions || [];
704                if (suggestions.length && this.$lastSuggestion.length) {
705                    this._appendSuggestions(query, suggestions);
706                } else if (suggestions.length) {
707                    this._renderSuggestions(query, suggestions);
708                } else if (!this.$lastSuggestion.length && this.templates.notFound) {
709                    this._renderNotFound(query);
710                }
711                this.trigger("rendered", this.name, suggestions, true);
712            },
713            _renderSuggestions: function renderSuggestions(query, suggestions) {
714                var $fragment;
715                $fragment = this._getSuggestionsFragment(query, suggestions);
716                this.$lastSuggestion = $fragment.children().last();
717                this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));
718            },
719            _appendSuggestions: function appendSuggestions(query, suggestions) {
720                var $fragment, $lastSuggestion;
721                $fragment = this._getSuggestionsFragment(query, suggestions);
722                $lastSuggestion = $fragment.children().last();
723                this.$lastSuggestion.after($fragment);
724                this.$lastSuggestion = $lastSuggestion;
725            },
726            _renderPending: function renderPending(query) {
727                var template = this.templates.pending;
728                this._resetLastSuggestion();
729                template && this.$el.html(template({
730                    query: query,
731                    dataset: this.name
732                }));
733            },
734            _renderNotFound: function renderNotFound(query) {
735                var template = this.templates.notFound;
736                this._resetLastSuggestion();
737                template && this.$el.html(template({
738                    query: query,
739                    dataset: this.name
740                }));
741            },
742            _empty: function empty() {
743                this.$el.empty();
744                this._resetLastSuggestion();
745            },
746            _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {
747                var that = this, fragment;
748                fragment = document.createDocumentFragment();
749                _.each(suggestions, function getSuggestionNode(suggestion) {
750                    var $el, context;
751                    context = that._injectQuery(query, suggestion);
752                    $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + " " + that.classes.selectable);
753                    fragment.appendChild($el[0]);
754                });
755                this.highlight && highlight({
756                    className: this.classes.highlight,
757                    node: fragment,
758                    pattern: query
759                });
760                return $(fragment);
761            },
762            _getFooter: function getFooter(query, suggestions) {
763                return this.templates.footer ? this.templates.footer({
764                    query: query,
765                    suggestions: suggestions,
766                    dataset: this.name
767                }) : null;
768            },
769            _getHeader: function getHeader(query, suggestions) {
770                return this.templates.header ? this.templates.header({
771                    query: query,
772                    suggestions: suggestions,
773                    dataset: this.name
774                }) : null;
775            },
776            _resetLastSuggestion: function resetLastSuggestion() {
777                this.$lastSuggestion = $();
778            },
779            _injectQuery: function injectQuery(query, obj) {
780                return _.isObject(obj) ? _.mixin({
781                    _query: query
782                }, obj) : obj;
783            },
784            update: function update(query) {
785                var that = this, canceled = false, syncCalled = false, rendered = 0;
786                this.cancel();
787                this.cancel = function cancel() {
788                    canceled = true;
789                    that.cancel = $.noop;
790                    that.async && that.trigger("asyncCanceled", query);
791                };
792                this.source(query, sync, async);
793                !syncCalled && sync([]);
794                function sync(suggestions) {
795                    if (syncCalled) {
796                        return;
797                    }
798                    syncCalled = true;
799                    suggestions = (suggestions || []).slice(0, that.limit);
800                    rendered = suggestions.length;
801                    that._overwrite(query, suggestions);
802                    if (rendered < that.limit && that.async) {
803                        that.trigger("asyncRequested", query);
804                    }
805                }
806                function async(suggestions) {
807                    suggestions = suggestions || [];
808                    if (!canceled && rendered < that.limit) {
809                        that.cancel = $.noop;
810                        rendered += suggestions.length;
811                        that._append(query, suggestions.slice(0, that.limit - rendered));
812                        that.async && that.trigger("asyncReceived", query);
813                    }
814                }
815            },
816            cancel: $.noop,
817            clear: function clear() {
818                this._empty();
819                this.cancel();
820                this.trigger("cleared");
821            },
822            isEmpty: function isEmpty() {
823                return this.$el.is(":empty");
824            },
825            destroy: function destroy() {
826                this.$el = $("<div>");
827            }
828        });
829        return Dataset;
830        function getDisplayFn(display) {
831            display = display || _.stringify;
832            return _.isFunction(display) ? display : displayFn;
833            function displayFn(obj) {
834                return obj[display];
835            }
836        }
837        function getTemplates(templates, displayFn) {
838            return {
839                notFound: templates.notFound && _.templatify(templates.notFound),
840                pending: templates.pending && _.templatify(templates.pending),
841                header: templates.header && _.templatify(templates.header),
842                footer: templates.footer && _.templatify(templates.footer),
843                suggestion: templates.suggestion || suggestionTemplate
844            };
845            function suggestionTemplate(context) {
846                return $("<div>").text(displayFn(context));
847            }
848        }
849        function isValidName(str) {
850            return /^[_a-zA-Z0-9-]+$/.test(str);
851        }
852    }();
853    var Menu = function() {
854        "use strict";
855        function Menu(o, www) {
856            var that = this;
857            o = o || {};
858            if (!o.node) {
859                $.error("node is required");
860            }
861            www.mixin(this);
862            this.$node = $(o.node);
863            this.query = null;
864            this.datasets = _.map(o.datasets, initializeDataset);
865            function initializeDataset(oDataset) {
866                var node = that.$node.find(oDataset.node).first();
867                oDataset.node = node.length ? node : $("<div>").appendTo(that.$node);
868                return new Dataset(oDataset, www);
869            }
870        }
871        _.mixin(Menu.prototype, EventEmitter, {
872            _onSelectableClick: function onSelectableClick($e) {
873                this.trigger("selectableClicked", $($e.currentTarget));
874            },
875            _onRendered: function onRendered(type, dataset, suggestions, async) {
876                this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
877                this.trigger("datasetRendered", dataset, suggestions, async);
878            },
879            _onCleared: function onCleared() {
880                this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());
881                this.trigger("datasetCleared");
882            },
883            _propagate: function propagate() {
884                this.trigger.apply(this, arguments);
885            },
886            _allDatasetsEmpty: function allDatasetsEmpty() {
887                return _.every(this.datasets, isDatasetEmpty);
888                function isDatasetEmpty(dataset) {
889                    return dataset.isEmpty();
890                }
891            },
892            _getSelectables: function getSelectables() {
893                return this.$node.find(this.selectors.selectable);
894            },
895            _removeCursor: function _removeCursor() {
896                var $selectable = this.getActiveSelectable();
897                $selectable && $selectable.removeClass(this.classes.cursor);
898            },
899            _ensureVisible: function ensureVisible($el) {
900                var elTop, elBottom, nodeScrollTop, nodeHeight;
901                elTop = $el.position().top;
902                elBottom = elTop + $el.outerHeight(true);
903                nodeScrollTop = this.$node.scrollTop();
904                nodeHeight = this.$node.height() + parseInt(this.$node.css("paddingTop"), 10) + parseInt(this.$node.css("paddingBottom"), 10);
905                if (elTop < 0) {
906                    this.$node.scrollTop(nodeScrollTop + elTop);
907                } else if (nodeHeight < elBottom) {
908                    this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
909                }
910            },
911            bind: function() {
912                var that = this, onSelectableClick;
913                onSelectableClick = _.bind(this._onSelectableClick, this);
914                this.$node.on("click.tt", this.selectors.selectable, onSelectableClick);
915                _.each(this.datasets, function(dataset) {
916                    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);
917                });
918                return this;
919            },
920            isOpen: function isOpen() {
921                return this.$node.hasClass(this.classes.open);
922            },
923            open: function open() {
924                this.$node.addClass(this.classes.open);
925            },
926            close: function close() {
927                this.$node.removeClass(this.classes.open);
928                this._removeCursor();
929            },
930            setLanguageDirection: function setLanguageDirection(dir) {
931                this.$node.attr("dir", dir);
932            },
933            selectableRelativeToCursor: function selectableRelativeToCursor(delta) {
934                var $selectables, $oldCursor, oldIndex, newIndex;
935                $oldCursor = this.getActiveSelectable();
936                $selectables = this._getSelectables();
937                oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;
938                newIndex = oldIndex + delta;
939                newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;
940                newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;
941                return newIndex === -1 ? null : $selectables.eq(newIndex);
942            },
943            setCursor: function setCursor($selectable) {
944                this._removeCursor();
945                if ($selectable = $selectable && $selectable.first()) {
946                    $selectable.addClass(this.classes.cursor);
947                    this._ensureVisible($selectable);
948                }
949            },
950            getSelectableData: function getSelectableData($el) {
951                return $el && $el.length ? Dataset.extractData($el) : null;
952            },
953            getActiveSelectable: function getActiveSelectable() {
954                var $selectable = this._getSelectables().filter(this.selectors.cursor).first();
955                return $selectable.length ? $selectable : null;
956            },
957            getTopSelectable: function getTopSelectable() {
958                var $selectable = this._getSelectables().first();
959                return $selectable.length ? $selectable : null;
960            },
961            update: function update(query) {
962                var isValidUpdate = query !== this.query;
963                if (isValidUpdate) {
964                    this.query = query;
965                    _.each(this.datasets, updateDataset);
966                }
967                return isValidUpdate;
968                function updateDataset(dataset) {
969                    dataset.update(query);
970                }
971            },
972            empty: function empty() {
973                _.each(this.datasets, clearDataset);
974                this.query = null;
975                this.$node.addClass(this.classes.empty);
976                function clearDataset(dataset) {
977                    dataset.clear();
978                }
979            },
980            destroy: function destroy() {
981                this.$node.off(".tt");
982                this.$node = $("<div>");
983                _.each(this.datasets, destroyDataset);
984                function destroyDataset(dataset) {
985                    dataset.destroy();
986                }
987            }
988        });
989        return Menu;
990    }();
991    var DefaultMenu = function() {
992        "use strict";
993        var s = Menu.prototype;
994        function DefaultMenu() {
995            Menu.apply(this, [].slice.call(arguments, 0));
996        }
997        _.mixin(DefaultMenu.prototype, Menu.prototype, {
998            open: function open() {
999                !this._allDatasetsEmpty() && this._show();
1000                return s.open.apply(this, [].slice.call(arguments, 0));
1001            },
1002            close: function close() {
1003                this._hide();
1004                return s.close.apply(this, [].slice.call(arguments, 0));
1005            },
1006            _onRendered: function onRendered() {
1007                if (this._allDatasetsEmpty()) {
1008                    this._hide();
1009                } else {
1010                    this.isOpen() && this._show();
1011                }
1012                return s._onRendered.apply(this, [].slice.call(arguments, 0));
1013            },
1014            _onCleared: function onCleared() {
1015                if (this._allDatasetsEmpty()) {
1016                    this._hide();
1017                } else {
1018                    this.isOpen() && this._show();
1019                }
1020                return s._onCleared.apply(this, [].slice.call(arguments, 0));
1021            },
1022            setLanguageDirection: function setLanguageDirection(dir) {
1023                this.$node.css(dir === "ltr" ? this.css.ltr : this.css.rtl);
1024                return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));
1025            },
1026            _hide: function hide() {
1027                this.$node.hide();
1028            },
1029            _show: function show() {
1030                this.$node.css("display", "block");
1031            }
1032        });
1033        return DefaultMenu;
1034    }();
1035    var Typeahead = function() {
1036        "use strict";
1037        function Typeahead(o, www) {
1038            var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;
1039            o = o || {};
1040            if (!o.input) {
1041                $.error("missing input");
1042            }
1043            if (!o.menu) {
1044                $.error("missing menu");
1045            }
1046            if (!o.eventBus) {
1047                $.error("missing event bus");
1048            }
1049            www.mixin(this);
1050            this.eventBus = o.eventBus;
1051            this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;
1052            this.input = o.input;
1053            this.menu = o.menu;
1054            this.enabled = true;
1055            this.active = false;
1056            this.input.hasFocus() && this.activate();
1057            this.dir = this.input.getLangDir();
1058            this._hacks();
1059            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);
1060            onFocused = c(this, "activate", "open", "_onFocused");
1061            onBlurred = c(this, "deactivate", "_onBlurred");
1062            onEnterKeyed = c(this, "isActive", "isOpen", "_onEnterKeyed");
1063            onTabKeyed = c(this, "isActive", "isOpen", "_onTabKeyed");
1064            onEscKeyed = c(this, "isActive", "_onEscKeyed");
1065            onUpKeyed = c(this, "isActive", "open", "_onUpKeyed");
1066            onDownKeyed = c(this, "isActive", "open", "_onDownKeyed");
1067            onLeftKeyed = c(this, "isActive", "isOpen", "_onLeftKeyed");
1068            onRightKeyed = c(this, "isActive", "isOpen", "_onRightKeyed");
1069            onQueryChanged = c(this, "_openIfActive", "_onQueryChanged");
1070            onWhitespaceChanged = c(this, "_openIfActive", "_onWhitespaceChanged");
1071            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);
1072        }
1073        _.mixin(Typeahead.prototype, {
1074            _hacks: function hacks() {
1075                var $input, $menu;
1076                $input = this.input.$input || $("<div>");
1077                $menu = this.menu.$node || $("<div>");
1078                $input.on("blur.tt", function($e) {
1079                    var active, isActive, hasActive;
1080                    active = document.activeElement;
1081                    isActive = $menu.is(active);
1082                    hasActive = $menu.has(active).length > 0;
1083                    if (_.isMsie() && (isActive || hasActive)) {
1084                        $e.preventDefault();
1085                        $e.stopImmediatePropagation();
1086                        _.defer(function() {
1087                            $input.focus();
1088                        });
1089                    }
1090                });
1091                $menu.on("mousedown.tt", function($e) {
1092                    $e.preventDefault();
1093                });
1094            },
1095            _onSelectableClicked: function onSelectableClicked(type, $el) {
1096                this.select($el);
1097            },
1098            _onDatasetCleared: function onDatasetCleared() {
1099                this._updateHint();
1100            },
1101            _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {
1102                this._updateHint();
1103                this.eventBus.trigger("render", suggestions, async, dataset);
1104            },
1105            _onAsyncRequested: function onAsyncRequested(type, dataset, query) {
1106                this.eventBus.trigger("asyncrequest", query, dataset);
1107            },
1108            _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {
1109                this.eventBus.trigger("asynccancel", query, dataset);
1110            },
1111            _onAsyncReceived: function onAsyncReceived(type, dataset, query) {
1112                this.eventBus.trigger("asyncreceive", query, dataset);
1113            },
1114            _onFocused: function onFocused() {
1115                this._minLengthMet() && this.menu.update(this.input.getQuery());
1116            },
1117            _onBlurred: function onBlurred() {
1118                if (this.input.hasQueryChangedSinceLastFocus()) {
1119                    this.eventBus.trigger("change", this.input.getQuery());
1120                }
1121            },
1122            _onEnterKeyed: function onEnterKeyed(type, $e) {
1123                var $selectable;
1124                if ($selectable = this.menu.getActiveSelectable()) {
1125                    this.select($selectable) && $e.preventDefault();
1126                }
1127            },
1128            _onTabKeyed: function onTabKeyed(type, $e) {
1129                var $selectable;
1130                if ($selectable = this.menu.getActiveSelectable()) {
1131                    this.select($selectable) && $e.preventDefault();
1132                } else if ($selectable = this.menu.getTopSelectable()) {
1133                    this.autocomplete($selectable) && $e.preventDefault();
1134                }
1135            },
1136            _onEscKeyed: function onEscKeyed() {
1137                this.close();
1138            },
1139            _onUpKeyed: function onUpKeyed() {
1140                this.moveCursor(-1);
1141            },
1142            _onDownKeyed: function onDownKeyed() {
1143                this.moveCursor(+1);
1144            },
1145            _onLeftKeyed: function onLeftKeyed() {
1146                if (this.dir === "rtl" && this.input.isCursorAtEnd()) {
1147                    this.autocomplete(this.menu.getTopSelectable());
1148                }
1149            },
1150            _onRightKeyed: function onRightKeyed() {
1151                if (this.dir === "ltr" && this.input.isCursorAtEnd()) {
1152                    this.autocomplete(this.menu.getTopSelectable());
1153                }
1154            },
1155            _onQueryChanged: function onQueryChanged(e, query) {
1156                this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();
1157            },
1158            _onWhitespaceChanged: function onWhitespaceChanged() {
1159                this._updateHint();
1160            },
1161            _onLangDirChanged: function onLangDirChanged(e, dir) {
1162                if (this.dir !== dir) {
1163                    this.dir = dir;
1164                    this.menu.setLanguageDirection(dir);
1165                }
1166            },
1167            _openIfActive: function openIfActive() {
1168                this.isActive() && this.open();
1169            },
1170            _minLengthMet: function minLengthMet(query) {
1171                query = _.isString(query) ? query : this.input.getQuery() || "";
1172                return query.length >= this.minLength;
1173            },
1174            _updateHint: function updateHint() {
1175                var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;
1176                $selectable = this.menu.getTopSelectable();
1177                data = this.menu.getSelectableData($selectable);
1178                val = this.input.getInputValue();
1179                if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {
1180                    query = Input.normalizeQuery(val);
1181                    escapedQuery = _.escapeRegExChars(query);
1182                    frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i");
1183                    match = frontMatchRegEx.exec(data.val);
1184                    match && this.input.setHint(val + match[1]);
1185                } else {
1186                    this.input.clearHint();
1187                }
1188            },
1189            isEnabled: function isEnabled() {
1190                return this.enabled;
1191            },
1192            enable: function enable() {
1193                this.enabled = true;
1194            },
1195            disable: function disable() {
1196                this.enabled = false;
1197            },
1198            isActive: function isActive() {
1199                return this.active;
1200            },
1201            activate: function activate() {
1202                if (this.isActive()) {
1203                    return true;
1204                } else if (!this.isEnabled() || this.eventBus.before("active")) {
1205                    return false;
1206                } else {
1207                    this.active = true;
1208                    this.eventBus.trigger("active");
1209                    return true;
1210                }
1211            },
1212            deactivate: function deactivate() {
1213                if (!this.isActive()) {
1214                    return true;
1215                } else if (this.eventBus.before("idle")) {
1216                    return false;
1217                } else {
1218                    this.active = false;
1219                    this.close();
1220                    this.eventBus.trigger("idle");
1221                    return true;
1222                }
1223            },
1224            isOpen: function isOpen() {
1225                return this.menu.isOpen();
1226            },
1227            open: function open() {
1228                if (!this.isOpen() && !this.eventBus.before("open")) {
1229                    this.menu.open();
1230                    this._updateHint();
1231                    this.eventBus.trigger("open");
1232                }
1233                return this.isOpen();
1234            },
1235            close: function close() {
1236                if (this.isOpen() && !this.eventBus.before("close")) {
1237                    this.menu.close();
1238                    this.input.clearHint();
1239                    this.input.resetInputValue();
1240                    this.eventBus.trigger("close");
1241                }
1242                return !this.isOpen();
1243            },
1244            setVal: function setVal(val) {
1245                this.input.setQuery(_.toStr(val));
1246            },
1247            getVal: function getVal() {
1248                return this.input.getQuery();
1249            },
1250            select: function select($selectable) {
1251                var data = this.menu.getSelectableData($selectable);
1252                if (data && !this.eventBus.before("select", data.obj)) {
1253                    this.input.setQuery(data.val, true);
1254                    this.eventBus.trigger("select", data.obj);
1255                    this.close();
1256                    return true;
1257                }
1258                return false;
1259            },
1260            autocomplete: function autocomplete($selectable) {
1261                var query, data, isValid;
1262                query = this.input.getQuery();
1263                data = this.menu.getSelectableData($selectable);
1264                isValid = data && query !== data.val;
1265                if (isValid && !this.eventBus.before("autocomplete", data.obj)) {
1266                    this.input.setQuery(data.val);
1267                    this.eventBus.trigger("autocomplete", data.obj);
1268                    return true;
1269                }
1270                return false;
1271            },
1272            moveCursor: function moveCursor(delta) {
1273                var query, $candidate, data, payload, cancelMove;
1274                query = this.input.getQuery();
1275                $candidate = this.menu.selectableRelativeToCursor(delta);
1276                data = this.menu.getSelectableData($candidate);
1277                payload = data ? data.obj : null;
1278                cancelMove = this._minLengthMet() && this.menu.update(query);
1279                if (!cancelMove && !this.eventBus.before("cursorchange", payload)) {
1280                    this.menu.setCursor($candidate);
1281                    if (data) {
1282                        this.input.setInputValue(data.val);
1283                    } else {
1284                        this.input.resetInputValue();
1285                        this._updateHint();
1286                    }
1287                    this.eventBus.trigger("cursorchange", payload);
1288                    return true;
1289                }
1290                return false;
1291            },
1292            destroy: function destroy() {
1293                this.input.destroy();
1294                this.menu.destroy();
1295            }
1296        });
1297        return Typeahead;
1298        function c(ctx) {
1299            var methods = [].slice.call(arguments, 1);
1300            return function() {
1301                var args = [].slice.call(arguments);
1302                _.each(methods, function(method) {
1303                    return ctx[method].apply(ctx, args);
1304                });
1305            };
1306        }
1307    }();
1308    (function() {
1309        "use strict";
1310        var old, keys, methods;
1311        old = $.fn.typeahead;
1312        keys = {
1313            www: "tt-www",
1314            attrs: "tt-attrs",
1315            typeahead: "tt-typeahead"
1316        };
1317        methods = {
1318            initialize: function initialize(o, datasets) {
1319                var www;
1320                datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);
1321                o = o || {};
1322                www = WWW(o.classNames);
1323                return this.each(attach);
1324                function attach() {
1325                    var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;
1326                    _.each(datasets, function(d) {
1327                        d.highlight = !!o.highlight;
1328                    });
1329                    $input = $(this);
1330                    $wrapper = $(www.html.wrapper);
1331                    $hint = $elOrNull(o.hint);
1332                    $menu = $elOrNull(o.menu);
1333                    defaultHint = o.hint !== false && !$hint;
1334                    defaultMenu = o.menu !== false && !$menu;
1335                    defaultHint && ($hint = buildHintFromInput($input, www));
1336                    defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));
1337                    $hint && $hint.val("");
1338                    $input = prepInput($input, www);
1339                    if (defaultHint || defaultMenu) {
1340                        $wrapper.css(www.css.wrapper);
1341                        $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);
1342                        $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);
1343                    }
1344                    MenuConstructor = defaultMenu ? DefaultMenu : Menu;
1345                    eventBus = new EventBus({
1346                        el: $input
1347                    });
1348                    input = new Input({
1349                        hint: $hint,
1350                        input: $input
1351                    }, www);
1352                    menu = new MenuConstructor({
1353                        node: $menu,
1354                        datasets: datasets
1355                    }, www);
1356                    typeahead = new Typeahead({
1357                        input: input,
1358                        menu: menu,
1359                        eventBus: eventBus,
1360                        minLength: o.minLength
1361                    }, www);
1362                    $input.data(keys.www, www);
1363                    $input.data(keys.typeahead, typeahead);
1364                }
1365            },
1366            isEnabled: function isEnabled() {
1367                var enabled;
1368                ttEach(this.first(), function(t) {
1369                    enabled = t.isEnabled();
1370                });
1371                return enabled;
1372            },
1373            enable: function enable() {
1374                ttEach(this, function(t) {
1375                    t.enable();
1376                });
1377                return this;
1378            },
1379            disable: function disable() {
1380                ttEach(this, function(t) {
1381                    t.disable();
1382                });
1383                return this;
1384            },
1385            isActive: function isActive() {
1386                var active;
1387                ttEach(this.first(), function(t) {
1388                    active = t.isActive();
1389                });
1390                return active;
1391            },
1392            activate: function activate() {
1393                ttEach(this, function(t) {
1394                    t.activate();
1395                });
1396                return this;
1397            },
1398            deactivate: function deactivate() {
1399                ttEach(this, function(t) {
1400                    t.deactivate();
1401                });
1402                return this;
1403            },
1404            isOpen: function isOpen() {
1405                var open;
1406                ttEach(this.first(), function(t) {
1407                    open = t.isOpen();
1408                });
1409                return open;
1410            },
1411            open: function open() {
1412                ttEach(this, function(t) {
1413                    t.open();
1414                });
1415                return this;
1416            },
1417            close: function close() {
1418                ttEach(this, function(t) {
1419                    t.close();
1420                });
1421                return this;
1422            },
1423            select: function select(el) {
1424                var success = false, $el = $(el);
1425                ttEach(this.first(), function(t) {
1426                    success = t.select($el);
1427                });
1428                return success;
1429            },
1430            autocomplete: function autocomplete(el) {
1431                var success = false, $el = $(el);
1432                ttEach(this.first(), function(t) {
1433                    success = t.autocomplete($el);
1434                });
1435                return success;
1436            },
1437            moveCursor: function moveCursoe(delta) {
1438                var success = false;
1439                ttEach(this.first(), function(t) {
1440                    success = t.moveCursor(delta);
1441                });
1442                return success;
1443            },
1444            val: function val(newVal) {
1445                var query;
1446                if (!arguments.length) {
1447                    ttEach(this.first(), function(t) {
1448                        query = t.getVal();
1449                    });
1450                    return query;
1451                } else {
1452                    ttEach(this, function(t) {
1453                        t.setVal(newVal);
1454                    });
1455                    return this;
1456                }
1457            },
1458            destroy: function destroy() {
1459                ttEach(this, function(typeahead, $input) {
1460                    revert($input);
1461                    typeahead.destroy();
1462                });
1463                return this;
1464            }
1465        };
1466        $.fn.typeahead = function(method) {
1467            if (methods[method]) {
1468                return methods[method].apply(this, [].slice.call(arguments, 1));
1469            } else {
1470                return methods.initialize.apply(this, arguments);
1471            }
1472        };
1473        $.fn.typeahead.noConflict = function noConflict() {
1474            $.fn.typeahead = old;
1475            return this;
1476        };
1477        function ttEach($els, fn) {
1478            $els.each(function() {
1479                var $input = $(this), typeahead;
1480                (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);
1481            });
1482        }
1483        function buildHintFromInput($input, www) {
1484            return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop("readonly", true).removeAttr("id name placeholder required").attr({
1485                autocomplete: "off",
1486                spellcheck: "false",
1487                tabindex: -1
1488            });
1489        }
1490        function prepInput($input, www) {
1491            $input.data(keys.attrs, {
1492                dir: $input.attr("dir"),
1493                autocomplete: $input.attr("autocomplete"),
1494                spellcheck: $input.attr("spellcheck"),
1495                style: $input.attr("style")
1496            });
1497            $input.addClass(www.classes.input).attr({
1498                autocomplete: "off",
1499                spellcheck: false
1500            });
1501            try {
1502                !$input.attr("dir") && $input.attr("dir", "auto");
1503            } catch (e) {}
1504            return $input;
1505        }
1506        function getBackgroundStyles($el) {
1507            return {
1508                backgroundAttachment: $el.css("background-attachment"),
1509                backgroundClip: $el.css("background-clip"),
1510                backgroundColor: $el.css("background-color"),
1511                backgroundImage: $el.css("background-image"),
1512                backgroundOrigin: $el.css("background-origin"),
1513                backgroundPosition: $el.css("background-position"),
1514                backgroundRepeat: $el.css("background-repeat"),
1515                backgroundSize: $el.css("background-size")
1516            };
1517        }
1518        function revert($input) {
1519            var www, $wrapper;
1520            www = $input.data(keys.www);
1521            $wrapper = $input.parent().filter(www.selectors.wrapper);
1522            _.each($input.data(keys.attrs), function(val, key) {
1523                _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);
1524            });
1525            $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);
1526            if ($wrapper.length) {
1527                $input.detach().insertAfter($wrapper);
1528                $wrapper.remove();
1529            }
1530        }
1531        function $elOrNull(obj) {
1532            var isValid, $el;
1533            isValid = _.isJQuery(obj) || _.isElement(obj);
1534            $el = isValid ? $(obj).first() : [];
1535            return $el.length ? $el : null;
1536        }
1537    })();
1538});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.