GPQAPP

Форк
0
/
select2.full.js 
6820 строк · 169.5 Кб
1
/*!
2
 * Select2 4.0.13
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
  'jquery'
503
], function ($) {
504
  var Utils = {};
505

506
  Utils.Extend = function (ChildClass, SuperClass) {
507
    var __hasProp = {}.hasOwnProperty;
508

509
    function BaseConstructor () {
510
      this.constructor = ChildClass;
511
    }
512

513
    for (var key in SuperClass) {
514
      if (__hasProp.call(SuperClass, key)) {
515
        ChildClass[key] = SuperClass[key];
516
      }
517
    }
518

519
    BaseConstructor.prototype = SuperClass.prototype;
520
    ChildClass.prototype = new BaseConstructor();
521
    ChildClass.__super__ = SuperClass.prototype;
522

523
    return ChildClass;
524
  };
525

526
  function getMethods (theClass) {
527
    var proto = theClass.prototype;
528

529
    var methods = [];
530

531
    for (var methodName in proto) {
532
      var m = proto[methodName];
533

534
      if (typeof m !== 'function') {
535
        continue;
536
      }
537

538
      if (methodName === 'constructor') {
539
        continue;
540
      }
541

542
      methods.push(methodName);
543
    }
544

545
    return methods;
546
  }
547

548
  Utils.Decorate = function (SuperClass, DecoratorClass) {
549
    var decoratedMethods = getMethods(DecoratorClass);
550
    var superMethods = getMethods(SuperClass);
551

552
    function DecoratedClass () {
553
      var unshift = Array.prototype.unshift;
554

555
      var argCount = DecoratorClass.prototype.constructor.length;
556

557
      var calledConstructor = SuperClass.prototype.constructor;
558

559
      if (argCount > 0) {
560
        unshift.call(arguments, SuperClass.prototype.constructor);
561

562
        calledConstructor = DecoratorClass.prototype.constructor;
563
      }
564

565
      calledConstructor.apply(this, arguments);
566
    }
567

568
    DecoratorClass.displayName = SuperClass.displayName;
569

570
    function ctr () {
571
      this.constructor = DecoratedClass;
572
    }
573

574
    DecoratedClass.prototype = new ctr();
575

576
    for (var m = 0; m < superMethods.length; m++) {
577
      var superMethod = superMethods[m];
578

579
      DecoratedClass.prototype[superMethod] =
580
        SuperClass.prototype[superMethod];
581
    }
582

583
    var calledMethod = function (methodName) {
584
      // Stub out the original method if it's not decorating an actual method
585
      var originalMethod = function () {};
586

587
      if (methodName in DecoratedClass.prototype) {
588
        originalMethod = DecoratedClass.prototype[methodName];
589
      }
590

591
      var decoratedMethod = DecoratorClass.prototype[methodName];
592

593
      return function () {
594
        var unshift = Array.prototype.unshift;
595

596
        unshift.call(arguments, originalMethod);
597

598
        return decoratedMethod.apply(this, arguments);
599
      };
600
    };
601

602
    for (var d = 0; d < decoratedMethods.length; d++) {
603
      var decoratedMethod = decoratedMethods[d];
604

605
      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
606
    }
607

608
    return DecoratedClass;
609
  };
610

611
  var Observable = function () {
612
    this.listeners = {};
613
  };
614

615
  Observable.prototype.on = function (event, callback) {
616
    this.listeners = this.listeners || {};
617

618
    if (event in this.listeners) {
619
      this.listeners[event].push(callback);
620
    } else {
621
      this.listeners[event] = [callback];
622
    }
623
  };
624

625
  Observable.prototype.trigger = function (event) {
626
    var slice = Array.prototype.slice;
627
    var params = slice.call(arguments, 1);
628

629
    this.listeners = this.listeners || {};
630

631
    // Params should always come in as an array
632
    if (params == null) {
633
      params = [];
634
    }
635

636
    // If there are no arguments to the event, use a temporary object
637
    if (params.length === 0) {
638
      params.push({});
639
    }
640

641
    // Set the `_type` of the first object to the event
642
    params[0]._type = event;
643

644
    if (event in this.listeners) {
645
      this.invoke(this.listeners[event], slice.call(arguments, 1));
646
    }
647

648
    if ('*' in this.listeners) {
649
      this.invoke(this.listeners['*'], arguments);
650
    }
651
  };
652

653
  Observable.prototype.invoke = function (listeners, params) {
654
    for (var i = 0, len = listeners.length; i < len; i++) {
655
      listeners[i].apply(this, params);
656
    }
657
  };
658

659
  Utils.Observable = Observable;
660

661
  Utils.generateChars = function (length) {
662
    var chars = '';
663

664
    for (var i = 0; i < length; i++) {
665
      var randomChar = Math.floor(Math.random() * 36);
666
      chars += randomChar.toString(36);
667
    }
668

669
    return chars;
670
  };
671

672
  Utils.bind = function (func, context) {
673
    return function () {
674
      func.apply(context, arguments);
675
    };
676
  };
677

678
  Utils._convertData = function (data) {
679
    for (var originalKey in data) {
680
      var keys = originalKey.split('-');
681

682
      var dataLevel = data;
683

684
      if (keys.length === 1) {
685
        continue;
686
      }
687

688
      for (var k = 0; k < keys.length; k++) {
689
        var key = keys[k];
690

691
        // Lowercase the first letter
692
        // By default, dash-separated becomes camelCase
693
        key = key.substring(0, 1).toLowerCase() + key.substring(1);
694

695
        if (!(key in dataLevel)) {
696
          dataLevel[key] = {};
697
        }
698

699
        if (k == keys.length - 1) {
700
          dataLevel[key] = data[originalKey];
701
        }
702

703
        dataLevel = dataLevel[key];
704
      }
705

706
      delete data[originalKey];
707
    }
708

709
    return data;
710
  };
711

712
  Utils.hasScroll = function (index, el) {
713
    // Adapted from the function created by @ShadowScripter
714
    // and adapted by @BillBarry on the Stack Exchange Code Review website.
715
    // The original code can be found at
716
    // http://codereview.stackexchange.com/q/13338
717
    // and was designed to be used with the Sizzle selector engine.
718

719
    var $el = $(el);
720
    var overflowX = el.style.overflowX;
721
    var overflowY = el.style.overflowY;
722

723
    //Check both x and y declarations
724
    if (overflowX === overflowY &&
725
        (overflowY === 'hidden' || overflowY === 'visible')) {
726
      return false;
727
    }
728

729
    if (overflowX === 'scroll' || overflowY === 'scroll') {
730
      return true;
731
    }
732

733
    return ($el.innerHeight() < el.scrollHeight ||
734
      $el.innerWidth() < el.scrollWidth);
735
  };
736

737
  Utils.escapeMarkup = function (markup) {
738
    var replaceMap = {
739
      '\\': '&#92;',
740
      '&': '&amp;',
741
      '<': '&lt;',
742
      '>': '&gt;',
743
      '"': '&quot;',
744
      '\'': '&#39;',
745
      '/': '&#47;'
746
    };
747

748
    // Do not try to escape the markup if it's not a string
749
    if (typeof markup !== 'string') {
750
      return markup;
751
    }
752

753
    return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
754
      return replaceMap[match];
755
    });
756
  };
757

758
  // Append an array of jQuery nodes to a given element.
759
  Utils.appendMany = function ($element, $nodes) {
760
    // jQuery 1.7.x does not support $.fn.append() with an array
761
    // Fall back to a jQuery object collection using $.fn.add()
762
    if ($.fn.jquery.substr(0, 3) === '1.7') {
763
      var $jqNodes = $();
764

765
      $.map($nodes, function (node) {
766
        $jqNodes = $jqNodes.add(node);
767
      });
768

769
      $nodes = $jqNodes;
770
    }
771

772
    $element.append($nodes);
773
  };
774

775
  // Cache objects in Utils.__cache instead of $.data (see #4346)
776
  Utils.__cache = {};
777

778
  var id = 0;
779
  Utils.GetUniqueElementId = function (element) {
780
    // Get a unique element Id. If element has no id,
781
    // creates a new unique number, stores it in the id
782
    // attribute and returns the new id.
783
    // If an id already exists, it simply returns it.
784

785
    var select2Id = element.getAttribute('data-select2-id');
786
    if (select2Id == null) {
787
      // If element has id, use it.
788
      if (element.id) {
789
        select2Id = element.id;
790
        element.setAttribute('data-select2-id', select2Id);
791
      } else {
792
        element.setAttribute('data-select2-id', ++id);
793
        select2Id = id.toString();
794
      }
795
    }
796
    return select2Id;
797
  };
798

799
  Utils.StoreData = function (element, name, value) {
800
    // Stores an item in the cache for a specified element.
801
    // name is the cache key.
802
    var id = Utils.GetUniqueElementId(element);
803
    if (!Utils.__cache[id]) {
804
      Utils.__cache[id] = {};
805
    }
806

807
    Utils.__cache[id][name] = value;
808
  };
809

810
  Utils.GetData = function (element, name) {
811
    // Retrieves a value from the cache by its key (name)
812
    // name is optional. If no name specified, return
813
    // all cache items for the specified element.
814
    // and for a specified element.
815
    var id = Utils.GetUniqueElementId(element);
816
    if (name) {
817
      if (Utils.__cache[id]) {
818
        if (Utils.__cache[id][name] != null) {
819
          return Utils.__cache[id][name];
820
        }
821
        return $(element).data(name); // Fallback to HTML5 data attribs.
822
      }
823
      return $(element).data(name); // Fallback to HTML5 data attribs.
824
    } else {
825
      return Utils.__cache[id];
826
    }
827
  };
828

829
  Utils.RemoveData = function (element) {
830
    // Removes all cached items for a specified element.
831
    var id = Utils.GetUniqueElementId(element);
832
    if (Utils.__cache[id] != null) {
833
      delete Utils.__cache[id];
834
    }
835

836
    element.removeAttribute('data-select2-id');
837
  };
838

839
  return Utils;
840
});
841

842
S2.define('select2/results',[
843
  'jquery',
844
  './utils'
845
], function ($, Utils) {
846
  function Results ($element, options, dataAdapter) {
847
    this.$element = $element;
848
    this.data = dataAdapter;
849
    this.options = options;
850

851
    Results.__super__.constructor.call(this);
852
  }
853

854
  Utils.Extend(Results, Utils.Observable);
855

856
  Results.prototype.render = function () {
857
    var $results = $(
858
      '<ul class="select2-results__options" role="listbox"></ul>'
859
    );
860

861
    if (this.options.get('multiple')) {
862
      $results.attr('aria-multiselectable', 'true');
863
    }
864

865
    this.$results = $results;
866

867
    return $results;
868
  };
869

870
  Results.prototype.clear = function () {
871
    this.$results.empty();
872
  };
873

874
  Results.prototype.displayMessage = function (params) {
875
    var escapeMarkup = this.options.get('escapeMarkup');
876

877
    this.clear();
878
    this.hideLoading();
879

880
    var $message = $(
881
      '<li role="alert" aria-live="assertive"' +
882
      ' class="select2-results__option"></li>'
883
    );
884

885
    var message = this.options.get('translations').get(params.message);
886

887
    $message.append(
888
      escapeMarkup(
889
        message(params.args)
890
      )
891
    );
892

893
    $message[0].className += ' select2-results__message';
894

895
    this.$results.append($message);
896
  };
897

898
  Results.prototype.hideMessages = function () {
899
    this.$results.find('.select2-results__message').remove();
900
  };
901

902
  Results.prototype.append = function (data) {
903
    this.hideLoading();
904

905
    var $options = [];
906

907
    if (data.results == null || data.results.length === 0) {
908
      if (this.$results.children().length === 0) {
909
        this.trigger('results:message', {
910
          message: 'noResults'
911
        });
912
      }
913

914
      return;
915
    }
916

917
    data.results = this.sort(data.results);
918

919
    for (var d = 0; d < data.results.length; d++) {
920
      var item = data.results[d];
921

922
      var $option = this.option(item);
923

924
      $options.push($option);
925
    }
926

927
    this.$results.append($options);
928
  };
929

930
  Results.prototype.position = function ($results, $dropdown) {
931
    var $resultsContainer = $dropdown.find('.select2-results');
932
    $resultsContainer.append($results);
933
  };
934

935
  Results.prototype.sort = function (data) {
936
    var sorter = this.options.get('sorter');
937

938
    return sorter(data);
939
  };
940

941
  Results.prototype.highlightFirstItem = function () {
942
    var $options = this.$results
943
      .find('.select2-results__option[aria-selected]');
944

945
    var $selected = $options.filter('[aria-selected=true]');
946

947
    // Check if there are any selected options
948
    if ($selected.length > 0) {
949
      // If there are selected options, highlight the first
950
      $selected.first().trigger('mouseenter');
951
    } else {
952
      // If there are no selected options, highlight the first option
953
      // in the dropdown
954
      $options.first().trigger('mouseenter');
955
    }
956

957
    this.ensureHighlightVisible();
958
  };
959

960
  Results.prototype.setClasses = function () {
961
    var self = this;
962

963
    this.data.current(function (selected) {
964
      var selectedIds = $.map(selected, function (s) {
965
        return s.id.toString();
966
      });
967

968
      var $options = self.$results
969
        .find('.select2-results__option[aria-selected]');
970

971
      $options.each(function () {
972
        var $option = $(this);
973

974
        var item = Utils.GetData(this, 'data');
975

976
        // id needs to be converted to a string when comparing
977
        var id = '' + item.id;
978

979
        if ((item.element != null && item.element.selected) ||
980
            (item.element == null && $.inArray(id, selectedIds) > -1)) {
981
          $option.attr('aria-selected', 'true');
982
        } else {
983
          $option.attr('aria-selected', 'false');
984
        }
985
      });
986

987
    });
988
  };
989

990
  Results.prototype.showLoading = function (params) {
991
    this.hideLoading();
992

993
    var loadingMore = this.options.get('translations').get('searching');
994

995
    var loading = {
996
      disabled: true,
997
      loading: true,
998
      text: loadingMore(params)
999
    };
1000
    var $loading = this.option(loading);
1001
    $loading.className += ' loading-results';
1002

1003
    this.$results.prepend($loading);
1004
  };
1005

1006
  Results.prototype.hideLoading = function () {
1007
    this.$results.find('.loading-results').remove();
1008
  };
1009

1010
  Results.prototype.option = function (data) {
1011
    var option = document.createElement('li');
1012
    option.className = 'select2-results__option';
1013

1014
    var attrs = {
1015
      'role': 'option',
1016
      'aria-selected': 'false'
1017
    };
1018

1019
    var matches = window.Element.prototype.matches ||
1020
      window.Element.prototype.msMatchesSelector ||
1021
      window.Element.prototype.webkitMatchesSelector;
1022

1023
    if ((data.element != null && matches.call(data.element, ':disabled')) ||
1024
        (data.element == null && data.disabled)) {
1025
      delete attrs['aria-selected'];
1026
      attrs['aria-disabled'] = 'true';
1027
    }
1028

1029
    if (data.id == null) {
1030
      delete attrs['aria-selected'];
1031
    }
1032

1033
    if (data._resultId != null) {
1034
      option.id = data._resultId;
1035
    }
1036

1037
    if (data.title) {
1038
      option.title = data.title;
1039
    }
1040

1041
    if (data.children) {
1042
      attrs.role = 'group';
1043
      attrs['aria-label'] = data.text;
1044
      delete attrs['aria-selected'];
1045
    }
1046

1047
    for (var attr in attrs) {
1048
      var val = attrs[attr];
1049

1050
      option.setAttribute(attr, val);
1051
    }
1052

1053
    if (data.children) {
1054
      var $option = $(option);
1055

1056
      var label = document.createElement('strong');
1057
      label.className = 'select2-results__group';
1058

1059
      var $label = $(label);
1060
      this.template(data, label);
1061

1062
      var $children = [];
1063

1064
      for (var c = 0; c < data.children.length; c++) {
1065
        var child = data.children[c];
1066

1067
        var $child = this.option(child);
1068

1069
        $children.push($child);
1070
      }
1071

1072
      var $childrenContainer = $('<ul></ul>', {
1073
        'class': 'select2-results__options select2-results__options--nested'
1074
      });
1075

1076
      $childrenContainer.append($children);
1077

1078
      $option.append(label);
1079
      $option.append($childrenContainer);
1080
    } else {
1081
      this.template(data, option);
1082
    }
1083

1084
    Utils.StoreData(option, 'data', data);
1085

1086
    return option;
1087
  };
1088

1089
  Results.prototype.bind = function (container, $container) {
1090
    var self = this;
1091

1092
    var id = container.id + '-results';
1093

1094
    this.$results.attr('id', id);
1095

1096
    container.on('results:all', function (params) {
1097
      self.clear();
1098
      self.append(params.data);
1099

1100
      if (container.isOpen()) {
1101
        self.setClasses();
1102
        self.highlightFirstItem();
1103
      }
1104
    });
1105

1106
    container.on('results:append', function (params) {
1107
      self.append(params.data);
1108

1109
      if (container.isOpen()) {
1110
        self.setClasses();
1111
      }
1112
    });
1113

1114
    container.on('query', function (params) {
1115
      self.hideMessages();
1116
      self.showLoading(params);
1117
    });
1118

1119
    container.on('select', function () {
1120
      if (!container.isOpen()) {
1121
        return;
1122
      }
1123

1124
      self.setClasses();
1125

1126
      if (self.options.get('scrollAfterSelect')) {
1127
        self.highlightFirstItem();
1128
      }
1129
    });
1130

1131
    container.on('unselect', function () {
1132
      if (!container.isOpen()) {
1133
        return;
1134
      }
1135

1136
      self.setClasses();
1137

1138
      if (self.options.get('scrollAfterSelect')) {
1139
        self.highlightFirstItem();
1140
      }
1141
    });
1142

1143
    container.on('open', function () {
1144
      // When the dropdown is open, aria-expended="true"
1145
      self.$results.attr('aria-expanded', 'true');
1146
      self.$results.attr('aria-hidden', 'false');
1147

1148
      self.setClasses();
1149
      self.ensureHighlightVisible();
1150
    });
1151

1152
    container.on('close', function () {
1153
      // When the dropdown is closed, aria-expended="false"
1154
      self.$results.attr('aria-expanded', 'false');
1155
      self.$results.attr('aria-hidden', 'true');
1156
      self.$results.removeAttr('aria-activedescendant');
1157
    });
1158

1159
    container.on('results:toggle', function () {
1160
      var $highlighted = self.getHighlightedResults();
1161

1162
      if ($highlighted.length === 0) {
1163
        return;
1164
      }
1165

1166
      $highlighted.trigger('mouseup');
1167
    });
1168

1169
    container.on('results:select', function () {
1170
      var $highlighted = self.getHighlightedResults();
1171

1172
      if ($highlighted.length === 0) {
1173
        return;
1174
      }
1175

1176
      var data = Utils.GetData($highlighted[0], 'data');
1177

1178
      if ($highlighted.attr('aria-selected') == 'true') {
1179
        self.trigger('close', {});
1180
      } else {
1181
        self.trigger('select', {
1182
          data: data
1183
        });
1184
      }
1185
    });
1186

1187
    container.on('results:previous', function () {
1188
      var $highlighted = self.getHighlightedResults();
1189

1190
      var $options = self.$results.find('[aria-selected]');
1191

1192
      var currentIndex = $options.index($highlighted);
1193

1194
      // If we are already at the top, don't move further
1195
      // If no options, currentIndex will be -1
1196
      if (currentIndex <= 0) {
1197
        return;
1198
      }
1199

1200
      var nextIndex = currentIndex - 1;
1201

1202
      // If none are highlighted, highlight the first
1203
      if ($highlighted.length === 0) {
1204
        nextIndex = 0;
1205
      }
1206

1207
      var $next = $options.eq(nextIndex);
1208

1209
      $next.trigger('mouseenter');
1210

1211
      var currentOffset = self.$results.offset().top;
1212
      var nextTop = $next.offset().top;
1213
      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
1214

1215
      if (nextIndex === 0) {
1216
        self.$results.scrollTop(0);
1217
      } else if (nextTop - currentOffset < 0) {
1218
        self.$results.scrollTop(nextOffset);
1219
      }
1220
    });
1221

1222
    container.on('results:next', function () {
1223
      var $highlighted = self.getHighlightedResults();
1224

1225
      var $options = self.$results.find('[aria-selected]');
1226

1227
      var currentIndex = $options.index($highlighted);
1228

1229
      var nextIndex = currentIndex + 1;
1230

1231
      // If we are at the last option, stay there
1232
      if (nextIndex >= $options.length) {
1233
        return;
1234
      }
1235

1236
      var $next = $options.eq(nextIndex);
1237

1238
      $next.trigger('mouseenter');
1239

1240
      var currentOffset = self.$results.offset().top +
1241
        self.$results.outerHeight(false);
1242
      var nextBottom = $next.offset().top + $next.outerHeight(false);
1243
      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
1244

1245
      if (nextIndex === 0) {
1246
        self.$results.scrollTop(0);
1247
      } else if (nextBottom > currentOffset) {
1248
        self.$results.scrollTop(nextOffset);
1249
      }
1250
    });
1251

1252
    container.on('results:focus', function (params) {
1253
      params.element.addClass('select2-results__option--highlighted');
1254
    });
1255

1256
    container.on('results:message', function (params) {
1257
      self.displayMessage(params);
1258
    });
1259

1260
    if ($.fn.mousewheel) {
1261
      this.$results.on('mousewheel', function (e) {
1262
        var top = self.$results.scrollTop();
1263

1264
        var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
1265

1266
        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
1267
        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
1268

1269
        if (isAtTop) {
1270
          self.$results.scrollTop(0);
1271

1272
          e.preventDefault();
1273
          e.stopPropagation();
1274
        } else if (isAtBottom) {
1275
          self.$results.scrollTop(
1276
            self.$results.get(0).scrollHeight - self.$results.height()
1277
          );
1278

1279
          e.preventDefault();
1280
          e.stopPropagation();
1281
        }
1282
      });
1283
    }
1284

1285
    this.$results.on('mouseup', '.select2-results__option[aria-selected]',
1286
      function (evt) {
1287
      var $this = $(this);
1288

1289
      var data = Utils.GetData(this, 'data');
1290

1291
      if ($this.attr('aria-selected') === 'true') {
1292
        if (self.options.get('multiple')) {
1293
          self.trigger('unselect', {
1294
            originalEvent: evt,
1295
            data: data
1296
          });
1297
        } else {
1298
          self.trigger('close', {});
1299
        }
1300

1301
        return;
1302
      }
1303

1304
      self.trigger('select', {
1305
        originalEvent: evt,
1306
        data: data
1307
      });
1308
    });
1309

1310
    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
1311
      function (evt) {
1312
      var data = Utils.GetData(this, 'data');
1313

1314
      self.getHighlightedResults()
1315
          .removeClass('select2-results__option--highlighted');
1316

1317
      self.trigger('results:focus', {
1318
        data: data,
1319
        element: $(this)
1320
      });
1321
    });
1322
  };
1323

1324
  Results.prototype.getHighlightedResults = function () {
1325
    var $highlighted = this.$results
1326
    .find('.select2-results__option--highlighted');
1327

1328
    return $highlighted;
1329
  };
1330

1331
  Results.prototype.destroy = function () {
1332
    this.$results.remove();
1333
  };
1334

1335
  Results.prototype.ensureHighlightVisible = function () {
1336
    var $highlighted = this.getHighlightedResults();
1337

1338
    if ($highlighted.length === 0) {
1339
      return;
1340
    }
1341

1342
    var $options = this.$results.find('[aria-selected]');
1343

1344
    var currentIndex = $options.index($highlighted);
1345

1346
    var currentOffset = this.$results.offset().top;
1347
    var nextTop = $highlighted.offset().top;
1348
    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
1349

1350
    var offsetDelta = nextTop - currentOffset;
1351
    nextOffset -= $highlighted.outerHeight(false) * 2;
1352

1353
    if (currentIndex <= 2) {
1354
      this.$results.scrollTop(0);
1355
    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
1356
      this.$results.scrollTop(nextOffset);
1357
    }
1358
  };
1359

1360
  Results.prototype.template = function (result, container) {
1361
    var template = this.options.get('templateResult');
1362
    var escapeMarkup = this.options.get('escapeMarkup');
1363

1364
    var content = template(result, container);
1365

1366
    if (content == null) {
1367
      container.style.display = 'none';
1368
    } else if (typeof content === 'string') {
1369
      container.innerHTML = escapeMarkup(content);
1370
    } else {
1371
      $(container).append(content);
1372
    }
1373
  };
1374

1375
  return Results;
1376
});
1377

1378
S2.define('select2/keys',[
1379

1380
], function () {
1381
  var KEYS = {
1382
    BACKSPACE: 8,
1383
    TAB: 9,
1384
    ENTER: 13,
1385
    SHIFT: 16,
1386
    CTRL: 17,
1387
    ALT: 18,
1388
    ESC: 27,
1389
    SPACE: 32,
1390
    PAGE_UP: 33,
1391
    PAGE_DOWN: 34,
1392
    END: 35,
1393
    HOME: 36,
1394
    LEFT: 37,
1395
    UP: 38,
1396
    RIGHT: 39,
1397
    DOWN: 40,
1398
    DELETE: 46
1399
  };
1400

1401
  return KEYS;
1402
});
1403

1404
S2.define('select2/selection/base',[
1405
  'jquery',
1406
  '../utils',
1407
  '../keys'
1408
], function ($, Utils, KEYS) {
1409
  function BaseSelection ($element, options) {
1410
    this.$element = $element;
1411
    this.options = options;
1412

1413
    BaseSelection.__super__.constructor.call(this);
1414
  }
1415

1416
  Utils.Extend(BaseSelection, Utils.Observable);
1417

1418
  BaseSelection.prototype.render = function () {
1419
    var $selection = $(
1420
      '<span class="select2-selection" role="combobox" ' +
1421
      ' aria-haspopup="true" aria-expanded="false">' +
1422
      '</span>'
1423
    );
1424

1425
    this._tabindex = 0;
1426

1427
    if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
1428
      this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
1429
    } else if (this.$element.attr('tabindex') != null) {
1430
      this._tabindex = this.$element.attr('tabindex');
1431
    }
1432

1433
    $selection.attr('title', this.$element.attr('title'));
1434
    $selection.attr('tabindex', this._tabindex);
1435
    $selection.attr('aria-disabled', 'false');
1436

1437
    this.$selection = $selection;
1438

1439
    return $selection;
1440
  };
1441

1442
  BaseSelection.prototype.bind = function (container, $container) {
1443
    var self = this;
1444

1445
    var resultsId = container.id + '-results';
1446

1447
    this.container = container;
1448

1449
    this.$selection.on('focus', function (evt) {
1450
      self.trigger('focus', evt);
1451
    });
1452

1453
    this.$selection.on('blur', function (evt) {
1454
      self._handleBlur(evt);
1455
    });
1456

1457
    this.$selection.on('keydown', function (evt) {
1458
      self.trigger('keypress', evt);
1459

1460
      if (evt.which === KEYS.SPACE) {
1461
        evt.preventDefault();
1462
      }
1463
    });
1464

1465
    container.on('results:focus', function (params) {
1466
      self.$selection.attr('aria-activedescendant', params.data._resultId);
1467
    });
1468

1469
    container.on('selection:update', function (params) {
1470
      self.update(params.data);
1471
    });
1472

1473
    container.on('open', function () {
1474
      // When the dropdown is open, aria-expanded="true"
1475
      self.$selection.attr('aria-expanded', 'true');
1476
      self.$selection.attr('aria-owns', resultsId);
1477

1478
      self._attachCloseHandler(container);
1479
    });
1480

1481
    container.on('close', function () {
1482
      // When the dropdown is closed, aria-expanded="false"
1483
      self.$selection.attr('aria-expanded', 'false');
1484
      self.$selection.removeAttr('aria-activedescendant');
1485
      self.$selection.removeAttr('aria-owns');
1486

1487
      self.$selection.trigger('focus');
1488

1489
      self._detachCloseHandler(container);
1490
    });
1491

1492
    container.on('enable', function () {
1493
      self.$selection.attr('tabindex', self._tabindex);
1494
      self.$selection.attr('aria-disabled', 'false');
1495
    });
1496

1497
    container.on('disable', function () {
1498
      self.$selection.attr('tabindex', '-1');
1499
      self.$selection.attr('aria-disabled', 'true');
1500
    });
1501
  };
1502

1503
  BaseSelection.prototype._handleBlur = function (evt) {
1504
    var self = this;
1505

1506
    // This needs to be delayed as the active element is the body when the tab
1507
    // key is pressed, possibly along with others.
1508
    window.setTimeout(function () {
1509
      // Don't trigger `blur` if the focus is still in the selection
1510
      if (
1511
        (document.activeElement == self.$selection[0]) ||
1512
        ($.contains(self.$selection[0], document.activeElement))
1513
      ) {
1514
        return;
1515
      }
1516

1517
      self.trigger('blur', evt);
1518
    }, 1);
1519
  };
1520

1521
  BaseSelection.prototype._attachCloseHandler = function (container) {
1522

1523
    $(document.body).on('mousedown.select2.' + container.id, function (e) {
1524
      var $target = $(e.target);
1525

1526
      var $select = $target.closest('.select2');
1527

1528
      var $all = $('.select2.select2-container--open');
1529

1530
      $all.each(function () {
1531
        if (this == $select[0]) {
1532
          return;
1533
        }
1534

1535
        var $element = Utils.GetData(this, 'element');
1536

1537
        $element.select2('close');
1538
      });
1539
    });
1540
  };
1541

1542
  BaseSelection.prototype._detachCloseHandler = function (container) {
1543
    $(document.body).off('mousedown.select2.' + container.id);
1544
  };
1545

1546
  BaseSelection.prototype.position = function ($selection, $container) {
1547
    var $selectionContainer = $container.find('.selection');
1548
    $selectionContainer.append($selection);
1549
  };
1550

1551
  BaseSelection.prototype.destroy = function () {
1552
    this._detachCloseHandler(this.container);
1553
  };
1554

1555
  BaseSelection.prototype.update = function (data) {
1556
    throw new Error('The `update` method must be defined in child classes.');
1557
  };
1558

1559
  /**
1560
   * Helper method to abstract the "enabled" (not "disabled") state of this
1561
   * object.
1562
   *
1563
   * @return {true} if the instance is not disabled.
1564
   * @return {false} if the instance is disabled.
1565
   */
