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