/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ "./assets/src/js/admin/user-tomselect.js":
/*!***********************************************!*\
  !*** ./assets/src/js/admin/user-tomselect.js ***!
  \***********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _scss_admin_permissions_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/scss/admin/permissions.scss */ \"./assets/src/scss/admin/permissions.scss\");\n/* harmony import */ var tom_select_dist_css_tom_select_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tom-select/dist/css/tom-select.css */ \"./node_modules/tom-select/dist/css/tom-select.css\");\n/* harmony import */ var tom_select__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tom-select */ \"./node_modules/tom-select/dist/js/tom-select.complete.js\");\n/* harmony import */ var tom_select__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tom_select__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\nvar settings = {\n  plugins: {\n    remove_button: {\n      title: \"Remove this item\"\n    }\n  }\n};\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n  document.querySelectorAll(\"select[multiple]\").forEach(function (element) {\n    new (tom_select__WEBPACK_IMPORTED_MODULE_2___default())(element, settings);\n  });\n});\n\n//# sourceURL=webpack://post-sync/./assets/src/js/admin/user-tomselect.js?");

/***/ }),

/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/tom-select/dist/css/tom-select.css":
/*!***********************************************************************************************!*\
  !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/tom-select/dist/css/tom-select.css ***!
  \***********************************************************************************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/**\\n * tom-select.css (v2.2.2)\\n * Copyright (c) contributors\\n *\\n * Licensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use this\\n * file except in compliance with the License. You may obtain a copy of the License at:\\n * http://www.apache.org/licenses/LICENSE-2.0\\n *\\n * Unless required by applicable law or agreed to in writing, software distributed under\\n * the License is distributed on an \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\\n * ANY KIND, either express or implied. See the License for the specific language\\n * governing permissions and limitations under the License.\\n *\\n */\\n:root {\\n  --ts-pr-clear-button:\\t0;\\n  --ts-pr-caret:\\t0;\\n  --ts-pr-min:\\t.75rem;\\n}\\n\\n.ts-wrapper.single .ts-control, .ts-wrapper.single .ts-control input {\\n  cursor: pointer;\\n}\\n\\n.ts-control {\\n  padding-right: max(var(--ts-pr-min), var(--ts-pr-clear-button) + var(--ts-pr-caret)) !important;\\n}\\n\\n.ts-wrapper.plugin-drag_drop.multi > .ts-control > div.ui-sortable-placeholder {\\n  visibility: visible !important;\\n  background: #f2f2f2 !important;\\n  background: rgba(0, 0, 0, 0.06) !important;\\n  border: 0 none !important;\\n  box-shadow: inset 0 0 12px 4px #fff;\\n}\\n.ts-wrapper.plugin-drag_drop .ui-sortable-placeholder::after {\\n  content: \\\"!\\\";\\n  visibility: hidden;\\n}\\n.ts-wrapper.plugin-drag_drop .ui-sortable-helper {\\n  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);\\n}\\n\\n.plugin-checkbox_options .option input {\\n  margin-right: 0.5rem;\\n}\\n\\n.plugin-clear_button {\\n  --ts-pr-clear-button: 1em;\\n}\\n.plugin-clear_button .clear-button {\\n  opacity: 0;\\n  position: absolute;\\n  top: 50%;\\n  transform: translateY(-50%);\\n  right: calc(8px - 6px);\\n  margin-right: 0 !important;\\n  background: transparent !important;\\n  transition: opacity 0.5s;\\n  cursor: pointer;\\n}\\n.plugin-clear_button.form-select .clear-button, .plugin-clear_button.single .clear-button {\\n  right: max( var(--ts-pr-caret), 8px);\\n}\\n.plugin-clear_button.focus.has-items .clear-button, .plugin-clear_button:not(.disabled):hover.has-items .clear-button {\\n  opacity: 1;\\n}\\n\\n.ts-wrapper .dropdown-header {\\n  position: relative;\\n  padding: 10px 8px;\\n  border-bottom: 1px solid #d0d0d0;\\n  background: #f8f8f8;\\n  border-radius: 3px 3px 0 0;\\n}\\n.ts-wrapper .dropdown-header-close {\\n  position: absolute;\\n  right: 8px;\\n  top: 50%;\\n  color: #303030;\\n  opacity: 0.4;\\n  margin-top: -12px;\\n  line-height: 20px;\\n  font-size: 20px !important;\\n}\\n.ts-wrapper .dropdown-header-close:hover {\\n  color: black;\\n}\\n\\n.plugin-dropdown_input.focus.dropdown-active .ts-control {\\n  box-shadow: none;\\n  border: 1px solid #d0d0d0;\\n}\\n.plugin-dropdown_input .dropdown-input {\\n  border: 1px solid #d0d0d0;\\n  border-width: 0 0 1px 0;\\n  display: block;\\n  padding: 8px 8px;\\n  box-shadow: none;\\n  width: 100%;\\n  background: transparent;\\n}\\n.plugin-dropdown_input .items-placeholder {\\n  border: 0 none !important;\\n  box-shadow: none !important;\\n  width: 100%;\\n}\\n.plugin-dropdown_input.has-items .items-placeholder, .plugin-dropdown_input.dropdown-active .items-placeholder {\\n  display: none !important;\\n}\\n\\n.ts-wrapper.plugin-input_autogrow.has-items .ts-control > input {\\n  min-width: 0;\\n}\\n.ts-wrapper.plugin-input_autogrow.has-items.focus .ts-control > input {\\n  flex: none;\\n  min-width: 4px;\\n}\\n.ts-wrapper.plugin-input_autogrow.has-items.focus .ts-control > input::-ms-input-placeholder {\\n  color: transparent;\\n}\\n.ts-wrapper.plugin-input_autogrow.has-items.focus .ts-control > input::placeholder {\\n  color: transparent;\\n}\\n\\n.ts-dropdown.plugin-optgroup_columns .ts-dropdown-content {\\n  display: flex;\\n}\\n.ts-dropdown.plugin-optgroup_columns .optgroup {\\n  border-right: 1px solid #f2f2f2;\\n  border-top: 0 none;\\n  flex-grow: 1;\\n  flex-basis: 0;\\n  min-width: 0;\\n}\\n.ts-dropdown.plugin-optgroup_columns .optgroup:last-child {\\n  border-right: 0 none;\\n}\\n.ts-dropdown.plugin-optgroup_columns .optgroup:before {\\n  display: none;\\n}\\n.ts-dropdown.plugin-optgroup_columns .optgroup-header {\\n  border-top: 0 none;\\n}\\n\\n.ts-wrapper.plugin-remove_button .item {\\n  display: inline-flex;\\n  align-items: center;\\n  padding-right: 0 !important;\\n}\\n.ts-wrapper.plugin-remove_button .item .remove {\\n  color: inherit;\\n  text-decoration: none;\\n  vertical-align: middle;\\n  display: inline-block;\\n  padding: 0 6px;\\n  border-radius: 0 2px 2px 0;\\n  box-sizing: border-box;\\n}\\n.ts-wrapper.plugin-remove_button .item .remove:hover {\\n  background: rgba(0, 0, 0, 0.05);\\n}\\n.ts-wrapper.plugin-remove_button.disabled .item .remove:hover {\\n  background: none;\\n}\\n.ts-wrapper.plugin-remove_button .remove-single {\\n  position: absolute;\\n  right: 0;\\n  top: 0;\\n  font-size: 23px;\\n}\\n\\n.ts-wrapper.plugin-remove_button:not(.rtl) .item .remove {\\n  border-left: 1px solid #d0d0d0;\\n  margin-left: 6px;\\n}\\n.ts-wrapper.plugin-remove_button:not(.rtl) .item.active .remove {\\n  border-left-color: #cacaca;\\n}\\n.ts-wrapper.plugin-remove_button:not(.rtl).disabled .item .remove {\\n  border-left-color: white;\\n}\\n\\n.ts-wrapper.plugin-remove_button.rtl .item .remove {\\n  border-right: 1px solid #d0d0d0;\\n  margin-right: 6px;\\n}\\n.ts-wrapper.plugin-remove_button.rtl .item.active .remove {\\n  border-right-color: #cacaca;\\n}\\n.ts-wrapper.plugin-remove_button.rtl.disabled .item .remove {\\n  border-right-color: white;\\n}\\n\\n.ts-wrapper {\\n  position: relative;\\n}\\n\\n.ts-dropdown,\\n.ts-control,\\n.ts-control input {\\n  color: #303030;\\n  font-family: inherit;\\n  font-size: 13px;\\n  line-height: 18px;\\n  font-smoothing: inherit;\\n}\\n\\n.ts-control,\\n.ts-wrapper.single.input-active .ts-control {\\n  background: #fff;\\n  cursor: text;\\n}\\n\\n.ts-control {\\n  border: 1px solid #d0d0d0;\\n  padding: 8px 8px;\\n  width: 100%;\\n  overflow: hidden;\\n  position: relative;\\n  z-index: 1;\\n  box-sizing: border-box;\\n  box-shadow: none;\\n  border-radius: 3px;\\n  display: flex;\\n  flex-wrap: wrap;\\n}\\n.ts-wrapper.multi.has-items .ts-control {\\n  padding: calc( 8px - 2px - 0px) 8px calc( 8px - 2px - 3px - 0px);\\n}\\n.full .ts-control {\\n  background-color: #fff;\\n}\\n.disabled .ts-control, .disabled .ts-control * {\\n  cursor: default !important;\\n}\\n.focus .ts-control {\\n  box-shadow: none;\\n}\\n.ts-control > * {\\n  vertical-align: baseline;\\n  display: inline-block;\\n}\\n.ts-wrapper.multi .ts-control > div {\\n  cursor: pointer;\\n  margin: 0 3px 3px 0;\\n  padding: 2px 6px;\\n  background: #f2f2f2;\\n  color: #303030;\\n  border: 0px solid #d0d0d0;\\n}\\n.ts-wrapper.multi .ts-control > div.active {\\n  background: #e8e8e8;\\n  color: #303030;\\n  border: 0px solid #cacaca;\\n}\\n.ts-wrapper.multi.disabled .ts-control > div, .ts-wrapper.multi.disabled .ts-control > div.active {\\n  color: #7d7d7d;\\n  background: white;\\n  border: 0px solid white;\\n}\\n.ts-control > input {\\n  flex: 1 1 auto;\\n  min-width: 7rem;\\n  display: inline-block !important;\\n  padding: 0 !important;\\n  min-height: 0 !important;\\n  max-height: none !important;\\n  max-width: 100% !important;\\n  margin: 0 !important;\\n  text-indent: 0 !important;\\n  border: 0 none !important;\\n  background: none !important;\\n  line-height: inherit !important;\\n  -webkit-user-select: auto !important;\\n     -moz-user-select: auto !important;\\n      -ms-user-select: auto !important;\\n          user-select: auto !important;\\n  box-shadow: none !important;\\n}\\n.ts-control > input::-ms-clear {\\n  display: none;\\n}\\n.ts-control > input:focus {\\n  outline: none !important;\\n}\\n.has-items .ts-control > input {\\n  margin: 0px 4px !important;\\n}\\n.ts-control.rtl {\\n  text-align: right;\\n}\\n.ts-control.rtl.single .ts-control:after {\\n  left: 15px;\\n  right: auto;\\n}\\n.ts-control.rtl .ts-control > input {\\n  margin: 0px 4px 0px -2px !important;\\n}\\n.disabled .ts-control {\\n  opacity: 0.5;\\n  background-color: #fafafa;\\n}\\n.input-hidden .ts-control > input {\\n  opacity: 0;\\n  position: absolute;\\n  left: -10000px;\\n}\\n\\n.ts-dropdown {\\n  position: absolute;\\n  top: 100%;\\n  left: 0;\\n  width: 100%;\\n  z-index: 10;\\n  border: 1px solid #d0d0d0;\\n  background: #fff;\\n  margin: 0.25rem 0 0 0;\\n  border-top: 0 none;\\n  box-sizing: border-box;\\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\\n  border-radius: 0 0 3px 3px;\\n}\\n.ts-dropdown [data-selectable] {\\n  cursor: pointer;\\n  overflow: hidden;\\n}\\n.ts-dropdown [data-selectable] .highlight {\\n  background: rgba(125, 168, 208, 0.2);\\n  border-radius: 1px;\\n}\\n.ts-dropdown .option,\\n.ts-dropdown .optgroup-header,\\n.ts-dropdown .no-results,\\n.ts-dropdown .create {\\n  padding: 5px 8px;\\n}\\n.ts-dropdown .option, .ts-dropdown [data-disabled], .ts-dropdown [data-disabled] [data-selectable].option {\\n  cursor: inherit;\\n  opacity: 0.5;\\n}\\n.ts-dropdown [data-selectable].option {\\n  opacity: 1;\\n  cursor: pointer;\\n}\\n.ts-dropdown .optgroup:first-child .optgroup-header {\\n  border-top: 0 none;\\n}\\n.ts-dropdown .optgroup-header {\\n  color: #303030;\\n  background: #fff;\\n  cursor: default;\\n}\\n.ts-dropdown .active {\\n  background-color: #f5fafd;\\n  color: #495c68;\\n}\\n.ts-dropdown .active.create {\\n  color: #495c68;\\n}\\n.ts-dropdown .create {\\n  color: rgba(48, 48, 48, 0.5);\\n}\\n.ts-dropdown .spinner {\\n  display: inline-block;\\n  width: 30px;\\n  height: 30px;\\n  margin: 5px 8px;\\n}\\n.ts-dropdown .spinner:after {\\n  content: \\\" \\\";\\n  display: block;\\n  width: 24px;\\n  height: 24px;\\n  margin: 3px;\\n  border-radius: 50%;\\n  border: 5px solid #d0d0d0;\\n  border-color: #d0d0d0 transparent #d0d0d0 transparent;\\n  animation: lds-dual-ring 1.2s linear infinite;\\n}\\n@keyframes lds-dual-ring {\\n  0% {\\n    transform: rotate(0deg);\\n  }\\n  100% {\\n    transform: rotate(360deg);\\n  }\\n}\\n\\n.ts-dropdown-content {\\n  overflow-y: auto;\\n  overflow-x: hidden;\\n  max-height: 200px;\\n  overflow-scrolling: touch;\\n  scroll-behavior: smooth;\\n}\\n\\n.ts-hidden-accessible {\\n  border: 0 !important;\\n  clip: rect(0 0 0 0) !important;\\n  -webkit-clip-path: inset(50%) !important;\\n          clip-path: inset(50%) !important;\\n  overflow: hidden !important;\\n  padding: 0 !important;\\n  position: absolute !important;\\n  width: 1px !important;\\n  white-space: nowrap !important;\\n}\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://post-sync/./node_modules/tom-select/dist/css/tom-select.css?./node_modules/css-loader/dist/cjs.js");

/***/ }),

/***/ "./node_modules/css-loader/dist/runtime/api.js":
/*!*****************************************************!*\
  !*** ./node_modules/css-loader/dist/runtime/api.js ***!
  \*****************************************************/
/***/ ((module) => {

"use strict";
eval("\n\n/*\n  MIT License http://www.opensource.org/licenses/mit-license.php\n  Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n  var list = [];\n\n  // return the list of modules as css string\n  list.toString = function toString() {\n    return this.map(function (item) {\n      var content = \"\";\n      var needLayer = typeof item[5] !== \"undefined\";\n      if (item[4]) {\n        content += \"@supports (\".concat(item[4], \") {\");\n      }\n      if (item[2]) {\n        content += \"@media \".concat(item[2], \" {\");\n      }\n      if (needLayer) {\n        content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n      }\n      content += cssWithMappingToString(item);\n      if (needLayer) {\n        content += \"}\";\n      }\n      if (item[2]) {\n        content += \"}\";\n      }\n      if (item[4]) {\n        content += \"}\";\n      }\n      return content;\n    }).join(\"\");\n  };\n\n  // import a list of modules into the list\n  list.i = function i(modules, media, dedupe, supports, layer) {\n    if (typeof modules === \"string\") {\n      modules = [[null, modules, undefined]];\n    }\n    var alreadyImportedModules = {};\n    if (dedupe) {\n      for (var k = 0; k < this.length; k++) {\n        var id = this[k][0];\n        if (id != null) {\n          alreadyImportedModules[id] = true;\n        }\n      }\n    }\n    for (var _k = 0; _k < modules.length; _k++) {\n      var item = [].concat(modules[_k]);\n      if (dedupe && alreadyImportedModules[item[0]]) {\n        continue;\n      }\n      if (typeof layer !== \"undefined\") {\n        if (typeof item[5] === \"undefined\") {\n          item[5] = layer;\n        } else {\n          item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n          item[5] = layer;\n        }\n      }\n      if (media) {\n        if (!item[2]) {\n          item[2] = media;\n        } else {\n          item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n          item[2] = media;\n        }\n      }\n      if (supports) {\n        if (!item[4]) {\n          item[4] = \"\".concat(supports);\n        } else {\n          item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n          item[4] = supports;\n        }\n      }\n      list.push(item);\n    }\n  };\n  return list;\n};\n\n//# sourceURL=webpack://post-sync/./node_modules/css-loader/dist/runtime/api.js?");

/***/ }),

/***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js":
/*!**************************************************************!*\
  !*** ./node_modules/css-loader/dist/runtime/noSourceMaps.js ***!
  \**************************************************************/
/***/ ((module) => {

"use strict";
eval("\n\nmodule.exports = function (i) {\n  return i[1];\n};\n\n//# sourceURL=webpack://post-sync/./node_modules/css-loader/dist/runtime/noSourceMaps.js?");

/***/ }),

/***/ "./assets/src/scss/admin/permissions.scss":
/*!************************************************!*\
  !*** ./assets/src/scss/admin/permissions.scss ***!
  \************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n\n\n//# sourceURL=webpack://post-sync/./assets/src/scss/admin/permissions.scss?");

/***/ }),

/***/ "./node_modules/tom-select/dist/css/tom-select.css":
/*!*********************************************************!*\
  !*** ./node_modules/tom-select/dist/css/tom-select.css ***!
  \*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../../../style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n/* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../../../style-loader/dist/runtime/styleDomAPI.js */ \"./node_modules/style-loader/dist/runtime/styleDomAPI.js\");\n/* harmony import */ var _style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../../../style-loader/dist/runtime/insertBySelector.js */ \"./node_modules/style-loader/dist/runtime/insertBySelector.js\");\n/* harmony import */ var _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../../../style-loader/dist/runtime/setAttributesWithoutAttributes.js */ \"./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\");\n/* harmony import */ var _style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../../../style-loader/dist/runtime/insertStyleElement.js */ \"./node_modules/style-loader/dist/runtime/insertStyleElement.js\");\n/* harmony import */ var _style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../../../style-loader/dist/runtime/styleTagTransform.js */ \"./node_modules/style-loader/dist/runtime/styleTagTransform.js\");\n/* harmony import */ var _style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _css_loader_dist_cjs_js_tom_select_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../../../css-loader/dist/cjs.js!./tom-select.css */ \"./node_modules/css-loader/dist/cjs.js!./node_modules/tom-select/dist/css/tom-select.css\");\n\n      \n      \n      \n      \n      \n      \n      \n      \n      \n\nvar options = {};\n\noptions.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());\noptions.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());\n\n      options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, \"head\");\n    \noptions.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());\noptions.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());\n\nvar update = _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_css_loader_dist_cjs_js_tom_select_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"], options);\n\n\n\n\n       /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_css_loader_dist_cjs_js_tom_select_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"] && _css_loader_dist_cjs_js_tom_select_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals ? _css_loader_dist_cjs_js_tom_select_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals : undefined);\n\n\n//# sourceURL=webpack://post-sync/./node_modules/tom-select/dist/css/tom-select.css?");

/***/ }),

/***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js":
/*!****************************************************************************!*\
  !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
  \****************************************************************************/
/***/ ((module) => {

"use strict";
eval("\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n  var result = -1;\n  for (var i = 0; i < stylesInDOM.length; i++) {\n    if (stylesInDOM[i].identifier === identifier) {\n      result = i;\n      break;\n    }\n  }\n  return result;\n}\nfunction modulesToDom(list, options) {\n  var idCountMap = {};\n  var identifiers = [];\n  for (var i = 0; i < list.length; i++) {\n    var item = list[i];\n    var id = options.base ? item[0] + options.base : item[0];\n    var count = idCountMap[id] || 0;\n    var identifier = \"\".concat(id, \" \").concat(count);\n    idCountMap[id] = count + 1;\n    var indexByIdentifier = getIndexByIdentifier(identifier);\n    var obj = {\n      css: item[1],\n      media: item[2],\n      sourceMap: item[3],\n      supports: item[4],\n      layer: item[5]\n    };\n    if (indexByIdentifier !== -1) {\n      stylesInDOM[indexByIdentifier].references++;\n      stylesInDOM[indexByIdentifier].updater(obj);\n    } else {\n      var updater = addElementStyle(obj, options);\n      options.byIndex = i;\n      stylesInDOM.splice(i, 0, {\n        identifier: identifier,\n        updater: updater,\n        references: 1\n      });\n    }\n    identifiers.push(identifier);\n  }\n  return identifiers;\n}\nfunction addElementStyle(obj, options) {\n  var api = options.domAPI(options);\n  api.update(obj);\n  var updater = function updater(newObj) {\n    if (newObj) {\n      if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n        return;\n      }\n      api.update(obj = newObj);\n    } else {\n      api.remove();\n    }\n  };\n  return updater;\n}\nmodule.exports = function (list, options) {\n  options = options || {};\n  list = list || [];\n  var lastIdentifiers = modulesToDom(list, options);\n  return function update(newList) {\n    newList = newList || [];\n    for (var i = 0; i < lastIdentifiers.length; i++) {\n      var identifier = lastIdentifiers[i];\n      var index = getIndexByIdentifier(identifier);\n      stylesInDOM[index].references--;\n    }\n    var newLastIdentifiers = modulesToDom(newList, options);\n    for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n      var _identifier = lastIdentifiers[_i];\n      var _index = getIndexByIdentifier(_identifier);\n      if (stylesInDOM[_index].references === 0) {\n        stylesInDOM[_index].updater();\n        stylesInDOM.splice(_index, 1);\n      }\n    }\n    lastIdentifiers = newLastIdentifiers;\n  };\n};\n\n//# sourceURL=webpack://post-sync/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?");

/***/ }),

/***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js":
/*!********************************************************************!*\
  !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
  \********************************************************************/
/***/ ((module) => {

"use strict";
eval("\n\nvar memo = {};\n\n/* istanbul ignore next  */\nfunction getTarget(target) {\n  if (typeof memo[target] === \"undefined\") {\n    var styleTarget = document.querySelector(target);\n\n    // Special case to return head of iframe instead of iframe itself\n    if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n      try {\n        // This will throw an exception if access to iframe is blocked\n        // due to cross-origin restrictions\n        styleTarget = styleTarget.contentDocument.head;\n      } catch (e) {\n        // istanbul ignore next\n        styleTarget = null;\n      }\n    }\n    memo[target] = styleTarget;\n  }\n  return memo[target];\n}\n\n/* istanbul ignore next  */\nfunction insertBySelector(insert, style) {\n  var target = getTarget(insert);\n  if (!target) {\n    throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n  }\n  target.appendChild(style);\n}\nmodule.exports = insertBySelector;\n\n//# sourceURL=webpack://post-sync/./node_modules/style-loader/dist/runtime/insertBySelector.js?");

/***/ }),

/***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js":
/*!**********************************************************************!*\
  !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
  \**********************************************************************/