1566
  BaseSelection.prototype.isEnabled = function () {
1567
    return !this.isDisabled();
1568
  };
1569

1570
  /**
1571
   * Helper method to abstract the "disabled" state of this object.
1572
   *
1573
   * @return {true} if the disabled option is true.
1574
   * @return {false} if the disabled option is false.
1575
   */
1576
  BaseSelection.prototype.isDisabled = function () {
1577
    return this.options.get('disabled');
1578
  };
1579

1580
  return BaseSelection;
1581
});
1582

1583
S2.define('select2/selection/single',[
1584
  'jquery',
1585
  './base',
1586
  '../utils',
1587
  '../keys'
1588
], function ($, BaseSelection, Utils, KEYS) {
1589
  function SingleSelection () {
1590
    SingleSelection.__super__.constructor.apply(this, arguments);
1591
  }
1592

1593
  Utils.Extend(SingleSelection, BaseSelection);
1594

1595
  SingleSelection.prototype.render = function () {
1596
    var $selection = SingleSelection.__super__.render.call(this);
1597

1598
    $selection.addClass('select2-selection--single');
1599

1600
    $selection.html(
1601
      '<span class="select2-selection__rendered"></span>' +
1602
      '<span class="select2-selection__arrow" role="presentation">' +
1603
        '<b role="presentation"></b>' +
1604
      '</span>'
1605
    );
1606

1607
    return $selection;
1608
  };
1609

1610
  SingleSelection.prototype.bind = function (container, $container) {
1611
    var self = this;
1612

1613
    SingleSelection.__super__.bind.apply(this, arguments);
1614

1615
    var id = container.id + '-container';
1616

1617
    this.$selection.find('.select2-selection__rendered')
1618
      .attr('id', id)
1619
      .attr('role', 'textbox')
1620
      .attr('aria-readonly', 'true');
1621
    this.$selection.attr('aria-labelledby', id);
1622

1623
    this.$selection.on('mousedown', function (evt) {
1624
      // Only respond to left clicks
1625
      if (evt.which !== 1) {
1626
        return;
1627
      }
1628

1629
      self.trigger('toggle', {
1630
        originalEvent: evt
1631
      });
1632
    });
1633

1634
    this.$selection.on('focus', function (evt) {
1635
      // User focuses on the container
1636
    });
1637

1638
    this.$selection.on('blur', function (evt) {
1639
      // User exits the container
1640
    });
1641

1642
    container.on('focus', function (evt) {
1643
      if (!container.isOpen()) {
1644
        self.$selection.trigger('focus');
1645
      }
1646
    });
1647
  };
1648

1649
  SingleSelection.prototype.clear = function () {
1650
    var $rendered = this.$selection.find('.select2-selection__rendered');
1651
    $rendered.empty();
1652
    $rendered.removeAttr('title'); // clear tooltip on empty
1653
  };
1654

1655
  SingleSelection.prototype.display = function (data, container) {
1656
    var template = this.options.get('templateSelection');
1657
    var escapeMarkup = this.options.get('escapeMarkup');
1658

1659
    return escapeMarkup(template(data, container));
1660
  };
1661

1662
  SingleSelection.prototype.selectionContainer = function () {
1663
    return $('<span></span>');
1664
  };
1665

1666
  SingleSelection.prototype.update = function (data) {
1667
    if (data.length === 0) {
1668
      this.clear();
1669
      return;
1670
    }
1671

1672
    var selection = data[0];
1673

1674
    var $rendered = this.$selection.find('.select2-selection__rendered');
1675
    var formatted = this.display(selection, $rendered);
1676

1677
    $rendered.empty().append(formatted);
1678

1679
    var title = selection.title || selection.text;
1680

1681
    if (title) {
1682
      $rendered.attr('title', title);
1683
    } else {
1684
      $rendered.removeAttr('title');
1685
    }
1686
  };
1687

1688
  return SingleSelection;
1689
});
1690

1691
S2.define('select2/selection/multiple',[
1692
  'jquery',
1693
  './base',
1694
  '../utils'
1695
], function ($, BaseSelection, Utils) {
1696
  function MultipleSelection ($element, options) {
1697
    MultipleSelection.__super__.constructor.apply(this, arguments);
1698
  }
1699

1700
  Utils.Extend(MultipleSelection, BaseSelection);
1701

1702
  MultipleSelection.prototype.render = function () {
1703
    var $selection = MultipleSelection.__super__.render.call(this);
1704

1705
    $selection.addClass('select2-selection--multiple');
1706

1707
    $selection.html(
1708
      '<ul class="select2-selection__rendered"></ul>'
1709
    );
1710

1711
    return $selection;
1712
  };
1713

1714
  MultipleSelection.prototype.bind = function (container, $container) {
1715
    var self = this;
1716

1717
    MultipleSelection.__super__.bind.apply(this, arguments);
1718

1719
    this.$selection.on('click', function (evt) {
1720
      self.trigger('toggle', {
1721
        originalEvent: evt
1722
      });
1723
    });
1724

1725
    this.$selection.on(
1726
      'click',
1727
      '.select2-selection__choice__remove',
1728
      function (evt) {
1729
        // Ignore the event if it is disabled
1730
        if (self.isDisabled()) {
1731
          return;
1732
        }
1733

1734
        var $remove = $(this);
1735
        var $selection = $remove.parent();
1736

1737
        var data = Utils.GetData($selection[0], 'data');
1738

1739
        self.trigger('unselect', {
1740
          originalEvent: evt,
1741
          data: data
1742
        });
1743
      }
1744
    );
1745
  };
1746

1747
  MultipleSelection.prototype.clear = function () {
1748
    var $rendered = this.$selection.find('.select2-selection__rendered');
1749
    $rendered.empty();
1750
    $rendered.removeAttr('title');
1751
  };
1752

1753
  MultipleSelection.prototype.display = function (data, container) {
1754
    var template = this.options.get('templateSelection');
1755
    var escapeMarkup = this.options.get('escapeMarkup');
1756

1757
    return escapeMarkup(template(data, container));
1758
  };
1759

1760
  MultipleSelection.prototype.selectionContainer = function () {
1761
    var $container = $(
1762
      '<li class="select2-selection__choice">' +
1763
        '<span class="select2-selection__choice__remove" role="presentation">' +
1764
          '&times;' +
1765
        '</span>' +
1766
      '</li>'
1767
    );
1768

1769
    return $container;
1770
  };
1771

1772
  MultipleSelection.prototype.update = function (data) {
1773
    this.clear();
1774

1775
    if (data.length === 0) {
1776
      return;
1777
    }
1778

1779
    var $selections = [];
1780

1781
    for (var d = 0; d < data.length; d++) {
1782
      var selection = data[d];
1783

1784
      var $selection = this.selectionContainer();
1785
      var formatted = this.display(selection, $selection);
1786

1787
      $selection.append(formatted);
1788

1789
      var title = selection.title || selection.text;
1790

1791
      if (title) {
1792
        $selection.attr('title', title);
1793
      }
1794

1795
      Utils.StoreData($selection[0], 'data', selection);
1796

1797
      $selections.push($selection);
1798
    }
1799

1800
    var $rendered = this.$selection.find('.select2-selection__rendered');
1801

1802
    Utils.appendMany($rendered, $selections);
1803
  };
1804

1805
  return MultipleSelection;
1806
});
1807

1808
S2.define('select2/selection/placeholder',[
1809
  '../utils'
1810
], function (Utils) {
1811
  function Placeholder (decorated, $element, options) {
1812
    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
1813

1814
    decorated.call(this, $element, options);
1815
  }
1816

1817
  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
1818
    if (typeof placeholder === 'string') {
1819
      placeholder = {
1820
        id: '',
1821
        text: placeholder
1822
      };
1823
    }
1824

1825
    return placeholder;
1826
  };
1827

1828
  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
1829
    var $placeholder = this.selectionContainer();
1830

1831
    $placeholder.html(this.display(placeholder));
1832
    $placeholder.addClass('select2-selection__placeholder')
1833
                .removeClass('select2-selection__choice');
1834

1835
    return $placeholder;
1836
  };
1837

1838
  Placeholder.prototype.update = function (decorated, data) {
1839
    var singlePlaceholder = (
1840
      data.length == 1 && data[0].id != this.placeholder.id
1841
    );
1842
    var multipleSelections = data.length > 1;
1843

1844
    if (multipleSelections || singlePlaceholder) {
1845
      return decorated.call(this, data);
1846
    }
1847

1848
    this.clear();
1849

1850
    var $placeholder = this.createPlaceholder(this.placeholder);
1851

1852
    this.$selection.find('.select2-selection__rendered').append($placeholder);
1853
  };
1854

1855
  return Placeholder;
1856
});
1857

1858
S2.define('select2/selection/allowClear',[
1859
  'jquery',
1860
  '../keys',
1861
  '../utils'
1862
], function ($, KEYS, Utils) {
1863
  function AllowClear () { }
1864

1865
  AllowClear.prototype.bind = function (decorated, container, $container) {
1866
    var self = this;
1867

1868
    decorated.call(this, container, $container);
1869

1870
    if (this.placeholder == null) {
1871
      if (this.options.get('debug') && window.console && console.error) {
1872
        console.error(
1873
          'Select2: The `allowClear` option should be used in combination ' +
1874
          'with the `placeholder` option.'
1875
        );
1876
      }
1877
    }
1878

1879
    this.$selection.on('mousedown', '.select2-selection__clear',
1880
      function (evt) {
1881
        self._handleClear(evt);
1882
    });
1883

1884
    container.on('keypress', function (evt) {
1885
      self._handleKeyboardClear(evt, container);
1886
    });
1887
  };
1888

1889
  AllowClear.prototype._handleClear = function (_, evt) {
1890
    // Ignore the event if it is disabled
1891
    if (this.isDisabled()) {
1892
      return;
1893
    }
1894

1895
    var $clear = this.$selection.find('.select2-selection__clear');
1896

1897
    // Ignore the event if nothing has been selected
1898
    if ($clear.length === 0) {
1899
      return;
1900
    }
1901

1902
    evt.stopPropagation();
1903

1904
    var data = Utils.GetData($clear[0], 'data');
1905

1906
    var previousVal = this.$element.val();
1907
    this.$element.val(this.placeholder.id);
1908

1909
    var unselectData = {
1910
      data: data
1911
    };
1912
    this.trigger('clear', unselectData);
1913
    if (unselectData.prevented) {
1914
      this.$element.val(previousVal);
1915
      return;
1916
    }
1917

1918
    for (var d = 0; d < data.length; d++) {
1919
      unselectData = {
1920
        data: data[d]
1921
      };
1922

1923
      // Trigger the `unselect` event, so people can prevent it from being
1924
      // cleared.
1925
      this.trigger('unselect', unselectData);
1926

1927
      // If the event was prevented, don't clear it out.
1928
      if (unselectData.prevented) {
1929
        this.$element.val(previousVal);
1930
        return;
1931
      }
1932
    }
1933

1934
    this.$element.trigger('input').trigger('change');
1935

1936
    this.trigger('toggle', {});
1937
  };
1938

1939
  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
1940
    if (container.isOpen()) {
1941
      return;
1942
    }
1943

1944
    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
1945
      this._handleClear(evt);
1946
    }
1947
  };
1948

1949
  AllowClear.prototype.update = function (decorated, data) {
1950
    decorated.call(this, data);
1951

1952
    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
1953
        data.length === 0) {
1954
      return;
1955
    }
1956

1957
    var removeAll = this.options.get('translations').get('removeAllItems');
1958

1959
    var $remove = $(
1960
      '<span class="select2-selection__clear" title="' + removeAll() +'">' +
1961
        '&times;' +
1962
      '</span>'
1963
    );
1964
    Utils.StoreData($remove[0], 'data', data);
1965

1966
    this.$selection.find('.select2-selection__rendered').prepend($remove);
1967
  };
1968

1969
  return AllowClear;
1970
});
1971

1972
S2.define('select2/selection/search',[
1973
  'jquery',
1974
  '../utils',
1975
  '../keys'
1976
], function ($, Utils, KEYS) {
1977
  function Search (decorated, $element, options) {
1978
    decorated.call(this, $element, options);
1979
  }
1980

1981
  Search.prototype.render = function (decorated) {
1982
    var $search = $(
1983
      '<li class="select2-search select2-search--inline">' +
1984
        '<input class="select2-search__field" type="search" tabindex="-1"' +
1985
        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
1986
        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
1987
      '</li>'
1988
    );
1989

1990
    this.$searchContainer = $search;
1991
    this.$search = $search.find('input');
1992

1993
    var $rendered = decorated.call(this);
1994

1995
    this._transferTabIndex();
1996

1997
    return $rendered;
1998
  };
1999

2000
  Search.prototype.bind = function (decorated, container, $container) {
2001
    var self = this;
2002

2003
    var resultsId = container.id + '-results';
2004

2005
    decorated.call(this, container, $container);
2006

2007
    container.on('open', function () {
2008
      self.$search.attr('aria-controls', resultsId);
2009
      self.$search.trigger('focus');
2010
    });
2011

2012
    container.on('close', function () {
2013
      self.$search.val('');
2014
      self.$search.removeAttr('aria-controls');
2015
      self.$search.removeAttr('aria-activedescendant');
2016
      self.$search.trigger('focus');
2017
    });
2018

2019
    container.on('enable', function () {
2020
      self.$search.prop('disabled', false);
2021

2022
      self._transferTabIndex();
2023
    });
2024

2025
    container.on('disable', function () {
2026
      self.$search.prop('disabled', true);
2027
    });
2028

2029
    container.on('focus', function (evt) {
2030
      self.$search.trigger('focus');
2031
    });
2032

2033
    container.on('results:focus', function (params) {
2034
      if (params.data._resultId) {
2035
        self.$search.attr('aria-activedescendant', params.data._resultId);
2036
      } else {
2037
        self.$search.removeAttr('aria-activedescendant');
2038
      }
2039
    });
2040

2041
    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
2042
      self.trigger('focus', evt);
2043
    });
2044

2045
    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
2046
      self._handleBlur(evt);
2047
    });
2048

2049
    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
2050
      evt.stopPropagation();
2051

2052
      self.trigger('keypress', evt);
2053

2054
      self._keyUpPrevented = evt.isDefaultPrevented();
2055

2056
      var key = evt.which;
2057

2058
      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
2059
        var $previousChoice = self.$searchContainer
2060
          .prev('.select2-selection__choice');
2061

2062
        if ($previousChoice.length > 0) {
2063
          var item = Utils.GetData($previousChoice[0], 'data');
2064

2065
          self.searchRemoveChoice(item);
2066

2067
          evt.preventDefault();
2068
        }
2069
      }
2070
    });
2071

2072
    this.$selection.on('click', '.select2-search--inline', function (evt) {
2073
      if (self.$search.val()) {
2074
        evt.stopPropagation();
2075
      }
2076
    });
2077

2078
    // Try to detect the IE version should the `documentMode` property that
2079
    // is stored on the document. This is only implemented in IE and is
2080
    // slightly cleaner than doing a user agent check.
2081
    // This property is not available in Edge, but Edge also doesn't have
2082
    // this bug.
2083
    var msie = document.documentMode;
2084
    var disableInputEvents = msie && msie <= 11;
2085

2086
    // Workaround for browsers which do not support the `input` event
2087
    // This will prevent double-triggering of events for browsers which support
2088
    // both the `keyup` and `input` events.
2089
    this.$selection.on(
2090
      'input.searchcheck',
2091
      '.select2-search--inline',
2092
      function (evt) {
2093
        // IE will trigger the `input` event when a placeholder is used on a
2094
        // search box. To get around this issue, we are forced to ignore all
2095
        // `input` events in IE and keep using `keyup`.
2096
        if (disableInputEvents) {
2097
          self.$selection.off('input.search input.searchcheck');
2098
          return;
2099
        }
2100

2101
        // Unbind the duplicated `keyup` event
2102
        self.$selection.off('keyup.search');
2103
      }
2104
    );
2105

2106
    this.$selection.on(
2107
      'keyup.search input.search',
2108
      '.select2-search--inline',
2109
      function (evt) {
2110
        // IE will trigger the `input` event when a placeholder is used on a
2111
        // search box. To get around this issue, we are forced to ignore all
2112
        // `input` events in IE and keep using `keyup`.
2113
        if (disableInputEvents && evt.type === 'input') {
2114
          self.$selection.off('input.search input.searchcheck');
2115
          return;
2116
        }
2117

2118
        var key = evt.which;
2119

2120
        // We can freely ignore events from modifier keys
2121
        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
2122
          return;
2123
        }
2124

2125
        // Tabbing will be handled during the `keydown` phase
2126
        if (key == KEYS.TAB) {
2127
          return;
2128
        }
2129

2130
        self.handleSearch(evt);
2131
      }
2132
    );
2133
  };
2134

2135
  /**
2136
   * This method will transfer the tabindex attribute from the rendered
2137
   * selection to the search box. This allows for the search box to be used as
2138
   * the primary focus instead of the selection container.
2139
   *
2140
   * @private
2141
   */
2142
  Search.prototype._transferTabIndex = function (decorated) {
2143
    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
2144
    this.$selection.attr('tabindex', '-1');
2145
  };
2146

2147
  Search.prototype.createPlaceholder = function (decorated, placeholder) {
2148
    this.$search.attr('placeholder', placeholder.text);
2149
  };
2150

