text: (function ($) {
      if (typeof $.fn.each2 == "undefined") {
          $.fn.extend({
              each2: function (c) {
                  var j = $([0]), i = -1, l = this.length;
                  while (++i < l && (j.context = j[0] = this[i]) && c.call(j[0], i, j) !== false) {
                  }
                  return this
              }
          })
      }
  })(jQuery);
  (function ($, undefined) {
      if (window.Select2 !== undefined) {
          return
      }
      var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer, lastMousePosition, $document, scrollBarDimensions, KEY = {
          TAB: 9,
          ENTER: 13,
          ESC: 27,
          SPACE: 32,
          LEFT: 37,
          UP: 38,
          RIGHT: 39,
          DOWN: 40,
          SHIFT: 16,
          CTRL: 17,
          ALT: 18,
          PAGE_UP: 33,
          PAGE_DOWN: 34,
          HOME: 36,
          END: 35,
          BACKSPACE: 8,
          DELETE: 46,
          isArrow: function (k) {
              k = k.which ? k.which : k;
              switch (k) {
                  case KEY.LEFT:
                  case KEY.RIGHT:
                  case KEY.UP:
                  case KEY.DOWN:
                      return true
              }
              return false
          },
          isControl: function (e) {
              var k = e.which;
              switch (k) {
                  case KEY.SHIFT:
                  case KEY.CTRL:
                  case KEY.ALT:
                      return true
              }
              if (e.metaKey) {
                  return true
              }
              return false
          },
          isFunctionKey: function (k) {
              k = k.which ? k.which : k;
              return k >= 112 && k <= 123
          }
      }, MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>";
      $document = $(document);
      nextUid = (function () {
          var counter = 1;
          return function () {
              return counter++
          }
      }());
      function indexOf(value, array) {
          var i = 0, l = array.length;
          for (; i < l; i = i + 1) {
              if (equal(value, array[i])) {
                  return i
              }
          }
          return -1
      }
  
      function measureScrollbar() {
          var $template = $(MEASURE_SCROLLBAR_TEMPLATE);
          $template.appendTo("body");
          var dim = {
              width: $template.width() - $template[0].clientWidth,
              height: $template.height() - $template[0].clientHeight
          };
          $template.remove();
          return dim
      }
  
      function equal(a, b) {
          if (a === b) {
              return true
          }
          if (a === undefined || b === undefined) {
              return false
          }
          if (a === null || b === null) {
              return false
          }
          if (a.constructor === String) {
              return a + "" === b + ""
          }
          if (b.constructor === String) {
              return b + "" === a + ""
          }
          return false
      }
  
      function splitVal(string, separator) {
          var val, i, l;
          if (string === null || string.length < 1) {
              return []
          }
          val = string.split(separator);
          for (i = 0, l = val.length; i < l; i = i + 1) {
              val[i] = $.trim(val[i])
          }
          return val
      }
  
      function getSideBorderPadding(element) {
          return element.outerWidth(false) - element.width()
      }
  
      function installKeyUpChangeEvent(element) {
          var key = "keyup-change-value";
          element.on("keydown", function () {
              if ($.data(element, key) === undefined) {
                  $.data(element, key, element.val())
              }
          });
          element.on("keyup", function () {
              var val = $.data(element, key);
              if (val !== undefined && element.val() !== val) {
                  $.removeData(element, key);
                  element.trigger("keyup-change")
              }
          })
      }
  
      $document.on("mousemove", function (e) {
          lastMousePosition = {x: e.pageX, y: e.pageY}
      });
      function installFilteredMouseMove(element) {
          element.on("mousemove", function (e) {
              var lastpos = lastMousePosition;
              if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
                  $(e.target).trigger("mousemove-filtered", e)
              }
          })
      }
  
      function debounce(quietMillis, fn, ctx) {
          ctx = ctx || undefined;
          var timeout;
          return function () {
              var args = arguments;
              window.clearTimeout(timeout);
              timeout = window.setTimeout(function () {
                  fn.apply(ctx, args)
              }, quietMillis)
          }
      }
  
      function thunk(formula) {
          var evaluated = false, value;
          return function () {
              if (evaluated === false) {
                  value = formula();
                  evaluated = true
              }
              return value
          }
      }
  
      function installDebouncedScroll(threshold, element) {
          var notify = debounce(threshold, function (e) {
              element.trigger("scroll-debounced", e)
          });
          element.on("scroll", function (e) {
              if (indexOf(e.target, element.get()) >= 0) {
                  notify(e)
              }
          })
      }
  
      function focus($el) {
          if ($el[0] === document.activeElement) {
              return
          }
          window.setTimeout(function () {
              var el = $el[0], pos = $el.val().length, range;
              $el.focus();
              if ($el.is(":visible") && el === document.activeElement) {
                  if (el.setSelectionRange) {
                      el.setSelectionRange(pos, pos)
                  } else {
                      if (el.createTextRange) {
                          range = el.createTextRange();
                          range.collapse(false);
                          range.select()
                      }
                  }
              }
          }, 0)
      }
  
      function getCursorInfo(el) {
          el = $(el)[0];
          var offset = 0;
          var length = 0;
          if ("selectionStart" in el) {
              offset = el.selectionStart;
              length = el.selectionEnd - offset
          } else {
              if ("selection" in document) {
                  el.focus();
                  var sel = document.selection.createRange();
                  length = document.selection.createRange().text.length;
                  sel.moveStart("character", -el.value.length);
                  offset = sel.text.length - length
              }
          }
          return {offset: offset, length: length}
      }
  
      function killEvent(event) {
          event.preventDefault();
          event.stopPropagation()
      }
  
      function killEventImmediately(event) {
          event.preventDefault();
          event.stopImmediatePropagation()
      }
  
      function measureTextWidth(e) {
          if (!sizer) {
              var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
              sizer = $(document.createElement("div")).css({
                  position: "absolute",
                  left: "-10000px",
                  top: "-10000px",
                  display: "none",
                  fontSize: style.fontSize,
                  fontFamily: style.fontFamily,
                  fontStyle: style.fontStyle,
                  fontWeight: style.fontWeight,
                  letterSpacing: style.letterSpacing,
                  textTransform: style.textTransform,
                  whiteSpace: "nowrap"
              });
              sizer.attr("class", "select2-sizer");
              $("body").append(sizer)
          }
          sizer.text(e.val());
          return sizer.width()
      }
  
      function syncCssClasses(dest, src, adapter) {
          var classes, replacements = [], adapted;
          classes = dest.attr("class");
          if (classes) {
              classes = "" + classes;
              $(classes.split(" ")).each2(function () {
                  if (this.indexOf("select2-") === 0) {
                      replacements.push(this)
                  }
              })
          }
          classes = src.attr("class");
          if (classes) {
              classes = "" + classes;
              $(classes.split(" ")).each2(function () {
                  if (this.indexOf("select2-") !== 0) {
                      adapted = adapter(this);
                      if (adapted) {
                          replacements.push(this)
                      }
                  }
              })
          }
          dest.attr("class", replacements.join(" "))
      }
  
      function markMatch(text, term, markup, escapeMarkup) {
          var match = text.toUpperCase().indexOf(term.toUpperCase()), tl = term.length;
          if (match < 0) {
              markup.push(escapeMarkup(text));
              return
          }
          markup.push(escapeMarkup(text.substring(0, match)));
          markup.push("<span class='select2-match'>");
          markup.push(escapeMarkup(text.substring(match, match + tl)));
          markup.push("</span>");
          markup.push(escapeMarkup(text.substring(match + tl, text.length)))
      }
  
      function ajax(options) {
          var timeout, requestSequence = 0, handler = null, quietMillis = options.quietMillis || 100, ajaxUrl = options.url, self = this;
          return function (query) {
              window.clearTimeout(timeout);
              timeout = window.setTimeout(function () {
                  requestSequence += 1;
                  var requestNumber = requestSequence, data = options.data, url = ajaxUrl, transport = options.transport || $.fn.select2.ajaxDefaults.transport, deprecated = {
                      type: options.type || "GET",
                      cache: options.cache || false,
                      jsonpCallback: options.jsonpCallback || undefined,
                      dataType: options.dataType || "json"
                  }, params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
                  data = data ? data.call(self, query.term, query.page, query.context) : null;
                  url = (typeof url === "function") ? url.call(self, query.term, query.page, query.context) : url;
                  if (null !== handler) {
                      handler.abort()
                  }
                  if (options.params) {
                      if ($.isFunction(options.params)) {
                          $.extend(params, options.params.call(self))
                      } else {
                          $.extend(params, options.params)
                      }
                  }
                  $.extend(params, {
                      url: url, dataType: options.dataType, data: data, success: function (data) {
                          if (requestNumber < requestSequence) {
                              return
                          }
                          var results = options.results(data, query.page);
                          query.callback(results)
                      }
                  });
                  handler = transport.call(self, params)
              }, quietMillis)
          }
      }
  
      function local(options) {
          var data = options, dataText, tmp, text = function (item) {
              return "" + item.text
          };
          if ($.isArray(data)) {
              tmp = data;
              data = {results: tmp}
          }
          if ($.isFunction(data) === false) {
              tmp = data;
              data = function () {
                  return tmp
              }
          }
          var dataItem = data();
          if (dataItem.text) {
              text = dataItem.text;
              if (!$.isFunction(text)) {
                  dataText = dataItem.text;
                  text = function (item) {
                      return item[dataText]
                  }
              }
          }
          return function (query) {
              var t = query.term, filtered = {results: []}, process;
              if (t === "") {
                  query.callback(data());
                  return
              }
              process = function (datum, collection) {
                  var group, attr;
                  datum = datum[0];
                  if (datum.children) {
                      group = {};
                      for (attr in datum) {
                          if (datum.hasOwnProperty(attr)) {
                              group[attr] = datum[attr]
                          }
                      }
                      group.children = [];
                      $(datum.children).each2(function (i, childDatum) {
                          process(childDatum, group.children)
                      });
                      if (group.children.length || query.matcher(t, text(group), datum)) {
                          collection.push(group)
                      }
                  } else {
                      if (query.matcher(t, text(datum), datum)) {
                          collection.push(datum)
                      }
                  }
              };
              $(data().results).each2(function (i, datum) {
                  process(datum, filtered.results)
              });
              query.callback(filtered)
          }
      }
  
      function tags(data) {
          var isFunc = $.isFunction(data);
          return function (query) {
              var t = query.term, filtered = {results: []};
              $(isFunc ? data() : data).each(function () {
                  var isObject = this.text !== undefined, text = isObject ? this.text : this;
                  if (t === "" || query.matcher(t, text)) {
                      filtered.results.push(isObject ? this : {id: this, text: this})
                  }
              });
              query.callback(filtered)
          }
      }
  
      function checkFormatter(formatter, formatterName) {
          if ($.isFunction(formatter)) {
              return true
          }
          if (!formatter) {
              return false
          }
          throw new Error("formatterName must be a function or a falsy value")
      }
  
      function evaluate(val) {
          return $.isFunction(val) ? val() : val
      }
  
      function countResults(results) {
          var count = 0;
          $.each(results, function (i, item) {
              if (item.children) {
                  count += countResults(item.children)
              } else {
                  count++
              }
          });
          return count
      }
  
      function defaultTokenizer(input, selection, selectCallback, opts) {
          var original = input, dupe = false, token, index, i, l, separator;
          if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) {
              return undefined
          }
          while (true) {
              index = -1;
              for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
                  separator = opts.tokenSeparators[i];
                  index = input.indexOf(separator);
                  if (index >= 0) {
                      break
                  }
              }
              if (index < 0) {
                  break
              }
              token = input.substring(0, index);
              input = input.substring(index + separator.length);
              if (token.length > 0) {
                  token = opts.createSearchChoice(token, selection);
                  if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
                      dupe = false;
                      for (i = 0, l = selection.length; i < l; i++) {
                          if (equal(opts.id(token), opts.id(selection[i]))) {
                              dupe = true;
                              break
                          }
                      }
                      if (!dupe) {
                          selectCallback(token)
                      }
                  }
              }
          }
          if (original !== input) {
              return input
          }
      }
  
      function clazz(SuperClass, methods) {
          var constructor = function () {
          };
          constructor.prototype = new SuperClass;
          constructor.prototype.constructor = constructor;
          constructor.prototype.parent = SuperClass.prototype;
          constructor.prototype = $.extend(constructor.prototype, methods);
          return constructor
      }
  
      AbstractSelect2 = clazz(Object, {
          bind: function (func) {
              var self = this;
              return function () {
                  func.apply(self, arguments)
              }
          }, init: function (opts) {
              var results, search, resultsSelector = ".select2-results", disabled, readonly;
              this.opts = opts = this.prepareOpts(opts);
              this.id = opts.id;
              if (opts.element.data("select2") !== undefined && opts.element.data("select2") !== null) {
                  this.destroy()
              }
              this.container = this.createContainer();
              this.containerId = "s2id_" + (opts.element.attr("id") || "autogen" + nextUid());
              this.containerSelector = "#" + this.containerId.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, "\\$1");
              this.container.attr("id", this.containerId);
              this.body = thunk(function () {
                  return opts.element.closest("body")
              });
              syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
              this.container.css(evaluate(opts.containerCss));
              this.container.addClass(evaluate(opts.containerCssClass));
              this.elementTabIndex = this.opts.element.attr("tabindex");
              this.opts.element.data("select2", this).attr("tabindex", "-1").before(this.container);
              this.container.data("select2", this);
              this.dropdown = this.container.find(".select2-drop");
              this.dropdown.addClass(evaluate(opts.dropdownCssClass));
              this.dropdown.data("select2", this);
              this.results = results = this.container.find(resultsSelector);
              this.search = search = this.container.find("input.select2-input");
              this.resultsPage = 0;
              this.context = null;
              this.initContainer();
              installFilteredMouseMove(this.results);
              this.dropdown.on("mousemove-filtered touchstart touchmove touchend", resultsSelector, this.bind(this.highlightUnderEvent));
              installDebouncedScroll(80, this.results);
              this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded));
              $(this.container).on("change", ".select2-input", function (e) {
                  e.stopPropagation()
              });
              $(this.dropdown).on("change", ".select2-input", function (e) {
                  e.stopPropagation()
              });
              if ($.fn.mousewheel) {
                  results.mousewheel(function (e, delta, deltaX, deltaY) {
                      var top = results.scrollTop(), height;
                      if (deltaY > 0 && top - deltaY <= 0) {
                          results.scrollTop(0);
                          killEvent(e)
                      } else {
                          if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
                              results.scrollTop(results.get(0).scrollHeight - results.height());
                              killEvent(e)
                          }
                      }
                  })
              }
              installKeyUpChangeEvent(search);
              search.on("keyup-change input paste", this.bind(this.updateResults));
              search.on("focus", function () {
                  search.addClass("select2-focused")
              });
              search.on("blur", function () {
                  search.removeClass("select2-focused")
              });
              this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) {
                  if ($(e.target).closest(".select2-result-selectable").length > 0) {
                      this.highlightUnderEvent(e);
                      this.selectHighlighted(e)
                  }
              }));
              this.dropdown.on("click mouseup mousedown", function (e) {
                  e.stopPropagation()
              });
              if ($.isFunction(this.opts.initSelection)) {
                  this.initSelection();
                  this.monitorSource()
              }
              if (opts.maximumInputLength !== null) {
                  this.search.attr("maxlength", opts.maximumInputLength)
              }
              var disabled = opts.element.prop("disabled");
              if (disabled === undefined) {
                  disabled = false
              }
              this.enable(!disabled);
              var readonly = opts.element.prop("readonly");
              if (readonly === undefined) {
                  readonly = false
              }
              this.readonly(readonly);
              scrollBarDimensions = scrollBarDimensions || measureScrollbar();
              this.autofocus = opts.element.prop("autofocus");
              opts.element.prop("autofocus", false);
              if (this.autofocus) {
                  this.focus()
              }
          }, destroy: function () {
              var select2 = this.opts.element.data("select2");
              if (this.propertyObserver) {
                  delete this.propertyObserver;
                  this.propertyObserver = null
              }
              if (select2 !== undefined) {
                  select2.container.remove();
                  select2.dropdown.remove();
                  select2.opts.element.removeClass("select2-offscreen").removeData("select2").off(".select2").attr({"tabindex": this.elementTabIndex}).prop("autofocus", this.autofocus || false).show()
              }
          }, optionToData: function (element) {
              if (element.is("option")) {
                  return {
                      id: element.prop("value"),
                      text: element.text(),
                      element: element.get(),
                      css: element.attr("class"),
                      disabled: element.prop("disabled"),
                      locked: equal(element.attr("locked"), "locked")
                  }
              } else {
                  if (element.is("optgroup")) {
                      return {
                          text: element.attr("label"),
                          children: [],
                          element: element.get(),
                          css: element.attr("class")
                      }
                  }
              }
          }, prepareOpts: function (opts) {
              var element, select, idKey, ajaxUrl, self = this;
              element = opts.element;
              if (element.get(0).tagName.toLowerCase() === "select") {
                  this.select = select = opts.element
              }
              if (select) {
                  $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () {
                      if (this in opts) {
                          throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.")
                      }
                  })
              }
              opts = $.extend({}, {
                  populateResults: function (container, results, query) {
                      var populate, data, result, children, id = this.opts.id;
                      populate = function (results, container, depth) {
                          var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;
                          results = opts.sortResults(results, container, query);
                          for (i = 0, l = results.length; i < l; i = i + 1) {
                              result = results[i];
                              disabled = (result.disabled === true);
                              selectable = (!disabled) && (id(result) !== undefined);
                              compound = result.children && result.children.length > 0;
                              node = $("<li></li>");
                              node.addClass("select2-results-dept-" + depth);
                              node.addClass("select2-result");
                              node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
                              if (disabled) {
                                  node.addClass("select2-disabled")
                              }
                              if (compound) {
                                  node.addClass("select2-result-with-children")
                              }
                              node.addClass(self.opts.formatResultCssClass(result));
                              label = $(document.createElement("div"));
                              label.addClass("select2-result-label");
                              formatted = opts.formatResult(result, label, query, self.opts.escapeMarkup);
                              if (formatted !== undefined) {
                                  label.html(formatted)
                              }
                              node.append(label);
                              if (compound) {
                                  innerContainer = $("<ul></ul>");
                                  innerContainer.addClass("select2-result-sub");
                                  populate(result.children, innerContainer, depth + 1);
                                  node.append(innerContainer)
                              }
                              node.data("select2-data", result);
                              container.append(node)
                          }
                      };
                      populate(results, container, 0)
                  }
              }, $.fn.select2.defaults, opts);
              if (typeof(opts.id) !== "function") {
                  idKey = opts.id;
                  opts.id = function (e) {
                      return e[idKey]
                  }
              }
              if ($.isArray(opts.element.data("select2Tags"))) {
                  if ("tags" in opts) {
                      throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id")
                  }
                  opts.tags = opts.element.data("select2Tags")
              }
              if (select) {
                  opts.query = this.bind(function (query) {
                      var data = {results: [], more: false}, term = query.term, children, firstChild, process;
                      process = function (element, collection) {
                          var group;
                          if (element.is("option")) {
                              if (query.matcher(term, element.text(), element)) {
                                  collection.push(self.optionToData(element))
                              }
                          } else {
                              if (element.is("optgroup")) {
                                  group = self.optionToData(element);
                                  element.children().each2(function (i, elm) {
                                      process(elm, group.children)
                                  });
                                  if (group.children.length > 0) {
                                      collection.push(group)
                                  }
                              }
                          }
                      };
                      children = element.children();
                      if (this.getPlaceholder() !== undefined && children.length > 0) {
                          firstChild = children[0];
                          if ($(firstChild).text() === "") {
                              children = children.not(firstChild)
                          }
                      }
                      children.each2(function (i, elm) {
                          process(elm, data.results)
                      });
                      query.callback(data)
                  });
                  opts.id = function (e) {
                      return e.id
                  };
                  opts.formatResultCssClass = function (data) {
                      return data.css
                  }
              } else {
                  if (!("query" in opts)) {
                      if ("ajax" in opts) {
                          ajaxUrl = opts.element.data("ajax-url");
                          if (ajaxUrl && ajaxUrl.length > 0) {
                              opts.ajax.url = ajaxUrl
                          }
                          opts.query = ajax.call(opts.element, opts.ajax)
                      } else {
                          if ("data" in opts) {
                              opts.query = local(opts.data)
                          } else {
                              if ("tags" in opts) {
                                  opts.query = tags(opts.tags);
                                  if (opts.createSearchChoice === undefined) {
                                      opts.createSearchChoice = function (term) {
                                          return {id: term, text: term}
                                      }
                                  }
                                  if (opts.initSelection === undefined) {
                                      opts.initSelection = function (element, callback) {
                                          var data = [];
                                          $(splitVal(element.val(), opts.separator)).each(function () {
                                              var id = this, text = this, tags = opts.tags;
                                              if ($.isFunction(tags)) {
                                                  tags = tags()
                                              }
                                              $(tags).each(function () {
                                                  if (equal(this.id, id)) {
                                                      text = this.text;
                                                      return false
                                                  }
                                              });
                                              data.push({id: id, text: text})
                                          });
                                          callback(data)
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
              if (typeof(opts.query) !== "function") {
                  throw"query function not defined for Select2 " + opts.element.attr("id")
              }
              return opts
          }, monitorSource: function () {
              var el = this.opts.element, sync;
              el.on("change.select2", this.bind(function (e) {
                  if (this.opts.element.data("select2-change-triggered") !== true) {
                      this.initSelection()
                  }
              }));
              sync = this.bind(function () {
                  var enabled, readonly, self = this;
                  var disabled = el.prop("disabled");
                  if (disabled === undefined) {
                      disabled = false
                  }
                  this.enable(!disabled);
                  var readonly = el.prop("readonly");
                  if (readonly === undefined) {
                      readonly = false
                  }
                  this.readonly(readonly);
                  syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
                  this.container.addClass(evaluate(this.opts.containerCssClass));
                  syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
                  this.dropdown.addClass(evaluate(this.opts.dropdownCssClass))
              });
              el.on("propertychange.select2 DOMAttrModified.select2", sync);
              if (this.mutationCallback === undefined) {
                  this.mutationCallback = function (mutations) {
                      mutations.forEach(sync)
                  }
              }
              if (typeof WebKitMutationObserver !== "undefined") {
                  if (this.propertyObserver) {
                      delete this.propertyObserver;
                      this.propertyObserver = null
                  }
                  this.propertyObserver = new WebKitMutationObserver(this.mutationCallback);
                  this.propertyObserver.observe(el.get(0), {attributes: true, subtree: false})
              }
          }, triggerSelect: function (data) {
              var evt = $.Event("select2-selecting", {val: this.id(data), object: data});
              this.opts.element.trigger(evt);
              return !evt.isDefaultPrevented()
          }, triggerChange: function (details) {
              details = details || {};
              details = $.extend({}, details, {type: "change", val: this.val()});
              this.opts.element.data("select2-change-triggered", true);
              this.opts.element.trigger(details);
              this.opts.element.data("select2-change-triggered", false);
              this.opts.element.click();
              if (this.opts.blurOnChange) {
                  this.opts.element.blur()
              }
          }, isInterfaceEnabled: function () {
              return this.enabledInterface === true
          }, enableInterface: function () {
              var enabled = this._enabled && !this._readonly, disabled = !enabled;
              if (enabled === this.enabledInterface) {
                  return false
              }
              this.container.toggleClass("select2-container-disabled", disabled);
              this.close();
              this.enabledInterface = enabled;
              return true
          }, enable: function (enabled) {
              if (enabled === undefined) {
                  enabled = true
              }
              if (this._enabled === enabled) {
                  return false
              }
              this._enabled = enabled;
              this.opts.element.prop("disabled", !enabled);
              this.enableInterface();
              return true
          }, readonly: function (enabled) {
              if (enabled === undefined) {
                  enabled = false
              }
              if (this._readonly === enabled) {
                  return false
              }
              this._readonly = enabled;
              this.opts.element.prop("readonly", enabled);
              this.enableInterface();
              return true
          }, opened: function () {
              return this.container.hasClass("select2-dropdown-open")
          }, positionDropdown: function () {
              var $dropdown = this.dropdown, offset = this.container.offset(), height = this.container.outerHeight(false), width = this.container.outerWidth(false), dropHeight = $dropdown.outerHeight(false), viewPortRight = $(window).scrollLeft() + $(window).width(), viewportBottom = $(window).scrollTop() + $(window).height(), dropTop = offset.top + height, dropLeft = offset.left, enoughRoomBelow = dropTop + dropHeight <= viewportBottom, enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(), dropWidth = $dropdown.outerWidth(false), enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight, aboveNow = $dropdown.hasClass("select2-drop-above"), bodyOffset, above, css, resultsListNode;
              if (this.opts.dropdownAutoWidth) {
                  resultsListNode = $(".select2-results", $dropdown)[0];
                  $dropdown.addClass("select2-drop-auto-width");
                  $dropdown.css("width", "");
                  dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
                  dropWidth > width ? width = dropWidth : dropWidth = width;
                  enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight
              } else {
                  this.container.removeClass("select2-drop-auto-width")
              }
              if (this.body().css("position") !== "static") {
                  bodyOffset = this.body().offset();
                  dropTop -= bodyOffset.top;
                  dropLeft -= bodyOffset.left
              }
              if (aboveNow) {
                  above = true;
                  if (!enoughRoomAbove && enoughRoomBelow) {
                      above = false
                  }
              } else {
                  above = false;
                  if (!enoughRoomBelow && enoughRoomAbove) {
                      above = true
                  }
              }
              if (!enoughRoomOnRight) {
                  dropLeft = offset.left + width - dropWidth
              }
              if (above) {
                  dropTop = offset.top - dropHeight;
                  this.container.addClass("select2-drop-above");
                  $dropdown.addClass("select2-drop-above")
              } else {
                  this.container.removeClass("select2-drop-above");
                  $dropdown.removeClass("select2-drop-above")
              }
              css = $.extend({top: dropTop, left: dropLeft, width: width}, evaluate(this.opts.dropdownCss));
              $dropdown.css(css)
          }, shouldOpen: function () {
              var event;
              if (this.opened()) {
                  return false
              }
              if (this._enabled === false || this._readonly === true) {
                  return false
              }
              event = $.Event("select2-opening");
              this.opts.element.trigger(event);
              return !event.isDefaultPrevented()
          }, clearDropdownAlignmentPreference: function () {
              this.container.removeClass("select2-drop-above");
              this.dropdown.removeClass("select2-drop-above")
          }, open: function () {
              if (!this.shouldOpen()) {
                  return false
              }
              this.opening();
              return true
          }, opening: function () {
              var cid = this.containerId, scroll = "scroll." + cid, resize = "resize." + cid, orient = "orientationchange." + cid, mask;
              this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
              this.clearDropdownAlignmentPreference();
              if (this.dropdown[0] !== this.body().children().last()[0]) {
                  this.dropdown.detach().appendTo(this.body())
              }
              mask = $("#select2-drop-mask");
              if (mask.length == 0) {
                  mask = $(document.createElement("div"));
                  mask.attr("id", "select2-drop-mask").attr("class", "select2-drop-mask");
                  mask.hide();
                  mask.appendTo(this.body());
                  mask.on("mousedown touchstart", function (e) {
                      var dropdown = $("#select2-drop"), self;
                      if (dropdown.length > 0) {
                          self = dropdown.data("select2");
                          if (self.opts.selectOnBlur) {
                              self.selectHighlighted({noFocus: true})
                          }
                          self.close();
                          e.preventDefault();
                          e.stopPropagation()
                      }
                  })
              }
              if (this.dropdown.prev()[0] !== mask[0]) {
                  this.dropdown.before(mask)
              }
              $("#select2-drop").removeAttr("id");
              this.dropdown.attr("id", "select2-drop");
              mask.css(_makeMaskCss());
              mask.show();
              this.dropdown.show();
              this.positionDropdown();
              this.dropdown.addClass("select2-drop-active");
              this.ensureHighlightVisible();
              var that = this;
              if (jQuery.browser.version != "7.0" && jQuery.browser.version != "6.0" && jQuery.browser.version != "8.0") {
                  this.container.parents().add(window).each(function () {
                      $(this).on(resize + " " + scroll + " " + orient, function (e) {
                          $("#select2-drop-mask").css(_makeMaskCss());
                          that.positionDropdown()
                      })
                  })
              }
              function _makeMaskCss() {
                  return {
                      width: Math.max(document.documentElement.scrollWidth, $(window).width()),
                      height: Math.max(document.documentElement.scrollHeight, $(window).height())
                  }
              }
          }, close: function () {
              if (!this.opened()) {
                  return
              }
              var cid = this.containerId, scroll = "scroll." + cid, resize = "resize." + cid, orient = "orientationchange." + cid;
              this.container.parents().add(window).each(function () {
                  $(this).off(scroll).off(resize).off(orient)
              });
              this.clearDropdownAlignmentPreference();
              $("#select2-drop-mask").hide();
              this.dropdown.removeAttr("id");
              this.dropdown.hide();
              this.container.removeClass("select2-dropdown-open");
              this.results.empty();
              this.clearSearch();
              this.search.removeClass("select2-active");
              this.opts.element.trigger($.Event("select2-close"))
          }, clearSearch: function () {
          }, getMaximumSelectionSize: function () {
              return evaluate(this.opts.maximumSelectionSize)
          }, ensureHighlightVisible: function () {
              var results = this.results, children, index, child, hb, rb, y, more;
              index = this.highlight();
              if (index < 0) {
                  return
              }
              if (index == 0) {
                  results.scrollTop(0);
                  return
              }
              children = this.findHighlightableChoices().find(".select2-result-label");
              child = $(children[index]);
              hb = child.offset().top + child.outerHeight(true);
              if (index === children.length - 1) {
                  more = results.find("li.select2-more-results");
                  if (more.length > 0) {
                      hb = more.offset().top + more.outerHeight(true)
                  }
              }
              rb = results.offset().top + results.outerHeight(true);
              if (hb > rb) {
                  results.scrollTop(results.scrollTop() + (hb - rb))
              }
              y = child.offset().top - results.offset().top;
              if (y < 0 && child.css("display") != "none") {
                  results.scrollTop(results.scrollTop() + y)
              }
          }, findHighlightableChoices: function () {
              return this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)")
          }, moveHighlight: function (delta) {
              var choices = this.findHighlightableChoices(), index = this.highlight();
              while (index > -1 && index < choices.length) {
                  index += delta;
                  var choice = $(choices[index]);
                  if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) {
                      this.highlight(index);
                      break
                  }
              }
          }, highlight: function (index) {
              var choices = this.findHighlightableChoices(), choice, data;
              if (arguments.length === 0) {
                  return indexOf(choices.filter(".select2-highlighted")[0], choices.get())
              }
              if (index >= choices.length) {
                  index = choices.length - 1
              }
              if (index < 0) {
                  index = 0
              }
              this.results.find(".select2-highlighted").removeClass("select2-highlighted");
              choice = $(choices[index]);
              choice.addClass("select2-highlighted");
              this.ensureHighlightVisible();
              data = choice.data("select2-data");
              if (data) {
                  this.opts.element.trigger({type: "select2-highlight", val: this.id(data), choice: data})
              }
          }, countSelectableResults: function () {
              return this.findHighlightableChoices().length
          }, highlightUnderEvent: function (event) {
              var el = $(event.target).closest(".select2-result-selectable");
              if (el.length > 0 && !el.is(".select2-highlighted")) {
                  var choices = this.findHighlightableChoices();
                  this.highlight(choices.index(el))
              } else {
                  if (el.length == 0) {
                      this.results.find(".select2-highlighted").removeClass("select2-highlighted")
                  }
              }
          }, loadMoreIfNeeded: function () {
              var results = this.results, more = results.find("li.select2-more-results"), below, offset = -1, page = this.resultsPage + 1, self = this, term = this.search.val(), context = this.context;
              if (more.length === 0) {
                  return
              }
              below = more.offset().top - results.offset().top - results.height();
              if (below <= this.opts.loadMorePadding) {
                  more.addClass("select2-active");
                  this.opts.query({
                      element: this.opts.element,
                      term: term,
                      page: page,
                      context: context,
                      matcher: this.opts.matcher,
                      callback: this.bind(function (data) {
                          if (!self.opened()) {
                              return
                          }
                          self.opts.populateResults.call(this, results, data.results, {
                              term: term,
                              page: page,
                              context: context
                          });
                          self.postprocessResults(data, false, false);
                          if (data.more === true) {
                              more.detach().appendTo(results).text(self.opts.formatLoadMore(page + 1));
                              window.setTimeout(function () {
                                  self.loadMoreIfNeeded()
                              }, 10)
                          } else {
                              more.remove()
                          }
                          self.positionDropdown();
                          self.resultsPage = page;
                          self.context = data.context
                      })
                  })
              }
          }, tokenize: function () {
          }, updateResults: function (initial) {
              var search = this.search, results = this.results, opts = this.opts, data, self = this, input, term = search.val(), lastTerm = $.data(this.container, "select2-last-term");
              if (initial !== true && lastTerm && equal(term, lastTerm)) {
                  return
              }
              $.data(this.container, "select2-last-term", term);
              if (initial !== true && (this.showSearchInput === false || !this.opened())) {
                  return
              }
              function postRender() {
                  results.scrollTop(0);
                  search.removeClass("select2-active");
                  self.positionDropdown()
              }
  
              function render(html) {
                  results.html(html);
                  postRender()
              }
  
              var maxSelSize = this.getMaximumSelectionSize();
              if (maxSelSize >= 1) {
                  data = this.data();
                  if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
                      render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(maxSelSize) + "</li>");
                      return
                  }
              }
              if (search.val().length < opts.minimumInputLength) {
                  if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
                      render("<li class='select2-no-results'>" + opts.formatInputTooShort(search.val(), opts.minimumInputLength) + "</li>")
                  } else {
                      render("")
                  }
                  if (initial) {
                      this.showSearch(true)
                  }
                  return
              }
              if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {
                  if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) {
                      render("<li class='select2-no-results'>" + opts.formatInputTooLong(search.val(), opts.maximumInputLength) + "</li>")
                  } else {
                      render("")
                  }
                  return
              }
              if (opts.formatSearching && this.findHighlightableChoices().length === 0) {
                  render("<li class='select2-searching'>" + opts.formatSearching() + "</li>")
              }
              search.addClass("select2-active");
              input = this.tokenize();
              if (input != undefined && input != null) {
                  search.val(input)
              }
              this.resultsPage = 1;
              opts.query({
                  element: opts.element,
                  term: search.val(),
                  page: this.resultsPage,
                  context: null,
                  matcher: opts.matcher,
                  callback: this.bind(function (data) {
                      var def;
                      if (!this.opened()) {
                          this.search.removeClass("select2-active");
                          return
                      }
                      this.context = (data.context === undefined) ? null : data.context;
                      if (this.opts.createSearchChoice && search.val() !== "") {
                          def = this.opts.createSearchChoice.call(null, search.val(), data.results);
                          if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
                              if ($(data.results).filter(function () {
                                      return equal(self.id(this), self.id(def))
                                  }).length === 0) {
                                  data.results.unshift(def)
                              }
                          }
                      }
                      if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
                          render("<li class='select2-no-results'>" + opts.formatNoMatches(search.val()) + "</li>");
                          return
                      }
                      results.empty();
                      self.opts.populateResults.call(this, results, data.results, {
                          term: search.val(),
                          page: this.resultsPage,
                          context: null
                      });
                      if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) {
                          results.append("<li class='select2-more-results'>" + self.opts.escapeMarkup(opts.formatLoadMore(this.resultsPage)) + "</li>");
                          window.setTimeout(function () {
                              self.loadMoreIfNeeded()
                          }, 10)
                      }
                      this.postprocessResults(data, initial);
                      postRender();
                      this.opts.element.trigger({type: "select2-loaded", data: data})
                  })
              })
          }, cancel: function () {
              this.close()
          }, blur: function () {
              if (this.opts.selectOnBlur) {
                  this.selectHighlighted({noFocus: true})
              }
              this.close();
              this.container.removeClass("select2-container-active");
              if (this.search[0] === document.activeElement) {
                  this.search.blur()
              }
              this.clearSearch();
              this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")
          }, focusSearch: function () {
              focus(this.search)
          }, selectHighlighted: function (options) {
              var index = this.highlight(), highlighted = this.results.find(".select2-highlighted"), data = highlighted.closest(".select2-result").data("select2-data");
              if (data) {
                  this.highlight(index);
                  this.onSelect(data, options)
              }
          }, getPlaceholder: function () {
              return this.opts.element.attr("placeholder") || this.opts.element.attr("data-placeholder") || this.opts.element.data("placeholder") || this.opts.placeholder
          }, initContainerWidth: function () {
              function resolveContainerWidth() {
                  var style, attrs, matches, i, l;
                  if (this.opts.width === "off") {
                      return null
                  } else {
                      if (this.opts.width === "element") {
                          return this.opts.element.outerWidth(false) === 0 ? "auto" : this.opts.element.outerWidth(false) + "px"
                      } else {
                          if (this.opts.width === "copy" || this.opts.width === "resolve") {
                              style = this.opts.element.attr("style");
                              if (style !== undefined) {
                                  attrs = style.split(";");
                                  for (i = 0, l = attrs.length; i < l; i = i + 1) {
                                      matches = attrs[i].replace(/\s/g, "").match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);
                                      if (matches !== null && matches.length >= 1) {
                                          return matches[1]
                                      }
                                  }
                              }
                              style = this.opts.element.css("width");
                              if (style && style.length > 0) {
                                  return style
                              }
                              if (this.opts.width === "resolve") {
                                  return (this.opts.element.outerWidth(false) === 0 ? "auto" : this.opts.element.outerWidth(false) + "px")
                              }
                              return null
                          } else {
                              if ($.isFunction(this.opts.width)) {
                                  return this.opts.width()
                              } else {
                                  return this.opts.width
                              }
                          }
                      }
                  }
              }
  
              var width = resolveContainerWidth.call(this);
              if (width !== null) {
                  this.container.css("width", width)
              }
          }
      });
      SingleSelect2 = clazz(AbstractSelect2, {
          createContainer: function () {
              var container = $(document.createElement("div")).attr({"class": "select2-container"}).html(["<a href='javascript:void(0)' onclick='return false;' class='select2-choice' tabindex='-1'>", "   <span>&nbsp;</span><abbr class='select2-search-choice-close'></abbr>", "   <div><b></b></div>", "</a>", "<input class='select2-focusser select2-offscreen' type='text'/>", "<div class='select2-drop select2-display-none'>", "   <div class='select2-search'>", "       <input type='text' autocomplete='off' autocorrect='off' autocapitilize='off' spellcheck='false' class='select2-input'/>", "   </div>", "   <ul class='select2-results'>", "   </ul>", "</div>"].join(""));
              return container
          }, enableInterface: function () {
              if (this.parent.enableInterface.apply(this, arguments)) {
                  this.focusser.prop("disabled", !this.isInterfaceEnabled())
              }
          }, opening: function () {
              var el, range;
              this.parent.opening.apply(this, arguments);
              if (this.showSearchInput !== false) {
                  this.search.val(this.focusser.val())
              }
              this.focusser.prop("disabled", true).val("");
              this.updateResults(true);
              this.opts.element.trigger($.Event("select2-open"))
          }, close: function () {
              if (!this.opened()) {
                  return
              }
              this.parent.close.apply(this, arguments);
              this.focusser.removeAttr("disabled");
              this.focusser.focus()
          }, focus: function () {
              if (this.opened()) {
                  this.close()
              } else {
                  this.focusser.removeAttr("disabled");
                  this.focusser.focus()
              }
          }, isFocused: function () {
              return this.container.hasClass("select2-container-active")
          }, cancel: function () {
              this.parent.cancel.apply(this, arguments);
              this.focusser.removeAttr("disabled");
              this.focusser.focus()
          }, initContainer: function () {
              var selection, container = this.container, dropdown = this.dropdown;
              this.showSearch(false);
              this.selection = selection = container.find(".select2-choice");
              this.focusser = container.find(".select2-focusser");
              this.focusser.attr("id", "s2id_autogen" + nextUid());
              $("label[for='" + this.opts.element.attr("id") + "']").attr("for", this.focusser.attr("id"));
              this.focusser.attr("tabindex", this.elementTabIndex);
              this.search.on("keydown", this.bind(function (e) {
                  if (!this.isInterfaceEnabled()) {
                      return
                  }
                  if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
                      killEvent(e);
                      return
                  }
                  switch (e.which) {
                      case KEY.UP:
                      case KEY.DOWN:
                          this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
                          killEvent(e);
                          return;
                      case KEY.ENTER:
                          this.selectHighlighted();
                          killEvent(e);
                          return;
                      case KEY.TAB:
                          this.selectHighlighted({noFocus: true});
                          return;
                      case KEY.ESC:
                          this.cancel(e);
                          killEvent(e);
                          return
                  }
              }));
              this.search.on("blur", this.bind(function (e) {
                  if (document.activeElement === this.body().get(0)) {
                      window.setTimeout(this.bind(function () {
                          this.search.focus()
                      }), 0)
                  }
              }));
              this.focusser.on("keydown", this.bind(function (e) {
                  if (!this.isInterfaceEnabled()) {
                      return
                  }
                  if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
                      return
                  }
                  if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
                      killEvent(e);
                      return
                  }
                  if (e.which == KEY.DOWN || e.which == KEY.UP || (e.which == KEY.ENTER && this.opts.openOnEnter)) {
                      this.open();
                      killEvent(e);
                      return
                  }
                  if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
                      if (this.opts.allowClear) {
                          this.clear()
                      }
                      killEvent(e);
                      return
                  }
              }));
              installKeyUpChangeEvent(this.focusser);
              this.focusser.on("keyup-change input", this.bind(function (e) {
                  e.stopPropagation();
                  if (this.opened()) {
                      return
                  }
                  this.open()
              }));
              selection.on("mousedown", "abbr", this.bind(function (e) {
                  if (!this.isInterfaceEnabled()) {
                      return
                  }
                  this.clear();
                  killEventImmediately(e);
                  this.close();
                  this.selection.focus()
              }));
              selection.on("mousedown", this.bind(function (e) {
                  if (!this.container.hasClass("select2-container-active")) {
                      this.opts.element.trigger($.Event("select2-focus"))
                  }
                  if (this.opened()) {
                      this.close()
                  } else {
                      if (this.isInterfaceEnabled()) {
                          this.open()
                      }
                  }
                  killEvent(e)
              }));
              dropdown.on("mousedown", this.bind(function () {
                  this.search.focus()
              }));
              selection.on("focus", this.bind(function (e) {
                  killEvent(e)
              }));
              this.focusser.on("focus", this.bind(function () {
                  if (!this.container.hasClass("select2-container-active")) {
                      this.opts.element.trigger($.Event("select2-focus"))
                  }
                  this.container.addClass("select2-container-active")
              })).on("blur", this.bind(function () {
                  if (!this.opened()) {
                      this.container.removeClass("select2-container-active");
                      this.opts.element.trigger($.Event("select2-blur"))
                  }
              }));
              this.search.on("focus", this.bind(function () {
                  if (!this.container.hasClass("select2-container-active")) {
                      this.opts.element.trigger($.Event("select2-focus"))
                  }
                  this.container.addClass("select2-container-active")
              }));
              this.initContainerWidth();
              this.opts.element.addClass("select2-offscreen");
              this.setPlaceholder()
          }, clear: function (triggerChange) {
              var data = this.selection.data("select2-data");
              if (data) {
                  this.opts.element.val("");
                  this.selection.find("span").empty();
                  this.selection.removeData("select2-data");
                  this.setPlaceholder();
                  if (triggerChange !== false) {
                      this.opts.element.trigger({type: "select2-removed", val: this.id(data), choice: data});
                      this.triggerChange({removed: data})
                  }
              }
          }, initSelection: function () {
              var selected;
              if (this.opts.element.val() === "" && this.opts.element.text() === "") {
                  this.updateSelection([]);
                  this.close();
                  this.setPlaceholder()
              } else {
                  var self = this;
                  this.opts.initSelection.call(null, this.opts.element, function (selected) {
                      if (selected !== undefined && selected !== null) {
                          self.updateSelection(selected);
                          self.close();
                          self.setPlaceholder()
                      }
                  })
              }
          }, prepareOpts: function () {
              var opts = this.parent.prepareOpts.apply(this, arguments), self = this;
              if (opts.element.get(0).tagName.toLowerCase() === "select") {
                  opts.initSelection = function (element, callback) {
                      var selected = element.find(":selected");
                      callback(self.optionToData(selected))
                  }
              } else {
                  if ("data" in opts) {
                      opts.initSelection = opts.initSelection || function (element, callback) {
                              var id = element.val();
                              var match = null;
                              opts.query({
                                  matcher: function (term, text, el) {
                                      var is_match = equal(id, opts.id(el));
                                      if (is_match) {
                                          match = el
                                      }
                                      return is_match
                                  }, callback: !$.isFunction(callback) ? $.noop : function () {
                                      callback(match)
                                  }
                              })
                          }
                  }
              }
              return opts
          }, getPlaceholder: function () {
              if (this.select) {
                  if (this.select.find("option").first().text() !== "") {
                      return undefined
                  }
              }
              return this.parent.getPlaceholder.apply(this, arguments)
          }, setPlaceholder: function () {
              var placeholder = this.getPlaceholder();
              if (this.opts.element.val() === "" && placeholder !== undefined) {
                  if (this.select && this.select.find("option:first").text() !== "") {
                      return
                  }
                  this.selection.find("span").html(this.opts.escapeMarkup(placeholder));
                  this.selection.addClass("select2-default");
                  this.container.removeClass("select2-allowclear")
              }
          }, postprocessResults: function (data, initial, noHighlightUpdate) {
              var selected = 0, self = this, showSearchInput = true;
              this.findHighlightableChoices().each2(function (i, elm) {
                  if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
                      selected = i;
                      return false
                  }
              });
              if (noHighlightUpdate !== false) {
                  this.highlight(selected)
              }
              if (initial === true && this.showSearchInput === false) {
                  var min = this.opts.minimumResultsForSearch;
                  if (min >= 0) {
                      this.showSearch(countResults(data.results) >= min)
                  }
              }
          }, showSearch: function (showSearchInput) {
              this.showSearchInput = showSearchInput;
              this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput);
              this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput);
              $(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput)
          }, onSelect: function (data, options) {
              if (!this.triggerSelect(data)) {
                  return
              }
              var old = this.opts.element.val(), oldData = this.data();
              this.opts.element.val(this.id(data));
              this.updateSelection(data);
              this.opts.element.trigger({type: "select2-selected", val: this.id(data), choice: data});
              this.close();
              if (!options || !options.noFocus) {
                  this.selection.focus()
              }
              if (!equal(old, this.id(data))) {
                  this.triggerChange({added: data, removed: oldData})
              }
          }, updateSelection: function (data) {
              var container = this.selection.find("span"), formatted;
              this.selection.data("select2-data", data);
              container.empty();
              formatted = this.opts.formatSelection(data, container);
              if (formatted !== undefined) {
                  container.append(this.opts.escapeMarkup(formatted))
              }
              this.selection.removeClass("select2-default");
              if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
                  this.container.addClass("select2-allowclear")
              }
          }, val: function () {
              var val, triggerChange = false, data = null, self = this, oldData = this.data();
              if (arguments.length === 0) {
                  return this.opts.element.val()
              }
              val = arguments[0];
              if (arguments.length > 1) {
                  triggerChange = arguments[1]
              }
              if (this.select) {
                  this.select.val(val).find(":selected").each2(function (i, elm) {
                      data = self.optionToData(elm);
                      return false
                  });
                  this.updateSelection(data);
                  this.setPlaceholder();
                  if (triggerChange) {
                      this.triggerChange({added: data, removed: oldData})
                  }
              } else {
                  if (this.opts.initSelection === undefined) {
                      throw new Error("cannot call val() if initSelection() is not defined")
                  }
                  if (!val && val !== 0) {
                      this.clear(triggerChange);
                      return
                  }
                  this.opts.element.val(val);
                  this.opts.initSelection(this.opts.element, function (data) {
                      self.opts.element.val(!data ? "" : self.id(data));
                      self.updateSelection(data);
                      self.setPlaceholder();
                      if (triggerChange) {
                          self.triggerChange({added: data, removed: oldData})
                      }
                  })
              }
          }, clearSearch: function () {
              this.search.val("");
              this.focusser.val("")
          }, data: function (value, triggerChange) {
              var data;
              if (arguments.length === 0) {
                  data = this.selection.data("select2-data");
                  if (data == undefined) {
                      data = null
                  }
                  return data
              } else {
                  if (!value || value === "") {
                      this.clear(triggerChange)
                  } else {
                      data = this.data();
                      this.opts.element.val(!value ? "" : this.id(value));
                      this.updateSelection(value);
                      if (triggerChange) {
                          this.triggerChange({added: value, removed: data})
                      }
                  }
              }
          }
      });
      MultiSelect2 = clazz(AbstractSelect2, {
          createContainer: function () {
              var container = $(document.createElement("div")).attr({"class": "select2-container select2-container-multi"}).html(["    <ul class='select2-choices'>", "  <li class='select2-search-field'>", "    <input type='text' autocomplete='off' autocorrect='off' autocapitilize='off' spellcheck='false' class='select2-input'>", "  </li>", "</ul>", "<div class='select2-drop select2-drop-multi select2-display-none'>", "   <ul class='select2-results'>", "   </ul>", "</div>"].join(""));
              return container
          }, prepareOpts: function () {
              var opts = this.parent.prepareOpts.apply(this, arguments), self = this;
              if (opts.element.get(0).tagName.toLowerCase() === "select") {
                  opts.initSelection = function (element, callback) {
                      var data = [];
                      element.find(":selected").each2(function (i, elm) {
                          data.push(self.optionToData(elm))
                      });
                      callback(data)
                  }
              } else {
                  if ("data" in opts) {
                      opts.initSelection = opts.initSelection || function (element, callback) {
                              var ids = splitVal(element.val(), opts.separator);
                              var matches = [];
                              opts.query({
                                  matcher: function (term, text, el) {
                                      var is_match = $.grep(ids, function (id) {
                                          return equal(id, opts.id(el))
                                      }).length;
                                      if (is_match) {
                                          matches.push(el)
                                      }
                                      return is_match
                                  }, callback: !$.isFunction(callback) ? $.noop : function () {
                                      var ordered = [];
                                      for (var i = 0; i < ids.length; i++) {
                                          var id = ids[i];
                                          for (var j = 0; j < matches.length; j++) {
                                              var match = matches[j];
                                              if (equal(id, opts.id(match))) {
                                                  ordered.push(match);
                                                  matches.splice(j, 1);
                                                  break
                                              }
                                          }
                                      }
                                      callback(ordered)
                                  }
                              })
                          }
                  }
              }
              return opts
          }, selectChoice: function (choice) {
              var selected = this.container.find(".select2-search-choice-focus");
              if (selected.length && choice && choice[0] == selected[0]) {
              } else {
                  if (selected.length) {
                      this.opts.element.trigger("choice-deselected", selected)
                  }
                  selected.removeClass("select2-search-choice-focus");
                  if (choice && choice.length) {
                      this.close();
                      choice.addClass("select2-search-choice-focus");
                      this.opts.element.trigger("choice-selected", choice)
                  }
              }
          }, initContainer: function () {
              var selector = ".select2-choices", selection;
              this.searchContainer = this.container.find(".select2-search-field");
              this.selection = selection = this.container.find(selector);
              var _this = this;
              this.selection.on("mousedown", ".select2-search-choice", function (e) {
                  _this.search[0].focus();
                  _this.selectChoice($(this))
              });
              this.search.attr("id", "s2id_autogen" + nextUid());
              $("label[for='" + this.opts.element.attr("id") + "']").attr("for", this.search.attr("id"));
              this.search.on("input paste", this.bind(function () {
                  if (!this.isInterfaceEnabled()) {
                      return
                  }
                  if (!this.opened()) {
                      this.open()
                  }
              }));
              this.search.attr("tabindex", this.elementTabIndex);
              this.keydowns = 0;
              this.search.on("keydown", this.bind(function (e) {
                  if (!this.isInterfaceEnabled()) {
                      return
                  }
                  ++this.keydowns;
                  var selected = selection.find(".select2-search-choice-focus");
                  var prev = selected.prev(".select2-search-choice:not(.select2-locked)");
                  var next = selected.next(".select2-search-choice:not(.select2-locked)");
                  var pos = getCursorInfo(this.search);
                  if (selected.length && (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) {
                      var selectedChoice = selected;
                      if (e.which == KEY.LEFT && prev.length) {
                          selectedChoice = prev
                      } else {
                          if (e.which == KEY.RIGHT) {
                              selectedChoice = next.length ? next : null
                          } else {
                              if (e.which === KEY.BACKSPACE) {
                                  this.unselect(selected.first());
                                  this.search.width(10);
                                  selectedChoice = prev.length ? prev : next
                              } else {
                                  if (e.which == KEY.DELETE) {
                                      this.unselect(selected.first());
                                      this.search.width(10);
                                      selectedChoice = next.length ? next : null
                                  } else {
                                      if (e.which == KEY.ENTER) {
                                          selectedChoice = null
                                      }
                                  }
                              }
                          }
                      }
                      this.selectChoice(selectedChoice);
                      killEvent(e);
                      if (!selectedChoice || !selectedChoice.length) {
                          this.open()
                      }
                      return
                  } else {
                      if (((e.which === KEY.BACKSPACE && this.keydowns == 1) || e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) {
                          this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last());
                          killEvent(e);
                          return
                      } else {
                          this.selectChoice(null)
                      }
                  }
                  if (this.opened()) {
                      switch (e.which) {
                          case KEY.UP:
                          case KEY.DOWN:
                              this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
                              killEvent(e);
                              return;
                          case KEY.ENTER:
                              this.selectHighlighted();
                              killEvent(e);
                              return;
                          case KEY.TAB:
                              this.selectHighlighted({noFocus: true});
                              return;
                          case KEY.ESC:
                              this.cancel(e);
                              killEvent(e);
                              return
                      }
                  }
                  if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.BACKSPACE || e.which === KEY.ESC) {
                      return
                  }
                  if (e.which === KEY.ENTER) {
                      if (this.opts.openOnEnter === false) {
                          return
                      } else {
                          if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
                              return
                          }
                      }
                  }
                  this.open();
                  if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
                      killEvent(e)
                  }
                  if (e.which === KEY.ENTER) {
                      killEvent(e)
                  }
              }));
              this.search.on("keyup", this.bind(function (e) {
                  this.keydowns = 0;
                  this.resizeSearch()
              }));
              this.search.on("blur", this.bind(function (e) {
                  this.container.removeClass("select2-container-active");
                  this.search.removeClass("select2-focused");
                  this.selectChoice(null);
                  if (!this.opened()) {
                      this.clearSearch()
                  }
                  e.stopImmediatePropagation();
                  this.opts.element.trigger($.Event("select2-blur"))
              }));
              this.container.on("mousedown", selector, this.bind(function (e) {
                  if (!this.isInterfaceEnabled()) {
                      return
                  }
                  if ($(e.target).closest(".select2-search-choice").length > 0) {
                      return
                  }
                  this.selectChoice(null);
                  this.clearPlaceholder();
                  if (!this.container.hasClass("select2-container-active")) {
                      this.opts.element.trigger($.Event("select2-focus"))
                  }
                  this.open();
                  this.focusSearch();
                  e.preventDefault()
              }));
              this.container.on("focus", selector, this.bind(function () {
                  if (!this.isInterfaceEnabled()) {
                      return
                  }
                  if (!this.container.hasClass("select2-container-active")) {
                      this.opts.element.trigger($.Event("select2-focus"))
                  }
                  this.container.addClass("select2-container-active");
                  this.dropdown.addClass("select2-drop-active");
                  this.clearPlaceholder()
              }));
              this.initContainerWidth();
              this.opts.element.addClass("select2-offscreen");
              this.clearSearch()
          }, enableInterface: function () {
              if (this.parent.enableInterface.apply(this, arguments)) {
                  this.search.prop("disabled", !this.isInterfaceEnabled())
              }
          }, initSelection: function () {
              var data;
              if (this.opts.element.val() === "" && this.opts.element.text() === "") {
                  this.updateSelection([]);
                  this.close();
                  this.clearSearch()
              }
              if (this.select || this.opts.element.val() !== "") {
                  var self = this;
                  this.opts.initSelection.call(null, this.opts.element, function (data) {
                      if (data !== undefined && data !== null) {
                          self.updateSelection(data);
                          self.close();
                          self.clearSearch()
                      }
                  })
              }
          }, clearSearch: function () {
              var placeholder = this.getPlaceholder(), maxWidth = this.getMaxSearchWidth();
              if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
                  this.search.val(placeholder).addClass("select2-default");
                  this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width"))
              } else {
                  this.search.val("").width(10)
              }
          }, clearPlaceholder: function () {
              if (this.search.hasClass("select2-default")) {
                  this.search.val("").removeClass("select2-default")
              }
          }, opening: function () {
              this.clearPlaceholder();
              this.resizeSearch();
              this.parent.opening.apply(this, arguments);
              this.focusSearch();
              this.updateResults(true);
              this.search.focus();
              this.opts.element.trigger($.Event("select2-open"))
          }, close: function () {
              if (!this.opened()) {
                  return
              }
              this.parent.close.apply(this, arguments)
          }, focus: function () {
              this.close();
              this.search.focus()
          }, isFocused: function () {
              return this.search.hasClass("select2-focused")
          }, updateSelection: function (data) {
              var ids = [], filtered = [], self = this;
              $(data).each(function () {
                  if (indexOf(self.id(this), ids) < 0) {
                      ids.push(self.id(this));
                      filtered.push(this)
                  }
              });
              data = filtered;
              this.selection.find(".select2-search-choice").remove();
              $(data).each(function () {
                  self.addSelectedChoice(this)
              });
              self.postprocessResults()
          }, tokenize: function () {
              var input = this.search.val();
              input = this.opts.tokenizer(input, this.data(), this.bind(this.onSelect), this.opts);
              if (input != null && input != undefined) {
                  this.search.val(input);
                  if (input.length > 0) {
                      this.open()
                  }
              }
          }, onSelect: function (data, options) {
              if (!this.triggerSelect(data)) {
                  return
              }
              this.addSelectedChoice(data);
              this.opts.element.trigger({type: "selected", val: this.id(data), choice: data});
              if (this.select || !this.opts.closeOnSelect) {
                  this.postprocessResults()
              }
              if (this.opts.closeOnSelect) {
                  this.close();
                  this.search.width(10)
              } else {
                  if (this.countSelectableResults() > 0) {
                      this.search.width(10);
                      this.resizeSearch();
                      if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {
                          this.updateResults(true)
                      }
                      this.positionDropdown()
                  } else {
                      this.close();
                      this.search.width(10)
                  }
              }
              this.triggerChange({added: data});
              if (!options || !options.noFocus) {
                  this.focusSearch()
              }
          }, cancel: function () {
              this.close();
              this.focusSearch()
          }, addSelectedChoice: function (data) {
              var enableChoice = !data.locked, enabledItem = $("<li class='select2-search-choice'>" + "    <div></div>" + "    <a href='#' onclick='return false;' class='select2-search-choice-close' tabindex='-1'></a>" + "</li>"), disabledItem = $("<li class='select2-search-choice select2-locked'>" + "<div></div>" + "</li>");
              var choice = enableChoice ? enabledItem : disabledItem, id = this.id(data), val = this.getVal(), formatted;
              formatted = this.opts.formatSelection(data, choice.find("div"));
              if (formatted != undefined) {
                  choice.find("div").replaceWith("<div title='" + this.opts.escapeMarkup(formatted) + "'>" + this.opts.escapeMarkup(formatted) + "</div>")
              }
              if (enableChoice) {
                  choice.find(".select2-search-choice-close").on("mousedown", killEvent).on("click dblclick", this.bind(function (e) {
                      if (!this.isInterfaceEnabled()) {
                          return
                      }
                      $(e.target).closest(".select2-search-choice").fadeOut("fast", this.bind(function () {
                          this.unselect($(e.target));
                          this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
                          this.close();
                          this.focusSearch()
                      })).dequeue();
                      killEvent(e)
                  })).on("focus", this.bind(function () {
                      if (!this.isInterfaceEnabled()) {
                          return
                      }
                      this.container.addClass("select2-container-active");
                      this.dropdown.addClass("select2-drop-active")
                  }))
              }
              choice.data("select2-data", data);
              choice.insertBefore(this.searchContainer);
              val.push(id);
              this.setVal(val)
          }, unselect: function (selected) {
              var val = this.getVal(), data, index;
              selected = selected.closest(".select2-search-choice");
              if (selected.length === 0) {
                  throw"Invalid argument: " + selected + ". Must be .select2-search-choice"
              }
              data = selected.data("select2-data");
              if (!data) {
                  return
              }
              index = indexOf(this.id(data), val);
              if (index >= 0) {
                  val.splice(index, 1);
                  this.setVal(val);
                  if (this.select) {
                      this.postprocessResults()
                  }
              }
              selected.remove();
              this.opts.element.trigger({type: "removed", val: this.id(data), choice: data});
              this.triggerChange({removed: data})
          }, postprocessResults: function (data, initial, noHighlightUpdate) {
              var val = this.getVal(), choices = this.results.find(".select2-result"), compound = this.results.find(".select2-result-with-children"), self = this;
              choices.each2(function (i, choice) {
                  var id = self.id(choice.data("select2-data"));
                  if (indexOf(id, val) >= 0) {
                      choice.addClass("select2-selected");
                      choice.find(".select2-result-selectable").addClass("select2-selected")
                  }
              });
              compound.each2(function (i, choice) {
                  if (!choice.is(".select2-result-selectable") && choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) {
                      choice.addClass("select2-selected")
                  }
              });
              if (this.highlight() == -1 && noHighlightUpdate !== false) {
                  self.highlight(0)
              }
              if (!this.opts.createSearchChoice && !choices.filter(".select2-result:not(.select2-selected)").length > 0) {
                  this.results.append("<li class='select2-no-results'>" + self.opts.formatNoMatches(self.search.val()) + "</li>")
              }
          }, getMaxSearchWidth: function () {
              return this.selection.width() - getSideBorderPadding(this.search)
          }, resizeSearch: function () {
              var minimumWidth, left, maxWidth, containerLeft, searchWidth, sideBorderPadding = getSideBorderPadding(this.search);
              minimumWidth = measureTextWidth(this.search) + 10;
              left = this.search.offset().left;
              maxWidth = this.selection.width();
              containerLeft = this.selection.offset().left;
              searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
              if (searchWidth < minimumWidth) {
                  searchWidth = maxWidth - sideBorderPadding
              }
              if (searchWidth < 40) {
                  searchWidth = maxWidth - sideBorderPadding
              }
              if (searchWidth <= 0) {
                  searchWidth = minimumWidth
              }
              this.search.width(searchWidth)
          }, getVal: function () {
              var val;
              if (this.select) {
                  val = this.select.val();
                  return val === null ? [] : val
              } else {
                  val = this.opts.element.val();
                  return splitVal(val, this.opts.separator)
              }
          }, setVal: function (val) {
              var unique;
              if (this.select) {
                  this.select.val(val)
              } else {
                  unique = [];
                  $(val).each(function () {
                      if (indexOf(this, unique) < 0) {
                          unique.push(this)
                      }
                  });
                  this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator))
              }
          }, buildChangeDetails: function (old, current) {
              var current = current.slice(0), old = old.slice(0);
              for (var i = 0; i < current.length; i++) {
                  for (var j = 0; j < old.length; j++) {
                      if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
                          current.splice(i, 1);
                          i--;
                          old.splice(j, 1);
                          j--
                      }
                  }
              }
              return {added: current, removed: old}
          }, val: function (val, triggerChange) {
              var oldData, self = this, changeDetails;
              if (arguments.length === 0) {
                  return this.getVal()
              }
              oldData = this.data();
              if (!oldData.length) {
                  oldData = []
              }
              if (!val && val !== 0) {
                  this.opts.element.val("");
                  this.updateSelection([]);
                  this.clearSearch();
                  if (triggerChange) {
                      this.triggerChange({added: this.data(), removed: oldData})
                  }
                  return
              }
              this.setVal(val);
              if (this.select) {
                  this.opts.initSelection(this.select, this.bind(this.updateSelection));
                  if (triggerChange) {
                      this.triggerChange(this.buildChangeDetails(oldData, this.data()))
                  }
              } else {
                  if (this.opts.initSelection === undefined) {
                      throw new Error("val() cannot be called if initSelection() is not defined")
                  }
                  this.opts.initSelection(this.opts.element, function (data) {
                      var ids = $(data).map(self.id);
                      self.setVal(ids);
                      self.updateSelection(data);
                      self.clearSearch();
                      if (triggerChange) {
                          self.triggerChange(this.buildChangeDetails(oldData, this.data()))
                      }
                  })
              }
              this.clearSearch()
          }, onSortStart: function () {
              if (this.select) {
                  throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.")
              }
              this.search.width(0);
              this.searchContainer.hide()
          }, onSortEnd: function () {
              var val = [], self = this;
              this.searchContainer.show();
              this.searchContainer.appendTo(this.searchContainer.parent());
              this.resizeSearch();
              this.selection.find(".select2-search-choice").each(function () {
                  val.push(self.opts.id($(this).data("select2-data")))
              });
              this.setVal(val);
              this.triggerChange()
          }, data: function (values, triggerChange) {
              var self = this, ids, old;
              if (arguments.length === 0) {
                  return this.selection.find(".select2-search-choice").map(function () {
                      return $(this).data("select2-data")
                  }).get()
              } else {
                  old = this.data();
                  if (!values) {
                      values = []
                  }
                  ids = $.map(values, function (e) {
                      return self.opts.id(e)
                  });
                  this.setVal(ids);
                  this.updateSelection(values);
                  this.clearSearch();
                  if (triggerChange) {
                      this.triggerChange(this.buildChangeDetails(old, this.data()))
                  }
              }
          }
      });
      $.fn.select2 = function () {
          var args = Array.prototype.slice.call(arguments, 0), opts, select2, value, multiple, allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "readonly", "positionDropdown", "data"], valueMethods = ["val", "opened", "isFocused", "container", "data"];
          this.each(function () {
              if (args.length === 0 || typeof(args[0]) === "object") {
                  opts = args.length === 0 ? {} : $.extend({}, args[0]);
                  opts.element = $(this);
                  if (opts.element.get(0).tagName.toLowerCase() === "select") {
                      multiple = opts.element.prop("multiple")
                  } else {
                      multiple = opts.multiple || false;
                      if ("tags" in opts) {
                          opts.multiple = multiple = true
                      }
                  }
                  select2 = multiple ? new MultiSelect2() : new SingleSelect2();
                  select2.init(opts)
              } else {
                  if (typeof(args[0]) === "string") {
                      if (indexOf(args[0], allowedMethods) < 0) {
                          throw"Unknown method: " + args[0]
                      }
                      value = undefined;
                      select2 = $(this).data("select2");
                      if (select2 === undefined) {
                          return
                      }
                      if (args[0] === "container") {
                          value = select2.container
                      } else {
                          value = select2[args[0]].apply(select2, args.slice(1))
                      }
                      if (indexOf(args[0], valueMethods) >= 0) {
                          return false
                      }
                  } else {
                      throw"Invalid arguments to select2 plugin: " + args
                  }
              }
          });
          return (value === undefined) ? this : value
      };
      $.fn.select2.defaults = {
          width: "copy",
          loadMorePadding: 0,
          closeOnSelect: true,
          openOnEnter: true,
          containerCss: {},
          dropdownCss: {},
          containerCssClass: "",
          dropdownCssClass: "",
          formatResult: function (result, container, query, escapeMarkup) {
              var markup = [];
              markMatch(result.text, query.term, markup, escapeMarkup);
              return markup.join("")
          },
          formatSelection: function (data, container) {
              return data ? data.text : undefined
          },
          sortResults: function (results, container, query) {
              return results
          },
          formatResultCssClass: function (data) {
              return undefined
          },
          formatNoMatches: function () {
              return "No matches found"
          },
          formatInputTooShort: function (input, min) {
              var n = min - input.length;
              return "Please enter " + n + " more character" + (n == 1 ? "" : "s")
          },
          formatInputTooLong: function (input, max) {
              var n = input.length - max;
              return "Please delete " + n + " character" + (n == 1 ? "" : "s")
          },
          formatSelectionTooBig: function (limit) {
              return "You can only select " + limit + " item" + (limit == 1 ? "" : "s")
          },
          formatLoadMore: function (pageNumber) {
              return "Loading more results..."
          },
          formatSearching: function () {
              return "Searching..."
          },
          minimumResultsForSearch: 0,
          minimumInputLength: 0,
          maximumInputLength: null,
          maximumSelectionSize: 0,
          id: function (e) {
              return e.id
          },
          matcher: function (term, text) {
              return ("" + text).toUpperCase().indexOf(("" + term).toUpperCase()) >= 0
          },
          separator: ",",
          tokenSeparators: [],
          tokenizer: defaultTokenizer,
          escapeMarkup: function (markup) {
              var replace_map = {
                  "\\": "&#92;",
                  "&": "&amp;",
                  "<": "&lt;",
                  ">": "&gt;",
                  '"': "&quot;",
                  "'": "&#39;",
                  "/": "&#47;"
              };
              return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
                  return replace_map[match]
              })
          },
          blurOnChange: false,
          selectOnBlur: false,
          adaptContainerCssClass: function (c) {
              return c
          },
          adaptDropdownCssClass: function (c) {
              return null
          }
      };
      $.fn.select2.ajaxDefaults = {transport: $.ajax, params: {type: "GET", cache: false, dataType: "json"}};
      window.Select2 = {
          query: {ajax: ajax, local: local, tags: tags},
          util: {debounce: debounce, markMatch: markMatch},
          "class": {"abstract": AbstractSelect2, "single": SingleSelect2, "multi": MultiSelect2}
      }
  }(jQuery));