All user data for FoundryVTT. Includes worlds, systems, modules, and any asset in the "foundryuserdata" directory. Does NOT include the FoundryVTT installation itself.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6217 lines
166 KiB

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