/*!
 * Select2 4.0.3
 * https://select2.github.io
 *
 * Released under the MIT license
 * https://github.com/select2/select2/blob/master/LICENSE.md
 */
(function (factory) {
  if (typeof define === 'function' && define.amd) {
	// AMD. Register as an anonymous module.
	define(['jquery'], factory);
  } else if (typeof module === 'object' && module.exports) {
	// Node/CommonJS
	module.exports = function (root, jQuery) {
	  if (jQuery === undefined) {
		// require('jQuery') returns a factory that requires window to
		// build a jQuery instance, we normalize how we use modules
		// that require this pattern but the window provided is a noop
		// if it's defined (how jquery works)
		if (typeof window !== 'undefined') {
		  jQuery = require('jquery');
		}
		else {
		  jQuery = require('jquery')(root);
		}
	  }
	  factory(jQuery);
	  return jQuery;
	};
  } else {
	// Browser globals
	factory(jQuery);
  }
} (function (jQuery) {
  // This is needed so we can catch the AMD loader configuration and use it
  // The inner file should be wrapped (by `banner.start.js`) in a function that
  // returns the AMD loader references.
  var S2 =(function () {
  // Restore the Select2 AMD loader so it can be used
  // Needed mostly in the language files, where the loader is not inserted
  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
	var S2 = jQuery.fn.select2.amd;
  }
var S2;(function () { if (!S2 || !S2.requirejs) {
if (!S2) { S2 = {}; } else { require = S2; }
/**
 * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/jrburke/almond for details
 */
//Going sloppy to avoid 'use strict' string cost, but strict practices should
//be followed.
/*jslint sloppy: true */
/*global setTimeout: false */

var requirejs, require, define;
(function (undef) {
	var main, req, makeMap, handlers,
		defined = {},
		waiting = {},
		config = {},
		defining = {},
		hasOwn = Object.prototype.hasOwnProperty,
		aps = [].slice,
		jsSuffixRegExp = /\.js$/;

	function hasProp(obj, prop) {
		return hasOwn.call(obj, prop);
	}

	/**
	 * Given a relative module name, like ./something, normalize it to
	 * a real name that can be mapped to a path.
	 * @param {String} name the relative name
	 * @param {String} baseName a real name that the name arg is relative
	 * to.
	 * @returns {String} normalized name
	 */
	function normalize(name, baseName) {
		var nameParts, nameSegment, mapValue, foundMap, lastIndex,
			foundI, foundStarMap, starI, i, j, part,
			baseParts = baseName && baseName.split("/"),
			map = config.map,
			starMap = (map && map['*']) || {};

		//Adjust any relative paths.
		if (name && name.charAt(0) === ".") {
			//If have a base name, try to normalize against it,
			//otherwise, assume it is a top-level require that will
			//be relative to baseUrl in the end.
			if (baseName) {
				name = name.split('/');
				lastIndex = name.length - 1;

				// Node .js allowance:
				if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
					name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
				}

				//Lop off the last part of baseParts, so that . matches the
				//"directory" and not name of the baseName's module. For instance,
				//baseName of "one/two/three", maps to "one/two/three.js", but we
				//want the directory, "one/two" for this normalization.
				name = baseParts.slice(0, baseParts.length - 1).concat(name);

				//start trimDots
				for (i = 0; i < name.length; i += 1) {
					part = name[i];
					if (part === ".") {
						name.splice(i, 1);
						i -= 1;
					} else if (part === "..") {
						if (i === 1 && (name[2] === '..' || name[0] === '..')) {
							//End of the line. Keep at least one non-dot
							//path segment at the front so it can be mapped
							//correctly to disk. Otherwise, there is likely
							//no path mapping for a path starting with '..'.
							//This can still fail, but catches the most reasonable
							//uses of ..
							break;
						} else if (i > 0) {
							name.splice(i - 1, 2);
							i -= 2;
						}
					}
				}
				//end trimDots

				name = name.join("/");
			} else if (name.indexOf('./') === 0) {
				// No baseName, so this is ID is resolved relative
				// to baseUrl, pull off the leading dot.
				name = name.substring(2);
			}
		}

		//Apply map config if available.
		if ((baseParts || starMap) && map) {
			nameParts = name.split('/');

			for (i = nameParts.length; i > 0; i -= 1) {
				nameSegment = nameParts.slice(0, i).join("/");

				if (baseParts) {
					//Find the longest baseName segment match in the config.
					//So, do joins on the biggest to smallest lengths of baseParts.
					for (j = baseParts.length; j > 0; j -= 1) {
						mapValue = map[baseParts.slice(0, j).join('/')];

						//baseName segment has  config, find if it has one for
						//this name.
						if (mapValue) {
							mapValue = mapValue[nameSegment];
							if (mapValue) {
								//Match, update name to the new value.
								foundMap = mapValue;
								foundI = i;
								break;
							}
						}
					}
				}

				if (foundMap) {
					break;
				}

				//Check for a star map match, but just hold on to it,
				//if there is a shorter segment match later in a matching
				//config, then favor over this star map.
				if (!foundStarMap && starMap && starMap[nameSegment]) {
					foundStarMap = starMap[nameSegment];
					starI = i;
				}
			}

			if (!foundMap && foundStarMap) {
				foundMap = foundStarMap;
				foundI = starI;
			}

			if (foundMap) {
				nameParts.splice(0, foundI, foundMap);
				name = nameParts.join('/');
			}
		}

		return name;
	}

	function makeRequire(relName, forceSync) {
		return function () {
			//A version of a require function that passes a moduleName
			//value for items that may need to
			//look up paths relative to the moduleName
			var args = aps.call(arguments, 0);

			//If first arg is not require('string'), and there is only
			//one arg, it is the array form without a callback. Insert
			//a null so that the following concat is correct.
			if (typeof args[0] !== 'string' && args.length === 1) {
				args.push(null);
			}
			return req.apply(undef, args.concat([relName, forceSync]));
		};
	}

	function makeNormalize(relName) {
		return function (name) {
			return normalize(name, relName);
		};
	}

	function makeLoad(depName) {
		return function (value) {
			defined[depName] = value;
		};
	}

	function callDep(name) {
		if (hasProp(waiting, name)) {
			var args = waiting[name];
			delete waiting[name];
			defining[name] = true;
			main.apply(undef, args);
		}

		if (!hasProp(defined, name) && !hasProp(defining, name)) {
			throw new Error('No ' + name);
		}
		return defined[name];
	}

	//Turns a plugin!resource to [plugin, resource]
	//with the plugin being undefined if the name
	//did not have a plugin prefix.
	function splitPrefix(name) {
		var prefix,
			index = name ? name.indexOf('!') : -1;
		if (index > -1) {
			prefix = name.substring(0, index);
			name = name.substring(index + 1, name.length);
		}
		return [prefix, name];
	}

	/**
	 * Makes a name map, normalizing the name, and using a plugin
	 * for normalization if necessary. Grabs a ref to plugin
	 * too, as an optimization.
	 */
	makeMap = function (name, relName) {
		var plugin,
			parts = splitPrefix(name),
			prefix = parts[0];

		name = parts[1];

		if (prefix) {
			prefix = normalize(prefix, relName);
			plugin = callDep(prefix);
		}

		//Normalize according
		if (prefix) {
			if (plugin && plugin.normalize) {
				name = plugin.normalize(name, makeNormalize(relName));
			} else {
				name = normalize(name, relName);
			}
		} else {
			name = normalize(name, relName);
			parts = splitPrefix(name);
			prefix = parts[0];
			name = parts[1];
			if (prefix) {
				plugin = callDep(prefix);
			}
		}

		//Using ridiculous property names for space reasons
		return {
			f: prefix ? prefix + '!' + name : name, //fullName
			n: name,
			pr: prefix,
			p: plugin
		};
	};

	function makeConfig(name) {
		return function () {
			return (config && config.config && config.config[name]) || {};
		};
	}

	handlers = {
		require: function (name) {
			return makeRequire(name);
		},
		exports: function (name) {
			var e = defined[name];
			if (typeof e !== 'undefined') {
				return e;
			} else {
				return (defined[name] = {});
			}
		},
		module: function (name) {
			return {
				id: name,
				uri: '',
				exports: defined[name],
				config: makeConfig(name)
			};
		}
	};

	main = function (name, deps, callback, relName) {
		var cjsModule, depName, ret, map, i,
			args = [],
			callbackType = typeof callback,
			usingExports;

		//Use name if no relName
		relName = relName || name;

		//Call the callback to define the module, if necessary.
		if (callbackType === 'undefined' || callbackType === 'function') {
			//Pull out the defined dependencies and pass the ordered
			//values to the callback.
			//Default to [require, exports, module] if no deps
			deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
			for (i = 0; i < deps.length; i += 1) {
				map = makeMap(deps[i], relName);
				depName = map.f;

				//Fast path CommonJS standard dependencies.
				if (depName === "require") {
					args[i] = handlers.require(name);
				} else if (depName === "exports") {
					//CommonJS module spec 1.1
					args[i] = handlers.exports(name);
					usingExports = true;
				} else if (depName === "module") {
					//CommonJS module spec 1.1
					cjsModule = args[i] = handlers.module(name);
				} else if (hasProp(defined, depName) ||
						   hasProp(waiting, depName) ||
						   hasProp(defining, depName)) {
					args[i] = callDep(depName);
				} else if (map.p) {
					map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
					args[i] = defined[depName];
				} else {
					throw new Error(name + ' missing ' + depName);
				}
			}

			ret = callback ? callback.apply(defined[name], args) : undefined;

			if (name) {
				//If setting exports via "module" is in play,
				//favor that over return value and exports. After that,
				//favor a non-undefined return value over exports use.
				if (cjsModule && cjsModule.exports !== undef &&
						cjsModule.exports !== defined[name]) {
					defined[name] = cjsModule.exports;
				} else if (ret !== undef || !usingExports) {
					//Use the return value from the function.
					defined[name] = ret;
				}
			}
		} else if (name) {
			//May just be an object definition for the module. Only
			//worry about defining if have a module name.
			defined[name] = callback;
		}
	};

	requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
		if (typeof deps === "string") {
			if (handlers[deps]) {
				//callback in this case is really relName
				return handlers[deps](callback);
			}
			//Just return the module wanted. In this scenario, the
			//deps arg is the module name, and second arg (if passed)
			//is just the relName.
			//Normalize module name, if it contains . or ..
			return callDep(makeMap(deps, callback).f);
		} else if (!deps.splice) {
			//deps is a config object, not an array.
			config = deps;
			if (config.deps) {
				req(config.deps, config.callback);
			}
			if (!callback) {
				return;
			}

			if (callback.splice) {
				//callback is an array, which means it is a dependency list.
				//Adjust args if there are dependencies
				deps = callback;
				callback = relName;
				relName = null;
			} else {
				deps = undef;
			}
		}

		//Support require(['a'])
		callback = callback || function () {};

		//If relName is a function, it is an errback handler,
		//so remove it.
		if (typeof relName === 'function') {
			relName = forceSync;
			forceSync = alt;
		}

		//Simulate async callback;
		if (forceSync) {
			main(undef, deps, callback, relName);
		} else {
			//Using a non-zero value because of concern for what old browsers
			//do, and latest browsers "upgrade" to 4 if lower value is used:
			//http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
			//If want a value immediately, use require('id') instead -- something
			//that works in almond on the global level, but not guaranteed and
			//unlikely to work in other AMD implementations.
			setTimeout(function () {
				main(undef, deps, callback, relName);
			}, 4);
		}

		return req;
	};

	/**
	 * Just drops the config on the floor, but returns req in case
	 * the config return value is used.
	 */
	req.config = function (cfg) {
		return req(cfg);
	};

	/**
	 * Expose module registry for debugging and tooling
	 */
	requirejs._defined = defined;

	define = function (name, deps, callback) {
		if (typeof name !== 'string') {
			throw new Error('See almond README: incorrect module build, no module name');
		}

		//This module may not have dependencies
		if (!deps.splice) {
			//deps is not an array, so probably means
			//an object literal or factory function for
			//the value. Adjust args.
			callback = deps;
			deps = [];
		}

		if (!hasProp(defined, name) && !hasProp(waiting, name)) {
			waiting[name] = [name, deps, callback];
		}
	};

	define.amd = {
		jQuery: true
	};
}());

S2.requirejs = requirejs;S2.require = require;S2.define = define;
}
}());
S2.define("almond", function(){});

/* global jQuery:false, $:false */
S2.define('jquery',[],function () {
  var _$ = jQuery || $;

  if (_$ == null && console && console.error) {
	console.error(
	  'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
	  'found. Make sure that you are including jQuery before Select2 on your ' +
	  'web page.'
	);
  }

  return _$;
});

S2.define('select2/utils',[
  'jquery'
], function ($) {
  var Utils = {};

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

	function BaseConstructor () {
	  this.constructor = ChildClass;
	}

	for (var key in SuperClass) {
	  if (__hasProp.call(SuperClass, key)) {
		ChildClass[key] = SuperClass[key];
	  }
	}

	BaseConstructor.prototype = SuperClass.prototype;
	ChildClass.prototype = new BaseConstructor();
	ChildClass.__super__ = SuperClass.prototype;

	return ChildClass;
  };

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

	var methods = [];

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

	  if (typeof m !== 'function') {
		continue;
	  }

	  if (methodName === 'constructor') {
		continue;
	  }

	  methods.push(methodName);
	}

	return methods;
  }

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

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

	  var argCount = DecoratorClass.prototype.constructor.length;

	  var calledConstructor = SuperClass.prototype.constructor;

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

		calledConstructor = DecoratorClass.prototype.constructor;
	  }

	  calledConstructor.apply(this, arguments);
	}

	DecoratorClass.displayName = SuperClass.displayName;

	function ctr () {
	  this.constructor = DecoratedClass;
	}

	DecoratedClass.prototype = new ctr();

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

		DecoratedClass.prototype[superMethod] =
		  SuperClass.prototype[superMethod];
	}

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

	  if (methodName in DecoratedClass.prototype) {
		originalMethod = DecoratedClass.prototype[methodName];
	  }

	  var decoratedMethod = DecoratorClass.prototype[methodName];

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

		unshift.call(arguments, originalMethod);

		return decoratedMethod.apply(this, arguments);
	  };
	};

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

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

	return DecoratedClass;
  };

  var Observable = function () {
	this.listeners = {};
  };

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

	if (event in this.listeners) {
	  this.listeners[event].push(callback);
	} else {
	  this.listeners[event] = [callback];
	}
  };

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

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

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

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

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

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

	if ('*' in this.listeners) {
	  this.invoke(this.listeners['*'], arguments);
	}
  };

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

  Utils.Observable = Observable;

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

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

	return chars;
  };

  Utils.bind = function (func, context) {
	return function () {
	  func.apply(context, arguments);
	};
  };

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

	  var dataLevel = data;

	  if (keys.length === 1) {
		continue;
	  }

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

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

		if (!(key in dataLevel)) {
		  dataLevel[key] = {};
		}

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

		dataLevel = dataLevel[key];
	  }

	  delete data[originalKey];
	}

	return data;
  };

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

	var $el = $(el);
	var overflowX = el.style.overflowX;
	var overflowY = el.style.overflowY;

	//Check both x and y declarations
	if (overflowX === overflowY &&
		(overflowY === 'hidden' || overflowY === 'visible')) {
	  return false;
	}

	if (overflowX === 'scroll' || overflowY === 'scroll') {
	  return true;
	}

	return ($el.innerHeight() < el.scrollHeight ||
	  $el.innerWidth() < el.scrollWidth);
  };

  Utils.escapeMarkup = function (markup) {
	var replaceMap = {
	  '\\': '&#92;',
	  '&': '&amp;',
	  '<': '&lt;',
	  '>': '&gt;',
	  '"': '&quot;',
	  '\'': '&#39;',
	  '/': '&#47;'
	};

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

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

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

	  $.map($nodes, function (node) {
		$jqNodes = $jqNodes.add(node);
	  });

	  $nodes = $jqNodes;
	}

	$element.append($nodes);
  };

  return Utils;
});