2151
  Search.prototype.update = function (decorated, data) {
2152
    var searchHadFocus = this.$search[0] == document.activeElement;
2153

2154
    this.$search.attr('placeholder', '');
2155

2156
    decorated.call(this, data);
2157

2158
    this.$selection.find('.select2-selection__rendered')
2159
                   .append(this.$searchContainer);
2160

2161
    this.resizeSearch();
2162
    if (searchHadFocus) {
2163
      this.$search.trigger('focus');
2164
    }
2165
  };
2166

2167
  Search.prototype.handleSearch = function () {
2168
    this.resizeSearch();
2169

2170
    if (!this._keyUpPrevented) {
2171
      var input = this.$search.val();
2172

2173
      this.trigger('query', {
2174
        term: input
2175
      });
2176
    }
2177

2178
    this._keyUpPrevented = false;
2179
  };
2180

2181
  Search.prototype.searchRemoveChoice = function (decorated, item) {
2182
    this.trigger('unselect', {
2183
      data: item
2184
    });
2185

2186
    this.$search.val(item.text);
2187
    this.handleSearch();
2188
  };
2189

2190
  Search.prototype.resizeSearch = function () {
2191
    this.$search.css('width', '25px');
2192

2193
    var width = '';
2194

2195
    if (this.$search.attr('placeholder') !== '') {
2196
      width = this.$selection.find('.select2-selection__rendered').width();
2197
    } else {
2198
      var minimumWidth = this.$search.val().length + 1;
2199

2200
      width = (minimumWidth * 0.75) + 'em';
2201
    }
2202

2203
    this.$search.css('width', width);
2204
  };
2205

2206
  return Search;
2207
});
2208

2209
S2.define('select2/selection/eventRelay',[
2210
  'jquery'
2211
], function ($) {
2212
  function EventRelay () { }
2213

2214
  EventRelay.prototype.bind = function (decorated, container, $container) {
2215
    var self = this;
2216
    var relayEvents = [
2217
      'open', 'opening',
2218
      'close', 'closing',
2219
      'select', 'selecting',
2220
      'unselect', 'unselecting',
2221
      'clear', 'clearing'
2222
    ];
2223

2224
    var preventableEvents = [
2225
      'opening', 'closing', 'selecting', 'unselecting', 'clearing'
2226
    ];
2227

2228
    decorated.call(this, container, $container);
2229

2230
    container.on('*', function (name, params) {
2231
      // Ignore events that should not be relayed
2232
      if ($.inArray(name, relayEvents) === -1) {
2233
        return;
2234
      }
2235

2236
      // The parameters should always be an object
2237
      params = params || {};
2238

2239
      // Generate the jQuery event for the Select2 event
2240
      var evt = $.Event('select2:' + name, {
2241
        params: params
2242
      });
2243

2244
      self.$element.trigger(evt);
2245

2246
      // Only handle preventable events if it was one
2247
      if ($.inArray(name, preventableEvents) === -1) {
2248
        return;
2249
      }
2250

2251
      params.prevented = evt.isDefaultPrevented();
2252
    });
2253
  };
2254

2255
  return EventRelay;
2256
});
2257

2258
S2.define('select2/translation',[
2259
  'jquery',
2260
  'require'
2261
], function ($, require) {
2262
  function Translation (dict) {
2263
    this.dict = dict || {};
2264
  }
2265

2266
  Translation.prototype.all = function () {
2267
    return this.dict;
2268
  };
2269

2270
  Translation.prototype.get = function (key) {
2271
    return this.dict[key];
2272
  };
2273

2274
  Translation.prototype.extend = function (translation) {
2275
    this.dict = $.extend({}, translation.all(), this.dict);
2276
  };
2277

2278
  // Static functions
2279

2280
  Translation._cache = {};
2281

2282
  Translation.loadPath = function (path) {
2283
    if (!(path in Translation._cache)) {
2284
      var translations = require(path);
2285

2286
      Translation._cache[path] = translations;
2287
    }
2288

2289
    return new Translation(Translation._cache[path]);
2290
  };
2291

2292
  return Translation;
2293
});
2294

2295
S2.define('select2/diacritics',[
2296

2297
], function () {
2298
  var diacritics = {
2299
    '\u24B6': 'A',
2300
    '\uFF21': 'A',
2301
    '\u00C0': 'A',
2302
    '\u00C1': 'A',
2303
    '\u00C2': 'A',
2304
    '\u1EA6': 'A',
2305
    '\u1EA4': 'A',
2306
    '\u1EAA': 'A',
2307
    '\u1EA8': 'A',
2308
    '\u00C3': 'A',
2309
    '\u0100': 'A',
2310
    '\u0102': 'A',
2311
    '\u1EB0': 'A',
2312
    '\u1EAE': 'A',
2313
    '\u1EB4': 'A',
2314
    '\u1EB2': 'A',
2315
    '\u0226': 'A',
2316
    '\u01E0': 'A',
2317
    '\u00C4': 'A',
2318
    '\u01DE': 'A',
2319
    '\u1EA2': 'A',
2320
    '\u00C5': 'A',
2321
    '\u01FA': 'A',
2322
    '\u01CD': 'A',
2323
    '\u0200': 'A',
2324
    '\u0202': 'A',
2325
    '\u1EA0': 'A',
2326
    '\u1EAC': 'A',
2327
    '\u1EB6': 'A',
2328
    '\u1E00': 'A',
2329
    '\u0104': 'A',
2330
    '\u023A': 'A',
2331
    '\u2C6F': 'A',
2332
    '\uA732': 'AA',
2333
    '\u00C6': 'AE',
2334
    '\u01FC': 'AE',
2335
    '\u01E2': 'AE',
2336
    '\uA734': 'AO',
2337
    '\uA736': 'AU',
2338
    '\uA738': 'AV',
2339
    '\uA73A': 'AV',
2340
    '\uA73C': 'AY',
2341
    '\u24B7': 'B',
2342
    '\uFF22': 'B',
2343
    '\u1E02': 'B',
2344
    '\u1E04': 'B',
2345
    '\u1E06': 'B',
2346
    '\u0243': 'B',
2347
    '\u0182': 'B',
2348
    '\u0181': 'B',
2349
    '\u24B8': 'C',
2350
    '\uFF23': 'C',
2351
    '\u0106': 'C',
2352
    '\u0108': 'C',
2353
    '\u010A': 'C',
2354
    '\u010C': 'C',
2355
    '\u00C7': 'C',
2356
    '\u1E08': 'C',
2357
    '\u0187': 'C',
2358
    '\u023B': 'C',
2359
    '\uA73E': 'C',
2360
    '\u24B9': 'D',
2361
    '\uFF24': 'D',
2362
    '\u1E0A': 'D',
2363
    '\u010E': 'D',
2364
    '\u1E0C': 'D',
2365
    '\u1E10': 'D',
2366
    '\u1E12': 'D',
2367
    '\u1E0E': 'D',
2368
    '\u0110': 'D',
2369
    '\u018B': 'D',
2370
    '\u018A': 'D',
2371
    '\u0189': 'D',
2372
    '\uA779': 'D',
2373
    '\u01F1': 'DZ',
2374
    '\u01C4': 'DZ',
2375
    '\u01F2': 'Dz',
2376
    '\u01C5': 'Dz',
2377
    '\u24BA': 'E',
2378
    '\uFF25': 'E',
2379
    '\u00C8': 'E',
2380
    '\u00C9': 'E',
2381
    '\u00CA': 'E',
2382
    '\u1EC0': 'E',
2383
    '\u1EBE': 'E',
2384
    '\u1EC4': 'E',
2385
    '\u1EC2': 'E',
2386
    '\u1EBC': 'E',
2387
    '\u0112': 'E',
2388
    '\u1E14': 'E',
2389
    '\u1E16': 'E',
2390
    '\u0114': 'E',
2391
    '\u0116': 'E',
2392
    '\u00CB': 'E',
2393
    '\u1EBA': 'E',
2394
    '\u011A': 'E',
2395
    '\u0204': 'E',
2396
    '\u0206': 'E',
2397
    '\u1EB8': 'E',
2398
    '\u1EC6': 'E',
2399
    '\u0228': 'E',
2400
    '\u1E1C': 'E',
2401
    '\u0118': 'E',
2402
    '\u1E18': 'E',
2403
    '\u1E1A': 'E',
2404
    '\u0190': 'E',
2405
    '\u018E': 'E',
2406
    '\u24BB': 'F',
2407
    '\uFF26': 'F',
2408
    '\u1E1E': 'F',
2409
    '\u0191': 'F',
2410
    '\uA77B': 'F',
2411
    '\u24BC': 'G',
2412
    '\uFF27': 'G',
2413
    '\u01F4': 'G',
2414
    '\u011C': 'G',
2415
    '\u1E20': 'G',
2416
    '\u011E': 'G',
2417
    '\u0120': 'G',
2418
    '\u01E6': 'G',
2419
    '\u0122': 'G',
2420
    '\u01E4': 'G',
2421
    '\u0193': 'G',
2422
    '\uA7A0': 'G',
2423
    '\uA77D': 'G',
2424
    '\uA77E': 'G',
2425
    '\u24BD': 'H',
2426
    '\uFF28': 'H',
2427
    '\u0124': 'H',
2428
    '\u1E22': 'H',
2429
    '\u1E26': 'H',
2430
    '\u021E': 'H',
2431
    '\u1E24': 'H',
2432
    '\u1E28': 'H',
2433
    '\u1E2A': 'H',
2434
    '\u0126': 'H',
2435
    '\u2C67': 'H',
2436
    '\u2C75': 'H',
2437
    '\uA78D': 'H',
2438
    '\u24BE': 'I',
2439
    '\uFF29': 'I',
2440
    '\u00CC': 'I',
2441
    '\u00CD': 'I',
2442
    '\u00CE': 'I',
2443
    '\u0128': 'I',
2444
    '\u012A': 'I',
2445
    '\u012C': 'I',
2446
    '\u0130': 'I',
2447
    '\u00CF': 'I',
2448
    '\u1E2E': 'I',
2449
    '\u1EC8': 'I',
2450
    '\u01CF': 'I',
2451
    '\u0208': 'I',
2452
    '\u020A': 'I',
2453
    '\u1ECA': 'I',
2454
    '\u012E': 'I',
2455
    '\u1E2C': 'I',
2456
    '\u0197': 'I',
2457
    '\u24BF': 'J',
2458
    '\uFF2A': 'J',
2459
    '\u0134': 'J',
2460
    '\u0248': 'J',
2461
    '\u24C0': 'K',
2462
    '\uFF2B': 'K',
2463
    '\u1E30': 'K',
2464
    '\u01E8': 'K',
2465
    '\u1E32': 'K',
2466
    '\u0136': 'K',
2467
    '\u1E34': 'K',
2468
    '\u0198': 'K',
2469
    '\u2C69': 'K',
2470
    '\uA740': 'K',
2471
    '\uA742': 'K',
2472
    '\uA744': 'K',
2473
    '\uA7A2': 'K',
2474
    '\u24C1': 'L',
2475
    '\uFF2C': 'L',
2476
    '\u013F': 'L',
2477
    '\u0139': 'L',
2478
    '\u013D': 'L',
2479
    '\u1E36': 'L',
2480
    '\u1E38': 'L',
2481
    '\u013B': 'L',
2482
    '\u1E3C': 'L',
2483
    '\u1E3A': 'L',
2484
    '\u0141': 'L',
2485
    '\u023D': 'L',
2486
    '\u2C62': 'L',
2487
    '\u2C60': 'L',
2488
    '\uA748': 'L',
2489
    '\uA746': 'L',
2490
    '\uA780': 'L',
2491
    '\u01C7': 'LJ',
2492
    '\u01C8': 'Lj',
2493
    '\u24C2': 'M',
2494
    '\uFF2D': 'M',
2495
    '\u1E3E': 'M',
2496
    '\u1E40': 'M',
2497
    '\u1E42': 'M',
2498
    '\u2C6E': 'M',
2499
    '\u019C': 'M',
2500
    '\u24C3': 'N',
2501
    '\uFF2E': 'N',
2502
    '\u01F8': 'N',
2503
    '\u0143': 'N',
2504
    '\u00D1': 'N',
2505
    '\u1E44': 'N',
2506
    '\u0147': 'N',
2507
    '\u1E46': 'N',
2508
    '\u0145': 'N',
2509
    '\u1E4A': 'N',
2510
    '\u1E48': 'N',
2511
    '\u0220': 'N',
2512
    '\u019D': 'N',
2513
    '\uA790': 'N',
2514
    '\uA7A4': 'N',
2515
    '\u01CA': 'NJ',
2516
    '\u01CB': 'Nj',
2517
    '\u24C4': 'O',
2518
    '\uFF2F': 'O',
2519
    '\u00D2': 'O',
2520
    '\u00D3': 'O',
2521
    '\u00D4': 'O',
2522
    '\u1ED2': 'O',
2523
    '\u1ED0': 'O',
2524
    '\u1ED6': 'O',
2525
    '\u1ED4': 'O',
2526
    '\u00D5': 'O',
2527
    '\u1E4C': 'O',
2528
    '\u022C': 'O',
2529
    '\u1E4E': 'O',
2530
    '\u014C': 'O',
2531
    '\u1E50': 'O',
2532
    '\u1E52': 'O',
2533
    '\u014E': 'O',
2534
    '\u022E': 'O',
2535
    '\u0230': 'O',
2536
    '\u00D6': 'O',
2537
    '\u022A': 'O',
2538
    '\u1ECE': 'O',
2539
    '\u0150': 'O',
2540
    '\u01D1': 'O',
2541
    '\u020C': 'O',
2542
    '\u020E': 'O',
2543
    '\u01A0': 'O',
2544
    '\u1EDC': 'O',
2545
    '\u1EDA': 'O',
2546
    '\u1EE0': 'O',
2547
    '\u1EDE': 'O',
2548
    '\u1EE2': 'O',
2549
    '\u1ECC': 'O',
2550
    '\u1ED8': 'O',
2551
    '\u01EA': 'O',
2552
    '\u01EC': 'O',
2553
    '\u00D8': 'O',
2554
    '\u01FE': 'O',
2555
    '\u0186': 'O',
2556
    '\u019F': 'O',
2557
    '\uA74A': 'O',
2558
    '\uA74C': 'O',
2559
    '\u0152': 'OE',
2560
    '\u01A2': 'OI',
2561
    '\uA74E': 'OO',
2562
    '\u0222': 'OU',
2563
    '\u24C5': 'P',
2564
    '\uFF30': 'P',
2565
    '\u1E54': 'P',
2566
    '\u1E56': 'P',
2567
    '\u01A4': 'P',
2568
    '\u2C63': 'P',
2569
    '\uA750': 'P',
2570
    '\uA752': 'P',
2571
    '\uA754': 'P',
2572
    '\u24C6': 'Q',
2573
    '\uFF31': 'Q',
2574
    '\uA756': 'Q',
2575
    '\uA758': 'Q',
2576
    '\u024A': 'Q',
2577
    '\u24C7': 'R',
2578
    '\uFF32': 'R',
2579
    '\u0154': 'R',
2580
    '\u1E58': 'R',
2581
    '\u0158': 'R',
2582
    '\u0210': 'R',
2583
    '\u0212': 'R',
2584
    '\u1E5A': 'R',
2585
    '\u1E5C': 'R',
2586
    '\u0156': 'R',
2587
    '\u1E5E': 'R',
2588
    '\u024C': 'R',
2589
    '\u2C64': 'R',
2590
    '\uA75A': 'R',
2591
    '\uA7A6': 'R',
2592
    '\uA782': 'R',
2593
    '\u24C8': 'S',
2594
    '\uFF33': 'S',
2595
    '\u1E9E': 'S',
2596
    '\u015A': 'S',
2597
    '\u1E64': 'S',
2598
    '\u015C': 'S',
2599
    '\u1E60': 'S',
2600
    '\u0160': 'S',
2601
    '\u1E66': 'S',
2602
    '\u1E62': 'S',
2603
    '\u1E68': 'S',
2604
    '\u0218': 'S',
2605
    '\u015E': 'S',
2606
    '\u2C7E': 'S',
2607
    '\uA7A8': 'S',
2608
    '\uA784': 'S',
2609
    '\u24C9': 'T',
2610
    '\uFF34': 'T',
2611
    '\u1E6A': 'T',
2612
    '\u0164': 'T',
2613
    '\u1E6C': 'T',
2614
    '\u021A': 'T',
2615
    '\u0162': 'T',
2616
    '\u1E70': 'T',
2617
    '\u1E6E': 'T',
2618
    '\u0166': 'T',
2619
    '\u01AC': 'T',
2620
    '\u01AE': 'T',
2621
    '\u023E': 'T',
2622
    '\uA786': 'T',
2623
    '\uA728': 'TZ',
2624
    '\u24CA': 'U',
2625
    '\uFF35': 'U',
2626
    '\u00D9': 'U',
2627
    '\u00DA': 'U',
2628
    '\u00DB': 'U',
2629
    '\u0168': 'U',
2630
    '\u1E78': 'U',
2631
    '\u016A': 'U',
2632
    '\u1E7A': 'U',
2633
    '\u016C': 'U',
2634
    '\u00DC': 'U',
2635
    '\u01DB': 'U',
2636
    '\u01D7': 'U',
2637
    '\u01D5': 'U',
2638
    '\u01D9': 'U',
2639
    '\u1EE6': 'U',
2640
    '\u016E': 'U',
2641
    '\u0170': 'U',
2642
    '\u01D3': 'U',
2643
    '\u0214': 'U',
2644
    '\u0216': 'U',
2645
    '\u01AF': 'U',
2646
    '\u1EEA': 'U',
2647
    '\u1EE8': 'U',
2648
    '\u1EEE': 'U',
2649
    '\u1EEC': 'U',
2650
    '\u1EF0': 'U',
2651
    '\u1EE4': 'U',
2652
    '\u1E72': 'U',
2653
    '\u0172': 'U',
2654
    '\u1E76': 'U',
2655
    '\u1E74': 'U',
2656
    '\u0244': 'U',
2657
    '\u24CB': 'V',
2658
    '\uFF36': 'V',
2659
    '\u1E7C': 'V',
2660
    '\u1E7E': 'V',
2661
    '\u01B2': 'V',
2662
    '\uA75E': 'V',
2663
    '\u0245': 'V',
2664
    '\uA760': 'VY',
2665
    '\u24CC': 'W',
2666
    '\uFF37': 'W',
2667
    '\u1E80': 'W',
2668
    '\u1E82': 'W',
2669
    '\u0174': 'W',
2670
    '\u1E86': 'W',
2671
    '\u1E84': 'W',
2672
    '\u1E88': 'W',
2673
    '\u2C72': 'W',
2674
    '\u24CD': 'X',
2675
    '\uFF38': 'X',
2676
    '\u1E8A': 'X',
2677
    '\u1E8C': 'X',
2678
    '\u24CE': 'Y',
2679
    '\uFF39': 'Y',
2680
    '\u1EF2': 'Y',
2681
    '\u00DD': 'Y',
2682
    '\u0176': 'Y',
2683
    '\u1EF8': 'Y',
2684
    '\u0232': 'Y',
2685
    '\u1E8E': 'Y',
2686
    '\u0178': 'Y',
2687
    '\u1EF6': 'Y',
2688
    '\u1EF4': 'Y',
2689
    '\u01B3': 'Y',
2690
    '\u024E': 'Y',
2691
    '\u1EFE': 'Y',
2692
    '\u24CF': 'Z',
2693
    '\uFF3A': 'Z',
2694
    '\u0179': 'Z',
2695
    '\u1E90': 'Z',
2696
    '\u017B': 'Z',
2697
    '\u017D': 'Z',
2698
    '\u1E92': 'Z',
2699
    '\u1E94': 'Z',
2700
    '\u01B5': 'Z',
2701
    '\u0224': 'Z',
2702
    '\u2C7F': 'Z',
2703
    '\u2C6B': 'Z',
2704
    '\uA762': 'Z',
2705
    '\u24D0': 'a',
2706
    '\uFF41': 'a',
2707
    '\u1E9A': 'a',
2708
    '\u00E0': 'a',
2709
    '\u00E1': 'a',
2710
    '\u00E2': 'a',
2711
    '\u1EA7': 'a',
2712
    '\u1EA5': 'a',
2713
    '\u1EAB': 'a',
2714
    '\u1EA9': 'a',
2715
    '\u00E3': 'a',
2716
    '\u0101': 'a',
2717
    '\u0103': 'a',
2718
    '\u1EB1': 'a',
2719
    '\u1EAF': 'a',
2720
    '\u1EB5': 'a',
2721
    '\u1EB3': 'a',
2722
    '\u0227': 'a',
2723
    '\u01E1': 'a',
2724
    '\u00E4': 'a',
2725
    '\u01DF': 'a',
2726
    '\u1EA3': 'a',
2727
    '\u00E5': 'a',
2728
    '\u01FB': 'a',
2729
    '\u01CE': 'a',
2730
    '\u0201': 'a',
2731
    '\u0203': 'a',
2732
    '\u1EA1': 'a',
2733
    '\u1EAD': 'a',
2734
    '\u1EB7': 'a',
2735
    '\u1E01': 'a',
2736
    '\u0105': 'a',
2737
    '\u2C65': 'a',
2738
    '\u0250': 'a',
2739
    '\uA733': 'aa',
2740
    '\u00E6': 'ae',
2741
    '\u01FD': 'ae',
2742
    '\u01E3': 'ae',
2743
    '\uA735': 'ao',
2744
    '\uA737': 'au',
2745
    '\uA739': 'av',
2746
    '\uA73B': 'av',
2747
    '\uA73D': 'ay',
2748
    '\u24D1': 'b',
2749
    '\uFF42': 'b',
2750
    '\u1E03': 'b',
2751
    '\u1E05': 'b',
2752
    '\u1E07': 'b',
2753
    '\u0180': 'b',
2754
    '\u0183': 'b',
2755
    '\u0253': 'b',
2756
    '\u24D2': 'c',
2757
    '\uFF43': 'c',
2758
    '\u0107': 'c',
2759
    '\u0109': 'c',
2760
    '\u010B': 'c',
2761
    '\u010D': 'c',
2762
    '\u00E7': 'c',
2763
    '\u1E09': 'c',
2764
    '\u0188': 'c',
2765
    '\u023C': 'c',
2766
    '\uA73F': 'c',
2767
    '\u2184': 'c',
2768
    '\u24D3': 'd',
2769
    '\uFF44': 'd',
2770
    '\u1E0B': 'd',
2771
    '\u010F': 'd',
2772
    '\u1E0D': 'd',
2773
    '\u1E11': 'd',
2774
    '\u1E13': 'd',
2775
    '\u1E0F': 'd',
2776
    '\u0111': 'd',
2777
    '\u018C': 'd',
2778
    '\u0256': 'd',
2779
    '\u0257': 'd',
2780
    '\uA77A': 'd',
2781
    '\u01F3': 'dz',
2782
    '\u01C6': 'dz',
2783
    '\u24D4': 'e',
2784
    '\uFF45': 'e',
2785
    '\u00E8': 'e',
2786
    '\u00E9': 'e',
2787
    '\u00EA': 'e',
2788
    '\u1EC1': 'e',
2789
    '\u1EBF': 'e',
2790
    '\u1EC5': 'e',
2791
    '\u1EC3': 'e',
2792
    '\u1EBD': 'e',
2793
    '\u0113': 'e',
2794
    '\u1E15': 'e',
2795
    '\u1E17': 'e',
2796
    '\u0115': 'e',
2797
    '\u0117': 'e',
2798
    '\u00EB': 'e',
2799
    '\u1EBB': 'e',
2800
    '\u011B': 'e',
2801
    '\u0205': 'e',
2802
    '\u0207': 'e',
2803
    '\u1EB9': 'e',
2804
    '\u1EC7': 'e',
2805
    '\u0229': 'e',
2806
    '\u1E1D': 'e',
2807
    '\u0119': 'e',
2808
    '\u1E19': 'e',
2809
    '\u1E1B': 'e',
2810
    '\u0247': 'e',
2811
    '\u025B': 'e',
2812
    '\u01DD': 'e',
2813
    '\u24D5': 'f',
2814
    '\uFF46': 'f',
2815
    '\u1E1F': 'f',
2816
    '\u0192': 'f',
2817
    '\uA77C': 'f',
2818
    '\u24D6': 'g',
2819
    '\uFF47': 'g',
2820
    '\u01F5': 'g',
2821
    '\u011D': 'g',
2822
    '\u1E21': 'g',
2823
    '\u011F': 'g',
2824
    '\u0121': 'g',
2825
    '\u01E7': 'g',
2826
    '\u0123': 'g',
2827
    '\u01E5': 'g',
2828
    '\u0260': 'g',
2829
    '\uA7A1': 'g',
2830
    '\u1D79': 'g',
2831
    '\uA77F': 'g',
2832
    '\u24D7': 'h',
2833
    '\uFF48': 'h',
2834
    '\u0125': 'h',
2835
    '\u1E23': 'h',
2836
    '\u1E27': 'h',
2837
    '\u021F': 'h',
2838
    '\u1E25': 'h',
2839
    '\u1E29': 'h',
2840
    '\u1E2B': 'h',
2841
    '\u1E96': 'h',
2842
    '\u0127': 'h',
2843
    '\u2C68': 'h',
2844
    '\u2C76': 'h',
2845
    '\u0265': 'h',
2846
    '\u0195': 'hv',
2847
    '\u24D8': 'i',
2848
    '\uFF49': 'i',
2849
    '\u00EC': 'i',
2850
    '\u00ED': 'i',
2851
    '\u00EE': 'i',
2852
    '\u0129': 'i',
2853
    '\u012B': 'i',
2854
    '\u012D': 'i',
2855
    '\u00EF': 'i',
2856
    '\u1E2F': 'i',
2857
    '\u1EC9': 'i',
2858
    '\u01D0': 'i',
2859
    '\u0209': 'i',
2860
    '\u020B': 'i',
2861
    '\u1ECB': 'i',
2862
    '\u012F': 'i',
2863
    '\u1E2D': 'i',
2864
    '\u0268': 'i',
2865
    '\u0131': 'i',
2866
    '\u24D9': 'j',
2867
    '\uFF4A': 'j',
2868
    '\u0135': 'j',
2869
    '\u01F0': 'j',
2870
    '\u0249': 'j',
2871
    '\u24DA': 'k',
2872
    '\uFF4B': 'k',
2873
    '\u1E31': 'k',
2874
    '\u01E9': 'k',
2875
    '\u1E33': 'k',
2876
    '\u0137': 'k',
2877
    '\u1E35': 'k',
2878
    '\u0199': 'k',
2879
    '\u2C6A': 'k',
2880
    '\uA741': 'k',
2881
    '\uA743': 'k',
2882
    '\uA745': 'k',
2883
    '\uA7A3': 'k',
2884
    '\u24DB': 'l',
2885
    '\uFF4C': 'l',
2886
    '\u0140': 'l',
2887
    '\u013A': 'l',
2888
    '\u013E': 'l',
2889
    '\u1E37': 'l',
2890
    '\u1E39': 'l',
2891
    '\u013C': 'l',
2892
    '\u1E3D': 'l',
2893
    '\u1E3B': 'l',
2894
    '\u017F': 'l',
2895
    '\u0142': 'l',
2896
    '\u019A': 'l',
2897
    '\u026B': 'l',
2898
    '\u2C61': 'l',
2899
    '\uA749': 'l',
2900
    '\uA781': 'l',
2901
    '\uA747': 'l',
2902
    '\u01C9': 'lj',
2903
    '\u24DC': 'm',
2904
    '\uFF4D': 'm',
2905
    '\u1E3F': 'm',
2906
    '\u1E41': 'm',
2907
    '\u1E43': 'm',
2908
    '\u0271': 'm',
2909
    '\u026F': 'm',
2910
    '\u24DD': 'n',
2911
    '\uFF4E': 'n',
2912
    '\u01F9': 'n',
2913
    '\u0144': 'n',
2914
    '\u00F1': 'n',
2915
    '\u1E45': 'n',
2916
    '\u0148': 'n',
2917
    '\u1E47': 'n',
2918
    '\u0146': 'n',
2919
    '\u1E4B': 'n',
2920
    '\u1E49': 'n',
2921
    '\u019E': 'n',
2922
    '\u0272': 'n',
2923
    '\u0149': 'n',
2924
    '\uA791': 'n',
2925
    '\uA7A5': 'n',
2926
    '\u01CC': 'nj',
2927
    '\u24DE': 'o',
2928
    '\uFF4F': 'o',
2929
    '\u00F2': 'o',
2930
    '\u00F3': 'o',
2931
    '\u00F4': 'o',
2932
    '\u1ED3': 'o',
2933
    '\u1ED1': 'o',
2934
    '\u1ED7': 'o',
2935
    '\u1ED5': 'o',
2936
    '\u00F5': 'o',
2937
    '\u1E4D': 'o',
2938
    '\u022D': 'o',
2939
    '\u1E4F': 'o',
2940
    '\u014D': 'o',
2941
    '\u1E51': 'o',
2942
    '\u1E53': 'o',
2943
    '\u014F': 'o',
2944
    '\u022F': 'o',
2945
    '\u0231': 'o',
2946
    '\u00F6': 'o',
2947
    '\u022B': 'o',
2948
    '\u1ECF': 'o',
2949
    '\u0151': 'o',
2950
    '\u01D2': 'o',
2951
    '\u020D': 'o',
2952
    '\u020F': 'o',
2953
    '\u01A1': 'o',
2954
    '\u1EDD': 'o',
2955
    '\u1EDB': 'o',
2956
    '\u1EE1': 'o',
2957
    '\u1EDF': 'o',
2958
    '\u1EE3': 'o',
2959
    '\u1ECD': 'o',
2960
    '\u1ED9': 'o',
2961
    '\u01EB': 'o',
2962
    '\u01ED': 'o',
2963
    '\u00F8': 'o',
2964
    '\u01FF': 'o',
2965
    '\u0254': 'o',
2966
    '\uA74B': 'o',
2967
    '\uA74D': 'o',
2968
    '\u0275': 'o',
2969
    '\u0153': 'oe',
2970
    '\u01A3': 'oi',
2971
    '\u0223': 'ou',
2972
    '\uA74F': 'oo',
2973
    '\u24DF': 'p',
2974
    '\uFF50': 'p',
2975
    '\u1E55': 'p',
2976
    '\u1E57': 'p',
2977
    '\u01A5': 'p',
2978
    '\u1D7D': 'p',
2979
    '\uA751': 'p',
2980
    '\uA753': 'p',
2981
    '\uA755': 'p',
2982
    '\u24E0': 'q',
2983
    '\uFF51': 'q',
2984
    '\u024B': 'q',
2985
    '\uA757': 'q',
2986
    '\uA759': 'q',
2987
    '\u24E1': 'r',
2988
    '\uFF52': 'r',
2989
    '\u0155': 'r',
2990
    '\u1E59': 'r',
2991
    '\u0159': 'r',
2992
    '\u0211': 'r',
2993
    '\u0213': 'r',
2994
    '\u1E5B': 'r',
2995
    '\u1E5D': 'r',
2996
    '\u0157': 'r',
2997
    '\u1E5F': 'r',
2998
    '\u024D': 'r',
2999
    '\u027D': 'r',
3000
    '\uA75B': 'r',
3001
    '\uA7A7': 'r',
3002
    '\uA783': 'r',
3003
    '\u24E2': 's',
3004
    '\uFF53': 's',
3005
    '\u00DF': 's',
3006
    '\u015B': 's',
3007
    '\u1E65': 's',
3008
    '\u015D': 's',
3009
    '\u1E61': 's',
3010
    '\u0161': 's',
3011
    '\u1E67': 's',
3012
    '\u1E63': 's',
3013
    '\u1E69': 's',
3014
    '\u0219': 's',
3015
    '\u015F': 's',
3016
    '\u023F': 's',
3017
    '\uA7A9': 's',
3018
    '\uA785': 's',
3019
    '\u1E9B': 's',
3020
    '\u24E3': 't',
3021
    '\uFF54': 't',
3022
    '\u1E6B': 't',
3023
    '\u1E97': 't',
3024
    '\u0165': 't',
3025
    '\u1E6D': 't',
3026
    '\u021B': 't',
3027
    '\u0163': 't',
3028
    '\u1E71': 't',
3029
    '\u1E6F': 't',
3030
    '\u0167': 't',
3031
    '\u01AD': 't',
3032
    '\u0288': 't',
3033
    '\u2C66': 't',
3034
    '\uA787': 't',
3035
    '\uA729': 'tz',
3036
    '\u24E4': 'u',
3037
    '\uFF55': 'u',
3038
    '\u00F9': 'u',
3039
    '\u00FA': 'u',
3040
    '\u00FB': 'u',
3041
    '\u0169': 'u',
3042
    '\u1E79': 'u',
3043
    '\u016B': 'u',
3044
    '\u1E7B': 'u',
3045
    '\u016D': 'u',
3046
    '\u00FC': 'u',
3047
    '\u01DC': 'u',
3048
    '\u01D8': 'u',
3049
    '\u01D6': 'u',
3050
    '\u01DA': 'u',
3051
    '\u1EE7': 'u',
3052
    '\u016F': 'u',
3053
    '\u0171': 'u',
3054
    '\u01D4': 'u',
3055
    '\u0215': 'u',
3056
    '\u0217': 'u',
3057
    '\u01B0': 'u',
3058
    '\u1EEB': 'u',
3059
    '\u1EE9': 'u',
3060
    '\u1EEF': 'u',
3061
    '\u1EED': 'u',
3062
    '\u1EF1': 'u',
3063
    '\u1EE5': 'u',
3064
    '\u1E73': 'u',
3065
    '\u0173': 'u',
3066
    '\u1E77': 'u',
3067
    '\u1E75': 'u',
3068
    '\u0289': 'u',
3069
    '\u24E5': 'v',
3070
    '\uFF56': 'v',
3071
    '\u1E7D': 'v',
3072
    '\u1E7F': 'v',
3073
    '\u028B': 'v',
3074
    '\uA75F': 'v',
3075
    '\u028C': 'v',
3076
    '\uA761': 'vy',
3077
    '\u24E6': 'w',
3078
    '\uFF57': 'w',
3079
    '\u1E81': 'w',
3080
    '\u1E83': 'w',
3081
    '\u0175': 'w',
3082
    '\u1E87': 'w',
3083
    '\u1E85': 'w',
3084
    '\u1E98': 'w',
3085
    '\u1E89': 'w',
3086
    '\u2C73': 'w',
3087
    '\u24E7': 'x',
3088
    '\uFF58': 'x',
3089
    '\u1E8B': 'x',
3090
    '\u1E8D': 'x',
3091
    '\u24E8': 'y',
3092
    '\uFF59': 'y',
3093
    '\u1EF3': 'y',
3094
    '\u00FD': 'y',
3095
    '\u0177': 'y',
3096
    '\u1EF9': 'y',
3097
    '\u0233': 'y',
3098
    '\u1E8F': 'y',
3099
    '\u00FF': 'y',
3100
    '\u1EF7': 'y',
3101
    '\u1E99': 'y',
3102
    '\u1EF5': 'y',
3103
    '\u01B4': 'y',
3104
    '\u024F': 'y',
3105
    '\u1EFF': 'y',
3106
    '\u24E9': 'z',
3107
    '\uFF5A': 'z',
3108
    '\u017A': 'z',
3109
    '\u1E91': 'z',
3110
    '\u017C': 'z',
3111
    '\u017E': 'z',
3112
    '\u1E93': 'z',
3113
    '\u1E95': 'z',
3114
    '\u01B6': 'z',
3115
    '\u0225': 'z',
3116
    '\u0240': 'z',
3117
    '\u2C6C': 'z',
3118
    '\uA763': 'z',
3119
    '\u0386': '\u0391',
3120
    '\u0388': '\u0395',
3121
    '\u0389': '\u0397',
3122
    '\u038A': '\u0399',
3123
    '\u03AA': '\u0399',
3124
    '\u038C': '\u039F',
3125
    '\u038E': '\u03A5',
3126
    '\u03AB': '\u03A5',
3127
    '\u038F': '\u03A9',
3128
    '\u03AC': '\u03B1',
3129
    '\u03AD': '\u03B5',
3130
    '\u03AE': '\u03B7',
3131
    '\u03AF': '\u03B9',
3132
    '\u03CA': '\u03B9',
3133
    '\u0390': '\u03B9',
3134
    '\u03CC': '\u03BF',
3135
    '\u03CD': '\u03C5',
3136
    '\u03CB': '\u03C5',
3137
    '\u03B0': '\u03C5',
3138
    '\u03CE': '\u03C9',
3139
    '\u03C2': '\u03C3',
3140
    '\u2019': '\''
3141
  };
3142

3143
  return diacritics;
3144
});
3145

