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