S2.define('select2/results',[
  'jquery',
  './utils'
], function ($, Utils) {
  function Results ($element, options, dataAdapter) {
	this.$element = $element;
	this.data = dataAdapter;
	this.options = options;

	Results.__super__.constructor.call(this);
  }

  Utils.Extend(Results, Utils.Observable);

  Results.prototype.render = function () {
	var $results = $(
	  '<ul class="select2-results__options" role="tree"></ul>'
	);

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

	this.$results = $results;

	return $results;
  };

  Results.prototype.clear = function () {
	this.$results.empty();
  };

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

	this.clear();
	this.hideLoading();

	var $message = $(
	  '<li role="treeitem" aria-live="assertive"' +
	  ' class="select2-results__option"></li>'
	);

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

	$message.append(
	  escapeMarkup(
		message(params.args)
	  )
	);

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

	this.$results.append($message);
  };

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

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

	var $options = [];

	if (data.results == null || data.results.length === 0) {
	  if (this.$results.children().length === 0) {
		this.trigger('results:message', {
		  message: 'noResults'
		});
	  }

	  return;
	}

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

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

	  var $option = this.option(item);

	  $options.push($option);
	}

	this.$results.append($options);
  };

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

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

	return sorter(data);
  };

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

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

	// Check if there are any selected options
	if ($selected.length > 0) {
	  // If there are selected options, highlight the first
	  $selected.first().trigger('mouseenter');
	} else {
	  // If there are no selected options, highlight the first option
	  // in the dropdown
	  $options.first().trigger('mouseenter');
	}

	this.ensureHighlightVisible();
  };

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

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

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

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

		var item = $.data(this, 'data');

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

		if ((item.element != null && item.element.selected) ||
			(item.element == null && $.inArray(id, selectedIds) > -1)) {
		  $option.attr('aria-selected', 'true');
		} else {
		  $option.attr('aria-selected', 'false');
		}
	  });

	});
  };

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

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

	var loading = {
	  disabled: true,
	  loading: true,
	  text: loadingMore(params)
	};
	var $loading = this.option(loading);
	$loading.className += ' loading-results';

	this.$results.prepend($loading);
  };

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

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

	var attrs = {
	  'role': 'treeitem',
	  'aria-selected': 'false'
	};

	if (data.disabled) {
	  delete attrs['aria-selected'];
	  attrs['aria-disabled'] = 'true';
	}

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

	if (data._resultId != null) {
	  option.id = data._resultId;
	}

	if (data.title) {
	  option.title = data.title;
	}

	if (data.children) {
	  attrs.role = 'group';
	  attrs['aria-label'] = data.text;
	  delete attrs['aria-selected'];
	}

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

	  option.setAttribute(attr, val);
	}

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

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

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

	  var $children = [];

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

		var $child = this.option(child);

		$children.push($child);
	  }

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

	  $childrenContainer.append($children);

	  $option.append(label);
	  $option.append($childrenContainer);
	} else {
	  this.template(data, option);
	}

	$.data(option, 'data', data);

	return option;
  };

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

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

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

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

	  if (container.isOpen()) {
		self.setClasses();
		self.highlightFirstItem();
	  }
	});

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

	  if (container.isOpen()) {
		self.setClasses();
	  }
	});

	container.on('query', function (params) {
	  self.hideMessages();
	  self.showLoading(params);
	});

	container.on('select', function () {
	  if (!container.isOpen()) {
		return;
	  }

	  self.setClasses();
	  self.highlightFirstItem();
	});

	container.on('unselect', function () {
	  if (!container.isOpen()) {
		return;
	  }

	  self.setClasses();
	  self.highlightFirstItem();
	});

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

	  self.setClasses();
	  self.ensureHighlightVisible();
	});

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

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

	  if ($highlighted.length === 0) {
		return;
	  }

	  $highlighted.trigger('mouseup');
	});

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

	  if ($highlighted.length === 0) {
		return;
	  }

	  var data = $highlighted.data('data');

	  if ($highlighted.attr('aria-selected') == 'true') {
		self.trigger('close', {});
	  } else {
		self.trigger('select', {
		  data: data
		});
	  }
	});

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

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

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

	  // If we are already at te top, don't move further
	  if (currentIndex === 0) {
		return;
	  }

	  var nextIndex = currentIndex - 1;

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

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

	  $next.trigger('mouseenter');

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

	  if (nextIndex === 0) {
		self.$results.scrollTop(0);
	  } else if (nextTop - currentOffset < 0) {
		self.$results.scrollTop(nextOffset);
	  }
	});

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

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

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

	  var nextIndex = currentIndex + 1;

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

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

	  $next.trigger('mouseenter');

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

	  if (nextIndex === 0) {
		self.$results.scrollTop(0);
	  } else if (nextBottom > currentOffset) {
		self.$results.scrollTop(nextOffset);
	  }
	});

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

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

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

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

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

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

		  e.preventDefault();
		  e.stopPropagation();
		} else if (isAtBottom) {
		  self.$results.scrollTop(
			self.$results.get(0).scrollHeight - self.$results.height()
		  );

		  e.preventDefault();
		  e.stopPropagation();
		}
	  });
	}

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

	  var data = $this.data('data');

	  if ($this.attr('aria-selected') === 'true') {
		if (self.options.get('multiple')) {
		  self.trigger('unselect', {
			originalEvent: evt,
			data: data
		  });
		} else {
		  self.trigger('close', {});
		}

		return;
	  }

	  self.trigger('select', {
		originalEvent: evt,
		data: data
	  });
	});

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

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

	  self.trigger('results:focus', {
		data: data,
		element: $(this)
	  });
	});
  };

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

	return $highlighted;
  };

  Results.prototype.destroy = function () {
	this.$results.remove();
  };

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

	if ($highlighted.length === 0) {
	  return;
	}

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

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

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

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

	if (currentIndex <= 2) {
	  this.$results.scrollTop(0);
	} else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
	  this.$results.scrollTop(nextOffset);
	}
  };

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

	var content = template(result, container);

	if (content == null) {
	  container.style.display = 'none';
	} else if (typeof content === 'string') {
	  container.innerHTML = escapeMarkup(content);
	} else {
	  $(container).append(content);
	}
  };

  return Results;
});

S2.define('select2/keys',[

], function () {
  var KEYS = {
	BACKSPACE: 8,
	TAB: 9,
	ENTER: 13,
	SHIFT: 16,
	CTRL: 17,
	ALT: 18,
	ESC: 27,
	SPACE: 32,
	PAGE_UP: 33,
	PAGE_DOWN: 34,
	END: 35,
	HOME: 36,
	LEFT: 37,
	UP: 38,
	RIGHT: 39,
	DOWN: 40,
	DELETE: 46
  };

  return KEYS;
});

S2.define('select2/selection/base',[
  'jquery',
  '../utils',
  '../keys'
], function ($, Utils, KEYS) {
  function BaseSelection ($element, options) {
	this.$element = $element;
	this.options = options;

	BaseSelection.__super__.constructor.call(this);
  }

  Utils.Extend(BaseSelection, Utils.Observable);

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

	this._tabindex = 0;

	if (this.$element.data('old-tabindex') != null) {
	  this._tabindex = this.$element.data('old-tabindex');
	} else if (this.$element.attr('tabindex') != null) {
	  this._tabindex = this.$element.attr('tabindex');
	}

	$selection.attr('title', this.$element.attr('title'));
	$selection.attr('tabindex', this._tabindex);

	this.$selection = $selection;

	return $selection;
  };

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

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

	this.container = container;

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

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

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

	  if (evt.which === KEYS.SPACE) {
		evt.preventDefault();
	  }
	});

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

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

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

	  self._attachCloseHandler(container);
	});

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

	  self.$selection.focus();

	  self._detachCloseHandler(container);
	});

	container.on('enable', function () {
	  self.$selection.attr('tabindex', self._tabindex);
	});

	container.on('disable', function () {
	  self.$selection.attr('tabindex', '-1');
	});
  };

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

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

	  self.trigger('blur', evt);
	}, 1);
  };

  BaseSelection.prototype._attachCloseHandler = function (container) {
	var self = this;

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

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

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

	  $all.each(function () {
		var $this = $(this);

		if (this == $select[0]) {
		  return;
		}

		var $element = $this.data('element');

		$element.select2('close');
	  });
	});
  };

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

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

  BaseSelection.prototype.destroy = function () {
	this._detachCloseHandler(this.container);
  };

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

  return BaseSelection;
});

S2.define('select2/selection/single',[
  'jquery',
  './base',
  '../utils',
  '../keys'
], function ($, BaseSelection, Utils, KEYS) {
  function SingleSelection () {
	SingleSelection.__super__.constructor.apply(this, arguments);
  }

  Utils.Extend(SingleSelection, BaseSelection);

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

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

	$selection.html(
	  '<span class="select2-selection__rendered"></span>' +
	  '<span class="select2-selection__arrow" role="presentation">' +
		'<b role="presentation"></b>' +
	  '</span>'
	);

	return $selection;
  };

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

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

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

	this.$selection.find('.select2-selection__rendered').attr('id', id);
	this.$selection.attr('aria-labelledby', id);

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

	  self.trigger('toggle', {
		originalEvent: evt
	  });
	});

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

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

	container.on('focus', function (evt) {
	  if (!container.isOpen()) {
		self.$selection.focus();
	  }
	});

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

  SingleSelection.prototype.clear = function () {
	this.$selection.find('.select2-selection__rendered').empty();
  };

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

	return escapeMarkup(template(data, container));
  };

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

  SingleSelection.prototype.update = function (data) {
	if (data.length === 0) {
	  this.clear();
	  return;
	}

	var selection = data[0];

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

	$rendered.empty().append(formatted);
	$rendered.prop('title', selection.title || selection.text);
  };

  return SingleSelection;
});