3146
S2.define('select2/data/base',[
3147
  '../utils'
3148
], function (Utils) {
3149
  function BaseAdapter ($element, options) {
3150
    BaseAdapter.__super__.constructor.call(this);
3151
  }
3152

3153
  Utils.Extend(BaseAdapter, Utils.Observable);
3154

3155
  BaseAdapter.prototype.current = function (callback) {
3156
    throw new Error('The `current` method must be defined in child classes.');
3157
  };
3158

3159
  BaseAdapter.prototype.query = function (params, callback) {
3160
    throw new Error('The `query` method must be defined in child classes.');
3161
  };
3162

3163
  BaseAdapter.prototype.bind = function (container, $container) {
3164
    // Can be implemented in subclasses
3165
  };
3166

3167
  BaseAdapter.prototype.destroy = function () {
3168
    // Can be implemented in subclasses
3169
  };
3170

3171
  BaseAdapter.prototype.generateResultId = function (container, data) {
3172
    var id = container.id + '-result-';
3173

3174
    id += Utils.generateChars(4);
3175

3176
    if (data.id != null) {
3177
      id += '-' + data.id.toString();
3178
    } else {
3179
      id += '-' + Utils.generateChars(4);
3180
    }
3181
    return id;
3182
  };
3183

3184
  return BaseAdapter;
3185
});
3186

3187
S2.define('select2/data/select',[
3188
  './base',
3189
  '../utils',
3190
  'jquery'
3191
], function (BaseAdapter, Utils, $) {
3192
  function SelectAdapter ($element, options) {
3193
    this.$element = $element;
3194
    this.options = options;
3195

3196
    SelectAdapter.__super__.constructor.call(this);
3197
  }
3198

3199
  Utils.Extend(SelectAdapter, BaseAdapter);
3200

3201
  SelectAdapter.prototype.current = function (callback) {
3202
    var data = [];
3203
    var self = this;
3204

3205
    this.$element.find(':selected').each(function () {
3206
      var $option = $(this);
3207

3208
      var option = self.item($option);
3209

3210
      data.push(option);
3211
    });
3212

3213
    callback(data);
3214
  };
3215

3216
  SelectAdapter.prototype.select = function (data) {
3217
    var self = this;
3218

3219
    data.selected = true;
3220

3221
    // If data.element is a DOM node, use it instead
3222
    if ($(data.element).is('option')) {
3223
      data.element.selected = true;
3224

3225
      this.$element.trigger('input').trigger('change');
3226

3227
      return;
3228
    }
3229

3230
    if (this.$element.prop('multiple')) {
3231
      this.current(function (currentData) {
3232
        var val = [];
3233

3234
        data = [data];
3235
        data.push.apply(data, currentData);
3236

3237
        for (var d = 0; d < data.length; d++) {
3238
          var id = data[d].id;
3239

3240
          if ($.inArray(id, val) === -1) {
3241
            val.push(id);
3242
          }
3243
        }
3244

3245
        self.$element.val(val);
3246
        self.$element.trigger('input').trigger('change');
3247
      });
3248
    } else {
3249
      var val = data.id;
3250

3251
      this.$element.val(val);
3252
      this.$element.trigger('input').trigger('change');
3253
    }
3254
  };
3255

3256
  SelectAdapter.prototype.unselect = function (data) {
3257
    var self = this;
3258

3259
    if (!this.$element.prop('multiple')) {
3260
      return;
3261
    }
3262

3263
    data.selected = false;
3264

3265
    if ($(data.element).is('option')) {
3266
      data.element.selected = false;
3267

3268
      this.$element.trigger('input').trigger('change');
3269

3270
      return;
3271
    }
3272

3273
    this.current(function (currentData) {
3274
      var val = [];
3275

3276
      for (var d = 0; d < currentData.length; d++) {
3277
        var id = currentData[d].id;
3278

3279
        if (id !== data.id && $.inArray(id, val) === -1) {
3280
          val.push(id);
3281
        }
3282
      }
3283

3284
      self.$element.val(val);
3285

3286
      self.$element.trigger('input').trigger('change');
3287
    });
3288
  };
3289

3290
  SelectAdapter.prototype.bind = function (container, $container) {
3291
    var self = this;
3292

3293
    this.container = container;
3294

3295
    container.on('select', function (params) {
3296
      self.select(params.data);
3297
    });
3298

3299
    container.on('unselect', function (params) {
3300
      self.unselect(params.data);
3301
    });
3302
  };
3303

3304
  SelectAdapter.prototype.destroy = function () {
3305
    // Remove anything added to child elements
3306
    this.$element.find('*').each(function () {
3307
      // Remove any custom data set by Select2
3308
      Utils.RemoveData(this);
3309
    });
3310
  };
3311

3312
  SelectAdapter.prototype.query = function (params, callback) {
3313
    var data = [];
3314
    var self = this;
3315

3316
    var $options = this.$element.children();
3317

3318
    $options.each(function () {
3319
      var $option = $(this);
3320

3321
      if (!$option.is('option') && !$option.is('optgroup')) {
3322
        return;
3323
      }
3324

3325
      var option = self.item($option);
3326

3327
      var matches = self.matches(params, option);
3328

3329
      if (matches !== null) {
3330
        data.push(matches);
3331
      }
3332
    });
3333

3334
    callback({
3335
      results: data
3336
    });
3337
  };
3338

3339
  SelectAdapter.prototype.addOptions = function ($options) {
3340
    Utils.appendMany(this.$element, $options);
3341
  };
3342

3343
  SelectAdapter.prototype.option = function (data) {
3344
    var option;
3345

3346
    if (data.children) {
3347
      option = document.createElement('optgroup');
3348
      option.label = data.text;
3349
    } else {
3350
      option = document.createElement('option');
3351

3352
      if (option.textContent !== undefined) {
3353
        option.textContent = data.text;
3354
      } else {
3355
        option.innerText = data.text;
3356
      }
3357
    }
3358

3359
    if (data.id !== undefined) {
3360
      option.value = data.id;
3361
    }
3362

3363
    if (data.disabled) {
3364
      option.disabled = true;
3365
    }
3366

3367
    if (data.selected) {
3368
      option.selected = true;
3369
    }
3370

3371
    if (data.title) {
3372
      option.title = data.title;
3373
    }
3374

3375
    var $option = $(option);
3376

3377
    var normalizedData = this._normalizeItem(data);
3378
    normalizedData.element = option;
3379

3380
    // Override the option's data with the combined data
3381
    Utils.StoreData(option, 'data', normalizedData);
3382

3383
    return $option;
3384
  };
3385

3386
  SelectAdapter.prototype.item = function ($option) {
3387
    var data = {};
3388

3389
    data = Utils.GetData($option[0], 'data');
3390

3391
    if (data != null) {
3392
      return data;
3393
    }
3394

3395
    if ($option.is('option')) {
3396
      data = {
3397
        id: $option.val(),
3398
        text: $option.text(),
3399
        disabled: $option.prop('disabled'),
3400
        selected: $option.prop('selected'),
3401
        title: $option.prop('title')
3402
      };
3403
    } else if ($option.is('optgroup')) {
3404
      data = {
3405
        text: $option.prop('label'),
3406
        children: [],
3407
        title: $option.prop('title')
3408
      };
3409

3410
      var $children = $option.children('option');
3411
      var children = [];
3412

3413
      for (var c = 0; c < $children.length; c++) {
3414
        var $child = $($children[c]);
3415

3416
        var child = this.item($child);
3417

3418
        children.push(child);
3419
      }
3420

3421
      data.children = children;
3422
    }
3423

3424
    data = this._normalizeItem(data);
3425
    data.element = $option[0];
3426

3427
    Utils.StoreData($option[0], 'data', data);
3428

3429
    return data;
3430
  };
3431

3432
  SelectAdapter.prototype._normalizeItem = function (item) {
3433
    if (item !== Object(item)) {
3434
      item = {
3435
        id: item,
3436
        text: item
3437
      };
3438
    }
3439

3440
    item = $.extend({}, {
3441
      text: ''
3442
    }, item);
3443

3444
    var defaults = {
3445
      selected: false,
3446
      disabled: false
3447
    };
3448

3449
    if (item.id != null) {
3450
      item.id = item.id.toString();
3451
    }
3452

3453
    if (item.text != null) {
3454
      item.text = item.text.toString();
3455
    }
3456

3457
    if (item._resultId == null && item.id && this.container != null) {
3458
      item._resultId = this.generateResultId(this.container, item);
3459
    }
3460

3461
    return $.extend({}, defaults, item);
3462
  };
3463

3464
  SelectAdapter.prototype.matches = function (params, data) {
3465
    var matcher = this.options.get('matcher');
3466

3467
    return matcher(params, data);
3468
  };
3469

3470
  return SelectAdapter;
3471
});
3472

3473
S2.define('select2/data/array',[
3474
  './select',
3475
  '../utils',
3476
  'jquery'
3477
], function (SelectAdapter, Utils, $) {
3478
  function ArrayAdapter ($element, options) {
3479
    this._dataToConvert = options.get('data') || [];
3480

3481
    ArrayAdapter.__super__.constructor.call(this, $element, options);
3482
  }
3483

3484
  Utils.Extend(ArrayAdapter, SelectAdapter);
3485

3486
  ArrayAdapter.prototype.bind = function (container, $container) {
3487
    ArrayAdapter.__super__.bind.call(this, container, $container);
3488

3489
    this.addOptions(this.convertToOptions(this._dataToConvert));
3490
  };
3491

3492
  ArrayAdapter.prototype.select = function (data) {
3493
    var $option = this.$element.find('option').filter(function (i, elm) {
3494
      return elm.value == data.id.toString();
3495
    });
3496

3497
    if ($option.length === 0) {
3498
      $option = this.option(data);
3499

3500
      this.addOptions($option);
3501
    }
3502

3503
    ArrayAdapter.__super__.select.call(this, data);
3504
  };
3505

3506
  ArrayAdapter.prototype.convertToOptions = function (data) {
3507
    var self = this;
3508

3509
    var $existing = this.$element.find('option');
3510
    var existingIds = $existing.map(function () {
3511
      return self.item($(this)).id;
3512
    }).get();
3513

3514
    var $options = [];
3515

3516
    // Filter out all items except for the one passed in the argument
3517
    function onlyItem (item) {
3518
      return function () {
3519
        return $(this).val() == item.id;
3520
      };
3521
    }
3522

3523
    for (var d = 0; d < data.length; d++) {
3524
      var item = this._normalizeItem(data[d]);
3525

3526
      // Skip items which were pre-loaded, only merge the data
3527
      if ($.inArray(item.id, existingIds) >= 0) {
3528
        var $existingOption = $existing.filter(onlyItem(item));
3529

3530
        var existingData = this.item($existingOption);
3531
        var newData = $.extend(true, {}, item, existingData);
3532

3533
        var $newOption = this.option(newData);
3534

3535
        $existingOption.replaceWith($newOption);
3536

3537
        continue;
3538
      }
3539

3540
      var $option = this.option(item);
3541

3542
      if (item.children) {
3543
        var $children = this.convertToOptions(item.children);
3544

3545
        Utils.appendMany($option, $children);
3546
      }
3547

3548
      $options.push($option);
3549
    }
3550

3551
    return $options;
3552
  };
3553

3554
  return ArrayAdapter;
3555
});
3556

