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