S2.define('select2/selection/multiple',[
  'jquery',
  './base',
  '../utils'
], function ($, BaseSelection, Utils) {
  function MultipleSelection ($element, options) {
	MultipleSelection.__super__.constructor.apply(this, arguments);
  }

  Utils.Extend(MultipleSelection, BaseSelection);

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

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

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

	return $selection;
  };

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

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

	this.$selection.on('click', function (evt) {
	  self.trigger('toggle', {
		originalEvent: evt
	  });
	});

	this.$selection.on(
	  'click',
	  '.select2-selection__choice__remove',
	  function (evt) {
		// Ignore the event if it is disabled
		if (self.options.get('disabled')) {
		  return;
		}

		var $remove = $(this);
		var $selection = $remove.parent();

		var data = $selection.data('data');

		self.trigger('unselect', {
		  originalEvent: evt,
		  data: data
		});
	  }
	);
  };

  MultipleSelection.prototype.clear = function () {
	this.$selection.find('.select2-selection__rendered').empty();
  };

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

	return escapeMarkup(template(data, container));
  };

  MultipleSelection.prototype.selectionContainer = function () {
	var $container = $(
	  '<li class="select2-selection__choice">' +
		'<span class="select2-selection__choice__remove" role="presentation">' +
		  '&times;' +
		'</span>' +
	  '</li>'
	);

	return $container;
  };

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

	if (data.length === 0) {
	  return;
	}

	var $selections = [];

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

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

	  $selection.append(formatted);
	  $selection.prop('title', selection.title || selection.text);

	  $selection.data('data', selection);

	  $selections.push($selection);
	}

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

	Utils.appendMany($rendered, $selections);
  };

  return MultipleSelection;
});

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

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

  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
	if (typeof placeholder === 'string') {
	  placeholder = {
		id: '',
		text: placeholder
	  };
	}

	return placeholder;
  };

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

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

	return $placeholder;
  };

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

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

	this.clear();

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

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

  return Placeholder;
});

S2.define('select2/selection/allowClear',[
  'jquery',
  '../keys'
], function ($, KEYS) {
  function AllowClear () { }

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

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

	if (this.placeholder == null) {
	  if (this.options.get('debug') && window.console && console.error) {
		console.error(
		  'Select2: The `allowClear` option should be used in combination ' +
		  'with the `placeholder` option.'
		);
	  }
	}

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

	container.on('keypress', function (evt) {
	  self._handleKeyboardClear(evt, container);
	});
  };

  AllowClear.prototype._handleClear = function (_, evt) {
	// Ignore the event if it is disabled
	if (this.options.get('disabled')) {
	  return;
	}

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

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

	evt.stopPropagation();

	var data = $clear.data('data');

	for (var d = 0; d < data.length; d++) {
	  var unselectData = {
		data: data[d]
	  };

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

	  // If the event was prevented, don't clear it out.
	  if (unselectData.prevented) {
		return;
	  }
	}

	this.$element.val(this.placeholder.id).trigger('change');

	this.trigger('toggle', {});
  };

  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
	if (container.isOpen()) {
	  return;
	}

	if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
	  this._handleClear(evt);
	}
  };

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

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

	var $remove = $(
	  '<span class="select2-selection__clear">' +
		'&times;' +
	  '</span>'
	);
	$remove.data('data', data);

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

  return AllowClear;
});

S2.define('select2/selection/search',[
  'jquery',
  '../utils',
  '../keys'
], function ($, Utils, KEYS) {
  function Search (decorated, $element, options) {
	decorated.call(this, $element, options);
  }

  Search.prototype.render = function (decorated) {
	var $search = $(
	  '<li class="select2-search select2-search--inline">' +
		'<input class="select2-search__field" type="search" tabindex="-1"' +
		' autocomplete="off" autocorrect="off" autocapitalize="off"' +
		' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
	  '</li>'
	);

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

	var $rendered = decorated.call(this);

	this._transferTabIndex();

	return $rendered;
  };

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

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

	container.on('open', function () {
	  self.$search.trigger('focus');
	});

	container.on('close', function () {
	  self.$search.val('');
	  self.$search.removeAttr('aria-activedescendant');
	  self.$search.trigger('focus');
	});

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

	  self._transferTabIndex();
	});

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

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

	container.on('results:focus', function (params) {
	  self.$search.attr('aria-activedescendant', params.id);
	});

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

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

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

	  self.trigger('keypress', evt);

	  self._keyUpPrevented = evt.isDefaultPrevented();

	  var key = evt.which;

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

		if ($previousChoice.length > 0) {
		  var item = $previousChoice.data('data');

		  self.searchRemoveChoice(item);

		  evt.preventDefault();
		}
	  }
	});

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

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

		// Unbind the duplicated `keyup` event
		self.$selection.off('keyup.search');
	  }
	);

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

		var key = evt.which;

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

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

		self.handleSearch(evt);
	  }
	);
  };

  /**
   * This method will transfer the tabindex attribute from the rendered
   * selection to the search box. This allows for the search box to be used as
   * the primary focus instead of the selection container.
   *
   * @private
   */
  Search.prototype._transferTabIndex = function (decorated) {
	this.$search.attr('tabindex', this.$selection.attr('tabindex'));
	this.$selection.attr('tabindex', '-1');
  };

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

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

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

	decorated.call(this, data);

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

	this.resizeSearch();
	if (searchHadFocus) {
	  this.$search.focus();
	}
  };

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

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

	  this.trigger('query', {
		term: input
	  });
	}

	this._keyUpPrevented = false;
  };

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

	this.$search.val(item.text);
	this.handleSearch();
  };

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

	var width = '';

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

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

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

  return Search;
});

S2.define('select2/selection/eventRelay',[
  'jquery'
], function ($) {
  function EventRelay () { }

  EventRelay.prototype.bind = function (decorated, container, $container) {
	var self = this;
	var relayEvents = [
	  'open', 'opening',
	  'close', 'closing',
	  'select', 'selecting',
	  'unselect', 'unselecting'
	];

	var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];

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

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

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

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

	  self.$element.trigger(evt);

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

	  params.prevented = evt.isDefaultPrevented();
	});
  };

  return EventRelay;
});

S2.define('select2/translation',[
  'jquery',
  'require'
], function ($, require) {
  function Translation (dict) {
	this.dict = dict || {};
  }

  Translation.prototype.all = function () {
	return this.dict;
  };

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

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

  // Static functions

  Translation._cache = {};

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

	  Translation._cache[path] = translations;
	}

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

  return Translation;
});