3557
S2.define('select2/data/ajax',[
3558
  './array',
3559
  '../utils',
3560
  'jquery'
3561
], function (ArrayAdapter, Utils, $) {
3562
  function AjaxAdapter ($element, options) {
3563
    this.ajaxOptions = this._applyDefaults(options.get('ajax'));
3564

3565
    if (this.ajaxOptions.processResults != null) {
3566
      this.processResults = this.ajaxOptions.processResults;
3567
    }
3568

3569
    AjaxAdapter.__super__.constructor.call(this, $element, options);
3570
  }
3571

3572
  Utils.Extend(AjaxAdapter, ArrayAdapter);
3573

3574
  AjaxAdapter.prototype._applyDefaults = function (options) {
3575
    var defaults = {
3576
      data: function (params) {
3577
        return $.extend({}, params, {
3578
          q: params.term
3579
        });
3580
      },
3581
      transport: function (params, success, failure) {
3582
        var $request = $.ajax(params);
3583

3584
        $request.then(success);
3585
        $request.fail(failure);
3586

3587
        return $request;
3588
      }
3589
    };
3590

3591
    return $.extend({}, defaults, options, true);
3592
  };
3593

3594
  AjaxAdapter.prototype.processResults = function (results) {
3595
    return results;
3596
  };
3597

3598
  AjaxAdapter.prototype.query = function (params, callback) {
3599
    var matches = [];
3600
    var self = this;
3601

3602
    if (this._request != null) {
3603
      // JSONP requests cannot always be aborted
3604
      if ($.isFunction(this._request.abort)) {
3605
        this._request.abort();
3606
      }
3607

3608
      this._request = null;
3609
    }
3610

3611
    var options = $.extend({
3612
      type: 'GET'
3613
    }, this.ajaxOptions);
3614

3615
    if (typeof options.url === 'function') {
3616
      options.url = options.url.call(this.$element, params);
3617
    }
3618

3619
    if (typeof options.data === 'function') {
3620
      options.data = options.data.call(this.$element, params);
3621
    }
3622

3623
    function request () {
3624
      var $request = options.transport(options, function (data) {
3625
        var results = self.processResults(data, params);
3626

3627
        if (self.options.get('debug') && window.console && console.error) {
3628
          // Check to make sure that the response included a `results` key.
3629
          if (!results || !results.results || !$.isArray(results.results)) {
3630
            console.error(
3631
              'Select2: The AJAX results did not return an array in the ' +
3632
              '`results` key of the response.'
3633
            );
3634
          }
3635
        }
3636

3637
        callback(results);
3638
      }, function () {
3639
        // Attempt to detect if a request was aborted
3640
        // Only works if the transport exposes a status property
3641
        if ('status' in $request &&
3642
            ($request.status === 0 || $request.status === '0')) {
3643
          return;
3644
        }
3645

3646
        self.trigger('results:message', {
3647
          message: 'errorLoading'
3648
        });
3649
      });
3650

3651
      self._request = $request;
3652
    }
3653

3654
    if (this.ajaxOptions.delay && params.term != null) {
3655
      if (this._queryTimeout) {
3656
        window.clearTimeout(this._queryTimeout);
3657
      }
3658

3659
      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
3660
    } else {
3661
      request();
3662
    }
3663
  };
3664

3665
  return AjaxAdapter;
3666
});
3667

3668
S2.define('select2/data/tags',[
3669
  'jquery'
3670
], function ($) {
3671
  function Tags (decorated, $element, options) {
3672
    var tags = options.get('tags');
3673

3674
    var createTag = options.get('createTag');
3675

3676
    if (createTag !== undefined) {
3677
      this.createTag = createTag;
3678
    }
3679

3680
    var insertTag = options.get('insertTag');
3681

3682
    if (insertTag !== undefined) {
3683
        this.insertTag = insertTag;
3684
    }
3685

3686
    decorated.call(this, $element, options);
3687

3688
    if ($.isArray(tags)) {
3689
      for (var t = 0; t < tags.length; t++) {
3690
        var tag = tags[t];
3691
        var item = this._normalizeItem(tag);
3692

3693
        var $option = this.option(item);
3694

3695
        this.$element.append($option);
3696
      }
3697
    }
3698
  }
3699

3700
  Tags.prototype.query = function (decorated, params, callback) {
3701
    var self = this;
3702

3703
    this._removeOldTags();
3704

3705
    if (params.term == null || params.page != null) {
3706
      decorated.call(this, params, callback);
3707
      return;
3708
    }
3709

3710
    function wrapper (obj, child) {
3711
      var data = obj.results;
3712

3713
      for (var i = 0; i < data.length; i++) {
3714
        var option = data[i];
3715

3716
        var checkChildren = (
3717
          option.children != null &&
3718
          !wrapper({
3719
            results: option.children
3720
          }, true)
3721
        );
3722

3723
        var optionText = (option.text || '').toUpperCase();
3724
        var paramsTerm = (params.term || '').toUpperCase();
3725

3726
        var checkText = optionText === paramsTerm;
3727

3728
        if (checkText || checkChildren) {
3729
          if (child) {
3730
            return false;
3731
          }
3732

3733
          obj.data = data;
3734
          callback(obj);
3735

3736
          return;
3737
        }
3738
      }
3739

3740
      if (child) {
3741
        return true;
3742
      }
3743

3744
      var tag = self.createTag(params);
3745

3746
      if (tag != null) {
3747
        var $option = self.option(tag);
3748
        $option.attr('data-select2-tag', true);
3749

3750
        self.addOptions([$option]);
3751

3752
        self.insertTag(data, tag);
3753
      }
3754

3755
      obj.results = data;
3756

3757
      callback(obj);
3758
    }
3759

3760
    decorated.call(this, params, wrapper);
3761
  };
3762

3763
  Tags.prototype.createTag = function (decorated, params) {
3764
    var term = $.trim(params.term);
3765

3766
    if (term === '') {
3767
      return null;
3768
    }
3769

3770
    return {
3771
      id: term,
3772
      text: term
3773
    };
3774
  };
3775

3776
  Tags.prototype.insertTag = function (_, data, tag) {
3777
    data.unshift(tag);
3778
  };
3779

3780
  Tags.prototype._removeOldTags = function (_) {
3781
    var $options = this.$element.find('option[data-select2-tag]');
3782

3783
    $options.each(function () {
3784
      if (this.selected) {
3785
        return;
3786
      }
3787

3788
      $(this).remove();
3789
    });
3790
  };
3791

3792
  return Tags;
3793
});
3794

3795
S2.define('select2/data/tokenizer',[
3796
  'jquery'
3797
], function ($) {
3798
  function Tokenizer (decorated, $element, options) {
3799
    var tokenizer = options.get('tokenizer');
3800

3801
    if (tokenizer !== undefined) {
3802
      this.tokenizer = tokenizer;
3803
    }
3804

3805
    decorated.call(this, $element, options);
3806
  }
3807

3808
  Tokenizer.prototype.bind = function (decorated, container, $container) {
3809
    decorated.call(this, container, $container);
3810

3811
    this.$search =  container.dropdown.$search || container.selection.$search ||
3812
      $container.find('.select2-search__field');
3813
  };
3814

3815
  Tokenizer.prototype.query = function (decorated, params, callback) {
3816
    var self = this;
3817

3818
    function createAndSelect (data) {
3819
      // Normalize the data object so we can use it for checks
3820
      var item = self._normalizeItem(data);
3821

3822
      // Check if the data object already exists as a tag
3823
      // Select it if it doesn't
3824
      var $existingOptions = self.$element.find('option').filter(function () {
3825
        return $(this).val() === item.id;
3826
      });
3827

3828
      // If an existing option wasn't found for it, create the option
3829
      if (!$existingOptions.length) {
3830
        var $option = self.option(item);
3831
        $option.attr('data-select2-tag', true);
3832

3833
        self._removeOldTags();
3834
        self.addOptions([$option]);
3835
      }
3836

3837
      // Select the item, now that we know there is an option for it
3838
      select(item);
3839
    }
3840

3841
    function select (data) {
3842
      self.trigger('select', {
3843
        data: data
3844
      });
3845
    }
3846

3847
    params.term = params.term || '';
3848

3849
    var tokenData = this.tokenizer(params, this.options, createAndSelect);
3850

3851
    if (tokenData.term !== params.term) {
3852
      // Replace the search term if we have the search box
3853
      if (this.$search.length) {
3854
        this.$search.val(tokenData.term);
3855
        this.$search.trigger('focus');
3856
      }
3857

3858
      params.term = tokenData.term;
3859
    }
3860

3861
    decorated.call(this, params, callback);
3862
  };
3863

3864
  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
3865
    var separators = options.get('tokenSeparators') || [];
3866
    var term = params.term;
3867
    var i = 0;
3868

3869
    var createTag = this.createTag || function (params) {
3870
      return {
3871
        id: params.term,
3872
        text: params.term
3873
      };
3874
    };
3875

3876
    while (i < term.length) {
3877
      var termChar = term[i];
3878

3879
      if ($.inArray(termChar, separators) === -1) {
3880
        i++;
3881

3882
        continue;
3883
      }
3884

3885
      var part = term.substr(0, i);
3886
      var partParams = $.extend({}, params, {
3887
        term: part
3888
      });
3889

3890
      var data = createTag(partParams);
3891

3892
      if (data == null) {
3893
        i++;
3894
        continue;
3895
      }
3896

3897
      callback(data);
3898

3899
      // Reset the term to not include the tokenized portion
3900
      term = term.substr(i + 1) || '';
3901
      i = 0;
3902
    }
3903

3904
    return {
3905
      term: term
3906
    };
3907
  };
3908

3909
  return Tokenizer;
3910
});
3911

3912
S2.define('select2/data/minimumInputLength',[
3913

3914
], function () {
3915
  function MinimumInputLength (decorated, $e, options) {
3916
    this.minimumInputLength = options.get('minimumInputLength');
3917

3918
    decorated.call(this, $e, options);
3919
  }
3920

3921
  MinimumInputLength.prototype.query = function (decorated, params, callback) {
3922
    params.term = params.term || '';
3923

3924
    if (params.term.length < this.minimumInputLength) {
3925
      this.trigger('results:message', {
3926
        message: 'inputTooShort',
3927
        args: {
3928
          minimum: this.minimumInputLength,
3929
          input: params.term,
3930
          params: params
3931
        }
3932
      });
3933

3934
      return;
3935
    }
3936

3937
    decorated.call(this, params, callback);
3938
  };
3939

3940
  return MinimumInputLength;
3941
});
3942

3943
S2.define('select2/data/maximumInputLength',[
3944

3945
], function () {
3946
  function MaximumInputLength (decorated, $e, options) {
3947
    this.maximumInputLength = options.get('maximumInputLength');
3948

3949
    decorated.call(this, $e, options);
3950
  }
3951

3952
  MaximumInputLength.prototype.query = function (decorated, params, callback) {
3953
    params.term = params.term || '';
3954

3955
    if (this.maximumInputLength > 0 &&
3956
        params.term.length > this.maximumInputLength) {
3957
      this.trigger('results:message', {
3958
        message: 'inputTooLong',
3959
        args: {
3960
          maximum: this.maximumInputLength,
3961
          input: params.term,
3962
          params: params
3963
        }
3964
      });
3965

3966
      return;
3967
    }
3968

3969
    decorated.call(this, params, callback);
3970
  };
3971

3972
  return MaximumInputLength;
3973
});
3974

3975
S2.define('select2/data/maximumSelectionLength',[
3976

3977
], function (){
3978
  function MaximumSelectionLength (decorated, $e, options) {
3979
    this.maximumSelectionLength = options.get('maximumSelectionLength');
3980

3981
    decorated.call(this, $e, options);
3982
  }
3983

3984
  MaximumSelectionLength.prototype.bind =
3985
    function (decorated, container, $container) {
3986
      var self = this;
3987

3988
      decorated.call(this, container, $container);
3989

3990
      container.on('select', function () {
3991
        self._checkIfMaximumSelected();
3992
      });
3993
  };
3994

3995
  MaximumSelectionLength.prototype.query =
3996
    function (decorated, params, callback) {
3997
      var self = this;
3998

3999
      this._checkIfMaximumSelected(function () {
4000
        decorated.call(self, params, callback);
4001
      });
4002
  };
4003

4004
  MaximumSelectionLength.prototype._checkIfMaximumSelected =
4005
    function (_, successCallback) {
4006
      var self = this;
4007

4008
      this.current(function (currentData) {
4009
        var count = currentData != null ? currentData.length : 0;
4010
        if (self.maximumSelectionLength > 0 &&
4011
          count >= self.maximumSelectionLength) {
4012
          self.trigger('results:message', {
4013
            message: 'maximumSelected',
4014
            args: {
4015
              maximum: self.maximumSelectionLength
4016
            }
4017
          });
4018
          return;
4019
        }
4020

4021
        if (successCallback) {
4022
          successCallback();
4023
        }
4024
      });
4025
  };
4026

4027
  return MaximumSelectionLength;
4028
});
4029

4030
S2.define('select2/dropdown',[
4031
  'jquery',
4032
  './utils'
4033
], function ($, Utils) {
4034
  function Dropdown ($element, options) {
4035
    this.$element = $element;
4036
    this.options = options;
4037

4038
    Dropdown.__super__.constructor.call(this);
4039
  }
4040

4041
  Utils.Extend(Dropdown, Utils.Observable);
4042

4043
  Dropdown.prototype.render = function () {
4044
    var $dropdown = $(
4045
      '<span class="select2-dropdown">' +
4046
        '<span class="select2-results"></span>' +
4047
      '</span>'
4048
    );
4049

4050
    $dropdown.attr('dir', this.options.get('dir'));
4051

4052
    this.$dropdown = $dropdown;
4053

4054
    return $dropdown;
4055
  };
4056

4057
  Dropdown.prototype.bind = function () {
4058
    // Should be implemented in subclasses
4059
  };
4060

4061
  Dropdown.prototype.position = function ($dropdown, $container) {
4062
    // Should be implemented in subclasses
4063
  };
4064

4065
  Dropdown.prototype.destroy = function () {
4066
    // Remove the dropdown from the DOM
4067
    this.$dropdown.remove();
4068
  };
4069

4070
  return Dropdown;
4071
});
4072

4073
S2.define('select2/dropdown/search',[
4074
  'jquery',
4075
  '../utils'
4076
], function ($, Utils) {
4077
  function Search () { }
4078

4079
  Search.prototype.render = function (decorated) {
4080
    var $rendered = decorated.call(this);
4081

4082
    var $search = $(
4083
      '<span class="select2-search select2-search--dropdown">' +
4084
        '<input class="select2-search__field" type="search" tabindex="-1"' +
4085
        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
4086
        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
4087
      '</span>'
4088
    );
4089

4090
    this.$searchContainer = $search;
4091
    this.$search = $search.find('input');
4092

4093
    $rendered.prepend($search);
4094

4095
    return $rendered;
4096
  };
4097

4098
  Search.prototype.bind = function (decorated, container, $container) {
4099
    var self = this;
4100

4101
    var resultsId = container.id + '-results';
4102

4103
    decorated.call(this, container, $container);
4104

4105
    this.$search.on('keydown', function (evt) {
4106
      self.trigger('keypress', evt);
4107

4108
      self._keyUpPrevented = evt.isDefaultPrevented();
4109
    });
4110

4111
    // Workaround for browsers which do not support the `input` event
4112
    // This will prevent double-triggering of events for browsers which support
4113
    // both the `keyup` and `input` events.
4114
    this.$search.on('input', function (evt) {
4115
      // Unbind the duplicated `keyup` event
4116
      $(this).off('keyup');
4117
    });
4118

4119
    this.$search.on('keyup input', function (evt) {
4120
      self.handleSearch(evt);
4121
    });
4122

4123
    container.on('open', function () {
4124
      self.$search.attr('tabindex', 0);
4125
      self.$search.attr('aria-controls', resultsId);
4126

4127
      self.$search.trigger('focus');
4128

4129
      window.setTimeout(function () {
4130
        self.$search.trigger('focus');
4131
      }, 0);
4132
    });
4133

4134
    container.on('close', function () {
4135
      self.$search.attr('tabindex', -1);
4136
      self.$search.removeAttr('aria-controls');
4137
      self.$search.removeAttr('aria-activedescendant');
4138

4139
      self.$search.val('');
4140
      self.$search.trigger('blur');
4141
    });
4142

4143
    container.on('focus', function () {
4144
      if (!container.isOpen()) {
4145
        self.$search.trigger('focus');
4146
      }
4147
    });
4148

4149
    container.on('results:all', function (params) {
4150
      if (params.query.term == null || params.query.term === '') {
4151
        var showSearch = self.showSearch(params);
4152

4153
        if (showSearch) {
4154
          self.$searchContainer.removeClass('select2-search--hide');
4155
        } else {
4156
          self.$searchContainer.addClass('select2-search--hide');
4157
        }
4158
      }
4159
    });
4160

4161
    container.on('results:focus', function (params) {
4162
      if (params.data._resultId) {
4163
        self.$search.attr('aria-activedescendant', params.data._resultId);
4164
      } else {
4165
        self.$search.removeAttr('aria-activedescendant');
4166
      }
4167
    });
4168
  };
4169

4170
  Search.prototype.handleSearch = function (evt) {
4171
    if (!this._keyUpPrevented) {
4172
      var input = this.$search.val();
4173

4174
      this.trigger('query', {
4175
        term: input
4176
      });
4177
    }
4178

4179
    this._keyUpPrevented = false;
4180
  };
4181

4182
  Search.prototype.showSearch = function (_, params) {
4183
    return true;
4184
  };
4185

4186
  return Search;
4187
});
4188

4189
S2.define('select2/dropdown/hidePlaceholder',[
4190

4191
], function () {
4192
  function HidePlaceholder (decorated, $element, options, dataAdapter) {
4193
    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
4194

4195
    decorated.call(this, $element, options, dataAdapter);
4196
  }
4197

4198
  HidePlaceholder.prototype.append = function (decorated, data) {
4199
    data.results = this.removePlaceholder(data.results);
4200

4201
    decorated.call(this, data);
4202
  };
4203

4204
  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
4205
    if (typeof placeholder === 'string') {
4206
      placeholder = {
4207
        id: '',
4208
        text: placeholder
4209
      };
4210
    }
4211

4212
    return placeholder;
4213
  };
4214

4215
  HidePlaceholder.prototype.removePlaceholder = function (_, data) {
4216
    var modifiedData = data.slice(0);
4217

4218
    for (var d = data.length - 1; d >= 0; d--) {
4219
      var item = data[d];
4220

4221
      if (this.placeholder.id === item.id) {
4222
        modifiedData.splice(d, 1);
4223
      }
4224
    }
4225

4226
    return modifiedData;
4227
  };
4228

4229
  return HidePlaceholder;
4230
});
4231

4232
S2.define('select2/dropdown/infiniteScroll',[
4233
  'jquery'
4234
], function ($) {
4235
  function InfiniteScroll (decorated, $element, options, dataAdapter) {
4236
    this.lastParams = {};
4237

4238
    decorated.call(this, $element, options, dataAdapter);
4239

4240
    this.$loadingMore = this.createLoadingMore();
4241
    this.loading = false;
4242
  }
4243

4244
  InfiniteScroll.prototype.append = function (decorated, data) {
4245
    this.$loadingMore.remove();
4246
    this.loading = false;
4247

4248
    decorated.call(this, data);
4249

4250
    if (this.showLoadingMore(data)) {
4251
      this.$results.append(this.$loadingMore);
4252
      this.loadMoreIfNeeded();
4253
    }
4254
  };
4255

4256
  InfiniteScroll.prototype.bind = function (decorated, container, $container) {
4257
    var self = this;
4258

4259
    decorated.call(this, container, $container);
4260

4261
    container.on('query', function (params) {
4262
      self.lastParams = params;
4263
      self.loading = true;
4264
    });
4265

4266
    container.on('query:append', function (params) {
4267
      self.lastParams = params;
4268
      self.loading = true;
4269
    });
4270

4271
    this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
4272
  };
4273

4274
  InfiniteScroll.prototype.loadMoreIfNeeded = function () {
4275
    var isLoadMoreVisible = $.contains(
4276
      document.documentElement,
4277
      this.$loadingMore[0]
4278
    );
4279

4280
    if (this.loading || !isLoadMoreVisible) {
4281
      return;
4282
    }
4283

4284
    var currentOffset = this.$results.offset().top +
4285
      this.$results.outerHeight(false);
4286
    var loadingMoreOffset = this.$loadingMore.offset().top +
4287
      this.$loadingMore.outerHeight(false);
4288

4289
    if (currentOffset + 50 >= loadingMoreOffset) {
4290
      this.loadMore();
4291
    }
4292
  };
4293

4294
  InfiniteScroll.prototype.loadMore = function () {
4295
    this.loading = true;
4296

4297
    var params = $.extend({}, {page: 1}, this.lastParams);
4298

4299
    params.page++;
4300

4301
    this.trigger('query:append', params);
4302
  };
4303

4304
  InfiniteScroll.prototype.showLoadingMore = function (_, data) {
4305
    return data.pagination && data.pagination.more;
4306
  };
4307

4308
  InfiniteScroll.prototype.createLoadingMore = function () {
4309
    var $option = $(
4310
      '<li ' +
4311
      'class="select2-results__option select2-results__option--load-more"' +
4312
      'role="option" aria-disabled="true"></li>'
4313
    );
4314

4315
    var message = this.options.get('translations').get('loadingMore');
4316

4317
    $option.html(message(this.lastParams));
4318

4319
    return $option;
4320
  };
4321

4322
  return InfiniteScroll;
4323
});
4324