/***/ ((module) => {

"use strict";
eval("\n\n/* istanbul ignore next  */\nfunction insertStyleElement(options) {\n  var element = document.createElement(\"style\");\n  options.setAttributes(element, options.attributes);\n  options.insert(element, options.options);\n  return element;\n}\nmodule.exports = insertStyleElement;\n\n//# sourceURL=webpack://post-sync/./node_modules/style-loader/dist/runtime/insertStyleElement.js?");

/***/ }),

/***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js":
/*!**********************************************************************************!*\
  !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
  \**********************************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";
eval("\n\n/* istanbul ignore next  */\nfunction setAttributesWithoutAttributes(styleElement) {\n  var nonce =  true ? __webpack_require__.nc : 0;\n  if (nonce) {\n    styleElement.setAttribute(\"nonce\", nonce);\n  }\n}\nmodule.exports = setAttributesWithoutAttributes;\n\n//# sourceURL=webpack://post-sync/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js?");

/***/ }),

/***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js":
/*!***************************************************************!*\
  !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
  \***************************************************************/
/***/ ((module) => {

"use strict";
eval("\n\n/* istanbul ignore next  */\nfunction apply(styleElement, options, obj) {\n  var css = \"\";\n  if (obj.supports) {\n    css += \"@supports (\".concat(obj.supports, \") {\");\n  }\n  if (obj.media) {\n    css += \"@media \".concat(obj.media, \" {\");\n  }\n  var needLayer = typeof obj.layer !== \"undefined\";\n  if (needLayer) {\n    css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n  }\n  css += obj.css;\n  if (needLayer) {\n    css += \"}\";\n  }\n  if (obj.media) {\n    css += \"}\";\n  }\n  if (obj.supports) {\n    css += \"}\";\n  }\n  var sourceMap = obj.sourceMap;\n  if (sourceMap && typeof btoa !== \"undefined\") {\n    css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n  }\n\n  // For old IE\n  /* istanbul ignore if  */\n  options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n  // istanbul ignore if\n  if (styleElement.parentNode === null) {\n    return false;\n  }\n  styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next  */\nfunction domAPI(options) {\n  if (typeof document === \"undefined\") {\n    return {\n      update: function update() {},\n      remove: function remove() {}\n    };\n  }\n  var styleElement = options.insertStyleElement(options);\n  return {\n    update: function update(obj) {\n      apply(styleElement, options, obj);\n    },\n    remove: function remove() {\n      removeStyleElement(styleElement);\n    }\n  };\n}\nmodule.exports = domAPI;\n\n//# sourceURL=webpack://post-sync/./node_modules/style-loader/dist/runtime/styleDomAPI.js?");

/***/ }),

/***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js":
/*!*********************************************************************!*\
  !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
  \*********************************************************************/
/***/ ((module) => {

"use strict";
eval("\n\n/* istanbul ignore next  */\nfunction styleTagTransform(css, styleElement) {\n  if (styleElement.styleSheet) {\n    styleElement.styleSheet.cssText = css;\n  } else {\n    while (styleElement.firstChild) {\n      styleElement.removeChild(styleElement.firstChild);\n    }\n    styleElement.appendChild(document.createTextNode(css));\n  }\n}\nmodule.exports = styleTagTransform;\n\n//# sourceURL=webpack://post-sync/./node_modules/style-loader/dist/runtime/styleTagTransform.js?");

/***/ }),

/***/ "./node_modules/tom-select/dist/js/tom-select.complete.js":
/*!****************************************************************!*\
  !*** ./node_modules/tom-select/dist/js/tom-select.complete.js ***!
  \****************************************************************/