S2.define('select2/diacritics',[

], function () {
  var diacritics = {
	'\u24B6': 'A',
	'\uFF21': 'A',
	'\u00C0': 'A',
	'\u00C1': 'A',
	'\u00C2': 'A',
	'\u1EA6': 'A',
	'\u1EA4': 'A',
	'\u1EAA': 'A',
	'\u1EA8': 'A',
	'\u00C3': 'A',
	'\u0100': 'A',
	'\u0102': 'A',
	'\u1EB0': 'A',
	'\u1EAE': 'A',
	'\u1EB4': 'A',
	'\u1EB2': 'A',
	'\u0226': 'A',
	'\u01E0': 'A',
	'\u00C4': 'A',
	'\u01DE': 'A',
	'\u1EA2': 'A',
	'\u00C5': 'A',
	'\u01FA': 'A',
	'\u01CD': 'A',
	'\u0200': 'A',
	'\u0202': 'A',
	'\u1EA0': 'A',
	'\u1EAC': 'A',
	'\u1EB6': 'A',
	'\u1E00': 'A',
	'\u0104': 'A',
	'\u023A': 'A',
	'\u2C6F': 'A',
	'\uA732': 'AA',
	'\u00C6': 'AE',
	'\u01FC': 'AE',
	'\u01E2': 'AE',
	'\uA734': 'AO',
	'\uA736': 'AU',
	'\uA738': 'AV',
	'\uA73A': 'AV',
	'\uA73C': 'AY',
	'\u24B7': 'B',
	'\uFF22': 'B',
	'\u1E02': 'B',
	'\u1E04': 'B',
	'\u1E06': 'B',
	'\u0243': 'B',
	'\u0182': 'B',
	'\u0181': 'B',
	'\u24B8': 'C',
	'\uFF23': 'C',
	'\u0106': 'C',
	'\u0108': 'C',
	'\u010A': 'C',
	'\u010C': 'C',
	'\u00C7': 'C',
	'\u1E08': 'C',
	'\u0187': 'C',
	'\u023B': 'C',
	'\uA73E': 'C',
	'\u24B9': 'D',
	'\uFF24': 'D',
	'\u1E0A': 'D',
	'\u010E': 'D',
	'\u1E0C': 'D',
	'\u1E10': 'D',
	'\u1E12': 'D',
	'\u1E0E': 'D',
	'\u0110': 'D',
	'\u018B': 'D',
	'\u018A': 'D',
	'\u0189': 'D',
	'\uA779': 'D',
	'\u01F1': 'DZ',
	'\u01C4': 'DZ',
	'\u01F2': 'Dz',
	'\u01C5': 'Dz',
	'\u24BA': 'E',
	'\uFF25': 'E',
	'\u00C8': 'E',
	'\u00C9': 'E',
	'\u00CA': 'E',
	'\u1EC0': 'E',
	'\u1EBE': 'E',
	'\u1EC4': 'E',
	'\u1EC2': 'E',
	'\u1EBC': 'E',
	'\u0112': 'E',
	'\u1E14': 'E',
	'\u1E16': 'E',
	'\u0114': 'E',
	'\u0116': 'E',
	'\u00CB': 'E',
	'\u1EBA': 'E',
	'\u011A': 'E',
	'\u0204': 'E',
	'\u0206': 'E',
	'\u1EB8': 'E',
	'\u1EC6': 'E',
	'\u0228': 'E',
	'\u1E1C': 'E',
	'\u0118': 'E',
	'\u1E18': 'E',
	'\u1E1A': 'E',
	'\u0190': 'E',
	'\u018E': 'E',
	'\u24BB': 'F',
	'\uFF26': 'F',
	'\u1E1E': 'F',
	'\u0191': 'F',
	'\uA77B': 'F',
	'\u24BC': 'G',
	'\uFF27': 'G',
	'\u01F4': 'G',
	'\u011C': 'G',
	'\u1E20': 'G',
	'\u011E': 'G',
	'\u0120': 'G',
	'\u01E6': 'G',
	'\u0122': 'G',
	'\u01E4': 'G',
	'\u0193': 'G',
	'\uA7A0': 'G',
	'\uA77D': 'G',
	'\uA77E': 'G',
	'\u24BD': 'H',
	'\uFF28': 'H',
	'\u0124': 'H',
	'\u1E22': 'H',
	'\u1E26': 'H',
	'\u021E': 'H',
	'\u1E24': 'H',
	'\u1E28': 'H',
	'\u1E2A': 'H',
	'\u0126': 'H',
	'\u2C67': 'H',
	'\u2C75': 'H',
	'\uA78D': 'H',
	'\u24BE': 'I',
	'\uFF29': 'I',
	'\u00CC': 'I',
	'\u00CD': 'I',
	'\u00CE': 'I',
	'\u0128': 'I',
	'\u012A': 'I',
	'\u012C': 'I',
	'\u0130': 'I',
	'\u00CF': 'I',
	'\u1E2E': 'I',
	'\u1EC8': 'I',
	'\u01CF': 'I',
	'\u0208': 'I',
	'\u020A': 'I',
	'\u1ECA': 'I',
	'\u012E': 'I',
	'\u1E2C': 'I',
	'\u0197': 'I',
	'\u24BF': 'J',
	'\uFF2A': 'J',
	'\u0134': 'J',
	'\u0248': 'J',
	'\u24C0': 'K',
	'\uFF2B': 'K',
	'\u1E30': 'K',
	'\u01E8': 'K',
	'\u1E32': 'K',
	'\u0136': 'K',
	'\u1E34': 'K',
	'\u0198': 'K',
	'\u2C69': 'K',
	'\uA740': 'K',
	'\uA742': 'K',
	'\uA744': 'K',
	'\uA7A2': 'K',
	'\u24C1': 'L',
	'\uFF2C': 'L',
	'\u013F': 'L',
	'\u0139': 'L',
	'\u013D': 'L',
	'\u1E36': 'L',
	'\u1E38': 'L',
	'\u013B': 'L',
	'\u1E3C': 'L',
	'\u1E3A': 'L',
	'\u0141': 'L',
	'\u023D': 'L',
	'\u2C62': 'L',
	'\u2C60': 'L',
	'\uA748': 'L',
	'\uA746': 'L',
	'\uA780': 'L',
	'\u01C7': 'LJ',
	'\u01C8': 'Lj',
	'\u24C2': 'M',
	'\uFF2D': 'M',
	'\u1E3E': 'M',
	'\u1E40': 'M',
	'\u1E42': 'M',
	'\u2C6E': 'M',
	'\u019C': 'M',
	'\u24C3': 'N',
	'\uFF2E': 'N',
	'\u01F8': 'N',
	'\u0143': 'N',
	'\u00D1': 'N',
	'\u1E44': 'N',
	'\u0147': 'N',
	'\u1E46': 'N',
	'\u0145': 'N',
	'\u1E4A': 'N',
	'\u1E48': 'N',
	'\u0220': 'N',
	'\u019D': 'N',
	'\uA790': 'N',
	'\uA7A4': 'N',
	'\u01CA': 'NJ',
	'\u01CB': 'Nj',
	'\u24C4': 'O',
	'\uFF2F': 'O',
	'\u00D2': 'O',
	'\u00D3': 'O',
	'\u00D4': 'O',
	'\u1ED2': 'O',
	'\u1ED0': 'O',
	'\u1ED6': 'O',
	'\u1ED4': 'O',
	'\u00D5': 'O',
	'\u1E4C': 'O',
	'\u022C': 'O',
	'\u1E4E': 'O',
	'\u014C': 'O',
	'\u1E50': 'O',
	'\u1E52': 'O',
	'\u014E': 'O',
	'\u022E': 'O',
	'\u0230': 'O',
	'\u00D6': 'O',
	'\u022A': 'O',
	'\u1ECE': 'O',
	'\u0150': 'O',
	'\u01D1': 'O',
	'\u020C': 'O',
	'\u020E': 'O',
	'\u01A0': 'O',
	'\u1EDC': 'O',
	'\u1EDA': 'O',
	'\u1EE0': 'O',
	'\u1EDE': 'O',
	'\u1EE2': 'O',
	'\u1ECC': 'O',
	'\u1ED8': 'O',
	'\u01EA': 'O',
	'\u01EC': 'O',
	'\u00D8': 'O',
	'\u01FE': 'O',
	'\u0186': 'O',
	'\u019F': 'O',
	'\uA74A': 'O',
	'\uA74C': 'O',
	'\u01A2': 'OI',
	'\uA74E': 'OO',
	'\u0222': 'OU',
	'\u24C5': 'P',
	'\uFF30': 'P',
	'\u1E54': 'P',
	'\u1E56': 'P',
	'\u01A4': 'P',
	'\u2C63': 'P',
	'\uA750': 'P',
	'\uA752': 'P',
	'\uA754': 'P',
	'\u24C6': 'Q',
	'\uFF31': 'Q',
	'\uA756': 'Q',
	'\uA758': 'Q',
	'\u024A': 'Q',
	'\u24C7': 'R',
	'\uFF32': 'R',
	'\u0154': 'R',
	'\u1E58': 'R',
	'\u0158': 'R',
	'\u0210': 'R',
	'\u0212': 'R',
	'\u1E5A': 'R',
	'\u1E5C': 'R',
	'\u0156': 'R',
	'\u1E5E': 'R',
	'\u024C': 'R',
	'\u2C64': 'R',
	'\uA75A': 'R',
	'\uA7A6': 'R',
	'\uA782': 'R',
	'\u24C8': 'S',
	'\uFF33': 'S',
	'\u1E9E': 'S',
	'\u015A': 'S',
	'\u1E64': 'S',
	'\u015C': 'S',
	'\u1E60': 'S',
	'\u0160': 'S',
	'\u1E66': 'S',
	'\u1E62': 'S',
	'\u1E68': 'S',
	'\u0218': 'S',
	'\u015E': 'S',
	'\u2C7E': 'S',
	'\uA7A8': 'S',
	'\uA784': 'S',
	'\u24C9': 'T',
	'\uFF34': 'T',
	'\u1E6A': 'T',
	'\u0164': 'T',
	'\u1E6C': 'T',
	'\u021A': 'T',
	'\u0162': 'T',
	'\u1E70': 'T',
	'\u1E6E': 'T',
	'\u0166': 'T',
	'\u01AC': 'T',
	'\u01AE': 'T',
	'\u023E': 'T',
	'\uA786': 'T',
	'\uA728': 'TZ',
	'\u24CA': 'U',
	'\uFF35': 'U',
	'\u00D9': 'U',
	'\u00DA': 'U',
	'\u00DB': 'U',
	'\u0168': 'U',
	'\u1E78': 'U',
	'\u016A': 'U',
	'\u1E7A': 'U',
	'\u016C': 'U',
	'\u00DC': 'U',
	'\u01DB': 'U',
	'\u01D7': 'U',
	'\u01D5': 'U',
	'\u01D9': 'U',
	'\u1EE6': 'U',
	'\u016E': 'U',
	'\u0170': 'U',
	'\u01D3': 'U',
	'\u0214': 'U',
	'\u0216': 'U',
	'\u01AF': 'U',
	'\u1EEA': 'U',
	'\u1EE8': 'U',
	'\u1EEE': 'U',
	'\u1EEC': 'U',
	'\u1EF0': 'U',
	'\u1EE4': 'U',
	'\u1E72': 'U',
	'\u0172': 'U',
	'\u1E76': 'U',
	'\u1E74': 'U',
	'\u0244': 'U',
	'\u24CB': 'V',
	'\uFF36': 'V',
	'\u1E7C': 'V',
	'\u1E7E': 'V',
	'\u01B2': 'V',
	'\uA75E': 'V',
	'\u0245': 'V',
	'\uA760': 'VY',
	'\u24CC': 'W',
	'\uFF37': 'W',
	'\u1E80': 'W',
	'\u1E82': 'W',
	'\u0174': 'W',
	'\u1E86': 'W',
	'\u1E84': 'W',
	'\u1E88': 'W',
	'\u2C72': 'W',
	'\u24CD': 'X',
	'\uFF38': 'X',
	'\u1E8A': 'X',
	'\u1E8C': 'X',
	'\u24CE': 'Y',
	'\uFF39': 'Y',
	'\u1EF2': 'Y',
	'\u00DD': 'Y',
	'\u0176': 'Y',
	'\u1EF8': 'Y',
	'\u0232': 'Y',
	'\u1E8E': 'Y',
	'\u0178': 'Y',
	'\u1EF6': 'Y',
	'\u1EF4': 'Y',
	'\u01B3': 'Y',
	'\u024E': 'Y',
	'\u1EFE': 'Y',
	'\u24CF': 'Z',
	'\uFF3A': 'Z',
	'\u0179': 'Z',
	'\u1E90': 'Z',
	'\u017B': 'Z',
	'\u017D': 'Z',
	'\u1E92': 'Z',
	'\u1E94': 'Z',
	'\u01B5': 'Z',
	'\u0224': 'Z',
	'\u2C7F': 'Z',
	'\u2C6B': 'Z',
	'\uA762': 'Z',
	'\u24D0': 'a',
	'\uFF41': 'a',
	'\u1E9A': 'a',
	'\u00E0': 'a',
	'\u00E1': 'a',
	'\u00E2': 'a',
	'\u1EA7': 'a',
	'\u1EA5': 'a',
	'\u1EAB': 'a',
	'\u1EA9': 'a',
	'\u00E3': 'a',
	'\u0101': 'a',
	'\u0103': 'a',
	'\u1EB1': 'a',
	'\u1EAF': 'a',
	'\u1EB5': 'a',
	'\u1EB3': 'a',
	'\u0227': 'a',
	'\u01E1': 'a',
	'\u00E4': 'a',
	'\u01DF': 'a',
	'\u1EA3': 'a',
	'\u00E5': 'a',
	'\u01FB': 'a',
	'\u01CE': 'a',
	'\u0201': 'a',
	'\u0203': 'a',
	'\u1EA1': 'a',
	'\u1EAD': 'a',
	'\u1EB7': 'a',
	'\u1E01': 'a',
	'\u0105': 'a',
	'\u2C65': 'a',
	'\u0250': 'a',
	'\uA733': 'aa',
	'\u00E6': 'ae',
	'\u01FD': 'ae',
	'\u01E3': 'ae',
	'\uA735': 'ao',
	'\uA737': 'au',
	'\uA739': 'av',
	'\uA73B': 'av',
	'\uA73D': 'ay',
	'\u24D1': 'b',
	'\uFF42': 'b',
	'\u1E03': 'b',
	'\u1E05': 'b',
	'\u1E07': 'b',
	'\u0180': 'b',
	'\u0183': 'b',
	'\u0253': 'b',
	'\u24D2': 'c',
	'\uFF43': 'c',
	'\u0107': 'c',
	'\u0109': 'c',
	'\u010B': 'c',
	'\u010D': 'c',
	'\u00E7': 'c',
	'\u1E09': 'c',
	'\u0188': 'c',
	'\u023C': 'c',
	'\uA73F': 'c',
	'\u2184': 'c',
	'\u24D3': 'd',
	'\uFF44': 'd',
	'\u1E0B': 'd',
	'\u010F': 'd',
	'\u1E0D': 'd',
	'\u1E11': 'd',
	'\u1E13': 'd',
	'\u1E0F': 'd',
	'\u0111': 'd',
	'\u018C': 'd',
	'\u0256': 'd',
	'\u0257': 'd',
	'\uA77A': 'd',
	'\u01F3': 'dz',
	'\u01C6': 'dz',
	'\u24D4': 'e',
	'\uFF45': 'e',
	'\u00E8': 'e',
	'\u00E9': 'e',
	'\u00EA': 'e',
	'\u1EC1': 'e',
	'\u1EBF': 'e',
	'\u1EC5': 'e',
	'\u1EC3': 'e',
	'\u1EBD': 'e',
	'\u0113': 'e',
	'\u1E15': 'e',
	'\u1E17': 'e',
	'\u0115': 'e',
	'\u0117': 'e',
	'\u00EB': 'e',
	'\u1EBB': 'e',
	'\u011B': 'e',
	'\u0205': 'e',
	'\u0207': 'e',
	'\u1EB9': 'e',
	'\u1EC7': 'e',
	'\u0229': 'e',
	'\u1E1D': 'e',
	'\u0119': 'e',
	'\u1E19': 'e',
	'\u1E1B': 'e',
	'\u0247': 'e',
	'\u025B': 'e',
	'\u01DD': 'e',
	'\u24D5': 'f',
	'\uFF46': 'f',
	'\u1E1F': 'f',
	'\u0192': 'f',
	'\uA77C': 'f',
	'\u24D6': 'g',
	'\uFF47': 'g',
	'\u01F5': 'g',
	'\u011D': 'g',
	'\u1E21': 'g',
	'\u011F': 'g',
	'\u0121': 'g',
	'\u01E7': 'g',
	'\u0123': 'g',
	'\u01E5': 'g',
	'\u0260': 'g',
	'\uA7A1': 'g',
	'\u1D79': 'g',
	'\uA77F': 'g',
	'\u24D7': 'h',
	'\uFF48': 'h',
	'\u0125': 'h',
	'\u1E23': 'h',
	'\u1E27': 'h',
	'\u021F': 'h',
	'\u1E25': 'h',
	'\u1E29': 'h',
	'\u1E2B': 'h',
	'\u1E96': 'h',
	'\u0127': 'h',
	'\u2C68': 'h',
	'\u2C76': 'h',
	'\u0265': 'h',
	'\u0195': 'hv',
	'\u24D8': 'i',
	'\uFF49': 'i',
	'\u00EC': 'i',
	'\u00ED': 'i',
	'\u00EE': 'i',
	'\u0129': 'i',
	'\u012B': 'i',
	'\u012D': 'i',
	'\u00EF': 'i',
	'\u1E2F': 'i',
	'\u1EC9': 'i',
	'\u01D0': 'i',
	'\u0209': 'i',
	'\u020B': 'i',
	'\u1ECB': 'i',
	'\u012F': 'i',
	'\u1E2D': 'i',
	'\u0268': 'i',
	'\u0131': 'i',
	'\u24D9': 'j',
	'\uFF4A': 'j',
	'\u0135': 'j',
	'\u01F0': 'j',
	'\u0249': 'j',
	'\u24DA': 'k',
	'\uFF4B': 'k',
	'\u1E31': 'k',
	'\u01E9': 'k',
	'\u1E33': 'k',
	'\u0137': 'k',
	'\u1E35': 'k',
	'\u0199': 'k',
	'\u2C6A': 'k',
	'\uA741': 'k',
	'\uA743': 'k',
	'\uA745': 'k',
	'\uA7A3': 'k',
	'\u24DB': 'l',
	'\uFF4C': 'l',
	'\u0140': 'l',
	'\u013A': 'l',
	'\u013E': 'l',
	'\u1E37': 'l',
	'\u1E39': 'l',
	'\u013C': 'l',
	'\u1E3D': 'l',
	'\u1E3B': 'l',
	'\u017F': 'l',
	'\u0142': 'l',
	'\u019A': 'l',
	'\u026B': 'l',
	'\u2C61': 'l',
	'\uA749': 'l',
	'\uA781': 'l',
	'\uA747': 'l',
	'\u01C9': 'lj',
	'\u24DC': 'm',
	'\uFF4D': 'm',
	'\u1E3F': 'm',
	'\u1E41': 'm',
	'\u1E43': 'm',
	'\u0271': 'm',
	'\u026F': 'm',
	'\u24DD': 'n',
	'\uFF4E': 'n',
	'\u01F9': 'n',
	'\u0144': 'n',
	'\u00F1': 'n',
	'\u1E45': 'n',
	'\u0148': 'n',
	'\u1E47': 'n',
	'\u0146': 'n',
	'\u1E4B': 'n',
	'\u1E49': 'n',
	'\u019E': 'n',
	'\u0272': 'n',
	'\u0149': 'n',
	'\uA791': 'n',
	'\uA7A5': 'n',
	'\u01CC': 'nj',
	'\u24DE': 'o',
	'\uFF4F': 'o',
	'\u00F2': 'o',
	'\u00F3': 'o',
	'\u00F4': 'o',
	'\u1ED3': 'o',
	'\u1ED1': 'o',
	'\u1ED7': 'o',
	'\u1ED5': 'o',
	'\u00F5': 'o',
	'\u1E4D': 'o',
	'\u022D': 'o',
	'\u1E4F': 'o',
	'\u014D': 'o',
	'\u1E51': 'o',
	'\u1E53': 'o',
	'\u014F': 'o',
	'\u022F': 'o',
	'\u0231': 'o',
	'\u00F6': 'o',
	'\u022B': 'o',
	'\u1ECF': 'o',
	'\u0151': 'o',
	'\u01D2': 'o',
	'\u020D': 'o',
	'\u020F': 'o',
	'\u01A1': 'o',
	'\u1EDD': 'o',
	'\u1EDB': 'o',
	'\u1EE1': 'o',
	'\u1EDF': 'o',
	'\u1EE3': 'o',
	'\u1ECD': 'o',
	'\u1ED9': 'o',
	'\u01EB': 'o',
	'\u01ED': 'o',
	'\u00F8': 'o',
	'\u01FF': 'o',
	'\u0254': 'o',
	'\uA74B': 'o',
	'\uA74D': 'o',
	'\u0275': 'o',
	'\u01A3': 'oi',
	'\u0223': 'ou',
	'\uA74F': 'oo',
	'\u24DF': 'p',
	'\uFF50': 'p',
	'\u1E55': 'p',
	'\u1E57': 'p',
	'\u01A5': 'p',
	'\u1D7D': 'p',
	'\uA751': 'p',
	'\uA753': 'p',
	'\uA755': 'p',
	'\u24E0': 'q',
	'\uFF51': 'q',
	'\u024B': 'q',
	'\uA757': 'q',
	'\uA759': 'q',
	'\u24E1': 'r',
	'\uFF52': 'r',
	'\u0155': 'r',
	'\u1E59': 'r',
	'\u0159': 'r',
	'\u0211': 'r',
	'\u0213': 'r',
	'\u1E5B': 'r',
	'\u1E5D': 'r',
	'\u0157': 'r',
	'\u1E5F': 'r',
	'\u024D': 'r',
	'\u027D': 'r',
	'\uA75B': 'r',
	'\uA7A7': 'r',
	'\uA783': 'r',
	'\u24E2': 's',
	'\uFF53': 's',
	'\u00DF': 's',
	'\u015B': 's',
	'\u1E65': 's',
	'\u015D': 's',
	'\u1E61': 's',
	'\u0161': 's',
	'\u1E67': 's',
	'\u1E63': 's',
	'\u1E69': 's',
	'\u0219': 's',
	'\u015F': 's',
	'\u023F': 's',
	'\uA7A9': 's',
	'\uA785': 's',
	'\u1E9B': 's',
	'\u24E3': 't',
	'\uFF54': 't',
	'\u1E6B': 't',
	'\u1E97': 't',
	'\u0165': 't',
	'\u1E6D': 't',
	'\u021B': 't',
	'\u0163': 't',
	'\u1E71': 't',
	'\u1E6F': 't',
	'\u0167': 't',
	'\u01AD': 't',
	'\u0288': 't',
	'\u2C66': 't',
	'\uA787': 't',
	'\uA729': 'tz',
	'\u24E4': 'u',
	'\uFF55': 'u',
	'\u00F9': 'u',
	'\u00FA': 'u',
	'\u00FB': 'u',
	'\u0169': 'u',
	'\u1E79': 'u',
	'\u016B': 'u',
	'\u1E7B': 'u',
	'\u016D': 'u',
	'\u00FC': 'u',
	'\u01DC': 'u',
	'\u01D8': 'u',
	'\u01D6': 'u',
	'\u01DA': 'u',
	'\u1EE7': 'u',
	'\u016F': 'u',
	'\u0171': 'u',
	'\u01D4': 'u',
	'\u0215': 'u',
	'\u0217': 'u',
	'\u01B0': 'u',
	'\u1EEB': 'u',
	'\u1EE9': 'u',
	'\u1EEF': 'u',
	'\u1EED': 'u',
	'\u1EF1': 'u',
	'\u1EE5': 'u',
	'\u1E73': 'u',
	'\u0173': 'u',
	'\u1E77': 'u',
	'\u1E75': 'u',
	'\u0289': 'u',
	'\u24E5': 'v',
	'\uFF56': 'v',
	'\u1E7D': 'v',
	'\u1E7F': 'v',
	'\u028B': 'v',
	'\uA75F': 'v',
	'\u028C': 'v',
	'\uA761': 'vy',
	'\u24E6': 'w',
	'\uFF57': 'w',
	'\u1E81': 'w',
	'\u1E83': 'w',
	'\u0175': 'w',
	'\u1E87': 'w',
	'\u1E85': 'w',
	'\u1E98': 'w',
	'\u1E89': 'w',
	'\u2C73': 'w',
	'\u24E7': 'x',
	'\uFF58': 'x',
	'\u1E8B': 'x',
	'\u1E8D': 'x',
	'\u24E8': 'y',
	'\uFF59': 'y',
	'\u1EF3': 'y',
	'\u00FD': 'y',
	'\u0177': 'y',
	'\u1EF9': 'y',
	'\u0233': 'y',
	'\u1E8F': 'y',
	'\u00FF': 'y',
	'\u1EF7': 'y',
	'\u1E99': 'y',
	'\u1EF5': 'y',
	'\u01B4': 'y',
	'\u024F': 'y',
	'\u1EFF': 'y',
	'\u24E9': 'z',
	'\uFF5A': 'z',
	'\u017A': 'z',
	'\u1E91': 'z',
	'\u017C': 'z',
	'\u017E': 'z',
	'\u1E93': 'z',
	'\u1E95': 'z',
	'\u01B6': 'z',
	'\u0225': 'z',
	'\u0240': 'z',
	'\u2C6C': 'z',
	'\uA763': 'z',
	'\u0386': '\u0391',
	'\u0388': '\u0395',
	'\u0389': '\u0397',
	'\u038A': '\u0399',
	'\u03AA': '\u0399',
	'\u038C': '\u039F',
	'\u038E': '\u03A5',
	'\u03AB': '\u03A5',
	'\u038F': '\u03A9',
	'\u03AC': '\u03B1',
	'\u03AD': '\u03B5',
	'\u03AE': '\u03B7',
	'\u03AF': '\u03B9',
	'\u03CA': '\u03B9',
	'\u0390': '\u03B9',
	'\u03CC': '\u03BF',
	'\u03CD': '\u03C5',
	'\u03CB': '\u03C5',
	'\u03B0': '\u03C5',
	'\u03C9': '\u03C9',
	'\u03C2': '\u03C3'
  };

  return diacritics;
});