4325
S2.define('select2/dropdown/attachBody',[
4326
  'jquery',
4327
  '../utils'
4328
], function ($, Utils) {
4329
  function AttachBody (decorated, $element, options) {
4330
    this.$dropdownParent = $(options.get('dropdownParent') || document.body);
4331

4332
    decorated.call(this, $element, options);
4333
  }
4334

4335
  AttachBody.prototype.bind = function (decorated, container, $container) {
4336
    var self = this;
4337

4338
    decorated.call(this, container, $container);
4339

4340
    container.on('open', function () {
4341
      self._showDropdown();
4342
      self._attachPositioningHandler(container);
4343

4344
      // Must bind after the results handlers to ensure correct sizing
4345
      self._bindContainerResultHandlers(container);
4346
    });
4347

4348
    container.on('close', function () {
4349
      self._hideDropdown();
4350
      self._detachPositioningHandler(container);
4351
    });
4352

4353
    this.$dropdownContainer.on('mousedown', function (evt) {
4354
      evt.stopPropagation();
4355
    });
4356
  };
4357

4358
  AttachBody.prototype.destroy = function (decorated) {
4359
    decorated.call(this);
4360

4361
    this.$dropdownContainer.remove();
4362
  };
4363

4364
  AttachBody.prototype.position = function (decorated, $dropdown, $container) {
4365
    // Clone all of the container classes
4366
    $dropdown.attr('class', $container.attr('class'));
4367

4368
    $dropdown.removeClass('select2');
4369
    $dropdown.addClass('select2-container--open');
4370

4371
    $dropdown.css({
4372
      position: 'absolute',
4373
      top: -999999
4374
    });
4375

4376
    this.$container = $container;
4377
  };
4378

4379
  AttachBody.prototype.render = function (decorated) {
4380
    var $container = $('<span></span>');
4381

4382
    var $dropdown = decorated.call(this);
4383
    $container.append($dropdown);
4384

4385
    this.$dropdownContainer = $container;
4386

4387
    return $container;
4388
  };
4389

4390
  AttachBody.prototype._hideDropdown = function (decorated) {
4391
    this.$dropdownContainer.detach();
4392
  };
4393

4394
  AttachBody.prototype._bindContainerResultHandlers =
4395
      function (decorated, container) {
4396

4397
    // These should only be bound once
4398
    if (this._containerResultsHandlersBound) {
4399
      return;
4400
    }
4401

4402
    var self = this;
4403

4404
    container.on('results:all', function () {
4405
      self._positionDropdown();
4406
      self._resizeDropdown();
4407
    });
4408

4409
    container.on('results:append', function () {
4410
      self._positionDropdown();
4411
      self._resizeDropdown();
4412
    });
4413

4414
    container.on('results:message', function () {
4415
      self._positionDropdown();
4416
      self._resizeDropdown();
4417
    });
4418

4419
    container.on('select', function () {
4420
      self._positionDropdown();
4421
      self._resizeDropdown();
4422
    });
4423

4424
    container.on('unselect', function () {
4425
      self._positionDropdown();
4426
      self._resizeDropdown();
4427
    });
4428

4429
    this._containerResultsHandlersBound = true;
4430
  };
4431

4432
  AttachBody.prototype._attachPositioningHandler =
4433
      function (decorated, container) {
4434
    var self = this;
4435

4436
    var scrollEvent = 'scroll.select2.' + container.id;
4437
    var resizeEvent = 'resize.select2.' + container.id;
4438
    var orientationEvent = 'orientationchange.select2.' + container.id;
4439

4440
    var $watchers = this.$container.parents().filter(Utils.hasScroll);
4441
    $watchers.each(function () {
4442
      Utils.StoreData(this, 'select2-scroll-position', {
4443
        x: $(this).scrollLeft(),
4444
        y: $(this).scrollTop()
4445
      });
4446
    });
4447

4448
    $watchers.on(scrollEvent, function (ev) {
4449
      var position = Utils.GetData(this, 'select2-scroll-position');
4450
      $(this).scrollTop(position.y);
4451
    });
4452

4453
    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
4454
      function (e) {
4455
      self._positionDropdown();
4456
      self._resizeDropdown();
4457
    });
4458
  };
4459

4460
  AttachBody.prototype._detachPositioningHandler =
4461
      function (decorated, container) {
4462
    var scrollEvent = 'scroll.select2.' + container.id;
4463
    var resizeEvent = 'resize.select2.' + container.id;
4464
    var orientationEvent = 'orientationchange.select2.' + container.id;
4465

4466
    var $watchers = this.$container.parents().filter(Utils.hasScroll);
4467
    $watchers.off(scrollEvent);
4468

4469
    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
4470
  };
4471

4472
  AttachBody.prototype._positionDropdown = function () {
4473
    var $window = $(window);
4474

4475
    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
4476
    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
4477

4478
    var newDirection = null;
4479

4480
    var offset = this.$container.offset();
4481

4482
    offset.bottom = offset.top + this.$container.outerHeight(false);
4483

4484
    var container = {
4485
      height: this.$container.outerHeight(false)
4486
    };
4487

4488
    container.top = offset.top;
4489
    container.bottom = offset.top + container.height;
4490

4491
    var dropdown = {
4492
      height: this.$dropdown.outerHeight(false)
4493
    };
4494

4495
    var viewport = {
4496
      top: $window.scrollTop(),
4497
      bottom: $window.scrollTop() + $window.height()
4498
    };
4499

4500
    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
4501
    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
4502

4503
    var css = {
4504
      left: offset.left,
4505
      top: container.bottom
4506
    };
4507

4508
    // Determine what the parent element is to use for calculating the offset
4509
    var $offsetParent = this.$dropdownParent;
4510

4511
    // For statically positioned elements, we need to get the element
4512
    // that is determining the offset
4513
    if ($offsetParent.css('position') === 'static') {
4514
      $offsetParent = $offsetParent.offsetParent();
4515
    }
4516

4517
    var parentOffset = {
4518
      top: 0,
4519
      left: 0
4520
    };
4521

4522
    if (
4523
      $.contains(document.body, $offsetParent[0]) ||
4524
      $offsetParent[0].isConnected
4525
      ) {
4526
      parentOffset = $offsetParent.offset();
4527
    }
4528

4529
    css.top -= parentOffset.top;
4530
    css.left -= parentOffset.left;
4531

4532
    if (!isCurrentlyAbove && !isCurrentlyBelow) {
4533
      newDirection = 'below';
4534
    }
4535

4536
    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
4537
      newDirection = 'above';
4538
    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
4539
      newDirection = 'below';
4540
    }
4541

4542
    if (newDirection == 'above' ||
4543
      (isCurrentlyAbove && newDirection !== 'below')) {
4544
      css.top = container.top - parentOffset.top - dropdown.height;
4545
    }
4546

4547
    if (newDirection != null) {
4548
      this.$dropdown
4549
        .removeClass('select2-dropdown--below select2-dropdown--above')
4550
        .addClass('select2-dropdown--' + newDirection);
4551
      this.$container
4552
        .removeClass('select2-container--below select2-container--above')
4553
        .addClass('select2-container--' + newDirection);
4554
    }
4555

4556
    this.$dropdownContainer.css(css);
4557
  };
4558

4559
  AttachBody.prototype._resizeDropdown = function () {
4560
    var css = {
4561
      width: this.$container.outerWidth(false) + 'px'
4562
    };
4563

4564
    if (this.options.get('dropdownAutoWidth')) {
4565
      css.minWidth = css.width;
4566
      css.position = 'relative';
4567
      css.width = 'auto';
4568
    }
4569

4570
    this.$dropdown.css(css);
4571
  };
4572

4573
  AttachBody.prototype._showDropdown = function (decorated) {
4574
    this.$dropdownContainer.appendTo(this.$dropdownParent);
4575

4576
    this._positionDropdown();
4577
    this._resizeDropdown();
4578
  };
4579

4580
  return AttachBody;
4581
});
4582

4583
S2.define('select2/dropdown/minimumResultsForSearch',[
4584

4585
], function () {
4586
  function countResults (data) {
4587
    var count = 0;
4588

4589
    for (var d = 0; d < data.length; d++) {
4590
      var item = data[d];
4591

4592
      if (item.children) {
4593
        count += countResults(item.children);
4594
      } else {
4595
        count++;
4596
      }
4597
    }
4598

4599
    return count;
4600
  }
4601

4602
  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
4603
    this.minimumResultsForSearch = options.get('minimumResultsForSearch');
4604

4605
    if (this.minimumResultsForSearch < 0) {
4606
      this.minimumResultsForSearch = Infinity;
4607
    }
4608

4609
    decorated.call(this, $element, options, dataAdapter);
4610
  }
4611

4612
  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
4613
    if (countResults(params.data.results) < this.minimumResultsForSearch) {
4614
      return false;
4615
    }
4616

4617
    return decorated.call(this, params);
4618
  };
4619

4620
  return MinimumResultsForSearch;
4621
});
4622

4623
S2.define('select2/dropdown/selectOnClose',[
4624
  '../utils'
4625
], function (Utils) {
4626
  function SelectOnClose () { }
4627

4628
  SelectOnClose.prototype.bind = function (decorated, container, $container) {
4629
    var self = this;
4630

4631
    decorated.call(this, container, $container);
4632

4633
    container.on('close', function (params) {
4634
      self._handleSelectOnClose(params);
4635
    });
4636
  };
4637

4638
  SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
4639
    if (params && params.originalSelect2Event != null) {
4640
      var event = params.originalSelect2Event;
4641

4642
      // Don't select an item if the close event was triggered from a select or
4643
      // unselect event
4644
      if (event._type === 'select' || event._type === 'unselect') {
4645
        return;
4646
      }
4647
    }
4648

4649
    var $highlightedResults = this.getHighlightedResults();
4650

4651
    // Only select highlighted results
4652
    if ($highlightedResults.length < 1) {
4653
      return;
4654
    }
4655

4656
    var data = Utils.GetData($highlightedResults[0], 'data');
4657

4658
    // Don't re-select already selected resulte
4659
    if (
4660
      (data.element != null && data.element.selected) ||
4661
      (data.element == null && data.selected)
4662
    ) {
4663
      return;
4664
    }
4665

4666
    this.trigger('select', {
4667
        data: data
4668
    });
4669
  };
4670

4671
  return SelectOnClose;
4672
});
4673

4674
S2.define('select2/dropdown/closeOnSelect',[
4675

4676
], function () {
4677
  function CloseOnSelect () { }
4678

4679
  CloseOnSelect.prototype.bind = function (decorated, container, $container) {
4680
    var self = this;
4681

4682
    decorated.call(this, container, $container);
4683

4684
    container.on('select', function (evt) {
4685
      self._selectTriggered(evt);
4686
    });
4687

4688
    container.on('unselect', function (evt) {
4689
      self._selectTriggered(evt);
4690
    });
4691
  };
4692

4693
  CloseOnSelect.prototype._selectTriggered = function (_, evt) {
4694
    var originalEvent = evt.originalEvent;
4695

4696
    // Don't close if the control key is being held
4697
    if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
4698
      return;
4699
    }
4700

4701
    this.trigger('close', {
4702
      originalEvent: originalEvent,
4703
      originalSelect2Event: evt
4704
    });
4705
  };
4706

4707
  return CloseOnSelect;
4708
});
4709

4710
S2.define('select2/i18n/en',[],function () {
4711
  // English
4712
  return {
4713
    errorLoading: function () {
4714
      return 'The results could not be loaded.';
4715
    },
4716
    inputTooLong: function (args) {
4717
      var overChars = args.input.length - args.maximum;
4718

4719
      var message = 'Please delete ' + overChars + ' character';
4720

4721
      if (overChars != 1) {
4722
        message += 's';
4723
      }
4724

4725
      return message;
4726
    },
4727
    inputTooShort: function (args) {
4728
      var remainingChars = args.minimum - args.input.length;
4729

4730
      var message = 'Please enter ' + remainingChars + ' or more characters';
4731

4732
      return message;
4733
    },
4734
    loadingMore: function () {
4735
      return 'Loading more results…';
4736
    },
4737
    maximumSelected: function (args) {
4738
      var message = 'You can only select ' + args.maximum + ' item';
4739

4740
      if (args.maximum != 1) {
4741
        message += 's';
4742
      }
4743

4744
      return message;
4745
    },
4746
    noResults: function () {
4747
      return 'No results found';
4748
    },
4749
    searching: function () {
4750
      return 'Searching…';
4751
    },
4752
    removeAllItems: function () {
4753
      return 'Remove all items';
4754
    }
4755
  };
4756
});
4757

4758
S2.define('select2/defaults',[
4759
  'jquery',
4760
  'require',
4761

4762
  './results',
4763

4764
  './selection/single',
4765
  './selection/multiple',
4766
  './selection/placeholder',
4767
  './selection/allowClear',
4768
  './selection/search',
4769
  './selection/eventRelay',
4770

4771
  './utils',
4772
  './translation',
4773
  './diacritics',
4774

4775
  './data/select',
4776
  './data/array',
4777
  './data/ajax',
4778
  './data/tags',
4779
  './data/tokenizer',
4780
  './data/minimumInputLength',
4781
  './data/maximumInputLength',
4782
  './data/maximumSelectionLength',
4783

4784
  './dropdown',
4785
  './dropdown/search',
4786
  './dropdown/hidePlaceholder',
4787
  './dropdown/infiniteScroll',
4788
  './dropdown/attachBody',
4789
  './dropdown/minimumResultsForSearch',
4790
  './dropdown/selectOnClose',
4791
  './dropdown/closeOnSelect',
4792

4793
  './i18n/en'
4794
], function ($, require,
4795

4796
             ResultsList,
4797

4798
             SingleSelection, MultipleSelection, Placeholder, AllowClear,
4799
             SelectionSearch, EventRelay,
4800

4801
             Utils, Translation, DIACRITICS,
4802

4803
             SelectData, ArrayData, AjaxData, Tags, Tokenizer,
4804
             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
4805

4806
             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
4807
             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
4808

4809
             EnglishTranslation) {
4810
  function Defaults () {
4811
    this.reset();
4812
  }
4813

4814
  Defaults.prototype.apply = function (options) {
4815
    options = $.extend(true, {}, this.defaults, options);
4816

4817
    if (options.dataAdapter == null) {
4818
      if (options.ajax != null) {
4819
        options.dataAdapter = AjaxData;
4820
      } else if (options.data != null) {
4821
        options.dataAdapter = ArrayData;
4822
      } else {
4823
        options.dataAdapter = SelectData;
4824
      }
4825

4826
      if (options.minimumInputLength > 0) {
4827
        options.dataAdapter = Utils.Decorate(
4828
          options.dataAdapter,
4829
          MinimumInputLength
4830
        );
4831
      }
4832

4833
      if (options.maximumInputLength > 0) {
4834
        options.dataAdapter = Utils.Decorate(
4835
          options.dataAdapter,
4836
          MaximumInputLength
4837
        );
4838
      }
4839

4840
      if (options.maximumSelectionLength > 0) {
4841
        options.dataAdapter = Utils.Decorate(
4842
          options.dataAdapter,
4843
          MaximumSelectionLength
4844
        );
4845
      }
4846

4847
      if (options.tags) {
4848
        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
4849
      }
4850

4851
      if (options.tokenSeparators != null || options.tokenizer != null) {
4852
        options.dataAdapter = Utils.Decorate(
4853
          options.dataAdapter,
4854
          Tokenizer
4855
        );
4856
      }
4857

4858
      if (options.query != null) {
4859
        var Query = require(options.amdBase + 'compat/query');
4860

4861
        options.dataAdapter = Utils.Decorate(
4862
          options.dataAdapter,
4863
          Query
4864
        );
4865
      }
4866

4867
      if (options.initSelection != null) {
4868
        var InitSelection = require(options.amdBase + 'compat/initSelection');
4869

4870
        options.dataAdapter = Utils.Decorate(
4871
          options.dataAdapter,
4872
          InitSelection
4873
        );
4874
      }
4875
    }
4876

4877
    if (options.resultsAdapter == null) {
4878
      options.resultsAdapter = ResultsList;
4879

4880
      if (options.ajax != null) {
4881
        options.resultsAdapter = Utils.Decorate(
4882
          options.resultsAdapter,
4883
          InfiniteScroll
4884
        );
4885
      }
4886

4887
      if (options.placeholder != null) {
4888
        options.resultsAdapter = Utils.Decorate(
4889
          options.resultsAdapter,
4890
          HidePlaceholder
4891
        );
4892
      }
4893

4894
      if (options.selectOnClose) {
4895
        options.resultsAdapter = Utils.Decorate(
4896
          options.resultsAdapter,
4897
          SelectOnClose
4898
        );
4899
      }
4900
    }
4901

4902
    if (options.dropdownAdapter == null) {
4903
      if (options.multiple) {
4904
        options.dropdownAdapter = Dropdown;
4905
      } else {
4906
        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
4907

4908
        options.dropdownAdapter = SearchableDropdown;
4909
      }
4910

4911
      if (options.minimumResultsForSearch !== 0) {
4912
        options.dropdownAdapter = Utils.Decorate(
4913
          options.dropdownAdapter,
4914
          MinimumResultsForSearch
4915
        );
4916
      }
4917

4918
      if (options.closeOnSelect) {
4919
        options.dropdownAdapter = Utils.Decorate(
4920
          options.dropdownAdapter,
4921
          CloseOnSelect
4922
        );
4923
      }
4924

4925
      if (
4926
        options.dropdownCssClass != null ||
4927
        options.dropdownCss != null ||
4928
        options.adaptDropdownCssClass != null
4929
      ) {
4930
        var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4931

4932
        options.dropdownAdapter = Utils.Decorate(
4933
          options.dropdownAdapter,
4934
          DropdownCSS
4935
        );
4936
      }
4937

4938
      options.dropdownAdapter = Utils.Decorate(
4939
        options.dropdownAdapter,
4940
        AttachBody
4941
      );
4942
    }
4943

4944
    if (options.selectionAdapter == null) {
4945
      if (options.multiple) {
4946
        options.selectionAdapter = MultipleSelection;
4947
      } else {
4948
        options.selectionAdapter = SingleSelection;
4949
      }
4950

4951
      // Add the placeholder mixin if a placeholder was specified
4952
      if (options.placeholder != null) {
4953
        options.selectionAdapter = Utils.Decorate(
4954
          options.selectionAdapter,
4955
          Placeholder
4956
        );
4957
      }
4958

4959
      if (options.allowClear) {
4960
        options.selectionAdapter = Utils.Decorate(
4961
          options.selectionAdapter,
4962
          AllowClear
4963
        );
4964
      }
4965

4966
      if (options.multiple) {
4967
        options.selectionAdapter = Utils.Decorate(
4968
          options.selectionAdapter,
4969
          SelectionSearch
4970
        );
4971
      }
4972

4973
      if (
4974
        options.containerCssClass != null ||
4975
        options.containerCss != null ||
4976
        options.adaptContainerCssClass != null
4977
      ) {
4978
        var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4979

4980
        options.selectionAdapter = Utils.Decorate(
4981
          options.selectionAdapter,
4982
          ContainerCSS
4983
        );
4984
      }
4985

4986
      options.selectionAdapter = Utils.Decorate(
4987
        options.selectionAdapter,
4988
        EventRelay
4989
      );
4990
    }
4991

4992
    // If the defaults were not previously applied from an element, it is
4993
    // possible for the language option to have not been resolved
4994
    options.language = this._resolveLanguage(options.language);
4995

4996
    // Always fall back to English since it will always be complete
4997
    options.language.push('en');
4998

4999
    var uniqueLanguages = [];
5000

5001
    for (var l = 0; l < options.language.length; l++) {
5002
      var language = options.language[l];
5003

5004
      if (uniqueLanguages.indexOf(language) === -1) {
5005
        uniqueLanguages.push(language);
5006
      }
5007
    }
5008

5009
    options.language = uniqueLanguages;
5010

5011
    options.translations = this._processTranslations(
5012
      options.language,
5013
      options.debug
5014
    );
5015

5016
    return options;
5017
  };
5018

5019
  Defaults.prototype.reset = function () {
5020
    function stripDiacritics (text) {
5021
      // Used 'uni range + named function' from http://jsperf.com/diacritics/18
5022
      function match(a) {
5023
        return DIACRITICS[a] || a;
5024
      }
5025

5026
      return text.replace(/[^\u0000-\u007E]/g, match);
5027
    }
5028

5029
    function matcher (params, data) {
5030
      // Always return the object if there is nothing to compare
5031
      if ($.trim(params.term) === '') {
5032
        return data;
5033
      }
5034

5035
      // Do a recursive check for options with children
5036
      if (data.children && data.children.length > 0) {
5037
        // Clone the data object if there are children
5038
        // This is required as we modify the object to remove any non-matches
5039
        var match = $.extend(true, {}, data);
5040

5041
        // Check each child of the option
5042
        for (var c = data.children.length - 1; c >= 0; c--) {
5043
          var child = data.children[c];
5044

5045
          var matches = matcher(params, child);
5046

5047
          // If there wasn't a match, remove the object in the array
5048
          if (matches == null) {
5049
            match.children.splice(c, 1);
5050
          }
5051
        }
5052

5053
        // If any children matched, return the new object
5054
        if (match.children.length > 0) {
5055
          return match;
5056
        }
5057

5058
        // If there were no matching children, check just the plain object
5059
        return matcher(params, match);
5060
      }
5061

5062
      var original = stripDiacritics(data.text).toUpperCase();
5063
      var term = stripDiacritics(params.term).toUpperCase();
5064

5065
      // Check if the text contains the term
5066
      if (original.indexOf(term) > -1) {
5067
        return data;
5068
      }
5069

5070
      // If it doesn't contain the term, don't return anything
5071
      return null;
5072
    }
5073

5074
    this.defaults = {
5075
      amdBase: './',
5076
      amdLanguageBase: './i18n/',
5077
      closeOnSelect: true,
5078
      debug: false,
5079
      dropdownAutoWidth: false,
5080
      escapeMarkup: Utils.escapeMarkup,
5081
      language: {},
5082
      matcher: matcher,
5083
      minimumInputLength: 0,
5084
      maximumInputLength: 0,
5085
      maximumSelectionLength: 0,
5086
      minimumResultsForSearch: 0,
5087
      selectOnClose: false,
5088
      scrollAfterSelect: false,
5089
      sorter: function (data) {
5090
        return data;
5091
      },
5092
      templateResult: function (result) {
5093
        return result.text;
5094
      },
5095
      templateSelection: function (selection) {
5096
        return selection.text;
5097
      },
5098
      theme: 'default',
5099
      width: 'resolve'
5100
    };
5101
  };
5102

5103
  Defaults.prototype.applyFromElement = function (options, $element) {
5104
    var optionLanguage = options.language;
5105
    var defaultLanguage = this.defaults.language;
5106
    var elementLanguage = $element.prop('lang');
5107
    var parentLanguage = $element.closest('[lang]').prop('lang');
5108

5109
    var languages = Array.prototype.concat.call(
5110
      this._resolveLanguage(elementLanguage),
5111
      this._resolveLanguage(optionLanguage),
5112
      this._resolveLanguage(defaultLanguage),
5113
      this._resolveLanguage(parentLanguage)
5114
    );
5115

5116
    options.language = languages;
5117

5118
    return options;
5119
  };
5120

5121
  Defaults.prototype._resolveLanguage = function (language) {
5122
    if (!language) {
5123
      return [];
5124
    }
5125

5126
    if ($.isEmptyObject(language)) {
5127
      return [];
5128
    }
5129

5130
    if ($.isPlainObject(language)) {
5131
      return [language];
5132
    }
5133

5134
    var languages;
5135

5136
    if (!$.isArray(language)) {
5137
      languages = [language];
5138
    } else {
5139
      languages = language;
5140
    }
5141

5142
    var resolvedLanguages = [];
5143

5144
    for (var l = 0; l < languages.length; l++) {
5145
      resolvedLanguages.push(languages[l]);
5146

5147
      if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
5148
        // Extract the region information if it is included
5149
        var languageParts = languages[l].split('-');
5150
        var baseLanguage = languageParts[0];
5151

5152
        resolvedLanguages.push(baseLanguage);
5153
      }
5154
    }
5155

5156
    return resolvedLanguages;
5157
  };
5158

5159
  Defaults.prototype._processTranslations = function (languages, debug) {
5160
    var translations = new Translation();
5161

5162
    for (var l = 0; l < languages.length; l++) {
5163
      var languageData = new Translation();
5164

5165
      var language = languages[l];
5166

5167
      if (typeof language === 'string') {
5168
        try {
5169
          // Try to load it with the original name
5170
          languageData = Translation.loadPath(language);
5171
        } catch (e) {
5172
          try {
5173
            // If we couldn't load it, check if it wasn't the full path
5174
            language = this.defaults.amdLanguageBase + language;
5175
            languageData = Translation.loadPath(language);
5176
          } catch (ex) {
5177
            // The translation could not be loaded at all. Sometimes this is
5178
            // because of a configuration problem, other times this can be
5179
            // because of how Select2 helps load all possible translation files
5180
            if (debug && window.console && console.warn) {
5181
              console.warn(
5182
                'Select2: The language file for "' + language + '" could ' +
5183
                'not be automatically loaded. A fallback will be used instead.'
5184
              );
5185
            }
5186
          }
5187
        }
5188
      } else if ($.isPlainObject(language)) {
5189
        languageData = new Translation(language);
5190
      } else {
5191
        languageData = language;
5192
      }
5193

5194
      translations.extend(languageData);
5195
    }
5196

5197
    return translations;
5198
  };
5199

5200
  Defaults.prototype.set = function (key, value) {
5201
    var camelKey = $.camelCase(key);
5202

5203
    var data = {};
5204
    data[camelKey] = value;
5205

5206
    var convertedData = Utils._convertData(data);
5207

5208
    $.extend(true, this.defaults, convertedData);
5209
  };
5210

5211
  var defaults = new Defaults();
5212

5213
  return defaults;
5214
});
5215

