PageSourceSearch

https://www.calagrana.com/assets/libs/select2/js/select2.js

js calagrana.com collected 2026-09-26 20:52:45 UTC 148,514 bytes, 5,746 lines download raw bytes

vendor: 5,220 bytes, lines 1-134
1/*!
2 * Select2 4.0.5
3 * https://select2.github.io
4 *
5 * Released under the MIT license
6 * https://github.com/select2/select2/blob/master/LICENSE.md
7 */
8(function (factory) {
9  if (typeof define === 'function' && define.amd) {
10    // AMD. Register as an anonymous module.
11    define(['jquery'], factory);
12  } else if (typeof module === 'object' && module.exports) {
13    // Node/CommonJS
14    module.exports = function (root, jQuery) {
15      if (jQuery === undefined) {
16        // require('jQuery') returns a factory that requires window to
17        // build a jQuery instance, we normalize how we use modules
18        // that require this pattern but the window provided is a noop
19        // if it's defined (how jquery works)
20        if (typeof window !== 'undefined') {
21          jQuery = require('jquery');
22        }
23        else {
24          jQuery = require('jquery')(root);
25        }
26      }
27      factory(jQuery);
28      return jQuery;
29    };
30  } else {
31    // Browser globals
32    factory(jQuery);
33  }
34} (function (jQuery) {
35  // This is needed so we can catch the AMD loader configuration and use it
36  // The inner file should be wrapped (by `banner.start.js`) in a function that
37  // returns the AMD loader references.
38  var S2 =(function () {
39  // Restore the Select2 AMD loader so it can be used
40  // Needed mostly in the language files, where the loader is not inserted
41  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
42    var S2 = jQuery.fn.select2.amd;
43  }
44var S2;(function () { if (!S2 || !S2.requirejs) {
45if (!S2) { S2 = {}; } else { require = S2; }
46/**
47 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
48 * Released under MIT license, http://github.com/requirejs/almond/LICENSE
49 */
50//Going sloppy to avoid 'use strict' string cost, but strict practices should
51//be followed.
52/*global setTimeout: false */
53
54var requirejs, require, define;
55(function (undef) {
56    var main, req, makeMap, handlers,
57        defined = {},
58        waiting = {},
59        config = {},
60        defining = {},
61        hasOwn = Object.prototype.hasOwnProperty,
62        aps = [].slice,
63        jsSuffixRegExp = /\.js$/;
64
65    function hasProp(obj, prop) {
66        return hasOwn.call(obj, prop);
67    }
68
69    /**
70     * Given a relative module name, like ./something, normalize it to
71     * a real name that can be mapped to a path.
72     * @param {String} name the relative name
73     * @param {String} baseName a real name that the name arg is relative
74     * to.
75     * @returns {String} normalized name
76     */
77    function normalize(name, baseName) {
78        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
79            foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
80            baseParts = baseName && baseName.split("/"),
81            map = config.map,
82            starMap = (map && map['*']) || {};
83
84        //Adjust any relative paths.
85        if (name) {
86            name = name.split('/');
87            lastIndex = name.length - 1;
88
89            // If wanting node ID compatibility, strip .js from end
90            // of IDs. Have to do this here, and not in nameToUrl
91            // because node allows either .js or non .js to map
92            // to same file.
93            if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
94                name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
95            }
96
97            // Starts with a '.' so need the baseName
98            if (name[0].charAt(0) === '.' && baseParts) {
99                //Convert baseName to array, and lop off the last part,
100                //so that . matches that 'directory' and not name of the baseName's
101                //module. For instance, baseName of 'one/two/three', maps to
102                //'one/two/three.js', but we want the directory, 'one/two' for
103                //this normalization.
104                normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
105                name = normalizedBaseParts.concat(name);
106            }
107
108            //start trimDots
109            for (i = 0; i < name.length; i++) {
110                part = name[i];
111                if (part === '.') {
112                    name.splice(i, 1);
113                    i -= 1;
114                } else if (part === '..') {
115                    // If at the start, or previous value is still ..,
116                    // keep them so that when converted to a path it may
117                    // still work when converted to a path, even though
118                    // as an ID it is less than ideal. In larger point
119                    // releases, may be better to just kick out an error.
120                    if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
121                        continue;
122                    } else if (i > 0) {
123                        name.splice(i - 1, 2);
124                        i -= 2;
125                    }
126                }
127            }
128            //end trimDots
129
130            name = name.join('/');
131        }
132
133        //Apply map config if available.
134        if ((baseParts || starMap) && map) {
vendor: 67,937 bytes, lines 135-2766
135            nameParts = name.split('/');
136
137            for (i = nameParts.length; i > 0; i -= 1) {
138                nameSegment = nameParts.slice(0, i).join("/");
139
140                if (baseParts) {
141                    //Find the longest baseName segment match in the config.
142                    //So, do joins on the biggest to smallest lengths of baseParts.
143                    for (j = baseParts.length; j > 0; j -= 1) {
144                        mapValue = map[baseParts.slice(0, j).join('/')];
145
146                        //baseName segment has  config, find if it has one for
147                        //this name.
148                        if (mapValue) {
149                            mapValue = mapValue[nameSegment];
150                            if (mapValue) {
151                                //Match, update name to the new value.
152                                foundMap = mapValue;
153                                foundI = i;
154                                break;
155                            }
156                        }
157                    }
158                }
159
160                if (foundMap) {
161                    break;
162                }
163
164                //Check for a star map match, but just hold on to it,
165                //if there is a shorter segment match later in a matching
166                //config, then favor over this star map.
167                if (!foundStarMap && starMap && starMap[nameSegment]) {
168                    foundStarMap = starMap[nameSegment];
169                    starI = i;
170                }
171            }
172
173            if (!foundMap && foundStarMap) {
174                foundMap = foundStarMap;
175                foundI = starI;
176            }
177
178            if (foundMap) {
179                nameParts.splice(0, foundI, foundMap);
180                name = nameParts.join('/');
181            }
182        }
183
184        return name;
185    }
186
187    function makeRequire(relName, forceSync) {
188        return function () {
189            //A version of a require function that passes a moduleName
190            //value for items that may need to
191            //look up paths relative to the moduleName
192            var args = aps.call(arguments, 0);
193
194            //If first arg is not require('string'), and there is only
195            //one arg, it is the array form without a callback. Insert
196            //a null so that the following concat is correct.
197            if (typeof args[0] !== 'string' && args.length === 1) {
198                args.push(null);
199            }
200            return req.apply(undef, args.concat([relName, forceSync]));
201        };
202    }
203
204    function makeNormalize(relName) {
205        return function (name) {
206            return normalize(name, relName);
207        };
208    }
209
210    function makeLoad(depName) {
211        return function (value) {
212            defined[depName] = value;
213        };
214    }
215
216    function callDep(name) {
217        if (hasProp(waiting, name)) {
218            var args = waiting[name];
219            delete waiting[name];
220            defining[name] = true;
221            main.apply(undef, args);
222        }
223
224        if (!hasProp(defined, name) && !hasProp(defining, name)) {
225            throw new Error('No ' + name);
226        }
227        return defined[name];
228    }
229
230    //Turns a plugin!resource to [plugin, resource]
231    //with the plugin being undefined if the name
232    //did not have a plugin prefix.
233    function splitPrefix(name) {
234        var prefix,
235            index = name ? name.indexOf('!') : -1;
236        if (index > -1) {
237            prefix = name.substring(0, index);
238            name = name.substring(index + 1, name.length);
239        }
240        return [prefix, name];
241    }
242
243    //Creates a parts array for a relName where first part is plugin ID,
244    //second part is resource ID. Assumes relName has already been normalized.
245    function makeRelParts(relName) {
246        return relName ? splitPrefix(relName) : [];
247    }
248
249    /**
250     * Makes a name map, normalizing the name, and using a plugin
251     * for normalization if necessary. Grabs a ref to plugin
252     * too, as an optimization.
253     */
254    makeMap = function (name, relParts) {
255        var plugin,
256            parts = splitPrefix(name),
257            prefix = parts[0],
258            relResourceName = relParts[1];
259
260        name = parts[1];
261
262        if (prefix) {
263            prefix = normalize(prefix, relResourceName);
264            plugin = callDep(prefix);
265        }
266
267        //Normalize according
268        if (prefix) {
269            if (plugin && plugin.normalize) {
270                name = plugin.normalize(name, makeNormalize(relResourceName));
271            } else {
272                name = normalize(name, relResourceName);
273            }
274        } else {
275            name = normalize(name, relResourceName);
276            parts = splitPrefix(name);
277            prefix = parts[0];
278            name = parts[1];
279            if (prefix) {
280                plugin = callDep(prefix);
281            }
282        }
283
284        //Using ridiculous property names for space reasons
285        return {
286            f: prefix ? prefix + '!' + name : name, //fullName
287            n: name,
288            pr: prefix,
289            p: plugin
290        };
291    };
292
293    function makeConfig(name) {
294        return function () {
295            return (config && config.config && config.config[name]) || {};
296        };
297    }
298
299    handlers = {
300        require: function (name) {
301            return makeRequire(name);
302        },
303        exports: function (name) {
304            var e = defined[name];
305            if (typeof e !== 'undefined') {
306                return e;
307            } else {
308                return (defined[name] = {});
309            }
310        },
311        module: function (name) {
312            return {
313                id: name,
314                uri: '',
315                exports: defined[name],
316                config: makeConfig(name)
317            };
318        }
319    };
320
321    main = function (name, deps, callback, relName) {
322        var cjsModule, depName, ret, map, i, relParts,
323            args = [],
324            callbackType = typeof callback,
325            usingExports;
326
327        //Use name if no relName
328        relName = relName || name;
329        relParts = makeRelParts(relName);
330
331        //Call the callback to define the module, if necessary.
332        if (callbackType === 'undefined' || callbackType === 'function') {
333            //Pull out the defined dependencies and pass the ordered
334            //values to the callback.
335            //Default to [require, exports, module] if no deps
336            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
337            for (i = 0; i < deps.length; i += 1) {
338                map = makeMap(deps[i], relParts);
339                depName = map.f;
340
341                //Fast path CommonJS standard dependencies.
342                if (depName === "require") {
343                    args[i] = handlers.require(name);
344                } else if (depName === "exports") {
345                    //CommonJS module spec 1.1
346                    args[i] = handlers.exports(name);
347                    usingExports = true;
348                } else if (depName === "module") {
349                    //CommonJS module spec 1.1
350                    cjsModule = args[i] = handlers.module(name);
351                } else if (hasProp(defined, depName) ||
352                           hasProp(waiting, depName) ||
353                           hasProp(defining, depName)) {
354                    args[i] = callDep(depName);
355                } else if (map.p) {
356                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
357                    args[i] = defined[depName];
358                } else {
359                    throw new Error(name + ' missing ' + depName);
360                }
361            }
362
363            ret = callback ? callback.apply(defined[name], args) : undefined;
364
365            if (name) {
366                //If setting exports via "module" is in play,
367                //favor that over return value and exports. After that,
368                //favor a non-undefined return value over exports use.
369                if (cjsModule && cjsModule.exports !== undef &&
370                        cjsModule.exports !== defined[name]) {
371                    defined[name] = cjsModule.exports;
372                } else if (ret !== undef || !usingExports) {
373                    //Use the return value from the function.
374                    defined[name] = ret;
375                }
376            }
377        } else if (name) {
378            //May just be an object definition for the module. Only
379            //worry about defining if have a module name.
380            defined[name] = callback;
381        }
382    };
383
384    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
385        if (typeof deps === "string") {
386            if (handlers[deps]) {
387                //callback in this case is really relName
388                return handlers[deps](callback);
389            }
390            //Just return the module wanted. In this scenario, the
391            //deps arg is the module name, and second arg (if passed)
392            //is just the relName.
393            //Normalize module name, if it contains . or ..
394            return callDep(makeMap(deps, makeRelParts(callback)).f);
395        } else if (!deps.splice) {
396            //deps is a config object, not an array.
397            config = deps;
398            if (config.deps) {
399                req(config.deps, config.callback);
400            }
401            if (!callback) {
402                return;
403            }
404
405            if (callback.splice) {
406                //callback is an array, which means it is a dependency list.
407                //Adjust args if there are dependencies
408                deps = callback;
409                callback = relName;
410                relName = null;
411            } else {
412                deps = undef;
413            }
414        }
415
416        //Support require(['a'])
417        callback = callback || function () {};
418
419        //If relName is a function, it is an errback handler,
420        //so remove it.
421        if (typeof relName === 'function') {
422            relName = forceSync;
423            forceSync = alt;
424        }
425
426        //Simulate async callback;
427        if (forceSync) {
428            main(undef, deps, callback, relName);
429        } else {
430            //Using a non-zero value because of concern for what old browsers
431            //do, and latest browsers "upgrade" to 4 if lower value is used:
432            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
433            //If want a value immediately, use require('id') instead -- something
434            //that works in almond on the global level, but not guaranteed and
435            //unlikely to work in other AMD implementations.
436            setTimeout(function () {
437                main(undef, deps, callback, relName);
438            }, 4);
439        }
440
441        return req;
442    };
443
444    /**
445     * Just drops the config on the floor, but returns req in case
446     * the config return value is used.
447     */
448    req.config = function (cfg) {
449        return req(cfg);
450    };
451
452    /**
453     * Expose module registry for debugging and tooling
454     */
455    requirejs._defined = defined;
456
457    define = function (name, deps, callback) {
458        if (typeof name !== 'string') {
459            throw new Error('See almond README: incorrect module build, no module name');
460        }
461
462        //This module may not have dependencies
463        if (!deps.splice) {
464            //deps is not an array, so probably means
465            //an object literal or factory function for
466            //the value. Adjust args.
467            callback = deps;
468            deps = [];
469        }
470
471        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
472            waiting[name] = [name, deps, callback];
473        }
474    };
475
476    define.amd = {
477        jQuery: true
478    };
479}());
480
481S2.requirejs = requirejs;S2.require = require;S2.define = define;
482}
483}());
484S2.define("almond", function(){});
485
486/* global jQuery:false, $:false */
487S2.define('jquery',[],function () {
488  var _$ = jQuery || $;
489
490  if (_$ == null && console && console.error) {
491    console.error(
492      'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
493      'found. Make sure that you are including jQuery before Select2 on your ' +
494      'web page.'
495    );
496  }
497
498  return _$;
499});
500
501S2.define('select2/utils',[
502  'jquery'
503], function ($) {
504  var Utils = {};
505
506  Utils.Extend = function (ChildClass, SuperClass) {
507    var __hasProp = {}.hasOwnProperty;
508
509    function BaseConstructor () {
510      this.constructor = ChildClass;
511    }
512
513    for (var key in SuperClass) {
514      if (__hasProp.call(SuperClass, key)) {
515        ChildClass[key] = SuperClass[key];
516      }
517    }
518
519    BaseConstructor.prototype = SuperClass.prototype;
520    ChildClass.prototype = new BaseConstructor();
521    ChildClass.__super__ = SuperClass.prototype;
522
523    return ChildClass;
524  };
525
526  function getMethods (theClass) {
527    var proto = theClass.prototype;
528
529    var methods = [];
530
531    for (var methodName in proto) {
532      var m = proto[methodName];
533
534      if (typeof m !== 'function') {
535        continue;
536      }
537
538      if (methodName === 'constructor') {
539        continue;
540      }
541
542      methods.push(methodName);
543    }
544
545    return methods;
546  }
547
548  Utils.Decorate = function (SuperClass, DecoratorClass) {
549    var decoratedMethods = getMethods(DecoratorClass);
550    var superMethods = getMethods(SuperClass);
551
552    function DecoratedClass () {
553      var unshift = Array.prototype.unshift;
554
555      var argCount = DecoratorClass.prototype.constructor.length;
556
557      var calledConstructor = SuperClass.prototype.constructor;
558
559      if (argCount > 0) {
560        unshift.call(arguments, SuperClass.prototype.constructor);
561
562        calledConstructor = DecoratorClass.prototype.constructor;
563      }
564
565      calledConstructor.apply(this, arguments);
566    }
567
568    DecoratorClass.displayName = SuperClass.displayName;
569
570    function ctr () {
571      this.constructor = DecoratedClass;
572    }
573
574    DecoratedClass.prototype = new ctr();
575
576    for (var m = 0; m < superMethods.length; m++) {
577        var superMethod = superMethods[m];
578
579        DecoratedClass.prototype[superMethod] =
580          SuperClass.prototype[superMethod];
581    }
582
583    var calledMethod = function (methodName) {
584      // Stub out the original method if it's not decorating an actual method
585      var originalMethod = function () {};
586
587      if (methodName in DecoratedClass.prototype) {
588        originalMethod = DecoratedClass.prototype[methodName];
589      }
590
591      var decoratedMethod = DecoratorClass.prototype[methodName];
592
593      return function () {
594        var unshift = Array.prototype.unshift;
595
596        unshift.call(arguments, originalMethod);
597
598        return decoratedMethod.apply(this, arguments);
599      };
600    };
601
602    for (var d = 0; d < decoratedMethods.length; d++) {
603      var decoratedMethod = decoratedMethods[d];
604
605      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
606    }
607
608    return DecoratedClass;
609  };
610
611  var Observable = function () {
612    this.listeners = {};
613  };
614
615  Observable.prototype.on = function (event, callback) {
616    this.listeners = this.listeners || {};
617
618    if (event in this.listeners) {
619      this.listeners[event].push(callback);
620    } else {
621      this.listeners[event] = [callback];
622    }
623  };
624
625  Observable.prototype.trigger = function (event) {
626    var slice = Array.prototype.slice;
627    var params = slice.call(arguments, 1);
628
629    this.listeners = this.listeners || {};
630
631    // Params should always come in as an array
632    if (params == null) {
633      params = [];
634    }
635
636    // If there are no arguments to the event, use a temporary object
637    if (params.length === 0) {
638      params.push({});
639    }
640
641    // Set the `_type` of the first object to the event
642    params[0]._type = event;
643
644    if (event in this.listeners) {
645      this.invoke(this.listeners[event], slice.call(arguments, 1));
646    }
647
648    if ('*' in this.listeners) {
649      this.invoke(this.listeners['*'], arguments);
650    }
651  };
652
653  Observable.prototype.invoke = function (listeners, params) {
654    for (var i = 0, len = listeners.length; i < len; i++) {
655      listeners[i].apply(this, params);
656    }
657  };
658
659  Utils.Observable = Observable;
660
661  Utils.generateChars = function (length) {
662    var chars = '';
663
664    for (var i = 0; i < length; i++) {
665      var randomChar = Math.floor(Math.random() * 36);
666      chars += randomChar.toString(36);
667    }
668
669    return chars;
670  };
671
672  Utils.bind = function (func, context) {
673    return function () {
674      func.apply(context, arguments);
675    };
676  };
677
678  Utils._convertData = function (data) {
679    for (var originalKey in data) {
680      var keys = originalKey.split('-');
681
682      var dataLevel = data;
683
684      if (keys.length === 1) {
685        continue;
686      }
687
688      for (var k = 0; k < keys.length; k++) {
689        var key = keys[k];
690
691        // Lowercase the first letter
692        // By default, dash-separated becomes camelCase
693        key = key.substring(0, 1).toLowerCase() + key.substring(1);
694
695        if (!(key in dataLevel)) {
696          dataLevel[key] = {};
697        }
698
699        if (k == keys.length - 1) {
700          dataLevel[key] = data[originalKey];
701        }
702
703        dataLevel = dataLevel[key];
704      }
705
706      delete data[originalKey];
707    }
708
709    return data;
710  };
711
712  Utils.hasScroll = function (index, el) {
713    // Adapted from the function created by @ShadowScripter
714    // and adapted by @BillBarry on the Stack Exchange Code Review website.
715    // The original code can be found at
716    // http://codereview.stackexchange.com/q/13338
717    // and was designed to be used with the Sizzle selector engine.
718
719    var $el = $(el);
720    var overflowX = el.style.overflowX;
721    var overflowY = el.style.overflowY;
722
723    //Check both x and y declarations
724    if (overflowX === overflowY &&
725        (overflowY === 'hidden' || overflowY === 'visible')) {
726      return false;
727    }
728
729    if (overflowX === 'scroll' || overflowY === 'scroll') {
730      return true;
731    }
732
733    return ($el.innerHeight() < el.scrollHeight ||
734      $el.innerWidth() < el.scrollWidth);
735  };
736
737  Utils.escapeMarkup = function (markup) {
738    var replaceMap = {
739      '\\': '&#92;',
740      '&': '&amp;',
741      '<': '&lt;',
742      '>': '&gt;',
743      '"': '&quot;',
744      '\'': '&#39;',
745      '/': '&#47;'
746    };
747
748    // Do not try to escape the markup if it's not a string
749    if (typeof markup !== 'string') {
750      return markup;
751    }
752
753    return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
754      return replaceMap[match];
755    });
756  };
757
758  // Append an array of jQuery nodes to a given element.
759  Utils.appendMany = function ($element, $nodes) {
760    // jQuery 1.7.x does not support $.fn.append() with an array
761    // Fall back to a jQuery object collection using $.fn.add()
762    if ($.fn.jquery.substr(0, 3) === '1.7') {
763      var $jqNodes = $();
764
765      $.map($nodes, function (node) {
766        $jqNodes = $jqNodes.add(node);
767      });
768
769      $nodes = $jqNodes;
770    }
771
772    $element.append($nodes);
773  };
774
775  return Utils;
776});
777
778S2.define('select2/results',[
779  'jquery',
780  './utils'
781], function ($, Utils) {
782  function Results ($element, options, dataAdapter) {
783    this.$element = $element;
784    this.data = dataAdapter;
785    this.options = options;
786
787    Results.__super__.constructor.call(this);
788  }
789
790  Utils.Extend(Results, Utils.Observable);
791
792  Results.prototype.render = function () {
793    var $results = $(
794      '<ul class="select2-results__options" role="tree"></ul>'
795    );
796
797    if (this.options.get('multiple')) {
798      $results.attr('aria-multiselectable', 'true');
799    }
800
801    this.$results = $results;
802
803    return $results;
804  };
805
806  Results.prototype.clear = function () {
807    this.$results.empty();
808  };
809
810  Results.prototype.displayMessage = function (params) {
811    var escapeMarkup = this.options.get('escapeMarkup');
812
813    this.clear();
814    this.hideLoading();
815
816    var $message = $(
817      '<li role="treeitem" aria-live="assertive"' +
818      ' class="select2-results__option"></li>'
819    );
820
821    var message = this.options.get('translations').get(params.message);
822
823    $message.append(
824      escapeMarkup(
825        message(params.args)
826      )
827    );
828
829    $message[0].className += ' select2-results__message';
830
831    this.$results.append($message);
832  };
833
834  Results.prototype.hideMessages = function () {
835    this.$results.find('.select2-results__message').remove();
836  };
837
838  Results.prototype.append = function (data) {
839    this.hideLoading();
840
841    var $options = [];
842
843    if (data.results == null || data.results.length === 0) {
844      if (this.$results.children().length === 0) {
845        this.trigger('results:message', {
846          message: 'noResults'
847        });
848      }
849
850      return;
851    }
852
853    data.results = this.sort(data.results);
854
855    for (var d = 0; d < data.results.length; d++) {
856      var item = data.results[d];
857
858      var $option = this.option(item);
859
860      $options.push($option);
861    }
862
863    this.$results.append($options);
864  };
865
866  Results.prototype.position = function ($results, $dropdown) {
867    var $resultsContainer = $dropdown.find('.select2-results');
868    $resultsContainer.append($results);
869  };
870
871  Results.prototype.sort = function (data) {
872    var sorter = this.options.get('sorter');
873
874    return sorter(data);
875  };
876
877  Results.prototype.highlightFirstItem = function () {
878    var $options = this.$results
879      .find('.select2-results__option[aria-selected]');
880
881    var $selected = $options.filter('[aria-selected=true]');
882
883    // Check if there are any selected options
884    if ($selected.length > 0) {
885      // If there are selected options, highlight the first
886      $selected.first().trigger('mouseenter');
887    } else {
888      // If there are no selected options, highlight the first option
889      // in the dropdown
890      $options.first().trigger('mouseenter');
891    }
892
893    this.ensureHighlightVisible();
894  };
895
896  Results.prototype.setClasses = function () {
897    var self = this;
898
899    this.data.current(function (selected) {
900      var selectedIds = $.map(selected, function (s) {
901        return s.id.toString();
902      });
903
904      var $options = self.$results
905        .find('.select2-results__option[aria-selected]');
906
907      $options.each(function () {
908        var $option = $(this);
909
910        var item = $.data(this, 'data');
911
912        // id needs to be converted to a string when comparing
913        var id = '' + item.id;
914
915        if ((item.element != null && item.element.selected) ||
916            (item.element == null && $.inArray(id, selectedIds) > -1)) {
917          $option.attr('aria-selected', 'true');
918        } else {
919          $option.attr('aria-selected', 'false');
920        }
921      });
922
923    });
924  };
925
926  Results.prototype.showLoading = function (params) {
927    this.hideLoading();
928
929    var loadingMore = this.options.get('translations').get('searching');
930
931    var loading = {
932      disabled: true,
933      loading: true,
934      text: loadingMore(params)
935    };
936    var $loading = this.option(loading);
937    $loading.className += ' loading-results';
938
939    this.$results.prepend($loading);
940  };
941
942  Results.prototype.hideLoading = function () {
943    this.$results.find('.loading-results').remove();
944  };
945
946  Results.prototype.option = function (data) {
947    var option = document.createElement('li');
948    option.className = 'select2-results__option';
949
950    var attrs = {
951      'role': 'treeitem',
952      'aria-selected': 'false'
953    };
954
955    if (data.disabled) {
956      delete attrs['aria-selected'];
957      attrs['aria-disabled'] = 'true';
958    }
959
960    if (data.id == null) {
961      delete attrs['aria-selected'];
962    }
963
964    if (data._resultId != null) {
965      option.id = data._resultId;
966    }
967
968    if (data.title) {
969      option.title = data.title;
970    }
971
972    if (data.children) {
973      attrs.role = 'group';
974      attrs['aria-label'] = data.text;
975      delete attrs['aria-selected'];
976    }
977
978    for (var attr in attrs) {
979      var val = attrs[attr];
980
981      option.setAttribute(attr, val);
982    }
983
984    if (data.children) {
985      var $option = $(option);
986
987      var label = document.createElement('strong');
988      label.className = 'select2-results__group';
989
990      var $label = $(label);
991      this.template(data, label);
992
993      var $children = [];
994
995      for (var c = 0; c < data.children.length; c++) {
996        var child = data.children[c];
997
998        var $child = this.option(child);
999
1000        $children.push($child);
1001      }
1002
1003      var $childrenContainer = $('<ul></ul>', {
1004        'class': 'select2-results__options select2-results__options--nested'
1005      });
1006
1007      $childrenContainer.append($children);
1008
1009      $option.append(label);
1010      $option.append($childrenContainer);
1011    } else {
1012      this.template(data, option);
1013    }
1014
1015    $.data(option, 'data', data);
1016
1017    return option;
1018  };
1019
1020  Results.prototype.bind = function (container, $container) {
1021    var self = this;
1022
1023    var id = container.id + '-results';
1024
1025    this.$results.attr('id', id);
1026
1027    container.on('results:all', function (params) {
1028      self.clear();
1029      self.append(params.data);
1030
1031      if (container.isOpen()) {
1032        self.setClasses();
1033        self.highlightFirstItem();
1034      }
1035    });
1036
1037    container.on('results:append', function (params) {
1038      self.append(params.data);
1039
1040      if (container.isOpen()) {
1041        self.setClasses();
1042      }
1043    });
1044
1045    container.on('query', function (params) {
1046      self.hideMessages();
1047      self.showLoading(params);
1048    });
1049
1050    container.on('select', function () {
1051      if (!container.isOpen()) {
1052        return;
1053      }
1054
1055      self.setClasses();
1056      self.highlightFirstItem();
1057    });
1058
1059    container.on('unselect', function () {
1060      if (!container.isOpen()) {
1061        return;
1062      }
1063
1064      self.setClasses();
1065      self.highlightFirstItem();
1066    });
1067
1068    container.on('open', function () {
1069      // When the dropdown is open, aria-expended="true"
1070      self.$results.attr('aria-expanded', 'true');
1071      self.$results.attr('aria-hidden', 'false');
1072
1073      self.setClasses();
1074      self.ensureHighlightVisible();
1075    });
1076
1077    container.on('close', function () {
1078      // When the dropdown is closed, aria-expended="false"
1079      self.$results.attr('aria-expanded', 'false');
1080      self.$results.attr('aria-hidden', 'true');
1081      self.$results.removeAttr('aria-activedescendant');
1082    });
1083
1084    container.on('results:toggle', function () {
1085      var $highlighted = self.getHighlightedResults();
1086
1087      if ($highlighted.length === 0) {
1088        return;
1089      }
1090
1091      $highlighted.trigger('mouseup');
1092    });
1093
1094    container.on('results:select', function () {
1095      var $highlighted = self.getHighlightedResults();
1096
1097      if ($highlighted.length === 0) {
1098        return;
1099      }
1100
1101      var data = $highlighted.data('data');
1102
1103      if ($highlighted.attr('aria-selected') == 'true') {
1104        self.trigger('close', {});
1105      } else {
1106        self.trigger('select', {
1107          data: data
1108        });
1109      }
1110    });
1111
1112    container.on('results:previous', function () {
1113      var $highlighted = self.getHighlightedResults();
1114
1115      var $options = self.$results.find('[aria-selected]');
1116
1117      var currentIndex = $options.index($highlighted);
1118
1119      // If we are already at te top, don't move further
1120      if (currentIndex === 0) {
1121        return;
1122      }
1123
1124      var nextIndex = currentIndex - 1;
1125
1126      // If none are highlighted, highlight the first
1127      if ($highlighted.length === 0) {
1128        nextIndex = 0;
1129      }
1130
1131      var $next = $options.eq(nextIndex);
1132
1133      $next.trigger('mouseenter');
1134
1135      var currentOffset = self.$results.offset().top;
1136      var nextTop = $next.offset().top;
1137      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
1138
1139      if (nextIndex === 0) {
1140        self.$results.scrollTop(0);
1141      } else if (nextTop - currentOffset < 0) {
1142        self.$results.scrollTop(nextOffset);
1143      }
1144    });
1145
1146    container.on('results:next', function () {
1147      var $highlighted = self.getHighlightedResults();
1148
1149      var $options = self.$results.find('[aria-selected]');
1150
1151      var currentIndex = $options.index($highlighted);
1152
1153      var nextIndex = currentIndex + 1;
1154
1155      // If we are at the last option, stay there
1156      if (nextIndex >= $options.length) {
1157        return;
1158      }
1159
1160      var $next = $options.eq(nextIndex);
1161
1162      $next.trigger('mouseenter');
1163
1164      var currentOffset = self.$results.offset().top +
1165        self.$results.outerHeight(false);
1166      var nextBottom = $next.offset().top + $next.outerHeight(false);
1167      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
1168
1169      if (nextIndex === 0) {
1170        self.$results.scrollTop(0);
1171      } else if (nextBottom > currentOffset) {
1172        self.$results.scrollTop(nextOffset);
1173      }
1174    });
1175
1176    container.on('results:focus', function (params) {
1177      params.element.addClass('select2-results__option--highlighted');
1178    });
1179
1180    container.on('results:message', function (params) {
1181      self.displayMessage(params);
1182    });
1183
1184    if ($.fn.mousewheel) {
1185      this.$results.on('mousewheel', function (e) {
1186        var top = self.$results.scrollTop();
1187
1188        var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
1189
1190        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
1191        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
1192
1193        if (isAtTop) {
1194          self.$results.scrollTop(0);
1195
1196          e.preventDefault();
1197          e.stopPropagation();
1198        } else if (isAtBottom) {
1199          self.$results.scrollTop(
1200            self.$results.get(0).scrollHeight - self.$results.height()
1201          );
1202
1203          e.preventDefault();
1204          e.stopPropagation();
1205        }
1206      });
1207    }
1208
1209    this.$results.on('mouseup', '.select2-results__option[aria-selected]',
1210      function (evt) {
1211      var $this = $(this);
1212
1213      var data = $this.data('data');
1214
1215      if ($this.attr('aria-selected') === 'true') {
1216        if (self.options.get('multiple')) {
1217          self.trigger('unselect', {
1218            originalEvent: evt,
1219            data: data
1220          });
1221        } else {
1222          self.trigger('close', {});
1223        }
1224
1225        return;
1226      }
1227
1228      self.trigger('select', {
1229        originalEvent: evt,
1230        data: data
1231      });
1232    });
1233
1234    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
1235      function (evt) {
1236      var data = $(this).data('data');
1237
1238      self.getHighlightedResults()
1239          .removeClass('select2-results__option--highlighted');
1240
1241      self.trigger('results:focus', {
1242        data: data,
1243        element: $(this)
1244      });
1245    });
1246  };
1247
1248  Results.prototype.getHighlightedResults = function () {
1249    var $highlighted = this.$results
1250    .find('.select2-results__option--highlighted');
1251
1252    return $highlighted;
1253  };
1254
1255  Results.prototype.destroy = function () {
1256    this.$results.remove();
1257  };
1258
1259  Results.prototype.ensureHighlightVisible = function () {
1260    var $highlighted = this.getHighlightedResults();
1261
1262    if ($highlighted.length === 0) {
1263      return;
1264    }
1265
1266    var $options = this.$results.find('[aria-selected]');
1267
1268    var currentIndex = $options.index($highlighted);
1269
1270    var currentOffset = this.$results.offset().top;
1271    var nextTop = $highlighted.offset().top;
1272    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
1273
1274    var offsetDelta = nextTop - currentOffset;
1275    nextOffset -= $highlighted.outerHeight(false) * 2;
1276
1277    if (currentIndex <= 2) {
1278      this.$results.scrollTop(0);
1279    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
1280      this.$results.scrollTop(nextOffset);
1281    }
1282  };
1283
1284  Results.prototype.template = function (result, container) {
1285    var template = this.options.get('templateResult');
1286    var escapeMarkup = this.options.get('escapeMarkup');
1287
1288    var content = template(result, container);
1289
1290    if (content == null) {
1291      container.style.display = 'none';
1292    } else if (typeof content === 'string') {
1293      container.innerHTML = escapeMarkup(content);
1294    } else {
1295      $(container).append(content);
1296    }
1297  };
1298
1299  return Results;
1300});
1301
1302S2.define('select2/keys',[
1303
1304], function () {
1305  var KEYS = {
1306    BACKSPACE: 8,
1307    TAB: 9,
1308    ENTER: 13,
1309    SHIFT: 16,
1310    CTRL: 17,
1311    ALT: 18,
1312    ESC: 27,
1313    SPACE: 32,
1314    PAGE_UP: 33,
1315    PAGE_DOWN: 34,
1316    END: 35,
1317    HOME: 36,
1318    LEFT: 37,
1319    UP: 38,
1320    RIGHT: 39,
1321    DOWN: 40,
1322    DELETE: 46
1323  };
1324
1325  return KEYS;
1326});
1327
1328S2.define('select2/selection/base',[
1329  'jquery',
1330  '../utils',
1331  '../keys'
1332], function ($, Utils, KEYS) {
1333  function BaseSelection ($element, options) {
1334    this.$element = $element;
1335    this.options = options;
1336
1337    BaseSelection.__super__.constructor.call(this);
1338  }
1339
1340  Utils.Extend(BaseSelection, Utils.Observable);
1341
1342  BaseSelection.prototype.render = function () {
1343    var $selection = $(
1344      '<span class="select2-selection" role="combobox" ' +
1345      ' aria-haspopup="true" aria-expanded="false">' +
1346      '</span>'
1347    );
1348
1349    this._tabindex = 0;
1350
1351    if (this.$element.data('old-tabindex') != null) {
1352      this._tabindex = this.$element.data('old-tabindex');
1353    } else if (this.$element.attr('tabindex') != null) {
1354      this._tabindex = this.$element.attr('tabindex');
1355    }
1356
1357    $selection.attr('title', this.$element.attr('title'));
1358    $selection.attr('tabindex', this._tabindex);
1359
1360    this.$selection = $selection;
1361
1362    return $selection;
1363  };
1364
1365  BaseSelection.prototype.bind = function (container, $container) {
1366    var self = this;
1367
1368    var id = container.id + '-container';
1369    var resultsId = container.id + '-results';
1370
1371    this.container = container;
1372
1373    this.$selection.on('focus', function (evt) {
1374      self.trigger('focus', evt);
1375    });
1376
1377    this.$selection.on('blur', function (evt) {
1378      self._handleBlur(evt);
1379    });
1380
1381    this.$selection.on('keydown', function (evt) {
1382      self.trigger('keypress', evt);
1383
1384      if (evt.which === KEYS.SPACE) {
1385        evt.preventDefault();
1386      }
1387    });
1388
1389    container.on('results:focus', function (params) {
1390      self.$selection.attr('aria-activedescendant', params.data._resultId);
1391    });
1392
1393    container.on('selection:update', function (params) {
1394      self.update(params.data);
1395    });
1396
1397    container.on('open', function () {
1398      // When the dropdown is open, aria-expanded="true"
1399      self.$selection.attr('aria-expanded', 'true');
1400      self.$selection.attr('aria-owns', resultsId);
1401
1402      self._attachCloseHandler(container);
1403    });
1404
1405    container.on('close', function () {
1406      // When the dropdown is closed, aria-expanded="false"
1407      self.$selection.attr('aria-expanded', 'false');
1408      self.$selection.removeAttr('aria-activedescendant');
1409      self.$selection.removeAttr('aria-owns');
1410
1411      self.$selection.focus();
1412
1413      self._detachCloseHandler(container);
1414    });
1415
1416    container.on('enable', function () {
1417      self.$selection.attr('tabindex', self._tabindex);
1418    });
1419
1420    container.on('disable', function () {
1421      self.$selection.attr('tabindex', '-1');
1422    });
1423  };
1424
1425  BaseSelection.prototype._handleBlur = function (evt) {
1426    var self = this;
1427
1428    // This needs to be delayed as the active element is the body when the tab
1429    // key is pressed, possibly along with others.
1430    window.setTimeout(function () {
1431      // Don't trigger `blur` if the focus is still in the selection
1432      if (
1433        (document.activeElement == self.$selection[0]) ||
1434        ($.contains(self.$selection[0], document.activeElement))
1435      ) {
1436        return;
1437      }
1438
1439      self.trigger('blur', evt);
1440    }, 1);
1441  };
1442
1443  BaseSelection.prototype._attachCloseHandler = function (container) {
1444    var self = this;
1445
1446    $(document.body).on('mousedown.select2.' + container.id, function (e) {
1447      var $target = $(e.target);
1448
1449      var $select = $target.closest('.select2');
1450
1451      var $all = $('.select2.select2-container--open');
1452
1453      $all.each(function () {
1454        var $this = $(this);
1455
1456        if (this == $select[0]) {
1457          return;
1458        }
1459
1460        var $element = $this.data('element');
1461
1462        $element.select2('close');
1463      });
1464    });
1465  };
1466
1467  BaseSelection.prototype._detachCloseHandler = function (container) {
1468    $(document.body).off('mousedown.select2.' + container.id);
1469  };
1470
1471  BaseSelection.prototype.position = function ($selection, $container) {
1472    var $selectionContainer = $container.find('.selection');
1473    $selectionContainer.append($selection);
1474  };
1475
1476  BaseSelection.prototype.destroy = function () {
1477    this._detachCloseHandler(this.container);
1478  };
1479
1480  BaseSelection.prototype.update = function (data) {
1481    throw new Error('The `update` method must be defined in child classes.');
1482  };
1483
1484  return BaseSelection;
1485});
1486
1487S2.define('select2/selection/single',[
1488  'jquery',
1489  './base',
1490  '../utils',
1491  '../keys'
1492], function ($, BaseSelection, Utils, KEYS) {
1493  function SingleSelection () {
1494    SingleSelection.__super__.constructor.apply(this, arguments);
1495  }
1496
1497  Utils.Extend(SingleSelection, BaseSelection);
1498
1499  SingleSelection.prototype.render = function () {
1500    var $selection = SingleSelection.__super__.render.call(this);
1501
1502    $selection.addClass('select2-selection--single');
1503
1504    $selection.html(
1505      '<span class="select2-selection__rendered"></span>' +
1506      '<span class="select2-selection__arrow" role="presentation">' +
1507        '<b role="presentation"></b>' +
1508      '</span>'
1509    );
1510
1511    return $selection;
1512  };
1513
1514  SingleSelection.prototype.bind = function (container, $container) {
1515    var self = this;
1516
1517    SingleSelection.__super__.bind.apply(this, arguments);
1518
1519    var id = container.id + '-container';
1520
1521    this.$selection.find('.select2-selection__rendered').attr('id', id);
1522    this.$selection.attr('aria-labelledby', id);
1523
1524    this.$selection.on('mousedown', function (evt) {
1525      // Only respond to left clicks
1526      if (evt.which !== 1) {
1527        return;
1528      }
1529
1530      self.trigger('toggle', {
1531        originalEvent: evt
1532      });
1533    });
1534
1535    this.$selection.on('focus', function (evt) {
1536      // User focuses on the container
1537    });
1538
1539    this.$selection.on('blur', function (evt) {
1540      // User exits the container
1541    });
1542
1543    container.on('focus', function (evt) {
1544      if (!container.isOpen()) {
1545        self.$selection.focus();
1546      }
1547    });
1548
1549    container.on('selection:update', function (params) {
1550      self.update(params.data);
1551    });
1552  };
1553
1554  SingleSelection.prototype.clear = function () {
1555    this.$selection.find('.select2-selection__rendered').empty();
1556  };
1557
1558  SingleSelection.prototype.display = function (data, container) {
1559    var template = this.options.get('templateSelection');
1560    var escapeMarkup = this.options.get('escapeMarkup');
1561
1562    return escapeMarkup(template(data, container));
1563  };
1564
1565  SingleSelection.prototype.selectionContainer = function () {
1566    return $('<span></span>');
1567  };
1568
1569  SingleSelection.prototype.update = function (data) {
1570    if (data.length === 0) {
1571      this.clear();
1572      return;
1573    }
1574
1575    var selection = data[0];
1576
1577    var $rendered = this.$selection.find('.select2-selection__rendered');
1578    var formatted = this.display(selection, $rendered);
1579
1580    $rendered.empty().append(formatted);
1581    $rendered.prop('title', selection.title || selection.text);
1582  };
1583
1584  return SingleSelection;
1585});
1586
1587S2.define('select2/selection/multiple',[
1588  'jquery',
1589  './base',
1590  '../utils'
1591], function ($, BaseSelection, Utils) {
1592  function MultipleSelection ($element, options) {
1593    MultipleSelection.__super__.constructor.apply(this, arguments);
1594  }
1595
1596  Utils.Extend(MultipleSelection, BaseSelection);
1597
1598  MultipleSelection.prototype.render = function () {
1599    var $selection = MultipleSelection.__super__.render.call(this);
1600
1601    $selection.addClass('select2-selection--multiple');
1602
1603    $selection.html(
1604      '<ul class="select2-selection__rendered"></ul>'
1605    );
1606
1607    return $selection;
1608  };
1609
1610  MultipleSelection.prototype.bind = function (container, $container) {
1611    var self = this;
1612
1613    MultipleSelection.__super__.bind.apply(this, arguments);
1614
1615    this.$selection.on('click', function (evt) {
1616      self.trigger('toggle', {
1617        originalEvent: evt
1618      });
1619    });
1620
1621    this.$selection.on(
1622      'click',
1623      '.select2-selection__choice__remove',
1624      function (evt) {
1625        // Ignore the event if it is disabled
1626        if (self.options.get('disabled')) {
1627          return;
1628        }
1629
1630        var $remove = $(this);
1631        var $selection = $remove.parent();
1632
1633        var data = $selection.data('data');
1634
1635        self.trigger('unselect', {
1636          originalEvent: evt,
1637          data: data
1638        });
1639      }
1640    );
1641  };
1642
1643  MultipleSelection.prototype.clear = function () {
1644    this.$selection.find('.select2-selection__rendered').empty();
1645  };
1646
1647  MultipleSelection.prototype.display = function (data, container) {
1648    var template = this.options.get('templateSelection');
1649    var escapeMarkup = this.options.get('escapeMarkup');
1650
1651    return escapeMarkup(template(data, container));
1652  };
1653
1654  MultipleSelection.prototype.selectionContainer = function () {
1655    var $container = $(
1656      '<li class="select2-selection__choice">' +
1657        '<span class="select2-selection__choice__remove" role="presentation">' +
1658          '&times;' +
1659        '</span>' +
1660      '</li>'
1661    );
1662
1663    return $container;
1664  };
1665
1666  MultipleSelection.prototype.update = function (data) {
1667    this.clear();
1668
1669    if (data.length === 0) {
1670      return;
1671    }
1672
1673    var $selections = [];
1674
1675    for (var d = 0; d < data.length; d++) {
1676      var selection = data[d];
1677
1678      var $selection = this.selectionContainer();
1679      var formatted = this.display(selection, $selection);
1680
1681      $selection.append(formatted);
1682      $selection.prop('title', selection.title || selection.text);
1683
1684      $selection.data('data', selection);
1685
1686      $selections.push($selection);
1687    }
1688
1689    var $rendered = this.$selection.find('.select2-selection__rendered');
1690
1691    Utils.appendMany($rendered, $selections);
1692  };
1693
1694  return MultipleSelection;
1695});
1696
1697S2.define('select2/selection/placeholder',[
1698  '../utils'
1699], function (Utils) {
1700  function Placeholder (decorated, $element, options) {
1701    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
1702
1703    decorated.call(this, $element, options);
1704  }
1705
1706  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
1707    if (typeof placeholder === 'string') {
1708      placeholder = {
1709        id: '',
1710        text: placeholder
1711      };
1712    }
1713
1714    return placeholder;
1715  };
1716
1717  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
1718    var $placeholder = this.selectionContainer();
1719
1720    $placeholder.html(this.display(placeholder));
1721    $placeholder.addClass('select2-selection__placeholder')
1722                .removeClass('select2-selection__choice');
1723
1724    return $placeholder;
1725  };
1726
1727  Placeholder.prototype.update = function (decorated, data) {
1728    var singlePlaceholder = (
1729      data.length == 1 && data[0].id != this.placeholder.id
1730    );
1731    var multipleSelections = data.length > 1;
1732
1733    if (multipleSelections || singlePlaceholder) {
1734      return decorated.call(this, data);
1735    }
1736
1737    this.clear();
1738
1739    var $placeholder = this.createPlaceholder(this.placeholder);
1740
1741    this.$selection.find('.select2-selection__rendered').append($placeholder);
1742  };
1743
1744  return Placeholder;
1745});
1746
1747S2.define('select2/selection/allowClear',[
1748  'jquery',
1749  '../keys'
1750], function ($, KEYS) {
1751  function AllowClear () { }
1752
1753  AllowClear.prototype.bind = function (decorated, container, $container) {
1754    var self = this;
1755
1756    decorated.call(this, container, $container);
1757
1758    if (this.placeholder == null) {
1759      if (this.options.get('debug') && window.console && console.error) {
1760        console.error(
1761          'Select2: The `allowClear` option should be used in combination ' +
1762          'with the `placeholder` option.'
1763        );
1764      }
1765    }
1766
1767    this.$selection.on('mousedown', '.select2-selection__clear',
1768      function (evt) {
1769        self._handleClear(evt);
1770    });
1771
1772    container.on('keypress', function (evt) {
1773      self._handleKeyboardClear(evt, container);
1774    });
1775  };
1776
1777  AllowClear.prototype._handleClear = function (_, evt) {
1778    // Ignore the event if it is disabled
1779    if (this.options.get('disabled')) {
1780      return;
1781    }
1782
1783    var $clear = this.$selection.find('.select2-selection__clear');
1784
1785    // Ignore the event if nothing has been selected
1786    if ($clear.length === 0) {
1787      return;
1788    }
1789
1790    evt.stopPropagation();
1791
1792    var data = $clear.data('data');
1793
1794    for (var d = 0; d < data.length; d++) {
1795      var unselectData = {
1796        data: data[d]
1797      };
1798
1799      // Trigger the `unselect` event, so people can prevent it from being
1800      // cleared.
1801      this.trigger('unselect', unselectData);
1802
1803      // If the event was prevented, don't clear it out.
1804      if (unselectData.prevented) {
1805        return;
1806      }
1807    }
1808
1809    this.$element.val(this.placeholder.id).trigger('change');
1810
1811    this.trigger('toggle', {});
1812  };
1813
1814  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
1815    if (container.isOpen()) {
1816      return;
1817    }
1818
1819    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
1820      this._handleClear(evt);
1821    }
1822  };
1823
1824  AllowClear.prototype.update = function (decorated, data) {
1825    decorated.call(this, data);
1826
1827    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
1828        data.length === 0) {
1829      return;
1830    }
1831
1832    var $remove = $(
1833      '<span class="select2-selection__clear">' +
1834        '&times;' +
1835      '</span>'
1836    );
1837    $remove.data('data', data);
1838
1839    this.$selection.find('.select2-selection__rendered').prepend($remove);
1840  };
1841
1842  return AllowClear;
1843});
1844
1845S2.define('select2/selection/search',[
1846  'jquery',
1847  '../utils',
1848  '../keys'
1849], function ($, Utils, KEYS) {
1850  function Search (decorated, $element, options) {
1851    decorated.call(this, $element, options);
1852  }
1853
1854  Search.prototype.render = function (decorated) {
1855    var $search = $(
1856      '<li class="select2-search select2-search--inline">' +
1857        '<input class="select2-search__field" type="search" tabindex="-1"' +
1858        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
1859        ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
1860      '</li>'
1861    );
1862
1863    this.$searchContainer = $search;
1864    this.$search = $search.find('input');
1865
1866    var $rendered = decorated.call(this);
1867
1868    this._transferTabIndex();
1869
1870    return $rendered;
1871  };
1872
1873  Search.prototype.bind = function (decorated, container, $container) {
1874    var self = this;
1875
1876    decorated.call(this, container, $container);
1877
1878    container.on('open', function () {
1879      self.$search.trigger('focus');
1880    });
1881
1882    container.on('close', function () {
1883      self.$search.val('');
1884      self.$search.removeAttr('aria-activedescendant');
1885      self.$search.trigger('focus');
1886    });
1887
1888    container.on('enable', function () {
1889      self.$search.prop('disabled', false);
1890
1891      self._transferTabIndex();
1892    });
1893
1894    container.on('disable', function () {
1895      self.$search.prop('disabled', true);
1896    });
1897
1898    container.on('focus', function (evt) {
1899      self.$search.trigger('focus');
1900    });
1901
1902    container.on('results:focus', function (params) {
1903      self.$search.attr('aria-activedescendant', params.id);
1904    });
1905
1906    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
1907      self.trigger('focus', evt);
1908    });
1909
1910    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
1911      self._handleBlur(evt);
1912    });
1913
1914    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
1915      evt.stopPropagation();
1916
1917      self.trigger('keypress', evt);
1918
1919      self._keyUpPrevented = evt.isDefaultPrevented();
1920
1921      var key = evt.which;
1922
1923      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
1924        var $previousChoice = self.$searchContainer
1925          .prev('.select2-selection__choice');
1926
1927        if ($previousChoice.length > 0) {
1928          var item = $previousChoice.data('data');
1929
1930          self.searchRemoveChoice(item);
1931
1932          evt.preventDefault();
1933        }
1934      }
1935    });
1936
1937    // Try to detect the IE version should the `documentMode` property that
1938    // is stored on the document. This is only implemented in IE and is
1939    // slightly cleaner than doing a user agent check.
1940    // This property is not available in Edge, but Edge also doesn't have
1941    // this bug.
1942    var msie = document.documentMode;
1943    var disableInputEvents = msie && msie <= 11;
1944
1945    // Workaround for browsers which do not support the `input` event
1946    // This will prevent double-triggering of events for browsers which support
1947    // both the `keyup` and `input` events.
1948    this.$selection.on(
1949      'input.searchcheck',
1950      '.select2-search--inline',
1951      function (evt) {
1952        // IE will trigger the `input` event when a placeholder is used on a
1953        // search box. To get around this issue, we are forced to ignore all
1954        // `input` events in IE and keep using `keyup`.
1955        if (disableInputEvents) {
1956          self.$selection.off('input.search input.searchcheck');
1957          return;
1958        }
1959
1960        // Unbind the duplicated `keyup` event
1961        self.$selection.off('keyup.search');
1962      }
1963    );
1964
1965    this.$selection.on(
1966      'keyup.search input.search',
1967      '.select2-search--inline',
1968      function (evt) {
1969        // IE will trigger the `input` event when a placeholder is used on a
1970        // search box. To get around this issue, we are forced to ignore all
1971        // `input` events in IE and keep using `keyup`.
1972        if (disableInputEvents && evt.type === 'input') {
1973          self.$selection.off('input.search input.searchcheck');
1974          return;
1975        }
1976
1977        var key = evt.which;
1978
1979        // We can freely ignore events from modifier keys
1980        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
1981          return;
1982        }
1983
1984        // Tabbing will be handled during the `keydown` phase
1985        if (key == KEYS.TAB) {
1986          return;
1987        }
1988
1989        self.handleSearch(evt);
1990      }
1991    );
1992  };
1993
1994  /**
1995   * This method will transfer the tabindex attribute from the rendered
1996   * selection to the search box. This allows for the search box to be used as
1997   * the primary focus instead of the selection container.
1998   *
1999   * @private
2000   */
2001  Search.prototype._transferTabIndex = function (decorated) {
2002    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
2003    this.$selection.attr('tabindex', '-1');
2004  };
2005
2006  Search.prototype.createPlaceholder = function (decorated, placeholder) {
2007    this.$search.attr('placeholder', placeholder.text);
2008  };
2009
2010  Search.prototype.update = function (decorated, data) {
2011    var searchHadFocus = this.$search[0] == document.activeElement;
2012
2013    this.$search.attr('placeholder', '');
2014
2015    decorated.call(this, data);
2016
2017    this.$selection.find('.select2-selection__rendered')
2018                   .append(this.$searchContainer);
2019
2020    this.resizeSearch();
2021    if (searchHadFocus) {
2022      this.$search.focus();
2023    }
2024  };
2025
2026  Search.prototype.handleSearch = function () {
2027    this.resizeSearch();
2028
2029    if (!this._keyUpPrevented) {
2030      var input = this.$search.val();
2031
2032      this.trigger('query', {
2033        term: input
2034      });
2035    }
2036
2037    this._keyUpPrevented = false;
2038  };
2039
2040  Search.prototype.searchRemoveChoice = function (decorated, item) {
2041    this.trigger('unselect', {
2042      data: item
2043    });
2044
2045    this.$search.val(item.text);
2046    this.handleSearch();
2047  };
2048
2049  Search.prototype.resizeSearch = function () {
2050    this.$search.css('width', '25px');
2051
2052    var width = '';
2053
2054    if (this.$search.attr('placeholder') !== '') {
2055      width = this.$selection.find('.select2-selection__rendered').innerWidth();
2056    } else {
2057      var minimumWidth = this.$search.val().length + 1;
2058
2059      width = (minimumWidth * 0.75) + 'em';
2060    }
2061
2062    this.$search.css('width', width);
2063  };
2064
2065  return Search;
2066});
2067
2068S2.define('select2/selection/eventRelay',[
2069  'jquery'
2070], function ($) {
2071  function EventRelay () { }
2072
2073  EventRelay.prototype.bind = function (decorated, container, $container) {
2074    var self = this;
2075    var relayEvents = [
2076      'open', 'opening',
2077      'close', 'closing',
2078      'select', 'selecting',
2079      'unselect', 'unselecting'
2080    ];
2081
2082    var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
2083
2084    decorated.call(this, container, $container);
2085
2086    container.on('*', function (name, params) {
2087      // Ignore events that should not be relayed
2088      if ($.inArray(name, relayEvents) === -1) {
2089        return;
2090      }
2091
2092      // The parameters should always be an object
2093      params = params || {};
2094
2095      // Generate the jQuery event for the Select2 event
2096      var evt = $.Event('select2:' + name, {
2097        params: params
2098      });
2099
2100      self.$element.trigger(evt);
2101
2102      // Only handle preventable events if it was one
2103      if ($.inArray(name, preventableEvents) === -1) {
2104        return;
2105      }
2106
2107      params.prevented = evt.isDefaultPrevented();
2108    });
2109  };
2110
2111  return EventRelay;
2112});
2113
2114S2.define('select2/translation',[
2115  'jquery',
2116  'require'
2117], function ($, require) {
2118  function Translation (dict) {
2119    this.dict = dict || {};
2120  }
2121
2122  Translation.prototype.all = function () {
2123    return this.dict;
2124  };
2125
2126  Translation.prototype.get = function (key) {
2127    return this.dict[key];
2128  };
2129
2130  Translation.prototype.extend = function (translation) {
2131    this.dict = $.extend({}, translation.all(), this.dict);
2132  };
2133
2134  // Static functions
2135
2136  Translation._cache = {};
2137
2138  Translation.loadPath = function (path) {
2139    if (!(path in Translation._cache)) {
2140      var translations = require(path);
2141
2142      Translation._cache[path] = translations;
2143    }
2144
2145    return new Translation(Translation._cache[path]);
2146  };
2147
2148  return Translation;
2149});
2150
2151S2.define('select2/diacritics',[
2152
2153], function () {
2154  var diacritics = {
2155    '\u24B6': 'A',
2156    '\uFF21': 'A',
2157    '\u00C0': 'A',
2158    '\u00C1': 'A',
2159    '\u00C2': 'A',
2160    '\u1EA6': 'A',
2161    '\u1EA4': 'A',
2162    '\u1EAA': 'A',
2163    '\u1EA8': 'A',
2164    '\u00C3': 'A',
2165    '\u0100': 'A',
2166    '\u0102': 'A',
2167    '\u1EB0': 'A',
2168    '\u1EAE': 'A',
2169    '\u1EB4': 'A',
2170    '\u1EB2': 'A',
2171    '\u0226': 'A',
2172    '\u01E0': 'A',
2173    '\u00C4': 'A',
2174    '\u01DE': 'A',
2175    '\u1EA2': 'A',
2176    '\u00C5': 'A',
2177    '\u01FA': 'A',
2178    '\u01CD': 'A',
2179    '\u0200': 'A',
2180    '\u0202': 'A',
2181    '\u1EA0': 'A',
2182    '\u1EAC': 'A',
2183    '\u1EB6': 'A',
2184    '\u1E00': 'A',
2185    '\u0104': 'A',
2186    '\u023A': 'A',
2187    '\u2C6F': 'A',
2188    '\uA732': 'AA',
2189    '\u00C6': 'AE',
2190    '\u01FC': 'AE',
2191    '\u01E2': 'AE',
2192    '\uA734': 'AO',
2193    '\uA736': 'AU',
2194    '\uA738': 'AV',
2195    '\uA73A': 'AV',
2196    '\uA73C': 'AY',
2197    '\u24B7': 'B',
2198    '\uFF22': 'B',
2199    '\u1E02': 'B',
2200    '\u1E04': 'B',
2201    '\u1E06': 'B',
2202    '\u0243': 'B',
2203    '\u0182': 'B',
2204    '\u0181': 'B',
2205    '\u24B8': 'C',
2206    '\uFF23': 'C',
2207    '\u0106': 'C',
2208    '\u0108': 'C',
2209    '\u010A': 'C',
2210    '\u010C': 'C',
2211    '\u00C7': 'C',
2212    '\u1E08': 'C',
2213    '\u0187': 'C',
2214    '\u023B': 'C',
2215    '\uA73E': 'C',
2216    '\u24B9': 'D',
2217    '\uFF24': 'D',
2218    '\u1E0A': 'D',
2219    '\u010E': 'D',
2220    '\u1E0C': 'D',
2221    '\u1E10': 'D',
2222    '\u1E12': 'D',
2223    '\u1E0E': 'D',
2224    '\u0110': 'D',
2225    '\u018B': 'D',
2226    '\u018A': 'D',
2227    '\u0189': 'D',
2228    '\uA779': 'D',
2229    '\u01F1': 'DZ',
2230    '\u01C4': 'DZ',
2231    '\u01F2': 'Dz',
2232    '\u01C5': 'Dz',
2233    '\u24BA': 'E',
2234    '\uFF25': 'E',
2235    '\u00C8': 'E',
2236    '\u00C9': 'E',
2237    '\u00CA': 'E',
2238    '\u1EC0': 'E',
2239    '\u1EBE': 'E',
2240    '\u1EC4': 'E',
2241    '\u1EC2': 'E',
2242    '\u1EBC': 'E',
2243    '\u0112': 'E',
2244    '\u1E14': 'E',
2245    '\u1E16': 'E',
2246    '\u0114': 'E',
2247    '\u0116': 'E',
2248    '\u00CB': 'E',
2249    '\u1EBA': 'E',
2250    '\u011A': 'E',
2251    '\u0204': 'E',
2252    '\u0206': 'E',
2253    '\u1EB8': 'E',
2254    '\u1EC6': 'E',
2255    '\u0228': 'E',
2256    '\u1E1C': 'E',
2257    '\u0118': 'E',
2258    '\u1E18': 'E',
2259    '\u1E1A': 'E',
2260    '\u0190': 'E',
2261    '\u018E': 'E',
2262    '\u24BB': 'F',
2263    '\uFF26': 'F',
2264    '\u1E1E': 'F',
2265    '\u0191': 'F',
2266    '\uA77B': 'F',
2267    '\u24BC': 'G',
2268    '\uFF27': 'G',
2269    '\u01F4': 'G',
2270    '\u011C': 'G',
2271    '\u1E20': 'G',
2272    '\u011E': 'G',
2273    '\u0120': 'G',
2274    '\u01E6': 'G',
2275    '\u0122': 'G',
2276    '\u01E4': 'G',
2277    '\u0193': 'G',
2278    '\uA7A0': 'G',
2279    '\uA77D': 'G',
2280    '\uA77E': 'G',
2281    '\u24BD': 'H',
2282    '\uFF28': 'H',
2283    '\u0124': 'H',
2284    '\u1E22': 'H',
2285    '\u1E26': 'H',
2286    '\u021E': 'H',
2287    '\u1E24': 'H',
2288    '\u1E28': 'H',
2289    '\u1E2A': 'H',
2290    '\u0126': 'H',
2291    '\u2C67': 'H',
2292    '\u2C75': 'H',
2293    '\uA78D': 'H',
2294    '\u24BE': 'I',
2295    '\uFF29': 'I',
2296    '\u00CC': 'I',
2297    '\u00CD': 'I',
2298    '\u00CE': 'I',
2299    '\u0128': 'I',
2300    '\u012A': 'I',
2301    '\u012C': 'I',
2302    '\u0130': 'I',
2303    '\u00CF': 'I',
2304    '\u1E2E': 'I',
2305    '\u1EC8': 'I',
2306    '\u01CF': 'I',
2307    '\u0208': 'I',
2308    '\u020A': 'I',
2309    '\u1ECA': 'I',
2310    '\u012E': 'I',
2311    '\u1E2C': 'I',
2312    '\u0197': 'I',
2313    '\u24BF': 'J',
2314    '\uFF2A': 'J',
2315    '\u0134': 'J',
2316    '\u0248': 'J',
2317    '\u24C0': 'K',
2318    '\uFF2B': 'K',
2319    '\u1E30': 'K',
2320    '\u01E8': 'K',
2321    '\u1E32': 'K',
2322    '\u0136': 'K',
2323    '\u1E34': 'K',
2324    '\u0198': 'K',
2325    '\u2C69': 'K',
2326    '\uA740': 'K',
2327    '\uA742': 'K',
2328    '\uA744': 'K',
2329    '\uA7A2': 'K',
2330    '\u24C1': 'L',
2331    '\uFF2C': 'L',
2332    '\u013F': 'L',
2333    '\u0139': 'L',
2334    '\u013D': 'L',
2335    '\u1E36': 'L',
2336    '\u1E38': 'L',
2337    '\u013B': 'L',
2338    '\u1E3C': 'L',
2339    '\u1E3A': 'L',
2340    '\u0141': 'L',
2341    '\u023D': 'L',
2342    '\u2C62': 'L',
2343    '\u2C60': 'L',
2344    '\uA748': 'L',
2345    '\uA746': 'L',
2346    '\uA780': 'L',
2347    '\u01C7': 'LJ',
2348    '\u01C8': 'Lj',
2349    '\u24C2': 'M',
2350    '\uFF2D': 'M',
2351    '\u1E3E': 'M',
2352    '\u1E40': 'M',
2353    '\u1E42': 'M',
2354    '\u2C6E': 'M',
2355    '\u019C': 'M',
2356    '\u24C3': 'N',
2357    '\uFF2E': 'N',
2358    '\u01F8': 'N',
2359    '\u0143': 'N',
2360    '\u00D1': 'N',
2361    '\u1E44': 'N',
2362    '\u0147': 'N',
2363    '\u1E46': 'N',
2364    '\u0145': 'N',
2365    '\u1E4A': 'N',
2366    '\u1E48': 'N',
2367    '\u0220': 'N',
2368    '\u019D': 'N',
2369    '\uA790': 'N',
2370    '\uA7A4': 'N',
2371    '\u01CA': 'NJ',
2372    '\u01CB': 'Nj',
2373    '\u24C4': 'O',
2374    '\uFF2F': 'O',
2375    '\u00D2': 'O',
2376    '\u00D3': 'O',
2377    '\u00D4': 'O',
2378    '\u1ED2': 'O',
2379    '\u1ED0': 'O',
2380    '\u1ED6': 'O',
2381    '\u1ED4': 'O',
2382    '\u00D5': 'O',
2383    '\u1E4C': 'O',
2384    '\u022C': 'O',
2385    '\u1E4E': 'O',
2386    '\u014C': 'O',
2387    '\u1E50': 'O',
2388    '\u1E52': 'O',
2389    '\u014E': 'O',
2390    '\u022E': 'O',
2391    '\u0230': 'O',
2392    '\u00D6': 'O',
2393    '\u022A': 'O',
2394    '\u1ECE': 'O',
2395    '\u0150': 'O',
2396    '\u01D1': 'O',
2397    '\u020C': 'O',
2398    '\u020E': 'O',
2399    '\u01A0': 'O',
2400    '\u1EDC': 'O',
2401    '\u1EDA': 'O',
2402    '\u1EE0': 'O',
2403    '\u1EDE': 'O',
2404    '\u1EE2': 'O',
2405    '\u1ECC': 'O',
2406    '\u1ED8': 'O',
2407    '\u01EA': 'O',
2408    '\u01EC': 'O',
2409    '\u00D8': 'O',
2410    '\u01FE': 'O',
2411    '\u0186': 'O',
2412    '\u019F': 'O',
2413    '\uA74A': 'O',
2414    '\uA74C': 'O',
2415    '\u01A2': 'OI',
2416    '\uA74E': 'OO',
2417    '\u0222': 'OU',
2418    '\u24C5': 'P',
2419    '\uFF30': 'P',
2420    '\u1E54': 'P',
2421    '\u1E56': 'P',
2422    '\u01A4': 'P',
2423    '\u2C63': 'P',
2424    '\uA750': 'P',
2425    '\uA752': 'P',
2426    '\uA754': 'P',
2427    '\u24C6': 'Q',
2428    '\uFF31': 'Q',
2429    '\uA756': 'Q',
2430    '\uA758': 'Q',
2431    '\u024A': 'Q',
2432    '\u24C7': 'R',
2433    '\uFF32': 'R',
2434    '\u0154': 'R',
2435    '\u1E58': 'R',
2436    '\u0158': 'R',
2437    '\u0210': 'R',
2438    '\u0212': 'R',
2439    '\u1E5A': 'R',
2440    '\u1E5C': 'R',
2441    '\u0156': 'R',
2442    '\u1E5E': 'R',
2443    '\u024C': 'R',
2444    '\u2C64': 'R',
2445    '\uA75A': 'R',
2446    '\uA7A6': 'R',
2447    '\uA782': 'R',
2448    '\u24C8': 'S',
2449    '\uFF33': 'S',
2450    '\u1E9E': 'S',
2451    '\u015A': 'S',
2452    '\u1E64': 'S',
2453    '\u015C': 'S',
2454    '\u1E60': 'S',
2455    '\u0160': 'S',
2456    '\u1E66': 'S',
2457    '\u1E62': 'S',
2458    '\u1E68': 'S',
2459    '\u0218': 'S',
2460    '\u015E': 'S',
2461    '\u2C7E': 'S',
2462    '\uA7A8': 'S',
2463    '\uA784': 'S',
2464    '\u24C9': 'T',
2465    '\uFF34': 'T',
2466    '\u1E6A': 'T',
2467    '\u0164': 'T',
2468    '\u1E6C': 'T',
2469    '\u021A': 'T',
2470    '\u0162': 'T',
2471    '\u1E70': 'T',
2472    '\u1E6E': 'T',
2473    '\u0166': 'T',
2474    '\u01AC': 'T',
2475    '\u01AE': 'T',
2476    '\u023E': 'T',
2477    '\uA786': 'T',
2478    '\uA728': 'TZ',
2479    '\u24CA': 'U',
2480    '\uFF35': 'U',
2481    '\u00D9': 'U',
2482    '\u00DA': 'U',
2483    '\u00DB': 'U',
2484    '\u0168': 'U',
2485    '\u1E78': 'U',
2486    '\u016A': 'U',
2487    '\u1E7A': 'U',
2488    '\u016C': 'U',
2489    '\u00DC': 'U',
2490    '\u01DB': 'U',
2491    '\u01D7': 'U',
2492    '\u01D5': 'U',
2493    '\u01D9': 'U',
2494    '\u1EE6': 'U',
2495    '\u016E': 'U',
2496    '\u0170': 'U',
2497    '\u01D3': 'U',
2498    '\u0214': 'U',
2499    '\u0216': 'U',
2500    '\u01AF': 'U',
2501    '\u1EEA': 'U',
2502    '\u1EE8': 'U',
2503    '\u1EEE': 'U',
2504    '\u1EEC': 'U',
2505    '\u1EF0': 'U',
2506    '\u1EE4': 'U',
2507    '\u1E72': 'U',
2508    '\u0172': 'U',
2509    '\u1E76': 'U',
2510    '\u1E74': 'U',
2511    '\u0244': 'U',
2512    '\u24CB': 'V',
2513    '\uFF36': 'V',
2514    '\u1E7C': 'V',
2515    '\u1E7E': 'V',
2516    '\u01B2': 'V',
2517    '\uA75E': 'V',
2518    '\u0245': 'V',
2519    '\uA760': 'VY',
2520    '\u24CC': 'W',
2521    '\uFF37': 'W',
2522    '\u1E80': 'W',
2523    '\u1E82': 'W',
2524    '\u0174': 'W',
2525    '\u1E86': 'W',
2526    '\u1E84': 'W',
2527    '\u1E88': 'W',
2528    '\u2C72': 'W',
2529    '\u24CD': 'X',
2530    '\uFF38': 'X',
2531    '\u1E8A': 'X',
2532    '\u1E8C': 'X',
2533    '\u24CE': 'Y',
2534    '\uFF39': 'Y',
2535    '\u1EF2': 'Y',
2536    '\u00DD': 'Y',
2537    '\u0176': 'Y',
2538    '\u1EF8': 'Y',
2539    '\u0232': 'Y',
2540    '\u1E8E': 'Y',
2541    '\u0178': 'Y',
2542    '\u1EF6': 'Y',
2543    '\u1EF4': 'Y',
2544    '\u01B3': 'Y',
2545    '\u024E': 'Y',
2546    '\u1EFE': 'Y',
2547    '\u24CF': 'Z',
2548    '\uFF3A': 'Z',
2549    '\u0179': 'Z',
2550    '\u1E90': 'Z',
2551    '\u017B': 'Z',
2552    '\u017D': 'Z',
2553    '\u1E92': 'Z',
2554    '\u1E94': 'Z',
2555    '\u01B5': 'Z',
2556    '\u0224': 'Z',
2557    '\u2C7F': 'Z',
2558    '\u2C6B': 'Z',
2559    '\uA762': 'Z',
2560    '\u24D0': 'a',
2561    '\uFF41': 'a',
2562    '\u1E9A': 'a',
2563    '\u00E0': 'a',
2564    '\u00E1': 'a',
2565    '\u00E2': 'a',
2566    '\u1EA7': 'a',
2567    '\u1EA5': 'a',
2568    '\u1EAB': 'a',
2569    '\u1EA9': 'a',
2570    '\u00E3': 'a',
2571    '\u0101': 'a',
2572    '\u0103': 'a',
2573    '\u1EB1': 'a',
2574    '\u1EAF': 'a',
2575    '\u1EB5': 'a',
2576    '\u1EB3': 'a',
2577    '\u0227': 'a',
2578    '\u01E1': 'a',
2579    '\u00E4': 'a',
2580    '\u01DF': 'a',
2581    '\u1EA3': 'a',
2582    '\u00E5': 'a',
2583    '\u01FB': 'a',
2584    '\u01CE': 'a',
2585    '\u0201': 'a',
2586    '\u0203': 'a',
2587    '\u1EA1': 'a',
2588    '\u1EAD': 'a',
2589    '\u1EB7': 'a',
2590    '\u1E01': 'a',
2591    '\u0105': 'a',
2592    '\u2C65': 'a',
2593    '\u0250': 'a',
2594    '\uA733': 'aa',
2595    '\u00E6': 'ae',
2596    '\u01FD': 'ae',
2597    '\u01E3': 'ae',
2598    '\uA735': 'ao',
2599    '\uA737': 'au',
2600    '\uA739': 'av',
2601    '\uA73B': 'av',
2602    '\uA73D': 'ay',
2603    '\u24D1': 'b',
2604    '\uFF42': 'b',
2605    '\u1E03': 'b',
2606    '\u1E05': 'b',
2607    '\u1E07': 'b',
2608    '\u0180': 'b',
2609    '\u0183': 'b',
2610    '\u0253': 'b',
2611    '\u24D2': 'c',
2612    '\uFF43': 'c',
2613    '\u0107': 'c',
2614    '\u0109': 'c',
2615    '\u010B': 'c',
2616    '\u010D': 'c',
2617    '\u00E7': 'c',
2618    '\u1E09': 'c',
2619    '\u0188': 'c',
2620    '\u023C': 'c',
2621    '\uA73F': 'c',
2622    '\u2184': 'c',
2623    '\u24D3': 'd',
2624    '\uFF44': 'd',
2625    '\u1E0B': 'd',
2626    '\u010F': 'd',
2627    '\u1E0D': 'd',
2628    '\u1E11': 'd',
2629    '\u1E13': 'd',
2630    '\u1E0F': 'd',
2631    '\u0111': 'd',
2632    '\u018C': 'd',
2633    '\u0256': 'd',
2634    '\u0257': 'd',
2635    '\uA77A': 'd',
2636    '\u01F3': 'dz',
2637    '\u01C6': 'dz',
2638    '\u24D4': 'e',
2639    '\uFF45': 'e',
2640    '\u00E8': 'e',
2641    '\u00E9': 'e',
2642    '\u00EA': 'e',
2643    '\u1EC1': 'e',
2644    '\u1EBF': 'e',
2645    '\u1EC5': 'e',
2646    '\u1EC3': 'e',
2647    '\u1EBD': 'e',
2648    '\u0113': 'e',
2649    '\u1E15': 'e',
2650    '\u1E17': 'e',
2651    '\u0115': 'e',
2652    '\u0117': 'e',
2653    '\u00EB': 'e',
2654    '\u1EBB': 'e',
2655    '\u011B': 'e',
2656    '\u0205': 'e',
2657    '\u0207': 'e',
2658    '\u1EB9': 'e',
2659    '\u1EC7': 'e',
2660    '\u0229': 'e',
2661    '\u1E1D': 'e',
2662    '\u0119': 'e',
2663    '\u1E19': 'e',
2664    '\u1E1B': 'e',
2665    '\u0247': 'e',
2666    '\u025B': 'e',
2667    '\u01DD': 'e',
2668    '\u24D5': 'f',
2669    '\uFF46': 'f',
2670    '\u1E1F': 'f',
2671    '\u0192': 'f',
2672    '\uA77C': 'f',
2673    '\u24D6': 'g',
2674    '\uFF47': 'g',
2675    '\u01F5': 'g',
2676    '\u011D': 'g',
2677    '\u1E21': 'g',
2678    '\u011F': 'g',
2679    '\u0121': 'g',
2680    '\u01E7': 'g',
2681    '\u0123': 'g',
2682    '\u01E5': 'g',
2683    '\u0260': 'g',
2684    '\uA7A1': 'g',
2685    '\u1D79': 'g',
2686    '\uA77F': 'g',
2687    '\u24D7': 'h',
2688    '\uFF48': 'h',
2689    '\u0125': 'h',
2690    '\u1E23': 'h',
2691    '\u1E27': 'h',
2692    '\u021F': 'h',
2693    '\u1E25': 'h',
2694    '\u1E29': 'h',
2695    '\u1E2B': 'h',
2696    '\u1E96': 'h',
2697    '\u0127': 'h',
2698    '\u2C68': 'h',
2699    '\u2C76': 'h',
2700    '\u0265': 'h',
2701    '\u0195': 'hv',
2702    '\u24D8': 'i',
2703    '\uFF49': 'i',
2704    '\u00EC': 'i',
2705    '\u00ED': 'i',
2706    '\u00EE': 'i',
2707    '\u0129': 'i',
2708    '\u012B': 'i',
2709    '\u012D': 'i',
2710    '\u00EF': 'i',
2711    '\u1E2F': 'i',
2712    '\u1EC9': 'i',
2713    '\u01D0': 'i',
2714    '\u0209': 'i',
2715    '\u020B': 'i',
2716    '\u1ECB': 'i',
2717    '\u012F': 'i',
2718    '\u1E2D': 'i',
2719    '\u0268': 'i',
2720    '\u0131': 'i',
2721    '\u24D9': 'j',
2722    '\uFF4A': 'j',
2723    '\u0135': 'j',
2724    '\u01F0': 'j',
2725    '\u0249': 'j',
2726    '\u24DA': 'k',
2727    '\uFF4B': 'k',
2728    '\u1E31': 'k',
2729    '\u01E9': 'k',
2730    '\u1E33': 'k',
2731    '\u0137': 'k',
2732    '\u1E35': 'k',
2733    '\u0199': 'k',
2734    '\u2C6A': 'k',
2735    '\uA741': 'k',
2736    '\uA743': 'k',
2737    '\uA745': 'k',
2738    '\uA7A3': 'k',
2739    '\u24DB': 'l',
2740    '\uFF4C': 'l',
2741    '\u0140': 'l',
2742    '\u013A': 'l',
2743    '\u013E': 'l',
2744    '\u1E37': 'l',
2745    '\u1E39': 'l',
2746    '\u013C': 'l',
2747    '\u1E3D': 'l',
2748    '\u1E3B': 'l',
2749    '\u017F': 'l',
2750    '\u0142': 'l',
2751    '\u019A': 'l',
2752    '\u026B': 'l',
2753    '\u2C61': 'l',
2754    '\uA749': 'l',
2755    '\uA781': 'l',
2756    '\uA747': 'l',
2757    '\u01C9': 'lj',
2758    '\u24DC': 'm',
2759    '\uFF4D': 'm',
2760    '\u1E3F': 'm',
2761    '\u1E41': 'm',
2762    '\u1E43': 'm',
2763    '\u0271': 'm',
2764    '\u026F': 'm',
2765    '\u24DD': 'n',
2766    '\uFF4E': 'n',
vendor: 6,356 bytes, lines 2767-3064
2767    '\u01F9': 'n',
2768    '\u0144': 'n',
2769    '\u00F1': 'n',
2770    '\u1E45': 'n',
2771    '\u0148': 'n',
2772    '\u1E47': 'n',
2773    '\u0146': 'n',
2774    '\u1E4B': 'n',
2775    '\u1E49': 'n',
2776    '\u019E': 'n',
2777    '\u0272': 'n',
2778    '\u0149': 'n',
2779    '\uA791': 'n',
2780    '\uA7A5': 'n',
2781    '\u01CC': 'nj',
2782    '\u24DE': 'o',
2783    '\uFF4F': 'o',
2784    '\u00F2': 'o',
2785    '\u00F3': 'o',
2786    '\u00F4': 'o',
2787    '\u1ED3': 'o',
2788    '\u1ED1': 'o',
2789    '\u1ED7': 'o',
2790    '\u1ED5': 'o',
2791    '\u00F5': 'o',
2792    '\u1E4D': 'o',
2793    '\u022D': 'o',
2794    '\u1E4F': 'o',
2795    '\u014D': 'o',
2796    '\u1E51': 'o',
2797    '\u1E53': 'o',
2798    '\u014F': 'o',
2799    '\u022F': 'o',
2800    '\u0231': 'o',
2801    '\u00F6': 'o',
2802    '\u022B': 'o',
2803    '\u1ECF': 'o',
2804    '\u0151': 'o',
2805    '\u01D2': 'o',
2806    '\u020D': 'o',
2807    '\u020F': 'o',
2808    '\u01A1': 'o',
2809    '\u1EDD': 'o',
2810    '\u1EDB': 'o',
2811    '\u1EE1': 'o',
2812    '\u1EDF': 'o',
2813    '\u1EE3': 'o',
2814    '\u1ECD': 'o',
2815    '\u1ED9': 'o',
2816    '\u01EB': 'o',
2817    '\u01ED': 'o',
2818    '\u00F8': 'o',
2819    '\u01FF': 'o',
2820    '\u0254': 'o',
2821    '\uA74B': 'o',
2822    '\uA74D': 'o',
2823    '\u0275': 'o',
2824    '\u01A3': 'oi',
2825    '\u0223': 'ou',
2826    '\uA74F': 'oo',
2827    '\u24DF': 'p',
2828    '\uFF50': 'p',
2829    '\u1E55': 'p',
2830    '\u1E57': 'p',
2831    '\u01A5': 'p',
2832    '\u1D7D': 'p',
2833    '\uA751': 'p',
2834    '\uA753': 'p',
2835    '\uA755': 'p',
2836    '\u24E0': 'q',
2837    '\uFF51': 'q',
2838    '\u024B': 'q',
2839    '\uA757': 'q',
2840    '\uA759': 'q',
2841    '\u24E1': 'r',
2842    '\uFF52': 'r',
2843    '\u0155': 'r',
2844    '\u1E59': 'r',
2845    '\u0159': 'r',
2846    '\u0211': 'r',
2847    '\u0213': 'r',
2848    '\u1E5B': 'r',
2849    '\u1E5D': 'r',
2850    '\u0157': 'r',
2851    '\u1E5F': 'r',
2852    '\u024D': 'r',
2853    '\u027D': 'r',
2854    '\uA75B': 'r',
2855    '\uA7A7': 'r',
2856    '\uA783': 'r',
2857    '\u24E2': 's',
2858    '\uFF53': 's',
2859    '\u00DF': 's',
2860    '\u015B': 's',
2861    '\u1E65': 's',
2862    '\u015D': 's',
2863    '\u1E61': 's',
2864    '\u0161': 's',
2865    '\u1E67': 's',
2866    '\u1E63': 's',
2867    '\u1E69': 's',
2868    '\u0219': 's',
2869    '\u015F': 's',
2870    '\u023F': 's',
2871    '\uA7A9': 's',
2872    '\uA785': 's',
2873    '\u1E9B': 's',
2874    '\u24E3': 't',
2875    '\uFF54': 't',
2876    '\u1E6B': 't',
2877    '\u1E97': 't',
2878    '\u0165': 't',
2879    '\u1E6D': 't',
2880    '\u021B': 't',
2881    '\u0163': 't',
2882    '\u1E71': 't',
2883    '\u1E6F': 't',
2884    '\u0167': 't',
2885    '\u01AD': 't',
2886    '\u0288': 't',
2887    '\u2C66': 't',
2888    '\uA787': 't',
2889    '\uA729': 'tz',
2890    '\u24E4': 'u',
2891    '\uFF55': 'u',
2892    '\u00F9': 'u',
2893    '\u00FA': 'u',
2894    '\u00FB': 'u',
2895    '\u0169': 'u',
2896    '\u1E79': 'u',
2897    '\u016B': 'u',
2898    '\u1E7B': 'u',
2899    '\u016D': 'u',
2900    '\u00FC': 'u',
2901    '\u01DC': 'u',
2902    '\u01D8': 'u',
2903    '\u01D6': 'u',
2904    '\u01DA': 'u',
2905    '\u1EE7': 'u',
2906    '\u016F': 'u',
2907    '\u0171': 'u',
2908    '\u01D4': 'u',
2909    '\u0215': 'u',
2910    '\u0217': 'u',
2911    '\u01B0': 'u',
2912    '\u1EEB': 'u',
2913    '\u1EE9': 'u',
2914    '\u1EEF': 'u',
2915    '\u1EED': 'u',
2916    '\u1EF1': 'u',
2917    '\u1EE5': 'u',
2918    '\u1E73': 'u',
2919    '\u0173': 'u',
2920    '\u1E77': 'u',
2921    '\u1E75': 'u',
2922    '\u0289': 'u',
2923    '\u24E5': 'v',
2924    '\uFF56': 'v',
2925    '\u1E7D': 'v',
2926    '\u1E7F': 'v',
2927    '\u028B': 'v',
2928    '\uA75F': 'v',
2929    '\u028C': 'v',
2930    '\uA761': 'vy',
2931    '\u24E6': 'w',
2932    '\uFF57': 'w',
2933    '\u1E81': 'w',
2934    '\u1E83': 'w',
2935    '\u0175': 'w',
2936    '\u1E87': 'w',
2937    '\u1E85': 'w',
2938    '\u1E98': 'w',
2939    '\u1E89': 'w',
2940    '\u2C73': 'w',
2941    '\u24E7': 'x',
2942    '\uFF58': 'x',
2943    '\u1E8B': 'x',
2944    '\u1E8D': 'x',
2945    '\u24E8': 'y',
2946    '\uFF59': 'y',
2947    '\u1EF3': 'y',
2948    '\u00FD': 'y',
2949    '\u0177': 'y',
2950    '\u1EF9': 'y',
2951    '\u0233': 'y',
2952    '\u1E8F': 'y',
2953    '\u00FF': 'y',
2954    '\u1EF7': 'y',
2955    '\u1E99': 'y',
2956    '\u1EF5': 'y',
2957    '\u01B4': 'y',
2958    '\u024F': 'y',
2959    '\u1EFF': 'y',
2960    '\u24E9': 'z',
2961    '\uFF5A': 'z',
2962    '\u017A': 'z',
2963    '\u1E91': 'z',
2964    '\u017C': 'z',
2965    '\u017E': 'z',
2966    '\u1E93': 'z',
2967    '\u1E95': 'z',
2968    '\u01B6': 'z',
2969    '\u0225': 'z',
2970    '\u0240': 'z',
2971    '\u2C6C': 'z',
2972    '\uA763': 'z',
2973    '\u0386': '\u0391',
2974    '\u0388': '\u0395',
2975    '\u0389': '\u0397',
2976    '\u038A': '\u0399',
2977    '\u03AA': '\u0399',
2978    '\u038C': '\u039F',
2979    '\u038E': '\u03A5',
2980    '\u03AB': '\u03A5',
2981    '\u038F': '\u03A9',
2982    '\u03AC': '\u03B1',
2983    '\u03AD': '\u03B5',
2984    '\u03AE': '\u03B7',
2985    '\u03AF': '\u03B9',
2986    '\u03CA': '\u03B9',
2987    '\u0390': '\u03B9',
2988    '\u03CC': '\u03BF',
2989    '\u03CD': '\u03C5',
2990    '\u03CB': '\u03C5',
2991    '\u03B0': '\u03C5',
2992    '\u03C9': '\u03C9',
2993    '\u03C2': '\u03C3'
2994  };
2995
2996  return diacritics;
2997});
2998
2999S2.define('select2/data/base',[
3000  '../utils'
3001], function (Utils) {
3002  function BaseAdapter ($element, options) {
3003    BaseAdapter.__super__.constructor.call(this);
3004  }
3005
3006  Utils.Extend(BaseAdapter, Utils.Observable);
3007
3008  BaseAdapter.prototype.current = function (callback) {
3009    throw new Error('The `current` method must be defined in child classes.');
3010  };
3011
3012  BaseAdapter.prototype.query = function (params, callback) {
3013    throw new Error('The `query` method must be defined in child classes.');
3014  };
3015
3016  BaseAdapter.prototype.bind = function (container, $container) {
3017    // Can be implemented in subclasses
3018  };
3019
3020  BaseAdapter.prototype.destroy = function () {
3021    // Can be implemented in subclasses
3022  };
3023
3024  BaseAdapter.prototype.generateResultId = function (container, data) {
3025    var id = container.id + '-result-';
3026
3027    id += Utils.generateChars(4);
3028
3029    if (data.id != null) {
3030      id += '-' + data.id.toString();
3031    } else {
3032      id += '-' + Utils.generateChars(4);
3033    }
3034    return id;
3035  };
3036
3037  return BaseAdapter;
3038});
3039
3040S2.define('select2/data/select',[
3041  './base',
3042  '../utils',
3043  'jquery'
3044], function (BaseAdapter, Utils, $) {
3045  function SelectAdapter ($element, options) {
3046    this.$element = $element;
3047    this.options = options;
3048
3049    SelectAdapter.__super__.constructor.call(this);
3050  }
3051
3052  Utils.Extend(SelectAdapter, BaseAdapter);
3053
3054  SelectAdapter.prototype.current = function (callback) {
3055    var data = [];
3056    var self = this;
3057
3058    this.$element.find(':selected').each(function () {
3059      var $option = $(this);
3060
3061      var option = self.item($option);
3062
3063      data.push(option);
3064    });
vendor: 63,056 bytes, lines 3065-5531
3065
3066    callback(data);
3067  };
3068
3069  SelectAdapter.prototype.select = function (data) {
3070    var self = this;
3071
3072    data.selected = true;
3073
3074    // If data.element is a DOM node, use it instead
3075    if ($(data.element).is('option')) {
3076      data.element.selected = true;
3077
3078      this.$element.trigger('change');
3079
3080      return;
3081    }
3082
3083    if (this.$element.prop('multiple')) {
3084      this.current(function (currentData) {
3085        var val = [];
3086
3087        data = [data];
3088        data.push.apply(data, currentData);
3089
3090        for (var d = 0; d < data.length; d++) {
3091          var id = data[d].id;
3092
3093          if ($.inArray(id, val) === -1) {
3094            val.push(id);
3095          }
3096        }
3097
3098        self.$element.val(val);
3099        self.$element.trigger('change');
3100      });
3101    } else {
3102      var val = data.id;
3103
3104      this.$element.val(val);
3105      this.$element.trigger('change');
3106    }
3107  };
3108
3109  SelectAdapter.prototype.unselect = function (data) {
3110    var self = this;
3111
3112    if (!this.$element.prop('multiple')) {
3113      return;
3114    }
3115
3116    data.selected = false;
3117
3118    if ($(data.element).is('option')) {
3119      data.element.selected = false;
3120
3121      this.$element.trigger('change');
3122
3123      return;
3124    }
3125
3126    this.current(function (currentData) {
3127      var val = [];
3128
3129      for (var d = 0; d < currentData.length; d++) {
3130        var id = currentData[d].id;
3131
3132        if (id !== data.id && $.inArray(id, val) === -1) {
3133          val.push(id);
3134        }
3135      }
3136
3137      self.$element.val(val);
3138
3139      self.$element.trigger('change');
3140    });
3141  };
3142
3143  SelectAdapter.prototype.bind = function (container, $container) {
3144    var self = this;
3145
3146    this.container = container;
3147
3148    container.on('select', function (params) {
3149      self.select(params.data);
3150    });
3151
3152    container.on('unselect', function (params) {
3153      self.unselect(params.data);
3154    });
3155  };
3156
3157  SelectAdapter.prototype.destroy = function () {
3158    // Remove anything added to child elements
3159    this.$element.find('*').each(function () {
3160      // Remove any custom data set by Select2
3161      $.removeData(this, 'data');
3162    });
3163  };
3164
3165  SelectAdapter.prototype.query = function (params, callback) {
3166    var data = [];
3167    var self = this;
3168
3169    var $options = this.$element.children();
3170
3171    $options.each(function () {
3172      var $option = $(this);
3173
3174      if (!$option.is('option') && !$option.is('optgroup')) {
3175        return;
3176      }
3177
3178      var option = self.item($option);
3179
3180      var matches = self.matches(params, option);
3181
3182      if (matches !== null) {
3183        data.push(matches);
3184      }
3185    });
3186
3187    callback({
3188      results: data
3189    });
3190  };
3191
3192  SelectAdapter.prototype.addOptions = function ($options) {
3193    Utils.appendMany(this.$element, $options);
3194  };
3195
3196  SelectAdapter.prototype.option = function (data) {
3197    var option;
3198
3199    if (data.children) {
3200      option = document.createElement('optgroup');
3201      option.label = data.text;
3202    } else {
3203      option = document.createElement('option');
3204
3205      if (option.textContent !== undefined) {
3206        option.textContent = data.text;
3207      } else {
3208        option.innerText = data.text;
3209      }
3210    }
3211
3212    if (data.id !== undefined) {
3213      option.value = data.id;
3214    }
3215
3216    if (data.disabled) {
3217      option.disabled = true;
3218    }
3219
3220    if (data.selected) {
3221      option.selected = true;
3222    }
3223
3224    if (data.title) {
3225      option.title = data.title;
3226    }
3227
3228    var $option = $(option);
3229
3230    var normalizedData = this._normalizeItem(data);
3231    normalizedData.element = option;
3232
3233    // Override the option's data with the combined data
3234    $.data(option, 'data', normalizedData);
3235
3236    return $option;
3237  };
3238
3239  SelectAdapter.prototype.item = function ($option) {
3240    var data = {};
3241
3242    data = $.data($option[0], 'data');
3243
3244    if (data != null) {
3245      return data;
3246    }
3247
3248    if ($option.is('option')) {
3249      data = {
3250        id: $option.val(),
3251        text: $option.text(),
3252        disabled: $option.prop('disabled'),
3253        selected: $option.prop('selected'),
3254        title: $option.prop('title')
3255      };
3256    } else if ($option.is('optgroup')) {
3257      data = {
3258        text: $option.prop('label'),
3259        children: [],
3260        title: $option.prop('title')
3261      };
3262
3263      var $children = $option.children('option');
3264      var children = [];
3265
3266      for (var c = 0; c < $children.length; c++) {
3267        var $child = $($children[c]);
3268
3269        var child = this.item($child);
3270
3271        children.push(child);
3272      }
3273
3274      data.children = children;
3275    }
3276
3277    data = this._normalizeItem(data);
3278    data.element = $option[0];
3279
3280    $.data($option[0], 'data', data);
3281
3282    return data;
3283  };
3284
3285  SelectAdapter.prototype._normalizeItem = function (item) {
3286    if (!$.isPlainObject(item)) {
3287      item = {
3288        id: item,
3289        text: item
3290      };
3291    }
3292
3293    item = $.extend({}, {
3294      text: ''
3295    }, item);
3296
3297    var defaults = {
3298      selected: false,
3299      disabled: false
3300    };
3301
3302    if (item.id != null) {
3303      item.id = item.id.toString();
3304    }
3305
3306    if (item.text != null) {
3307      item.text = item.text.toString();
3308    }
3309
3310    if (item._resultId == null && item.id && this.container != null) {
3311      item._resultId = this.generateResultId(this.container, item);
3312    }
3313
3314    return $.extend({}, defaults, item);
3315  };
3316
3317  SelectAdapter.prototype.matches = function (params, data) {
3318    var matcher = this.options.get('matcher');
3319
3320    return matcher(params, data);
3321  };
3322
3323  return SelectAdapter;
3324});
3325
3326S2.define('select2/data/array',[
3327  './select',
3328  '../utils',
3329  'jquery'
3330], function (SelectAdapter, Utils, $) {
3331  function ArrayAdapter ($element, options) {
3332    var data = options.get('data') || [];
3333
3334    ArrayAdapter.__super__.constructor.call(this, $element, options);
3335
3336    this.addOptions(this.convertToOptions(data));
3337  }
3338
3339  Utils.Extend(ArrayAdapter, SelectAdapter);
3340
3341  ArrayAdapter.prototype.select = function (data) {
3342    var $option = this.$element.find('option').filter(function (i, elm) {
3343      return elm.value == data.id.toString();
3344    });
3345
3346    if ($option.length === 0) {
3347      $option = this.option(data);
3348
3349      this.addOptions($option);
3350    }
3351
3352    ArrayAdapter.__super__.select.call(this, data);
3353  };
3354
3355  ArrayAdapter.prototype.convertToOptions = function (data) {
3356    var self = this;
3357
3358    var $existing = this.$element.find('option');
3359    var existingIds = $existing.map(function () {
3360      return self.item($(this)).id;
3361    }).get();
3362
3363    var $options = [];
3364
3365    // Filter out all items except for the one passed in the argument
3366    function onlyItem (item) {
3367      return function () {
3368        return $(this).val() == item.id;
3369      };
3370    }
3371
3372    for (var d = 0; d < data.length; d++) {
3373      var item = this._normalizeItem(data[d]);
3374
3375      // Skip items which were pre-loaded, only merge the data
3376      if ($.inArray(item.id, existingIds) >= 0) {
3377        var $existingOption = $existing.filter(onlyItem(item));
3378
3379        var existingData = this.item($existingOption);
3380        var newData = $.extend(true, {}, item, existingData);
3381
3382        var $newOption = this.option(newData);
3383
3384        $existingOption.replaceWith($newOption);
3385
3386        continue;
3387      }
3388
3389      var $option = this.option(item);
3390
3391      if (item.children) {
3392        var $children = this.convertToOptions(item.children);
3393
3394        Utils.appendMany($option, $children);
3395      }
3396
3397      $options.push($option);
3398    }
3399
3400    return $options;
3401  };
3402
3403  return ArrayAdapter;
3404});
3405
3406S2.define('select2/data/ajax',[
3407  './array',
3408  '../utils',
3409  'jquery'
3410], function (ArrayAdapter, Utils, $) {
3411  function AjaxAdapter ($element, options) {
3412    this.ajaxOptions = this._applyDefaults(options.get('ajax'));
3413
3414    if (this.ajaxOptions.processResults != null) {
3415      this.processResults = this.ajaxOptions.processResults;
3416    }
3417
3418    AjaxAdapter.__super__.constructor.call(this, $element, options);
3419  }
3420
3421  Utils.Extend(AjaxAdapter, ArrayAdapter);
3422
3423  AjaxAdapter.prototype._applyDefaults = function (options) {
3424    var defaults = {
3425      data: function (params) {
3426        return $.extend({}, params, {
3427          q: params.term
3428        });
3429      },
3430      transport: function (params, success, failure) {
3431        var $request = $.ajax(params);
3432
3433        $request.then(success);
3434        $request.fail(failure);
3435
3436        return $request;
3437      }
3438    };
3439
3440    return $.extend({}, defaults, options, true);
3441  };
3442
3443  AjaxAdapter.prototype.processResults = function (results) {
3444    return results;
3445  };
3446
3447  AjaxAdapter.prototype.query = function (params, callback) {
3448    var matches = [];
3449    var self = this;
3450
3451    if (this._request != null) {
3452      // JSONP requests cannot always be aborted
3453      if ($.isFunction(this._request.abort)) {
3454        this._request.abort();
3455      }
3456
3457      this._request = null;
3458    }
3459
3460    var options = $.extend({
3461      type: 'GET'
3462    }, this.ajaxOptions);
3463
3464    if (typeof options.url === 'function') {
3465      options.url = options.url.call(this.$element, params);
3466    }
3467
3468    if (typeof options.data === 'function') {
3469      options.data = options.data.call(this.$element, params);
3470    }
3471
3472    function request () {
3473      var $request = options.transport(options, function (data) {
3474        var results = self.processResults(data, params);
3475
3476        if (self.options.get('debug') && window.console && console.error) {
3477          // Check to make sure that the response included a `results` key.
3478          if (!results || !results.results || !$.isArray(results.results)) {
3479            console.error(
3480              'Select2: The AJAX results did not return an array in the ' +
3481              '`results` key of the response.'
3482            );
3483          }
3484        }
3485
3486        callback(results);
3487      }, function () {
3488        // Attempt to detect if a request was aborted
3489        // Only works if the transport exposes a status property
3490        if ($request.status && $request.status === '0') {
3491          return;
3492        }
3493
3494        self.trigger('results:message', {
3495          message: 'errorLoading'
3496        });
3497      });
3498
3499      self._request = $request;
3500    }
3501
3502    if (this.ajaxOptions.delay && params.term != null) {
3503      if (this._queryTimeout) {
3504        window.clearTimeout(this._queryTimeout);
3505      }
3506
3507      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
3508    } else {
3509      request();
3510    }
3511  };
3512
3513  return AjaxAdapter;
3514});
3515
3516S2.define('select2/data/tags',[
3517  'jquery'
3518], function ($) {
3519  function Tags (decorated, $element, options) {
3520    var tags = options.get('tags');
3521
3522    var createTag = options.get('createTag');
3523
3524    if (createTag !== undefined) {
3525      this.createTag = createTag;
3526    }
3527
3528    var insertTag = options.get('insertTag');
3529
3530    if (insertTag !== undefined) {
3531        this.insertTag = insertTag;
3532    }
3533
3534    decorated.call(this, $element, options);
3535
3536    if ($.isArray(tags)) {
3537      for (var t = 0; t < tags.length; t++) {
3538        var tag = tags[t];
3539        var item = this._normalizeItem(tag);
3540
3541        var $option = this.option(item);
3542
3543        this.$element.append($option);
3544      }
3545    }
3546  }
3547
3548  Tags.prototype.query = function (decorated, params, callback) {
3549    var self = this;
3550
3551    this._removeOldTags();
3552
3553    if (params.term == null || params.page != null) {
3554      decorated.call(this, params, callback);
3555      return;
3556    }
3557
3558    function wrapper (obj, child) {
3559      var data = obj.results;
3560
3561      for (var i = 0; i < data.length; i++) {
3562        var option = data[i];
3563
3564        var checkChildren = (
3565          option.children != null &&
3566          !wrapper({
3567            results: option.children
3568          }, true)
3569        );
3570
3571        var optionText = (option.text || '').toUpperCase();
3572        var paramsTerm = (params.term || '').toUpperCase();
3573
3574        var checkText = optionText === paramsTerm;
3575
3576        if (checkText || checkChildren) {
3577          if (child) {
3578            return false;
3579          }
3580
3581          obj.data = data;
3582          callback(obj);
3583
3584          return;
3585        }
3586      }
3587
3588      if (child) {
3589        return true;
3590      }
3591
3592      var tag = self.createTag(params);
3593
3594      if (tag != null) {
3595        var $option = self.option(tag);
3596        $option.attr('data-select2-tag', true);
3597
3598        self.addOptions([$option]);
3599
3600        self.insertTag(data, tag);
3601      }
3602
3603      obj.results = data;
3604
3605      callback(obj);
3606    }
3607
3608    decorated.call(this, params, wrapper);
3609  };
3610
3611  Tags.prototype.createTag = function (decorated, params) {
3612    var term = $.trim(params.term);
3613
3614    if (term === '') {
3615      return null;
3616    }
3617
3618    return {
3619      id: term,
3620      text: term
3621    };
3622  };
3623
3624  Tags.prototype.insertTag = function (_, data, tag) {
3625    data.unshift(tag);
3626  };
3627
3628  Tags.prototype._removeOldTags = function (_) {
3629    var tag = this._lastTag;
3630
3631    var $options = this.$element.find('option[data-select2-tag]');
3632
3633    $options.each(function () {
3634      if (this.selected) {
3635        return;
3636      }
3637
3638      $(this).remove();
3639    });
3640  };
3641
3642  return Tags;
3643});
3644
3645S2.define('select2/data/tokenizer',[
3646  'jquery'
3647], function ($) {
3648  function Tokenizer (decorated, $element, options) {
3649    var tokenizer = options.get('tokenizer');
3650
3651    if (tokenizer !== undefined) {
3652      this.tokenizer = tokenizer;
3653    }
3654
3655    decorated.call(this, $element, options);
3656  }
3657
3658  Tokenizer.prototype.bind = function (decorated, container, $container) {
3659    decorated.call(this, container, $container);
3660
3661    this.$search =  container.dropdown.$search || container.selection.$search ||
3662      $container.find('.select2-search__field');
3663  };
3664
3665  Tokenizer.prototype.query = function (decorated, params, callback) {
3666    var self = this;
3667
3668    function createAndSelect (data) {
3669      // Normalize the data object so we can use it for checks
3670      var item = self._normalizeItem(data);
3671
3672      // Check if the data object already exists as a tag
3673      // Select it if it doesn't
3674      var $existingOptions = self.$element.find('option').filter(function () {
3675        return $(this).val() === item.id;
3676      });
3677
3678      // If an existing option wasn't found for it, create the option
3679      if (!$existingOptions.length) {
3680        var $option = self.option(item);
3681        $option.attr('data-select2-tag', true);
3682
3683        self._removeOldTags();
3684        self.addOptions([$option]);
3685      }
3686
3687      // Select the item, now that we know there is an option for it
3688      select(item);
3689    }
3690
3691    function select (data) {
3692      self.trigger('select', {
3693        data: data
3694      });
3695    }
3696
3697    params.term = params.term || '';
3698
3699    var tokenData = this.tokenizer(params, this.options, createAndSelect);
3700
3701    if (tokenData.term !== params.term) {
3702      // Replace the search term if we have the search box
3703      if (this.$search.length) {
3704        this.$search.val(tokenData.term);
3705        this.$search.focus();
3706      }
3707
3708      params.term = tokenData.term;
3709    }
3710
3711    decorated.call(this, params, callback);
3712  };
3713
3714  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
3715    var separators = options.get('tokenSeparators') || [];
3716    var term = params.term;
3717    var i = 0;
3718
3719    var createTag = this.createTag || function (params) {
3720      return {
3721        id: params.term,
3722        text: params.term
3723      };
3724    };
3725
3726    while (i < term.length) {
3727      var termChar = term[i];
3728
3729      if ($.inArray(termChar, separators) === -1) {
3730        i++;
3731
3732        continue;
3733      }
3734
3735      var part = term.substr(0, i);
3736      var partParams = $.extend({}, params, {
3737        term: part
3738      });
3739
3740      var data = createTag(partParams);
3741
3742      if (data == null) {
3743        i++;
3744        continue;
3745      }
3746
3747      callback(data);
3748
3749      // Reset the term to not include the tokenized portion
3750      term = term.substr(i + 1) || '';
3751      i = 0;
3752    }
3753
3754    return {
3755      term: term
3756    };
3757  };
3758
3759  return Tokenizer;
3760});
3761
3762S2.define('select2/data/minimumInputLength',[
3763
3764], function () {
3765  function MinimumInputLength (decorated, $e, options) {
3766    this.minimumInputLength = options.get('minimumInputLength');
3767
3768    decorated.call(this, $e, options);
3769  }
3770
3771  MinimumInputLength.prototype.query = function (decorated, params, callback) {
3772    params.term = params.term || '';
3773
3774    if (params.term.length < this.minimumInputLength) {
3775      this.trigger('results:message', {
3776        message: 'inputTooShort',
3777        args: {
3778          minimum: this.minimumInputLength,
3779          input: params.term,
3780          params: params
3781        }
3782      });
3783
3784      return;
3785    }
3786
3787    decorated.call(this, params, callback);
3788  };
3789
3790  return MinimumInputLength;
3791});
3792
3793S2.define('select2/data/maximumInputLength',[
3794
3795], function () {
3796  function MaximumInputLength (decorated, $e, options) {
3797    this.maximumInputLength = options.get('maximumInputLength');
3798
3799    decorated.call(this, $e, options);
3800  }
3801
3802  MaximumInputLength.prototype.query = function (decorated, params, callback) {
3803    params.term = params.term || '';
3804
3805    if (this.maximumInputLength > 0 &&
3806        params.term.length > this.maximumInputLength) {
3807      this.trigger('results:message', {
3808        message: 'inputTooLong',
3809        args: {
3810          maximum: this.maximumInputLength,
3811          input: params.term,
3812          params: params
3813        }
3814      });
3815
3816      return;
3817    }
3818
3819    decorated.call(this, params, callback);
3820  };
3821
3822  return MaximumInputLength;
3823});
3824
3825S2.define('select2/data/maximumSelectionLength',[
3826
3827], function (){
3828  function MaximumSelectionLength (decorated, $e, options) {
3829    this.maximumSelectionLength = options.get('maximumSelectionLength');
3830
3831    decorated.call(this, $e, options);
3832  }
3833
3834  MaximumSelectionLength.prototype.query =
3835    function (decorated, params, callback) {
3836      var self = this;
3837
3838      this.current(function (currentData) {
3839        var count = currentData != null ? currentData.length : 0;
3840        if (self.maximumSelectionLength > 0 &&
3841          count >= self.maximumSelectionLength) {
3842          self.trigger('results:message', {
3843            message: 'maximumSelected',
3844            args: {
3845              maximum: self.maximumSelectionLength
3846            }
3847          });
3848          return;
3849        }
3850        decorated.call(self, params, callback);
3851      });
3852  };
3853
3854  return MaximumSelectionLength;
3855});
3856
3857S2.define('select2/dropdown',[
3858  'jquery',
3859  './utils'
3860], function ($, Utils) {
3861  function Dropdown ($element, options) {
3862    this.$element = $element;
3863    this.options = options;
3864
3865    Dropdown.__super__.constructor.call(this);
3866  }
3867
3868  Utils.Extend(Dropdown, Utils.Observable);
3869
3870  Dropdown.prototype.render = function () {
3871    var $dropdown = $(
3872      '<span class="select2-dropdown">' +
3873        '<span class="select2-results"></span>' +
3874      '</span>'
3875    );
3876
3877    $dropdown.attr('dir', this.options.get('dir'));
3878
3879    this.$dropdown = $dropdown;
3880
3881    return $dropdown;
3882  };
3883
3884  Dropdown.prototype.bind = function () {
3885    // Should be implemented in subclasses
3886  };
3887
3888  Dropdown.prototype.position = function ($dropdown, $container) {
3889    // Should be implmented in subclasses
3890  };
3891
3892  Dropdown.prototype.destroy = function () {
3893    // Remove the dropdown from the DOM
3894    this.$dropdown.remove();
3895  };
3896
3897  return Dropdown;
3898});
3899
3900S2.define('select2/dropdown/search',[
3901  'jquery',
3902  '../utils'
3903], function ($, Utils) {
3904  function Search () { }
3905
3906  Search.prototype.render = function (decorated) {
3907    var $rendered = decorated.call(this);
3908
3909    var $search = $(
3910      '<span class="select2-search select2-search--dropdown">' +
3911        '<input class="select2-search__field" type="search" tabindex="-1"' +
3912        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
3913        ' spellcheck="false" role="textbox" />' +
3914      '</span>'
3915    );
3916
3917    this.$searchContainer = $search;
3918    this.$search = $search.find('input');
3919
3920    $rendered.prepend($search);
3921
3922    return $rendered;
3923  };
3924
3925  Search.prototype.bind = function (decorated, container, $container) {
3926    var self = this;
3927
3928    decorated.call(this, container, $container);
3929
3930    this.$search.on('keydown', function (evt) {
3931      self.trigger('keypress', evt);
3932
3933      self._keyUpPrevented = evt.isDefaultPrevented();
3934    });
3935
3936    // Workaround for browsers which do not support the `input` event
3937    // This will prevent double-triggering of events for browsers which support
3938    // both the `keyup` and `input` events.
3939    this.$search.on('input', function (evt) {
3940      // Unbind the duplicated `keyup` event
3941      $(this).off('keyup');
3942    });
3943
3944    this.$search.on('keyup input', function (evt) {
3945      self.handleSearch(evt);
3946    });
3947
3948    container.on('open', function () {
3949      self.$search.attr('tabindex', 0);
3950
3951      self.$search.focus();
3952
3953      window.setTimeout(function () {
3954        self.$search.focus();
3955      }, 0);
3956    });
3957
3958    container.on('close', function () {
3959      self.$search.attr('tabindex', -1);
3960
3961      self.$search.val('');
3962    });
3963
3964    container.on('focus', function () {
3965      if (!container.isOpen()) {
3966        self.$search.focus();
3967      }
3968    });
3969
3970    container.on('results:all', function (params) {
3971      if (params.query.term == null || params.query.term === '') {
3972        var showSearch = self.showSearch(params);
3973
3974        if (showSearch) {
3975          self.$searchContainer.removeClass('select2-search--hide');
3976        } else {
3977          self.$searchContainer.addClass('select2-search--hide');
3978        }
3979      }
3980    });
3981  };
3982
3983  Search.prototype.handleSearch = function (evt) {
3984    if (!this._keyUpPrevented) {
3985      var input = this.$search.val();
3986
3987      this.trigger('query', {
3988        term: input
3989      });
3990    }
3991
3992    this._keyUpPrevented = false;
3993  };
3994
3995  Search.prototype.showSearch = function (_, params) {
3996    return true;
3997  };
3998
3999  return Search;
4000});
4001
4002S2.define('select2/dropdown/hidePlaceholder',[
4003
4004], function () {
4005  function HidePlaceholder (decorated, $element, options, dataAdapter) {
4006    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
4007
4008    decorated.call(this, $element, options, dataAdapter);
4009  }
4010
4011  HidePlaceholder.prototype.append = function (decorated, data) {
4012    data.results = this.removePlaceholder(data.results);
4013
4014    decorated.call(this, data);
4015  };
4016
4017  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
4018    if (typeof placeholder === 'string') {
4019      placeholder = {
4020        id: '',
4021        text: placeholder
4022      };
4023    }
4024
4025    return placeholder;
4026  };
4027
4028  HidePlaceholder.prototype.removePlaceholder = function (_, data) {
4029    var modifiedData = data.slice(0);
4030
4031    for (var d = data.length - 1; d >= 0; d--) {
4032      var item = data[d];
4033
4034      if (this.placeholder.id === item.id) {
4035        modifiedData.splice(d, 1);
4036      }
4037    }
4038
4039    return modifiedData;
4040  };
4041
4042  return HidePlaceholder;
4043});
4044
4045S2.define('select2/dropdown/infiniteScroll',[
4046  'jquery'
4047], function ($) {
4048  function InfiniteScroll (decorated, $element, options, dataAdapter) {
4049    this.lastParams = {};
4050
4051    decorated.call(this, $element, options, dataAdapter);
4052
4053    this.$loadingMore = this.createLoadingMore();
4054    this.loading = false;
4055  }
4056
4057  InfiniteScroll.prototype.append = function (decorated, data) {
4058    this.$loadingMore.remove();
4059    this.loading = false;
4060
4061    decorated.call(this, data);
4062
4063    if (this.showLoadingMore(data)) {
4064      this.$results.append(this.$loadingMore);
4065    }
4066  };
4067
4068  InfiniteScroll.prototype.bind = function (decorated, container, $container) {
4069    var self = this;
4070
4071    decorated.call(this, container, $container);
4072
4073    container.on('query', function (params) {
4074      self.lastParams = params;
4075      self.loading = true;
4076    });
4077
4078    container.on('query:append', function (params) {
4079      self.lastParams = params;
4080      self.loading = true;
4081    });
4082
4083    this.$results.on('scroll', function () {
4084      var isLoadMoreVisible = $.contains(
4085        document.documentElement,
4086        self.$loadingMore[0]
4087      );
4088
4089      if (self.loading || !isLoadMoreVisible) {
4090        return;
4091      }
4092
4093      var currentOffset = self.$results.offset().top +
4094        self.$results.outerHeight(false);
4095      var loadingMoreOffset = self.$loadingMore.offset().top +
4096        self.$loadingMore.outerHeight(false);
4097
4098      if (currentOffset + 50 >= loadingMoreOffset) {
4099        self.loadMore();
4100      }
4101    });
4102  };
4103
4104  InfiniteScroll.prototype.loadMore = function () {
4105    this.loading = true;
4106
4107    var params = $.extend({}, {page: 1}, this.lastParams);
4108
4109    params.page++;
4110
4111    this.trigger('query:append', params);
4112  };
4113
4114  InfiniteScroll.prototype.showLoadingMore = function (_, data) {
4115    return data.pagination && data.pagination.more;
4116  };
4117
4118  InfiniteScroll.prototype.createLoadingMore = function () {
4119    var $option = $(
4120      '<li ' +
4121      'class="select2-results__option select2-results__option--load-more"' +
4122      'role="treeitem" aria-disabled="true"></li>'
4123    );
4124
4125    var message = this.options.get('translations').get('loadingMore');
4126
4127    $option.html(message(this.lastParams));
4128
4129    return $option;
4130  };
4131
4132  return InfiniteScroll;
4133});
4134
4135S2.define('select2/dropdown/attachBody',[
4136  'jquery',
4137  '../utils'
4138], function ($, Utils) {
4139  function AttachBody (decorated, $element, options) {
4140    this.$dropdownParent = options.get('dropdownParent') || $(document.body);
4141
4142    decorated.call(this, $element, options);
4143  }
4144
4145  AttachBody.prototype.bind = function (decorated, container, $container) {
4146    var self = this;
4147
4148    var setupResultsEvents = false;
4149
4150    decorated.call(this, container, $container);
4151
4152    container.on('open', function () {
4153      self._showDropdown();
4154      self._attachPositioningHandler(container);
4155
4156      if (!setupResultsEvents) {
4157        setupResultsEvents = true;
4158
4159        container.on('results:all', function () {
4160          self._positionDropdown();
4161          self._resizeDropdown();
4162        });
4163
4164        container.on('results:append', function () {
4165          self._positionDropdown();
4166          self._resizeDropdown();
4167        });
4168      }
4169    });
4170
4171    container.on('close', function () {
4172      self._hideDropdown();
4173      self._detachPositioningHandler(container);
4174    });
4175
4176    this.$dropdownContainer.on('mousedown', function (evt) {
4177      evt.stopPropagation();
4178    });
4179  };
4180
4181  AttachBody.prototype.destroy = function (decorated) {
4182    decorated.call(this);
4183
4184    this.$dropdownContainer.remove();
4185  };
4186
4187  AttachBody.prototype.position = function (decorated, $dropdown, $container) {
4188    // Clone all of the container classes
4189    $dropdown.attr('class', $container.attr('class'));
4190
4191    $dropdown.removeClass('select2');
4192    $dropdown.addClass('select2-container--open');
4193
4194    $dropdown.css({
4195      position: 'absolute',
4196      top: -999999
4197    });
4198
4199    this.$container = $container;
4200  };
4201
4202  AttachBody.prototype.render = function (decorated) {
4203    var $container = $('<span></span>');
4204
4205    var $dropdown = decorated.call(this);
4206    $container.append($dropdown);
4207
4208    this.$dropdownContainer = $container;
4209
4210    return $container;
4211  };
4212
4213  AttachBody.prototype._hideDropdown = function (decorated) {
4214    this.$dropdownContainer.detach();
4215  };
4216
4217  AttachBody.prototype._attachPositioningHandler =
4218      function (decorated, container) {
4219    var self = this;
4220
4221    var scrollEvent = 'scroll.select2.' + container.id;
4222    var resizeEvent = 'resize.select2.' + container.id;
4223    var orientationEvent = 'orientationchange.select2.' + container.id;
4224
4225    var $watchers = this.$container.parents().filter(Utils.hasScroll);
4226    $watchers.each(function () {
4227      $(this).data('select2-scroll-position', {
4228        x: $(this).scrollLeft(),
4229        y: $(this).scrollTop()
4230      });
4231    });
4232
4233    $watchers.on(scrollEvent, function (ev) {
4234      var position = $(this).data('select2-scroll-position');
4235      $(this).scrollTop(position.y);
4236    });
4237
4238    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
4239      function (e) {
4240      self._positionDropdown();
4241      self._resizeDropdown();
4242    });
4243  };
4244
4245  AttachBody.prototype._detachPositioningHandler =
4246      function (decorated, container) {
4247    var scrollEvent = 'scroll.select2.' + container.id;
4248    var resizeEvent = 'resize.select2.' + container.id;
4249    var orientationEvent = 'orientationchange.select2.' + container.id;
4250
4251    var $watchers = this.$container.parents().filter(Utils.hasScroll);
4252    $watchers.off(scrollEvent);
4253
4254    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
4255  };
4256
4257  AttachBody.prototype._positionDropdown = function () {
4258    var $window = $(window);
4259
4260    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
4261    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
4262
4263    var newDirection = null;
4264
4265    var offset = this.$container.offset();
4266
4267    offset.bottom = offset.top + this.$container.outerHeight(false);
4268
4269    var container = {
4270      height: this.$container.outerHeight(false)
4271    };
4272
4273    container.top = offset.top;
4274    container.bottom = offset.top + container.height;
4275
4276    var dropdown = {
4277      height: this.$dropdown.outerHeight(false)
4278    };
4279
4280    var viewport = {
4281      top: $window.scrollTop(),
4282      bottom: $window.scrollTop() + $window.height()
4283    };
4284
4285    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
4286    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
4287
4288    var css = {
4289      left: offset.left,
4290      top: container.bottom
4291    };
4292
4293    // Determine what the parent element is to use for calciulating the offset
4294    var $offsetParent = this.$dropdownParent;
4295
4296    // For statically positoned elements, we need to get the element
4297    // that is determining the offset
4298    if ($offsetParent.css('position') === 'static') {
4299      $offsetParent = $offsetParent.offsetParent();
4300    }
4301
4302    var parentOffset = $offsetParent.offset();
4303
4304    css.top -= parentOffset.top;
4305    css.left -= parentOffset.left;
4306
4307    if (!isCurrentlyAbove && !isCurrentlyBelow) {
4308      newDirection = 'below';
4309    }
4310
4311    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
4312      newDirection = 'above';
4313    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
4314      newDirection = 'below';
4315    }
4316
4317    if (newDirection == 'above' ||
4318      (isCurrentlyAbove && newDirection !== 'below')) {
4319      css.top = container.top - parentOffset.top - dropdown.height;
4320    }
4321
4322    if (newDirection != null) {
4323      this.$dropdown
4324        .removeClass('select2-dropdown--below select2-dropdown--above')
4325        .addClass('select2-dropdown--' + newDirection);
4326      this.$container
4327        .removeClass('select2-container--below select2-container--above')
4328        .addClass('select2-container--' + newDirection);
4329    }
4330
4331    this.$dropdownContainer.css(css);
4332  };
4333
4334  AttachBody.prototype._resizeDropdown = function () {
4335    var css = {
4336      width: this.$container.outerWidth(false) + 'px'
4337    };
4338
4339    if (this.options.get('dropdownAutoWidth')) {
4340      css.minWidth = css.width;
4341      css.position = 'relative';
4342      css.width = 'auto';
4343    }
4344
4345    this.$dropdown.css(css);
4346  };
4347
4348  AttachBody.prototype._showDropdown = function (decorated) {
4349    this.$dropdownContainer.appendTo(this.$dropdownParent);
4350
4351    this._positionDropdown();
4352    this._resizeDropdown();
4353  };
4354
4355  return AttachBody;
4356});
4357
4358S2.define('select2/dropdown/minimumResultsForSearch',[
4359
4360], function () {
4361  function countResults (data) {
4362    var count = 0;
4363
4364    for (var d = 0; d < data.length; d++) {
4365      var item = data[d];
4366
4367      if (item.children) {
4368        count += countResults(item.children);
4369      } else {
4370        count++;
4371      }
4372    }
4373
4374    return count;
4375  }
4376
4377  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
4378    this.minimumResultsForSearch = options.get('minimumResultsForSearch');
4379
4380    if (this.minimumResultsForSearch < 0) {
4381      this.minimumResultsForSearch = Infinity;
4382    }
4383
4384    decorated.call(this, $element, options, dataAdapter);
4385  }
4386
4387  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
4388    if (countResults(params.data.results) < this.minimumResultsForSearch) {
4389      return false;
4390    }
4391
4392    return decorated.call(this, params);
4393  };
4394
4395  return MinimumResultsForSearch;
4396});
4397
4398S2.define('select2/dropdown/selectOnClose',[
4399
4400], function () {
4401  function SelectOnClose () { }
4402
4403  SelectOnClose.prototype.bind = function (decorated, container, $container) {
4404    var self = this;
4405
4406    decorated.call(this, container, $container);
4407
4408    container.on('close', function (params) {
4409      self._handleSelectOnClose(params);
4410    });
4411  };
4412
4413  SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
4414    if (params && params.originalSelect2Event != null) {
4415      var event = params.originalSelect2Event;
4416
4417      // Don't select an item if the close event was triggered from a select or
4418      // unselect event
4419      if (event._type === 'select' || event._type === 'unselect') {
4420        return;
4421      }
4422    }
4423
4424    var $highlightedResults = this.getHighlightedResults();
4425
4426    // Only select highlighted results
4427    if ($highlightedResults.length < 1) {
4428      return;
4429    }
4430
4431    var data = $highlightedResults.data('data');
4432
4433    // Don't re-select already selected resulte
4434    if (
4435      (data.element != null && data.element.selected) ||
4436      (data.element == null && data.selected)
4437    ) {
4438      return;
4439    }
4440
4441    this.trigger('select', {
4442        data: data
4443    });
4444  };
4445
4446  return SelectOnClose;
4447});
4448
4449S2.define('select2/dropdown/closeOnSelect',[
4450
4451], function () {
4452  function CloseOnSelect () { }
4453
4454  CloseOnSelect.prototype.bind = function (decorated, container, $container) {
4455    var self = this;
4456
4457    decorated.call(this, container, $container);
4458
4459    container.on('select', function (evt) {
4460      self._selectTriggered(evt);
4461    });
4462
4463    container.on('unselect', function (evt) {
4464      self._selectTriggered(evt);
4465    });
4466  };
4467
4468  CloseOnSelect.prototype._selectTriggered = function (_, evt) {
4469    var originalEvent = evt.originalEvent;
4470
4471    // Don't close if the control key is being held
4472    if (originalEvent && originalEvent.ctrlKey) {
4473      return;
4474    }
4475
4476    this.trigger('close', {
4477      originalEvent: originalEvent,
4478      originalSelect2Event: evt
4479    });
4480  };
4481
4482  return CloseOnSelect;
4483});
4484
4485S2.define('select2/i18n/en',[],function () {
4486  // English
4487  return {
4488    errorLoading: function () {
4489      return 'The results could not be loaded.';
4490    },
4491    inputTooLong: function (args) {
4492      var overChars = args.input.length - args.maximum;
4493
4494      var message = 'Please delete ' + overChars + ' character';
4495
4496      if (overChars != 1) {
4497        message += 's';
4498      }
4499
4500      return message;
4501    },
4502    inputTooShort: function (args) {
4503      var remainingChars = args.minimum - args.input.length;
4504
4505      var message = 'Please enter ' + remainingChars + ' or more characters';
4506
4507      return message;
4508    },
4509    loadingMore: function () {
4510      return 'Loading more results…';
4511    },
4512    maximumSelected: function (args) {
4513      var message = 'You can only select ' + args.maximum + ' item';
4514
4515      if (args.maximum != 1) {
4516        message += 's';
4517      }
4518
4519      return message;
4520    },
4521    noResults: function () {
4522      return 'No results found';
4523    },
4524    searching: function () {
4525      return 'Searching…';
4526    }
4527  };
4528});
4529
4530S2.define('select2/defaults',[
4531  'jquery',
4532  'require',
4533
4534  './results',
4535
4536  './selection/single',
4537  './selection/multiple',
4538  './selection/placeholder',
4539  './selection/allowClear',
4540  './selection/search',
4541  './selection/eventRelay',
4542
4543  './utils',
4544  './translation',
4545  './diacritics',
4546
4547  './data/select',
4548  './data/array',
4549  './data/ajax',
4550  './data/tags',
4551  './data/tokenizer',
4552  './data/minimumInputLength',
4553  './data/maximumInputLength',
4554  './data/maximumSelectionLength',
4555
4556  './dropdown',
4557  './dropdown/search',
4558  './dropdown/hidePlaceholder',
4559  './dropdown/infiniteScroll',
4560  './dropdown/attachBody',
4561  './dropdown/minimumResultsForSearch',
4562  './dropdown/selectOnClose',
4563  './dropdown/closeOnSelect',
4564
4565  './i18n/en'
4566], function ($, require,
4567
4568             ResultsList,
4569
4570             SingleSelection, MultipleSelection, Placeholder, AllowClear,
4571             SelectionSearch, EventRelay,
4572
4573             Utils, Translation, DIACRITICS,
4574
4575             SelectData, ArrayData, AjaxData, Tags, Tokenizer,
4576             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
4577
4578             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
4579             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
4580
4581             EnglishTranslation) {
4582  function Defaults () {
4583    this.reset();
4584  }
4585
4586  Defaults.prototype.apply = function (options) {
4587    options = $.extend(true, {}, this.defaults, options);
4588
4589    if (options.dataAdapter == null) {
4590      if (options.ajax != null) {
4591        options.dataAdapter = AjaxData;
4592      } else if (options.data != null) {
4593        options.dataAdapter = ArrayData;
4594      } else {
4595        options.dataAdapter = SelectData;
4596      }
4597
4598      if (options.minimumInputLength > 0) {
4599        options.dataAdapter = Utils.Decorate(
4600          options.dataAdapter,
4601          MinimumInputLength
4602        );
4603      }
4604
4605      if (options.maximumInputLength > 0) {
4606        options.dataAdapter = Utils.Decorate(
4607          options.dataAdapter,
4608          MaximumInputLength
4609        );
4610      }
4611
4612      if (options.maximumSelectionLength > 0) {
4613        options.dataAdapter = Utils.Decorate(
4614          options.dataAdapter,
4615          MaximumSelectionLength
4616        );
4617      }
4618
4619      if (options.tags) {
4620        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
4621      }
4622
4623      if (options.tokenSeparators != null || options.tokenizer != null) {
4624        options.dataAdapter = Utils.Decorate(
4625          options.dataAdapter,
4626          Tokenizer
4627        );
4628      }
4629
4630      if (options.query != null) {
4631        var Query = require(options.amdBase + 'compat/query');
4632
4633        options.dataAdapter = Utils.Decorate(
4634          options.dataAdapter,
4635          Query
4636        );
4637      }
4638
4639      if (options.initSelection != null) {
4640        var InitSelection = require(options.amdBase + 'compat/initSelection');
4641
4642        options.dataAdapter = Utils.Decorate(
4643          options.dataAdapter,
4644          InitSelection
4645        );
4646      }
4647    }
4648
4649    if (options.resultsAdapter == null) {
4650      options.resultsAdapter = ResultsList;
4651
4652      if (options.ajax != null) {
4653        options.resultsAdapter = Utils.Decorate(
4654          options.resultsAdapter,
4655          InfiniteScroll
4656        );
4657      }
4658
4659      if (options.placeholder != null) {
4660        options.resultsAdapter = Utils.Decorate(
4661          options.resultsAdapter,
4662          HidePlaceholder
4663        );
4664      }
4665
4666      if (options.selectOnClose) {
4667        options.resultsAdapter = Utils.Decorate(
4668          options.resultsAdapter,
4669          SelectOnClose
4670        );
4671      }
4672    }
4673
4674    if (options.dropdownAdapter == null) {
4675      if (options.multiple) {
4676        options.dropdownAdapter = Dropdown;
4677      } else {
4678        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
4679
4680        options.dropdownAdapter = SearchableDropdown;
4681      }
4682
4683      if (options.minimumResultsForSearch !== 0) {
4684        options.dropdownAdapter = Utils.Decorate(
4685          options.dropdownAdapter,
4686          MinimumResultsForSearch
4687        );
4688      }
4689
4690      if (options.closeOnSelect) {
4691        options.dropdownAdapter = Utils.Decorate(
4692          options.dropdownAdapter,
4693          CloseOnSelect
4694        );
4695      }
4696
4697      if (
4698        options.dropdownCssClass != null ||
4699        options.dropdownCss != null ||
4700        options.adaptDropdownCssClass != null
4701      ) {
4702        var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4703
4704        options.dropdownAdapter = Utils.Decorate(
4705          options.dropdownAdapter,
4706          DropdownCSS
4707        );
4708      }
4709
4710      options.dropdownAdapter = Utils.Decorate(
4711        options.dropdownAdapter,
4712        AttachBody
4713      );
4714    }
4715
4716    if (options.selectionAdapter == null) {
4717      if (options.multiple) {
4718        options.selectionAdapter = MultipleSelection;
4719      } else {
4720        options.selectionAdapter = SingleSelection;
4721      }
4722
4723      // Add the placeholder mixin if a placeholder was specified
4724      if (options.placeholder != null) {
4725        options.selectionAdapter = Utils.Decorate(
4726          options.selectionAdapter,
4727          Placeholder
4728        );
4729      }
4730
4731      if (options.allowClear) {
4732        options.selectionAdapter = Utils.Decorate(
4733          options.selectionAdapter,
4734          AllowClear
4735        );
4736      }
4737
4738      if (options.multiple) {
4739        options.selectionAdapter = Utils.Decorate(
4740          options.selectionAdapter,
4741          SelectionSearch
4742        );
4743      }
4744
4745      if (
4746        options.containerCssClass != null ||
4747        options.containerCss != null ||
4748        options.adaptContainerCssClass != null
4749      ) {
4750        var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4751
4752        options.selectionAdapter = Utils.Decorate(
4753          options.selectionAdapter,
4754          ContainerCSS
4755        );
4756      }
4757
4758      options.selectionAdapter = Utils.Decorate(
4759        options.selectionAdapter,
4760        EventRelay
4761      );
4762    }
4763
4764    if (typeof options.language === 'string') {
4765      // Check if the language is specified with a region
4766      if (options.language.indexOf('-') > 0) {
4767        // Extract the region information if it is included
4768        var languageParts = options.language.split('-');
4769        var baseLanguage = languageParts[0];
4770
4771        options.language = [options.language, baseLanguage];
4772      } else {
4773        options.language = [options.language];
4774      }
4775    }
4776
4777    if ($.isArray(options.language)) {
4778      var languages = new Translation();
4779      options.language.push('en');
4780
4781      var languageNames = options.language;
4782
4783      for (var l = 0; l < languageNames.length; l++) {
4784        var name = languageNames[l];
4785        var language = {};
4786
4787        try {
4788          // Try to load it with the original name
4789          language = Translation.loadPath(name);
4790        } catch (e) {
4791          try {
4792            // If we couldn't load it, check if it wasn't the full path
4793            name = this.defaults.amdLanguageBase + name;
4794            language = Translation.loadPath(name);
4795          } catch (ex) {
4796            // The translation could not be loaded at all. Sometimes this is
4797            // because of a configuration problem, other times this can be
4798            // because of how Select2 helps load all possible translation files.
4799            if (options.debug && window.console && console.warn) {
4800              console.warn(
4801                'Select2: The language file for "' + name + '" could not be ' +
4802                'automatically loaded. A fallback will be used instead.'
4803              );
4804            }
4805
4806            continue;
4807          }
4808        }
4809
4810        languages.extend(language);
4811      }
4812
4813      options.translations = languages;
4814    } else {
4815      var baseTranslation = Translation.loadPath(
4816        this.defaults.amdLanguageBase + 'en'
4817      );
4818      var customTranslation = new Translation(options.language);
4819
4820      customTranslation.extend(baseTranslation);
4821
4822      options.translations = customTranslation;
4823    }
4824
4825    return options;
4826  };
4827
4828  Defaults.prototype.reset = function () {
4829    function stripDiacritics (text) {
4830      // Used 'uni range + named function' from http://jsperf.com/diacritics/18
4831      function match(a) {
4832        return DIACRITICS[a] || a;
4833      }
4834
4835      return text.replace(/[^\u0000-\u007E]/g, match);
4836    }
4837
4838    function matcher (params, data) {
4839      // Always return the object if there is nothing to compare
4840      if ($.trim(params.term) === '') {
4841        return data;
4842      }
4843
4844      // Do a recursive check for options with children
4845      if (data.children && data.children.length > 0) {
4846        // Clone the data object if there are children
4847        // This is required as we modify the object to remove any non-matches
4848        var match = $.extend(true, {}, data);
4849
4850        // Check each child of the option
4851        for (var c = data.children.length - 1; c >= 0; c--) {
4852          var child = data.children[c];
4853
4854          var matches = matcher(params, child);
4855
4856          // If there wasn't a match, remove the object in the array
4857          if (matches == null) {
4858            match.children.splice(c, 1);
4859          }
4860        }
4861
4862        // If any children matched, return the new object
4863        if (match.children.length > 0) {
4864          return match;
4865        }
4866
4867        // If there were no matching children, check just the plain object
4868        return matcher(params, match);
4869      }
4870
4871      var original = stripDiacritics(data.text).toUpperCase();
4872      var term = stripDiacritics(params.term).toUpperCase();
4873
4874      // Check if the text contains the term
4875      if (original.indexOf(term) > -1) {
4876        return data;
4877      }
4878
4879      // If it doesn't contain the term, don't return anything
4880      return null;
4881    }
4882
4883    this.defaults = {
4884      amdBase: './',
4885      amdLanguageBase: './i18n/',
4886      closeOnSelect: true,
4887      debug: false,
4888      dropdownAutoWidth: false,
4889      escapeMarkup: Utils.escapeMarkup,
4890      language: EnglishTranslation,
4891      matcher: matcher,
4892      minimumInputLength: 0,
4893      maximumInputLength: 0,
4894      maximumSelectionLength: 0,
4895      minimumResultsForSearch: 0,
4896      selectOnClose: false,
4897      sorter: function (data) {
4898        return data;
4899      },
4900      templateResult: function (result) {
4901        return result.text;
4902      },
4903      templateSelection: function (selection) {
4904        return selection.text;
4905      },
4906      theme: 'default',
4907      width: 'resolve'
4908    };
4909  };
4910
4911  Defaults.prototype.set = function (key, value) {
4912    var camelKey = $.camelCase(key);
4913
4914    var data = {};
4915    data[camelKey] = value;
4916
4917    var convertedData = Utils._convertData(data);
4918
4919    $.extend(this.defaults, convertedData);
4920  };
4921
4922  var defaults = new Defaults();
4923
4924  return defaults;
4925});
4926
4927S2.define('select2/options',[
4928  'require',
4929  'jquery',
4930  './defaults',
4931  './utils'
4932], function (require, $, Defaults, Utils) {
4933  function Options (options, $element) {
4934    this.options = options;
4935
4936    if ($element != null) {
4937      this.fromElement($element);
4938    }
4939
4940    this.options = Defaults.apply(this.options);
4941
4942    if ($element && $element.is('input')) {
4943      var InputCompat = require(this.get('amdBase') + 'compat/inputData');
4944
4945      this.options.dataAdapter = Utils.Decorate(
4946        this.options.dataAdapter,
4947        InputCompat
4948      );
4949    }
4950  }
4951
4952  Options.prototype.fromElement = function ($e) {
4953    var excludedData = ['select2'];
4954
4955    if (this.options.multiple == null) {
4956      this.options.multiple = $e.prop('multiple');
4957    }
4958
4959    if (this.options.disabled == null) {
4960      this.options.disabled = $e.prop('disabled');
4961    }
4962
4963    if (this.options.language == null) {
4964      if ($e.prop('lang')) {
4965        this.options.language = $e.prop('lang').toLowerCase();
4966      } else if ($e.closest('[lang]').prop('lang')) {
4967        this.options.language = $e.closest('[lang]').prop('lang');
4968      }
4969    }
4970
4971    if (this.options.dir == null) {
4972      if ($e.prop('dir')) {
4973        this.options.dir = $e.prop('dir');
4974      } else if ($e.closest('[dir]').prop('dir')) {
4975        this.options.dir = $e.closest('[dir]').prop('dir');
4976      } else {
4977        this.options.dir = 'ltr';
4978      }
4979    }
4980
4981    $e.prop('disabled', this.options.disabled);
4982    $e.prop('multiple', this.options.multiple);
4983
4984    if ($e.data('select2Tags')) {
4985      if (this.options.debug && window.console && console.warn) {
4986        console.warn(
4987          'Select2: The `data-select2-tags` attribute has been changed to ' +
4988          'use the `data-data` and `data-tags="true"` attributes and will be ' +
4989          'removed in future versions of Select2.'
4990        );
4991      }
4992
4993      $e.data('data', $e.data('select2Tags'));
4994      $e.data('tags', true);
4995    }
4996
4997    if ($e.data('ajaxUrl')) {
4998      if (this.options.debug && window.console && console.warn) {
4999        console.warn(
5000          'Select2: The `data-ajax-url` attribute has been changed to ' +
5001          '`data-ajax--url` and support for the old attribute will be removed' +
5002          ' in future versions of Select2.'
5003        );
5004      }
5005
5006      $e.attr('ajax--url', $e.data('ajaxUrl'));
5007      $e.data('ajax--url', $e.data('ajaxUrl'));
5008    }
5009
5010    var dataset = {};
5011
5012    // Prefer the element's `dataset` attribute if it exists
5013    // jQuery 1.x does not correctly handle data attributes with multiple dashes
5014    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
5015      dataset = $.extend(true, {}, $e[0].dataset, $e.data());
5016    } else {
5017      dataset = $e.data();
5018    }
5019
5020    var data = $.extend(true, {}, dataset);
5021
5022    data = Utils._convertData(data);
5023
5024    for (var key in data) {
5025      if ($.inArray(key, excludedData) > -1) {
5026        continue;
5027      }
5028
5029      if ($.isPlainObject(this.options[key])) {
5030        $.extend(this.options[key], data[key]);
5031      } else {
5032        this.options[key] = data[key];
5033      }
5034    }
5035
5036    return this;
5037  };
5038
5039  Options.prototype.get = function (key) {
5040    return this.options[key];
5041  };
5042
5043  Options.prototype.set = function (key, val) {
5044    this.options[key] = val;
5045  };
5046
5047  return Options;
5048});
5049
5050S2.define('select2/core',[
5051  'jquery',
5052  './options',
5053  './utils',
5054  './keys'
5055], function ($, Options, Utils, KEYS) {
5056  var Select2 = function ($element, options) {
5057    if ($element.data('select2') != null) {
5058      $element.data('select2').destroy();
5059    }
5060
5061    this.$element = $element;
5062
5063    this.id = this._generateId($element);
5064
5065    options = options || {};
5066
5067    this.options = new Options(options, $element);
5068
5069    Select2.__super__.constructor.call(this);
5070
5071    // Set up the tabindex
5072
5073    var tabindex = $element.attr('tabindex') || 0;
5074    $element.data('old-tabindex', tabindex);
5075    $element.attr('tabindex', '-1');
5076
5077    // Set up containers and adapters
5078
5079    var DataAdapter = this.options.get('dataAdapter');
5080    this.dataAdapter = new DataAdapter($element, this.options);
5081
5082    var $container = this.render();
5083
5084    this._placeContainer($container);
5085
5086    var SelectionAdapter = this.options.get('selectionAdapter');
5087    this.selection = new SelectionAdapter($element, this.options);
5088    this.$selection = this.selection.render();
5089
5090    this.selection.position(this.$selection, $container);
5091
5092    var DropdownAdapter = this.options.get('dropdownAdapter');
5093    this.dropdown = new DropdownAdapter($element, this.options);
5094    this.$dropdown = this.dropdown.render();
5095
5096    this.dropdown.position(this.$dropdown, $container);
5097
5098    var ResultsAdapter = this.options.get('resultsAdapter');
5099    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
5100    this.$results = this.results.render();
5101
5102    this.results.position(this.$results, this.$dropdown);
5103
5104    // Bind events
5105
5106    var self = this;
5107
5108    // Bind the container to all of the adapters
5109    this._bindAdapters();
5110
5111    // Register any DOM event handlers
5112    this._registerDomEvents();
5113
5114    // Register any internal event handlers
5115    this._registerDataEvents();
5116    this._registerSelectionEvents();
5117    this._registerDropdownEvents();
5118    this._registerResultsEvents();
5119    this._registerEvents();
5120
5121    // Set the initial state
5122    this.dataAdapter.current(function (initialData) {
5123      self.trigger('selection:update', {
5124        data: initialData
5125      });
5126    });
5127
5128    // Hide the original select
5129    $element.addClass('select2-hidden-accessible');
5130    $element.attr('aria-hidden', 'true');
5131
5132    // Synchronize any monitored attributes
5133    this._syncAttributes();
5134
5135    $element.data('select2', this);
5136  };
5137
5138  Utils.Extend(Select2, Utils.Observable);
5139
5140  Select2.prototype._generateId = function ($element) {
5141    var id = '';
5142
5143    if ($element.attr('id') != null) {
5144      id = $element.attr('id');
5145    } else if ($element.attr('name') != null) {
5146      id = $element.attr('name') + '-' + Utils.generateChars(2);
5147    } else {
5148      id = Utils.generateChars(4);
5149    }
5150
5151    id = id.replace(/(:|\.|\[|\]|,)/g, '');
5152    id = 'select2-' + id;
5153
5154    return id;
5155  };
5156
5157  Select2.prototype._placeContainer = function ($container) {
5158    $container.insertAfter(this.$element);
5159
5160    var width = this._resolveWidth(this.$element, this.options.get('width'));
5161
5162    if (width != null) {
5163      $container.css('width', width);
5164    }
5165  };
5166
5167  Select2.prototype._resolveWidth = function ($element, method) {
5168    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
5169
5170    if (method == 'resolve') {
5171      var styleWidth = this._resolveWidth($element, 'style');
5172
5173      if (styleWidth != null) {
5174        return styleWidth;
5175      }
5176
5177      return this._resolveWidth($element, 'element');
5178    }
5179
5180    if (method == 'element') {
5181      var elementWidth = $element.outerWidth(false);
5182
5183      if (elementWidth <= 0) {
5184        return 'auto';
5185      }
5186
5187      return elementWidth + 'px';
5188    }
5189
5190    if (method == 'style') {
5191      var style = $element.attr('style');
5192
5193      if (typeof(style) !== 'string') {
5194        return null;
5195      }
5196
5197      var attrs = style.split(';');
5198
5199      for (var i = 0, l = attrs.length; i < l; i = i + 1) {
5200        var attr = attrs[i].replace(/\s/g, '');
5201        var matches = attr.match(WIDTH);
5202
5203        if (matches !== null && matches.length >= 1) {
5204          return matches[1];
5205        }
5206      }
5207
5208      return null;
5209    }
5210
5211    return method;
5212  };
5213
5214  Select2.prototype._bindAdapters = function () {
5215    this.dataAdapter.bind(this, this.$container);
5216    this.selection.bind(this, this.$container);
5217
5218    this.dropdown.bind(this, this.$container);
5219    this.results.bind(this, this.$container);
5220  };
5221
5222  Select2.prototype._registerDomEvents = function () {
5223    var self = this;
5224
5225    this.$element.on('change.select2', function () {
5226      self.dataAdapter.current(function (data) {
5227        self.trigger('selection:update', {
5228          data: data
5229        });
5230      });
5231    });
5232
5233    this.$element.on('focus.select2', function (evt) {
5234      self.trigger('focus', evt);
5235    });
5236
5237    this._syncA = Utils.bind(this._syncAttributes, this);
5238    this._syncS = Utils.bind(this._syncSubtree, this);
5239
5240    if (this.$element[0].attachEvent) {
5241      this.$element[0].attachEvent('onpropertychange', this._syncA);
5242    }
5243
5244    var observer = window.MutationObserver ||
5245      window.WebKitMutationObserver ||
5246      window.MozMutationObserver
5247    ;
5248
5249    if (observer != null) {
5250      this._observer = new observer(function (mutations) {
5251        $.each(mutations, self._syncA);
5252        $.each(mutations, self._syncS);
5253      });
5254      this._observer.observe(this.$element[0], {
5255        attributes: true,
5256        childList: true,
5257        subtree: false
5258      });
5259    } else if (this.$element[0].addEventListener) {
5260      this.$element[0].addEventListener(
5261        'DOMAttrModified',
5262        self._syncA,
5263        false
5264      );
5265      this.$element[0].addEventListener(
5266        'DOMNodeInserted',
5267        self._syncS,
5268        false
5269      );
5270      this.$element[0].addEventListener(
5271        'DOMNodeRemoved',
5272        self._syncS,
5273        false
5274      );
5275    }
5276  };
5277
5278  Select2.prototype._registerDataEvents = function () {
5279    var self = this;
5280
5281    this.dataAdapter.on('*', function (name, params) {
5282      self.trigger(name, params);
5283    });
5284  };
5285
5286  Select2.prototype._registerSelectionEvents = function () {
5287    var self = this;
5288    var nonRelayEvents = ['toggle', 'focus'];
5289
5290    this.selection.on('toggle', function () {
5291      self.toggleDropdown();
5292    });
5293
5294    this.selection.on('focus', function (params) {
5295      self.focus(params);
5296    });
5297
5298    this.selection.on('*', function (name, params) {
5299      if ($.inArray(name, nonRelayEvents) !== -1) {
5300        return;
5301      }
5302
5303      self.trigger(name, params);
5304    });
5305  };
5306
5307  Select2.prototype._registerDropdownEvents = function () {
5308    var self = this;
5309
5310    this.dropdown.on('*', function (name, params) {
5311      self.trigger(name, params);
5312    });
5313  };
5314
5315  Select2.prototype._registerResultsEvents = function () {
5316    var self = this;
5317
5318    this.results.on('*', function (name, params) {
5319      self.trigger(name, params);
5320    });
5321  };
5322
5323  Select2.prototype._registerEvents = function () {
5324    var self = this;
5325
5326    this.on('open', function () {
5327      self.$container.addClass('select2-container--open');
5328    });
5329
5330    this.on('close', function () {
5331      self.$container.removeClass('select2-container--open');
5332    });
5333
5334    this.on('enable', function () {
5335      self.$container.removeClass('select2-container--disabled');
5336    });
5337
5338    this.on('disable', function () {
5339      self.$container.addClass('select2-container--disabled');
5340    });
5341
5342    this.on('blur', function () {
5343      self.$container.removeClass('select2-container--focus');
5344    });
5345
5346    this.on('query', function (params) {
5347      if (!self.isOpen()) {
5348        self.trigger('open', {});
5349      }
5350
5351      this.dataAdapter.query(params, function (data) {
5352        self.trigger('results:all', {
5353          data: data,
5354          query: params
5355        });
5356      });
5357    });
5358
5359    this.on('query:append', function (params) {
5360      this.dataAdapter.query(params, function (data) {
5361        self.trigger('results:append', {
5362          data: data,
5363          query: params
5364        });
5365      });
5366    });
5367
5368    this.on('keypress', function (evt) {
5369      var key = evt.which;
5370
5371      if (self.isOpen()) {
5372        if (key === KEYS.ESC || key === KEYS.TAB ||
5373            (key === KEYS.UP && evt.altKey)) {
5374          self.close();
5375
5376          evt.preventDefault();
5377        } else if (key === KEYS.ENTER) {
5378          self.trigger('results:select', {});
5379
5380          evt.preventDefault();
5381        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
5382          self.trigger('results:toggle', {});
5383
5384          evt.preventDefault();
5385        } else if (key === KEYS.UP) {
5386          self.trigger('results:previous', {});
5387
5388          evt.preventDefault();
5389        } else if (key === KEYS.DOWN) {
5390          self.trigger('results:next', {});
5391
5392          evt.preventDefault();
5393        }
5394      } else {
5395        if (key === KEYS.ENTER || key === KEYS.SPACE ||
5396            (key === KEYS.DOWN && evt.altKey)) {
5397          self.open();
5398
5399          evt.preventDefault();
5400        }
5401      }
5402    });
5403  };
5404
5405  Select2.prototype._syncAttributes = function () {
5406    this.options.set('disabled', this.$element.prop('disabled'));
5407
5408    if (this.options.get('disabled')) {
5409      if (this.isOpen()) {
5410        this.close();
5411      }
5412
5413      this.trigger('disable', {});
5414    } else {
5415      this.trigger('enable', {});
5416    }
5417  };
5418
5419  Select2.prototype._syncSubtree = function (evt, mutations) {
5420    var changed = false;
5421    var self = this;
5422
5423    // Ignore any mutation events raised for elements that aren't options or
5424    // optgroups. This handles the case when the select element is destroyed
5425    if (
5426      evt && evt.target && (
5427        evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
5428      )
5429    ) {
5430      return;
5431    }
5432
5433    if (!mutations) {
5434      // If mutation events aren't supported, then we can only assume that the
5435      // change affected the selections
5436      changed = true;
5437    } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
5438      for (var n = 0; n < mutations.addedNodes.length; n++) {
5439        var node = mutations.addedNodes[n];
5440
5441        if (node.selected) {
5442          changed = true;
5443        }
5444      }
5445    } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
5446      changed = true;
5447    }
5448
5449    // Only re-pull the data if we think there is a change
5450    if (changed) {
5451      this.dataAdapter.current(function (currentData) {
5452        self.trigger('selection:update', {
5453          data: currentData
5454        });
5455      });
5456    }
5457  };
5458
5459  /**
5460   * Override the trigger method to automatically trigger pre-events when
5461   * there are events that can be prevented.
5462   */
5463  Select2.prototype.trigger = function (name, args) {
5464    var actualTrigger = Select2.__super__.trigger;
5465    var preTriggerMap = {
5466      'open': 'opening',
5467      'close': 'closing',
5468      'select': 'selecting',
5469      'unselect': 'unselecting'
5470    };
5471
5472    if (args === undefined) {
5473      args = {};
5474    }
5475
5476    if (name in preTriggerMap) {
5477      var preTriggerName = preTriggerMap[name];
5478      var preTriggerArgs = {
5479        prevented: false,
5480        name: name,
5481        args: args
5482      };
5483
5484      actualTrigger.call(this, preTriggerName, preTriggerArgs);
5485
5486      if (preTriggerArgs.prevented) {
5487        args.prevented = true;
5488
5489        return;
5490      }
5491    }
5492
5493    actualTrigger.call(this, name, args);
5494  };
5495
5496  Select2.prototype.toggleDropdown = function () {
5497    if (this.options.get('disabled')) {
5498      return;
5499    }
5500
5501    if (this.isOpen()) {
5502      this.close();
5503    } else {
5504      this.open();
5505    }
5506  };
5507
5508  Select2.prototype.open = function () {
5509    if (this.isOpen()) {
5510      return;
5511    }
5512
5513    this.trigger('query', {});
5514  };
5515
5516  Select2.prototype.close = function () {
5517    if (!this.isOpen()) {
5518      return;
5519    }
5520
5521    this.trigger('close', {});
5522  };
5523
5524  Select2.prototype.isOpen = function () {
5525    return this.$container.hasClass('select2-container--open');
5526  };
5527
5528  Select2.prototype.hasFocus = function () {
5529    return this.$container.hasClass('select2-container--focus');
5530  };
5531
vendor: 5,945 bytes, lines 5532-5746
5532  Select2.prototype.focus = function (data) {
5533    // No need to re-trigger focus events if we are already focused
5534    if (this.hasFocus()) {
5535      return;
5536    }
5537
5538    this.$container.addClass('select2-container--focus');
5539    this.trigger('focus', {});
5540  };
5541
5542  Select2.prototype.enable = function (args) {
5543    if (this.options.get('debug') && window.console && console.warn) {
5544      console.warn(
5545        'Select2: The `select2("enable")` method has been deprecated and will' +
5546        ' be removed in later Select2 versions. Use $element.prop("disabled")' +
5547        ' instead.'
5548      );
5549    }
5550
5551    if (args == null || args.length === 0) {
5552      args = [true];
5553    }
5554
5555    var disabled = !args[0];
5556
5557    this.$element.prop('disabled', disabled);
5558  };
5559
5560  Select2.prototype.data = function () {
5561    if (this.options.get('debug') &&
5562        arguments.length > 0 && window.console && console.warn) {
5563      console.warn(
5564        'Select2: Data can no longer be set using `select2("data")`. You ' +
5565        'should consider setting the value instead using `$element.val()`.'
5566      );
5567    }
5568
5569    var data = [];
5570
5571    this.dataAdapter.current(function (currentData) {
5572      data = currentData;
5573    });
5574
5575    return data;
5576  };
5577
5578  Select2.prototype.val = function (args) {
5579    if (this.options.get('debug') && window.console && console.warn) {
5580      console.warn(
5581        'Select2: The `select2("val")` method has been deprecated and will be' +
5582        ' removed in later Select2 versions. Use $element.val() instead.'
5583      );
5584    }
5585
5586    if (args == null || args.length === 0) {
5587      return this.$element.val();
5588    }
5589
5590    var newVal = args[0];
5591
5592    if ($.isArray(newVal)) {
5593      newVal = $.map(newVal, function (obj) {
5594        return obj.toString();
5595      });
5596    }
5597
5598    this.$element.val(newVal).trigger('change');
5599  };
5600
5601  Select2.prototype.destroy = function () {
5602    this.$container.remove();
5603
5604    if (this.$element[0].detachEvent) {
5605      this.$element[0].detachEvent('onpropertychange', this._syncA);
5606    }
5607
5608    if (this._observer != null) {
5609      this._observer.disconnect();
5610      this._observer = null;
5611    } else if (this.$element[0].removeEventListener) {
5612      this.$element[0]
5613        .removeEventListener('DOMAttrModified', this._syncA, false);
5614      this.$element[0]
5615        .removeEventListener('DOMNodeInserted', this._syncS, false);
5616      this.$element[0]
5617        .removeEventListener('DOMNodeRemoved', this._syncS, false);
5618    }
5619
5620    this._syncA = null;
5621    this._syncS = null;
5622
5623    this.$element.off('.select2');
5624    this.$element.attr('tabindex', this.$element.data('old-tabindex'));
5625
5626    this.$element.removeClass('select2-hidden-accessible');
5627    this.$element.attr('aria-hidden', 'false');
5628    this.$element.removeData('select2');
5629
5630    this.dataAdapter.destroy();
5631    this.selection.destroy();
5632    this.dropdown.destroy();
5633    this.results.destroy();
5634
5635    this.dataAdapter = null;
5636    this.selection = null;
5637    this.dropdown = null;
5638    this.results = null;
5639  };
5640
5641  Select2.prototype.render = function () {
5642    var $container = $(
5643      '<span class="select2 select2-container">' +
5644        '<span class="selection"></span>' +
5645        '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
5646      '</span>'
5647    );
5648
5649    $container.attr('dir', this.options.get('dir'));
5650
5651    this.$container = $container;
5652
5653    this.$container.addClass('select2-container--' + this.options.get('theme'));
5654
5655    $container.data('element', this.$element);
5656
5657    return $container;
5658  };
5659
5660  return Select2;
5661});
5662
5663S2.define('jquery-mousewheel',[
5664  'jquery'
5665], function ($) {
5666  // Used to shim jQuery.mousewheel for non-full builds.
5667  return $;
5668});
5669
5670S2.define('jquery.select2',[
5671  'jquery',
5672  'jquery-mousewheel',
5673
5674  './select2/core',
5675  './select2/defaults'
5676], function ($, _, Select2, Defaults) {
5677  if ($.fn.select2 == null) {
5678    // All methods that should return the element
5679    var thisMethods = ['open', 'close', 'destroy'];
5680
5681    $.fn.select2 = function (options) {
5682      options = options || {};
5683
5684      if (typeof options === 'object') {
5685        this.each(function () {
5686          var instanceOptions = $.extend(true, {}, options);
5687
5688          var instance = new Select2($(this), instanceOptions);
5689        });
5690
5691        return this;
5692      } else if (typeof options === 'string') {
5693        var ret;
5694        var args = Array.prototype.slice.call(arguments, 1);
5695
5696        this.each(function () {
5697          var instance = $(this).data('select2');
5698
5699          if (instance == null && window.console && console.error) {
5700            console.error(
5701              'The select2(\'' + options + '\') method was called on an ' +
5702              'element that is not using Select2.'
5703            );
5704          }
5705
5706          ret = instance[options].apply(instance, args);
5707        });
5708
5709        // Check if we should be returning `this`
5710        if ($.inArray(options, thisMethods) > -1) {
5711          return this;
5712        }
5713
5714        return ret;
5715      } else {
5716        throw new Error('Invalid arguments for Select2: ' + options);
5717      }
5718    };
5719  }
5720
5721  if ($.fn.select2.defaults == null) {
5722    $.fn.select2.defaults = Defaults;
5723  }
5724
5725  return Select2;
5726});
5727
5728  // Return the AMD loader configuration so it can be used outside of this file
5729  return {
5730    define: S2.define,
5731    require: S2.require
5732  };
5733}());
5734
5735  // Autoload the jQuery bindings
5736  // We know that all of the modules exist above this, so we're safe
5737  var select2 = S2.require('jquery.select2');
5738
5739  // Hold the AMD module references on the jQuery function that was just loaded
5740  // This allows Select2 to use the internal loader outside of this file, such
5741  // as in the language files.
5742  jQuery.fn.select2.amd = S2;
5743
5744  // Return the Select2 instance for anyone who is importing it.
5745  return select2;
5746}));

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.