S2.define('select2/data/base',[
  '../utils'
], function (Utils) {
  function BaseAdapter ($element, options) {
	BaseAdapter.__super__.constructor.call(this);
  }

  Utils.Extend(BaseAdapter, Utils.Observable);

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

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

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

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

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

	id += Utils.generateChars(4);

	if (data.id != null) {
	  id += '-' + data.id.toString();
	} else {
	  id += '-' + Utils.generateChars(4);
	}
	return id;
  };

  return BaseAdapter;
});

S2.define('select2/data/select',[
  './base',
  '../utils',
  'jquery'
], function (BaseAdapter, Utils, $) {
  function SelectAdapter ($element, options) {
	this.$element = $element;
	this.options = options;

	SelectAdapter.__super__.constructor.call(this);
  }

  Utils.Extend(SelectAdapter, BaseAdapter);

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

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

	  var option = self.item($option);

	  data.push(option);
	});

	callback(data);
  };

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

	data.selected = true;

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

	  this.$element.trigger('change');

	  return;
	}

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

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

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

		  if ($.inArray(id, val) === -1) {
			val.push(id);
		  }
		}

		self.$element.val(val);
		self.$element.trigger('change');
	  });
	} else {
	  var val = data.id;

	  this.$element.val(val);
	  this.$element.trigger('change');
	}
  };

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

	if (!this.$element.prop('multiple')) {
	  return;
	}

	data.selected = false;

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

	  this.$element.trigger('change');

	  return;
	}

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

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

		if (id !== data.id && $.inArray(id, val) === -1) {
		  val.push(id);
		}
	  }

	  self.$element.val(val);

	  self.$element.trigger('change');
	});
  };

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

	this.container = container;

	container.on('select', function (params) {
	  self.select(params.data);
	});

	container.on('unselect', function (params) {
	  self.unselect(params.data);
	});
  };

  SelectAdapter.prototype.destroy = function () {
	// Remove anything added to child elements
	this.$element.find('*').each(function () {
	  // Remove any custom data set by Select2
	  $.removeData(this, 'data');
	});
  };

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

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

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

	  if (!$option.is('option') && !$option.is('optgroup')) {
		return;
	  }

	  var option = self.item($option);

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

	  if (matches !== null) {
		data.push(matches);
	  }
	});

	callback({
	  results: data
	});
  };

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

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

	if (data.children) {
	  option = document.createElement('optgroup');
	  option.label = data.text;
	} else {
	  option = document.createElement('option');

	  if (option.textContent !== undefined) {
		option.textContent = data.text;
	  } else {
		option.innerText = data.text;
	  }
	}

	if (data.id !== undefined) {
	  option.value = data.id;
	}

	if (data.disabled) {
	  option.disabled = true;
	}

	if (data.selected) {
	  option.selected = true;
	}

	if (data.title) {
	  option.title = data.title;
	}

	var $option = $(option);

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

	// Override the option's data with the combined data
	$.data(option, 'data', normalizedData);

	return $option;
  };

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

	data = $.data($option[0], 'data');

	if (data != null) {
	  return data;
	}

	if ($option.is('option')) {
	  data = {
		id: $option.val(),
		text: $option.text(),
		disabled: $option.prop('disabled'),
		selected: $option.prop('selected'),
		title: $option.prop('title')
	  };
	} else if ($option.is('optgroup')) {
	  data = {
		text: $option.prop('label'),
		children: [],
		title: $option.prop('title')
	  };

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

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

		var child = this.item($child);

		children.push(child);
	  }

	  data.children = children;
	}

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

	$.data($option[0], 'data', data);

	return data;
  };

  SelectAdapter.prototype._normalizeItem = function (item) {
	if (!$.isPlainObject(item)) {
	  item = {
		id: item,
		text: item
	  };
	}

	item = $.extend({}, {
	  text: ''
	}, item);

	var defaults = {
	  selected: false,
	  disabled: false
	};

	if (item.id != null) {
	  item.id = item.id.toString();
	}

	if (item.text != null) {
	  item.text = item.text.toString();
	}

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

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

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

	return matcher(params, data);
  };

  return SelectAdapter;
});

S2.define('select2/data/array',[
  './select',
  '../utils',
  'jquery'
], function (SelectAdapter, Utils, $) {
  function ArrayAdapter ($element, options) {
	var data = options.get('data') || [];

	ArrayAdapter.__super__.constructor.call(this, $element, options);

	this.addOptions(this.convertToOptions(data));
  }

  Utils.Extend(ArrayAdapter, SelectAdapter);

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

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

	  this.addOptions($option);
	}

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

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

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

	var $options = [];

	// Filter out all items except for the one passed in the argument
	function onlyItem (item) {
	  return function () {
		return $(this).val() == item.id;
	  };
	}

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

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

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

		var $newOption = this.option(newData);

		$existingOption.replaceWith($newOption);

		continue;
	  }

	  var $option = this.option(item);

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

		Utils.appendMany($option, $children);
	  }

	  $options.push($option);
	}

	return $options;
  };

  return ArrayAdapter;
});