5216
S2.define('select2/options',[
5217
  'require',
5218
  'jquery',
5219
  './defaults',
5220
  './utils'
5221
], function (require, $, Defaults, Utils) {
5222
  function Options (options, $element) {
5223
    this.options = options;
5224

5225
    if ($element != null) {
5226
      this.fromElement($element);
5227
    }
5228

5229
    if ($element != null) {
5230
      this.options = Defaults.applyFromElement(this.options, $element);
5231
    }
5232

5233
    this.options = Defaults.apply(this.options);
5234

5235
    if ($element && $element.is('input')) {
5236
      var InputCompat = require(this.get('amdBase') + 'compat/inputData');
5237

5238
      this.options.dataAdapter = Utils.Decorate(
5239
        this.options.dataAdapter,
5240
        InputCompat
5241
      );
5242
    }
5243
  }
5244

5245
  Options.prototype.fromElement = function ($e) {
5246
    var excludedData = ['select2'];
5247

5248
    if (this.options.multiple == null) {
5249
      this.options.multiple = $e.prop('multiple');
5250
    }
5251

5252
    if (this.options.disabled == null) {
5253
      this.options.disabled = $e.prop('disabled');
5254
    }
5255

5256
    if (this.options.dir == null) {
5257
      if ($e.prop('dir')) {
5258
        this.options.dir = $e.prop('dir');
5259
      } else if ($e.closest('[dir]').prop('dir')) {
5260
        this.options.dir = $e.closest('[dir]').prop('dir');
5261
      } else {
5262
        this.options.dir = 'ltr';
5263
      }
5264
    }
5265

5266
    $e.prop('disabled', this.options.disabled);
5267
    $e.prop('multiple', this.options.multiple);
5268

5269
    if (Utils.GetData($e[0], 'select2Tags')) {
5270
      if (this.options.debug && window.console && console.warn) {
5271
        console.warn(
5272
          'Select2: The `data-select2-tags` attribute has been changed to ' +
5273
          'use the `data-data` and `data-tags="true"` attributes and will be ' +
5274
          'removed in future versions of Select2.'
5275
        );
5276
      }
5277

5278
      Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
5279
      Utils.StoreData($e[0], 'tags', true);
5280
    }
5281

5282
    if (Utils.GetData($e[0], 'ajaxUrl')) {
5283
      if (this.options.debug && window.console && console.warn) {
5284
        console.warn(
5285
          'Select2: The `data-ajax-url` attribute has been changed to ' +
5286
          '`data-ajax--url` and support for the old attribute will be removed' +
5287
          ' in future versions of Select2.'
5288
        );
5289
      }
5290

5291
      $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
5292
      Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
5293
    }
5294

5295
    var dataset = {};
5296

5297
    function upperCaseLetter(_, letter) {
5298
      return letter.toUpperCase();
5299
    }
5300

5301
    // Pre-load all of the attributes which are prefixed with `data-`
5302
    for (var attr = 0; attr < $e[0].attributes.length; attr++) {
5303
      var attributeName = $e[0].attributes[attr].name;
5304
      var prefix = 'data-';
5305

5306
      if (attributeName.substr(0, prefix.length) == prefix) {
5307
        // Get the contents of the attribute after `data-`
5308
        var dataName = attributeName.substring(prefix.length);
5309

5310
        // Get the data contents from the consistent source
5311
        // This is more than likely the jQuery data helper
5312
        var dataValue = Utils.GetData($e[0], dataName);
5313

5314
        // camelCase the attribute name to match the spec
5315
        var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
5316

5317
        // Store the data attribute contents into the dataset since
5318
        dataset[camelDataName] = dataValue;
5319
      }
5320
    }
5321

5322
    // Prefer the element's `dataset` attribute if it exists
5323
    // jQuery 1.x does not correctly handle data attributes with multiple dashes
5324
    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
5325
      dataset = $.extend(true, {}, $e[0].dataset, dataset);
5326
    }
5327

5328
    // Prefer our internal data cache if it exists
5329
    var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
5330

5331
    data = Utils._convertData(data);
5332

5333
    for (var key in data) {
5334
      if ($.inArray(key, excludedData) > -1) {
5335
        continue;
5336
      }
5337

5338
      if ($.isPlainObject(this.options[key])) {
5339
        $.extend(this.options[key], data[key]);
5340
      } else {
5341
        this.options[key] = data[key];
5342
      }
5343
    }
5344

5345
    return this;
5346
  };
5347

5348
  Options.prototype.get = function (key) {
5349
    return this.options[key];
5350
  };
5351

5352
  Options.prototype.set = function (key, val) {
5353
    this.options[key] = val;
5354
  };
5355

5356
  return Options;
5357
});
5358

5359
S2.define('select2/core',[
5360
  'jquery',
5361
  './options',
5362
  './utils',
5363
  './keys'
5364
], function ($, Options, Utils, KEYS) {
5365
  var Select2 = function ($element, options) {
5366
    if (Utils.GetData($element[0], 'select2') != null) {
5367
      Utils.GetData($element[0], 'select2').destroy();
5368
    }
5369

5370
    this.$element = $element;
5371

5372
    this.id = this._generateId($element);
5373

5374
    options = options || {};
5375

5376
    this.options = new Options(options, $element);
5377

5378
    Select2.__super__.constructor.call(this);
5379

5380
    // Set up the tabindex
5381

5382
    var tabindex = $element.attr('tabindex') || 0;
5383
    Utils.StoreData($element[0], 'old-tabindex', tabindex);
5384
    $element.attr('tabindex', '-1');
5385

5386
    // Set up containers and adapters
5387

5388
    var DataAdapter = this.options.get('dataAdapter');
5389
    this.dataAdapter = new DataAdapter($element, this.options);
5390

5391
    var $container = this.render();
5392

5393
    this._placeContainer($container);
5394

5395
    var SelectionAdapter = this.options.get('selectionAdapter');
5396
    this.selection = new SelectionAdapter($element, this.options);
5397
    this.$selection = this.selection.render();
5398

5399
    this.selection.position(this.$selection, $container);
5400

5401
    var DropdownAdapter = this.options.get('dropdownAdapter');
5402
    this.dropdown = new DropdownAdapter($element, this.options);
5403
    this.$dropdown = this.dropdown.render();
5404

5405
    this.dropdown.position(this.$dropdown, $container);
5406

5407
    var ResultsAdapter = this.options.get('resultsAdapter');
5408
    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
5409
    this.$results = this.results.render();
5410

5411
    this.results.position(this.$results, this.$dropdown);
5412

5413
    // Bind events
5414

5415
    var self = this;
5416

5417
    // Bind the container to all of the adapters
5418
    this._bindAdapters();
5419

5420
    // Register any DOM event handlers
5421
    this._registerDomEvents();
5422

5423
    // Register any internal event handlers
5424
    this._registerDataEvents();
5425
    this._registerSelectionEvents();
5426
    this._registerDropdownEvents();
5427
    this._registerResultsEvents();
5428
    this._registerEvents();
5429

5430
    // Set the initial state
5431
    this.dataAdapter.current(function (initialData) {
5432
      self.trigger('selection:update', {
5433
        data: initialData
5434
      });
5435
    });
5436

5437
    // Hide the original select
5438
    $element.addClass('select2-hidden-accessible');
5439
    $element.attr('aria-hidden', 'true');
5440

5441
    // Synchronize any monitored attributes
5442
    this._syncAttributes();
5443

5444
    Utils.StoreData($element[0], 'select2', this);
5445

5446
    // Ensure backwards compatibility with $element.data('select2').
5447
    $element.data('select2', this);
5448
  };
5449

5450
  Utils.Extend(Select2, Utils.Observable);
5451

5452
  Select2.prototype._generateId = function ($element) {
5453
    var id = '';
5454

5455
    if ($element.attr('id') != null) {
5456
      id = $element.attr('id');
5457
    } else if ($element.attr('name') != null) {
5458
      id = $element.attr('name') + '-' + Utils.generateChars(2);
5459
    } else {
5460
      id = Utils.generateChars(4);
5461
    }
5462

5463
    id = id.replace(/(:|\.|\[|\]|,)/g, '');
5464
    id = 'select2-' + id;
5465

5466
    return id;
5467
  };
5468

5469
  Select2.prototype._placeContainer = function ($container) {
5470
    $container.insertAfter(this.$element);
5471

5472
    var width = this._resolveWidth(this.$element, this.options.get('width'));
5473

5474
    if (width != null) {
5475
      $container.css('width', width);
5476
    }
5477
  };
5478

5479
  Select2.prototype._resolveWidth = function ($element, method) {
5480
    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
5481

5482
    if (method == 'resolve') {
5483
      var styleWidth = this._resolveWidth($element, 'style');
5484

5485
      if (styleWidth != null) {
5486
        return styleWidth;
5487
      }
5488

5489
      return this._resolveWidth($element, 'element');
5490
    }
5491

5492
    if (method == 'element') {
5493
      var elementWidth = $element.outerWidth(false);
5494

5495
      if (elementWidth <= 0) {
5496
        return 'auto';
5497
      }
5498

5499
      return elementWidth + 'px';
5500
    }
5501

5502
    if (method == 'style') {
5503
      var style = $element.attr('style');
5504

5505
      if (typeof(style) !== 'string') {
5506
        return null;
5507
      }
5508

5509
      var attrs = style.split(';');
5510

5511
      for (var i = 0, l = attrs.length; i < l; i = i + 1) {
5512
        var attr = attrs[i].replace(/\s/g, '');
5513
        var matches = attr.match(WIDTH);
5514

5515
        if (matches !== null && matches.length >= 1) {
5516
          return matches[1];
5517
        }
5518
      }
5519

5520
      return null;
5521
    }
5522

5523
    if (method == 'computedstyle') {
5524
      var computedStyle = window.getComputedStyle($element[0]);
5525

5526
      return computedStyle.width;
5527
    }
5528

5529
    return method;
5530
  };
5531

5532
  Select2.prototype._bindAdapters = function () {
5533
    this.dataAdapter.bind(this, this.$container);
5534
    this.selection.bind(this, this.$container);
5535

5536
    this.dropdown.bind(this, this.$container);
5537
    this.results.bind(this, this.$container);
5538
  };
5539

5540
  Select2.prototype._registerDomEvents = function () {
5541
    var self = this;
5542

5543
    this.$element.on('change.select2', function () {
5544
      self.dataAdapter.current(function (data) {
5545
        self.trigger('selection:update', {
5546
          data: data
5547
        });
5548
      });
5549
    });
5550

5551
    this.$element.on('focus.select2', function (evt) {
5552
      self.trigger('focus', evt);
5553
    });
5554

5555
    this._syncA = Utils.bind(this._syncAttributes, this);
5556
    this._syncS = Utils.bind(this._syncSubtree, this);
5557

5558
    if (this.$element[0].attachEvent) {
5559
      this.$element[0].attachEvent('onpropertychange', this._syncA);
5560
    }
5561

5562
    var observer = window.MutationObserver ||
5563
      window.WebKitMutationObserver ||
5564
      window.MozMutationObserver
5565
    ;
5566

5567
    if (observer != null) {
5568
      this._observer = new observer(function (mutations) {
5569
        self._syncA();
5570
        self._syncS(null, mutations);
5571
      });
5572
      this._observer.observe(this.$element[0], {
5573
        attributes: true,
5574
        childList: true,
5575
        subtree: false
5576
      });
5577
    } else if (this.$element[0].addEventListener) {
5578
      this.$element[0].addEventListener(
5579
        'DOMAttrModified',
5580
        self._syncA,
5581
        false
5582
      );
5583
      this.$element[0].addEventListener(
5584
        'DOMNodeInserted',
5585
        self._syncS,
5586
        false
5587
      );
5588
      this.$element[0].addEventListener(
5589
        'DOMNodeRemoved',
5590
        self._syncS,
5591
        false
5592
      );
5593
    }
5594
  };
5595

5596
  Select2.prototype._registerDataEvents = function () {
5597
    var self = this;
5598

5599
    this.dataAdapter.on('*', function (name, params) {
5600
      self.trigger(name, params);
5601
    });
5602
  };
5603

5604
  Select2.prototype._registerSelectionEvents = function () {
5605
    var self = this;
5606
    var nonRelayEvents = ['toggle', 'focus'];
5607

5608
    this.selection.on('toggle', function () {
5609
      self.toggleDropdown();
5610
    });
5611

5612
    this.selection.on('focus', function (params) {
5613
      self.focus(params);
5614
    });
5615

5616
    this.selection.on('*', function (name, params) {
5617
      if ($.inArray(name, nonRelayEvents) !== -1) {
5618
        return;
5619
      }
5620

5621
      self.trigger(name, params);
5622
    });
5623
  };
5624

5625
  Select2.prototype._registerDropdownEvents = function () {
5626
    var self = this;
5627

5628
    this.dropdown.on('*', function (name, params) {
5629
      self.trigger(name, params);
5630
    });
5631
  };
5632

5633
  Select2.prototype._registerResultsEvents = function () {
5634
    var self = this;
5635

5636
    this.results.on('*', function (name, params) {
5637
      self.trigger(name, params);
5638
    });
5639
  };
5640

5641
  Select2.prototype._registerEvents = function () {
5642
    var self = this;
5643

5644
    this.on('open', function () {
5645
      self.$container.addClass('select2-container--open');
5646
    });
5647

5648
    this.on('close', function () {
5649
      self.$container.removeClass('select2-container--open');
5650
    });
5651

5652
    this.on('enable', function () {
5653
      self.$container.removeClass('select2-container--disabled');
5654
    });
5655

5656
    this.on('disable', function () {
5657
      self.$container.addClass('select2-container--disabled');
5658
    });
5659

5660
    this.on('blur', function () {
5661
      self.$container.removeClass('select2-container--focus');
5662
    });
5663

5664
    this.on('query', function (params) {
5665
      if (!self.isOpen()) {
5666
        self.trigger('open', {});
5667
      }
5668

5669
      this.dataAdapter.query(params, function (data) {
5670
        self.trigger('results:all', {
5671
          data: data,
5672
          query: params
5673
        });
5674
      });
5675
    });
5676

5677
    this.on('query:append', function (params) {
5678
      this.dataAdapter.query(params, function (data) {
5679
        self.trigger('results:append', {
5680
          data: data,
5681
          query: params
5682
        });
5683
      });
5684
    });
5685

5686
    this.on('keypress', function (evt) {
5687
      var key = evt.which;
5688

5689
      if (self.isOpen()) {
5690
        if (key === KEYS.ESC || key === KEYS.TAB ||
5691
            (key === KEYS.UP && evt.altKey)) {
5692
          self.close(evt);
5693

5694
          evt.preventDefault();
5695
        } else if (key === KEYS.ENTER) {
5696
          self.trigger('results:select', {});
5697

5698
          evt.preventDefault();
5699
        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
5700
          self.trigger('results:toggle', {});
5701

5702
          evt.preventDefault();
5703
        } else if (key === KEYS.UP) {
5704
          self.trigger('results:previous', {});
5705

5706
          evt.preventDefault();
5707
        } else if (key === KEYS.DOWN) {
5708
          self.trigger('results:next', {});
5709

5710
          evt.preventDefault();
5711
        }
5712
      } else {
5713
        if (key === KEYS.ENTER || key === KEYS.SPACE ||
5714
            (key === KEYS.DOWN && evt.altKey)) {
5715
          self.open();
5716

5717
          evt.preventDefault();
5718
        }
5719
      }
5720
    });
5721
  };
5722

5723
  Select2.prototype._syncAttributes = function () {
5724
    this.options.set('disabled', this.$element.prop('disabled'));
5725

5726
    if (this.isDisabled()) {
5727
      if (this.isOpen()) {
5728
        this.close();
5729
      }
5730

5731
      this.trigger('disable', {});
5732
    } else {
5733
      this.trigger('enable', {});
5734
    }
5735
  };
5736

5737
  Select2.prototype._isChangeMutation = function (evt, mutations) {
5738
    var changed = false;
5739
    var self = this;
5740

5741
    // Ignore any mutation events raised for elements that aren't options or
5742
    // optgroups. This handles the case when the select element is destroyed
5743
    if (
5744
      evt && evt.target && (
5745
        evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
5746
      )
5747
    ) {
5748
      return;
5749
    }
5750

5751
    if (!mutations) {
5752
      // If mutation events aren't supported, then we can only assume that the
5753
      // change affected the selections
5754
      changed = true;
5755
    } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
5756
      for (var n = 0; n < mutations.addedNodes.length; n++) {
5757
        var node = mutations.addedNodes[n];
5758

5759
        if (node.selected) {
5760
          changed = true;
5761
        }
5762
      }
5763
    } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
5764
      changed = true;
5765
    } else if ($.isArray(mutations)) {
5766
      $.each(mutations, function(evt, mutation) {
5767
        if (self._isChangeMutation(evt, mutation)) {
5768
          // We've found a change mutation.
5769
          // Let's escape from the loop and continue
5770
          changed = true;
5771
          return false;
5772
        }
5773
      });
5774
    }
5775
    return changed;
5776
  };
5777

5778
  Select2.prototype._syncSubtree = function (evt, mutations) {
5779
    var changed = this._isChangeMutation(evt, mutations);
5780
    var self = this;
5781

5782
    // Only re-pull the data if we think there is a change
5783
    if (changed) {
5784
      this.dataAdapter.current(function (currentData) {
5785
        self.trigger('selection:update', {
5786
          data: currentData
5787
        });
5788
      });
5789
    }
5790
  };
5791

5792
  /**
5793
   * Override the trigger method to automatically trigger pre-events when
5794
   * there are events that can be prevented.
5795
   */
5796
  Select2.prototype.trigger = function (name, args) {
5797
    var actualTrigger = Select2.__super__.trigger;
5798
    var preTriggerMap = {
5799
      'open': 'opening',
5800
      'close': 'closing',
5801
      'select': 'selecting',
5802
      'unselect': 'unselecting',
5803
      'clear': 'clearing'
5804
    };
5805

5806
    if (args === undefined) {
5807
      args = {};
5808
    }
5809

5810
    if (name in preTriggerMap) {
5811
      var preTriggerName = preTriggerMap[name];
5812
      var preTriggerArgs = {
5813
        prevented: false,
5814
        name: name,
5815
        args: args
5816
      };
5817

5818
      actualTrigger.call(this, preTriggerName, preTriggerArgs);
5819

5820
      if (preTriggerArgs.prevented) {
5821
        args.prevented = true;
5822

5823
        return;
5824
      }
5825
    }
5826

5827
    actualTrigger.call(this, name, args);
5828
  };
5829

5830
  Select2.prototype.toggleDropdown = function () {
5831
    if (this.isDisabled()) {
5832
      return;
5833
    }
5834

5835
    if (this.isOpen()) {
5836
      this.close();
5837
    } else {
5838
      this.open();
5839
    }
5840
  };
5841

5842
  Select2.prototype.open = function () {
5843
    if (this.isOpen()) {
5844
      return;
5845
    }
5846

5847
    if (this.isDisabled()) {
5848
      return;
5849
    }
5850

5851
    this.trigger('query', {});
5852
  };
5853

5854
  Select2.prototype.close = function (evt) {
5855
    if (!this.isOpen()) {
5856
      return;
5857
    }
5858

5859
    this.trigger('close', { originalEvent : evt });
5860
  };
5861

5862
  /**
5863
   * Helper method to abstract the "enabled" (not "disabled") state of this
5864
   * object.
5865
   *
5866
   * @return {true} if the instance is not disabled.
5867
   * @return {false} if the instance is disabled.
5868
   */
5869
  Select2.prototype.isEnabled = function () {
5870
    return !this.isDisabled();
5871
  };
5872

5873
  /**
5874
   * Helper method to abstract the "disabled" state of this object.
5875
   *
5876
   * @return {true} if the disabled option is true.
5877
   * @return {false} if the disabled option is false.
5878
   */
5879
  Select2.prototype.isDisabled = function () {
5880
    return this.options.get('disabled');
5881
  };
5882

5883
  Select2.prototype.isOpen = function () {
5884
    return this.$container.hasClass('select2-container--open');
5885
  };
5886

5887
  Select2.prototype.hasFocus = function () {
5888
    return this.$container.hasClass('select2-container--focus');
5889
  };
5890

5891
  Select2.prototype.focus = function (data) {
5892
    // No need to re-trigger focus events if we are already focused
5893
    if (this.hasFocus()) {
5894
      return;
5895
    }
5896

5897
    this.$container.addClass('select2-container--focus');
5898
    this.trigger('focus', {});
5899
  };
5900

5901
  Select2.prototype.enable = function (args) {
5902
    if (this.options.get('debug') && window.console && console.warn) {
5903
      console.warn(
5904
        'Select2: The `select2("enable")` method has been deprecated and will' +
5905
        ' be removed in later Select2 versions. Use $element.prop("disabled")' +
5906
        ' instead.'
5907
      );
5908
    }
5909

5910
    if (args == null || args.length === 0) {
5911
      args = [true];
5912
    }
5913

5914
    var disabled = !args[0];
5915

5916
    this.$element.prop('disabled', disabled);
5917
  };
5918

5919
  Select2.prototype.data = function () {
5920
    if (this.options.get('debug') &&
5921
        arguments.length > 0 && window.console && console.warn) {
5922
      console.warn(
5923
        'Select2: Data can no longer be set using `select2("data")`. You ' +
5924
        'should consider setting the value instead using `$element.val()`.'
5925
      );
5926
    }
5927

5928
    var data = [];
5929

5930
    this.dataAdapter.current(function (currentData) {
5931
      data = currentData;
5932
    });
5933

5934
    return data;
5935
  };
5936

5937
  Select2.prototype.val = function (args) {
5938
    if (this.options.get('debug') && window.console && console.warn) {
5939
      console.warn(
5940
        'Select2: The `select2("val")` method has been deprecated and will be' +
5941
        ' removed in later Select2 versions. Use $element.val() instead.'
5942
      );
5943
    }
5944

5945
    if (args == null || args.length === 0) {
5946
      return this.$element.val();
5947
    }
5948

5949
    var newVal = args[0];
5950

5951
    if ($.isArray(newVal)) {
5952
      newVal = $.map(newVal, function (obj) {
5953
        return obj.toString();
5954
      });
5955
    }
5956

5957
    this.$element.val(newVal).trigger('input').trigger('change');
5958
  };
5959

5960
  Select2.prototype.destroy = function () {
5961
    this.$container.remove();
5962

5963
    if (this.$element[0].detachEvent) {
5964
      this.$element[0].detachEvent('onpropertychange', this._syncA);
5965
    }
5966

5967
    if (this._observer != null) {
5968
      this._observer.disconnect();
5969
      this._observer = null;
5970
    } else if (this.$element[0].removeEventListener) {
5971
      this.$element[0]
5972
        .removeEventListener('DOMAttrModified', this._syncA, false);
5973
      this.$element[0]
5974
        .removeEventListener('DOMNodeInserted', this._syncS, false);
5975
      this.$element[0]
5976
        .removeEventListener('DOMNodeRemoved', this._syncS, false);
5977
    }
5978

5979
    this._syncA = null;
5980
    this._syncS = null;
5981

5982
    this.$element.off('.select2');
5983
    this.$element.attr('tabindex',
5984
    Utils.GetData(this.$element[0], 'old-tabindex'));
5985

5986
    this.$element.removeClass('select2-hidden-accessible');
5987
    this.$element.attr('aria-hidden', 'false');
5988
    Utils.RemoveData(this.$element[0]);
5989
    this.$element.removeData('select2');
5990

5991
    this.dataAdapter.destroy();
5992
    this.selection.destroy();
5993
    this.dropdown.destroy();
5994
    this.results.destroy();
5995

5996
    this.dataAdapter = null;
5997
    this.selection = null;
5998
    this.dropdown = null;
5999
    this.results = null;
6000
  };
6001

6002
  Select2.prototype.render = function () {
6003
    var $container = $(
6004
      '<span class="select2 select2-container">' +
6005
        '<span class="selection"></span>' +
6006
        '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
6007
      '</span>'
6008
    );
6009

6010
    $container.attr('dir', this.options.get('dir'));
6011

6012
    this.$container = $container;
6013

6014
    this.$container.addClass('select2-container--' + this.options.get('theme'));
6015

6016
    Utils.StoreData($container[0], 'element', this.$element);
6017

6018
    return $container;
6019
  };
