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