S2.define('select2/data/ajax',[
  './array',
  '../utils',
  'jquery'
], function (ArrayAdapter, Utils, $) {
  function AjaxAdapter ($element, options) {
	this.ajaxOptions = this._applyDefaults(options.get('ajax'));

	if (this.ajaxOptions.processResults != null) {
	  this.processResults = this.ajaxOptions.processResults;
	}

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

  Utils.Extend(AjaxAdapter, ArrayAdapter);

  AjaxAdapter.prototype._applyDefaults = function (options) {
	var defaults = {
	  data: function (params) {
		return $.extend({}, params, {
		  q: params.term
		});
	  },
	  transport: function (params, success, failure) {
		var $request = $.ajax(params);

		$request.then(success);
		$request.fail(failure);

		return $request;
	  }
	};

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

  AjaxAdapter.prototype.processResults = function (results) {
	return results;
  };

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

	if (this._request != null) {
	  // JSONP requests cannot always be aborted
	  if ($.isFunction(this._request.abort)) {
		this._request.abort();
	  }

	  this._request = null;
	}

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

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

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

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

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

		callback(results);
	  }, function () {
		// Attempt to detect if a request was aborted
		// Only works if the transport exposes a status property
		if ($request.status && $request.status === '0') {
		  return;
		}

		self.trigger('results:message', {
		  message: 'errorLoading'
		});
	  });

	  self._request = $request;
	}

	if (this.ajaxOptions.delay && params.term != null) {
	  if (this._queryTimeout) {
		window.clearTimeout(this._queryTimeout);
	  }

	  this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
	} else {
	  request();
	}
  };

  return AjaxAdapter;
});

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

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

	if (createTag !== undefined) {
	  this.createTag = createTag;
	}

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

	if (insertTag !== undefined) {
		this.insertTag = insertTag;
	}

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

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

		var $option = this.option(item);

		this.$element.append($option);
	  }
	}
  }

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

	this._removeOldTags();

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

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

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

		var checkChildren = (
		  option.children != null &&
		  !wrapper({
			results: option.children
		  }, true)
		);

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

		var checkText = optionText === paramsTerm;

		if (checkText || checkChildren) {
		  if (child) {
			return false;
		  }

		  obj.data = data;
		  callback(obj);

		  return;
		}
	  }

	  if (child) {
		return true;
	  }

	  var tag = self.createTag(params);

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

		self.addOptions([$option]);

		self.insertTag(data, tag);
	  }

	  obj.results = data;

	  callback(obj);
	}

	decorated.call(this, params, wrapper);
  };

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

	if (term === '') {
	  return null;
	}

	return {
	  id: term,
	  text: term
	};
  };

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

  Tags.prototype._removeOldTags = function (_) {
	var tag = this._lastTag;

	var $options = this.$element.find('option[data-select2-tag]');

	$options.each(function () {
	  if (this.selected) {
		return;
	  }

	  $(this).remove();
	});
  };

  return Tags;
});

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

	if (tokenizer !== undefined) {
	  this.tokenizer = tokenizer;
	}

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

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

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

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

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

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

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

		self._removeOldTags();
		self.addOptions([$option]);
	  }

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

	function select (data) {
	  self.trigger('select', {
		data: data
	  });
	}

	params.term = params.term || '';

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

	if (tokenData.term !== params.term) {
	  // Replace the search term if we have the search box
	  if (this.$search.length) {
		this.$search.val(tokenData.term);
		this.$search.focus();
	  }

	  params.term = tokenData.term;
	}

	decorated.call(this, params, callback);
  };

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

	var createTag = this.createTag || function (params) {
	  return {
		id: params.term,
		text: params.term
	  };
	};

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

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

		continue;
	  }

	  var part = term.substr(0, i);
	  var partParams = $.extend({}, params, {
		term: part
	  });

	  var data = createTag(partParams);

	  if (data == null) {
		i++;
		continue;
	  }

	  callback(data);

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

	return {
	  term: term
	};
  };

  return Tokenizer;
});

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

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

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

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

	if (params.term.length < this.minimumInputLength) {
	  this.trigger('results:message', {
		message: 'inputTooShort',
		args: {
		  minimum: this.minimumInputLength,
		  input: params.term,
		  params: params
		}
	  });

	  return;
	}

	decorated.call(this, params, callback);
  };

  return MinimumInputLength;
});

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

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

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

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

	if (this.maximumInputLength > 0 &&
		params.term.length > this.maximumInputLength) {
	  this.trigger('results:message', {
		message: 'inputTooLong',
		args: {
		  maximum: this.maximumInputLength,
		  input: params.term,
		  params: params
		}
	  });

	  return;
	}

	decorated.call(this, params, callback);
  };

  return MaximumInputLength;
});

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

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

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

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

	  this.current(function (currentData) {
		var count = currentData != null ? currentData.length : 0;
		if (self.maximumSelectionLength > 0 &&
		  count >= self.maximumSelectionLength) {
		  self.trigger('results:message', {
			message: 'maximumSelected',
			args: {
			  maximum: self.maximumSelectionLength
			}
		  });
		  return;
		}
		decorated.call(self, params, callback);
	  });
  };

  return MaximumSelectionLength;
});

S2.define('select2/dropdown',[
  'jquery',
  './utils'
], function ($, Utils) {
  function Dropdown ($element, options) {
	this.$element = $element;
	this.options = options;

	Dropdown.__super__.constructor.call(this);
  }

  Utils.Extend(Dropdown, Utils.Observable);

  Dropdown.prototype.render = function () {
	var $dropdown = $(
	  '<span class="select2-dropdown">' +
		'<span class="select2-results"></span>' +
	  '</span>'
	);

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

	this.$dropdown = $dropdown;

	return $dropdown;
  };

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

  Dropdown.prototype.position = function ($dropdown, $container) {
	// Should be implmented in subclasses
  };

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

  return Dropdown;
});

S2.define('select2/dropdown/search',[
  'jquery',
  '../utils'
], function ($, Utils) {
  function Search () { }

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

	var $search = $(
	  '<span class="select2-search select2-search--dropdown">' +
		'<input class="select2-search__field" type="search" tabindex="-1"' +
		' autocomplete="off" autocorrect="off" autocapitalize="off"' +
		' spellcheck="false" role="textbox" />' +
	  '</span>'
	);

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

	$rendered.prepend($search);

	return $rendered;
  };

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

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

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

	  self._keyUpPrevented = evt.isDefaultPrevented();
	});

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

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

	container.on('open', function () {
	  self.$search.attr('tabindex', 0);

	  self.$search.focus();

	  window.setTimeout(function () {
		self.$search.focus();
	  }, 0);
	});

	container.on('close', function () {
	  self.$search.attr('tabindex', -1);

	  self.$search.val('');
	});

	container.on('focus', function () {
	  if (container.isOpen()) {
		self.$search.focus();
	  }
	});

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

		if (showSearch) {
		  self.$searchContainer.removeClass('select2-search--hide');
		} else {
		  self.$searchContainer.addClass('select2-search--hide');
		}
	  }
	});
  };

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

	  this.trigger('query', {
		term: input
	  });
	}

	this._keyUpPrevented = false;
  };

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

  return Search;
});

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

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

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

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

	decorated.call(this, data);
  };

  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
	if (typeof placeholder === 'string') {
	  placeholder = {
		id: '',
		text: placeholder
	  };
	}

	return placeholder;
  };

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

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

	  if (this.placeholder.id === item.id) {
		modifiedData.splice(d, 1);
	  }
	}

	return modifiedData;
  };

  return HidePlaceholder;
});

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

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

	this.$loadingMore = this.createLoadingMore();
	this.loading = false;
  }

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

	decorated.call(this, data);

	if (this.showLoadingMore(data)) {
	  this.$results.append(this.$loadingMore);
	}
  };

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

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

	container.on('query', function (params) {
	  self.lastParams = params;
	  self.loading = true;
	});

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

	this.$results.on('scroll', function () {
	  var isLoadMoreVisible = $.contains(
		document.documentElement,
		self.$loadingMore[0]
	  );

	  if (self.loading || !isLoadMoreVisible) {
		return;
	  }

	  var currentOffset = self.$results.offset().top +
		self.$results.outerHeight(false);
	  var loadingMoreOffset = self.$loadingMore.offset().top +
		self.$loadingMore.outerHeight(false);

	  if (currentOffset + 50 >= loadingMoreOffset) {
		self.loadMore();
	  }
	});
  };

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

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

	params.page++;

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

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

  InfiniteScroll.prototype.createLoadingMore = function () {
	var $option = $(
	  '<li ' +
	  'class="select2-results__option select2-results__option--load-more"' +
	  'role="treeitem" aria-disabled="true"></li>'
	);

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

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

	return $option;
  };

  return InfiniteScroll;
});

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

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

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

	var setupResultsEvents = false;

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

	container.on('open', function () {
	  self._showDropdown();
	  self._attachPositioningHandler(container);

	  if (!setupResultsEvents) {
		setupResultsEvents = true;

		container.on('results:all', function () {
		  self._positionDropdown();
		  self._resizeDropdown();
		});

		container.on('results:append', function () {
		  self._positionDropdown();
		  self._resizeDropdown();
		});
	  }
	});

	container.on('close', function () {
	  self._hideDropdown();
	  self._detachPositioningHandler(container);
	});

	this.$dropdownContainer.on('mousedown', function (evt) {
	  evt.stopPropagation();
	});
  };

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

	this.$dropdownContainer.remove();
  };

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

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

	$dropdown.css({
	  position: 'absolute',
	  top: -999999
	});

	this.$container = $container;
  };

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

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

	this.$dropdownContainer = $container;

	return $container;
  };

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

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

	var scrollEvent = 'scroll.select2.' + container.id;
	var resizeEvent = 'resize.select2.' + container.id;
	var orientationEvent = 'orientationchange.select2.' + container.id;

	var $watchers = this.$container.parents().filter(Utils.hasScroll);
	$watchers.each(function () {
	  $(this).data('select2-scroll-position', {
		x: $(this).scrollLeft(),
		y: $(this).scrollTop()
	  });
	});

	$watchers.on(scrollEvent, function (ev) {
	  var position = $(this).data('select2-scroll-position');
	  $(this).scrollTop(position.y);
	});

	$(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
	  function (e) {
	  self._positionDropdown();
	  self._resizeDropdown();
	});
  };

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

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

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

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

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

	var newDirection = null;

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

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

	var container = {
	  height: this.$container.outerHeight(false)
	};

	container.top = offset.top;
	container.bottom = offset.top + container.height;

	var dropdown = {
	  height: this.$dropdown.outerHeight(false)
	};

	var viewport = {
	  top: $window.scrollTop(),
	  bottom: $window.scrollTop() + $window.height()
	};

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

	var css = {
	  left: offset.left,
	  top: container.bottom
	};

	// Determine what the parent element is to use for calciulating the offset
	var $offsetParent = this.$dropdownParent;

	// For statically positoned elements, we need to get the element
	// that is determining the offset
	if ($offsetParent.css('position') === 'static') {
	  $offsetParent = $offsetParent.offsetParent();
	}

	var parentOffset = $offsetParent.offset();

	css.top -= parentOffset.top;
	css.left -= parentOffset.left;

	if (!isCurrentlyAbove && !isCurrentlyBelow) {
	  newDirection = 'below';
	}

	if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
	  newDirection = 'above';
	} else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
	  newDirection = 'below';
	}

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

	if (newDirection != null) {
	  this.$dropdown
		.removeClass('select2-dropdown--below select2-dropdown--above')
		.addClass('select2-dropdown--' + newDirection);
	  this.$container
		.removeClass('select2-container--below select2-container--above')
		.addClass('select2-container--' + newDirection);
	}

	this.$dropdownContainer.css(css);
  };

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

	if (this.options.get('dropdownAutoWidth')) {
	  css.minWidth = css.width;
	  css.position = 'relative';
	  css.width = 'auto';
	}

	this.$dropdown.css(css);
  };

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

	this._positionDropdown();
	this._resizeDropdown();
  };

  return AttachBody;
});

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

], function () {
  function countResults (data) {
	var count = 0;

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

	  if (item.children) {
		count += countResults(item.children);
	  } else {
		count++;
	  }
	}

	return count;
  }

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

	if (this.minimumResultsForSearch < 0) {
	  this.minimumResultsForSearch = Infinity;
	}

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

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

	return decorated.call(this, params);
  };

  return MinimumResultsForSearch;
});

S2.define('select2/dropdown/selectOnClose',[

], function () {
  function SelectOnClose () { }

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

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

	container.on('close', function (params) {
	  self._handleSelectOnClose(params);
	});
  };

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

	  // Don't select an item if the close event was triggered from a select or
	  // unselect event
	  if (event._type === 'select' || event._type === 'unselect') {
		return;
	  }
	}

	var $highlightedResults = this.getHighlightedResults();

	// Only select highlighted results
	if ($highlightedResults.length < 1) {
	  return;
	}

	var data = $highlightedResults.data('data');

	// Don't re-select already selected resulte
	if (
	  (data.element != null && data.element.selected) ||
	  (data.element == null && data.selected)
	) {
	  return;
	}

	this.trigger('select', {
		data: data
	});
  };

  return SelectOnClose;
});

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

], function () {
  function CloseOnSelect () { }

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

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

	container.on('select', function (evt) {
	  self._selectTriggered(evt);
	});

	container.on('unselect', function (evt) {
	  self._selectTriggered(evt);
	});
  };

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

	// Don't close if the control key is being held
	if (originalEvent && originalEvent.ctrlKey) {
	  return;
	}

	this.trigger('close', {
	  originalEvent: originalEvent,
	  originalSelect2Event: evt
	});
  };

  return CloseOnSelect;
});

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

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

	  if (overChars != 1) {
		message += 's';
	  }

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

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

	  return message;
	},
	loadingMore: function () {
	  return 'Loading more results…';
	},
	maximumSelected: function (args) {
	  var message = 'You can only select ' + args.maximum + ' item';

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

	  return message;
	},
	noResults: function () {
	  return 'No results found';
	},
	searching: function () {
	  return 'Searching…';
	}
  };
});