/***/ (function(module) {

eval("/**\n* Tom Select v2.2.2\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n(function (global, factory) {\n\t true ? module.exports = factory() :\n\t0;\n})(this, (function () { 'use strict';\n\n\t/**\n\t * MicroEvent - to make any js object an event emitter\n\t *\n\t * - pure javascript - server compatible, browser compatible\n\t * - dont rely on the browser doms\n\t * - super simple - you get it immediatly, no mistery, no magic involved\n\t *\n\t * @author Jerome Etienne (https://github.com/jeromeetienne)\n\t */\n\n\t/**\n\t * Execute callback for each event in space separated list of event names\n\t *\n\t */\n\tfunction forEvents(events, callback) {\n\t  events.split(/\\s+/).forEach(event => {\n\t    callback(event);\n\t  });\n\t}\n\n\tclass MicroEvent {\n\t  constructor() {\n\t    this._events = void 0;\n\t    this._events = {};\n\t  }\n\n\t  on(events, fct) {\n\t    forEvents(events, event => {\n\t      const event_array = this._events[event] || [];\n\t      event_array.push(fct);\n\t      this._events[event] = event_array;\n\t    });\n\t  }\n\n\t  off(events, fct) {\n\t    var n = arguments.length;\n\n\t    if (n === 0) {\n\t      this._events = {};\n\t      return;\n\t    }\n\n\t    forEvents(events, event => {\n\t      if (n === 1) {\n\t        delete this._events[event];\n\t        return;\n\t      }\n\n\t      const event_array = this._events[event];\n\t      if (event_array === undefined) return;\n\t      event_array.splice(event_array.indexOf(fct), 1);\n\t      this._events[event] = event_array;\n\t    });\n\t  }\n\n\t  trigger(events, ...args) {\n\t    var self = this;\n\t    forEvents(events, event => {\n\t      const event_array = self._events[event];\n\t      if (event_array === undefined) return;\n\t      event_array.forEach(fct => {\n\t        fct.apply(self, args);\n\t      });\n\t    });\n\t  }\n\n\t}\n\n\t/**\n\t * microplugin.js\n\t * Copyright (c) 2013 Brian Reavis & contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t * @author Brian Reavis <brian@thirdroute.com>\n\t */\n\tfunction MicroPlugin(Interface) {\n\t  Interface.plugins = {};\n\t  return class extends Interface {\n\t    constructor(...args) {\n\t      super(...args);\n\t      this.plugins = {\n\t        names: [],\n\t        settings: {},\n\t        requested: {},\n\t        loaded: {}\n\t      };\n\t    }\n\n\t    /**\n\t     * Registers a plugin.\n\t     *\n\t     * @param {function} fn\n\t     */\n\t    static define(name, fn) {\n\t      Interface.plugins[name] = {\n\t        'name': name,\n\t        'fn': fn\n\t      };\n\t    }\n\t    /**\n\t     * Initializes the listed plugins (with options).\n\t     * Acceptable formats:\n\t     *\n\t     * List (without options):\n\t     *   ['a', 'b', 'c']\n\t     *\n\t     * List (with options):\n\t     *   [{'name': 'a', options: {}}, {'name': 'b', options: {}}]\n\t     *\n\t     * Hash (with options):\n\t     *   {'a': { ... }, 'b': { ... }, 'c': { ... }}\n\t     *\n\t     * @param {array|object} plugins\n\t     */\n\n\n\t    initializePlugins(plugins) {\n\t      var key, name;\n\t      const self = this;\n\t      const queue = [];\n\n\t      if (Array.isArray(plugins)) {\n\t        plugins.forEach(plugin => {\n\t          if (typeof plugin === 'string') {\n\t            queue.push(plugin);\n\t          } else {\n\t            self.plugins.settings[plugin.name] = plugin.options;\n\t            queue.push(plugin.name);\n\t          }\n\t        });\n\t      } else if (plugins) {\n\t        for (key in plugins) {\n\t          if (plugins.hasOwnProperty(key)) {\n\t            self.plugins.settings[key] = plugins[key];\n\t            queue.push(key);\n\t          }\n\t        }\n\t      }\n\n\t      while (name = queue.shift()) {\n\t        self.require(name);\n\t      }\n\t    }\n\n\t    loadPlugin(name) {\n\t      var self = this;\n\t      var plugins = self.plugins;\n\t      var plugin = Interface.plugins[name];\n\n\t      if (!Interface.plugins.hasOwnProperty(name)) {\n\t        throw new Error('Unable to find \"' + name + '\" plugin');\n\t      }\n\n\t      plugins.requested[name] = true;\n\t      plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);\n\t      plugins.names.push(name);\n\t    }\n\t    /**\n\t     * Initializes a plugin.\n\t     *\n\t     */\n\n\n\t    require(name) {\n\t      var self = this;\n\t      var plugins = self.plugins;\n\n\t      if (!self.plugins.loaded.hasOwnProperty(name)) {\n\t        if (plugins.requested[name]) {\n\t          throw new Error('Plugin has circular dependency (\"' + name + '\")');\n\t        }\n\n\t        self.loadPlugin(name);\n\t      }\n\n\t      return plugins.loaded[name];\n\t    }\n\n\t  };\n\t}\n\n\t/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */\n\t/**\n\t * Convert array of strings to a regular expression\n\t *\tex ['ab','a'] => (?:ab|a)\n\t * \tex ['a','b'] => [ab]\n\t * @param {string[]} chars\n\t * @return {string}\n\t */\n\tconst arrayToPattern = chars => {\n\t  chars = chars.filter(Boolean);\n\n\t  if (chars.length < 2) {\n\t    return chars[0] || '';\n\t  }\n\n\t  return maxValueLength(chars) == 1 ? '[' + chars.join('') + ']' : '(?:' + chars.join('|') + ')';\n\t};\n\t/**\n\t * @param {string[]} array\n\t * @return {string}\n\t */\n\n\tconst sequencePattern = array => {\n\t  if (!hasDuplicates(array)) {\n\t    return array.join('');\n\t  }\n\n\t  let pattern = '';\n\t  let prev_char_count = 0;\n\n\t  const prev_pattern = () => {\n\t    if (prev_char_count > 1) {\n\t      pattern += '{' + prev_char_count + '}';\n\t    }\n\t  };\n\n\t  array.forEach((char, i) => {\n\t    if (char === array[i - 1]) {\n\t      prev_char_count++;\n\t      return;\n\t    }\n\n\t    prev_pattern();\n\t    pattern += char;\n\t    prev_char_count = 1;\n\t  });\n\t  prev_pattern();\n\t  return pattern;\n\t};\n\t/**\n\t * Convert array of strings to a regular expression\n\t *\tex ['ab','a'] => (?:ab|a)\n\t * \tex ['a','b'] => [ab]\n\t * @param {Set<string>} chars\n\t * @return {string}\n\t */\n\n\tconst setToPattern = chars => {\n\t  let array = toArray(chars);\n\t  return arrayToPattern(array);\n\t};\n\t/**\n\t *\n\t * https://stackoverflow.com/questions/7376598/in-javascript-how-do-i-check-if-an-array-has-duplicate-values\n\t * @param {any[]} array\n\t */\n\n\tconst hasDuplicates = array => {\n\t  return new Set(array).size !== array.length;\n\t};\n\t/**\n\t * https://stackoverflow.com/questions/63006601/why-does-u-throw-an-invalid-escape-error\n\t * @param {string} str\n\t * @return {string}\n\t */\n\n\tconst escape_regex = str => {\n\t  return (str + '').replace(/([\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\|\\}\\\\])/gu, '\\\\$1');\n\t};\n\t/**\n\t * Return the max length of array values\n\t * @param {string[]} array\n\t *\n\t */\n\n\tconst maxValueLength = array => {\n\t  return array.reduce((longest, value) => Math.max(longest, unicodeLength(value)), 0);\n\t};\n\t/**\n\t * @param {string} str\n\t */\n\n\tconst unicodeLength = str => {\n\t  return toArray(str).length;\n\t};\n\t/**\n\t * @param {any} p\n\t * @return {any[]}\n\t */\n\n\tconst toArray = p => Array.from(p);\n\n\t/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */\n\t/**\n\t * Get all possible combinations of substrings that add up to the given string\n\t * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string\n\t * @param {string} input\n\t * @return {string[][]}\n\t */\n\tconst allSubstrings = input => {\n\t  if (input.length === 1) return [[input]];\n\t  /** @type {string[][]} */\n\n\t  let result = [];\n\t  const start = input.substring(1);\n\t  const suba = allSubstrings(start);\n\t  suba.forEach(function (subresult) {\n\t    let tmp = subresult.slice(0);\n\t    tmp[0] = input.charAt(0) + tmp[0];\n\t    result.push(tmp);\n\t    tmp = subresult.slice(0);\n\t    tmp.unshift(input.charAt(0));\n\t    result.push(tmp);\n\t  });\n\t  return result;\n\t};\n\n\t/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */\n\n\t/**\n\t * @typedef {{[key:string]:string}} TUnicodeMap\n\t * @typedef {{[key:string]:Set<string>}} TUnicodeSets\n\t * @typedef {[[number,number]]} TCodePoints\n\t * @typedef {{folded:string,composed:string,code_point:number}} TCodePointObj\n\t * @typedef {{start:number,end:number,length:number,substr:string}} TSequencePart\n\t */\n\t/** @type {TCodePoints} */\n\n\tconst code_points = [[0, 65535]];\n\tconst accent_pat = '[\\u0300-\\u036F\\u{b7}\\u{2be}\\u{2bc}]';\n\t/** @type {TUnicodeMap} */\n\n\tlet unicode_map;\n\t/** @type {RegExp} */\n\n\tlet multi_char_reg;\n\tconst max_char_length = 3;\n\t/** @type {TUnicodeMap} */\n\n\tconst latin_convert = {};\n\t/** @type {TUnicodeMap} */\n\n\tconst latin_condensed = {\n\t  '/': '⁄∕',\n\t  '0': '߀',\n\t  \"a\": \"ⱥɐɑ\",\n\t  \"aa\": \"ꜳ\",\n\t  \"ae\": \"æǽǣ\",\n\t  \"ao\": \"ꜵ\",\n\t  \"au\": \"ꜷ\",\n\t  \"av\": \"ꜹꜻ\",\n\t  \"ay\": \"ꜽ\",\n\t  \"b\": \"ƀɓƃ\",\n\t  \"c\": \"ꜿƈȼↄ\",\n\t  \"d\": \"đɗɖᴅƌꮷԁɦ\",\n\t  \"e\": \"ɛǝᴇɇ\",\n\t  \"f\": \"ꝼƒ\",\n\t  \"g\": \"ǥɠꞡᵹꝿɢ\",\n\t  \"h\": \"ħⱨⱶɥ\",\n\t  \"i\": \"ɨı\",\n\t  \"j\": \"ɉȷ\",\n\t  \"k\": \"ƙⱪꝁꝃꝅꞣ\",\n\t  \"l\": \"łƚɫⱡꝉꝇꞁɭ\",\n\t  \"m\": \"ɱɯϻ\",\n\t  \"n\": \"ꞥƞɲꞑᴎлԉ\",\n\t  \"o\": \"øǿɔɵꝋꝍᴑ\",\n\t  \"oe\": \"œ\",\n\t  \"oi\": \"ƣ\",\n\t  \"oo\": \"ꝏ\",\n\t  \"ou\": \"ȣ\",\n\t  \"p\": \"ƥᵽꝑꝓꝕρ\",\n\t  \"q\": \"ꝗꝙɋ\",\n\t  \"r\": \"ɍɽꝛꞧꞃ\",\n\t  \"s\": \"ßȿꞩꞅʂ\",\n\t  \"t\": \"ŧƭʈⱦꞇ\",\n\t  \"th\": \"þ\",\n\t  \"tz\": \"ꜩ\",\n\t  \"u\": \"ʉ\",\n\t  \"v\": \"ʋꝟʌ\",\n\t  \"vy\": \"ꝡ\",\n\t  \"w\": \"ⱳ\",\n\t  \"y\": \"ƴɏỿ\",\n\t  \"z\": \"ƶȥɀⱬꝣ\",\n\t  \"hv\": \"ƕ\"\n\t};\n\n\tfor (let latin in latin_condensed) {\n\t  let unicode = latin_condensed[latin] || '';\n\n\t  for (let i = 0; i < unicode.length; i++) {\n\t    let char = unicode.substring(i, i + 1);\n\t    latin_convert[char] = latin;\n\t  }\n\t}\n\n\tconst convert_pat = new RegExp(Object.keys(latin_convert).join('|') + '|' + accent_pat, 'gu');\n\t/**\n\t * Initialize the unicode_map from the give code point ranges\n\t *\n\t * @param {TCodePoints=} _code_points\n\t */\n\n\tconst initialize = _code_points => {\n\t  if (unicode_map !== undefined) return;\n\t  unicode_map = generateMap(_code_points || code_points);\n\t};\n\t/**\n\t * Helper method for normalize a string\n\t * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\n\t * @param {string} str\n\t * @param {string} form\n\t */\n\n\tconst normalize = (str, form = 'NFKD') => str.normalize(form);\n\t/**\n\t * Remove accents without reordering string\n\t * calling str.normalize('NFKD') on \\u{594}\\u{595}\\u{596} becomes \\u{596}\\u{594}\\u{595}\n\t * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703\n\t * @param {string} str\n\t * @return {string}\n\t */\n\n\tconst asciifold = str => {\n\t  return toArray(str).reduce(\n\t  /**\n\t   * @param {string} result\n\t   * @param {string} char\n\t   */\n\t  (result, char) => {\n\t    return result + _asciifold(char);\n\t  }, '');\n\t};\n\t/**\n\t * @param {string} str\n\t * @return {string}\n\t */\n\n\tconst _asciifold = str => {\n\t  str = normalize(str).toLowerCase().replace(convert_pat, (\n\t  /** @type {string} */\n\t  char) => {\n\t    return latin_convert[char] || '';\n\t  }); //return str;\n\n\t  return normalize(str, 'NFC');\n\t};\n\t/**\n\t * Generate a list of unicode variants from the list of code points\n\t * @param {TCodePoints} code_points\n\t * @yield {TCodePointObj}\n\t */\n\n\tfunction* generator(code_points) {\n\t  for (const [code_point_min, code_point_max] of code_points) {\n\t    for (let i = code_point_min; i <= code_point_max; i++) {\n\t      let composed = String.fromCharCode(i);\n\t      let folded = asciifold(composed);\n\n\t      if (folded == composed.toLowerCase()) {\n\t        continue;\n\t      } // skip when folded is a string longer than 3 characters long\n\t      // bc the resulting regex patterns will be long\n\t      // eg:\n\t      // folded صلى الله عليه وسلم length 18 code point 65018\n\t      // folded جل جلاله length 8 code point 65019\n\n\n\t      if (folded.length > max_char_length) {\n\t        continue;\n\t      }\n\n\t      if (folded.length == 0) {\n\t        continue;\n\t      }\n\n\t      yield {\n\t        folded: folded,\n\t        composed: composed,\n\t        code_point: i\n\t      };\n\t    }\n\t  }\n\t}\n\t/**\n\t * Generate a unicode map from the list of code points\n\t * @param {TCodePoints} code_points\n\t * @return {TUnicodeSets}\n\t */\n\n\tconst generateSets = code_points => {\n\t  /** @type {{[key:string]:Set<string>}} */\n\t  const unicode_sets = {};\n\t  /**\n\t   * @param {string} folded\n\t   * @param {string} to_add\n\t   */\n\n\t  const addMatching = (folded, to_add) => {\n\t    /** @type {Set<string>} */\n\t    const folded_set = unicode_sets[folded] || new Set();\n\t    const patt = new RegExp('^' + setToPattern(folded_set) + '$', 'iu');\n\n\t    if (to_add.match(patt)) {\n\t      return;\n\t    }\n\n\t    folded_set.add(escape_regex(to_add));\n\t    unicode_sets[folded] = folded_set;\n\t  };\n\n\t  for (let value of generator(code_points)) {\n\t    addMatching(value.folded, value.folded);\n\t    addMatching(value.folded, value.composed);\n\t  }\n\n\t  return unicode_sets;\n\t};\n\t/**\n\t * Generate a unicode map from the list of code points\n\t * ae => (?:(?:ae|Æ|Ǽ|Ǣ)|(?:A|Ⓐ|Ａ...)(?:E|ɛ|Ⓔ...))\n\t *\n\t * @param {TCodePoints} code_points\n\t * @return {TUnicodeMap}\n\t */\n\n\tconst generateMap = code_points => {\n\t  /** @type {TUnicodeSets} */\n\t  const unicode_sets = generateSets(code_points);\n\t  /** @type {TUnicodeMap} */\n\n\t  const unicode_map = {};\n\t  /** @type {string[]} */\n\n\t  let multi_char = [];\n\n\t  for (let folded in unicode_sets) {\n\t    let set = unicode_sets[folded];\n\n\t    if (set) {\n\t      unicode_map[folded] = setToPattern(set);\n\t    }\n\n\t    if (folded.length > 1) {\n\t      multi_char.push(escape_regex(folded));\n\t    }\n\t  }\n\n\t  multi_char.sort((a, b) => b.length - a.length);\n\t  const multi_char_patt = arrayToPattern(multi_char);\n\t  multi_char_reg = new RegExp('^' + multi_char_patt, 'u');\n\t  return unicode_map;\n\t};\n\t/**\n\t * Map each element of an array from it's folded value to all possible unicode matches\n\t * @param {string[]} strings\n\t * @param {number} min_replacement\n\t * @return {string}\n\t */\n\n\tconst mapSequence = (strings, min_replacement = 1) => {\n\t  let chars_replaced = 0;\n\t  strings = strings.map(str => {\n\t    if (unicode_map[str]) {\n\t      chars_replaced += str.length;\n\t    }\n\n\t    return unicode_map[str] || str;\n\t  });\n\n\t  if (chars_replaced >= min_replacement) {\n\t    return sequencePattern(strings);\n\t  }\n\n\t  return '';\n\t};\n\t/**\n\t * Convert a short string and split it into all possible patterns\n\t * Keep a pattern only if min_replacement is met\n\t *\n\t * 'abc'\n\t * \t\t=> [['abc'],['ab','c'],['a','bc'],['a','b','c']]\n\t *\t\t=> ['abc-pattern','ab-c-pattern'...]\n\t *\n\t *\n\t * @param {string} str\n\t * @param {number} min_replacement\n\t * @return {string}\n\t */\n\n\tconst substringsToPattern = (str, min_replacement = 1) => {\n\t  min_replacement = Math.max(min_replacement, str.length - 1);\n\t  return arrayToPattern(allSubstrings(str).map(sub_pat => {\n\t    return mapSequence(sub_pat, min_replacement);\n\t  }));\n\t};\n\t/**\n\t * Convert an array of sequences into a pattern\n\t * [{start:0,end:3,length:3,substr:'iii'}...] => (?:iii...)\n\t *\n\t * @param {Sequence[]} sequences\n\t * @param {boolean} all\n\t */\n\n\tconst sequencesToPattern = (sequences, all = true) => {\n\t  let min_replacement = sequences.length > 1 ? 1 : 0;\n\t  return arrayToPattern(sequences.map(sequence => {\n\t    let seq = [];\n\t    const len = all ? sequence.length() : sequence.length() - 1;\n\n\t    for (let j = 0; j < len; j++) {\n\t      seq.push(substringsToPattern(sequence.substrs[j] || '', min_replacement));\n\t    }\n\n\t    return sequencePattern(seq);\n\t  }));\n\t};\n\t/**\n\t * Return true if the sequence is already in the sequences\n\t * @param {Sequence} needle_seq\n\t * @param {Sequence[]} sequences\n\t */\n\n\n\tconst inSequences = (needle_seq, sequences) => {\n\t  for (const seq of sequences) {\n\t    if (seq.start != needle_seq.start || seq.end != needle_seq.end) {\n\t      continue;\n\t    }\n\n\t    if (seq.substrs.join('') !== needle_seq.substrs.join('')) {\n\t      continue;\n\t    }\n\n\t    let needle_parts = needle_seq.parts;\n\t    /**\n\t     * @param {TSequencePart} part\n\t     */\n\n\t    const filter = part => {\n\t      for (const needle_part of needle_parts) {\n\t        if (needle_part.start === part.start && needle_part.substr === part.substr) {\n\t          return false;\n\t        }\n\n\t        if (part.length == 1 || needle_part.length == 1) {\n\t          continue;\n\t        } // check for overlapping parts\n\t        // a = ['::=','==']\n\t        // b = ['::','===']\n\t        // a = ['r','sm']\n\t        // b = ['rs','m']\n\n\n\t        if (part.start < needle_part.start && part.end > needle_part.start) {\n\t          return true;\n\t        }\n\n\t        if (needle_part.start < part.start && needle_part.end > part.start) {\n\t          return true;\n\t        }\n\t      }\n\n\t      return false;\n\t    };\n\n\t    let filtered = seq.parts.filter(filter);\n\n\t    if (filtered.length > 0) {\n\t      continue;\n\t    }\n\n\t    return true;\n\t  }\n\n\t  return false;\n\t};\n\n\tclass Sequence {\n\t  constructor() {\n\t    /** @type {TSequencePart[]} */\n\t    this.parts = [];\n\t    /** @type {string[]} */\n\n\t    this.substrs = [];\n\t    this.start = 0;\n\t    this.end = 0;\n\t  }\n\t  /**\n\t   * @param {TSequencePart|undefined} part\n\t   */\n\n\n\t  add(part) {\n\t    if (part) {\n\t      this.parts.push(part);\n\t      this.substrs.push(part.substr);\n\t      this.start = Math.min(part.start, this.start);\n\t      this.end = Math.max(part.end, this.end);\n\t    }\n\t  }\n\n\t  last() {\n\t    return this.parts[this.parts.length - 1];\n\t  }\n\n\t  length() {\n\t    return this.parts.length;\n\t  }\n\t  /**\n\t   * @param {number} position\n\t   * @param {TSequencePart} last_piece\n\t   */\n\n\n\t  clone(position, last_piece) {\n\t    let clone = new Sequence();\n\t    let parts = JSON.parse(JSON.stringify(this.parts));\n\t    let last_part = parts.pop();\n\n\t    for (const part of parts) {\n\t      clone.add(part);\n\t    }\n\n\t    let last_substr = last_piece.substr.substring(0, position - last_part.start);\n\t    let clone_last_len = last_substr.length;\n\t    clone.add({\n\t      start: last_part.start,\n\t      end: last_part.start + clone_last_len,\n\t      length: clone_last_len,\n\t      substr: last_substr\n\t    });\n\t    return clone;\n\t  }\n\n\t}\n\t/**\n\t * Expand a regular expression pattern to include unicode variants\n\t * \teg /a/ becomes /aⓐａẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁąⱥɐɑAⒶＡÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢÅǺǍȀȂẠẬẶḀĄȺⱯ/\n\t *\n\t * Issue:\n\t *  ﺊﺋ [ 'ﺊ = \\\\u{fe8a}', 'ﺋ = \\\\u{fe8b}' ]\n\t *\tbecomes:\tئئ [ 'ي = \\\\u{64a}', 'ٔ = \\\\u{654}', 'ي = \\\\u{64a}', 'ٔ = \\\\u{654}' ]\n\t *\n\t *\tİĲ = IIJ = ⅡJ\n\t *\n\t * \t1/2/4\n\t *\n\t * @param {string} str\n\t * @return {string|undefined}\n\t */\n\n\n\tconst getPattern = str => {\n\t  initialize();\n\t  str = asciifold(str);\n\t  let pattern = '';\n\t  let sequences = [new Sequence()];\n\n\t  for (let i = 0; i < str.length; i++) {\n\t    let substr = str.substring(i);\n\t    let match = substr.match(multi_char_reg);\n\t    const char = str.substring(i, i + 1);\n\t    const match_str = match ? match[0] : null; // loop through sequences\n\t    // add either the char or multi_match\n\n\t    let overlapping = [];\n\t    let added_types = new Set();\n\n\t    for (const sequence of sequences) {\n\t      const last_piece = sequence.last();\n\n\t      if (!last_piece || last_piece.length == 1 || last_piece.end <= i) {\n\t        // if we have a multi match\n\t        if (match_str) {\n\t          const len = match_str.length;\n\t          sequence.add({\n\t            start: i,\n\t            end: i + len,\n\t            length: len,\n\t            substr: match_str\n\t          });\n\t          added_types.add('1');\n\t        } else {\n\t          sequence.add({\n\t            start: i,\n\t            end: i + 1,\n\t            length: 1,\n\t            substr: char\n\t          });\n\t          added_types.add('2');\n\t        }\n\t      } else if (match_str) {\n\t        let clone = sequence.clone(i, last_piece);\n\t        const len = match_str.length;\n\t        clone.add({\n\t          start: i,\n\t          end: i + len,\n\t          length: len,\n\t          substr: match_str\n\t        });\n\t        overlapping.push(clone);\n\t      } else {\n\t        // don't add char\n\t        // adding would create invalid patterns: 234 => [2,34,4]\n\t        added_types.add('3');\n\t      }\n\t    } // if we have overlapping\n\n\n\t    if (overlapping.length > 0) {\n\t      // ['ii','iii'] before ['i','i','iii']\n\t      overlapping = overlapping.sort((a, b) => {\n\t        return a.length() - b.length();\n\t      });\n\n\t      for (let clone of overlapping) {\n\t        // don't add if we already have an equivalent sequence\n\t        if (inSequences(clone, sequences)) {\n\t          continue;\n\t        }\n\n\t        sequences.push(clone);\n\t      }\n\n\t      continue;\n\t    } // if we haven't done anything unique\n\t    // clean up the patterns\n\t    // helps keep patterns smaller\n\t    // if str = 'r₨㎧aarss', pattern will be 446 instead of 655\n\n\n\t    if (i > 0 && added_types.size == 1 && !added_types.has('3')) {\n\t      pattern += sequencesToPattern(sequences, false);\n\t      let new_seq = new Sequence();\n\t      const old_seq = sequences[0];\n\n\t      if (old_seq) {\n\t        new_seq.add(old_seq.last());\n\t      }\n\n\t      sequences = [new_seq];\n\t    }\n\t  }\n\n\t  pattern += sequencesToPattern(sequences, true);\n\t  return pattern;\n\t};\n\n\t/*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */\n\n\t/**\n\t * A property getter resolving dot-notation\n\t * @param  {Object}  obj     The root object to fetch property on\n\t * @param  {String}  name    The optionally dotted property name to fetch\n\t * @return {Object}          The resolved property value\n\t */\n\tconst getAttr = (obj, name) => {\n\t  if (!obj) return;\n\t  return obj[name];\n\t};\n\t/**\n\t * A property getter resolving dot-notation\n\t * @param  {Object}  obj     The root object to fetch property on\n\t * @param  {String}  name    The optionally dotted property name to fetch\n\t * @return {Object}          The resolved property value\n\t */\n\n\tconst getAttrNesting = (obj, name) => {\n\t  if (!obj) return;\n\t  var part,\n\t      names = name.split(\".\");\n\n\t  while ((part = names.shift()) && (obj = obj[part]));\n\n\t  return obj;\n\t};\n\t/**\n\t * Calculates how close of a match the\n\t * given value is against a search token.\n\t *\n\t */\n\n\tconst scoreValue = (value, token, weight) => {\n\t  var score, pos;\n\t  if (!value) return 0;\n\t  value = value + '';\n\t  if (token.regex == null) return 0;\n\t  pos = value.search(token.regex);\n\t  if (pos === -1) return 0;\n\t  score = token.string.length / value.length;\n\t  if (pos === 0) score += 0.5;\n\t  return score * weight;\n\t};\n\t/**\n\t * Cast object property to an array if it exists and has a value\n\t *\n\t */\n\n\tconst propToArray = (obj, key) => {\n\t  var value = obj[key];\n\t  if (typeof value == 'function') return value;\n\n\t  if (value && !Array.isArray(value)) {\n\t    obj[key] = [value];\n\t  }\n\t};\n\t/**\n\t * Iterates over arrays and hashes.\n\t *\n\t * ```\n\t * iterate(this.items, function(item, id) {\n\t *    // invoked for each item\n\t * });\n\t * ```\n\t *\n\t */\n\n\tconst iterate$1 = (object, callback) => {\n\t  if (Array.isArray(object)) {\n\t    object.forEach(callback);\n\t  } else {\n\t    for (var key in object) {\n\t      if (object.hasOwnProperty(key)) {\n\t        callback(object[key], key);\n\t      }\n\t    }\n\t  }\n\t};\n\tconst cmp = (a, b) => {\n\t  if (typeof a === 'number' && typeof b === 'number') {\n\t    return a > b ? 1 : a < b ? -1 : 0;\n\t  }\n\n\t  a = asciifold(a + '').toLowerCase();\n\t  b = asciifold(b + '').toLowerCase();\n\t  if (a > b) return 1;\n\t  if (b > a) return -1;\n\t  return 0;\n\t};\n\n\t/*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */\n\n\t/**\n\t * sifter.js\n\t * Copyright (c) 2013–2020 Brian Reavis & contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t * @author Brian Reavis <brian@thirdroute.com>\n\t */\n\n\tclass Sifter {\n\t  // []|{};\n\n\t  /**\n\t   * Textually searches arrays and hashes of objects\n\t   * by property (or multiple properties). Designed\n\t   * specifically for autocomplete.\n\t   *\n\t   */\n\t  constructor(items, settings) {\n\t    this.items = void 0;\n\t    this.settings = void 0;\n\t    this.items = items;\n\t    this.settings = settings || {\n\t      diacritics: true\n\t    };\n\t  }\n\n\t  /**\n\t   * Splits a search string into an array of individual\n\t   * regexps to be used to match results.\n\t   *\n\t   */\n\t  tokenize(query, respect_word_boundaries, weights) {\n\t    if (!query || !query.length) return [];\n\t    const tokens = [];\n\t    const words = query.split(/\\s+/);\n\t    var field_regex;\n\n\t    if (weights) {\n\t      field_regex = new RegExp('^(' + Object.keys(weights).map(escape_regex).join('|') + ')\\:(.*)$');\n\t    }\n\n\t    words.forEach(word => {\n\t      let field_match;\n\t      let field = null;\n\t      let regex = null; // look for \"field:query\" tokens\n\n\t      if (field_regex && (field_match = word.match(field_regex))) {\n\t        field = field_match[1];\n\t        word = field_match[2];\n\t      }\n\n\t      if (word.length > 0) {\n\t        if (this.settings.diacritics) {\n\t          regex = getPattern(word) || null;\n\t        } else {\n\t          regex = escape_regex(word);\n\t        }\n\n\t        if (regex && respect_word_boundaries) regex = \"\\\\b\" + regex;\n\t      }\n\n\t      tokens.push({\n\t        string: word,\n\t        regex: regex ? new RegExp(regex, 'iu') : null,\n\t        field: field\n\t      });\n\t    });\n\t    return tokens;\n\t  }\n\n\t  /**\n\t   * Returns a function to be used to score individual results.\n\t   *\n\t   * Good matches will have a higher score than poor matches.\n\t   * If an item is not a match, 0 will be returned by the function.\n\t   *\n\t   * @returns {T.ScoreFn}\n\t   */\n\t  getScoreFunction(query, options) {\n\t    var search = this.prepareSearch(query, options);\n\t    return this._getScoreFunction(search);\n\t  }\n\t  /**\n\t   * @returns {T.ScoreFn}\n\t   *\n\t   */\n\n\n\t  _getScoreFunction(search) {\n\t    const tokens = search.tokens,\n\t          token_count = tokens.length;\n\n\t    if (!token_count) {\n\t      return function () {\n\t        return 0;\n\t      };\n\t    }\n\n\t    const fields = search.options.fields,\n\t          weights = search.weights,\n\t          field_count = fields.length,\n\t          getAttrFn = search.getAttrFn;\n\n\t    if (!field_count) {\n\t      return function () {\n\t        return 1;\n\t      };\n\t    }\n\t    /**\n\t     * Calculates the score of an object\n\t     * against the search query.\n\t     *\n\t     */\n\n\n\t    const scoreObject = function () {\n\t      if (field_count === 1) {\n\t        return function (token, data) {\n\t          const field = fields[0].field;\n\t          return scoreValue(getAttrFn(data, field), token, weights[field] || 1);\n\t        };\n\t      }\n\n\t      return function (token, data) {\n\t        var sum = 0; // is the token specific to a field?\n\n\t        if (token.field) {\n\t          const value = getAttrFn(data, token.field);\n\n\t          if (!token.regex && value) {\n\t            sum += 1 / field_count;\n\t          } else {\n\t            sum += scoreValue(value, token, 1);\n\t          }\n\t        } else {\n\t          iterate$1(weights, (weight, field) => {\n\t            sum += scoreValue(getAttrFn(data, field), token, weight);\n\t          });\n\t        }\n\n\t        return sum / field_count;\n\t      };\n\t    }();\n\n\t    if (token_count === 1) {\n\t      return function (data) {\n\t        return scoreObject(tokens[0], data);\n\t      };\n\t    }\n\n\t    if (search.options.conjunction === 'and') {\n\t      return function (data) {\n\t        var score,\n\t            sum = 0;\n\n\t        for (let token of tokens) {\n\t          score = scoreObject(token, data);\n\t          if (score <= 0) return 0;\n\t          sum += score;\n\t        }\n\n\t        return sum / token_count;\n\t      };\n\t    } else {\n\t      return function (data) {\n\t        var sum = 0;\n\t        iterate$1(tokens, token => {\n\t          sum += scoreObject(token, data);\n\t        });\n\t        return sum / token_count;\n\t      };\n\t    }\n\t  }\n\n\t  /**\n\t   * Returns a function that can be used to compare two\n\t   * results, for sorting purposes. If no sorting should\n\t   * be performed, `null` will be returned.\n\t   *\n\t   * @return function(a,b)\n\t   */\n\t  getSortFunction(query, options) {\n\t    var search = this.prepareSearch(query, options);\n\t    return this._getSortFunction(search);\n\t  }\n\n\t  _getSortFunction(search) {\n\t    var implicit_score,\n\t        sort_flds = [];\n\t    const self = this,\n\t          options = search.options,\n\t          sort = !search.query && options.sort_empty ? options.sort_empty : options.sort;\n\n\t    if (typeof sort == 'function') {\n\t      return sort.bind(this);\n\t    }\n\t    /**\n\t     * Fetches the specified sort field value\n\t     * from a search result item.\n\t     *\n\t     */\n\n\n\t    const get_field = function get_field(name, result) {\n\t      if (name === '$score') return result.score;\n\t      return search.getAttrFn(self.items[result.id], name);\n\t    }; // parse options\n\n\n\t    if (sort) {\n\t      for (let s of sort) {\n\t        if (search.query || s.field !== '$score') {\n\t          sort_flds.push(s);\n\t        }\n\t      }\n\t    } // the \"$score\" field is implied to be the primary\n\t    // sort field, unless it's manually specified\n\n\n\t    if (search.query) {\n\t      implicit_score = true;\n\n\t      for (let fld of sort_flds) {\n\t        if (fld.field === '$score') {\n\t          implicit_score = false;\n\t          break;\n\t        }\n\t      }\n\n\t      if (implicit_score) {\n\t        sort_flds.unshift({\n\t          field: '$score',\n\t          direction: 'desc'\n\t        });\n\t      } // without a search.query, all items will have the same score\n\n\t    } else {\n\t      sort_flds = sort_flds.filter(fld => fld.field !== '$score');\n\t    } // build function\n\n\n\t    const sort_flds_count = sort_flds.length;\n\n\t    if (!sort_flds_count) {\n\t      return null;\n\t    }\n\n\t    return function (a, b) {\n\t      var result, field;\n\n\t      for (let sort_fld of sort_flds) {\n\t        field = sort_fld.field;\n\t        let multiplier = sort_fld.direction === 'desc' ? -1 : 1;\n\t        result = multiplier * cmp(get_field(field, a), get_field(field, b));\n\t        if (result) return result;\n\t      }\n\n\t      return 0;\n\t    };\n\t  }\n\n\t  /**\n\t   * Parses a search query and returns an object\n\t   * with tokens and fields ready to be populated\n\t   * with results.\n\t   *\n\t   */\n\t  prepareSearch(query, optsUser) {\n\t    const weights = {};\n\t    var options = Object.assign({}, optsUser);\n\t    propToArray(options, 'sort');\n\t    propToArray(options, 'sort_empty'); // convert fields to new format\n\n\t    if (options.fields) {\n\t      propToArray(options, 'fields');\n\t      const fields = [];\n\t      options.fields.forEach(field => {\n\t        if (typeof field == 'string') {\n\t          field = {\n\t            field: field,\n\t            weight: 1\n\t          };\n\t        }\n\n\t        fields.push(field);\n\t        weights[field.field] = 'weight' in field ? field.weight : 1;\n\t      });\n\t      options.fields = fields;\n\t    }\n\n\t    return {\n\t      options: options,\n\t      query: query.toLowerCase().trim(),\n\t      tokens: this.tokenize(query, options.respect_word_boundaries, weights),\n\t      total: 0,\n\t      items: [],\n\t      weights: weights,\n\t      getAttrFn: options.nesting ? getAttrNesting : getAttr\n\t    };\n\t  }\n\n\t  /**\n\t   * Searches through all items and returns a sorted array of matches.\n\t   *\n\t   */\n\t  search(query, options) {\n\t    var self = this,\n\t        score,\n\t        search;\n\t    search = this.prepareSearch(query, options);\n\t    options = search.options;\n\t    query = search.query; // generate result scoring function\n\n\t    const fn_score = options.score || self._getScoreFunction(search); // perform search and sort\n\n\n\t    if (query.length) {\n\t      iterate$1(self.items, (item, id) => {\n\t        score = fn_score(item);\n\n\t        if (options.filter === false || score > 0) {\n\t          search.items.push({\n\t            'score': score,\n\t            'id': id\n\t          });\n\t        }\n\t      });\n\t    } else {\n\t      iterate$1(self.items, (_, id) => {\n\t        search.items.push({\n\t          'score': 1,\n\t          'id': id\n\t        });\n\t      });\n\t    }\n\n\t    const fn_sort = self._getSortFunction(search);\n\n\t    if (fn_sort) search.items.sort(fn_sort); // apply limits\n\n\t    search.total = search.items.length;\n\n\t    if (typeof options.limit === 'number') {\n\t      search.items = search.items.slice(0, options.limit);\n\t    }\n\n\t    return search;\n\t  }\n\n\t}\n\n\t/**\n\t * Iterates over arrays and hashes.\n\t *\n\t * ```\n\t * iterate(this.items, function(item, id) {\n\t *    // invoked for each item\n\t * });\n\t * ```\n\t *\n\t */\n\n\tconst iterate = (object, callback) => {\n\t  if (Array.isArray(object)) {\n\t    object.forEach(callback);\n\t  } else {\n\t    for (var key in object) {\n\t      if (object.hasOwnProperty(key)) {\n\t        callback(object[key], key);\n\t      }\n\t    }\n\t  }\n\t};\n\n\t/**\n\t * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n\t * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n\t *\n\t * param query should be {}\n\t */\n\n\tconst getDom = query => {\n\t  if (query.jquery) {\n\t    return query[0];\n\t  }\n\n\t  if (query instanceof HTMLElement) {\n\t    return query;\n\t  }\n\n\t  if (isHtmlString(query)) {\n\t    var tpl = document.createElement('template');\n\t    tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n\n\t    return tpl.content.firstChild;\n\t  }\n\n\t  return document.querySelector(query);\n\t};\n\tconst isHtmlString = arg => {\n\t  if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n\t    return true;\n\t  }\n\n\t  return false;\n\t};\n\tconst escapeQuery = query => {\n\t  return query.replace(/['\"\\\\]/g, '\\\\$&');\n\t};\n\t/**\n\t * Dispatch an event\n\t *\n\t */\n\n\tconst triggerEvent = (dom_el, event_name) => {\n\t  var event = document.createEvent('HTMLEvents');\n\t  event.initEvent(event_name, true, false);\n\t  dom_el.dispatchEvent(event);\n\t};\n\t/**\n\t * Apply CSS rules to a dom element\n\t *\n\t */\n\n\tconst applyCSS = (dom_el, css) => {\n\t  Object.assign(dom_el.style, css);\n\t};\n\t/**\n\t * Add css classes\n\t *\n\t */\n\n\tconst addClasses = (elmts, ...classes) => {\n\t  var norm_classes = classesArray(classes);\n\t  elmts = castAsArray(elmts);\n\t  elmts.map(el => {\n\t    norm_classes.map(cls => {\n\t      el.classList.add(cls);\n\t    });\n\t  });\n\t};\n\t/**\n\t * Remove css classes\n\t *\n\t */\n\n\tconst removeClasses = (elmts, ...classes) => {\n\t  var norm_classes = classesArray(classes);\n\t  elmts = castAsArray(elmts);\n\t  elmts.map(el => {\n\t    norm_classes.map(cls => {\n\t      el.classList.remove(cls);\n\t    });\n\t  });\n\t};\n\t/**\n\t * Return arguments\n\t *\n\t */\n\n\tconst classesArray = args => {\n\t  var classes = [];\n\t  iterate(args, _classes => {\n\t    if (typeof _classes === 'string') {\n\t      _classes = _classes.trim().split(/[\\11\\12\\14\\15\\40]/);\n\t    }\n\n\t    if (Array.isArray(_classes)) {\n\t      classes = classes.concat(_classes);\n\t    }\n\t  });\n\t  return classes.filter(Boolean);\n\t};\n\t/**\n\t * Create an array from arg if it's not already an array\n\t *\n\t */\n\n\tconst castAsArray = arg => {\n\t  if (!Array.isArray(arg)) {\n\t    arg = [arg];\n\t  }\n\n\t  return arg;\n\t};\n\t/**\n\t * Get the closest node to the evt.target matching the selector\n\t * Stops at wrapper\n\t *\n\t */\n\n\tconst parentMatch = (target, selector, wrapper) => {\n\t  if (wrapper && !wrapper.contains(target)) {\n\t    return;\n\t  }\n\n\t  while (target && target.matches) {\n\t    if (target.matches(selector)) {\n\t      return target;\n\t    }\n\n\t    target = target.parentNode;\n\t  }\n\t};\n\t/**\n\t * Get the first or last item from an array\n\t *\n\t * > 0 - right (last)\n\t * <= 0 - left (first)\n\t *\n\t */\n\n\tconst getTail = (list, direction = 0) => {\n\t  if (direction > 0) {\n\t    return list[list.length - 1];\n\t  }\n\n\t  return list[0];\n\t};\n\t/**\n\t * Return true if an object is empty\n\t *\n\t */\n\n\tconst isEmptyObject = obj => {\n\t  return Object.keys(obj).length === 0;\n\t};\n\t/**\n\t * Get the index of an element amongst sibling nodes of the same type\n\t *\n\t */\n\n\tconst nodeIndex = (el, amongst) => {\n\t  if (!el) return -1;\n\t  amongst = amongst || el.nodeName;\n\t  var i = 0;\n\n\t  while (el = el.previousElementSibling) {\n\t    if (el.matches(amongst)) {\n\t      i++;\n\t    }\n\t  }\n\n\t  return i;\n\t};\n\t/**\n\t * Set attributes of an element\n\t *\n\t */\n\n\tconst setAttr = (el, attrs) => {\n\t  iterate(attrs, (val, attr) => {\n\t    if (val == null) {\n\t      el.removeAttribute(attr);\n\t    } else {\n\t      el.setAttribute(attr, '' + val);\n\t    }\n\t  });\n\t};\n\t/**\n\t * Replace a node\n\t */\n\n\tconst replaceNode = (existing, replacement) => {\n\t  if (existing.parentNode) existing.parentNode.replaceChild(replacement, existing);\n\t};\n\n\t/**\n\t * highlight v3 | MIT license | Johann Burkard <jb@eaio.com>\n\t * Highlights arbitrary terms in a node.\n\t *\n\t * - Modified by Marshal <beatgates@gmail.com> 2011-6-24 (added regex)\n\t * - Modified by Brian Reavis <brian@thirdroute.com> 2012-8-27 (cleanup)\n\t */\n\tconst highlight = (element, regex) => {\n\t  if (regex === null) return; // convet string to regex\n\n\t  if (typeof regex === 'string') {\n\t    if (!regex.length) return;\n\t    regex = new RegExp(regex, 'i');\n\t  } // Wrap matching part of text node with highlighting <span>, e.g.\n\t  // Soccer  ->  <span class=\"highlight\">Soc</span>cer  for regex = /soc/i\n\n\n\t  const highlightText = node => {\n\t    var match = node.data.match(regex);\n\n\t    if (match && node.data.length > 0) {\n\t      var spannode = document.createElement('span');\n\t      spannode.className = 'highlight';\n\t      var middlebit = node.splitText(match.index);\n\t      middlebit.splitText(match[0].length);\n\t      var middleclone = middlebit.cloneNode(true);\n\t      spannode.appendChild(middleclone);\n\t      replaceNode(middlebit, spannode);\n\t      return 1;\n\t    }\n\n\t    return 0;\n\t  }; // Recurse element node, looking for child text nodes to highlight, unless element\n\t  // is childless, <script>, <style>, or already highlighted: <span class=\"hightlight\">\n\n\n\t  const highlightChildren = node => {\n\t    if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && (node.className !== 'highlight' || node.tagName !== 'SPAN')) {\n\t      Array.from(node.childNodes).forEach(element => {\n\t        highlightRecursive(element);\n\t      });\n\t    }\n\t  };\n\n\t  const highlightRecursive = node => {\n\t    if (node.nodeType === 3) {\n\t      return highlightText(node);\n\t    }\n\n\t    highlightChildren(node);\n\t    return 0;\n\t  };\n\n\t  highlightRecursive(element);\n\t};\n\t/**\n\t * removeHighlight fn copied from highlight v5 and\n\t * edited to remove with(), pass js strict mode, and use without jquery\n\t */\n\n\tconst removeHighlight = el => {\n\t  var elements = el.querySelectorAll(\"span.highlight\");\n\t  Array.prototype.forEach.call(elements, function (el) {\n\t    var parent = el.parentNode;\n\t    parent.replaceChild(el.firstChild, el);\n\t    parent.normalize();\n\t  });\n\t};\n\n\tconst KEY_A = 65;\n\tconst KEY_RETURN = 13;\n\tconst KEY_ESC = 27;\n\tconst KEY_LEFT = 37;\n\tconst KEY_UP = 38;\n\tconst KEY_RIGHT = 39;\n\tconst KEY_DOWN = 40;\n\tconst KEY_BACKSPACE = 8;\n\tconst KEY_DELETE = 46;\n\tconst KEY_TAB = 9;\n\tconst IS_MAC = typeof navigator === 'undefined' ? false : /Mac/.test(navigator.userAgent);\n\tconst KEY_SHORTCUT = IS_MAC ? 'metaKey' : 'ctrlKey'; // ctrl key or apple key for ma\n\n\tvar defaults = {\n\t  options: [],\n\t  optgroups: [],\n\t  plugins: [],\n\t  delimiter: ',',\n\t  splitOn: null,\n\t  // regexp or string for splitting up values from a paste command\n\t  persist: true,\n\t  diacritics: true,\n\t  create: null,\n\t  createOnBlur: false,\n\t  createFilter: null,\n\t  highlight: true,\n\t  openOnFocus: true,\n\t  shouldOpen: null,\n\t  maxOptions: 50,\n\t  maxItems: null,\n\t  hideSelected: null,\n\t  duplicates: false,\n\t  addPrecedence: false,\n\t  selectOnTab: false,\n\t  preload: null,\n\t  allowEmptyOption: false,\n\t  //closeAfterSelect: false,\n\t  loadThrottle: 300,\n\t  loadingClass: 'loading',\n\t  dataAttr: null,\n\t  //'data-data',\n\t  optgroupField: 'optgroup',\n\t  valueField: 'value',\n\t  labelField: 'text',\n\t  disabledField: 'disabled',\n\t  optgroupLabelField: 'label',\n\t  optgroupValueField: 'value',\n\t  lockOptgroupOrder: false,\n\t  sortField: '$order',\n\t  searchField: ['text'],\n\t  searchConjunction: 'and',\n\t  mode: null,\n\t  wrapperClass: 'ts-wrapper',\n\t  controlClass: 'ts-control',\n\t  dropdownClass: 'ts-dropdown',\n\t  dropdownContentClass: 'ts-dropdown-content',\n\t  itemClass: 'item',\n\t  optionClass: 'option',\n\t  dropdownParent: null,\n\t  controlInput: '<input type=\"text\" autocomplete=\"off\" size=\"1\" />',\n\t  copyClassesToDropdown: false,\n\t  placeholder: null,\n\t  hidePlaceholder: null,\n\t  shouldLoad: function (query) {\n\t    return query.length > 0;\n\t  },\n\n\t  /*\n\t  load                 : null, // function(query, callback) { ... }\n\t  score                : null, // function(search) { ... }\n\t  onInitialize         : null, // function() { ... }\n\t  onChange             : null, // function(value) { ... }\n\t  onItemAdd            : null, // function(value, $item) { ... }\n\t  onItemRemove         : null, // function(value) { ... }\n\t  onClear              : null, // function() { ... }\n\t  onOptionAdd          : null, // function(value, data) { ... }\n\t  onOptionRemove       : null, // function(value) { ... }\n\t  onOptionClear        : null, // function() { ... }\n\t  onOptionGroupAdd     : null, // function(id, data) { ... }\n\t  onOptionGroupRemove  : null, // function(id) { ... }\n\t  onOptionGroupClear   : null, // function() { ... }\n\t  onDropdownOpen       : null, // function(dropdown) { ... }\n\t  onDropdownClose      : null, // function(dropdown) { ... }\n\t  onType               : null, // function(str) { ... }\n\t  onDelete             : null, // function(values) { ... }\n\t  */\n\t  render: {\n\t    /*\n\t    item: null,\n\t    optgroup: null,\n\t    optgroup_header: null,\n\t    option: null,\n\t    option_create: null\n\t    */\n\t  }\n\t};\n\n\t/**\n\t * Converts a scalar to its best string representation\n\t * for hash keys and HTML attribute values.\n\t *\n\t * Transformations:\n\t *   'str'     -> 'str'\n\t *   null      -> ''\n\t *   undefined -> ''\n\t *   true      -> '1'\n\t *   false     -> '0'\n\t *   0         -> '0'\n\t *   1         -> '1'\n\t *\n\t */\n\tconst hash_key = value => {\n\t  if (typeof value === 'undefined' || value === null) return null;\n\t  return get_hash(value);\n\t};\n\tconst get_hash = value => {\n\t  if (typeof value === 'boolean') return value ? '1' : '0';\n\t  return value + '';\n\t};\n\t/**\n\t * Escapes a string for use within HTML.\n\t *\n\t */\n\n\tconst escape_html = str => {\n\t  return (str + '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\t};\n\t/**\n\t * Debounce the user provided load function\n\t *\n\t */\n\n\tconst loadDebounce = (fn, delay) => {\n\t  var timeout;\n\t  return function (value, callback) {\n\t    var self = this;\n\n\t    if (timeout) {\n\t      self.loading = Math.max(self.loading - 1, 0);\n\t      clearTimeout(timeout);\n\t    }\n\n\t    timeout = setTimeout(function () {\n\t      timeout = null;\n\t      self.loadedSearches[value] = true;\n\t      fn.call(self, value, callback);\n\t    }, delay);\n\t  };\n\t};\n\t/**\n\t * Debounce all fired events types listed in `types`\n\t * while executing the provided `fn`.\n\t *\n\t */\n\n\tconst debounce_events = (self, types, fn) => {\n\t  var type;\n\t  var trigger = self.trigger;\n\t  var event_args = {}; // override trigger method\n\n\t  self.trigger = function () {\n\t    var type = arguments[0];\n\n\t    if (types.indexOf(type) !== -1) {\n\t      event_args[type] = arguments;\n\t    } else {\n\t      return trigger.apply(self, arguments);\n\t    }\n\t  }; // invoke provided function\n\n\n\t  fn.apply(self, []);\n\t  self.trigger = trigger; // trigger queued events\n\n\t  for (type of types) {\n\t    if (type in event_args) {\n\t      trigger.apply(self, event_args[type]);\n\t    }\n\t  }\n\t};\n\t/**\n\t * Determines the current selection within a text input control.\n\t * Returns an object containing:\n\t *   - start\n\t *   - length\n\t *\n\t */\n\n\tconst getSelection = input => {\n\t  return {\n\t    start: input.selectionStart || 0,\n\t    length: (input.selectionEnd || 0) - (input.selectionStart || 0)\n\t  };\n\t};\n\t/**\n\t * Prevent default\n\t *\n\t */\n\n\tconst preventDefault = (evt, stop = false) => {\n\t  if (evt) {\n\t    evt.preventDefault();\n\n\t    if (stop) {\n\t      evt.stopPropagation();\n\t    }\n\t  }\n\t};\n\t/**\n\t * Add event helper\n\t *\n\t */\n\n\tconst addEvent = (target, type, callback, options) => {\n\t  target.addEventListener(type, callback, options);\n\t};\n\t/**\n\t * Return true if the requested key is down\n\t * Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )\n\t * The current evt may not always set ( eg calling advanceSelection() )\n\t *\n\t */\n\n\tconst isKeyDown = (key_name, evt) => {\n\t  if (!evt) {\n\t    return false;\n\t  }\n\n\t  if (!evt[key_name]) {\n\t    return false;\n\t  }\n\n\t  var count = (evt.altKey ? 1 : 0) + (evt.ctrlKey ? 1 : 0) + (evt.shiftKey ? 1 : 0) + (evt.metaKey ? 1 : 0);\n\n\t  if (count === 1) {\n\t    return true;\n\t  }\n\n\t  return false;\n\t};\n\t/**\n\t * Get the id of an element\n\t * If the id attribute is not set, set the attribute with the given id\n\t *\n\t */\n\n\tconst getId = (el, id) => {\n\t  const existing_id = el.getAttribute('id');\n\n\t  if (existing_id) {\n\t    return existing_id;\n\t  }\n\n\t  el.setAttribute('id', id);\n\t  return id;\n\t};\n\t/**\n\t * Returns a string with backslashes added before characters that need to be escaped.\n\t */\n\n\tconst addSlashes = str => {\n\t  return str.replace(/[\\\\\"']/g, '\\\\$&');\n\t};\n\t/**\n\t *\n\t */\n\n\tconst append = (parent, node) => {\n\t  if (node) parent.append(node);\n\t};\n\n\tfunction getSettings(input, settings_user) {\n\t  var settings = Object.assign({}, defaults, settings_user);\n\t  var attr_data = settings.dataAttr;\n\t  var field_label = settings.labelField;\n\t  var field_value = settings.valueField;\n\t  var field_disabled = settings.disabledField;\n\t  var field_optgroup = settings.optgroupField;\n\t  var field_optgroup_label = settings.optgroupLabelField;\n\t  var field_optgroup_value = settings.optgroupValueField;\n\t  var tag_name = input.tagName.toLowerCase();\n\t  var placeholder = input.getAttribute('placeholder') || input.getAttribute('data-placeholder');\n\n\t  if (!placeholder && !settings.allowEmptyOption) {\n\t    let option = input.querySelector('option[value=\"\"]');\n\n\t    if (option) {\n\t      placeholder = option.textContent;\n\t    }\n\t  }\n\n\t  var settings_element = {\n\t    placeholder: placeholder,\n\t    options: [],\n\t    optgroups: [],\n\t    items: [],\n\t    maxItems: null\n\t  };\n\t  /**\n\t   * Initialize from a <select> element.\n\t   *\n\t   */\n\n\t  var init_select = () => {\n\t    var tagName;\n\t    var options = settings_element.options;\n\t    var optionsMap = {};\n\t    var group_count = 1;\n\n\t    var readData = el => {\n\t      var data = Object.assign({}, el.dataset); // get plain object from DOMStringMap\n\n\t      var json = attr_data && data[attr_data];\n\n\t      if (typeof json === 'string' && json.length) {\n\t        data = Object.assign(data, JSON.parse(json));\n\t      }\n\n\t      return data;\n\t    };\n\n\t    var addOption = (option, group) => {\n\t      var value = hash_key(option.value);\n\t      if (value == null) return;\n\t      if (!value && !settings.allowEmptyOption) return; // if the option already exists, it's probably been\n\t      // duplicated in another optgroup. in this case, push\n\t      // the current group to the \"optgroup\" property on the\n\t      // existing option so that it's rendered in both places.\n\n\t      if (optionsMap.hasOwnProperty(value)) {\n\t        if (group) {\n\t          var arr = optionsMap[value][field_optgroup];\n\n\t          if (!arr) {\n\t            optionsMap[value][field_optgroup] = group;\n\t          } else if (!Array.isArray(arr)) {\n\t            optionsMap[value][field_optgroup] = [arr, group];\n\t          } else {\n\t            arr.push(group);\n\t          }\n\t        }\n\t      } else {\n\t        var option_data = readData(option);\n\t        option_data[field_label] = option_data[field_label] || option.textContent;\n\t        option_data[field_value] = option_data[field_value] || value;\n\t        option_data[field_disabled] = option_data[field_disabled] || option.disabled;\n\t        option_data[field_optgroup] = option_data[field_optgroup] || group;\n\t        option_data.$option = option;\n\t        optionsMap[value] = option_data;\n\t        options.push(option_data);\n\t      }\n\n\t      if (option.selected) {\n\t        settings_element.items.push(value);\n\t      }\n\t    };\n\n\t    var addGroup = optgroup => {\n\t      var id, optgroup_data;\n\t      optgroup_data = readData(optgroup);\n\t      optgroup_data[field_optgroup_label] = optgroup_data[field_optgroup_label] || optgroup.getAttribute('label') || '';\n\t      optgroup_data[field_optgroup_value] = optgroup_data[field_optgroup_value] || group_count++;\n\t      optgroup_data[field_disabled] = optgroup_data[field_disabled] || optgroup.disabled;\n\t      settings_element.optgroups.push(optgroup_data);\n\t      id = optgroup_data[field_optgroup_value];\n\t      iterate(optgroup.children, option => {\n\t        addOption(option, id);\n\t      });\n\t    };\n\n\t    settings_element.maxItems = input.hasAttribute('multiple') ? null : 1;\n\t    iterate(input.children, child => {\n\t      tagName = child.tagName.toLowerCase();\n\n\t      if (tagName === 'optgroup') {\n\t        addGroup(child);\n\t      } else if (tagName === 'option') {\n\t        addOption(child);\n\t      }\n\t    });\n\t  };\n\t  /**\n\t   * Initialize from a <input type=\"text\"> element.\n\t   *\n\t   */\n\n\n\t  var init_textbox = () => {\n\t    const data_raw = input.getAttribute(attr_data);\n\n\t    if (!data_raw) {\n\t      var value = input.value.trim() || '';\n\t      if (!settings.allowEmptyOption && !value.length) return;\n\t      const values = value.split(settings.delimiter);\n\t      iterate(values, value => {\n\t        const option = {};\n\t        option[field_label] = value;\n\t        option[field_value] = value;\n\t        settings_element.options.push(option);\n\t      });\n\t      settings_element.items = values;\n\t    } else {\n\t      settings_element.options = JSON.parse(data_raw);\n\t      iterate(settings_element.options, opt => {\n\t        settings_element.items.push(opt[field_value]);\n\t      });\n\t    }\n\t  };\n\n\t  if (tag_name === 'select') {\n\t    init_select();\n\t  } else {\n\t    init_textbox();\n\t  }\n\n\t  return Object.assign({}, defaults, settings_element, settings_user);\n\t}\n\n\tvar instance_i = 0;\n\tclass TomSelect extends MicroPlugin(MicroEvent) {\n\t  // @deprecated 1.8\n\t  constructor(input_arg, user_settings) {\n\t    super();\n\t    this.control_input = void 0;\n\t    this.wrapper = void 0;\n\t    this.dropdown = void 0;\n\t    this.control = void 0;\n\t    this.dropdown_content = void 0;\n\t    this.focus_node = void 0;\n\t    this.order = 0;\n\t    this.settings = void 0;\n\t    this.input = void 0;\n\t    this.tabIndex = void 0;\n\t    this.is_select_tag = void 0;\n\t    this.rtl = void 0;\n\t    this.inputId = void 0;\n\t    this._destroy = void 0;\n\t    this.sifter = void 0;\n\t    this.isOpen = false;\n\t    this.isDisabled = false;\n\t    this.isRequired = void 0;\n\t    this.isInvalid = false;\n\t    this.isValid = true;\n\t    this.isLocked = false;\n\t    this.isFocused = false;\n\t    this.isInputHidden = false;\n\t    this.isSetup = false;\n\t    this.ignoreFocus = false;\n\t    this.ignoreHover = false;\n\t    this.hasOptions = false;\n\t    this.currentResults = void 0;\n\t    this.lastValue = '';\n\t    this.caretPos = 0;\n\t    this.loading = 0;\n\t    this.loadedSearches = {};\n\t    this.activeOption = null;\n\t    this.activeItems = [];\n\t    this.optgroups = {};\n\t    this.options = {};\n\t    this.userOptions = {};\n\t    this.items = [];\n\t    instance_i++;\n\t    var dir;\n\t    var input = getDom(input_arg);\n\n\t    if (input.tomselect) {\n\t      throw new Error('Tom Select already initialized on this element');\n\t    }\n\n\t    input.tomselect = this; // detect rtl environment\n\n\t    var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null);\n\t    dir = computedStyle.getPropertyValue('direction'); // setup default state\n\n\t    const settings = getSettings(input, user_settings);\n\t    this.settings = settings;\n\t    this.input = input;\n\t    this.tabIndex = input.tabIndex || 0;\n\t    this.is_select_tag = input.tagName.toLowerCase() === 'select';\n\t    this.rtl = /rtl/i.test(dir);\n\t    this.inputId = getId(input, 'tomselect-' + instance_i);\n\t    this.isRequired = input.required; // search system\n\n\t    this.sifter = new Sifter(this.options, {\n\t      diacritics: settings.diacritics\n\t    }); // option-dependent defaults\n\n\t    settings.mode = settings.mode || (settings.maxItems === 1 ? 'single' : 'multi');\n\n\t    if (typeof settings.hideSelected !== 'boolean') {\n\t      settings.hideSelected = settings.mode === 'multi';\n\t    }\n\n\t    if (typeof settings.hidePlaceholder !== 'boolean') {\n\t      settings.hidePlaceholder = settings.mode !== 'multi';\n\t    } // set up createFilter callback\n\n\n\t    var filter = settings.createFilter;\n\n\t    if (typeof filter !== 'function') {\n\t      if (typeof filter === 'string') {\n\t        filter = new RegExp(filter);\n\t      }\n\n\t      if (filter instanceof RegExp) {\n\t        settings.createFilter = input => filter.test(input);\n\t      } else {\n\t        settings.createFilter = value => {\n\t          return this.settings.duplicates || !this.options[value];\n\t        };\n\t      }\n\t    }\n\n\t    this.initializePlugins(settings.plugins);\n\t    this.setupCallbacks();\n\t    this.setupTemplates(); // Create all elements\n\n\t    const wrapper = getDom('<div>');\n\t    const control = getDom('<div>');\n\n\t    const dropdown = this._render('dropdown');\n\n\t    const dropdown_content = getDom(`<div role=\"listbox\" tabindex=\"-1\">`);\n\t    const classes = this.input.getAttribute('class') || '';\n\t    const inputMode = settings.mode;\n\t    var control_input;\n\t    addClasses(wrapper, settings.wrapperClass, classes, inputMode);\n\t    addClasses(control, settings.controlClass);\n\t    append(wrapper, control);\n\t    addClasses(dropdown, settings.dropdownClass, inputMode);\n\n\t    if (settings.copyClassesToDropdown) {\n\t      addClasses(dropdown, classes);\n\t    }\n\n\t    addClasses(dropdown_content, settings.dropdownContentClass);\n\t    append(dropdown, dropdown_content);\n\t    getDom(settings.dropdownParent || wrapper).appendChild(dropdown); // default controlInput\n\n\t    if (isHtmlString(settings.controlInput)) {\n\t      control_input = getDom(settings.controlInput); // set attributes\n\n\t      var attrs = ['autocorrect', 'autocapitalize', 'autocomplete'];\n\t      iterate$1(attrs, attr => {\n\t        if (input.getAttribute(attr)) {\n\t          setAttr(control_input, {\n\t            [attr]: input.getAttribute(attr)\n\t          });\n\t        }\n\t      });\n\t      control_input.tabIndex = -1;\n\t      control.appendChild(control_input);\n\t      this.focus_node = control_input; // dom element\n\t    } else if (settings.controlInput) {\n\t      control_input = getDom(settings.controlInput);\n\t      this.focus_node = control_input;\n\t    } else {\n\t      control_input = getDom('<input/>');\n\t      this.focus_node = control;\n\t    }\n\n\t    this.wrapper = wrapper;\n\t    this.dropdown = dropdown;\n\t    this.dropdown_content = dropdown_content;\n\t    this.control = control;\n\t    this.control_input = control_input;\n\t    this.setup();\n\t  }\n\t  /**\n\t   * set up event bindings.\n\t   *\n\t   */\n\n\n\t  setup() {\n\t    const self = this;\n\t    const settings = self.settings;\n\t    const control_input = self.control_input;\n\t    const dropdown = self.dropdown;\n\t    const dropdown_content = self.dropdown_content;\n\t    const wrapper = self.wrapper;\n\t    const control = self.control;\n\t    const input = self.input;\n\t    const focus_node = self.focus_node;\n\t    const passive_event = {\n\t      passive: true\n\t    };\n\t    const listboxId = self.inputId + '-ts-dropdown';\n\t    setAttr(dropdown_content, {\n\t      id: listboxId\n\t    });\n\t    setAttr(focus_node, {\n\t      role: 'combobox',\n\t      'aria-haspopup': 'listbox',\n\t      'aria-expanded': 'false',\n\t      'aria-controls': listboxId\n\t    });\n\t    const control_id = getId(focus_node, self.inputId + '-ts-control');\n\t    const query = \"label[for='\" + escapeQuery(self.inputId) + \"']\";\n\t    const label = document.querySelector(query);\n\t    const label_click = self.focus.bind(self);\n\n\t    if (label) {\n\t      addEvent(label, 'click', label_click);\n\t      setAttr(label, {\n\t        for: control_id\n\t      });\n\t      const label_id = getId(label, self.inputId + '-ts-label');\n\t      setAttr(focus_node, {\n\t        'aria-labelledby': label_id\n\t      });\n\t      setAttr(dropdown_content, {\n\t        'aria-labelledby': label_id\n\t      });\n\t    }\n\n\t    wrapper.style.width = input.style.width;\n\n\t    if (self.plugins.names.length) {\n\t      const classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-');\n\t      addClasses([wrapper, dropdown], classes_plugins);\n\t    }\n\n\t    if ((settings.maxItems === null || settings.maxItems > 1) && self.is_select_tag) {\n\t      setAttr(input, {\n\t        multiple: 'multiple'\n\t      });\n\t    }\n\n\t    if (settings.placeholder) {\n\t      setAttr(control_input, {\n\t        placeholder: settings.placeholder\n\t      });\n\t    } // if splitOn was not passed in, construct it from the delimiter to allow pasting universally\n\n\n\t    if (!settings.splitOn && settings.delimiter) {\n\t      settings.splitOn = new RegExp('\\\\s*' + escape_regex(settings.delimiter) + '+\\\\s*');\n\t    } // debounce user defined load() if loadThrottle > 0\n\t    // after initializePlugins() so plugins can create/modify user defined loaders\n\n\n\t    if (settings.load && settings.loadThrottle) {\n\t      settings.load = loadDebounce(settings.load, settings.loadThrottle);\n\t    }\n\n\t    self.control_input.type = input.type;\n\t    addEvent(dropdown, 'mousemove', () => {\n\t      self.ignoreHover = false;\n\t    });\n\t    addEvent(dropdown, 'mouseenter', e => {\n\t      var target_match = parentMatch(e.target, '[data-selectable]', dropdown);\n\t      if (target_match) self.onOptionHover(e, target_match);\n\t    }, {\n\t      capture: true\n\t    }); // clicking on an option should select it\n\n\t    addEvent(dropdown, 'click', evt => {\n\t      const option = parentMatch(evt.target, '[data-selectable]');\n\n\t      if (option) {\n\t        self.onOptionSelect(evt, option);\n\t        preventDefault(evt, true);\n\t      }\n\t    });\n\t    addEvent(control, 'click', evt => {\n\t      var target_match = parentMatch(evt.target, '[data-ts-item]', control);\n\n\t      if (target_match && self.onItemSelect(evt, target_match)) {\n\t        preventDefault(evt, true);\n\t        return;\n\t      } // retain focus (see control_input mousedown)\n\n\n\t      if (control_input.value != '') {\n\t        return;\n\t      }\n\n\t      self.onClick();\n\t      preventDefault(evt, true);\n\t    }); // keydown on focus_node for arrow_down/arrow_up\n\n\t    addEvent(focus_node, 'keydown', e => self.onKeyDown(e)); // keypress and input/keyup\n\n\t    addEvent(control_input, 'keypress', e => self.onKeyPress(e));\n\t    addEvent(control_input, 'input', e => self.onInput(e));\n\t    addEvent(focus_node, 'blur', e => self.onBlur(e));\n\t    addEvent(focus_node, 'focus', e => self.onFocus(e));\n\t    addEvent(control_input, 'paste', e => self.onPaste(e));\n\n\t    const doc_mousedown = evt => {\n\t      // blur if target is outside of this instance\n\t      // dropdown is not always inside wrapper\n\t      const target = evt.composedPath()[0];\n\n\t      if (!wrapper.contains(target) && !dropdown.contains(target)) {\n\t        if (self.isFocused) {\n\t          self.blur();\n\t        }\n\n\t        self.inputState();\n\t        return;\n\t      } // retain focus by preventing native handling. if the\n\t      // event target is the input it should not be modified.\n\t      // otherwise, text selection within the input won't work.\n\t      // Fixes bug #212 which is no covered by tests\n\n\n\t      if (target == control_input && self.isOpen) {\n\t        evt.stopPropagation(); // clicking anywhere in the control should not blur the control_input (which would close the dropdown)\n\t      } else {\n\t        preventDefault(evt, true);\n\t      }\n\t    };\n\n\t    const win_scroll = () => {\n\t      if (self.isOpen) {\n\t        self.positionDropdown();\n\t      }\n\t    };\n\n\t    addEvent(document, 'mousedown', doc_mousedown);\n\t    addEvent(window, 'scroll', win_scroll, passive_event);\n\t    addEvent(window, 'resize', win_scroll, passive_event);\n\n\t    this._destroy = () => {\n\t      document.removeEventListener('mousedown', doc_mousedown);\n\t      window.removeEventListener('scroll', win_scroll);\n\t      window.removeEventListener('resize', win_scroll);\n\t      if (label) label.removeEventListener('click', label_click);\n\t    }; // store original html and tab index so that they can be\n\t    // restored when the destroy() method is called.\n\n\n\t    this.revertSettings = {\n\t      innerHTML: input.innerHTML,\n\t      tabIndex: input.tabIndex\n\t    };\n\t    input.tabIndex = -1;\n\t    input.insertAdjacentElement('afterend', self.wrapper);\n\t    self.sync(false);\n\t    settings.items = [];\n\t    delete settings.optgroups;\n\t    delete settings.options;\n\t    addEvent(input, 'invalid', () => {\n\t      if (self.isValid) {\n\t        self.isValid = false;\n\t        self.isInvalid = true;\n\t        self.refreshState();\n\t      }\n\t    });\n\t    self.updateOriginalInput();\n\t    self.refreshItems();\n\t    self.close(false);\n\t    self.inputState();\n\t    self.isSetup = true;\n\n\t    if (input.disabled) {\n\t      self.disable();\n\t    } else {\n\t      self.enable(); //sets tabIndex\n\t    }\n\n\t    self.on('change', this.onChange);\n\t    addClasses(input, 'tomselected', 'ts-hidden-accessible');\n\t    self.trigger('initialize'); // preload options\n\n\t    if (settings.preload === true) {\n\t      self.preload();\n\t    }\n\t  }\n\t  /**\n\t   * Register options and optgroups\n\t   *\n\t   */\n\n\n\t  setupOptions(options = [], optgroups = []) {\n\t    // build options table\n\t    this.addOptions(options); // build optgroup table\n\n\t    iterate$1(optgroups, optgroup => {\n\t      this.registerOptionGroup(optgroup);\n\t    });\n\t  }\n\t  /**\n\t   * Sets up default rendering functions.\n\t   */\n\n\n\t  setupTemplates() {\n\t    var self = this;\n\t    var field_label = self.settings.labelField;\n\t    var field_optgroup = self.settings.optgroupLabelField;\n\t    var templates = {\n\t      'optgroup': data => {\n\t        let optgroup = document.createElement('div');\n\t        optgroup.className = 'optgroup';\n\t        optgroup.appendChild(data.options);\n\t        return optgroup;\n\t      },\n\t      'optgroup_header': (data, escape) => {\n\t        return '<div class=\"optgroup-header\">' + escape(data[field_optgroup]) + '</div>';\n\t      },\n\t      'option': (data, escape) => {\n\t        return '<div>' + escape(data[field_label]) + '</div>';\n\t      },\n\t      'item': (data, escape) => {\n\t        return '<div>' + escape(data[field_label]) + '</div>';\n\t      },\n\t      'option_create': (data, escape) => {\n\t        return '<div class=\"create\">Add <strong>' + escape(data.input) + '</strong>&hellip;</div>';\n\t      },\n\t      'no_results': () => {\n\t        return '<div class=\"no-results\">No results found</div>';\n\t      },\n\t      'loading': () => {\n\t        return '<div class=\"spinner\"></div>';\n\t      },\n\t      'not_loading': () => {},\n\t      'dropdown': () => {\n\t        return '<div></div>';\n\t      }\n\t    };\n\t    self.settings.render = Object.assign({}, templates, self.settings.render);\n\t  }\n\t  /**\n\t   * Maps fired events to callbacks provided\n\t   * in the settings used when creating the control.\n\t   */\n\n\n\t  setupCallbacks() {\n\t    var key, fn;\n\t    var callbacks = {\n\t      'initialize': 'onInitialize',\n\t      'change': 'onChange',\n\t      'item_add': 'onItemAdd',\n\t      'item_remove': 'onItemRemove',\n\t      'item_select': 'onItemSelect',\n\t      'clear': 'onClear',\n\t      'option_add': 'onOptionAdd',\n\t      'option_remove': 'onOptionRemove',\n\t      'option_clear': 'onOptionClear',\n\t      'optgroup_add': 'onOptionGroupAdd',\n\t      'optgroup_remove': 'onOptionGroupRemove',\n\t      'optgroup_clear': 'onOptionGroupClear',\n\t      'dropdown_open': 'onDropdownOpen',\n\t      'dropdown_close': 'onDropdownClose',\n\t      'type': 'onType',\n\t      'load': 'onLoad',\n\t      'focus': 'onFocus',\n\t      'blur': 'onBlur'\n\t    };\n\n\t    for (key in callbacks) {\n\t      fn = this.settings[callbacks[key]];\n\t      if (fn) this.on(key, fn);\n\t    }\n\t  }\n\t  /**\n\t   * Sync the Tom Select instance with the original input or select\n\t   *\n\t   */\n\n\n\t  sync(get_settings = true) {\n\t    const self = this;\n\t    const settings = get_settings ? getSettings(self.input, {\n\t      delimiter: self.settings.delimiter\n\t    }) : self.settings;\n\t    self.setupOptions(settings.options, settings.optgroups);\n\t    self.setValue(settings.items || [], true); // silent prevents recursion\n\n\t    self.lastQuery = null; // so updated options will be displayed in dropdown\n\t  }\n\t  /**\n\t   * Triggered when the main control element\n\t   * has a click event.\n\t   *\n\t   */\n\n\n\t  onClick() {\n\t    var self = this;\n\n\t    if (self.activeItems.length > 0) {\n\t      self.clearActiveItems();\n\t      self.focus();\n\t      return;\n\t    }\n\n\t    if (self.isFocused && self.isOpen) {\n\t      self.blur();\n\t    } else {\n\t      self.focus();\n\t    }\n\t  }\n\t  /**\n\t   * @deprecated v1.7\n\t   *\n\t   */\n\n\n\t  onMouseDown() {}\n\t  /**\n\t   * Triggered when the value of the control has been changed.\n\t   * This should propagate the event to the original DOM\n\t   * input / select element.\n\t   */\n\n\n\t  onChange() {\n\t    triggerEvent(this.input, 'input');\n\t    triggerEvent(this.input, 'change');\n\t  }\n\t  /**\n\t   * Triggered on <input> paste.\n\t   *\n\t   */\n\n\n\t  onPaste(e) {\n\t    var self = this;\n\n\t    if (self.isInputHidden || self.isLocked) {\n\t      preventDefault(e);\n\t      return;\n\t    } // If a regex or string is included, this will split the pasted\n\t    // input and create Items for each separate value\n\n\n\t    if (!self.settings.splitOn) {\n\t      return;\n\t    } // Wait for pasted text to be recognized in value\n\n\n\t    setTimeout(() => {\n\t      var pastedText = self.inputValue();\n\n\t      if (!pastedText.match(self.settings.splitOn)) {\n\t        return;\n\t      }\n\n\t      var splitInput = pastedText.trim().split(self.settings.splitOn);\n\t      iterate$1(splitInput, piece => {\n\t        const hash = hash_key(piece);\n\n\t        if (hash) {\n\t          if (this.options[piece]) {\n\t            self.addItem(piece);\n\t          } else {\n\t            self.createItem(piece);\n\t          }\n\t        }\n\t      });\n\t    }, 0);\n\t  }\n\t  /**\n\t   * Triggered on <input> keypress.\n\t   *\n\t   */\n\n\n\t  onKeyPress(e) {\n\t    var self = this;\n\n\t    if (self.isLocked) {\n\t      preventDefault(e);\n\t      return;\n\t    }\n\n\t    var character = String.fromCharCode(e.keyCode || e.which);\n\n\t    if (self.settings.create && self.settings.mode === 'multi' && character === self.settings.delimiter) {\n\t      self.createItem();\n\t      preventDefault(e);\n\t      return;\n\t    }\n\t  }\n\t  /**\n\t   * Triggered on <input> keydown.\n\t   *\n\t   */\n\n\n\t  onKeyDown(e) {\n\t    var self = this;\n\t    self.ignoreHover = true;\n\n\t    if (self.isLocked) {\n\t      if (e.keyCode !== KEY_TAB) {\n\t        preventDefault(e);\n\t      }\n\n\t      return;\n\t    }\n\n\t    switch (e.keyCode) {\n\t      // ctrl+A: select all\n\t      case KEY_A:\n\t        if (isKeyDown(KEY_SHORTCUT, e)) {\n\t          if (self.control_input.value == '') {\n\t            preventDefault(e);\n\t            self.selectAll();\n\t            return;\n\t          }\n\t        }\n\n\t        break;\n\t      // esc: close dropdown\n\n\t      case KEY_ESC:\n\t        if (self.isOpen) {\n\t          preventDefault(e, true);\n\t          self.close();\n\t        }\n\n\t        self.clearActiveItems();\n\t        return;\n\t      // down: open dropdown or move selection down\n\n\t      case KEY_DOWN:\n\t        if (!self.isOpen && self.hasOptions) {\n\t          self.open();\n\t        } else if (self.activeOption) {\n\t          let next = self.getAdjacent(self.activeOption, 1);\n\t          if (next) self.setActiveOption(next);\n\t        }\n\n\t        preventDefault(e);\n\t        return;\n\t      // up: move selection up\n\n\t      case KEY_UP:\n\t        if (self.activeOption) {\n\t          let prev = self.getAdjacent(self.activeOption, -1);\n\t          if (prev) self.setActiveOption(prev);\n\t        }\n\n\t        preventDefault(e);\n\t        return;\n\t      // return: select active option\n\n\t      case KEY_RETURN:\n\t        if (self.canSelect(self.activeOption)) {\n\t          self.onOptionSelect(e, self.activeOption);\n\t          preventDefault(e); // if the option_create=null, the dropdown might be closed\n\t        } else if (self.settings.create && self.createItem()) {\n\t          preventDefault(e); // don't submit form when searching for a value\n\t        } else if (document.activeElement == self.control_input && self.isOpen) {\n\t          preventDefault(e);\n\t        }\n\n\t        return;\n\t      // left: modifiy item selection to the left\n\n\t      case KEY_LEFT:\n\t        self.advanceSelection(-1, e);\n\t        return;\n\t      // right: modifiy item selection to the right\n\n\t      case KEY_RIGHT:\n\t        self.advanceSelection(1, e);\n\t        return;\n\t      // tab: select active option and/or create item\n\n\t      case KEY_TAB:\n\t        if (self.settings.selectOnTab) {\n\t          if (self.canSelect(self.activeOption)) {\n\t            self.onOptionSelect(e, self.activeOption); // prevent default [tab] behaviour of jump to the next field\n\t            // if select isFull, then the dropdown won't be open and [tab] will work normally\n\n\t            preventDefault(e);\n\t          }\n\n\t          if (self.settings.create && self.createItem()) {\n\t            preventDefault(e);\n\t          }\n\t        }\n\n\t        return;\n\t      // delete|backspace: delete items\n\n\t      case KEY_BACKSPACE:\n\t      case KEY_DELETE:\n\t        self.deleteSelection(e);\n\t        return;\n\t    } // don't enter text in the control_input when active items are selected\n\n\n\t    if (self.isInputHidden && !isKeyDown(KEY_SHORTCUT, e)) {\n\t      preventDefault(e);\n\t    }\n\t  }\n\t  /**\n\t   * Triggered on <input> keyup.\n\t   *\n\t   */\n\n\n\t  onInput(e) {\n\t    var self = this;\n\n\t    if (self.isLocked) {\n\t      return;\n\t    }\n\n\t    var value = self.inputValue();\n\n\t    if (self.lastValue !== value) {\n\t      self.lastValue = value;\n\n\t      if (self.settings.shouldLoad.call(self, value)) {\n\t        self.load(value);\n\t      }\n\n\t      self.refreshOptions();\n\t      self.trigger('type', value);\n\t    }\n\t  }\n\t  /**\n\t   * Triggered when the user rolls over\n\t   * an option in the autocomplete dropdown menu.\n\t   *\n\t   */\n\n\n\t  onOptionHover(evt, option) {\n\t    if (this.ignoreHover) return;\n\t    this.setActiveOption(option, false);\n\t  }\n\t  /**\n\t   * Triggered on <input> focus.\n\t   *\n\t   */\n\n\n\t  onFocus(e) {\n\t    var self = this;\n\t    var wasFocused = self.isFocused;\n\n\t    if (self.isDisabled) {\n\t      self.blur();\n\t      preventDefault(e);\n\t      return;\n\t    }\n\n\t    if (self.ignoreFocus) return;\n\t    self.isFocused = true;\n\t    if (self.settings.preload === 'focus') self.preload();\n\t    if (!wasFocused) self.trigger('focus');\n\n\t    if (!self.activeItems.length) {\n\t      self.showInput();\n\t      self.refreshOptions(!!self.settings.openOnFocus);\n\t    }\n\n\t    self.refreshState();\n\t  }\n\t  /**\n\t   * Triggered on <input> blur.\n\t   *\n\t   */\n\n\n\t  onBlur(e) {\n\t    if (document.hasFocus() === false) return;\n\t    var self = this;\n\t    if (!self.isFocused) return;\n\t    self.isFocused = false;\n\t    self.ignoreFocus = false;\n\n\t    var deactivate = () => {\n\t      self.close();\n\t      self.setActiveItem();\n\t      self.setCaret(self.items.length);\n\t      self.trigger('blur');\n\t    };\n\n\t    if (self.settings.create && self.settings.createOnBlur) {\n\t      self.createItem(null, deactivate);\n\t    } else {\n\t      deactivate();\n\t    }\n\t  }\n\t  /**\n\t   * Triggered when the user clicks on an option\n\t   * in the autocomplete dropdown menu.\n\t   *\n\t   */\n\n\n\t  onOptionSelect(evt, option) {\n\t    var value,\n\t        self = this; // should not be possible to trigger a option under a disabled optgroup\n\n\t    if (option.parentElement && option.parentElement.matches('[data-disabled]')) {\n\t      return;\n\t    }\n\n\t    if (option.classList.contains('create')) {\n\t      self.createItem(null, () => {\n\t        if (self.settings.closeAfterSelect) {\n\t          self.close();\n\t        }\n\t      });\n\t    } else {\n\t      value = option.dataset.value;\n\n\t      if (typeof value !== 'undefined') {\n\t        self.lastQuery = null;\n\t        self.addItem(value);\n\n\t        if (self.settings.closeAfterSelect) {\n\t          self.close();\n\t        }\n\n\t        if (!self.settings.hideSelected && evt.type && /click/.test(evt.type)) {\n\t          self.setActiveOption(option);\n\t        }\n\t      }\n\t    }\n\t  }\n\t  /**\n\t   * Return true if the given option can be selected\n\t   *\n\t   */\n\n\n\t  canSelect(option) {\n\t    if (this.isOpen && option && this.dropdown_content.contains(option)) {\n\t      return true;\n\t    }\n\n\t    return false;\n\t  }\n\t  /**\n\t   * Triggered when the user clicks on an item\n\t   * that has been selected.\n\t   *\n\t   */\n\n\n\t  onItemSelect(evt, item) {\n\t    var self = this;\n\n\t    if (!self.isLocked && self.settings.mode === 'multi') {\n\t      preventDefault(evt);\n\t      self.setActiveItem(item, evt);\n\t      return true;\n\t    }\n\n\t    return false;\n\t  }\n\t  /**\n\t   * Determines whether or not to invoke\n\t   * the user-provided option provider / loader\n\t   *\n\t   * Note, there is a subtle difference between\n\t   * this.canLoad() and this.settings.shouldLoad();\n\t   *\n\t   *\t- settings.shouldLoad() is a user-input validator.\n\t   *\tWhen false is returned, the not_loading template\n\t   *\twill be added to the dropdown\n\t   *\n\t   *\t- canLoad() is lower level validator that checks\n\t   * \tthe Tom Select instance. There is no inherent user\n\t   *\tfeedback when canLoad returns false\n\t   *\n\t   */\n\n\n\t  canLoad(value) {\n\t    if (!this.settings.load) return false;\n\t    if (this.loadedSearches.hasOwnProperty(value)) return false;\n\t    return true;\n\t  }\n\t  /**\n\t   * Invokes the user-provided option provider / loader.\n\t   *\n\t   */\n\n\n\t  load(value) {\n\t    const self = this;\n\t    if (!self.canLoad(value)) return;\n\t    addClasses(self.wrapper, self.settings.loadingClass);\n\t    self.loading++;\n\t    const callback = self.loadCallback.bind(self);\n\t    self.settings.load.call(self, value, callback);\n\t  }\n\t  /**\n\t   * Invoked by the user-provided option provider\n\t   *\n\t   */\n\n\n\t  loadCallback(options, optgroups) {\n\t    const self = this;\n\t    self.loading = Math.max(self.loading - 1, 0);\n\t    self.lastQuery = null;\n\t    self.clearActiveOption(); // when new results load, focus should be on first option\n\n\t    self.setupOptions(options, optgroups);\n\t    self.refreshOptions(self.isFocused && !self.isInputHidden);\n\n\t    if (!self.loading) {\n\t      removeClasses(self.wrapper, self.settings.loadingClass);\n\t    }\n\n\t    self.trigger('load', options, optgroups);\n\t  }\n\n\t  preload() {\n\t    var classList = this.wrapper.classList;\n\t    if (classList.contains('preloaded')) return;\n\t    classList.add('preloaded');\n\t    this.load('');\n\t  }\n\t  /**\n\t   * Sets the input field of the control to the specified value.\n\t   *\n\t   */\n\n\n\t  setTextboxValue(value = '') {\n\t    var input = this.control_input;\n\t    var changed = input.value !== value;\n\n\t    if (changed) {\n\t      input.value = value;\n\t      triggerEvent(input, 'update');\n\t      this.lastValue = value;\n\t    }\n\t  }\n\t  /**\n\t   * Returns the value of the control. If multiple items\n\t   * can be selected (e.g. <select multiple>), this returns\n\t   * an array. If only one item can be selected, this\n\t   * returns a string.\n\t   *\n\t   */\n\n\n\t  getValue() {\n\t    if (this.is_select_tag && this.input.hasAttribute('multiple')) {\n\t      return this.items;\n\t    }\n\n\t    return this.items.join(this.settings.delimiter);\n\t  }\n\t  /**\n\t   * Resets the selected items to the given value.\n\t   *\n\t   */\n\n\n\t  setValue(value, silent) {\n\t    var events = silent ? [] : ['change'];\n\t    debounce_events(this, events, () => {\n\t      this.clear(silent);\n\t      this.addItems(value, silent);\n\t    });\n\t  }\n\t  /**\n\t   * Resets the number of max items to the given value\n\t   *\n\t   */\n\n\n\t  setMaxItems(value) {\n\t    if (value === 0) value = null; //reset to unlimited items.\n\n\t    this.settings.maxItems = value;\n\t    this.refreshState();\n\t  }\n\t  /**\n\t   * Sets the selected item.\n\t   *\n\t   */\n\n\n\t  setActiveItem(item, e) {\n\t    var self = this;\n\t    var eventName;\n\t    var i, begin, end, swap;\n\t    var last;\n\t    if (self.settings.mode === 'single') return; // clear the active selection\n\n\t    if (!item) {\n\t      self.clearActiveItems();\n\n\t      if (self.isFocused) {\n\t        self.showInput();\n\t      }\n\n\t      return;\n\t    } // modify selection\n\n\n\t    eventName = e && e.type.toLowerCase();\n\n\t    if (eventName === 'click' && isKeyDown('shiftKey', e) && self.activeItems.length) {\n\t      last = self.getLastActive();\n\t      begin = Array.prototype.indexOf.call(self.control.children, last);\n\t      end = Array.prototype.indexOf.call(self.control.children, item);\n\n\t      if (begin > end) {\n\t        swap = begin;\n\t        begin = end;\n\t        end = swap;\n\t      }\n\n\t      for (i = begin; i <= end; i++) {\n\t        item = self.control.children[i];\n\n\t        if (self.activeItems.indexOf(item) === -1) {\n\t          self.setActiveItemClass(item);\n\t        }\n\t      }\n\n\t      preventDefault(e);\n\t    } else if (eventName === 'click' && isKeyDown(KEY_SHORTCUT, e) || eventName === 'keydown' && isKeyDown('shiftKey', e)) {\n\t      if (item.classList.contains('active')) {\n\t        self.removeActiveItem(item);\n\t      } else {\n\t        self.setActiveItemClass(item);\n\t      }\n\t    } else {\n\t      self.clearActiveItems();\n\t      self.setActiveItemClass(item);\n\t    } // ensure control has focus\n\n\n\t    self.hideInput();\n\n\t    if (!self.isFocused) {\n\t      self.focus();\n\t    }\n\t  }\n\t  /**\n\t   * Set the active and last-active classes\n\t   *\n\t   */\n\n\n\t  setActiveItemClass(item) {\n\t    const self = this;\n\t    const last_active = self.control.querySelector('.last-active');\n\t    if (last_active) removeClasses(last_active, 'last-active');\n\t    addClasses(item, 'active last-active');\n\t    self.trigger('item_select', item);\n\n\t    if (self.activeItems.indexOf(item) == -1) {\n\t      self.activeItems.push(item);\n\t    }\n\t  }\n\t  /**\n\t   * Remove active item\n\t   *\n\t   */\n\n\n\t  removeActiveItem(item) {\n\t    var idx = this.activeItems.indexOf(item);\n\t    this.activeItems.splice(idx, 1);\n\t    removeClasses(item, 'active');\n\t  }\n\t  /**\n\t   * Clears all the active items\n\t   *\n\t   */\n\n\n\t  clearActiveItems() {\n\t    removeClasses(this.activeItems, 'active');\n\t    this.activeItems = [];\n\t  }\n\t  /**\n\t   * Sets the selected item in the dropdown menu\n\t   * of available options.\n\t   *\n\t   */\n\n\n\t  setActiveOption(option, scroll = true) {\n\t    if (option === this.activeOption) {\n\t      return;\n\t    }\n\n\t    this.clearActiveOption();\n\t    if (!option) return;\n\t    this.activeOption = option;\n\t    setAttr(this.focus_node, {\n\t      'aria-activedescendant': option.getAttribute('id')\n\t    });\n\t    setAttr(option, {\n\t      'aria-selected': 'true'\n\t    });\n\t    addClasses(option, 'active');\n\t    if (scroll) this.scrollToOption(option);\n\t  }\n\t  /**\n\t   * Sets the dropdown_content scrollTop to display the option\n\t   *\n\t   */\n\n\n\t  scrollToOption(option, behavior) {\n\t    if (!option) return;\n\t    const content = this.dropdown_content;\n\t    const height_menu = content.clientHeight;\n\t    const scrollTop = content.scrollTop || 0;\n\t    const height_item = option.offsetHeight;\n\t    const y = option.getBoundingClientRect().top - content.getBoundingClientRect().top + scrollTop;\n\n\t    if (y + height_item > height_menu + scrollTop) {\n\t      this.scroll(y - height_menu + height_item, behavior);\n\t    } else if (y < scrollTop) {\n\t      this.scroll(y, behavior);\n\t    }\n\t  }\n\t  /**\n\t   * Scroll the dropdown to the given position\n\t   *\n\t   */\n\n\n\t  scroll(scrollTop, behavior) {\n\t    const content = this.dropdown_content;\n\n\t    if (behavior) {\n\t      content.style.scrollBehavior = behavior;\n\t    }\n\n\t    content.scrollTop = scrollTop;\n\t    content.style.scrollBehavior = '';\n\t  }\n\t  /**\n\t   * Clears the active option\n\t   *\n\t   */\n\n\n\t  clearActiveOption() {\n\t    if (this.activeOption) {\n\t      removeClasses(this.activeOption, 'active');\n\t      setAttr(this.activeOption, {\n\t        'aria-selected': null\n\t      });\n\t    }\n\n\t    this.activeOption = null;\n\t    setAttr(this.focus_node, {\n\t      'aria-activedescendant': null\n\t    });\n\t  }\n\t  /**\n\t   * Selects all items (CTRL + A).\n\t   */\n\n\n\t  selectAll() {\n\t    const self = this;\n\t    if (self.settings.mode === 'single') return;\n\t    const activeItems = self.controlChildren();\n\t    if (!activeItems.length) return;\n\t    self.hideInput();\n\t    self.close();\n\t    self.activeItems = activeItems;\n\t    iterate$1(activeItems, item => {\n\t      self.setActiveItemClass(item);\n\t    });\n\t  }\n\t  /**\n\t   * Determines if the control_input should be in a hidden or visible state\n\t   *\n\t   */\n\n\n\t  inputState() {\n\t    var self = this;\n\t    if (!self.control.contains(self.control_input)) return;\n\t    setAttr(self.control_input, {\n\t      placeholder: self.settings.placeholder\n\t    });\n\n\t    if (self.activeItems.length > 0 || !self.isFocused && self.settings.hidePlaceholder && self.items.length > 0) {\n\t      self.setTextboxValue();\n\t      self.isInputHidden = true;\n\t    } else {\n\t      if (self.settings.hidePlaceholder && self.items.length > 0) {\n\t        setAttr(self.control_input, {\n\t          placeholder: ''\n\t        });\n\t      }\n\n\t      self.isInputHidden = false;\n\t    }\n\n\t    self.wrapper.classList.toggle('input-hidden', self.isInputHidden);\n\t  }\n\t  /**\n\t   * Hides the input element out of view, while\n\t   * retaining its focus.\n\t   * @deprecated 1.3\n\t   */\n\n\n\t  hideInput() {\n\t    this.inputState();\n\t  }\n\t  /**\n\t   * Restores input visibility.\n\t   * @deprecated 1.3\n\t   */\n\n\n\t  showInput() {\n\t    this.inputState();\n\t  }\n\t  /**\n\t   * Get the input value\n\t   */\n\n\n\t  inputValue() {\n\t    return this.control_input.value.trim();\n\t  }\n\t  /**\n\t   * Gives the control focus.\n\t   */\n\n\n\t  focus() {\n\t    var self = this;\n\t    if (self.isDisabled) return;\n\t    self.ignoreFocus = true;\n\n\t    if (self.control_input.offsetWidth) {\n\t      self.control_input.focus();\n\t    } else {\n\t      self.focus_node.focus();\n\t    }\n\n\t    setTimeout(() => {\n\t      self.ignoreFocus = false;\n\t      self.onFocus();\n\t    }, 0);\n\t  }\n\t  /**\n\t   * Forces the control out of focus.\n\t   *\n\t   */\n\n\n\t  blur() {\n\t    this.focus_node.blur();\n\t    this.onBlur();\n\t  }\n\t  /**\n\t   * Returns a function that scores an object\n\t   * to show how good of a match it is to the\n\t   * provided query.\n\t   *\n\t   * @return {function}\n\t   */\n\n\n\t  getScoreFunction(query) {\n\t    return this.sifter.getScoreFunction(query, this.getSearchOptions());\n\t  }\n\t  /**\n\t   * Returns search options for sifter (the system\n\t   * for scoring and sorting results).\n\t   *\n\t   * @see https://github.com/orchidjs/sifter.js\n\t   * @return {object}\n\t   */\n\n\n\t  getSearchOptions() {\n\t    var settings = this.settings;\n\t    var sort = settings.sortField;\n\n\t    if (typeof settings.sortField === 'string') {\n\t      sort = [{\n\t        field: settings.sortField\n\t      }];\n\t    }\n\n\t    return {\n\t      fields: settings.searchField,\n\t      conjunction: settings.searchConjunction,\n\t      sort: sort,\n\t      nesting: settings.nesting\n\t    };\n\t  }\n\t  /**\n\t   * Searches through available options and returns\n\t   * a sorted array of matches.\n\t   *\n\t   */\n\n\n\t  search(query) {\n\t    var result, calculateScore;\n\t    var self = this;\n\t    var options = this.getSearchOptions(); // validate user-provided result scoring function\n\n\t    if (self.settings.score) {\n\t      calculateScore = self.settings.score.call(self, query);\n\n\t      if (typeof calculateScore !== 'function') {\n\t        throw new Error('Tom Select \"score\" setting must be a function that returns a function');\n\t      }\n\t    } // perform search\n\n\n\t    if (query !== self.lastQuery) {\n\t      self.lastQuery = query;\n\t      result = self.sifter.search(query, Object.assign(options, {\n\t        score: calculateScore\n\t      }));\n\t      self.currentResults = result;\n\t    } else {\n\t      result = Object.assign({}, self.currentResults);\n\t    } // filter out selected items\n\n\n\t    if (self.settings.hideSelected) {\n\t      result.items = result.items.filter(item => {\n\t        let hashed = hash_key(item.id);\n\t        return !(hashed && self.items.indexOf(hashed) !== -1);\n\t      });\n\t    }\n\n\t    return result;\n\t  }\n\t  /**\n\t   * Refreshes the list of available options shown\n\t   * in the autocomplete dropdown menu.\n\t   *\n\t   */\n\n\n\t  refreshOptions(triggerDropdown = true) {\n\t    var i, j, k, n, optgroup, optgroups, html, has_create_option, active_group;\n\t    var create;\n\t    const groups = {};\n\t    const groups_order = [];\n\t    var self = this;\n\t    var query = self.inputValue();\n\t    const same_query = query === self.lastQuery || query == '' && self.lastQuery == null;\n\t    var results = self.search(query);\n\t    var active_option = null;\n\t    var show_dropdown = self.settings.shouldOpen || false;\n\t    var dropdown_content = self.dropdown_content;\n\n\t    if (same_query) {\n\t      active_option = self.activeOption;\n\n\t      if (active_option) {\n\t        active_group = active_option.closest('[data-group]');\n\t      }\n\t    } // build markup\n\n\n\t    n = results.items.length;\n\n\t    if (typeof self.settings.maxOptions === 'number') {\n\t      n = Math.min(n, self.settings.maxOptions);\n\t    }\n\n\t    if (n > 0) {\n\t      show_dropdown = true;\n\t    } // render and group available options individually\n\n\n\t    for (i = 0; i < n; i++) {\n\t      // get option dom element\n\t      let item = results.items[i];\n\t      if (!item) continue;\n\t      let opt_value = item.id;\n\t      let option = self.options[opt_value];\n\t      if (option === undefined) continue;\n\t      let opt_hash = get_hash(opt_value);\n\t      let option_el = self.getOption(opt_hash, true); // toggle 'selected' class\n\n\t      if (!self.settings.hideSelected) {\n\t        option_el.classList.toggle('selected', self.items.includes(opt_hash));\n\t      }\n\n\t      optgroup = option[self.settings.optgroupField] || '';\n\t      optgroups = Array.isArray(optgroup) ? optgroup : [optgroup];\n\n\t      for (j = 0, k = optgroups && optgroups.length; j < k; j++) {\n\t        optgroup = optgroups[j];\n\n\t        if (!self.optgroups.hasOwnProperty(optgroup)) {\n\t          optgroup = '';\n\t        }\n\n\t        let group_fragment = groups[optgroup];\n\n\t        if (group_fragment === undefined) {\n\t          group_fragment = document.createDocumentFragment();\n\t          groups_order.push(optgroup);\n\t        } // nodes can only have one parent, so if the option is in mutple groups, we need a clone\n\n\n\t        if (j > 0) {\n\t          option_el = option_el.cloneNode(true);\n\t          setAttr(option_el, {\n\t            id: option.$id + '-clone-' + j,\n\t            'aria-selected': null\n\t          });\n\t          option_el.classList.add('ts-cloned');\n\t          removeClasses(option_el, 'active'); // make sure we keep the activeOption in the same group\n\n\t          if (self.activeOption && self.activeOption.dataset.value == opt_value) {\n\t            if (active_group && active_group.dataset.group === optgroup.toString()) {\n\t              active_option = option_el;\n\t            }\n\t          }\n\t        }\n\n\t        group_fragment.appendChild(option_el);\n\t        groups[optgroup] = group_fragment;\n\t      }\n\t    } // sort optgroups\n\n\n\t    if (self.settings.lockOptgroupOrder) {\n\t      groups_order.sort((a, b) => {\n\t        const grp_a = self.optgroups[a];\n\t        const grp_b = self.optgroups[b];\n\t        const a_order = grp_a && grp_a.$order || 0;\n\t        const b_order = grp_b && grp_b.$order || 0;\n\t        return a_order - b_order;\n\t      });\n\t    } // render optgroup headers & join groups\n\n\n\t    html = document.createDocumentFragment();\n\t    iterate$1(groups_order, optgroup => {\n\t      let group_fragment = groups[optgroup];\n\t      if (!group_fragment || !group_fragment.children.length) return;\n\t      let group_heading = self.optgroups[optgroup];\n\n\t      if (group_heading !== undefined) {\n\t        let group_options = document.createDocumentFragment();\n\t        let header = self.render('optgroup_header', group_heading);\n\t        append(group_options, header);\n\t        append(group_options, group_fragment);\n\t        let group_html = self.render('optgroup', {\n\t          group: group_heading,\n\t          options: group_options\n\t        });\n\t        append(html, group_html);\n\t      } else {\n\t        append(html, group_fragment);\n\t      }\n\t    });\n\t    dropdown_content.innerHTML = '';\n\t    append(dropdown_content, html); // highlight matching terms inline\n\n\t    if (self.settings.highlight) {\n\t      removeHighlight(dropdown_content);\n\n\t      if (results.query.length && results.tokens.length) {\n\t        iterate$1(results.tokens, tok => {\n\t          highlight(dropdown_content, tok.regex);\n\t        });\n\t      }\n\t    } // helper method for adding templates to dropdown\n\n\n\t    var add_template = template => {\n\t      let content = self.render(template, {\n\t        input: query\n\t      });\n\n\t      if (content) {\n\t        show_dropdown = true;\n\t        dropdown_content.insertBefore(content, dropdown_content.firstChild);\n\t      }\n\n\t      return content;\n\t    }; // add loading message\n\n\n\t    if (self.loading) {\n\t      add_template('loading'); // invalid query\n\t    } else if (!self.settings.shouldLoad.call(self, query)) {\n\t      add_template('not_loading'); // add no_results message\n\t    } else if (results.items.length === 0) {\n\t      add_template('no_results');\n\t    } // add create option\n\n\n\t    has_create_option = self.canCreate(query);\n\n\t    if (has_create_option) {\n\t      create = add_template('option_create');\n\t    } // activate\n\n\n\t    self.hasOptions = results.items.length > 0 || has_create_option;\n\n\t    if (show_dropdown) {\n\t      if (results.items.length > 0) {\n\t        if (!active_option && self.settings.mode === 'single' && self.items[0] != undefined) {\n\t          active_option = self.getOption(self.items[0]);\n\t        }\n\n\t        if (!dropdown_content.contains(active_option)) {\n\t          let active_index = 0;\n\n\t          if (create && !self.settings.addPrecedence) {\n\t            active_index = 1;\n\t          }\n\n\t          active_option = self.selectable()[active_index];\n\t        }\n\t      } else if (create) {\n\t        active_option = create;\n\t      }\n\n\t      if (triggerDropdown && !self.isOpen) {\n\t        self.open();\n\t        self.scrollToOption(active_option, 'auto');\n\t      }\n\n\t      self.setActiveOption(active_option);\n\t    } else {\n\t      self.clearActiveOption();\n\n\t      if (triggerDropdown && self.isOpen) {\n\t        self.close(false); // if create_option=null, we want the dropdown to close but not reset the textbox value\n\t      }\n\t    }\n\t  }\n\t  /**\n\t   * Return list of selectable options\n\t   *\n\t   */\n\n\n\t  selectable() {\n\t    return this.dropdown_content.querySelectorAll('[data-selectable]');\n\t  }\n\t  /**\n\t   * Adds an available option. If it already exists,\n\t   * nothing will happen. Note: this does not refresh\n\t   * the options list dropdown (use `refreshOptions`\n\t   * for that).\n\t   *\n\t   * Usage:\n\t   *\n\t   *   this.addOption(data)\n\t   *\n\t   */\n\n\n\t  addOption(data, user_created = false) {\n\t    const self = this; // @deprecated 1.7.7\n\t    // use addOptions( array, user_created ) for adding multiple options\n\n\t    if (Array.isArray(data)) {\n\t      self.addOptions(data, user_created);\n\t      return false;\n\t    }\n\n\t    const key = hash_key(data[self.settings.valueField]);\n\n\t    if (key === null || self.options.hasOwnProperty(key)) {\n\t      return false;\n\t    }\n\n\t    data.$order = data.$order || ++self.order;\n\t    data.$id = self.inputId + '-opt-' + data.$order;\n\t    self.options[key] = data;\n\t    self.lastQuery = null;\n\n\t    if (user_created) {\n\t      self.userOptions[key] = user_created;\n\t      self.trigger('option_add', key, data);\n\t    }\n\n\t    return key;\n\t  }\n\t  /**\n\t   * Add multiple options\n\t   *\n\t   */\n\n\n\t  addOptions(data, user_created = false) {\n\t    iterate$1(data, dat => {\n\t      this.addOption(dat, user_created);\n\t    });\n\t  }\n\t  /**\n\t   * @deprecated 1.7.7\n\t   */\n\n\n\t  registerOption(data) {\n\t    return this.addOption(data);\n\t  }\n\t  /**\n\t   * Registers an option group to the pool of option groups.\n\t   *\n\t   * @return {boolean|string}\n\t   */\n\n\n\t  registerOptionGroup(data) {\n\t    var key = hash_key(data[this.settings.optgroupValueField]);\n\t    if (key === null) return false;\n\t    data.$order = data.$order || ++this.order;\n\t    this.optgroups[key] = data;\n\t    return key;\n\t  }\n\t  /**\n\t   * Registers a new optgroup for options\n\t   * to be bucketed into.\n\t   *\n\t   */\n\n\n\t  addOptionGroup(id, data) {\n\t    var hashed_id;\n\t    data[this.settings.optgroupValueField] = id;\n\n\t    if (hashed_id = this.registerOptionGroup(data)) {\n\t      this.trigger('optgroup_add', hashed_id, data);\n\t    }\n\t  }\n\t  /**\n\t   * Removes an existing option group.\n\t   *\n\t   */\n\n\n\t  removeOptionGroup(id) {\n\t    if (this.optgroups.hasOwnProperty(id)) {\n\t      delete this.optgroups[id];\n\t      this.clearCache();\n\t      this.trigger('optgroup_remove', id);\n\t    }\n\t  }\n\t  /**\n\t   * Clears all existing option groups.\n\t   */\n\n\n\t  clearOptionGroups() {\n\t    this.optgroups = {};\n\t    this.clearCache();\n\t    this.trigger('optgroup_clear');\n\t  }\n\t  /**\n\t   * Updates an option available for selection. If\n\t   * it is visible in the selected items or options\n\t   * dropdown, it will be re-rendered automatically.\n\t   *\n\t   */\n\n\n\t  updateOption(value, data) {\n\t    const self = this;\n\t    var item_new;\n\t    var index_item;\n\t    const value_old = hash_key(value);\n\t    const value_new = hash_key(data[self.settings.valueField]); // sanity checks\n\n\t    if (value_old === null) return;\n\t    const data_old = self.options[value_old];\n\t    if (data_old == undefined) return;\n\t    if (typeof value_new !== 'string') throw new Error('Value must be set in option data');\n\t    const option = self.getOption(value_old);\n\t    const item = self.getItem(value_old);\n\t    data.$order = data.$order || data_old.$order;\n\t    delete self.options[value_old]; // invalidate render cache\n\t    // don't remove existing node yet, we'll remove it after replacing it\n\n\t    self.uncacheValue(value_new);\n\t    self.options[value_new] = data; // update the option if it's in the dropdown\n\n\t    if (option) {\n\t      if (self.dropdown_content.contains(option)) {\n\t        const option_new = self._render('option', data);\n\n\t        replaceNode(option, option_new);\n\n\t        if (self.activeOption === option) {\n\t          self.setActiveOption(option_new);\n\t        }\n\t      }\n\n\t      option.remove();\n\t    } // update the item if we have one\n\n\n\t    if (item) {\n\t      index_item = self.items.indexOf(value_old);\n\n\t      if (index_item !== -1) {\n\t        self.items.splice(index_item, 1, value_new);\n\t      }\n\n\t      item_new = self._render('item', data);\n\t      if (item.classList.contains('active')) addClasses(item_new, 'active');\n\t      replaceNode(item, item_new);\n\t    } // invalidate last query because we might have updated the sortField\n\n\n\t    self.lastQuery = null;\n\t  }\n\t  /**\n\t   * Removes a single option.\n\t   *\n\t   */\n\n\n\t  removeOption(value, silent) {\n\t    const self = this;\n\t    value = get_hash(value);\n\t    self.uncacheValue(value);\n\t    delete self.userOptions[value];\n\t    delete self.options[value];\n\t    self.lastQuery = null;\n\t    self.trigger('option_remove', value);\n\t    self.removeItem(value, silent);\n\t  }\n\t  /**\n\t   * Clears all options.\n\t   */\n\n\n\t  clearOptions(filter) {\n\t    const boundFilter = (filter || this.clearFilter).bind(this);\n\t    this.loadedSearches = {};\n\t    this.userOptions = {};\n\t    this.clearCache();\n\t    const selected = {};\n\t    iterate$1(this.options, (option, key) => {\n\t      if (boundFilter(option, key)) {\n\t        selected[key] = option;\n\t      }\n\t    });\n\t    this.options = this.sifter.items = selected;\n\t    this.lastQuery = null;\n\t    this.trigger('option_clear');\n\t  }\n\t  /**\n\t   * Used by clearOptions() to decide whether or not an option should be removed\n\t   * Return true to keep an option, false to remove\n\t   *\n\t   */\n\n\n\t  clearFilter(option, value) {\n\t    if (this.items.indexOf(value) >= 0) {\n\t      return true;\n\t    }\n\n\t    return false;\n\t  }\n\t  /**\n\t   * Returns the dom element of the option\n\t   * matching the given value.\n\t   *\n\t   */\n\n\n\t  getOption(value, create = false) {\n\t    const hashed = hash_key(value);\n\t    if (hashed === null) return null;\n\t    const option = this.options[hashed];\n\n\t    if (option != undefined) {\n\t      if (option.$div) {\n\t        return option.$div;\n\t      }\n\n\t      if (create) {\n\t        return this._render('option', option);\n\t      }\n\t    }\n\n\t    return null;\n\t  }\n\t  /**\n\t   * Returns the dom element of the next or previous dom element of the same type\n\t   * Note: adjacent options may not be adjacent DOM elements (optgroups)\n\t   *\n\t   */\n\n\n\t  getAdjacent(option, direction, type = 'option') {\n\t    var self = this,\n\t        all;\n\n\t    if (!option) {\n\t      return null;\n\t    }\n\n\t    if (type == 'item') {\n\t      all = self.controlChildren();\n\t    } else {\n\t      all = self.dropdown_content.querySelectorAll('[data-selectable]');\n\t    }\n\n\t    for (let i = 0; i < all.length; i++) {\n\t      if (all[i] != option) {\n\t        continue;\n\t      }\n\n\t      if (direction > 0) {\n\t        return all[i + 1];\n\t      }\n\n\t      return all[i - 1];\n\t    }\n\n\t    return null;\n\t  }\n\t  /**\n\t   * Returns the dom element of the item\n\t   * matching the given value.\n\t   *\n\t   */\n\n\n\t  getItem(item) {\n\t    if (typeof item == 'object') {\n\t      return item;\n\t    }\n\n\t    var value = hash_key(item);\n\t    return value !== null ? this.control.querySelector(`[data-value=\"${addSlashes(value)}\"]`) : null;\n\t  }\n\t  /**\n\t   * \"Selects\" multiple items at once. Adds them to the list\n\t   * at the current caret position.\n\t   *\n\t   */\n\n\n\t  addItems(values, silent) {\n\t    var self = this;\n\t    var items = Array.isArray(values) ? values : [values];\n\t    items = items.filter(x => self.items.indexOf(x) === -1);\n\t    const last_item = items[items.length - 1];\n\t    items.forEach(item => {\n\t      self.isPending = item !== last_item;\n\t      self.addItem(item, silent);\n\t    });\n\t  }\n\t  /**\n\t   * \"Selects\" an item. Adds it to the list\n\t   * at the current caret position.\n\t   *\n\t   */\n\n\n\t  addItem(value, silent) {\n\t    var events = silent ? [] : ['change', 'dropdown_close'];\n\t    debounce_events(this, events, () => {\n\t      var item, wasFull;\n\t      const self = this;\n\t      const inputMode = self.settings.mode;\n\t      const hashed = hash_key(value);\n\n\t      if (hashed && self.items.indexOf(hashed) !== -1) {\n\t        if (inputMode === 'single') {\n\t          self.close();\n\t        }\n\n\t        if (inputMode === 'single' || !self.settings.duplicates) {\n\t          return;\n\t        }\n\t      }\n\n\t      if (hashed === null || !self.options.hasOwnProperty(hashed)) return;\n\t      if (inputMode === 'single') self.clear(silent);\n\t      if (inputMode === 'multi' && self.isFull()) return;\n\t      item = self._render('item', self.options[hashed]);\n\n\t      if (self.control.contains(item)) {\n\t        // duplicates\n\t        item = item.cloneNode(true);\n\t      }\n\n\t      wasFull = self.isFull();\n\t      self.items.splice(self.caretPos, 0, hashed);\n\t      self.insertAtCaret(item);\n\n\t      if (self.isSetup) {\n\t        // update menu / remove the option (if this is not one item being added as part of series)\n\t        if (!self.isPending && self.settings.hideSelected) {\n\t          let option = self.getOption(hashed);\n\t          let next = self.getAdjacent(option, 1);\n\n\t          if (next) {\n\t            self.setActiveOption(next);\n\t          }\n\t        } // refreshOptions after setActiveOption(),\n\t        // otherwise setActiveOption() will be called by refreshOptions() with the wrong value\n\n\n\t        if (!self.isPending && !self.settings.closeAfterSelect) {\n\t          self.refreshOptions(self.isFocused && inputMode !== 'single');\n\t        } // hide the menu if the maximum number of items have been selected or no options are left\n\n\n\t        if (self.settings.closeAfterSelect != false && self.isFull()) {\n\t          self.close();\n\t        } else if (!self.isPending) {\n\t          self.positionDropdown();\n\t        }\n\n\t        self.trigger('item_add', hashed, item);\n\n\t        if (!self.isPending) {\n\t          self.updateOriginalInput({\n\t            silent: silent\n\t          });\n\t        }\n\t      }\n\n\t      if (!self.isPending || !wasFull && self.isFull()) {\n\t        self.inputState();\n\t        self.refreshState();\n\t      }\n\t    });\n\t  }\n\t  /**\n\t   * Removes the selected item matching\n\t   * the provided value.\n\t   *\n\t   */\n\n\n\t  removeItem(item = null, silent) {\n\t    const self = this;\n\t    item = self.getItem(item);\n\t    if (!item) return;\n\t    var i, idx;\n\t    const value = item.dataset.value;\n\t    i = nodeIndex(item);\n\t    item.remove();\n\n\t    if (item.classList.contains('active')) {\n\t      idx = self.activeItems.indexOf(item);\n\t      self.activeItems.splice(idx, 1);\n\t      removeClasses(item, 'active');\n\t    }\n\n\t    self.items.splice(i, 1);\n\t    self.lastQuery = null;\n\n\t    if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {\n\t      self.removeOption(value, silent);\n\t    }\n\n\t    if (i < self.caretPos) {\n\t      self.setCaret(self.caretPos - 1);\n\t    }\n\n\t    self.updateOriginalInput({\n\t      silent: silent\n\t    });\n\t    self.refreshState();\n\t    self.positionDropdown();\n\t    self.trigger('item_remove', value, item);\n\t  }\n\t  /**\n\t   * Invokes the `create` method provided in the\n\t   * TomSelect options that should provide the data\n\t   * for the new item, given the user input.\n\t   *\n\t   * Once this completes, it will be added\n\t   * to the item list.\n\t   *\n\t   */\n\n\n\t  createItem(input = null, callback = () => {}) {\n\t    // triggerDropdown parameter @deprecated 2.1.1\n\t    if (arguments.length === 3) {\n\t      callback = arguments[2];\n\t    }\n\n\t    if (typeof callback != 'function') {\n\t      callback = () => {};\n\t    }\n\n\t    var self = this;\n\t    var caret = self.caretPos;\n\t    var output;\n\t    input = input || self.inputValue();\n\n\t    if (!self.canCreate(input)) {\n\t      callback();\n\t      return false;\n\t    }\n\n\t    self.lock();\n\t    var created = false;\n\n\t    var create = data => {\n\t      self.unlock();\n\t      if (!data || typeof data !== 'object') return callback();\n\t      var value = hash_key(data[self.settings.valueField]);\n\n\t      if (typeof value !== 'string') {\n\t        return callback();\n\t      }\n\n\t      self.setTextboxValue();\n\t      self.addOption(data, true);\n\t      self.setCaret(caret);\n\t      self.addItem(value);\n\t      callback(data);\n\t      created = true;\n\t    };\n\n\t    if (typeof self.settings.create === 'function') {\n\t      output = self.settings.create.call(this, input, create);\n\t    } else {\n\t      output = {\n\t        [self.settings.labelField]: input,\n\t        [self.settings.valueField]: input\n\t      };\n\t    }\n\n\t    if (!created) {\n\t      create(output);\n\t    }\n\n\t    return true;\n\t  }\n\t  /**\n\t   * Re-renders the selected item lists.\n\t   */\n\n\n\t  refreshItems() {\n\t    var self = this;\n\t    self.lastQuery = null;\n\n\t    if (self.isSetup) {\n\t      self.addItems(self.items);\n\t    }\n\n\t    self.updateOriginalInput();\n\t    self.refreshState();\n\t  }\n\t  /**\n\t   * Updates all state-dependent attributes\n\t   * and CSS classes.\n\t   */\n\n\n\t  refreshState() {\n\t    const self = this;\n\t    self.refreshValidityState();\n\t    const isFull = self.isFull();\n\t    const isLocked = self.isLocked;\n\t    self.wrapper.classList.toggle('rtl', self.rtl);\n\t    const wrap_classList = self.wrapper.classList;\n\t    wrap_classList.toggle('focus', self.isFocused);\n\t    wrap_classList.toggle('disabled', self.isDisabled);\n\t    wrap_classList.toggle('required', self.isRequired);\n\t    wrap_classList.toggle('invalid', !self.isValid);\n\t    wrap_classList.toggle('locked', isLocked);\n\t    wrap_classList.toggle('full', isFull);\n\t    wrap_classList.toggle('input-active', self.isFocused && !self.isInputHidden);\n\t    wrap_classList.toggle('dropdown-active', self.isOpen);\n\t    wrap_classList.toggle('has-options', isEmptyObject(self.options));\n\t    wrap_classList.toggle('has-items', self.items.length > 0);\n\t  }\n\t  /**\n\t   * Update the `required` attribute of both input and control input.\n\t   *\n\t   * The `required` property needs to be activated on the control input\n\t   * for the error to be displayed at the right place. `required` also\n\t   * needs to be temporarily deactivated on the input since the input is\n\t   * hidden and can't show errors.\n\t   */\n\n\n\t  refreshValidityState() {\n\t    var self = this;\n\n\t    if (!self.input.validity) {\n\t      return;\n\t    }\n\n\t    self.isValid = self.input.validity.valid;\n\t    self.isInvalid = !self.isValid;\n\t  }\n\t  /**\n\t   * Determines whether or not more items can be added\n\t   * to the control without exceeding the user-defined maximum.\n\t   *\n\t   * @returns {boolean}\n\t   */\n\n\n\t  isFull() {\n\t    return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems;\n\t  }\n\t  /**\n\t   * Refreshes the original <select> or <input>\n\t   * element to reflect the current state.\n\t   *\n\t   */\n\n\n\t  updateOriginalInput(opts = {}) {\n\t    const self = this;\n\t    var option, label;\n\t    const empty_option = self.input.querySelector('option[value=\"\"]');\n\n\t    if (self.is_select_tag) {\n\t      const selected = [];\n\t      const has_selected = self.input.querySelectorAll('option:checked').length;\n\n\t      function AddSelected(option_el, value, label) {\n\t        if (!option_el) {\n\t          option_el = getDom('<option value=\"' + escape_html(value) + '\">' + escape_html(label) + '</option>');\n\t        } // don't move empty option from top of list\n\t        // fixes bug in firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1725293\n\n\n\t        if (option_el != empty_option) {\n\t          self.input.append(option_el);\n\t        }\n\n\t        selected.push(option_el); // marking empty option as selected can break validation\n\t        // fixes https://github.com/orchidjs/tom-select/issues/303\n\n\t        if (option_el != empty_option || has_selected > 0) {\n\t          option_el.selected = true;\n\t        }\n\n\t        return option_el;\n\t      } // unselect all selected options\n\n\n\t      self.input.querySelectorAll('option:checked').forEach(option_el => {\n\t        option_el.selected = false;\n\t      }); // nothing selected?\n\n\t      if (self.items.length == 0 && self.settings.mode == 'single') {\n\t        AddSelected(empty_option, \"\", \"\"); // order selected <option> tags for values in self.items\n\t      } else {\n\t        self.items.forEach(value => {\n\t          option = self.options[value];\n\t          label = option[self.settings.labelField] || '';\n\n\t          if (selected.includes(option.$option)) {\n\t            const reuse_opt = self.input.querySelector(`option[value=\"${addSlashes(value)}\"]:not(:checked)`);\n\t            AddSelected(reuse_opt, value, label);\n\t          } else {\n\t            option.$option = AddSelected(option.$option, value, label);\n\t          }\n\t        });\n\t      }\n\t    } else {\n\t      self.input.value = self.getValue();\n\t    }\n\n\t    if (self.isSetup) {\n\t      if (!opts.silent) {\n\t        self.trigger('change', self.getValue());\n\t      }\n\t    }\n\t  }\n\t  /**\n\t   * Shows the autocomplete dropdown containing\n\t   * the available options.\n\t   */\n\n\n\t  open() {\n\t    var self = this;\n\t    if (self.isLocked || self.isOpen || self.settings.mode === 'multi' && self.isFull()) return;\n\t    self.isOpen = true;\n\t    setAttr(self.focus_node, {\n\t      'aria-expanded': 'true'\n\t    });\n\t    self.refreshState();\n\t    applyCSS(self.dropdown, {\n\t      visibility: 'hidden',\n\t      display: 'block'\n\t    });\n\t    self.positionDropdown();\n\t    applyCSS(self.dropdown, {\n\t      visibility: 'visible',\n\t      display: 'block'\n\t    });\n\t    self.focus();\n\t    self.trigger('dropdown_open', self.dropdown);\n\t  }\n\t  /**\n\t   * Closes the autocomplete dropdown menu.\n\t   */\n\n\n\t  close(setTextboxValue = true) {\n\t    var self = this;\n\t    var trigger = self.isOpen;\n\n\t    if (setTextboxValue) {\n\t      // before blur() to prevent form onchange event\n\t      self.setTextboxValue();\n\n\t      if (self.settings.mode === 'single' && self.items.length) {\n\t        self.hideInput();\n\t      }\n\t    }\n\n\t    self.isOpen = false;\n\t    setAttr(self.focus_node, {\n\t      'aria-expanded': 'false'\n\t    });\n\t    applyCSS(self.dropdown, {\n\t      display: 'none'\n\t    });\n\n\t    if (self.settings.hideSelected) {\n\t      self.clearActiveOption();\n\t    }\n\n\t    self.refreshState();\n\t    if (trigger) self.trigger('dropdown_close', self.dropdown);\n\t  }\n\t  /**\n\t   * Calculates and applies the appropriate\n\t   * position of the dropdown if dropdownParent = 'body'.\n\t   * Otherwise, position is determined by css\n\t   */\n\n\n\t  positionDropdown() {\n\t    if (this.settings.dropdownParent !== 'body') {\n\t      return;\n\t    }\n\n\t    var context = this.control;\n\t    var rect = context.getBoundingClientRect();\n\t    var top = context.offsetHeight + rect.top + window.scrollY;\n\t    var left = rect.left + window.scrollX;\n\t    applyCSS(this.dropdown, {\n\t      width: rect.width + 'px',\n\t      top: top + 'px',\n\t      left: left + 'px'\n\t    });\n\t  }\n\t  /**\n\t   * Resets / clears all selected items\n\t   * from the control.\n\t   *\n\t   */\n\n\n\t  clear(silent) {\n\t    var self = this;\n\t    if (!self.items.length) return;\n\t    var items = self.controlChildren();\n\t    iterate$1(items, item => {\n\t      self.removeItem(item, true);\n\t    });\n\t    self.showInput();\n\t    if (!silent) self.updateOriginalInput();\n\t    self.trigger('clear');\n\t  }\n\t  /**\n\t   * A helper method for inserting an element\n\t   * at the current caret position.\n\t   *\n\t   */\n\n\n\t  insertAtCaret(el) {\n\t    const self = this;\n\t    const caret = self.caretPos;\n\t    const target = self.control;\n\t    target.insertBefore(el, target.children[caret] || null);\n\t    self.setCaret(caret + 1);\n\t  }\n\t  /**\n\t   * Removes the current selected item(s).\n\t   *\n\t   */\n\n\n\t  deleteSelection(e) {\n\t    var direction, selection, caret, tail;\n\t    var self = this;\n\t    direction = e && e.keyCode === KEY_BACKSPACE ? -1 : 1;\n\t    selection = getSelection(self.control_input); // determine items that will be removed\n\n\t    const rm_items = [];\n\n\t    if (self.activeItems.length) {\n\t      tail = getTail(self.activeItems, direction);\n\t      caret = nodeIndex(tail);\n\n\t      if (direction > 0) {\n\t        caret++;\n\t      }\n\n\t      iterate$1(self.activeItems, item => rm_items.push(item));\n\t    } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) {\n\t      const items = self.controlChildren();\n\t      let rm_item;\n\n\t      if (direction < 0 && selection.start === 0 && selection.length === 0) {\n\t        rm_item = items[self.caretPos - 1];\n\t      } else if (direction > 0 && selection.start === self.inputValue().length) {\n\t        rm_item = items[self.caretPos];\n\t      }\n\n\t      if (rm_item !== undefined) {\n\t        rm_items.push(rm_item);\n\t      }\n\t    }\n\n\t    if (!self.shouldDelete(rm_items, e)) {\n\t      return false;\n\t    }\n\n\t    preventDefault(e, true); // perform removal\n\n\t    if (typeof caret !== 'undefined') {\n\t      self.setCaret(caret);\n\t    }\n\n\t    while (rm_items.length) {\n\t      self.removeItem(rm_items.pop());\n\t    }\n\n\t    self.showInput();\n\t    self.positionDropdown();\n\t    self.refreshOptions(false);\n\t    return true;\n\t  }\n\t  /**\n\t   * Return true if the items should be deleted\n\t   */\n\n\n\t  shouldDelete(items, evt) {\n\t    const values = items.map(item => item.dataset.value); // allow the callback to abort\n\n\t    if (!values.length || typeof this.settings.onDelete === 'function' && this.settings.onDelete(values, evt) === false) {\n\t      return false;\n\t    }\n\n\t    return true;\n\t  }\n\t  /**\n\t   * Selects the previous / next item (depending on the `direction` argument).\n\t   *\n\t   * > 0 - right\n\t   * < 0 - left\n\t   *\n\t   */\n\n\n\t  advanceSelection(direction, e) {\n\t    var last_active,\n\t        adjacent,\n\t        self = this;\n\t    if (self.rtl) direction *= -1;\n\t    if (self.inputValue().length) return; // add or remove to active items\n\n\t    if (isKeyDown(KEY_SHORTCUT, e) || isKeyDown('shiftKey', e)) {\n\t      last_active = self.getLastActive(direction);\n\n\t      if (last_active) {\n\t        if (!last_active.classList.contains('active')) {\n\t          adjacent = last_active;\n\t        } else {\n\t          adjacent = self.getAdjacent(last_active, direction, 'item');\n\t        } // if no active item, get items adjacent to the control input\n\n\t      } else if (direction > 0) {\n\t        adjacent = self.control_input.nextElementSibling;\n\t      } else {\n\t        adjacent = self.control_input.previousElementSibling;\n\t      }\n\n\t      if (adjacent) {\n\t        if (adjacent.classList.contains('active')) {\n\t          self.removeActiveItem(last_active);\n\t        }\n\n\t        self.setActiveItemClass(adjacent); // mark as last_active !! after removeActiveItem() on last_active\n\t      } // move caret to the left or right\n\n\t    } else {\n\t      self.moveCaret(direction);\n\t    }\n\t  }\n\n\t  moveCaret(direction) {}\n\t  /**\n\t   * Get the last active item\n\t   *\n\t   */\n\n\n\t  getLastActive(direction) {\n\t    let last_active = this.control.querySelector('.last-active');\n\n\t    if (last_active) {\n\t      return last_active;\n\t    }\n\n\t    var result = this.control.querySelectorAll('.active');\n\n\t    if (result) {\n\t      return getTail(result, direction);\n\t    }\n\t  }\n\t  /**\n\t   * Moves the caret to the specified index.\n\t   *\n\t   * The input must be moved by leaving it in place and moving the\n\t   * siblings, due to the fact that focus cannot be restored once lost\n\t   * on mobile webkit devices\n\t   *\n\t   */\n\n\n\t  setCaret(new_pos) {\n\t    this.caretPos = this.items.length;\n\t  }\n\t  /**\n\t   * Return list of item dom elements\n\t   *\n\t   */\n\n\n\t  controlChildren() {\n\t    return Array.from(this.control.querySelectorAll('[data-ts-item]'));\n\t  }\n\t  /**\n\t   * Disables user input on the control. Used while\n\t   * items are being asynchronously created.\n\t   */\n\n\n\t  lock() {\n\t    this.isLocked = true;\n\t    this.refreshState();\n\t  }\n\t  /**\n\t   * Re-enables user input on the control.\n\t   */\n\n\n\t  unlock() {\n\t    this.isLocked = false;\n\t    this.refreshState();\n\t  }\n\t  /**\n\t   * Disables user input on the control completely.\n\t   * While disabled, it cannot receive focus.\n\t   */\n\n\n\t  disable() {\n\t    var self = this;\n\t    self.input.disabled = true;\n\t    self.control_input.disabled = true;\n\t    self.focus_node.tabIndex = -1;\n\t    self.isDisabled = true;\n\t    this.close();\n\t    self.lock();\n\t  }\n\t  /**\n\t   * Enables the control so that it can respond\n\t   * to focus and user input.\n\t   */\n\n\n\t  enable() {\n\t    var self = this;\n\t    self.input.disabled = false;\n\t    self.control_input.disabled = false;\n\t    self.focus_node.tabIndex = self.tabIndex;\n\t    self.isDisabled = false;\n\t    self.unlock();\n\t  }\n\t  /**\n\t   * Completely destroys the control and\n\t   * unbinds all event listeners so that it can\n\t   * be garbage collected.\n\t   */\n\n\n\t  destroy() {\n\t    var self = this;\n\t    var revertSettings = self.revertSettings;\n\t    self.trigger('destroy');\n\t    self.off();\n\t    self.wrapper.remove();\n\t    self.dropdown.remove();\n\t    self.input.innerHTML = revertSettings.innerHTML;\n\t    self.input.tabIndex = revertSettings.tabIndex;\n\t    removeClasses(self.input, 'tomselected', 'ts-hidden-accessible');\n\n\t    self._destroy();\n\n\t    delete self.input.tomselect;\n\t  }\n\t  /**\n\t   * A helper method for rendering \"item\" and\n\t   * \"option\" templates, given the data.\n\t   *\n\t   */\n\n\n\t  render(templateName, data) {\n\t    var id, html;\n\t    const self = this;\n\n\t    if (typeof this.settings.render[templateName] !== 'function') {\n\t      return null;\n\t    } // render markup\n\n\n\t    html = self.settings.render[templateName].call(this, data, escape_html);\n\n\t    if (!html) {\n\t      return null;\n\t    }\n\n\t    html = getDom(html); // add mandatory attributes\n\n\t    if (templateName === 'option' || templateName === 'option_create') {\n\t      if (data[self.settings.disabledField]) {\n\t        setAttr(html, {\n\t          'aria-disabled': 'true'\n\t        });\n\t      } else {\n\t        setAttr(html, {\n\t          'data-selectable': ''\n\t        });\n\t      }\n\t    } else if (templateName === 'optgroup') {\n\t      id = data.group[self.settings.optgroupValueField];\n\t      setAttr(html, {\n\t        'data-group': id\n\t      });\n\n\t      if (data.group[self.settings.disabledField]) {\n\t        setAttr(html, {\n\t          'data-disabled': ''\n\t        });\n\t      }\n\t    }\n\n\t    if (templateName === 'option' || templateName === 'item') {\n\t      const value = get_hash(data[self.settings.valueField]);\n\t      setAttr(html, {\n\t        'data-value': value\n\t      }); // make sure we have some classes if a template is overwritten\n\n\t      if (templateName === 'item') {\n\t        addClasses(html, self.settings.itemClass);\n\t        setAttr(html, {\n\t          'data-ts-item': ''\n\t        });\n\t      } else {\n\t        addClasses(html, self.settings.optionClass);\n\t        setAttr(html, {\n\t          role: 'option',\n\t          id: data.$id\n\t        }); // update cache\n\n\t        data.$div = html;\n\t        self.options[value] = data;\n\t      }\n\t    }\n\n\t    return html;\n\t  }\n\t  /**\n\t   * Type guarded rendering\n\t   *\n\t   */\n\n\n\t  _render(templateName, data) {\n\t    const html = this.render(templateName, data);\n\n\t    if (html == null) {\n\t      throw 'HTMLElement expected';\n\t    }\n\n\t    return html;\n\t  }\n\t  /**\n\t   * Clears the render cache for a template. If\n\t   * no template is given, clears all render\n\t   * caches.\n\t   *\n\t   */\n\n\n\t  clearCache() {\n\t    iterate$1(this.options, option => {\n\t      if (option.$div) {\n\t        option.$div.remove();\n\t        delete option.$div;\n\t      }\n\t    });\n\t  }\n\t  /**\n\t   * Removes a value from item and option caches\n\t   *\n\t   */\n\n\n\t  uncacheValue(value) {\n\t    const option_el = this.getOption(value);\n\t    if (option_el) option_el.remove();\n\t  }\n\t  /**\n\t   * Determines whether or not to display the\n\t   * create item prompt, given a user input.\n\t   *\n\t   */\n\n\n\t  canCreate(input) {\n\t    return this.settings.create && input.length > 0 && this.settings.createFilter.call(this, input);\n\t  }\n\t  /**\n\t   * Wraps this.`method` so that `new_fn` can be invoked 'before', 'after', or 'instead' of the original method\n\t   *\n\t   * this.hook('instead','onKeyDown',function( arg1, arg2 ...){\n\t   *\n\t   * });\n\t   */\n\n\n\t  hook(when, method, new_fn) {\n\t    var self = this;\n\t    var orig_method = self[method];\n\n\t    self[method] = function () {\n\t      var result, result_new;\n\n\t      if (when === 'after') {\n\t        result = orig_method.apply(self, arguments);\n\t      }\n\n\t      result_new = new_fn.apply(self, arguments);\n\n\t      if (when === 'instead') {\n\t        return result_new;\n\t      }\n\n\t      if (when === 'before') {\n\t        result = orig_method.apply(self, arguments);\n\t      }\n\n\t      return result;\n\t    };\n\t  }\n\n\t}\n\n\t/**\n\t * Plugin: \"change_listener\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction change_listener () {\n\t  addEvent(this.input, 'change', () => {\n\t    this.sync();\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"restore_on_backspace\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction checkbox_options () {\n\t  var self = this;\n\t  var orig_onOptionSelect = self.onOptionSelect;\n\t  self.settings.hideSelected = false; // update the checkbox for an option\n\n\t  var UpdateCheckbox = function UpdateCheckbox(option) {\n\t    setTimeout(() => {\n\t      var checkbox = option.querySelector('input');\n\n\t      if (checkbox instanceof HTMLInputElement) {\n\t        if (option.classList.contains('selected')) {\n\t          checkbox.checked = true;\n\t        } else {\n\t          checkbox.checked = false;\n\t        }\n\t      }\n\t    }, 1);\n\t  }; // add checkbox to option template\n\n\n\t  self.hook('after', 'setupTemplates', () => {\n\t    var orig_render_option = self.settings.render.option;\n\n\t    self.settings.render.option = (data, escape_html) => {\n\t      var rendered = getDom(orig_render_option.call(self, data, escape_html));\n\t      var checkbox = document.createElement('input');\n\t      checkbox.addEventListener('click', function (evt) {\n\t        preventDefault(evt);\n\t      });\n\t      checkbox.type = 'checkbox';\n\t      const hashed = hash_key(data[self.settings.valueField]);\n\n\t      if (hashed && self.items.indexOf(hashed) > -1) {\n\t        checkbox.checked = true;\n\t      }\n\n\t      rendered.prepend(checkbox);\n\t      return rendered;\n\t    };\n\t  }); // uncheck when item removed\n\n\t  self.on('item_remove', value => {\n\t    var option = self.getOption(value);\n\n\t    if (option) {\n\t      // if dropdown hasn't been opened yet, the option won't exist\n\t      option.classList.remove('selected'); // selected class won't be removed yet\n\n\t      UpdateCheckbox(option);\n\t    }\n\t  }); // check when item added\n\n\t  self.on('item_add', value => {\n\t    var option = self.getOption(value);\n\n\t    if (option) {\n\t      // if dropdown hasn't been opened yet, the option won't exist\n\t      UpdateCheckbox(option);\n\t    }\n\t  }); // remove items when selected option is clicked\n\n\t  self.hook('instead', 'onOptionSelect', (evt, option) => {\n\t    if (option.classList.contains('selected')) {\n\t      option.classList.remove('selected');\n\t      self.removeItem(option.dataset.value);\n\t      self.refreshOptions();\n\t      preventDefault(evt, true);\n\t      return;\n\t    }\n\n\t    orig_onOptionSelect.call(self, evt, option);\n\t    UpdateCheckbox(option);\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"dropdown_header\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction clear_button (userOptions) {\n\t  const self = this;\n\t  const options = Object.assign({\n\t    className: 'clear-button',\n\t    title: 'Clear All',\n\t    html: data => {\n\t      return `<div class=\"${data.className}\" title=\"${data.title}\">&#10799;</div>`;\n\t    }\n\t  }, userOptions);\n\t  self.on('initialize', () => {\n\t    var button = getDom(options.html(options));\n\t    button.addEventListener('click', evt => {\n\t      if (self.isDisabled) {\n\t        return;\n\t      }\n\n\t      self.clear();\n\n\t      if (self.settings.mode === 'single' && self.settings.allowEmptyOption) {\n\t        self.addItem('');\n\t      }\n\n\t      evt.preventDefault();\n\t      evt.stopPropagation();\n\t    });\n\t    self.control.appendChild(button);\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"drag_drop\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction drag_drop () {\n\t  var self = this;\n\t  if (!$.fn.sortable) throw new Error('The \"drag_drop\" plugin requires jQuery UI \"sortable\".');\n\t  if (self.settings.mode !== 'multi') return;\n\t  var orig_lock = self.lock;\n\t  var orig_unlock = self.unlock;\n\t  self.hook('instead', 'lock', () => {\n\t    var sortable = $(self.control).data('sortable');\n\t    if (sortable) sortable.disable();\n\t    return orig_lock.call(self);\n\t  });\n\t  self.hook('instead', 'unlock', () => {\n\t    var sortable = $(self.control).data('sortable');\n\t    if (sortable) sortable.enable();\n\t    return orig_unlock.call(self);\n\t  });\n\t  self.on('initialize', () => {\n\t    var $control = $(self.control).sortable({\n\t      items: '[data-value]',\n\t      forcePlaceholderSize: true,\n\t      disabled: self.isLocked,\n\t      start: (e, ui) => {\n\t        ui.placeholder.css('width', ui.helper.css('width'));\n\t        $control.css({\n\t          overflow: 'visible'\n\t        });\n\t      },\n\t      stop: () => {\n\t        $control.css({\n\t          overflow: 'hidden'\n\t        });\n\t        var values = [];\n\t        $control.children('[data-value]').each(function () {\n\t          if (this.dataset.value) values.push(this.dataset.value);\n\t        });\n\t        self.setValue(values);\n\t      }\n\t    });\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"dropdown_header\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction dropdown_header (userOptions) {\n\t  const self = this;\n\t  const options = Object.assign({\n\t    title: 'Untitled',\n\t    headerClass: 'dropdown-header',\n\t    titleRowClass: 'dropdown-header-title',\n\t    labelClass: 'dropdown-header-label',\n\t    closeClass: 'dropdown-header-close',\n\t    html: data => {\n\t      return '<div class=\"' + data.headerClass + '\">' + '<div class=\"' + data.titleRowClass + '\">' + '<span class=\"' + data.labelClass + '\">' + data.title + '</span>' + '<a class=\"' + data.closeClass + '\">&times;</a>' + '</div>' + '</div>';\n\t    }\n\t  }, userOptions);\n\t  self.on('initialize', () => {\n\t    var header = getDom(options.html(options));\n\t    var close_link = header.querySelector('.' + options.closeClass);\n\n\t    if (close_link) {\n\t      close_link.addEventListener('click', evt => {\n\t        preventDefault(evt, true);\n\t        self.close();\n\t      });\n\t    }\n\n\t    self.dropdown.insertBefore(header, self.dropdown.firstChild);\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"dropdown_input\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction caret_position () {\n\t  var self = this;\n\t  /**\n\t   * Moves the caret to the specified index.\n\t   *\n\t   * The input must be moved by leaving it in place and moving the\n\t   * siblings, due to the fact that focus cannot be restored once lost\n\t   * on mobile webkit devices\n\t   *\n\t   */\n\n\t  self.hook('instead', 'setCaret', new_pos => {\n\t    if (self.settings.mode === 'single' || !self.control.contains(self.control_input)) {\n\t      new_pos = self.items.length;\n\t    } else {\n\t      new_pos = Math.max(0, Math.min(self.items.length, new_pos));\n\n\t      if (new_pos != self.caretPos && !self.isPending) {\n\t        self.controlChildren().forEach((child, j) => {\n\t          if (j < new_pos) {\n\t            self.control_input.insertAdjacentElement('beforebegin', child);\n\t          } else {\n\t            self.control.appendChild(child);\n\t          }\n\t        });\n\t      }\n\t    }\n\n\t    self.caretPos = new_pos;\n\t  });\n\t  self.hook('instead', 'moveCaret', direction => {\n\t    if (!self.isFocused) return; // move caret before or after selected items\n\n\t    const last_active = self.getLastActive(direction);\n\n\t    if (last_active) {\n\t      const idx = nodeIndex(last_active);\n\t      self.setCaret(direction > 0 ? idx + 1 : idx);\n\t      self.setActiveItem();\n\t      removeClasses(last_active, 'last-active'); // move caret left or right of current position\n\t    } else {\n\t      self.setCaret(self.caretPos + direction);\n\t    }\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"dropdown_input\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction dropdown_input () {\n\t  const self = this;\n\t  self.settings.shouldOpen = true; // make sure the input is shown even if there are no options to display in the dropdown\n\n\t  self.hook('before', 'setup', () => {\n\t    self.focus_node = self.control;\n\t    addClasses(self.control_input, 'dropdown-input');\n\t    const div = getDom('<div class=\"dropdown-input-wrap\">');\n\t    div.append(self.control_input);\n\t    self.dropdown.insertBefore(div, self.dropdown.firstChild); // set a placeholder in the select control\n\n\t    const placeholder = getDom('<input class=\"items-placeholder\" tabindex=\"-1\" />');\n\t    placeholder.placeholder = self.settings.placeholder || '';\n\t    self.control.append(placeholder);\n\t  });\n\t  self.on('initialize', () => {\n\t    // set tabIndex on control to -1, otherwise [shift+tab] will put focus right back on control_input\n\t    self.control_input.addEventListener('keydown', evt => {\n\t      //addEvent(self.control_input,'keydown' as const,(evt:KeyboardEvent) =>{\n\t      switch (evt.keyCode) {\n\t        case KEY_ESC:\n\t          if (self.isOpen) {\n\t            preventDefault(evt, true);\n\t            self.close();\n\t          }\n\n\t          self.clearActiveItems();\n\t          return;\n\n\t        case KEY_TAB:\n\t          self.focus_node.tabIndex = -1;\n\t          break;\n\t      }\n\n\t      return self.onKeyDown.call(self, evt);\n\t    });\n\t    self.on('blur', () => {\n\t      self.focus_node.tabIndex = self.isDisabled ? -1 : self.tabIndex;\n\t    }); // give the control_input focus when the dropdown is open\n\n\t    self.on('dropdown_open', () => {\n\t      self.control_input.focus();\n\t    }); // prevent onBlur from closing when focus is on the control_input\n\n\t    const orig_onBlur = self.onBlur;\n\t    self.hook('instead', 'onBlur', evt => {\n\t      if (evt && evt.relatedTarget == self.control_input) return;\n\t      return orig_onBlur.call(self);\n\t    });\n\t    addEvent(self.control_input, 'blur', () => self.onBlur()); // return focus to control to allow further keyboard input\n\n\t    self.hook('before', 'close', () => {\n\t      if (!self.isOpen) return;\n\t      self.focus_node.focus({\n\t        preventScroll: true\n\t      });\n\t    });\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"input_autogrow\" (Tom Select)\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction input_autogrow () {\n\t  var self = this;\n\t  self.on('initialize', () => {\n\t    var test_input = document.createElement('span');\n\t    var control = self.control_input;\n\t    test_input.style.cssText = 'position:absolute; top:-99999px; left:-99999px; width:auto; padding:0; white-space:pre; ';\n\t    self.wrapper.appendChild(test_input);\n\t    var transfer_styles = ['letterSpacing', 'fontSize', 'fontFamily', 'fontWeight', 'textTransform'];\n\n\t    for (const style_name of transfer_styles) {\n\t      // @ts-ignore TS7015 https://stackoverflow.com/a/50506154/697576\n\t      test_input.style[style_name] = control.style[style_name];\n\t    }\n\t    /**\n\t     * Set the control width\n\t     *\n\t     */\n\n\n\t    var resize = () => {\n\t      test_input.textContent = control.value;\n\t      control.style.width = test_input.clientWidth + 'px';\n\t    };\n\n\t    resize();\n\t    self.on('update item_add item_remove', resize);\n\t    addEvent(control, 'input', resize);\n\t    addEvent(control, 'keyup', resize);\n\t    addEvent(control, 'blur', resize);\n\t    addEvent(control, 'update', resize);\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"input_autogrow\" (Tom Select)\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction no_backspace_delete () {\n\t  var self = this;\n\t  var orig_deleteSelection = self.deleteSelection;\n\t  this.hook('instead', 'deleteSelection', evt => {\n\t    if (self.activeItems.length) {\n\t      return orig_deleteSelection.call(self, evt);\n\t    }\n\n\t    return false;\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"no_active_items\" (Tom Select)\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction no_active_items () {\n\t  this.hook('instead', 'setActiveItem', () => {});\n\t  this.hook('instead', 'selectAll', () => {});\n\t}\n\n\t/**\n\t * Plugin: \"optgroup_columns\" (Tom Select.js)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction optgroup_columns () {\n\t  var self = this;\n\t  var orig_keydown = self.onKeyDown;\n\t  self.hook('instead', 'onKeyDown', evt => {\n\t    var index, option, options, optgroup;\n\n\t    if (!self.isOpen || !(evt.keyCode === KEY_LEFT || evt.keyCode === KEY_RIGHT)) {\n\t      return orig_keydown.call(self, evt);\n\t    }\n\n\t    self.ignoreHover = true;\n\t    optgroup = parentMatch(self.activeOption, '[data-group]');\n\t    index = nodeIndex(self.activeOption, '[data-selectable]');\n\n\t    if (!optgroup) {\n\t      return;\n\t    }\n\n\t    if (evt.keyCode === KEY_LEFT) {\n\t      optgroup = optgroup.previousSibling;\n\t    } else {\n\t      optgroup = optgroup.nextSibling;\n\t    }\n\n\t    if (!optgroup) {\n\t      return;\n\t    }\n\n\t    options = optgroup.querySelectorAll('[data-selectable]');\n\t    option = options[Math.min(options.length - 1, index)];\n\n\t    if (option) {\n\t      self.setActiveOption(option);\n\t    }\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"remove_button\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction remove_button (userOptions) {\n\t  const options = Object.assign({\n\t    label: '&times;',\n\t    title: 'Remove',\n\t    className: 'remove',\n\t    append: true\n\t  }, userOptions); //options.className = 'remove-single';\n\n\t  var self = this; // override the render method to add remove button to each item\n\n\t  if (!options.append) {\n\t    return;\n\t  }\n\n\t  var html = '<a href=\"javascript:void(0)\" class=\"' + options.className + '\" tabindex=\"-1\" title=\"' + escape_html(options.title) + '\">' + options.label + '</a>';\n\t  self.hook('after', 'setupTemplates', () => {\n\t    var orig_render_item = self.settings.render.item;\n\n\t    self.settings.render.item = (data, escape) => {\n\t      var item = getDom(orig_render_item.call(self, data, escape));\n\t      var close_button = getDom(html);\n\t      item.appendChild(close_button);\n\t      addEvent(close_button, 'mousedown', evt => {\n\t        preventDefault(evt, true);\n\t      });\n\t      addEvent(close_button, 'click', evt => {\n\t        // propagating will trigger the dropdown to show for single mode\n\t        preventDefault(evt, true);\n\t        if (self.isLocked) return;\n\t        if (!self.shouldDelete([item], evt)) return;\n\t        self.removeItem(item);\n\t        self.refreshOptions(false);\n\t        self.inputState();\n\t      });\n\t      return item;\n\t    };\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"restore_on_backspace\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction restore_on_backspace (userOptions) {\n\t  const self = this;\n\t  const options = Object.assign({\n\t    text: option => {\n\t      return option[self.settings.labelField];\n\t    }\n\t  }, userOptions);\n\t  self.on('item_remove', function (value) {\n\t    if (!self.isFocused) {\n\t      return;\n\t    }\n\n\t    if (self.control_input.value.trim() === '') {\n\t      var option = self.options[value];\n\n\t      if (option) {\n\t        self.setTextboxValue(options.text.call(self, option));\n\t      }\n\t    }\n\t  });\n\t}\n\n\t/**\n\t * Plugin: \"restore_on_backspace\" (Tom Select)\n\t * Copyright (c) contributors\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n\t * file except in compliance with the License. You may obtain a copy of the License at:\n\t * http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software distributed under\n\t * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n\t * ANY KIND, either express or implied. See the License for the specific language\n\t * governing permissions and limitations under the License.\n\t *\n\t */\n\tfunction virtual_scroll () {\n\t  const self = this;\n\t  const orig_canLoad = self.canLoad;\n\t  const orig_clearActiveOption = self.clearActiveOption;\n\t  const orig_loadCallback = self.loadCallback;\n\t  var pagination = {};\n\t  var dropdown_content;\n\t  var loading_more = false;\n\t  var load_more_opt;\n\t  var default_values = [];\n\n\t  if (!self.settings.shouldLoadMore) {\n\t    // return true if additional results should be loaded\n\t    self.settings.shouldLoadMore = () => {\n\t      const scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);\n\n\t      if (scroll_percent > 0.9) {\n\t        return true;\n\t      }\n\n\t      if (self.activeOption) {\n\t        var selectable = self.selectable();\n\t        var index = Array.from(selectable).indexOf(self.activeOption);\n\n\t        if (index >= selectable.length - 2) {\n\t          return true;\n\t        }\n\t      }\n\n\t      return false;\n\t    };\n\t  }\n\n\t  if (!self.settings.firstUrl) {\n\t    throw 'virtual_scroll plugin requires a firstUrl() method';\n\t  } // in order for virtual scrolling to work,\n\t  // options need to be ordered the same way they're returned from the remote data source\n\n\n\t  self.settings.sortField = [{\n\t    field: '$order'\n\t  }, {\n\t    field: '$score'\n\t  }]; // can we load more results for given query?\n\n\t  const canLoadMore = query => {\n\t    if (typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions) {\n\t      return false;\n\t    }\n\n\t    if (query in pagination && pagination[query]) {\n\t      return true;\n\t    }\n\n\t    return false;\n\t  };\n\n\t  const clearFilter = (option, value) => {\n\t    if (self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0) {\n\t      return true;\n\t    }\n\n\t    return false;\n\t  }; // set the next url that will be\n\n\n\t  self.setNextUrl = (value, next_url) => {\n\t    pagination[value] = next_url;\n\t  }; // getUrl() to be used in settings.load()\n\n\n\t  self.getUrl = query => {\n\t    if (query in pagination) {\n\t      const next_url = pagination[query];\n\t      pagination[query] = false;\n\t      return next_url;\n\t    } // if the user goes back to a previous query\n\t    // we need to load the first page again\n\n\n\t    pagination = {};\n\t    return self.settings.firstUrl.call(self, query);\n\t  }; // don't clear the active option (and cause unwanted dropdown scroll)\n\t  // while loading more results\n\n\n\t  self.hook('instead', 'clearActiveOption', () => {\n\t    if (loading_more) {\n\t      return;\n\t    }\n\n\t    return orig_clearActiveOption.call(self);\n\t  }); // override the canLoad method\n\n\t  self.hook('instead', 'canLoad', query => {\n\t    // first time the query has been seen\n\t    if (!(query in pagination)) {\n\t      return orig_canLoad.call(self, query);\n\t    }\n\n\t    return canLoadMore(query);\n\t  }); // wrap the load\n\n\t  self.hook('instead', 'loadCallback', (options, optgroups) => {\n\t    if (!loading_more) {\n\t      self.clearOptions(clearFilter);\n\t    } else if (load_more_opt) {\n\t      const first_option = options[0];\n\n\t      if (first_option !== undefined) {\n\t        load_more_opt.dataset.value = first_option[self.settings.valueField];\n\t      }\n\t    }\n\n\t    orig_loadCallback.call(self, options, optgroups);\n\t    loading_more = false;\n\t  }); // add templates to dropdown\n\t  //\tloading_more if we have another url in the queue\n\t  //\tno_more_results if we don't have another url in the queue\n\n\t  self.hook('after', 'refreshOptions', () => {\n\t    const query = self.lastValue;\n\t    var option;\n\n\t    if (canLoadMore(query)) {\n\t      option = self.render('loading_more', {\n\t        query: query\n\t      });\n\n\t      if (option) {\n\t        option.setAttribute('data-selectable', ''); // so that navigating dropdown with [down] keypresses can navigate to this node\n\n\t        load_more_opt = option;\n\t      }\n\t    } else if (query in pagination && !dropdown_content.querySelector('.no-results')) {\n\t      option = self.render('no_more_results', {\n\t        query: query\n\t      });\n\t    }\n\n\t    if (option) {\n\t      addClasses(option, self.settings.optionClass);\n\t      dropdown_content.append(option);\n\t    }\n\t  }); // add scroll listener and default templates\n\n\t  self.on('initialize', () => {\n\t    default_values = Object.keys(self.options);\n\t    dropdown_content = self.dropdown_content; // default templates\n\n\t    self.settings.render = Object.assign({}, {\n\t      loading_more: () => {\n\t        return `<div class=\"loading-more-results\">Loading more results ... </div>`;\n\t      },\n\t      no_more_results: () => {\n\t        return `<div class=\"no-more-results\">No more results</div>`;\n\t      }\n\t    }, self.settings.render); // watch dropdown content scroll position\n\n\t    dropdown_content.addEventListener('scroll', () => {\n\t      if (!self.settings.shouldLoadMore.call(self)) {\n\t        return;\n\t      } // !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true\n\n\n\t      if (!canLoadMore(self.lastValue)) {\n\t        return;\n\t      } // don't call load() too much\n\n\n\t      if (loading_more) return;\n\t      loading_more = true;\n\t      self.load.call(self, self.lastValue);\n\t    });\n\t  });\n\t}\n\n\tTomSelect.define('change_listener', change_listener);\n\tTomSelect.define('checkbox_options', checkbox_options);\n\tTomSelect.define('clear_button', clear_button);\n\tTomSelect.define('drag_drop', drag_drop);\n\tTomSelect.define('dropdown_header', dropdown_header);\n\tTomSelect.define('caret_position', caret_position);\n\tTomSelect.define('dropdown_input', dropdown_input);\n\tTomSelect.define('input_autogrow', input_autogrow);\n\tTomSelect.define('no_backspace_delete', no_backspace_delete);\n\tTomSelect.define('no_active_items', no_active_items);\n\tTomSelect.define('optgroup_columns', optgroup_columns);\n\tTomSelect.define('remove_button', remove_button);\n\tTomSelect.define('restore_on_backspace', restore_on_backspace);\n\tTomSelect.define('virtual_scroll', virtual_scroll);\n\n\treturn TomSelect;\n\n}));\nvar tomSelect=function(el,opts){return new TomSelect(el,opts);} \n//# sourceMappingURL=tom-select.complete.js.map\n\n\n//# sourceURL=webpack://post-sync/./node_modules/tom-select/dist/js/tom-select.complete.js?");

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			id: moduleId,
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/compat get default export */
/******/ 	(() => {
/******/ 		// getDefaultExport function for compatibility with non-harmony modules
/******/ 		__webpack_require__.n = (module) => {
/******/ 			var getter = module && module.__esModule ?
/******/ 				() => (module['default']) :
/******/ 				() => (module);
/******/ 			__webpack_require__.d(getter, { a: getter });
/******/ 			return getter;
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__webpack_require__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/nonce */
/******/ 	(() => {
/******/ 		__webpack_require__.nc = undefined;
/******/ 	})();
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module can't be inlined because the eval devtool is used.
/******/ 	var __webpack_exports__ = __webpack_require__("./assets/src/js/admin/user-tomselect.js");
/******/ 	
/******/ })()
;