6020

6021
  return Select2;
6022
});
6023

6024
S2.define('select2/compat/utils',[
6025
  'jquery'
6026
], function ($) {
6027
  function syncCssClasses ($dest, $src, adapter) {
6028
    var classes, replacements = [], adapted;
6029

6030
    classes = $.trim($dest.attr('class'));
6031

6032
    if (classes) {
6033
      classes = '' + classes; // for IE which returns object
6034

6035
      $(classes.split(/\s+/)).each(function () {
6036
        // Save all Select2 classes
6037
        if (this.indexOf('select2-') === 0) {
6038
          replacements.push(this);
6039
        }
6040
      });
6041
    }
6042

6043
    classes = $.trim($src.attr('class'));
6044

6045
    if (classes) {
6046
      classes = '' + classes; // for IE which returns object
6047

6048
      $(classes.split(/\s+/)).each(function () {
6049
        // Only adapt non-Select2 classes
6050
        if (this.indexOf('select2-') !== 0) {
6051
          adapted = adapter(this);
6052

6053
          if (adapted != null) {
6054
            replacements.push(adapted);
6055
          }
6056
        }
6057
      });
6058
    }
6059

6060
    $dest.attr('class', replacements.join(' '));
6061
  }
6062

6063
  return {
6064
    syncCssClasses: syncCssClasses
6065
  };
6066
});
6067

6068
S2.define('select2/compat/containerCss',[
6069
  'jquery',
6070
  './utils'
6071
], function ($, CompatUtils) {
6072
  // No-op CSS adapter that discards all classes by default
6073
  function _containerAdapter (clazz) {
6074
    return null;
6075
  }
6076

6077
  function ContainerCSS () { }
6078

6079
  ContainerCSS.prototype.render = function (decorated) {
6080
    var $container = decorated.call(this);
6081

6082
    var containerCssClass = this.options.get('containerCssClass') || '';
6083

6084
    if ($.isFunction(containerCssClass)) {
6085
      containerCssClass = containerCssClass(this.$element);
6086
    }
6087

6088
    var containerCssAdapter = this.options.get('adaptContainerCssClass');
6089
    containerCssAdapter = containerCssAdapter || _containerAdapter;
6090

6091
    if (containerCssClass.indexOf(':all:') !== -1) {
6092
      containerCssClass = containerCssClass.replace(':all:', '');
6093

6094
      var _cssAdapter = containerCssAdapter;
6095

6096
      containerCssAdapter = function (clazz) {
6097
        var adapted = _cssAdapter(clazz);
6098

6099
        if (adapted != null) {
6100
          // Append the old one along with the adapted one
6101
          return adapted + ' ' + clazz;
6102
        }
6103

6104
        return clazz;
6105
      };
6106
    }
6107

6108
    var containerCss = this.options.get('containerCss') || {};
6109

6110
    if ($.isFunction(containerCss)) {
6111
      containerCss = containerCss(this.$element);
6112
    }
6113

6114
    CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
6115

6116
    $container.css(containerCss);
6117
    $container.addClass(containerCssClass);
6118

6119
    return $container;
6120
  };
6121

6122
  return ContainerCSS;
6123
});
6124

6125
S2.define('select2/compat/dropdownCss',[
6126
  'jquery',
6127
  './utils'
6128
], function ($, CompatUtils) {
6129
  // No-op CSS adapter that discards all classes by default
6130
  function _dropdownAdapter (clazz) {
6131
    return null;
6132
  }
6133

6134
  function DropdownCSS () { }
6135

6136
  DropdownCSS.prototype.render = function (decorated) {
6137
    var $dropdown = decorated.call(this);
6138

6139
    var dropdownCssClass = this.options.get('dropdownCssClass') || '';
6140

6141
    if ($.isFunction(dropdownCssClass)) {
6142
      dropdownCssClass = dropdownCssClass(this.$element);
6143
    }
6144

6145
    var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');
6146
    dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;
6147

6148
    if (dropdownCssClass.indexOf(':all:') !== -1) {
6149
      dropdownCssClass = dropdownCssClass.replace(':all:', '');
6150

6151
      var _cssAdapter = dropdownCssAdapter;
6152

6153
      dropdownCssAdapter = function (clazz) {
6154
        var adapted = _cssAdapter(clazz);
6155

6156
        if (adapted != null) {
6157
          // Append the old one along with the adapted one
6158
          return adapted + ' ' + clazz;
6159
        }
6160

6161
        return clazz;
6162
      };
6163
    }
6164

6165
    var dropdownCss = this.options.get('dropdownCss') || {};
6166

6167
    if ($.isFunction(dropdownCss)) {
6168
      dropdownCss = dropdownCss(this.$element);
6169
    }
6170

6171
    CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);
6172

6173
    $dropdown.css(dropdownCss);
6174
    $dropdown.addClass(dropdownCssClass);
6175

6176
    return $dropdown;
6177
  };
6178

6179
  return DropdownCSS;
6180
});
6181

6182
S2.define('select2/compat/initSelection',[
6183
  'jquery'
6184
], function ($) {
6185
  function InitSelection (decorated, $element, options) {
6186
    if (options.get('debug') && window.console && console.warn) {
6187
      console.warn(
6188
        'Select2: The `initSelection` option has been deprecated in favor' +
6189
        ' of a custom data adapter that overrides the `current` method. ' +
6190
        'This method is now called multiple times instead of a single ' +
6191
        'time when the instance is initialized. Support will be removed ' +
6192
        'for the `initSelection` option in future versions of Select2'
6193
      );
6194
    }
6195

6196
    this.initSelection = options.get('initSelection');
6197
    this._isInitialized = false;
6198

6199
    decorated.call(this, $element, options);
6200
  }
6201

6202
  InitSelection.prototype.current = function (decorated, callback) {
6203
    var self = this;
6204

6205
    if (this._isInitialized) {
6206
      decorated.call(this, callback);
6207

6208
      return;
6209
    }
6210

6211
    this.initSelection.call(null, this.$element, function (data) {
6212
      self._isInitialized = true;
6213

6214
      if (!$.isArray(data)) {
6215
        data = [data];
6216
      }
6217

6218
      callback(data);
6219
    });
6220
  };
6221

6222
  return InitSelection;
6223
});
6224

6225
S2.define('select2/compat/inputData',[
6226
  'jquery',
6227
  '../utils'
6228
], function ($, Utils) {
6229
  function InputData (decorated, $element, options) {
6230
    this._currentData = [];
6231
    this._valueSeparator = options.get('valueSeparator') || ',';
6232

6233
    if ($element.prop('type') === 'hidden') {
6234
      if (options.get('debug') && console && console.warn) {
6235
        console.warn(
6236
          'Select2: Using a hidden input with Select2 is no longer ' +
6237
          'supported and may stop working in the future. It is recommended ' +
6238
          'to use a `<select>` element instead.'
6239
        );
6240
      }
6241
    }
6242

6243
    decorated.call(this, $element, options);
6244
  }
6245

6246
  InputData.prototype.current = function (_, callback) {
6247
    function getSelected (data, selectedIds) {
6248
      var selected = [];
6249

6250
      if (data.selected || $.inArray(data.id, selectedIds) !== -1) {
6251
        data.selected = true;
6252
        selected.push(data);
6253
      } else {
6254
        data.selected = false;
6255
      }
6256

6257
      if (data.children) {
6258
        selected.push.apply(selected, getSelected(data.children, selectedIds));
6259
      }
6260

6261
      return selected;
6262
    }
6263

6264
    var selected = [];
6265

6266
    for (var d = 0; d < this._currentData.length; d++) {
6267
      var data = this._currentData[d];
6268

6269
      selected.push.apply(
6270
        selected,
6271
        getSelected(
6272
          data,
6273
          this.$element.val().split(
6274
            this._valueSeparator
6275
          )
6276
        )
6277
      );
6278
    }
6279

6280
    callback(selected);
6281
  };
6282

6283
  InputData.prototype.select = function (_, data) {
6284
    if (!this.options.get('multiple')) {
6285
      this.current(function (allData) {
6286
        $.map(allData, function (data) {
6287
          data.selected = false;
6288
        });
6289
      });
6290

6291
      this.$element.val(data.id);
6292
      this.$element.trigger('input').trigger('change');
6293
    } else {
6294
      var value = this.$element.val();
6295
      value += this._valueSeparator + data.id;
6296

6297
      this.$element.val(value);
6298
      this.$element.trigger('input').trigger('change');
6299
    }
6300
  };
6301

6302
  InputData.prototype.unselect = function (_, data) {
6303
    var self = this;
6304

6305
    data.selected = false;
6306

6307
    this.current(function (allData) {
6308
      var values = [];
6309

6310
      for (var d = 0; d < allData.length; d++) {
6311
        var item = allData[d];
6312

6313
        if (data.id == item.id) {
6314
          continue;
6315
        }
6316

6317
        values.push(item.id);
6318
      }
6319

6320
      self.$element.val(values.join(self._valueSeparator));
6321
      self.$element.trigger('input').trigger('change');
6322
    });
6323
  };
6324

6325
  InputData.prototype.query = function (_, params, callback) {
6326
    var results = [];
6327

6328
    for (var d = 0; d < this._currentData.length; d++) {
6329
      var data = this._currentData[d];
6330

6331
      var matches = this.matches(params, data);
6332

6333
      if (matches !== null) {
6334
        results.push(matches);
6335
      }
6336
    }
6337

6338
    callback({
6339
      results: results
6340
    });
6341
  };
6342

6343
  InputData.prototype.addOptions = function (_, $options) {
6344
    var options = $.map($options, function ($option) {
6345
      return Utils.GetData($option[0], 'data');
6346
    });
6347

6348
    this._currentData.push.apply(this._currentData, options);
6349
  };
6350

6351
  return InputData;
6352
});
6353

6354
S2.define('select2/compat/matcher',[
6355
  'jquery'
6356
], function ($) {
6357
  function oldMatcher (matcher) {
6358
    function wrappedMatcher (params, data) {
6359
      var match = $.extend(true, {}, data);
6360

6361
      if (params.term == null || $.trim(params.term) === '') {
6362
        return match;
6363
      }
6364

6365
      if (data.children) {
6366
        for (var c = data.children.length - 1; c >= 0; c--) {
6367
          var child = data.children[c];
6368

6369
          // Check if the child object matches
6370
          // The old matcher returned a boolean true or false
6371
          var doesMatch = matcher(params.term, child.text, child);
6372

6373
          // If the child didn't match, pop it off
6374
          if (!doesMatch) {
6375
            match.children.splice(c, 1);
6376
          }
6377
        }
6378

6379
        if (match.children.length > 0) {
6380
          return match;
6381
        }
6382
      }
6383

6384
      if (matcher(params.term, data.text, data)) {
6385
        return match;
6386
      }
6387

6388
      return null;
6389
    }
6390

6391
    return wrappedMatcher;
6392
  }
6393

6394
  return oldMatcher;
6395
});
6396

6397
S2.define('select2/compat/query',[
6398

6399
], function () {
6400
  function Query (decorated, $element, options) {
6401
    if (options.get('debug') && window.console && console.warn) {
6402
      console.warn(
6403
        'Select2: The `query` option has been deprecated in favor of a ' +
6404
        'custom data adapter that overrides the `query` method. Support ' +
6405
        'will be removed for the `query` option in future versions of ' +
6406
        'Select2.'
6407
      );
6408
    }
6409

6410
    decorated.call(this, $element, options);
6411
  }
6412

6413
  Query.prototype.query = function (_, params, callback) {
6414
    params.callback = callback;
6415

6416
    var query = this.options.get('query');
6417

6418
    query.call(null, params);
6419
  };
6420

6421
  return Query;
6422
});
6423

6424
S2.define('select2/dropdown/attachContainer',[
6425

6426
], function () {
6427
  function AttachContainer (decorated, $element, options) {
6428
    decorated.call(this, $element, options);
6429
  }
6430

6431
  AttachContainer.prototype.position =
6432
    function (decorated, $dropdown, $container) {
6433
    var $dropdownContainer = $container.find('.dropdown-wrapper');
6434
    $dropdownContainer.append($dropdown);
6435

6436
    $dropdown.addClass('select2-dropdown--below');
6437
    $container.addClass('select2-container--below');
6438
  };
6439

6440
  return AttachContainer;
6441
});
6442

6443
S2.define('select2/dropdown/stopPropagation',[
6444

6445
], function () {
6446
  function StopPropagation () { }
6447

6448
  StopPropagation.prototype.bind = function (decorated, container, $container) {
6449
    decorated.call(this, container, $container);
6450

6451
    var stoppedEvents = [
6452
    'blur',
6453
    'change',
6454
    'click',
6455
    'dblclick',
6456
    'focus',
6457
    'focusin',
6458
    'focusout',
6459
    'input',
6460
    'keydown',
6461
    'keyup',
6462
    'keypress',
6463
    'mousedown',
6464
    'mouseenter',
6465
    'mouseleave',
6466
    'mousemove',
6467
    'mouseover',
6468
    'mouseup',
6469
    'search',
6470
    'touchend',
6471
    'touchstart'
6472
    ];
6473

6474
    this.$dropdown.on(stoppedEvents.join(' '), function (evt) {
6475
      evt.stopPropagation();
6476
    });
6477
  };
6478

6479
  return StopPropagation;
6480
});
6481

6482
S2.define('select2/selection/stopPropagation',[
6483

6484
], function () {
6485
  function StopPropagation () { }
6486

6487
  StopPropagation.prototype.bind = function (decorated, container, $container) {
6488
    decorated.call(this, container, $container);
6489

6490
    var stoppedEvents = [
6491
      'blur',
6492
      'change',
6493
      'click',
6494
      'dblclick',
6495
      'focus',
6496
      'focusin',
6497
      'focusout',
6498
      'input',
6499
      'keydown',
6500
      'keyup',
6501
      'keypress',
6502
      'mousedown',
6503
      'mouseenter',
6504
      'mouseleave',
6505
      'mousemove',
6506
      'mouseover',
6507
      'mouseup',
6508
      'search',
6509
      'touchend',
6510
      'touchstart'
6511
    ];
6512

6513
    this.$selection.on(stoppedEvents.join(' '), function (evt) {
6514
      evt.stopPropagation();
6515
    });
6516
  };
6517

6518
  return StopPropagation;
6519
});
6520

6521
/*!
6522
 * jQuery Mousewheel 3.1.13
6523
 *
6524
 * Copyright jQuery Foundation and other contributors
6525
 * Released under the MIT license
6526
 * http://jquery.org/license
6527
 */
6528

6529
(function (factory) {
6530
    if ( typeof S2.define === 'function' && S2.define.amd ) {
6531
        // AMD. Register as an anonymous module.
6532
        S2.define('jquery-mousewheel',['jquery'], factory);
6533
    } else if (typeof exports === 'object') {
6534
        // Node/CommonJS style for Browserify
6535
        module.exports = factory;
6536
    } else {
6537
        // Browser globals
6538
        factory(jQuery);
6539
    }
6540
}(function ($) {
6541

6542
    var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
6543
        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
6544
                    ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
6545
        slice  = Array.prototype.slice,
6546
        nullLowestDeltaTimeout, lowestDelta;
6547

6548
    if ( $.event.fixHooks ) {
6549
        for ( var i = toFix.length; i; ) {
6550
            $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
6551
        }
6552
    }
6553

6554
    var special = $.event.special.mousewheel = {
6555
        version: '3.1.12',
6556

6557
        setup: function() {
6558
            if ( this.addEventListener ) {
6559
                for ( var i = toBind.length; i; ) {
6560
                    this.addEventListener( toBind[--i], handler, false );
6561
                }
6562
            } else {
6563
                this.onmousewheel = handler;
6564
            }
6565
            // Store the line height and page height for this particular element
6566
            $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
6567
            $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
6568
        },
6569

6570
        teardown: function() {
6571
            if ( this.removeEventListener ) {
6572
                for ( var i = toBind.length; i; ) {
6573
                    this.removeEventListener( toBind[--i], handler, false );
6574
                }
6575
            } else {
6576
                this.onmousewheel = null;
6577
            }
6578
            // Clean up the data we added to the element
6579
            $.removeData(this, 'mousewheel-line-height');
6580
            $.removeData(this, 'mousewheel-page-height');
6581
        },
6582

6583
        getLineHeight: function(elem) {
6584
            var $elem = $(elem),
6585
                $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
6586
            if (!$parent.length) {
6587
                $parent = $('body');
6588
            }
6589
            return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
6590
        },
6591

6592
        getPageHeight: function(elem) {
6593
            return $(elem).height();
6594
        },
6595

6596
        settings: {
6597
            adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
6598
            normalizeOffset: true  // calls getBoundingClientRect for each event
6599
        }
6600
    };
6601

6602
    $.fn.extend({
6603
        mousewheel: function(fn) {
6604
            return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
6605
        },
6606

6607
        unmousewheel: function(fn) {
6608
            return this.unbind('mousewheel', fn);
6609
        }
6610
    });
6611

6612

6613
    function handler(event) {
6614
        var orgEvent   = event || window.event,
6615
            args       = slice.call(arguments, 1),
6616
            delta      = 0,
6617
            deltaX     = 0,
6618
            deltaY     = 0,
6619
            absDelta   = 0,
6620
            offsetX    = 0,
6621
            offsetY    = 0;
6622
        event = $.event.fix(orgEvent);
6623
        event.type = 'mousewheel';
6624

6625
        // Old school scrollwheel delta
6626
        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }
6627
        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }
6628
        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }
6629
        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
6630

6631
        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
6632
        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
6633
            deltaX = deltaY * -1;
6634
            deltaY = 0;
6635
        }
6636

6637
        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
6638
        delta = deltaY === 0 ? deltaX : deltaY;
6639

6640
        // New school wheel delta (wheel event)
6641
        if ( 'deltaY' in orgEvent ) {
6642
            deltaY = orgEvent.deltaY * -1;
6643
            delta  = deltaY;
6644
        }
6645
        if ( 'deltaX' in orgEvent ) {
6646
            deltaX = orgEvent.deltaX;
6647
            if ( deltaY === 0 ) { delta  = deltaX * -1; }
6648
        }
6649

6650
        // No change actually happened, no reason to go any further
6651
        if ( deltaY === 0 && deltaX === 0 ) { return; }
6652

6653
        // Need to convert lines and pages to pixels if we aren't already in pixels
6654
        // There are three delta modes:
6655
        //   * deltaMode 0 is by pixels, nothing to do
6656
        //   * deltaMode 1 is by lines
6657
        //   * deltaMode 2 is by pages
6658
        if ( orgEvent.deltaMode === 1 ) {
6659
            var lineHeight = $.data(this, 'mousewheel-line-height');
6660
            delta  *= lineHeight;
6661
            deltaY *= lineHeight;
6662
            deltaX *= lineHeight;
6663
        } else if ( orgEvent.deltaMode === 2 ) {
6664
            var pageHeight = $.data(this, 'mousewheel-page-height');
6665
            delta  *= pageHeight;
6666
            deltaY *= pageHeight;
6667
            deltaX *= pageHeight;
6668
        }
6669

6670
        // Store lowest absolute delta to normalize the delta values
6671
        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
6672

6673
        if ( !lowestDelta || absDelta < lowestDelta ) {
6674
            lowestDelta = absDelta;
6675

6676
            // Adjust older deltas if necessary
6677
            if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
6678
                lowestDelta /= 40;
6679
            }
6680
        }
6681

6682
        // Adjust older deltas if necessary
6683
        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
6684
            // Divide all the things by 40!
6685
            delta  /= 40;
6686
            deltaX /= 40;
6687
            deltaY /= 40;
6688
        }
6689

6690
        // Get a whole, normalized value for the deltas
6691
        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);
6692
        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
6693
        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
6694

6695
        // Normalise offsetX and offsetY properties
6696
        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
6697
            var boundingRect = this.getBoundingClientRect();
6698
            offsetX = event.clientX - boundingRect.left;
6699
            offsetY = event.clientY - boundingRect.top;
6700
        }
6701

6702
        // Add information to the event object
6703
        event.deltaX = deltaX;
6704
        event.deltaY = deltaY;
6705
        event.deltaFactor = lowestDelta;
6706
        event.offsetX = offsetX;
6707
        event.offsetY = offsetY;
6708
        // Go ahead and set deltaMode to 0 since we converted to pixels
6709
        // Although this is a little odd since we overwrite the deltaX/Y
6710
        // properties with normalized deltas.
6711
        event.deltaMode = 0;
6712

6713
        // Add event and delta to the front of the arguments
6714
        args.unshift(event, delta, deltaX, deltaY);
6715

6716
        // Clearout lowestDelta after sometime to better
6717
        // handle multiple device types that give different
6718
        // a different lowestDelta
6719
        // Ex: trackpad = 3 and mouse wheel = 120
6720
        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
6721
        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
6722

6723
        return ($.event.dispatch || $.event.handle).apply(this, args);
6724
    }
6725

6726
    function nullLowestDelta() {
6727
        lowestDelta = null;
6728
    }
6729

6730
    function shouldAdjustOldDeltas(orgEvent, absDelta) {
6731
        // If this is an older event and the delta is divisable by 120,
6732
        // then we are assuming that the browser is treating this as an
6733
        // older mouse wheel event and that we should divide the deltas
6734
        // by 40 to try and get a more usable deltaFactor.
6735
        // Side note, this actually impacts the reported scroll distance
6736
        // in older browsers and can cause scrolling to be slower than native.
6737
        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
6738
        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
6739
    }
6740

6741
}));
6742

6743
S2.define('jquery.select2',[
6744
  'jquery',
6745
  'jquery-mousewheel',
6746

6747
  './select2/core',
6748
  './select2/defaults',
6749
  './select2/utils'
6750
], function ($, _, Select2, Defaults, Utils) {
6751
  if ($.fn.select2 == null) {
6752
    // All methods that should return the element
6753
    var thisMethods = ['open', 'close', 'destroy'];
6754

6755
    $.fn.select2 = function (options) {
6756
      options = options || {};
6757

6758
      if (typeof options === 'object') {
6759
        this.each(function () {
6760
          var instanceOptions = $.extend(true, {}, options);
6761

6762
          var instance = new Select2($(this), instanceOptions);
6763
        });
6764

6765
        return this;
6766
      } else if (typeof options === 'string') {
6767
        var ret;
6768
        var args = Array.prototype.slice.call(arguments, 1);
6769

6770
        this.each(function () {
6771
          var instance = Utils.GetData(this, 'select2');
6772

6773
          if (instance == null && window.console && console.error) {
6774
            console.error(
6775
              'The select2(\'' + options + '\') method was called on an ' +
6776
              'element that is not using Select2.'
6777
            );
6778
          }
6779

6780
          ret = instance[options].apply(instance, args);
6781
        });
6782

6783
        // Check if we should be returning `this`
6784
        if ($.inArray(options, thisMethods) > -1) {
6785
          return this;
6786
        }
6787

6788
        return ret;
6789
      } else {
6790
        throw new Error('Invalid arguments for Select2: ' + options);
6791
      }
6792
    };
6793
  }
6794

6795
  if ($.fn.select2.defaults == null) {
6796
    $.fn.select2.defaults = Defaults;
6797
  }
6798

6799
  return Select2;
6800
});
6801

6802
  // Return the AMD loader configuration so it can be used outside of this file
6803
  return {
6804
    define: S2.define,
6805
    require: S2.require
6806
  };
6807
}());
6808

6809
  // Autoload the jQuery bindings
6810
  // We know that all of the modules exist above this, so we're safe
6811
  var select2 = S2.require('jquery.select2');
6812

6813
  // Hold the AMD module references on the jQuery function that was just loaded
6814
  // This allows Select2 to use the internal loader outside of this file, such
6815
  // as in the language files.
6816
  jQuery.fn.select2.amd = S2;
6817

6818
  // Return the Select2 instance for anyone who is importing it.
6819
  return select2;
6820
}));
6821

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.