S2.define('select2/defaults',[
  'jquery',
  'require',

  './results',

  './selection/single',
  './selection/multiple',
  './selection/placeholder',
  './selection/allowClear',
  './selection/search',
  './selection/eventRelay',

  './utils',
  './translation',
  './diacritics',

  './data/select',
  './data/array',
  './data/ajax',
  './data/tags',
  './data/tokenizer',
  './data/minimumInputLength',
  './data/maximumInputLength',
  './data/maximumSelectionLength',

  './dropdown',
  './dropdown/search',
  './dropdown/hidePlaceholder',
  './dropdown/infiniteScroll',
  './dropdown/attachBody',
  './dropdown/minimumResultsForSearch',
  './dropdown/selectOnClose',
  './dropdown/closeOnSelect',

  './i18n/en'
], function ($, require,

			 ResultsList,

			 SingleSelection, MultipleSelection, Placeholder, AllowClear,
			 SelectionSearch, EventRelay,

			 Utils, Translation, DIACRITICS,

			 SelectData, ArrayData, AjaxData, Tags, Tokenizer,
			 MinimumInputLength, MaximumInputLength, MaximumSelectionLength,

			 Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
			 AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,

			 EnglishTranslation) {
  function Defaults () {
	this.reset();
  }

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

	if (options.dataAdapter == null) {
	  if (options.ajax != null) {
		options.dataAdapter = AjaxData;
	  } else if (options.data != null) {
		options.dataAdapter = ArrayData;
	  } else {
		options.dataAdapter = SelectData;
	  }

	  if (options.minimumInputLength > 0) {
		options.dataAdapter = Utils.Decorate(
		  options.dataAdapter,
		  MinimumInputLength
		);
	  }

	  if (options.maximumInputLength > 0) {
		options.dataAdapter = Utils.Decorate(
		  options.dataAdapter,
		  MaximumInputLength
		);
	  }

	  if (options.maximumSelectionLength > 0) {
		options.dataAdapter = Utils.Decorate(
		  options.dataAdapter,
		  MaximumSelectionLength
		);
	  }

	  if (options.tags) {
		options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
	  }

	  if (options.tokenSeparators != null || options.tokenizer != null) {
		options.dataAdapter = Utils.Decorate(
		  options.dataAdapter,
		  Tokenizer
		);
	  }

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

		options.dataAdapter = Utils.Decorate(
		  options.dataAdapter,
		  Query
		);
	  }

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

		options.dataAdapter = Utils.Decorate(
		  options.dataAdapter,
		  InitSelection
		);
	  }
	}

	if (options.resultsAdapter == null) {
	  options.resultsAdapter = ResultsList;

	  if (options.ajax != null) {
		options.resultsAdapter = Utils.Decorate(
		  options.resultsAdapter,
		  InfiniteScroll
		);
	  }

	  if (options.placeholder != null) {
		options.resultsAdapter = Utils.Decorate(
		  options.resultsAdapter,
		  HidePlaceholder
		);
	  }

	  if (options.selectOnClose) {
		options.resultsAdapter = Utils.Decorate(
		  options.resultsAdapter,
		  SelectOnClose
		);
	  }
	}

	if (options.dropdownAdapter == null) {
	  if (options.multiple) {
		options.dropdownAdapter = Dropdown;
	  } else {
		var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);

		options.dropdownAdapter = SearchableDropdown;
	  }

	  if (options.minimumResultsForSearch !== 0) {
		options.dropdownAdapter = Utils.Decorate(
		  options.dropdownAdapter,
		  MinimumResultsForSearch
		);
	  }

	  if (options.closeOnSelect) {
		options.dropdownAdapter = Utils.Decorate(
		  options.dropdownAdapter,
		  CloseOnSelect
		);
	  }

	  if (
		options.dropdownCssClass != null ||
		options.dropdownCss != null ||
		options.adaptDropdownCssClass != null
	  ) {
		var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');

		options.dropdownAdapter = Utils.Decorate(
		  options.dropdownAdapter,
		  DropdownCSS
		);
	  }

	  options.dropdownAdapter = Utils.Decorate(
		options.dropdownAdapter,
		AttachBody
	  );
	}

	if (options.selectionAdapter == null) {
	  if (options.multiple) {
		options.selectionAdapter = MultipleSelection;
	  } else {
		options.selectionAdapter = SingleSelection;
	  }

	  // Add the placeholder mixin if a placeholder was specified
	  if (options.placeholder != null) {
		options.selectionAdapter = Utils.Decorate(
		  options.selectionAdapter,
		  Placeholder
		);
	  }

	  if (options.allowClear) {
		options.selectionAdapter = Utils.Decorate(
		  options.selectionAdapter,
		  AllowClear
		);
	  }

	  if (options.multiple) {
		options.selectionAdapter = Utils.Decorate(
		  options.selectionAdapter,
		  SelectionSearch
		);
	  }

	  if (
		options.containerCssClass != null ||
		options.containerCss != null ||
		options.adaptContainerCssClass != null
	  ) {
		var ContainerCSS = require(options.amdBase + 'compat/containerCss');

		options.selectionAdapter = Utils.Decorate(
		  options.selectionAdapter,
		  ContainerCSS
		);
	  }

	  options.selectionAdapter = Utils.Decorate(
		options.selectionAdapter,
		EventRelay
	  );
	}

	if (typeof options.language === 'string') {
	  // Check if the language is specified with a region
	  if (options.language.indexOf('-') > 0) {
		// Extract the region information if it is included
		var languageParts = options.language.split('-');
		var baseLanguage = languageParts[0];

		options.language = [options.language, baseLanguage];
	  } else {
		options.language = [options.language];
	  }
	}

	if ($.isArray(options.language)) {
	  var languages = new Translation();
	  options.language.push('en');

	  var languageNames = options.language;

	  for (var l = 0; l < languageNames.length; l++) {
		var name = languageNames[l];
		var language = {};

		try {
		  // Try to load it with the original name
		  language = Translation.loadPath(name);
		} catch (e) {
		  try {
			// If we couldn't load it, check if it wasn't the full path
			name = this.defaults.amdLanguageBase + name;
			language = Translation.loadPath(name);
		  } catch (ex) {
			// The translation could not be loaded at all. Sometimes this is
			// because of a configuration problem, other times this can be
			// because of how Select2 helps load all possible translation files.
			if (options.debug && window.console && console.warn) {
			  console.warn(
				'Select2: The language file for "' + name + '" could not be ' +
				'automatically loaded. A fallback will be used instead.'
			  );
			}

			continue;
		  }
		}

		languages.extend(language);
	  }

	  options.translations = languages;
	} else {
	  var baseTranslation = Translation.loadPath(
		this.defaults.amdLanguageBase + 'en'
	  );
	  var customTranslation = new Translation(options.language);

	  customTranslation.extend(baseTranslation);

	  options.translations = customTranslation;
	}

	return options;
  };

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

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

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

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

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

		  var matches = matcher(params, child);

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

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

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

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

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

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

	this.defaults = {
	  amdBase: './',
	  amdLanguageBase: './i18n/',
	  closeOnSelect: true,
	  debug: false,
	  dropdownAutoWidth: false,
	  escapeMarkup: Utils.escapeMarkup,
	  language: EnglishTranslation,
	  matcher: matcher,
	  minimumInputLength: 0,
	  maximumInputLength: 0,
	  maximumSelectionLength: 0,
	  minimumResultsForSearch: 0,
	  selectOnClose: false,
	  sorter: function (data) {
		return data;
	  },
	  templateResult: function (result) {
		return result.text;
	  },
	  templateSelection: function (selection) {
		return selection.text;
	  },
	  theme: 'default',
	  width: 'resolve'
	};
  };

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

	var data = {};
	data[camelKey] = value;

	var convertedData = Utils._convertData(data);

	$.extend(this.defaults, convertedData);
  };

  var defaults = new Defaults();

  return defaults;
});

S2.define('select2/options',[
  'require',
  'jquery',
  './defaults',
  './utils'
], function (require, $, Defaults, Utils) {
  function Options (options, $element) {
	this.options = options;

	if ($element != null) {
	  this.fromElement($element);
	}

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

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

	  this.options.dataAdapter = Utils.Decorate(
		this.options.dataAdapter,
		InputCompat
	  );
	}
  }

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

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

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

	if (this.options.language == null) {
	  if ($e.prop('lang')) {
		this.options.language = $e.prop('lang').toLowerCase();
	  } else if ($e.closest('[lang]').prop('lang')) {
		this.options.language = $e.closest('[lang]').prop('lang');
	  }
	}

	if (this.options.dir == null) {
	  if ($e.prop('dir')) {
		this.options.dir = $e.prop('dir');
	  } else if ($e.closest('[dir]').prop('dir')) {
		this.options.dir = $e.closest('[dir]').prop('dir');
	  } else {
		this.options.dir = 'ltr';
	  }
	}

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

	if ($e.data('select2Tags')) {
	  if (this.options.debug && window.console && console.warn) {
		console.warn(
		  'Select2: The `data-select2-tags` attribute has been changed to ' +
		  'use the `data-data` and `data-tags="true"` attributes and will be ' +
		  'removed in future versions of Select2.'
		);
	  }

	  $e.data('data', $e.data('select2Tags'));
	  $e.data('tags', true);
	}

	if ($e.data('ajaxUrl')) {
	  if (this.options.debug && window.console && console.warn) {
		console.warn(
		  'Select2: The `data-ajax-url` attribute has been changed to ' +
		  '`data-ajax--url` and support for the old attribute will be removed' +
		  ' in future versions of Select2.'
		);
	  }

	  $e.attr('ajax--url', $e.data('ajaxUrl'));
	  $e.data('ajax--url', $e.data('ajaxUrl'));
	}

	var dataset = {};

	// Prefer the element's `dataset` attribute if it exists
	// jQuery 1.x does not correctly handle data attributes with multiple dashes
	if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
	  dataset = $.extend(true, {}, $e[0].dataset, $e.data());
	} else {
	  dataset = $e.data();
	}

	var data = $.extend(true, {}, dataset);

	data = Utils._convertData(data);

	for (var key in data) {
	  if ($.inArray(key, excludedData) > -1) {
		continue;
	  }

	  if ($.isPlainObject(this.options[key])) {
		$.extend(this.options[key], data[key]);
	  } else {
		this.options[key] = data[key];
	  }
	}

	return this;
  };

  Options.prototype.get = function (key) {
	return this.options[key];
  };

  Options.prototype.set = function (key, val) {
	this.options[key] = val;
  };

  return Options;
});

S2.define('select2/core',[
  'jquery',
  './options',
  './utils',
  './keys'
], function ($, Options, Utils, KEYS) {
  var Select2 = function ($element, options) {
	if ($element.data('select2') != null) {
	  $element.data('select2').destroy();
	}

	this.$element = $element;

	this.id = this._generateId($element);

	options = options || {};

	this.options = new Options(options, $element);

	Select2.__super__.constructor.call(this);

	// Set up the tabindex

	var tabindex = $element.attr('tabindex') || 0;
	$element.data('old-tabindex', tabindex);
	$element.attr('tabindex', '-1');

	// Set up containers and adapters

	var DataAdapter = this.options.get('dataAdapter');
	this.dataAdapter = new DataAdapter($element, this.options);

	var $container = this.render();

	this._placeContainer($container);

	var SelectionAdapter = this.options.get('selectionAdapter');
	this.selection = new SelectionAdapter($element, this.options);
	this.$selection = this.selection.render();

	this.selection.position(this.$selection, $container);

	var DropdownAdapter = this.options.get('dropdownAdapter');
	this.dropdown = new DropdownAdapter($element, this.options);
	this.$dropdown = this.dropdown.render();

	this.dropdown.position(this.$dropdown, $container);

	var ResultsAdapter = this.options.get('resultsAdapter');
	this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
	this.$results = this.results.render();

	this.results.position(this.$results, this.$dropdown);

	// Bind events

	var self = this;

	// Bind the container to all of the adapters
	this._bindAdapters();

	// Register any DOM event handlers
	this._registerDomEvents();

	// Register any internal event handlers
	this._registerDataEvents();
	this._registerSelectionEvents();
	this._registerDropdownEvents();
	this._registerResultsEvents();
	this._registerEvents();

	// Set the initial state
	this.dataAdapter.current(function (initialData) {
	  self.trigger('selection:update', {
		data: initialData
	  });
	});

	// Hide the original select
	$element.addClass('select2-hidden-accessible');
	$element.attr('aria-hidden', 'true');

	// Synchronize any monitored attributes
	this._syncAttributes();

	$element.data('select2', this);
  };

  Utils.Extend(Select2, Utils.Observable);

  Select2.prototype._generateId = function ($element) {
	var id = '';

	if ($element.attr('id') != null) {
	  id = $element.attr('id');
	} else if ($element.attr('name') != null) {
	  id = $element.attr('name') + '-' + Utils.generateChars(2);
	} else {
	  id = Utils.generateChars(4);
	}

	id = id.replace(/(:|\.|\[|\]|,)/g, '');
	id = 'select2-' + id;

	return id;
  };

  Select2.prototype._placeContainer = function ($container) {
	$container.insertAfter(this.$element);

	var width = this._resolveWidth(this.$element, this.options.get('width'));

	if (width != null) {
	  $container.css('width', width);
	}
  };

  Select2.prototype._resolveWidth = function ($element, method) {
	var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;

	if (method == 'resolve') {
	  var styleWidth = this._resolveWidth($element, 'style');

	  if (styleWidth != null) {
		return styleWidth;
	  }

	  return this._resolveWidth($element, 'element');
	}

	if (method == 'element') {
	  var elementWidth = $element.outerWidth(false);

	  if (elementWidth <= 0) {
		return 'auto';
	  }

	  return elementWidth + 'px';
	}

	if (method == 'style') {
	  var style = $element.attr('style');

	  if (typeof(style) !== 'string') {
		return null;
	  }

	  var attrs = style.split(';');

	  for (var i = 0, l = attrs.length; i < l; i = i + 1) {
		var attr = attrs[i].replace(/\s/g, '');
		var matches = attr.match(WIDTH);

		if (matches !== null && matches.length >= 1) {
		  return matches[1];
		}
	  }

	  return null;
	}

	return method;
  };

  Select2.prototype._bindAdapters = function () {
	this.dataAdapter.bind(this, this.$container);
	this.selection.bind(this, this.$container);

	this.dropdown.bind(this, this.$container);
	this.results.bind(this, this.$container);
  };

  Select2.prototype._registerDomEvents = function () {
	var self = this;

	this.$element.on('change.select2', function () {
	  self.dataAdapter.current(function (data) {
		self.trigger('selection:update', {
		  data: data
		});
	  });
	});

	this.$element.on('focus.select2', function (evt) {
	  self.trigger('focus', evt);
	});

	this._syncA = Utils.bind(this._syncAttributes, this);
	this._syncS = Utils.bind(this._syncSubtree, this);

	if (this.$element[0].attachEvent) {
	  this.$element[0].attachEvent('onpropertychange', this._syncA);
	}

	var observer = window.MutationObserver ||
	  window.WebKitMutationObserver ||
	  window.MozMutationObserver
	;

	if (observer != null) {
	  this._observer = new observer(function (mutations) {
		$.each(mutations, self._syncA);
		$.each(mutations, self._syncS);
	  });
	  this._observer.observe(this.$element[0], {
		attributes: true,
		childList: true,
		subtree: false
	  });
	} else if (this.$element[0].addEventListener) {
	  this.$element[0].addEventListener(
		'DOMAttrModified',
		self._syncA,
		false
	  );
	  this.$element[0].addEventListener(
		'DOMNodeInserted',
		self._syncS,
		false
	  );
	  this.$element[0].addEventListener(
		'DOMNodeRemoved',
		self._syncS,
		false
	  );
	}
  };

  Select2.prototype._registerDataEvents = function () {
	var self = this;

	this.dataAdapter.on('*', function (name, params) {
	  self.trigger(name, params);
	});
  };

  Select2.prototype._registerSelectionEvents = function () {
	var self = this;
	var nonRelayEvents = ['toggle', 'focus'];

	this.selection.on('toggle', function () {
	  self.toggleDropdown();
	});

	this.selection.on('focus', function (params) {
	  self.focus(params);
	});

	this.selection.on('*', function (name, params) {
	  if ($.inArray(name, nonRelayEvents) !== -1) {
		return;
	  }

	  self.trigger(name, params);
	});
  };

  Select2.prototype._registerDropdownEvents = function () {
	var self = this;

	this.dropdown.on('*', function (name, params) {
	  self.trigger(name, params);
	});
  };

  Select2.prototype._registerResultsEvents = function () {
	var self = this;

	this.results.on('*', function (name, params) {
	  self.trigger(name, params);
	});
  };

  Select2.prototype._registerEvents = function () {
	var self = this;

	this.on('open', function () {
	  self.$container.addClass('select2-container--open');
	});

	this.on('close', function () {
	  self.$container.removeClass('select2-container--open');
	});

	this.on('enable', function () {
	  self.$container.removeClass('select2-container--disabled');
	});

	this.on('disable', function () {
	  self.$container.addClass('select2-container--disabled');
	});

	this.on('blur', function () {
	  self.$container.removeClass('select2-container--focus');
	});

	this.on('query', function (params) {
	  if (!self.isOpen()) {
		self.trigger('open', {});
	  }

	  this.dataAdapter.query(params, function (data) {
		self.trigger('results:all', {
		  data: data,
		  query: params
		});
	  });
	});

	this.on('query:append', function (params) {
	  this.dataAdapter.query(params, function (data) {
		self.trigger('results:append', {
		  data: data,
		  query: params
		});
	  });
	});

	this.on('keypress', function (evt) {
	  var key = evt.which;

	  if (self.isOpen()) {
		if (key === KEYS.ESC || key === KEYS.TAB ||
			(key === KEYS.UP && evt.altKey)) {
		  self.close();

		  evt.preventDefault();
		} else if (key === KEYS.ENTER) {
		  self.trigger('results:select', {});

		  evt.preventDefault();
		} else if ((key === KEYS.SPACE && evt.ctrlKey)) {
		  self.trigger('results:toggle', {});

		  evt.preventDefault();
		} else if (key === KEYS.UP) {
		  self.trigger('results:previous', {});

		  evt.preventDefault();
		} else if (key === KEYS.DOWN) {
		  self.trigger('results:next', {});

		  evt.preventDefault();
		}
	  } else {
		if (key === KEYS.ENTER || key === KEYS.SPACE ||
			(key === KEYS.DOWN && evt.altKey)) {
		  self.open();

		  evt.preventDefault();
		}
	  }
	});
  };

  Select2.prototype._syncAttributes = function () {
	this.options.set('disabled', this.$element.prop('disabled'));

	if (this.options.get('disabled')) {
	  if (this.isOpen()) {
		this.close();
	  }

	  this.trigger('disable', {});
	} else {
	  this.trigger('enable', {});
	}
  };

  Select2.prototype._syncSubtree = function (evt, mutations) {
	var changed = false;
	var self = this;

	// Ignore any mutation events raised for elements that aren't options or
	// optgroups. This handles the case when the select element is destroyed
	if (
	  evt && evt.target && (
		evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
	  )
	) {
	  return;
	}

	if (!mutations) {
	  // If mutation events aren't supported, then we can only assume that the
	  // change affected the selections
	  changed = true;
	} else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
	  for (var n = 0; n < mutations.addedNodes.length; n++) {
		var node = mutations.addedNodes[n];

		if (node.selected) {
		  changed = true;
		}
	  }
	} else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
	  changed = true;
	}

	// Only re-pull the data if we think there is a change
	if (changed) {
	  this.dataAdapter.current(function (currentData) {
		self.trigger('selection:update', {
		  data: currentData
		});
	  });
	}
  };

  /**
   * Override the trigger method to automatically trigger pre-events when
   * there are events that can be prevented.
   */
  Select2.prototype.trigger = function (name, args) {
	var actualTrigger = Select2.__super__.trigger;
	var preTriggerMap = {
	  'open': 'opening',
	  'close': 'closing',
	  'select': 'selecting',
	  'unselect': 'unselecting'
	};

	if (args === undefined) {
	  args = {};
	}

	if (name in preTriggerMap) {
	  var preTriggerName = preTriggerMap[name];
	  var preTriggerArgs = {
		prevented: false,
		name: name,
		args: args
	  };

	  actualTrigger.call(this, preTriggerName, preTriggerArgs);

	  if (preTriggerArgs.prevented) {
		args.prevented = true;

		return;
	  }
	}

	actualTrigger.call(this, name, args);
  };

  Select2.prototype.toggleDropdown = function () {
	if (this.options.get('disabled')) {
	  return;
	}

	if (this.isOpen()) {
	  this.close();
	} else {
	  this.open();
	}
  };

  Select2.prototype.open = function () {
	if (this.isOpen()) {
	  return;
	}

	this.trigger('query', {});
  };

  Select2.prototype.close = function () {
	if (!this.isOpen()) {
	  return;
	}

	this.trigger('close', {});
  };

  Select2.prototype.isOpen = function () {
	return this.$container.hasClass('select2-container--open');
  };

  Select2.prototype.hasFocus = function () {
	return this.$container.hasClass('select2-container--focus');
  };

  Select2.prototype.focus = function (data) {
	// No need to re-trigger focus events if we are already focused
	if (this.hasFocus()) {
	  return;
	}

	this.$container.addClass('select2-container--focus');
	this.trigger('focus', {});
  };

  Select2.prototype.enable = function (args) {
	if (this.options.get('debug') && window.console && console.warn) {
	  console.warn(
		'Select2: The `select2("enable")` method has been deprecated and will' +
		' be removed in later Select2 versions. Use $element.prop("disabled")' +
		' instead.'
	  );
	}

	if (args == null || args.length === 0) {
	  args = [true];
	}

	var disabled = !args[0];

	this.$element.prop('disabled', disabled);
  };

  Select2.prototype.data = function () {
	if (this.options.get('debug') &&
		arguments.length > 0 && window.console && console.warn) {
	  console.warn(
		'Select2: Data can no longer be set using `select2("data")`. You ' +
		'should consider setting the value instead using `$element.val()`.'
	  );
	}

	var data = [];

	this.dataAdapter.current(function (currentData) {
	  data = currentData;
	});

	return data;
  };

  Select2.prototype.val = function (args) {
	if (this.options.get('debug') && window.console && console.warn) {
	  console.warn(
		'Select2: The `select2("val")` method has been deprecated and will be' +
		' removed in later Select2 versions. Use $element.val() instead.'
	  );
	}

	if (args == null || args.length === 0) {
	  return this.$element.val();
	}

	var newVal = args[0];

	if ($.isArray(newVal)) {
	  newVal = $.map(newVal, function (obj) {
		return obj.toString();
	  });
	}

	this.$element.val(newVal).trigger('change');
  };

  Select2.prototype.destroy = function () {
	this.$container.remove();

	if (this.$element[0].detachEvent) {
	  this.$element[0].detachEvent('onpropertychange', this._syncA);
	}

	if (this._observer != null) {
	  this._observer.disconnect();
	  this._observer = null;
	} else if (this.$element[0].removeEventListener) {
	  this.$element[0]
		.removeEventListener('DOMAttrModified', this._syncA, false);
	  this.$element[0]
		.removeEventListener('DOMNodeInserted', this._syncS, false);
	  this.$element[0]
		.removeEventListener('DOMNodeRemoved', this._syncS, false);
	}

	this._syncA = null;
	this._syncS = null;

	this.$element.off('.select2');
	this.$element.attr('tabindex', this.$element.data('old-tabindex'));

	this.$element.removeClass('select2-hidden-accessible');
	this.$element.attr('aria-hidden', 'false');
	this.$element.removeData('select2');

	this.dataAdapter.destroy();
	this.selection.destroy();
	this.dropdown.destroy();
	this.results.destroy();

	this.dataAdapter = null;
	this.selection = null;
	this.dropdown = null;
	this.results = null;
  };

  Select2.prototype.render = function () {
	var $container = $(
	  '<span class="select2 select2-container">' +
		'<span class="selection"></span>' +
		'<span class="dropdown-wrapper" aria-hidden="true"></span>' +
	  '</span>'
	);

	$container.attr('dir', this.options.get('dir'));

	this.$container = $container;

	this.$container.addClass('select2-container--' + this.options.get('theme'));

	$container.data('element', this.$element);

	return $container;
  };

  return Select2;
});

S2.define('jquery-mousewheel',[
  'jquery'
], function ($) {
  // Used to shim jQuery.mousewheel for non-full builds.
  return $;
});

S2.define('jquery.select2',[
  'jquery',
  'jquery-mousewheel',

  './select2/core',
  './select2/defaults'
], function ($, _, Select2, Defaults) {
  if ($.fn.select2 == null) {
	// All methods that should return the element
	var thisMethods = ['open', 'close', 'destroy'];

	$.fn.select2 = function (options) {
	  options = options || {};

	  if (typeof options === 'object') {
		this.each(function () {
		  var instanceOptions = $.extend(true, {}, options);

		  var instance = new Select2($(this), instanceOptions);
		});

		return this;
	  } else if (typeof options === 'string') {
		var ret;
		var args = Array.prototype.slice.call(arguments, 1);

		this.each(function () {
		  var instance = $(this).data('select2');

		  if (instance == null && window.console && console.error) {
			console.error(
			  'The select2(\'' + options + '\') method was called on an ' +
			  'element that is not using Select2.'
			);
		  }

		  ret = instance[options].apply(instance, args);
		});

		// Check if we should be returning `this`
		if ($.inArray(options, thisMethods) > -1) {
		  return this;
		}

		return ret;
	  } else {
		throw new Error('Invalid arguments for Select2: ' + options);
	  }
	};
  }

  if ($.fn.select2.defaults == null) {
	$.fn.select2.defaults = Defaults;
  }

  return Select2;
});

  // Return the AMD loader configuration so it can be used outside of this file
  return {
	define: S2.define,
	require: S2.require
  };
}());

  // Autoload the jQuery bindings
  // We know that all of the modules exist above this, so we're safe
  var select2 = S2.require('jquery.select2');

  // Hold the AMD module references on the jQuery function that was just loaded
  // This allows Select2 to use the internal loader outside of this file, such
  // as in the language files.
  jQuery.fn.select2.amd = S2;

  // Return the Select2 instance for anyone who is importing it.
  return select2;
}));
