PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.9
4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / assets / js / dist / admin / admin-tools.js

admin-tools.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.9, at assets/js/dist/admin/admin-tools.js

7,039 lines 238.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ var __webpack_modules__ = ({
4
5 /***/ "./assets/src/js/admin/tools/assign-user-course.js"
6 /*!*********************************************************!*\
7 !*** ./assets/src/js/admin/tools/assign-user-course.js ***!
8 \*********************************************************/
9 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
10
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ "default": () => (/* binding */ assignUserCourse)
14 /* harmony export */ });
15 /* harmony import */ var _utils_admin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils-admin.js */ "./assets/src/js/admin/utils-admin.js");
16 /**
17 * Assign user to course
18 *
19 * @since 4.2.5.6
20 * @version 1.0.1
21 */
22
23 function assignUserCourse() {
24 let elFormAssignUserCourse;
25 let elFormUnAssignUserCourse;
26 let elUserUnAssign, elCourseUnAssign, elUserAssign, elCourseAssign;
27 const limitHandle = 5;
28 const getAllElements = () => {
29 elFormAssignUserCourse = document.querySelector('#lp-assign-user-course-form');
30 elFormUnAssignUserCourse = document.querySelector('#lp-unassign-user-course-form');
31 if (elFormAssignUserCourse) {
32 elUserUnAssign = elFormUnAssignUserCourse.querySelector('[name=user_ids]');
33 elCourseUnAssign = elFormUnAssignUserCourse.querySelector('[name=course_ids]');
34 }
35 if (elFormUnAssignUserCourse) {
36 elUserAssign = elFormAssignUserCourse.querySelector('[name=user_ids]');
37 elCourseAssign = elFormAssignUserCourse.querySelector('[name=course_ids]');
38 }
39 };
40 const events = () => {
41 const elForm = document.querySelector('form');
42 if (!elForm) {
43 return;
44 }
45 document.addEventListener('submit', e => {
46 const elForm = e.target;
47 const formData = new FormData(e.target); // Create a FormData object from the form
48
49 // get values of form.
50 const obj = Object.fromEntries(Array.from(formData.keys(), key => {
51 const val = formData.getAll(key);
52 return [key, val.length > 1 ? val : val.pop()];
53 }));
54 if (elForm.id === 'lp-assign-user-course-form') {
55 e.preventDefault();
56 if (!confirm('Are you sure you want to Assign?')) {
57 return;
58 }
59 const {
60 packages,
61 data,
62 totalPage
63 } = handleDataBeforeSend(obj);
64 fetchAPIAssignCourse(packages, data, 1, totalPage);
65 } else if (elForm.id === 'lp-unassign-user-course-form') {
66 e.preventDefault();
67 if (!confirm('Are you sure you want to Unassign?')) {
68 return;
69 }
70 const {
71 packages,
72 data,
73 totalPage
74 } = handleDataBeforeSend(obj);
75 fetchAPIUnAssignCourse(packages, data, 1, totalPage);
76 }
77 });
78 };
79 const handleDataBeforeSend = dataRaw => {
80 // Cut to packages to send, 1 packages has 5 items.
81 let arrCourseIds = [];
82 let arrUserIds = [];
83 if (typeof dataRaw.course_ids === 'string') {
84 arrCourseIds.push(dataRaw.course_ids);
85 } else if (typeof dataRaw.course_ids === 'object') {
86 arrCourseIds = dataRaw.course_ids;
87 }
88 if (typeof dataRaw.user_ids === 'string') {
89 arrUserIds.push(dataRaw.user_ids);
90 } else if (typeof dataRaw.user_ids === 'object') {
91 arrUserIds = dataRaw.user_ids;
92 }
93 const packages = [];
94 arrCourseIds.map((courseId, indexCourse) => {
95 const item = {};
96 item.course_id = courseId;
97 arrUserIds.map((userID, indexUser) => {
98 const newItem = {
99 ...item,
100 user_id: userID
101 };
102 packages.push(newItem);
103 });
104 });
105 const data = packages.slice(0, limitHandle);
106 const totalPage = Math.ceil(packages.length / limitHandle);
107 return {
108 packages,
109 data,
110 totalPage
111 };
112 };
113 const fetchAPIAssignCourse = (packages, data, page, totalPage) => {
114 const url = _utils_admin_js__WEBPACK_IMPORTED_MODULE_0__.Api.admin.apiAssignUserCourse;
115 const params = {
116 headers: {
117 'Content-Type': 'application/json',
118 'X-WP-Nonce': lpDataAdmin.nonce
119 },
120 method: 'POST',
121 body: JSON.stringify({
122 data,
123 page,
124 totalPage
125 })
126 };
127 const elProgress = elFormAssignUserCourse.querySelector('.percent');
128 const elButtonAssign = elFormAssignUserCourse.querySelector('.lp-button-assign-course');
129 const elMessage = elFormAssignUserCourse.querySelector('.message');
130 elButtonAssign.disabled = true;
131 _utils_admin_js__WEBPACK_IMPORTED_MODULE_0__.Utils.lpFetchAPI(url, params, {
132 success: response => {
133 const {
134 status,
135 message
136 } = response;
137 if (status === 'success') {
138 let page = parseInt(response.data.page);
139 const begin = page * limitHandle;
140 const end = begin + limitHandle;
141 data = packages.slice(begin, end);
142 elProgress.innerHTML = response.data.percent;
143 fetchAPIAssignCourse(packages, data, ++page, totalPage);
144 } else if (status === 'finished') {
145 elProgress.innerHTML = '';
146 elMessage.style.color = 'green';
147 elMessage.innerHTML = message;
148 setTimeout(() => {
149 elMessage.innerHTML = '';
150 }, 2000);
151 elButtonAssign.disabled = false;
152 // Clear data selected on Tom Select.
153 if (!elUserAssign.tomselect || !elCourseAssign.tomselect) {
154 return;
155 }
156 elUserAssign.tomselect.clear();
157 elCourseAssign.tomselect.clear();
158 } else if (status === 'error') {
159 elButtonAssign.disabled = false;
160 elMessage.style.color = 'red';
161 elMessage.innerHTML = message;
162 setTimeout(() => {
163 elMessage.innerHTML = '';
164 }, 2000);
165 }
166 },
167 error: err => {
168 elButtonAssign.disabled = false;
169 elMessage.innerHTML = err.message;
170 },
171 completed: () => {}
172 });
173 };
174 const fetchAPIUnAssignCourse = (packages, data, page, totalPage) => {
175 const url = _utils_admin_js__WEBPACK_IMPORTED_MODULE_0__.Api.admin.apiUnAssignUserCourse;
176 const params = {
177 headers: {
178 'Content-Type': 'application/json',
179 'X-WP-Nonce': lpDataAdmin.nonce
180 },
181 method: 'POST',
182 body: JSON.stringify({
183 data,
184 page,
185 totalPage
186 })
187 };
188 const elProgress = elFormUnAssignUserCourse.querySelector('.percent');
189 const elButtonAssign = elFormUnAssignUserCourse.querySelector('.lp-button-unassign-course');
190 const elMessage = elFormUnAssignUserCourse.querySelector('.message');
191 elButtonAssign.disabled = true;
192 _utils_admin_js__WEBPACK_IMPORTED_MODULE_0__.Utils.lpFetchAPI(url, params, {
193 success: response => {
194 const {
195 status,
196 message
197 } = response;
198 if (status === 'success') {
199 let page = parseInt(response.data.page);
200 const begin = page * limitHandle;
201 const end = begin + limitHandle;
202 data = packages.slice(begin, end);
203 elProgress.innerHTML = response.data.percent;
204 fetchAPIUnAssignCourse(packages, data, ++page, totalPage);
205 } else if (status === 'finished') {
206 elProgress.innerHTML = '';
207 elMessage.style.color = 'green';
208 elMessage.innerHTML = message;
209 setTimeout(() => {
210 elMessage.innerHTML = '';
211 }, 2000);
212 elButtonAssign.disabled = false;
213 // Clear data selected on Tom Select.
214 if (!elUserUnAssign.tomselect || !elCourseUnAssign.tomselect) {
215 return;
216 }
217 elUserUnAssign.tomselect.clear();
218 elCourseUnAssign.tomselect.clear();
219 } else if (status === 'error') {
220 elButtonAssign.disabled = false;
221 elMessage.style.color = 'red';
222 elMessage.innerHTML = message;
223 setTimeout(() => {
224 elMessage.innerHTML = '';
225 }, 2000);
226 }
227 },
228 error: err => {
229 elButtonAssign.disabled = false;
230 elMessage.innerHTML = err.message;
231 },
232 completed: () => {}
233 });
234 };
235
236 // DOMContentLoaded.
237 document.addEventListener('DOMContentLoaded', () => {
238 getAllElements();
239 if (!elFormAssignUserCourse) {
240 return;
241 }
242 events();
243 });
244 }
245
246 /***/ },
247
248 /***/ "./assets/src/js/admin/utils-admin.js"
249 /*!********************************************!*\
250 !*** ./assets/src/js/admin/utils-admin.js ***!
251 \********************************************/
252 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
253
254 __webpack_require__.r(__webpack_exports__);
255 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
256 /* harmony export */ AdminUtilsFunctions: () => (/* binding */ AdminUtilsFunctions),
257 /* harmony export */ Api: () => (/* reexport safe */ _api_js__WEBPACK_IMPORTED_MODULE_2__["default"]),
258 /* harmony export */ Utils: () => (/* reexport module object */ _utils_js__WEBPACK_IMPORTED_MODULE_0__)
259 /* harmony export */ });
260 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ "./assets/src/js/utils.js");
261 /* harmony import */ var tom_select__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tom-select */ "./node_modules/tom-select/dist/esm/tom-select.complete.js");
262 /* harmony import */ var _api_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../api.js */ "./assets/src/js/api.js");
263 /**
264 * Library run on Admin
265 *
266 * @since 4.2.6.9
267 * @version 1.0.1
268 */
269
270
271
272 const AdminUtilsFunctions = {
273 buildTomSelect(elTomSelect, options, fetchAPI, dataSend, callBackHandleData) {
274 if (!elTomSelect) {
275 return;
276 }
277 const optionDefault = {
278 plugins: {
279 remove_button: {
280 title: 'Remove this item'
281 },
282 dropdown_input: {}
283 },
284 onInitialize() {},
285 onItemAdd(e) {
286 // Get list without current item.
287 if (fetchAPI) {
288 const selectedOptions = Array.from(elTomSelect.selectedOptions);
289 const selectedValues = selectedOptions.map(option => option.value);
290 selectedValues.push(e);
291 dataSend.id_not_in = selectedValues.join(',');
292 fetchAPI('', dataSend, callBackHandleData);
293 }
294 }
295 };
296 if (fetchAPI) {
297 optionDefault.load = (keySearch, callbackTom) => {
298 const selectedOptions = Array.from(elTomSelect.selectedOptions);
299 const selectedValues = selectedOptions.map(option => option.value);
300 dataSend.id_not_in = selectedValues.join(',');
301 fetchAPI(keySearch, dataSend, AdminUtilsFunctions.callBackTomSelectSearchAPI(callbackTom, callBackHandleData));
302 };
303 }
304 options = {
305 ...optionDefault,
306 ...options
307 };
308 const items_selected = options.options;
309 /*if ( options?.options?.length > 20 ) {
310 const chunkSize = 20;
311 const length = options.options.length;
312 let i = 0;
313 const chunkedOptions = { ...options };
314 chunkedOptions.options = items_selected.slice( i, chunkSize );
315 const tomSelect = new TomSelect( elTomSelect, chunkedOptions );
316 i += chunkSize;
317 const interval = setInterval( () => {
318 if ( i > ( length - 1 ) ) {
319 clearInterval( interval );
320 }
321 const optionsSlice = items_selected.slice( i, i + chunkSize );
322 i += chunkSize;
323 tomSelect.addOptions( optionsSlice );
324 tomSelect.setValue( options.items );
325 }, 200 );
326 return tomSelect;
327 }*/
328
329 return new tom_select__WEBPACK_IMPORTED_MODULE_1__["default"](elTomSelect, options);
330 },
331 callBackTomSelectSearchAPI(callbackTom, callBackHandleData) {
332 return {
333 success: response => {
334 const options = callBackHandleData.success(response);
335 callbackTom(options);
336 }
337 };
338 },
339 fetchCourses(keySearch = '', dataSend = {}, callback) {
340 const url = _api_js__WEBPACK_IMPORTED_MODULE_2__["default"].admin.apiSearchCourses;
341 dataSend.search = keySearch;
342 const params = {
343 headers: {
344 'Content-Type': 'application/json',
345 'X-WP-Nonce': lpDataAdmin.nonce
346 },
347 method: 'POST',
348 body: JSON.stringify(dataSend)
349 };
350 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpFetchAPI(url, params, callback);
351 },
352 fetchUsers(keySearch = '', dataSend = {}, callback) {
353 const url = _api_js__WEBPACK_IMPORTED_MODULE_2__["default"].admin.apiSearchUsers;
354 dataSend.search = keySearch;
355 const params = {
356 headers: {
357 'Content-Type': 'application/json',
358 'X-WP-Nonce': lpDataAdmin.nonce
359 },
360 method: 'POST',
361 body: JSON.stringify(dataSend)
362 };
363 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpFetchAPI(url, params, callback);
364 }
365 };
366
367
368 /***/ },
369
370 /***/ "./assets/src/js/api.js"
371 /*!******************************!*\
372 !*** ./assets/src/js/api.js ***!
373 \******************************/
374 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
375
376 __webpack_require__.r(__webpack_exports__);
377 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
378 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
379 /* harmony export */ });
380 /**
381 * List API on backend
382 *
383 * @since 4.2.6
384 * @version 1.0.2
385 */
386
387 const lplistAPI = {};
388 let lp_rest_url;
389 if ('undefined' !== typeof lpDataAdmin) {
390 lp_rest_url = lpDataAdmin.lp_rest_url;
391 lplistAPI.admin = {
392 apiAdminNotice: lp_rest_url + 'lp/v1/admin/tools/admin-notices',
393 apiAddons: lp_rest_url + 'lp/v1/addon/all',
394 apiAddonAction: lp_rest_url + 'lp/v1/addon/action-n',
395 apiAddonsPurchase: lp_rest_url + 'lp/v1/addon/info-addons-purchase',
396 apiSearchCourses: lp_rest_url + 'lp/v1/admin/tools/search-course',
397 apiSearchUsers: lp_rest_url + 'lp/v1/admin/tools/search-user',
398 apiAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/assign-user-course',
399 apiUnAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/unassign-user-course'
400 };
401 }
402 if ('undefined' !== typeof lpData) {
403 lp_rest_url = lpData.lp_rest_url;
404 lplistAPI.frontend = {
405 apiWidgets: lp_rest_url + 'lp/v1/widgets/api',
406 apiCourses: lp_rest_url + 'lp/v1/courses/archive-course',
407 // Deprecated API, don't load from v4.3.7
408 apiAJAX: lp_rest_url + 'lp/v1/load_content_via_ajax/',
409 // Deprecated since 4.3.0
410 apiProfileCoverImage: lp_rest_url + 'lp/v1/profile/cover-image'
411 };
412 }
413 if (lp_rest_url) {
414 lplistAPI.apiCourses = lp_rest_url + 'lp/v1/courses/';
415 lplistAPI.apiEditCoursesArchiveBlock = lp_rest_url + 'lp/v1/courses/edit-archive-block';
416 lplistAPI.apiCoursesSuggest = lp_rest_url + 'lp/v1/courses/courses-suggest';
417 }
418 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (lplistAPI);
419
420 /***/ },
421
422 /***/ "./assets/src/js/utils.js"
423 /*!********************************!*\
424 !*** ./assets/src/js/utils.js ***!
425 \********************************/
426 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
427
428 __webpack_require__.r(__webpack_exports__);
429 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
430 /* harmony export */ debounce: () => (/* binding */ debounce),
431 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
432 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
433 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
434 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
435 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
436 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
437 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
438 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
439 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
440 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
441 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
442 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
443 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
444 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
445 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
446 /* harmony export */ });
447 /**
448 * Utils functions
449 *
450 * @param url
451 * @param data
452 * @param functions
453 * @since 4.2.5.1
454 * @version 1.0.6
455 */
456 const lpClassName = {
457 hidden: 'lp-hidden',
458 loading: 'loading',
459 elCollapse: 'lp-collapse',
460 elSectionToggle: '.lp-section-toggle',
461 elTriggerToggle: '.lp-trigger-toggle'
462 };
463 const lpFetchAPI = (url, data = {}, functions = {}) => {
464 if ('function' === typeof functions.before) {
465 functions.before();
466 }
467 fetch(url, {
468 method: 'GET',
469 ...data
470 }).then(response => response.json()).then(response => {
471 if ('function' === typeof functions.success) {
472 functions.success(response);
473 }
474 }).catch(err => {
475 if ('function' === typeof functions.error) {
476 functions.error(err);
477 }
478 }).finally(() => {
479 if ('function' === typeof functions.completed) {
480 functions.completed();
481 }
482 });
483 };
484
485 /**
486 * Get current URL without params.
487 *
488 * @since 4.2.5.1
489 */
490 const lpGetCurrentURLNoParam = () => {
491 let currentUrl = window.location.href;
492 const hasParams = currentUrl.includes('?');
493 if (hasParams) {
494 currentUrl = currentUrl.split('?')[0];
495 }
496 return currentUrl;
497 };
498 const lpAddQueryArgs = (endpoint, args) => {
499 const url = new URL(endpoint);
500 Object.keys(args).forEach(arg => {
501 url.searchParams.set(arg, args[arg]);
502 });
503 return url;
504 };
505
506 /**
507 * Listen element viewed.
508 *
509 * @param el
510 * @param callback
511 * @since 4.2.5.8
512 */
513 const listenElementViewed = (el, callback) => {
514 const observerSeeItem = new IntersectionObserver(function (entries) {
515 for (const entry of entries) {
516 if (entry.isIntersecting) {
517 callback(entry);
518 }
519 }
520 });
521 observerSeeItem.observe(el);
522 };
523
524 /**
525 * Listen element created.
526 *
527 * @param callback
528 * @since 4.2.5.8
529 */
530 const listenElementCreated = callback => {
531 const observerCreateItem = new MutationObserver(function (mutations) {
532 mutations.forEach(function (mutation) {
533 if (mutation.addedNodes) {
534 mutation.addedNodes.forEach(function (node) {
535 if (node.nodeType === 1) {
536 callback(node);
537 }
538 });
539 }
540 });
541 });
542 observerCreateItem.observe(document, {
543 childList: true,
544 subtree: true
545 });
546 // End.
547 };
548
549 /**
550 * Listen element created.
551 *
552 * @param selector
553 * @param callback
554 * @since 4.2.7.1
555 */
556 const lpOnElementReady = (selector, callback) => {
557 const element = document.querySelector(selector);
558 if (element) {
559 callback(element);
560 return;
561 }
562 const observer = new MutationObserver((mutations, obs) => {
563 const element = document.querySelector(selector);
564 if (element) {
565 obs.disconnect();
566 callback(element);
567 }
568 });
569 observer.observe(document.documentElement, {
570 childList: true,
571 subtree: true
572 });
573 };
574
575 // Parse JSON from string with content include LP_AJAX_START.
576 const lpAjaxParseJsonOld = data => {
577 if (typeof data !== 'string') {
578 return data;
579 }
580 const m = String.raw({
581 raw: data
582 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
583 try {
584 if (m) {
585 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
586 } else {
587 data = JSON.parse(data);
588 }
589 } catch (e) {
590 data = {};
591 }
592 return data;
593 };
594
595 // status 0: hide, 1: show
596 const lpShowHideEl = (el, status = 0) => {
597 if (!el) {
598 return;
599 }
600 if (!status) {
601 el.classList.add(lpClassName.hidden);
602 } else {
603 el.classList.remove(lpClassName.hidden);
604 }
605 };
606
607 // status 0: hide, 1: show
608 const lpSetLoadingEl = (el, status) => {
609 if (!el) {
610 return;
611 }
612 if (!status) {
613 el.classList.remove(lpClassName.loading);
614 } else {
615 el.classList.add(lpClassName.loading);
616 }
617 };
618
619 // Toggle collapse section
620 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
621 if (!elTriggerClassName) {
622 elTriggerClassName = lpClassName.elTriggerToggle;
623 }
624
625 // Exclude elements, which should not trigger the collapse toggle
626 if (elsExclude && elsExclude.length > 0) {
627 for (const elExclude of elsExclude) {
628 if (target.closest(elExclude)) {
629 return;
630 }
631 }
632 }
633 const elTrigger = target.closest(elTriggerClassName);
634 if (!elTrigger) {
635 return;
636 }
637
638 //console.log( 'elTrigger', elTrigger );
639
640 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
641 if (!elSectionToggle) {
642 return;
643 }
644 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
645 if ('function' === typeof callback) {
646 callback(elSectionToggle);
647 }
648 };
649
650 // Get data of form
651 const getDataOfForm = form => {
652 const dataSend = {};
653 const formData = new FormData(form);
654 for (const pair of formData.entries()) {
655 const key = pair[0];
656 const value = formData.getAll(key);
657 if (!dataSend.hasOwnProperty(key)) {
658 // Convert value array to string.
659 dataSend[key] = value.join(',');
660 }
661 }
662 return dataSend;
663 };
664
665 // Get field keys of form
666 const getFieldKeysOfForm = form => {
667 const keys = [];
668 const elements = form.elements;
669 for (let i = 0; i < elements.length; i++) {
670 const name = elements[i].name;
671 if (name && !keys.includes(name)) {
672 keys.push(name);
673 }
674 }
675 return keys;
676 };
677
678 // Merge data handle with data form.
679 const mergeDataWithDatForm = (elForm, dataHandle) => {
680 const dataForm = getDataOfForm(elForm);
681 const keys = getFieldKeysOfForm(elForm);
682 keys.forEach(key => {
683 if (!dataForm.hasOwnProperty(key)) {
684 delete dataHandle[key];
685 } else if (dataForm[key][0] === '') {
686 delete dataForm[key];
687 delete dataHandle[key];
688 }
689 });
690 dataHandle = {
691 ...dataHandle,
692 ...dataForm
693 };
694 return dataHandle;
695 };
696
697 /**
698 * Event trigger
699 * For each list of event handlers, listen event on document.
700 *
701 * eventName: 'click', 'change', ...
702 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
703 *
704 * @param eventName
705 * @param eventHandlers
706 */
707 const eventHandlers = (eventName, eventHandlers) => {
708 document.addEventListener(eventName, e => {
709 const target = e.target;
710 let args = {
711 e,
712 target
713 };
714 eventHandlers.forEach(eventHandler => {
715 args = {
716 ...args,
717 ...eventHandler
718 };
719
720 //console.log( args );
721
722 // Check condition before call back
723 if (eventHandler.conditionBeforeCallBack) {
724 if (eventHandler.conditionBeforeCallBack(args) !== true) {
725 return;
726 }
727 }
728
729 // Special check for keydown event with checkIsEventEnter = true
730 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
731 if (e.key !== 'Enter') {
732 return;
733 }
734 }
735 if (target.closest(eventHandler.selector)) {
736 if (eventHandler.class) {
737 // Call method of class, function callBack will understand exactly {this} is class object.
738 eventHandler.class[eventHandler.callBack](args);
739 } else {
740 // For send args is objected, {this} is eventHandler object, not class object.
741 eventHandler.callBack(args);
742 }
743 }
744 });
745 });
746 };
747
748 /**
749 * Debounce - delays function execution until after `wait` ms of inactivity.
750 *
751 * Each call resets the timer. Only the last call in a burst executes.
752 *
753 * USE CASES:
754 * - Search inputs, form validation, window resize
755 * - Multiple elements need independent timers
756 * - When you need to call with different arguments
757 *
758 * EXAMPLES:
759 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
760 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
761 *
762 * const debouncedResize = debounce( recalculateLayout, 250 );
763 * window.addEventListener('resize', debouncedResize);
764 *
765 * ⚠️ Create ONCE outside event handlers, not inside.
766 *
767 * @param {Function} func - Function to debounce (can be anonymous)
768 * @param {number} wait - Milliseconds to wait (default: 500)
769 * @return {Function} Debounced wrapper function
770 * @since 4.3.7
771 * @version 1.0.0
772 */
773 const debounce = (func, wait = 500) => {
774 let timer;
775 return args => {
776 clearTimeout(timer);
777 timer = setTimeout(() => func(args), wait);
778 };
779 };
780
781 /***/ },
782
783 /***/ "./node_modules/@orchidjs/sifter/dist/esm/sifter.js"
784 /*!**********************************************************!*\
785 !*** ./node_modules/@orchidjs/sifter/dist/esm/sifter.js ***!
786 \**********************************************************/
787 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
788
789 __webpack_require__.r(__webpack_exports__);
790 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
791 /* harmony export */ Sifter: () => (/* binding */ Sifter),
792 /* harmony export */ cmp: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_0__.cmp),
793 /* harmony export */ getAttr: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_0__.getAttr),
794 /* harmony export */ getAttrNesting: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_0__.getAttrNesting),
795 /* harmony export */ getPattern: () => (/* reexport safe */ _orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_1__.getPattern),
796 /* harmony export */ iterate: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_0__.iterate),
797 /* harmony export */ propToArray: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_0__.propToArray),
798 /* harmony export */ scoreValue: () => (/* reexport safe */ _utils_js__WEBPACK_IMPORTED_MODULE_0__.scoreValue)
799 /* harmony export */ });
800 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils.js */ "./node_modules/@orchidjs/sifter/dist/esm/utils.js");
801 /* harmony import */ var _orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @orchidjs/unicode-variants */ "./node_modules/@orchidjs/unicode-variants/dist/esm/index.js");
802 /* harmony import */ var _types_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./types.js */ "./node_modules/@orchidjs/sifter/dist/esm/types.js");
803 /**
804 * sifter.js
805 * Copyright (c) 2013–2020 Brian Reavis & contributors
806 *
807 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
808 * file except in compliance with the License. You may obtain a copy of the License at:
809 * http://www.apache.org/licenses/LICENSE-2.0
810 *
811 * Unless required by applicable law or agreed to in writing, software distributed under
812 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
813 * ANY KIND, either express or implied. See the License for the specific language
814 * governing permissions and limitations under the License.
815 *
816 * @author Brian Reavis <brian@thirdroute.com>
817 */
818
819
820 class Sifter {
821 items; // []|{};
822 settings;
823 /**
824 * Textually searches arrays and hashes of objects
825 * by property (or multiple properties). Designed
826 * specifically for autocomplete.
827 *
828 */
829 constructor(items, settings) {
830 this.items = items;
831 this.settings = settings || { diacritics: true };
832 }
833 ;
834 /**
835 * Splits a search string into an array of individual
836 * regexps to be used to match results.
837 *
838 */
839 tokenize(query, respect_word_boundaries, weights) {
840 if (!query || !query.length)
841 return [];
842 const tokens = [];
843 const words = query.split(/\s+/);
844 var field_regex;
845 if (weights) {
846 field_regex = new RegExp('^(' + Object.keys(weights).map(_orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_1__.escape_regex).join('|') + ')\:(.*)$');
847 }
848 words.forEach((word) => {
849 let field_match;
850 let field = null;
851 let regex = null;
852 // look for "field:query" tokens
853 if (field_regex && (field_match = word.match(field_regex))) {
854 field = field_match[1];
855 word = field_match[2];
856 }
857 if (word.length > 0) {
858 if (this.settings.diacritics) {
859 regex = (0,_orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_1__.getPattern)(word) || null;
860 }
861 else {
862 regex = (0,_orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_1__.escape_regex)(word);
863 }
864 if (regex && respect_word_boundaries)
865 regex = "\\b" + regex;
866 }
867 tokens.push({
868 string: word,
869 regex: regex ? new RegExp(regex, 'iu') : null,
870 field: field,
871 });
872 });
873 return tokens;
874 }
875 ;
876 /**
877 * Returns a function to be used to score individual results.
878 *
879 * Good matches will have a higher score than poor matches.
880 * If an item is not a match, 0 will be returned by the function.
881 *
882 * @returns {T.ScoreFn}
883 */
884 getScoreFunction(query, options) {
885 var search = this.prepareSearch(query, options);
886 return this._getScoreFunction(search);
887 }
888 /**
889 * @returns {T.ScoreFn}
890 *
891 */
892 _getScoreFunction(search) {
893 const tokens = search.tokens, token_count = tokens.length;
894 if (!token_count) {
895 return function () { return 0; };
896 }
897 const fields = search.options.fields, weights = search.weights, field_count = fields.length, getAttrFn = search.getAttrFn;
898 if (!field_count) {
899 return function () { return 1; };
900 }
901 /**
902 * Calculates the score of an object
903 * against the search query.
904 *
905 */
906 const scoreObject = (function () {
907 if (field_count === 1) {
908 return function (token, data) {
909 const field = fields[0].field;
910 return (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.scoreValue)(getAttrFn(data, field), token, weights[field] || 1);
911 };
912 }
913 return function (token, data) {
914 var sum = 0;
915 // is the token specific to a field?
916 if (token.field) {
917 const value = getAttrFn(data, token.field);
918 if (!token.regex && value) {
919 sum += (1 / field_count);
920 }
921 else {
922 sum += (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.scoreValue)(value, token, 1);
923 }
924 }
925 else {
926 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.iterate)(weights, (weight, field) => {
927 sum += (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.scoreValue)(getAttrFn(data, field), token, weight);
928 });
929 }
930 return sum / field_count;
931 };
932 })();
933 if (token_count === 1) {
934 return function (data) {
935 return scoreObject(tokens[0], data);
936 };
937 }
938 if (search.options.conjunction === 'and') {
939 return function (data) {
940 var score, sum = 0;
941 for (let token of tokens) {
942 score = scoreObject(token, data);
943 if (score <= 0)
944 return 0;
945 sum += score;
946 }
947 return sum / token_count;
948 };
949 }
950 else {
951 return function (data) {
952 var sum = 0;
953 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.iterate)(tokens, (token) => {
954 sum += scoreObject(token, data);
955 });
956 return sum / token_count;
957 };
958 }
959 }
960 ;
961 /**
962 * Returns a function that can be used to compare two
963 * results, for sorting purposes. If no sorting should
964 * be performed, `null` will be returned.
965 *
966 * @return function(a,b)
967 */
968 getSortFunction(query, options) {
969 var search = this.prepareSearch(query, options);
970 return this._getSortFunction(search);
971 }
972 _getSortFunction(search) {
973 var implicit_score, sort_flds = [];
974 const self = this, options = search.options, sort = (!search.query && options.sort_empty) ? options.sort_empty : options.sort;
975 if (typeof sort == 'function') {
976 return sort.bind(this);
977 }
978 /**
979 * Fetches the specified sort field value
980 * from a search result item.
981 *
982 */
983 const get_field = function (name, result) {
984 if (name === '$score')
985 return result.score;
986 return search.getAttrFn(self.items[result.id], name);
987 };
988 // parse options
989 if (sort) {
990 for (let s of sort) {
991 if (search.query || s.field !== '$score') {
992 sort_flds.push(s);
993 }
994 }
995 }
996 // the "$score" field is implied to be the primary
997 // sort field, unless it's manually specified
998 if (search.query) {
999 implicit_score = true;
1000 for (let fld of sort_flds) {
1001 if (fld.field === '$score') {
1002 implicit_score = false;
1003 break;
1004 }
1005 }
1006 if (implicit_score) {
1007 sort_flds.unshift({ field: '$score', direction: 'desc' });
1008 }
1009 // without a search.query, all items will have the same score
1010 }
1011 else {
1012 sort_flds = sort_flds.filter((fld) => fld.field !== '$score');
1013 }
1014 // build function
1015 const sort_flds_count = sort_flds.length;
1016 if (!sort_flds_count) {
1017 return null;
1018 }
1019 return function (a, b) {
1020 var result, field;
1021 for (let sort_fld of sort_flds) {
1022 field = sort_fld.field;
1023 let multiplier = sort_fld.direction === 'desc' ? -1 : 1;
1024 result = multiplier * (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.cmp)(get_field(field, a), get_field(field, b));
1025 if (result)
1026 return result;
1027 }
1028 return 0;
1029 };
1030 }
1031 ;
1032 /**
1033 * Parses a search query and returns an object
1034 * with tokens and fields ready to be populated
1035 * with results.
1036 *
1037 */
1038 prepareSearch(query, optsUser) {
1039 const weights = {};
1040 var options = Object.assign({}, optsUser);
1041 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.propToArray)(options, 'sort');
1042 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.propToArray)(options, 'sort_empty');
1043 // convert fields to new format
1044 if (options.fields) {
1045 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.propToArray)(options, 'fields');
1046 const fields = [];
1047 options.fields.forEach((field) => {
1048 if (typeof field == 'string') {
1049 field = { field: field, weight: 1 };
1050 }
1051 fields.push(field);
1052 weights[field.field] = ('weight' in field) ? field.weight : 1;
1053 });
1054 options.fields = fields;
1055 }
1056 return {
1057 options: options,
1058 query: query.toLowerCase().trim(),
1059 tokens: this.tokenize(query, options.respect_word_boundaries, weights),
1060 total: 0,
1061 items: [],
1062 weights: weights,
1063 getAttrFn: (options.nesting) ? _utils_js__WEBPACK_IMPORTED_MODULE_0__.getAttrNesting : _utils_js__WEBPACK_IMPORTED_MODULE_0__.getAttr,
1064 };
1065 }
1066 ;
1067 /**
1068 * Searches through all items and returns a sorted array of matches.
1069 *
1070 */
1071 search(query, options) {
1072 var self = this, score, search;
1073 search = this.prepareSearch(query, options);
1074 options = search.options;
1075 query = search.query;
1076 // generate result scoring function
1077 const fn_score = options.score || self._getScoreFunction(search);
1078 // perform search and sort
1079 if (query.length) {
1080 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.iterate)(self.items, (item, id) => {
1081 score = fn_score(item);
1082 if (options.filter === false || score > 0) {
1083 search.items.push({ 'score': score, 'id': id });
1084 }
1085 });
1086 }
1087 else {
1088 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.iterate)(self.items, (_, id) => {
1089 search.items.push({ 'score': 1, 'id': id });
1090 });
1091 }
1092 const fn_sort = self._getSortFunction(search);
1093 if (fn_sort)
1094 search.items.sort(fn_sort);
1095 // apply limits
1096 search.total = search.items.length;
1097 if (typeof options.limit === 'number') {
1098 search.items = search.items.slice(0, options.limit);
1099 }
1100 return search;
1101 }
1102 ;
1103 }
1104
1105
1106 //# sourceMappingURL=sifter.js.map
1107
1108 /***/ },
1109
1110 /***/ "./node_modules/@orchidjs/sifter/dist/esm/types.js"
1111 /*!*********************************************************!*\
1112 !*** ./node_modules/@orchidjs/sifter/dist/esm/types.js ***!
1113 \*********************************************************/
1114 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1115
1116 __webpack_require__.r(__webpack_exports__);
1117
1118 //# sourceMappingURL=types.js.map
1119
1120 /***/ },
1121
1122 /***/ "./node_modules/@orchidjs/sifter/dist/esm/utils.js"
1123 /*!*********************************************************!*\
1124 !*** ./node_modules/@orchidjs/sifter/dist/esm/utils.js ***!
1125 \*********************************************************/
1126 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1127
1128 __webpack_require__.r(__webpack_exports__);
1129 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1130 /* harmony export */ cmp: () => (/* binding */ cmp),
1131 /* harmony export */ getAttr: () => (/* binding */ getAttr),
1132 /* harmony export */ getAttrNesting: () => (/* binding */ getAttrNesting),
1133 /* harmony export */ iterate: () => (/* binding */ iterate),
1134 /* harmony export */ propToArray: () => (/* binding */ propToArray),
1135 /* harmony export */ scoreValue: () => (/* binding */ scoreValue)
1136 /* harmony export */ });
1137 /* harmony import */ var _orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @orchidjs/unicode-variants */ "./node_modules/@orchidjs/unicode-variants/dist/esm/index.js");
1138
1139 /**
1140 * A property getter resolving dot-notation
1141 * @param {Object} obj The root object to fetch property on
1142 * @param {String} name The optionally dotted property name to fetch
1143 * @return {Object} The resolved property value
1144 */
1145 const getAttr = (obj, name) => {
1146 if (!obj)
1147 return;
1148 return obj[name];
1149 };
1150 /**
1151 * A property getter resolving dot-notation
1152 * @param {Object} obj The root object to fetch property on
1153 * @param {String} name The optionally dotted property name to fetch
1154 * @return {Object} The resolved property value
1155 */
1156 const getAttrNesting = (obj, name) => {
1157 if (!obj)
1158 return;
1159 var part, names = name.split(".");
1160 while ((part = names.shift()) && (obj = obj[part]))
1161 ;
1162 return obj;
1163 };
1164 /**
1165 * Calculates how close of a match the
1166 * given value is against a search token.
1167 *
1168 */
1169 const scoreValue = (value, token, weight) => {
1170 var score, pos;
1171 if (!value)
1172 return 0;
1173 value = value + '';
1174 if (token.regex == null)
1175 return 0;
1176 pos = value.search(token.regex);
1177 if (pos === -1)
1178 return 0;
1179 score = token.string.length / value.length;
1180 if (pos === 0)
1181 score += 0.5;
1182 return score * weight;
1183 };
1184 /**
1185 * Cast object property to an array if it exists and has a value
1186 *
1187 */
1188 const propToArray = (obj, key) => {
1189 var value = obj[key];
1190 if (typeof value == 'function')
1191 return value;
1192 if (value && !Array.isArray(value)) {
1193 obj[key] = [value];
1194 }
1195 };
1196 /**
1197 * Iterates over arrays and hashes.
1198 *
1199 * ```
1200 * iterate(this.items, function(item, id) {
1201 * // invoked for each item
1202 * });
1203 * ```
1204 *
1205 */
1206 const iterate = (object, callback) => {
1207 if (Array.isArray(object)) {
1208 object.forEach(callback);
1209 }
1210 else {
1211 for (var key in object) {
1212 if (object.hasOwnProperty(key)) {
1213 callback(object[key], key);
1214 }
1215 }
1216 }
1217 };
1218 const cmp = (a, b) => {
1219 if (typeof a === 'number' && typeof b === 'number') {
1220 return a > b ? 1 : (a < b ? -1 : 0);
1221 }
1222 a = (0,_orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_0__.asciifold)(a + '').toLowerCase();
1223 b = (0,_orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_0__.asciifold)(b + '').toLowerCase();
1224 if (a > b)
1225 return 1;
1226 if (b > a)
1227 return -1;
1228 return 0;
1229 };
1230 //# sourceMappingURL=utils.js.map
1231
1232 /***/ },
1233
1234 /***/ "./node_modules/@orchidjs/unicode-variants/dist/esm/index.js"
1235 /*!*******************************************************************!*\
1236 !*** ./node_modules/@orchidjs/unicode-variants/dist/esm/index.js ***!
1237 \*******************************************************************/
1238 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1239
1240 __webpack_require__.r(__webpack_exports__);
1241 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1242 /* harmony export */ _asciifold: () => (/* binding */ _asciifold),
1243 /* harmony export */ asciifold: () => (/* binding */ asciifold),
1244 /* harmony export */ code_points: () => (/* binding */ code_points),
1245 /* harmony export */ escape_regex: () => (/* reexport safe */ _regex_js__WEBPACK_IMPORTED_MODULE_0__.escape_regex),
1246 /* harmony export */ generateMap: () => (/* binding */ generateMap),
1247 /* harmony export */ generateSets: () => (/* binding */ generateSets),
1248 /* harmony export */ generator: () => (/* binding */ generator),
1249 /* harmony export */ getPattern: () => (/* binding */ getPattern),
1250 /* harmony export */ initialize: () => (/* binding */ initialize),
1251 /* harmony export */ mapSequence: () => (/* binding */ mapSequence),
1252 /* harmony export */ normalize: () => (/* binding */ normalize),
1253 /* harmony export */ substringsToPattern: () => (/* binding */ substringsToPattern),
1254 /* harmony export */ unicode_map: () => (/* binding */ unicode_map)
1255 /* harmony export */ });
1256 /* harmony import */ var _regex_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./regex.js */ "./node_modules/@orchidjs/unicode-variants/dist/esm/regex.js");
1257 /* harmony import */ var _strings_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./strings.js */ "./node_modules/@orchidjs/unicode-variants/dist/esm/strings.js");
1258
1259
1260 const code_points = [[0, 65535]];
1261 const accent_pat = '[\u0300-\u036F\u{b7}\u{2be}\u{2bc}]';
1262 let unicode_map;
1263 let multi_char_reg;
1264 const max_char_length = 3;
1265 const latin_convert = {};
1266 const latin_condensed = {
1267 '/': '⁄∕',
1268 '0': '߀',
1269 "a": "ⱥɐɑ",
1270 "aa": "",
1271 "ae": "æǽǣ",
1272 "ao": "",
1273 "au": "",
1274 "av": "ꜹꜻ",
1275 "ay": "",
1276 "b": "ƀɓƃ",
1277 "c": "ꜿƈȼↄ",
1278 "d": "đɗɖ�
1279 ƌꮷԁɦ",
1280 "e": "ɛǝᴇɇ",
1281 "f": "ꝼƒ",
1282 "g": "ǥɠꞡᵹꝿɢ",
1283 "h": "ħⱨⱶɥ",
1284 "i": "ɨı",
1285 "j": "ɉȷ",
1286 "k": "ƙⱪꝁꝃ�
1287 ",
1288 "l": "łƚɫⱡꝉꝇꞁɭ",
1289 "m": "ɱɯϻ",
1290 "n": "ꞥƞɲꞑᴎлԉ",
1291 "o": "øǿɔɵꝋꝍᴑ",
1292 "oe": "œ",
1293 "oi": "ƣ",
1294 "oo": "",
1295 "ou": "ȣ",
1296 "p": "ƥᵽꝑꝓꝕρ",
1297 "q": "ꝗꝙɋ",
1298 "r": "ɍɽꝛꞧꞃ",
1299 "s": "ßȿꞩ�
1300 ʂ",
1301 "t": "ŧƭʈⱦꞇ",
1302 "th": "þ",
1303 "tz": "",
1304 "u": "ʉ",
1305 "v": "ʋꝟʌ",
1306 "vy": "",
1307 "w": "",
1308 "y": "ƴɏỿ",
1309 "z": "ƶȥɀⱬꝣ",
1310 "hv": "ƕ"
1311 };
1312 for (let latin in latin_condensed) {
1313 let unicode = latin_condensed[latin] || '';
1314 for (let i = 0; i < unicode.length; i++) {
1315 let char = unicode.substring(i, i + 1);
1316 latin_convert[char] = latin;
1317 }
1318 }
1319 const convert_pat = new RegExp(Object.keys(latin_convert).join('|') + '|' + accent_pat, 'gu');
1320 /**
1321 * Initialize the unicode_map from the give code point ranges
1322 */
1323 const initialize = (_code_points) => {
1324 if (unicode_map !== undefined)
1325 return;
1326 unicode_map = generateMap(_code_points || code_points);
1327 };
1328 /**
1329 * Helper method for normalize a string
1330 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
1331 */
1332 const normalize = (str, form = 'NFKD') => str.normalize(form);
1333 /**
1334 * Remove accents without reordering string
1335 * calling str.normalize('NFKD') on \u{594}\u{595}\u{596} becomes \u{596}\u{594}\u{595}
1336 * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703
1337 */
1338 const asciifold = (str) => {
1339 return Array.from(str).reduce(
1340 /**
1341 * @param {string} result
1342 * @param {string} char
1343 */
1344 (result, char) => {
1345 return result + _asciifold(char);
1346 }, '');
1347 };
1348 const _asciifold = (str) => {
1349 str = normalize(str)
1350 .toLowerCase()
1351 .replace(convert_pat, (/** @type {string} */ char) => {
1352 return latin_convert[char] || '';
1353 });
1354 //return str;
1355 return normalize(str, 'NFC');
1356 };
1357 /**
1358 * Generate a list of unicode variants from the list of code points
1359 */
1360 function* generator(code_points) {
1361 for (const [code_point_min, code_point_max] of code_points) {
1362 for (let i = code_point_min; i <= code_point_max; i++) {
1363 let composed = String.fromCharCode(i);
1364 let folded = asciifold(composed);
1365 if (folded == composed.toLowerCase()) {
1366 continue;
1367 }
1368 // skip when folded is a string longer than 3 characters long
1369 // bc the resulting regex patterns will be long
1370 // eg:
1371 // folded صلى الله عليه وسل�
1372 length 18 code point 65018
1373 // folded جل جلاله length 8 code point 65019
1374 if (folded.length > max_char_length) {
1375 continue;
1376 }
1377 if (folded.length == 0) {
1378 continue;
1379 }
1380 yield { folded: folded, composed: composed, code_point: i };
1381 }
1382 }
1383 }
1384 /**
1385 * Generate a unicode map from the list of code points
1386 */
1387 const generateSets = (code_points) => {
1388 const unicode_sets = {};
1389 const addMatching = (folded, to_add) => {
1390 /** @type {Set<string>} */
1391 const folded_set = unicode_sets[folded] || new Set();
1392 const patt = new RegExp('^' + (0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.setToPattern)(folded_set) + '$', 'iu');
1393 if (to_add.match(patt)) {
1394 return;
1395 }
1396 folded_set.add((0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.escape_regex)(to_add));
1397 unicode_sets[folded] = folded_set;
1398 };
1399 for (let value of generator(code_points)) {
1400 addMatching(value.folded, value.folded);
1401 addMatching(value.folded, value.composed);
1402 }
1403 return unicode_sets;
1404 };
1405 /**
1406 * Generate a unicode map from the list of code points
1407 * ae => (?:(?:ae|Æ|Ǽ|Ǣ)|(?:A|Ⓐ|A...)(?:E|ɛ|Ⓔ...))
1408 */
1409 const generateMap = (code_points) => {
1410 const unicode_sets = generateSets(code_points);
1411 const unicode_map = {};
1412 let multi_char = [];
1413 for (let folded in unicode_sets) {
1414 let set = unicode_sets[folded];
1415 if (set) {
1416 unicode_map[folded] = (0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.setToPattern)(set);
1417 }
1418 if (folded.length > 1) {
1419 multi_char.push((0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.escape_regex)(folded));
1420 }
1421 }
1422 multi_char.sort((a, b) => b.length - a.length);
1423 const multi_char_patt = (0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.arrayToPattern)(multi_char);
1424 multi_char_reg = new RegExp('^' + multi_char_patt, 'u');
1425 return unicode_map;
1426 };
1427 /**
1428 * Map each element of an array from its folded value to all possible unicode matches
1429 */
1430 const mapSequence = (strings, min_replacement = 1) => {
1431 let chars_replaced = 0;
1432 strings = strings.map((str) => {
1433 if (unicode_map[str]) {
1434 chars_replaced += str.length;
1435 }
1436 return unicode_map[str] || str;
1437 });
1438 if (chars_replaced >= min_replacement) {
1439 return (0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.sequencePattern)(strings);
1440 }
1441 return '';
1442 };
1443 /**
1444 * Convert a short string and split it into all possible patterns
1445 * Keep a pattern only if min_replacement is met
1446 *
1447 * 'abc'
1448 * => [['abc'],['ab','c'],['a','bc'],['a','b','c']]
1449 * => ['abc-pattern','ab-c-pattern'...]
1450 */
1451 const substringsToPattern = (str, min_replacement = 1) => {
1452 min_replacement = Math.max(min_replacement, str.length - 1);
1453 return (0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.arrayToPattern)((0,_strings_js__WEBPACK_IMPORTED_MODULE_1__.allSubstrings)(str).map((sub_pat) => {
1454 return mapSequence(sub_pat, min_replacement);
1455 }));
1456 };
1457 /**
1458 * Convert an array of sequences into a pattern
1459 * [{start:0,end:3,length:3,substr:'iii'}...] => (?:iii...)
1460 */
1461 const sequencesToPattern = (sequences, all = true) => {
1462 let min_replacement = sequences.length > 1 ? 1 : 0;
1463 return (0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.arrayToPattern)(sequences.map((sequence) => {
1464 let seq = [];
1465 const len = all ? sequence.length() : sequence.length() - 1;
1466 for (let j = 0; j < len; j++) {
1467 seq.push(substringsToPattern(sequence.substrs[j] || '', min_replacement));
1468 }
1469 return (0,_regex_js__WEBPACK_IMPORTED_MODULE_0__.sequencePattern)(seq);
1470 }));
1471 };
1472 /**
1473 * Return true if the sequence is already in the sequences
1474 */
1475 const inSequences = (needle_seq, sequences) => {
1476 for (const seq of sequences) {
1477 if (seq.start != needle_seq.start || seq.end != needle_seq.end) {
1478 continue;
1479 }
1480 if (seq.substrs.join('') !== needle_seq.substrs.join('')) {
1481 continue;
1482 }
1483 let needle_parts = needle_seq.parts;
1484 const filter = (part) => {
1485 for (const needle_part of needle_parts) {
1486 if (needle_part.start === part.start && needle_part.substr === part.substr) {
1487 return false;
1488 }
1489 if (part.length == 1 || needle_part.length == 1) {
1490 continue;
1491 }
1492 // check for overlapping parts
1493 // a = ['::=','==']
1494 // b = ['::','===']
1495 // a = ['r','sm']
1496 // b = ['rs','m']
1497 if (part.start < needle_part.start && part.end > needle_part.start) {
1498 return true;
1499 }
1500 if (needle_part.start < part.start && needle_part.end > part.start) {
1501 return true;
1502 }
1503 }
1504 return false;
1505 };
1506 let filtered = seq.parts.filter(filter);
1507 if (filtered.length > 0) {
1508 continue;
1509 }
1510 return true;
1511 }
1512 return false;
1513 };
1514 class Sequence {
1515 parts;
1516 substrs;
1517 start;
1518 end;
1519 constructor() {
1520 this.parts = [];
1521 this.substrs = [];
1522 this.start = 0;
1523 this.end = 0;
1524 }
1525 add(part) {
1526 if (part) {
1527 this.parts.push(part);
1528 this.substrs.push(part.substr);
1529 this.start = Math.min(part.start, this.start);
1530 this.end = Math.max(part.end, this.end);
1531 }
1532 }
1533 last() {
1534 return this.parts[this.parts.length - 1];
1535 }
1536 length() {
1537 return this.parts.length;
1538 }
1539 clone(position, last_piece) {
1540 let clone = new Sequence();
1541 let parts = JSON.parse(JSON.stringify(this.parts));
1542 let last_part = parts.pop();
1543 for (const part of parts) {
1544 clone.add(part);
1545 }
1546 let last_substr = last_piece.substr.substring(0, position - last_part.start);
1547 let clone_last_len = last_substr.length;
1548 clone.add({ start: last_part.start, end: last_part.start + clone_last_len, length: clone_last_len, substr: last_substr });
1549 return clone;
1550 }
1551 }
1552 /**
1553 * Expand a regular expression pattern to include unicode variants
1554 * eg /a/ becomes /aⓐaẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁ�
1555 ⱥɐɑAⒶAÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢ�
1556 ǺǍȀȂẠẬẶḀĄȺⱯ/
1557 *
1558 * Issue:
1559 * ﺊﺋ [ 'ﺊ = \\u{fe8a}', 'ﺋ = \\u{fe8b}' ]
1560 * becomes: ئئ [ 'ي = \\u{64a}', 'ٔ = \\u{654}', 'ي = \\u{64a}', 'ٔ = \\u{654}' ]
1561 *
1562 * İIJ = IIJ = �
1563 �J
1564 *
1565 * 1/2/4
1566 */
1567 const getPattern = (str) => {
1568 initialize();
1569 str = asciifold(str);
1570 let pattern = '';
1571 let sequences = [new Sequence()];
1572 for (let i = 0; i < str.length; i++) {
1573 let substr = str.substring(i);
1574 let match = substr.match(multi_char_reg);
1575 const char = str.substring(i, i + 1);
1576 const match_str = match ? match[0] : null;
1577 // loop through sequences
1578 // add either the char or multi_match
1579 let overlapping = [];
1580 let added_types = new Set();
1581 for (const sequence of sequences) {
1582 const last_piece = sequence.last();
1583 if (!last_piece || last_piece.length == 1 || last_piece.end <= i) {
1584 // if we have a multi match
1585 if (match_str) {
1586 const len = match_str.length;
1587 sequence.add({ start: i, end: i + len, length: len, substr: match_str });
1588 added_types.add('1');
1589 }
1590 else {
1591 sequence.add({ start: i, end: i + 1, length: 1, substr: char });
1592 added_types.add('2');
1593 }
1594 }
1595 else if (match_str) {
1596 let clone = sequence.clone(i, last_piece);
1597 const len = match_str.length;
1598 clone.add({ start: i, end: i + len, length: len, substr: match_str });
1599 overlapping.push(clone);
1600 }
1601 else {
1602 // don't add char
1603 // adding would create invalid patterns: 234 => [2,34,4]
1604 added_types.add('3');
1605 }
1606 }
1607 // if we have overlapping
1608 if (overlapping.length > 0) {
1609 // ['ii','iii'] before ['i','i','iii']
1610 overlapping = overlapping.sort((a, b) => {
1611 return a.length() - b.length();
1612 });
1613 for (let clone of overlapping) {
1614 // don't add if we already have an equivalent sequence
1615 if (inSequences(clone, sequences)) {
1616 continue;
1617 }
1618 sequences.push(clone);
1619 }
1620 continue;
1621 }
1622 // if we haven't done anything unique
1623 // clean up the patterns
1624 // helps keep patterns smaller
1625 // if str = 'r₨㎧aarss', pattern will be 446 instead of 655
1626 if (i > 0 && added_types.size == 1 && !added_types.has('3')) {
1627 pattern += sequencesToPattern(sequences, false);
1628 let new_seq = new Sequence();
1629 const old_seq = sequences[0];
1630 if (old_seq) {
1631 new_seq.add(old_seq.last());
1632 }
1633 sequences = [new_seq];
1634 }
1635 }
1636 pattern += sequencesToPattern(sequences, true);
1637 return pattern;
1638 };
1639
1640 //# sourceMappingURL=index.js.map
1641
1642 /***/ },
1643
1644 /***/ "./node_modules/@orchidjs/unicode-variants/dist/esm/regex.js"
1645 /*!*******************************************************************!*\
1646 !*** ./node_modules/@orchidjs/unicode-variants/dist/esm/regex.js ***!
1647 \*******************************************************************/
1648 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1649
1650 __webpack_require__.r(__webpack_exports__);
1651 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1652 /* harmony export */ arrayToPattern: () => (/* binding */ arrayToPattern),
1653 /* harmony export */ escape_regex: () => (/* binding */ escape_regex),
1654 /* harmony export */ hasDuplicates: () => (/* binding */ hasDuplicates),
1655 /* harmony export */ maxValueLength: () => (/* binding */ maxValueLength),
1656 /* harmony export */ sequencePattern: () => (/* binding */ sequencePattern),
1657 /* harmony export */ setToPattern: () => (/* binding */ setToPattern),
1658 /* harmony export */ unicodeLength: () => (/* binding */ unicodeLength)
1659 /* harmony export */ });
1660 /**
1661 * Convert array of strings to a regular expression
1662 * ex ['ab','a'] => (?:ab|a)
1663 * ex ['a','b'] => [ab]
1664 */
1665 const arrayToPattern = (chars) => {
1666 chars = chars.filter(Boolean);
1667 if (chars.length < 2) {
1668 return chars[0] || '';
1669 }
1670 return (maxValueLength(chars) == 1) ? '[' + chars.join('') + ']' : '(?:' + chars.join('|') + ')';
1671 };
1672 const sequencePattern = (array) => {
1673 if (!hasDuplicates(array)) {
1674 return array.join('');
1675 }
1676 let pattern = '';
1677 let prev_char_count = 0;
1678 const prev_pattern = () => {
1679 if (prev_char_count > 1) {
1680 pattern += '{' + prev_char_count + '}';
1681 }
1682 };
1683 array.forEach((char, i) => {
1684 if (char === array[i - 1]) {
1685 prev_char_count++;
1686 return;
1687 }
1688 prev_pattern();
1689 pattern += char;
1690 prev_char_count = 1;
1691 });
1692 prev_pattern();
1693 return pattern;
1694 };
1695 /**
1696 * Convert array of strings to a regular expression
1697 * ex ['ab','a'] => (?:ab|a)
1698 * ex ['a','b'] => [ab]
1699 */
1700 const setToPattern = (chars) => {
1701 let array = Array.from(chars);
1702 return arrayToPattern(array);
1703 };
1704 /**
1705 * https://stackoverflow.com/questions/7376598/in-javascript-how-do-i-check-if-an-array-has-duplicate-values
1706 */
1707 const hasDuplicates = (array) => {
1708 return (new Set(array)).size !== array.length;
1709 };
1710 /**
1711 * https://stackoverflow.com/questions/63006601/why-does-u-throw-an-invalid-escape-error
1712 */
1713 const escape_regex = (str) => {
1714 return (str + '').replace(/([\$\(\)\*\+\.\?\[\]\^\{\|\}\\])/gu, '\\$1');
1715 };
1716 /**
1717 * Return the max length of array values
1718 */
1719 const maxValueLength = (array) => {
1720 return array.reduce((longest, value) => Math.max(longest, unicodeLength(value)), 0);
1721 };
1722 const unicodeLength = (str) => {
1723 return Array.from(str).length;
1724 };
1725 //# sourceMappingURL=regex.js.map
1726
1727 /***/ },
1728
1729 /***/ "./node_modules/@orchidjs/unicode-variants/dist/esm/strings.js"
1730 /*!*********************************************************************!*\
1731 !*** ./node_modules/@orchidjs/unicode-variants/dist/esm/strings.js ***!
1732 \*********************************************************************/
1733 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1734
1735 __webpack_require__.r(__webpack_exports__);
1736 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1737 /* harmony export */ allSubstrings: () => (/* binding */ allSubstrings)
1738 /* harmony export */ });
1739 /**
1740 * Get all possible combinations of substrings that add up to the given string
1741 * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string
1742 */
1743 const allSubstrings = (input) => {
1744 if (input.length === 1)
1745 return [[input]];
1746 let result = [];
1747 const start = input.substring(1);
1748 const suba = allSubstrings(start);
1749 suba.forEach(function (subresult) {
1750 let tmp = subresult.slice(0);
1751 tmp[0] = input.charAt(0) + tmp[0];
1752 result.push(tmp);
1753 tmp = subresult.slice(0);
1754 tmp.unshift(input.charAt(0));
1755 result.push(tmp);
1756 });
1757 return result;
1758 };
1759 //# sourceMappingURL=strings.js.map
1760
1761 /***/ },
1762
1763 /***/ "./node_modules/tom-select/dist/esm/constants.js"
1764 /*!*******************************************************!*\
1765 !*** ./node_modules/tom-select/dist/esm/constants.js ***!
1766 \*******************************************************/
1767 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1768
1769 __webpack_require__.r(__webpack_exports__);
1770 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1771 /* harmony export */ IS_MAC: () => (/* binding */ IS_MAC),
1772 /* harmony export */ KEY_A: () => (/* binding */ KEY_A),
1773 /* harmony export */ KEY_BACKSPACE: () => (/* binding */ KEY_BACKSPACE),
1774 /* harmony export */ KEY_DELETE: () => (/* binding */ KEY_DELETE),
1775 /* harmony export */ KEY_DOWN: () => (/* binding */ KEY_DOWN),
1776 /* harmony export */ KEY_ESC: () => (/* binding */ KEY_ESC),
1777 /* harmony export */ KEY_LEFT: () => (/* binding */ KEY_LEFT),
1778 /* harmony export */ KEY_RETURN: () => (/* binding */ KEY_RETURN),
1779 /* harmony export */ KEY_RIGHT: () => (/* binding */ KEY_RIGHT),
1780 /* harmony export */ KEY_SHORTCUT: () => (/* binding */ KEY_SHORTCUT),
1781 /* harmony export */ KEY_TAB: () => (/* binding */ KEY_TAB),
1782 /* harmony export */ KEY_UP: () => (/* binding */ KEY_UP)
1783 /* harmony export */ });
1784 const KEY_A = 65;
1785 const KEY_RETURN = 13;
1786 const KEY_ESC = 27;
1787 const KEY_LEFT = 37;
1788 const KEY_UP = 38;
1789 const KEY_RIGHT = 39;
1790 const KEY_DOWN = 40;
1791 const KEY_BACKSPACE = 8;
1792 const KEY_DELETE = 46;
1793 const KEY_TAB = 9;
1794 const IS_MAC = typeof navigator === 'undefined' ? false : /Mac/.test(navigator.userAgent);
1795 const KEY_SHORTCUT = IS_MAC ? 'metaKey' : 'ctrlKey'; // ctrl key or apple key for ma
1796 //# sourceMappingURL=constants.js.map
1797
1798 /***/ },
1799
1800 /***/ "./node_modules/tom-select/dist/esm/contrib/highlight.js"
1801 /*!***************************************************************!*\
1802 !*** ./node_modules/tom-select/dist/esm/contrib/highlight.js ***!
1803 \***************************************************************/
1804 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1805
1806 __webpack_require__.r(__webpack_exports__);
1807 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1808 /* harmony export */ highlight: () => (/* binding */ highlight),
1809 /* harmony export */ removeHighlight: () => (/* binding */ removeHighlight)
1810 /* harmony export */ });
1811 /* harmony import */ var _vanilla_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../vanilla.js */ "./node_modules/tom-select/dist/esm/vanilla.js");
1812 /**
1813 * highlight v3 | MIT license | Johann Burkard <jb@eaio.com>
1814 * Highlights arbitrary terms in a node.
1815 *
1816 * - Modified by Marshal <beatgates@gmail.com> 2011-6-24 (added regex)
1817 * - Modified by Brian Reavis <brian@thirdroute.com> 2012-8-27 (cleanup)
1818 */
1819
1820 const highlight = (element, regex) => {
1821 if (regex === null)
1822 return;
1823 // convet string to regex
1824 if (typeof regex === 'string') {
1825 if (!regex.length)
1826 return;
1827 regex = new RegExp(regex, 'i');
1828 }
1829 // Wrap matching part of text node with highlighting <span>, e.g.
1830 // Soccer -> <span class="highlight">Soc</span>cer for regex = /soc/i
1831 const highlightText = (node) => {
1832 var match = node.data.match(regex);
1833 if (match && node.data.length > 0) {
1834 var spannode = document.createElement('span');
1835 spannode.className = 'highlight';
1836 var middlebit = node.splitText(match.index);
1837 middlebit.splitText(match[0].length);
1838 var middleclone = middlebit.cloneNode(true);
1839 spannode.appendChild(middleclone);
1840 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_0__.replaceNode)(middlebit, spannode);
1841 return 1;
1842 }
1843 return 0;
1844 };
1845 // Recurse element node, looking for child text nodes to highlight, unless element
1846 // is childless, <script>, <style>, or already highlighted: <span class="hightlight">
1847 const highlightChildren = (node) => {
1848 if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && (node.className !== 'highlight' || node.tagName !== 'SPAN')) {
1849 Array.from(node.childNodes).forEach(element => {
1850 highlightRecursive(element);
1851 });
1852 }
1853 };
1854 const highlightRecursive = (node) => {
1855 if (node.nodeType === 3) {
1856 return highlightText(node);
1857 }
1858 highlightChildren(node);
1859 return 0;
1860 };
1861 highlightRecursive(element);
1862 };
1863 /**
1864 * removeHighlight fn copied from highlight v5 and
1865 * edited to remove with(), pass js strict mode, and use without jquery
1866 */
1867 const removeHighlight = (el) => {
1868 var elements = el.querySelectorAll("span.highlight");
1869 Array.prototype.forEach.call(elements, function (el) {
1870 var parent = el.parentNode;
1871 parent.replaceChild(el.firstChild, el);
1872 parent.normalize();
1873 });
1874 };
1875 //# sourceMappingURL=highlight.js.map
1876
1877 /***/ },
1878
1879 /***/ "./node_modules/tom-select/dist/esm/contrib/microevent.js"
1880 /*!****************************************************************!*\
1881 !*** ./node_modules/tom-select/dist/esm/contrib/microevent.js ***!
1882 \****************************************************************/
1883 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1884
1885 __webpack_require__.r(__webpack_exports__);
1886 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1887 /* harmony export */ "default": () => (/* binding */ MicroEvent)
1888 /* harmony export */ });
1889 /**
1890 * MicroEvent - to make any js object an event emitter
1891 *
1892 * - pure javascript - server compatible, browser compatible
1893 * - dont rely on the browser doms
1894 * - super simple - you get it immediatly, no mistery, no magic involved
1895 *
1896 * @author Jerome Etienne (https://github.com/jeromeetienne)
1897 */
1898 /**
1899 * Execute callback for each event in space separated list of event names
1900 *
1901 */
1902 function forEvents(events, callback) {
1903 events.split(/\s+/).forEach((event) => {
1904 callback(event);
1905 });
1906 }
1907 class MicroEvent {
1908 constructor() {
1909 this._events = {};
1910 }
1911 on(events, fct) {
1912 forEvents(events, (event) => {
1913 const event_array = this._events[event] || [];
1914 event_array.push(fct);
1915 this._events[event] = event_array;
1916 });
1917 }
1918 off(events, fct) {
1919 var n = arguments.length;
1920 if (n === 0) {
1921 this._events = {};
1922 return;
1923 }
1924 forEvents(events, (event) => {
1925 if (n === 1) {
1926 delete this._events[event];
1927 return;
1928 }
1929 const event_array = this._events[event];
1930 if (event_array === undefined)
1931 return;
1932 event_array.splice(event_array.indexOf(fct), 1);
1933 this._events[event] = event_array;
1934 });
1935 }
1936 trigger(events, ...args) {
1937 var self = this;
1938 forEvents(events, (event) => {
1939 const event_array = self._events[event];
1940 if (event_array === undefined)
1941 return;
1942 event_array.forEach(fct => {
1943 fct.apply(self, args);
1944 });
1945 });
1946 }
1947 }
1948 ;
1949 //# sourceMappingURL=microevent.js.map
1950
1951 /***/ },
1952
1953 /***/ "./node_modules/tom-select/dist/esm/contrib/microplugin.js"
1954 /*!*****************************************************************!*\
1955 !*** ./node_modules/tom-select/dist/esm/contrib/microplugin.js ***!
1956 \*****************************************************************/
1957 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
1958
1959 __webpack_require__.r(__webpack_exports__);
1960 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1961 /* harmony export */ "default": () => (/* binding */ MicroPlugin)
1962 /* harmony export */ });
1963 /**
1964 * microplugin.js
1965 * Copyright (c) 2013 Brian Reavis & contributors
1966 *
1967 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
1968 * file except in compliance with the License. You may obtain a copy of the License at:
1969 * http://www.apache.org/licenses/LICENSE-2.0
1970 *
1971 * Unless required by applicable law or agreed to in writing, software distributed under
1972 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1973 * ANY KIND, either express or implied. See the License for the specific language
1974 * governing permissions and limitations under the License.
1975 *
1976 * @author Brian Reavis <brian@thirdroute.com>
1977 */
1978 function MicroPlugin(Interface) {
1979 Interface.plugins = {};
1980 return class extends Interface {
1981 constructor() {
1982 super(...arguments);
1983 this.plugins = {
1984 names: [],
1985 settings: {},
1986 requested: {},
1987 loaded: {}
1988 };
1989 }
1990 /**
1991 * Registers a plugin.
1992 *
1993 * @param {function} fn
1994 */
1995 static define(name, fn) {
1996 Interface.plugins[name] = {
1997 'name': name,
1998 'fn': fn
1999 };
2000 }
2001 /**
2002 * Initializes the listed plugins (with options).
2003 * Acceptable formats:
2004 *
2005 * List (without options):
2006 * ['a', 'b', 'c']
2007 *
2008 * List (with options):
2009 * [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
2010 *
2011 * Hash (with options):
2012 * {'a': { ... }, 'b': { ... }, 'c': { ... }}
2013 *
2014 * @param {array|object} plugins
2015 */
2016 initializePlugins(plugins) {
2017 var key, name;
2018 const self = this;
2019 const queue = [];
2020 if (Array.isArray(plugins)) {
2021 plugins.forEach((plugin) => {
2022 if (typeof plugin === 'string') {
2023 queue.push(plugin);
2024 }
2025 else {
2026 self.plugins.settings[plugin.name] = plugin.options;
2027 queue.push(plugin.name);
2028 }
2029 });
2030 }
2031 else if (plugins) {
2032 for (key in plugins) {
2033 if (plugins.hasOwnProperty(key)) {
2034 self.plugins.settings[key] = plugins[key];
2035 queue.push(key);
2036 }
2037 }
2038 }
2039 while (name = queue.shift()) {
2040 self.require(name);
2041 }
2042 }
2043 loadPlugin(name) {
2044 var self = this;
2045 var plugins = self.plugins;
2046 var plugin = Interface.plugins[name];
2047 if (!Interface.plugins.hasOwnProperty(name)) {
2048 throw new Error('Unable to find "' + name + '" plugin');
2049 }
2050 plugins.requested[name] = true;
2051 plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
2052 plugins.names.push(name);
2053 }
2054 /**
2055 * Initializes a plugin.
2056 *
2057 */
2058 require(name) {
2059 var self = this;
2060 var plugins = self.plugins;
2061 if (!self.plugins.loaded.hasOwnProperty(name)) {
2062 if (plugins.requested[name]) {
2063 throw new Error('Plugin has circular dependency ("' + name + '")');
2064 }
2065 self.loadPlugin(name);
2066 }
2067 return plugins.loaded[name];
2068 }
2069 };
2070 }
2071 //# sourceMappingURL=microplugin.js.map
2072
2073 /***/ },
2074
2075 /***/ "./node_modules/tom-select/dist/esm/defaults.js"
2076 /*!******************************************************!*\
2077 !*** ./node_modules/tom-select/dist/esm/defaults.js ***!
2078 \******************************************************/
2079 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2080
2081 __webpack_require__.r(__webpack_exports__);
2082 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2083 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2084 /* harmony export */ });
2085 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
2086 options: [],
2087 optgroups: [],
2088 plugins: [],
2089 delimiter: ',',
2090 splitOn: null, // regexp or string for splitting up values from a paste command
2091 persist: true,
2092 diacritics: true,
2093 create: null,
2094 createOnBlur: false,
2095 createFilter: null,
2096 highlight: true,
2097 openOnFocus: true,
2098 shouldOpen: null,
2099 maxOptions: 50,
2100 maxItems: null,
2101 hideSelected: null,
2102 duplicates: false,
2103 addPrecedence: false,
2104 selectOnTab: false,
2105 preload: null,
2106 allowEmptyOption: false,
2107 //closeAfterSelect: false,
2108 refreshThrottle: 300,
2109 loadThrottle: 300,
2110 loadingClass: 'loading',
2111 dataAttr: null, //'data-data',
2112 optgroupField: 'optgroup',
2113 valueField: 'value',
2114 labelField: 'text',
2115 disabledField: 'disabled',
2116 optgroupLabelField: 'label',
2117 optgroupValueField: 'value',
2118 lockOptgroupOrder: false,
2119 sortField: '$order',
2120 searchField: ['text'],
2121 searchConjunction: 'and',
2122 mode: null,
2123 wrapperClass: 'ts-wrapper',
2124 controlClass: 'ts-control',
2125 dropdownClass: 'ts-dropdown',
2126 dropdownContentClass: 'ts-dropdown-content',
2127 itemClass: 'item',
2128 optionClass: 'option',
2129 dropdownParent: null,
2130 controlInput: '<input type="text" autocomplete="off" size="1" />',
2131 copyClassesToDropdown: false,
2132 placeholder: null,
2133 hidePlaceholder: null,
2134 shouldLoad: function (query) {
2135 return query.length > 0;
2136 },
2137 /*
2138 load : null, // function(query, callback) { ... }
2139 score : null, // function(search) { ... }
2140 onInitialize : null, // function() { ... }
2141 onChange : null, // function(value) { ... }
2142 onItemAdd : null, // function(value, $item) { ... }
2143 onItemRemove : null, // function(value) { ... }
2144 onClear : null, // function() { ... }
2145 onOptionAdd : null, // function(value, data) { ... }
2146 onOptionRemove : null, // function(value) { ... }
2147 onOptionClear : null, // function() { ... }
2148 onOptionGroupAdd : null, // function(id, data) { ... }
2149 onOptionGroupRemove : null, // function(id) { ... }
2150 onOptionGroupClear : null, // function() { ... }
2151 onDropdownOpen : null, // function(dropdown) { ... }
2152 onDropdownClose : null, // function(dropdown) { ... }
2153 onType : null, // function(str) { ... }
2154 onDelete : null, // function(values) { ... }
2155 */
2156 render: {
2157 /*
2158 item: null,
2159 optgroup: null,
2160 optgroup_header: null,
2161 option: null,
2162 option_create: null
2163 */
2164 }
2165 });
2166 //# sourceMappingURL=defaults.js.map
2167
2168 /***/ },
2169
2170 /***/ "./node_modules/tom-select/dist/esm/getSettings.js"
2171 /*!*********************************************************!*\
2172 !*** ./node_modules/tom-select/dist/esm/getSettings.js ***!
2173 \*********************************************************/
2174 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2175
2176 __webpack_require__.r(__webpack_exports__);
2177 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2178 /* harmony export */ "default": () => (/* binding */ getSettings)
2179 /* harmony export */ });
2180 /* harmony import */ var _defaults_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./defaults.js */ "./node_modules/tom-select/dist/esm/defaults.js");
2181 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.js */ "./node_modules/tom-select/dist/esm/utils.js");
2182
2183
2184 function getSettings(input, settings_user) {
2185 var settings = Object.assign({}, _defaults_js__WEBPACK_IMPORTED_MODULE_0__["default"], settings_user);
2186 var attr_data = settings.dataAttr;
2187 var field_label = settings.labelField;
2188 var field_value = settings.valueField;
2189 var field_disabled = settings.disabledField;
2190 var field_optgroup = settings.optgroupField;
2191 var field_optgroup_label = settings.optgroupLabelField;
2192 var field_optgroup_value = settings.optgroupValueField;
2193 var tag_name = input.tagName.toLowerCase();
2194 var placeholder = input.getAttribute('placeholder') || input.getAttribute('data-placeholder');
2195 if (!placeholder && !settings.allowEmptyOption) {
2196 let option = input.querySelector('option[value=""]');
2197 if (option) {
2198 placeholder = option.textContent;
2199 }
2200 }
2201 var settings_element = {
2202 placeholder: placeholder,
2203 options: [],
2204 optgroups: [],
2205 items: [],
2206 maxItems: null,
2207 };
2208 /**
2209 * Initialize from a <select> element.
2210 *
2211 */
2212 var init_select = () => {
2213 var tagName;
2214 var options = settings_element.options;
2215 var optionsMap = {};
2216 var group_count = 1;
2217 let $order = 0;
2218 var readData = (el) => {
2219 var data = Object.assign({}, el.dataset); // get plain object from DOMStringMap
2220 var json = attr_data && data[attr_data];
2221 if (typeof json === 'string' && json.length) {
2222 data = Object.assign(data, JSON.parse(json));
2223 }
2224 return data;
2225 };
2226 var addOption = (option, group) => {
2227 var value = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.hash_key)(option.value);
2228 if (value == null)
2229 return;
2230 if (!value && !settings.allowEmptyOption)
2231 return;
2232 // if the option already exists, it's probably been
2233 // duplicated in another optgroup. in this case, push
2234 // the current group to the "optgroup" property on the
2235 // existing option so that it's rendered in both places.
2236 if (optionsMap.hasOwnProperty(value)) {
2237 if (group) {
2238 var arr = optionsMap[value][field_optgroup];
2239 if (!arr) {
2240 optionsMap[value][field_optgroup] = group;
2241 }
2242 else if (!Array.isArray(arr)) {
2243 optionsMap[value][field_optgroup] = [arr, group];
2244 }
2245 else {
2246 arr.push(group);
2247 }
2248 }
2249 }
2250 else {
2251 var option_data = readData(option);
2252 option_data[field_label] = option_data[field_label] || option.textContent;
2253 option_data[field_value] = option_data[field_value] || value;
2254 option_data[field_disabled] = option_data[field_disabled] || option.disabled;
2255 option_data[field_optgroup] = option_data[field_optgroup] || group;
2256 option_data.$option = option;
2257 option_data.$order = option_data.$order || ++$order;
2258 optionsMap[value] = option_data;
2259 options.push(option_data);
2260 }
2261 if (option.selected) {
2262 settings_element.items.push(value);
2263 }
2264 };
2265 var addGroup = (optgroup) => {
2266 var id, optgroup_data;
2267 optgroup_data = readData(optgroup);
2268 optgroup_data[field_optgroup_label] = optgroup_data[field_optgroup_label] || optgroup.getAttribute('label') || '';
2269 optgroup_data[field_optgroup_value] = optgroup_data[field_optgroup_value] || group_count++;
2270 optgroup_data[field_disabled] = optgroup_data[field_disabled] || optgroup.disabled;
2271 optgroup_data.$order = optgroup_data.$order || ++$order;
2272 settings_element.optgroups.push(optgroup_data);
2273 id = optgroup_data[field_optgroup_value];
2274 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.iterate)(optgroup.children, (option) => {
2275 addOption(option, id);
2276 });
2277 };
2278 settings_element.maxItems = input.hasAttribute('multiple') ? null : 1;
2279 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.iterate)(input.children, (child) => {
2280 tagName = child.tagName.toLowerCase();
2281 if (tagName === 'optgroup') {
2282 addGroup(child);
2283 }
2284 else if (tagName === 'option') {
2285 addOption(child);
2286 }
2287 });
2288 };
2289 /**
2290 * Initialize from a <input type="text"> element.
2291 *
2292 */
2293 var init_textbox = () => {
2294 const data_raw = input.getAttribute(attr_data);
2295 if (!data_raw) {
2296 var value = input.value.trim() || '';
2297 if (!settings.allowEmptyOption && !value.length)
2298 return;
2299 const values = value.split(settings.delimiter);
2300 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.iterate)(values, (value) => {
2301 const option = {};
2302 option[field_label] = value;
2303 option[field_value] = value;
2304 settings_element.options.push(option);
2305 });
2306 settings_element.items = values;
2307 }
2308 else {
2309 settings_element.options = JSON.parse(data_raw);
2310 (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.iterate)(settings_element.options, (opt) => {
2311 settings_element.items.push(opt[field_value]);
2312 });
2313 }
2314 };
2315 if (tag_name === 'select') {
2316 init_select();
2317 }
2318 else {
2319 init_textbox();
2320 }
2321 return Object.assign({}, _defaults_js__WEBPACK_IMPORTED_MODULE_0__["default"], settings_element, settings_user);
2322 }
2323 ;
2324 //# sourceMappingURL=getSettings.js.map
2325
2326 /***/ },
2327
2328 /***/ "./node_modules/tom-select/dist/esm/plugins/caret_position/plugin.js"
2329 /*!***************************************************************************!*\
2330 !*** ./node_modules/tom-select/dist/esm/plugins/caret_position/plugin.js ***!
2331 \***************************************************************************/
2332 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2333
2334 __webpack_require__.r(__webpack_exports__);
2335 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2336 /* harmony export */ "default": () => (/* binding */ plugin)
2337 /* harmony export */ });
2338 /**
2339 * Tom Select v2.4.3
2340 * Licensed under the Apache License, Version 2.0 (the "License");
2341 */
2342
2343 /**
2344 * Converts a scalar to its best string representation
2345 * for hash keys and HTML attribute values.
2346 *
2347 * Transformations:
2348 * 'str' -> 'str'
2349 * null -> ''
2350 * undefined -> ''
2351 * true -> '1'
2352 * false -> '0'
2353 * 0 -> '0'
2354 * 1 -> '1'
2355 *
2356 */
2357
2358 /**
2359 * Iterates over arrays and hashes.
2360 *
2361 * ```
2362 * iterate(this.items, function(item, id) {
2363 * // invoked for each item
2364 * });
2365 * ```
2366 *
2367 */
2368 const iterate = (object, callback) => {
2369 if (Array.isArray(object)) {
2370 object.forEach(callback);
2371 } else {
2372 for (var key in object) {
2373 if (object.hasOwnProperty(key)) {
2374 callback(object[key], key);
2375 }
2376 }
2377 }
2378 };
2379
2380 /**
2381 * Remove css classes
2382 *
2383 */
2384 const removeClasses = (elmts, ...classes) => {
2385 var norm_classes = classesArray(classes);
2386 elmts = castAsArray(elmts);
2387 elmts.map(el => {
2388 norm_classes.map(cls => {
2389 el.classList.remove(cls);
2390 });
2391 });
2392 };
2393
2394 /**
2395 * Return arguments
2396 *
2397 */
2398 const classesArray = args => {
2399 var classes = [];
2400 iterate(args, _classes => {
2401 if (typeof _classes === 'string') {
2402 _classes = _classes.trim().split(/[\t\n\f\r\s]/);
2403 }
2404 if (Array.isArray(_classes)) {
2405 classes = classes.concat(_classes);
2406 }
2407 });
2408 return classes.filter(Boolean);
2409 };
2410
2411 /**
2412 * Create an array from arg if it's not already an array
2413 *
2414 */
2415 const castAsArray = arg => {
2416 if (!Array.isArray(arg)) {
2417 arg = [arg];
2418 }
2419 return arg;
2420 };
2421
2422 /**
2423 * Get the index of an element amongst sibling nodes of the same type
2424 *
2425 */
2426 const nodeIndex = (el, amongst) => {
2427 if (!el) return -1;
2428 amongst = amongst || el.nodeName;
2429 var i = 0;
2430 while (el = el.previousElementSibling) {
2431 if (el.matches(amongst)) {
2432 i++;
2433 }
2434 }
2435 return i;
2436 };
2437
2438 /**
2439 * Plugin: "dropdown_input" (Tom Select)
2440 * Copyright (c) contributors
2441 *
2442 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
2443 * file except in compliance with the License. You may obtain a copy of the License at:
2444 * http://www.apache.org/licenses/LICENSE-2.0
2445 *
2446 * Unless required by applicable law or agreed to in writing, software distributed under
2447 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
2448 * ANY KIND, either express or implied. See the License for the specific language
2449 * governing permissions and limitations under the License.
2450 *
2451 */
2452
2453 function plugin () {
2454 var self = this;
2455
2456 /**
2457 * Moves the caret to the specified index.
2458 *
2459 * The input must be moved by leaving it in place and moving the
2460 * siblings, due to the fact that focus cannot be restored once lost
2461 * on mobile webkit devices
2462 *
2463 */
2464 self.hook('instead', 'setCaret', new_pos => {
2465 if (self.settings.mode === 'single' || !self.control.contains(self.control_input)) {
2466 new_pos = self.items.length;
2467 } else {
2468 new_pos = Math.max(0, Math.min(self.items.length, new_pos));
2469 if (new_pos != self.caretPos && !self.isPending) {
2470 self.controlChildren().forEach((child, j) => {
2471 if (j < new_pos) {
2472 self.control_input.insertAdjacentElement('beforebegin', child);
2473 } else {
2474 self.control.appendChild(child);
2475 }
2476 });
2477 }
2478 }
2479 self.caretPos = new_pos;
2480 });
2481 self.hook('instead', 'moveCaret', direction => {
2482 if (!self.isFocused) return;
2483
2484 // move caret before or after selected items
2485 const last_active = self.getLastActive(direction);
2486 if (last_active) {
2487 const idx = nodeIndex(last_active);
2488 self.setCaret(direction > 0 ? idx + 1 : idx);
2489 self.setActiveItem();
2490 removeClasses(last_active, 'last-active');
2491
2492 // move caret left or right of current position
2493 } else {
2494 self.setCaret(self.caretPos + direction);
2495 }
2496 });
2497 }
2498
2499
2500 //# sourceMappingURL=plugin.js.map
2501
2502
2503 /***/ },
2504
2505 /***/ "./node_modules/tom-select/dist/esm/plugins/change_listener/plugin.js"
2506 /*!****************************************************************************!*\
2507 !*** ./node_modules/tom-select/dist/esm/plugins/change_listener/plugin.js ***!
2508 \****************************************************************************/
2509 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2510
2511 __webpack_require__.r(__webpack_exports__);
2512 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2513 /* harmony export */ "default": () => (/* binding */ plugin)
2514 /* harmony export */ });
2515 /**
2516 * Tom Select v2.4.3
2517 * Licensed under the Apache License, Version 2.0 (the "License");
2518 */
2519
2520 /**
2521 * Converts a scalar to its best string representation
2522 * for hash keys and HTML attribute values.
2523 *
2524 * Transformations:
2525 * 'str' -> 'str'
2526 * null -> ''
2527 * undefined -> ''
2528 * true -> '1'
2529 * false -> '0'
2530 * 0 -> '0'
2531 * 1 -> '1'
2532 *
2533 */
2534
2535 /**
2536 * Add event helper
2537 *
2538 */
2539 const addEvent = (target, type, callback, options) => {
2540 target.addEventListener(type, callback, options);
2541 };
2542
2543 /**
2544 * Plugin: "change_listener" (Tom Select)
2545 * Copyright (c) contributors
2546 *
2547 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
2548 * file except in compliance with the License. You may obtain a copy of the License at:
2549 * http://www.apache.org/licenses/LICENSE-2.0
2550 *
2551 * Unless required by applicable law or agreed to in writing, software distributed under
2552 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
2553 * ANY KIND, either express or implied. See the License for the specific language
2554 * governing permissions and limitations under the License.
2555 *
2556 */
2557
2558 function plugin () {
2559 addEvent(this.input, 'change', () => {
2560 this.sync();
2561 });
2562 }
2563
2564
2565 //# sourceMappingURL=plugin.js.map
2566
2567
2568 /***/ },
2569
2570 /***/ "./node_modules/tom-select/dist/esm/plugins/checkbox_options/plugin.js"
2571 /*!*****************************************************************************!*\
2572 !*** ./node_modules/tom-select/dist/esm/plugins/checkbox_options/plugin.js ***!
2573 \*****************************************************************************/
2574 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2575
2576 __webpack_require__.r(__webpack_exports__);
2577 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2578 /* harmony export */ "default": () => (/* binding */ plugin)
2579 /* harmony export */ });
2580 /**
2581 * Tom Select v2.4.3
2582 * Licensed under the Apache License, Version 2.0 (the "License");
2583 */
2584
2585 /**
2586 * Converts a scalar to its best string representation
2587 * for hash keys and HTML attribute values.
2588 *
2589 * Transformations:
2590 * 'str' -> 'str'
2591 * null -> ''
2592 * undefined -> ''
2593 * true -> '1'
2594 * false -> '0'
2595 * 0 -> '0'
2596 * 1 -> '1'
2597 *
2598 */
2599 const hash_key = value => {
2600 if (typeof value === 'undefined' || value === null) return null;
2601 return get_hash(value);
2602 };
2603 const get_hash = value => {
2604 if (typeof value === 'boolean') return value ? '1' : '0';
2605 return value + '';
2606 };
2607
2608 /**
2609 * Prevent default
2610 *
2611 */
2612 const preventDefault = (evt, stop = false) => {
2613 if (evt) {
2614 evt.preventDefault();
2615 if (stop) {
2616 evt.stopPropagation();
2617 }
2618 }
2619 };
2620
2621 /**
2622 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
2623 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
2624 *
2625 * param query should be {}
2626 */
2627 const getDom = query => {
2628 if (query.jquery) {
2629 return query[0];
2630 }
2631 if (query instanceof HTMLElement) {
2632 return query;
2633 }
2634 if (isHtmlString(query)) {
2635 var tpl = document.createElement('template');
2636 tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
2637 return tpl.content.firstChild;
2638 }
2639 return document.querySelector(query);
2640 };
2641 const isHtmlString = arg => {
2642 if (typeof arg === 'string' && arg.indexOf('<') > -1) {
2643 return true;
2644 }
2645 return false;
2646 };
2647
2648 /**
2649 * Plugin: "checkbox_options" (Tom Select)
2650 * Copyright (c) contributors
2651 *
2652 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
2653 * file except in compliance with the License. You may obtain a copy of the License at:
2654 * http://www.apache.org/licenses/LICENSE-2.0
2655 *
2656 * Unless required by applicable law or agreed to in writing, software distributed under
2657 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
2658 * ANY KIND, either express or implied. See the License for the specific language
2659 * governing permissions and limitations under the License.
2660 *
2661 */
2662
2663 function plugin (userOptions) {
2664 var self = this;
2665 var orig_onOptionSelect = self.onOptionSelect;
2666 self.settings.hideSelected = false;
2667 const cbOptions = Object.assign({
2668 // so that the user may add different ones as well
2669 className: "tomselect-checkbox",
2670 // the following default to the historic plugin's values
2671 checkedClassNames: undefined,
2672 uncheckedClassNames: undefined
2673 }, userOptions);
2674 var UpdateChecked = function UpdateChecked(checkbox, toCheck) {
2675 if (toCheck) {
2676 checkbox.checked = true;
2677 if (cbOptions.uncheckedClassNames) {
2678 checkbox.classList.remove(...cbOptions.uncheckedClassNames);
2679 }
2680 if (cbOptions.checkedClassNames) {
2681 checkbox.classList.add(...cbOptions.checkedClassNames);
2682 }
2683 } else {
2684 checkbox.checked = false;
2685 if (cbOptions.checkedClassNames) {
2686 checkbox.classList.remove(...cbOptions.checkedClassNames);
2687 }
2688 if (cbOptions.uncheckedClassNames) {
2689 checkbox.classList.add(...cbOptions.uncheckedClassNames);
2690 }
2691 }
2692 };
2693
2694 // update the checkbox for an option
2695 var UpdateCheckbox = function UpdateCheckbox(option) {
2696 setTimeout(() => {
2697 var checkbox = option.querySelector('input.' + cbOptions.className);
2698 if (checkbox instanceof HTMLInputElement) {
2699 UpdateChecked(checkbox, option.classList.contains('selected'));
2700 }
2701 }, 1);
2702 };
2703
2704 // add checkbox to option template
2705 self.hook('after', 'setupTemplates', () => {
2706 var orig_render_option = self.settings.render.option;
2707 self.settings.render.option = (data, escape_html) => {
2708 var rendered = getDom(orig_render_option.call(self, data, escape_html));
2709 var checkbox = document.createElement('input');
2710 if (cbOptions.className) {
2711 checkbox.classList.add(cbOptions.className);
2712 }
2713 checkbox.addEventListener('click', function (evt) {
2714 preventDefault(evt);
2715 });
2716 checkbox.type = 'checkbox';
2717 const hashed = hash_key(data[self.settings.valueField]);
2718 UpdateChecked(checkbox, !!(hashed && self.items.indexOf(hashed) > -1));
2719 rendered.prepend(checkbox);
2720 return rendered;
2721 };
2722 });
2723
2724 // uncheck when item removed
2725 self.on('item_remove', value => {
2726 var option = self.getOption(value);
2727 if (option) {
2728 // if dropdown hasn't been opened yet, the option won't exist
2729 option.classList.remove('selected'); // selected class won't be removed yet
2730 UpdateCheckbox(option);
2731 }
2732 });
2733
2734 // check when item added
2735 self.on('item_add', value => {
2736 var option = self.getOption(value);
2737 if (option) {
2738 // if dropdown hasn't been opened yet, the option won't exist
2739 UpdateCheckbox(option);
2740 }
2741 });
2742
2743 // remove items when selected option is clicked
2744 self.hook('instead', 'onOptionSelect', (evt, option) => {
2745 if (option.classList.contains('selected')) {
2746 option.classList.remove('selected');
2747 self.removeItem(option.dataset.value);
2748 self.refreshOptions();
2749 preventDefault(evt, true);
2750 return;
2751 }
2752 orig_onOptionSelect.call(self, evt, option);
2753 UpdateCheckbox(option);
2754 });
2755 }
2756
2757
2758 //# sourceMappingURL=plugin.js.map
2759
2760
2761 /***/ },
2762
2763 /***/ "./node_modules/tom-select/dist/esm/plugins/clear_button/plugin.js"
2764 /*!*************************************************************************!*\
2765 !*** ./node_modules/tom-select/dist/esm/plugins/clear_button/plugin.js ***!
2766 \*************************************************************************/
2767 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2768
2769 __webpack_require__.r(__webpack_exports__);
2770 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2771 /* harmony export */ "default": () => (/* binding */ plugin)
2772 /* harmony export */ });
2773 /**
2774 * Tom Select v2.4.3
2775 * Licensed under the Apache License, Version 2.0 (the "License");
2776 */
2777
2778 /**
2779 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
2780 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
2781 *
2782 * param query should be {}
2783 */
2784 const getDom = query => {
2785 if (query.jquery) {
2786 return query[0];
2787 }
2788 if (query instanceof HTMLElement) {
2789 return query;
2790 }
2791 if (isHtmlString(query)) {
2792 var tpl = document.createElement('template');
2793 tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
2794 return tpl.content.firstChild;
2795 }
2796 return document.querySelector(query);
2797 };
2798 const isHtmlString = arg => {
2799 if (typeof arg === 'string' && arg.indexOf('<') > -1) {
2800 return true;
2801 }
2802 return false;
2803 };
2804
2805 /**
2806 * Plugin: "dropdown_header" (Tom Select)
2807 * Copyright (c) contributors
2808 *
2809 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
2810 * file except in compliance with the License. You may obtain a copy of the License at:
2811 * http://www.apache.org/licenses/LICENSE-2.0
2812 *
2813 * Unless required by applicable law or agreed to in writing, software distributed under
2814 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
2815 * ANY KIND, either express or implied. See the License for the specific language
2816 * governing permissions and limitations under the License.
2817 *
2818 */
2819
2820 function plugin (userOptions) {
2821 const self = this;
2822 const options = Object.assign({
2823 className: 'clear-button',
2824 title: 'Clear All',
2825 html: data => {
2826 return `<div class="${data.className}" title="${data.title}">&#10799;</div>`;
2827 }
2828 }, userOptions);
2829 self.on('initialize', () => {
2830 var button = getDom(options.html(options));
2831 button.addEventListener('click', evt => {
2832 if (self.isLocked) return;
2833 self.clear();
2834 if (self.settings.mode === 'single' && self.settings.allowEmptyOption) {
2835 self.addItem('');
2836 }
2837 evt.preventDefault();
2838 evt.stopPropagation();
2839 });
2840 self.control.appendChild(button);
2841 });
2842 }
2843
2844
2845 //# sourceMappingURL=plugin.js.map
2846
2847
2848 /***/ },
2849
2850 /***/ "./node_modules/tom-select/dist/esm/plugins/drag_drop/plugin.js"
2851 /*!**********************************************************************!*\
2852 !*** ./node_modules/tom-select/dist/esm/plugins/drag_drop/plugin.js ***!
2853 \**********************************************************************/
2854 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
2855
2856 __webpack_require__.r(__webpack_exports__);
2857 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2858 /* harmony export */ "default": () => (/* binding */ plugin)
2859 /* harmony export */ });
2860 /**
2861 * Tom Select v2.4.3
2862 * Licensed under the Apache License, Version 2.0 (the "License");
2863 */
2864
2865 /**
2866 * Converts a scalar to its best string representation
2867 * for hash keys and HTML attribute values.
2868 *
2869 * Transformations:
2870 * 'str' -> 'str'
2871 * null -> ''
2872 * undefined -> ''
2873 * true -> '1'
2874 * false -> '0'
2875 * 0 -> '0'
2876 * 1 -> '1'
2877 *
2878 */
2879
2880 /**
2881 * Prevent default
2882 *
2883 */
2884 const preventDefault = (evt, stop = false) => {
2885 if (evt) {
2886 evt.preventDefault();
2887 if (stop) {
2888 evt.stopPropagation();
2889 }
2890 }
2891 };
2892
2893 /**
2894 * Add event helper
2895 *
2896 */
2897 const addEvent = (target, type, callback, options) => {
2898 target.addEventListener(type, callback, options);
2899 };
2900
2901 /**
2902 * Iterates over arrays and hashes.
2903 *
2904 * ```
2905 * iterate(this.items, function(item, id) {
2906 * // invoked for each item
2907 * });
2908 * ```
2909 *
2910 */
2911 const iterate = (object, callback) => {
2912 if (Array.isArray(object)) {
2913 object.forEach(callback);
2914 } else {
2915 for (var key in object) {
2916 if (object.hasOwnProperty(key)) {
2917 callback(object[key], key);
2918 }
2919 }
2920 }
2921 };
2922
2923 /**
2924 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
2925 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
2926 *
2927 * param query should be {}
2928 */
2929 const getDom = query => {
2930 if (query.jquery) {
2931 return query[0];
2932 }
2933 if (query instanceof HTMLElement) {
2934 return query;
2935 }
2936 if (isHtmlString(query)) {
2937 var tpl = document.createElement('template');
2938 tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
2939 return tpl.content.firstChild;
2940 }
2941 return document.querySelector(query);
2942 };
2943 const isHtmlString = arg => {
2944 if (typeof arg === 'string' && arg.indexOf('<') > -1) {
2945 return true;
2946 }
2947 return false;
2948 };
2949
2950 /**
2951 * Set attributes of an element
2952 *
2953 */
2954 const setAttr = (el, attrs) => {
2955 iterate(attrs, (val, attr) => {
2956 if (val == null) {
2957 el.removeAttribute(attr);
2958 } else {
2959 el.setAttribute(attr, '' + val);
2960 }
2961 });
2962 };
2963
2964 /**
2965 * Plugin: "drag_drop" (Tom Select)
2966 * Copyright (c) contributors
2967 *
2968 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
2969 * file except in compliance with the License. You may obtain a copy of the License at:
2970 * http://www.apache.org/licenses/LICENSE-2.0
2971 *
2972 * Unless required by applicable law or agreed to in writing, software distributed under
2973 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
2974 * ANY KIND, either express or implied. See the License for the specific language
2975 * governing permissions and limitations under the License.
2976 *
2977 */
2978
2979 const insertAfter = (referenceNode, newNode) => {
2980 var _referenceNode$parent;
2981 (_referenceNode$parent = referenceNode.parentNode) == null || _referenceNode$parent.insertBefore(newNode, referenceNode.nextSibling);
2982 };
2983 const insertBefore = (referenceNode, newNode) => {
2984 var _referenceNode$parent2;
2985 (_referenceNode$parent2 = referenceNode.parentNode) == null || _referenceNode$parent2.insertBefore(newNode, referenceNode);
2986 };
2987 const isBefore = (referenceNode, newNode) => {
2988 do {
2989 var _newNode;
2990 newNode = (_newNode = newNode) == null ? void 0 : _newNode.previousElementSibling;
2991 if (referenceNode == newNode) {
2992 return true;
2993 }
2994 } while (newNode && newNode.previousElementSibling);
2995 return false;
2996 };
2997 function plugin () {
2998 var self = this;
2999 if (self.settings.mode !== 'multi') return;
3000 var orig_lock = self.lock;
3001 var orig_unlock = self.unlock;
3002 let sortable = true;
3003 let drag_item;
3004
3005 /**
3006 * Add draggable attribute to item
3007 */
3008 self.hook('after', 'setupTemplates', () => {
3009 var orig_render_item = self.settings.render.item;
3010 self.settings.render.item = (data, escape) => {
3011 const item = getDom(orig_render_item.call(self, data, escape));
3012 setAttr(item, {
3013 'draggable': 'true'
3014 });
3015
3016 // prevent doc_mousedown (see tom-select.ts)
3017 const mousedown = evt => {
3018 if (!sortable) preventDefault(evt);
3019 evt.stopPropagation();
3020 };
3021 const dragStart = evt => {
3022 drag_item = item;
3023 setTimeout(() => {
3024 item.classList.add('ts-dragging');
3025 }, 0);
3026 };
3027 const dragOver = evt => {
3028 evt.preventDefault();
3029 item.classList.add('ts-drag-over');
3030 moveitem(item, drag_item);
3031 };
3032 const dragLeave = () => {
3033 item.classList.remove('ts-drag-over');
3034 };
3035 const moveitem = (targetitem, dragitem) => {
3036 if (dragitem === undefined) return;
3037 if (isBefore(dragitem, item)) {
3038 insertAfter(targetitem, dragitem);
3039 } else {
3040 insertBefore(targetitem, dragitem);
3041 }
3042 };
3043 const dragend = () => {
3044 var _drag_item;
3045 document.querySelectorAll('.ts-drag-over').forEach(el => el.classList.remove('ts-drag-over'));
3046 (_drag_item = drag_item) == null || _drag_item.classList.remove('ts-dragging');
3047 drag_item = undefined;
3048 var values = [];
3049 self.control.querySelectorAll(`[data-value]`).forEach(el => {
3050 if (el.dataset.value) {
3051 let value = el.dataset.value;
3052 if (value) {
3053 values.push(value);
3054 }
3055 }
3056 });
3057 self.setValue(values);
3058 };
3059 addEvent(item, 'mousedown', mousedown);
3060 addEvent(item, 'dragstart', dragStart);
3061 addEvent(item, 'dragenter', dragOver);
3062 addEvent(item, 'dragover', dragOver);
3063 addEvent(item, 'dragleave', dragLeave);
3064 addEvent(item, 'dragend', dragend);
3065 return item;
3066 };
3067 });
3068 self.hook('instead', 'lock', () => {
3069 sortable = false;
3070 return orig_lock.call(self);
3071 });
3072 self.hook('instead', 'unlock', () => {
3073 sortable = true;
3074 return orig_unlock.call(self);
3075 });
3076 }
3077
3078
3079 //# sourceMappingURL=plugin.js.map
3080
3081
3082 /***/ },
3083
3084 /***/ "./node_modules/tom-select/dist/esm/plugins/dropdown_header/plugin.js"
3085 /*!****************************************************************************!*\
3086 !*** ./node_modules/tom-select/dist/esm/plugins/dropdown_header/plugin.js ***!
3087 \****************************************************************************/
3088 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3089
3090 __webpack_require__.r(__webpack_exports__);
3091 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3092 /* harmony export */ "default": () => (/* binding */ plugin)
3093 /* harmony export */ });
3094 /**
3095 * Tom Select v2.4.3
3096 * Licensed under the Apache License, Version 2.0 (the "License");
3097 */
3098
3099 /**
3100 * Converts a scalar to its best string representation
3101 * for hash keys and HTML attribute values.
3102 *
3103 * Transformations:
3104 * 'str' -> 'str'
3105 * null -> ''
3106 * undefined -> ''
3107 * true -> '1'
3108 * false -> '0'
3109 * 0 -> '0'
3110 * 1 -> '1'
3111 *
3112 */
3113
3114 /**
3115 * Prevent default
3116 *
3117 */
3118 const preventDefault = (evt, stop = false) => {
3119 if (evt) {
3120 evt.preventDefault();
3121 if (stop) {
3122 evt.stopPropagation();
3123 }
3124 }
3125 };
3126
3127 /**
3128 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
3129 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
3130 *
3131 * param query should be {}
3132 */
3133 const getDom = query => {
3134 if (query.jquery) {
3135 return query[0];
3136 }
3137 if (query instanceof HTMLElement) {
3138 return query;
3139 }
3140 if (isHtmlString(query)) {
3141 var tpl = document.createElement('template');
3142 tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
3143 return tpl.content.firstChild;
3144 }
3145 return document.querySelector(query);
3146 };
3147 const isHtmlString = arg => {
3148 if (typeof arg === 'string' && arg.indexOf('<') > -1) {
3149 return true;
3150 }
3151 return false;
3152 };
3153
3154 /**
3155 * Plugin: "dropdown_header" (Tom Select)
3156 * Copyright (c) contributors
3157 *
3158 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3159 * file except in compliance with the License. You may obtain a copy of the License at:
3160 * http://www.apache.org/licenses/LICENSE-2.0
3161 *
3162 * Unless required by applicable law or agreed to in writing, software distributed under
3163 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3164 * ANY KIND, either express or implied. See the License for the specific language
3165 * governing permissions and limitations under the License.
3166 *
3167 */
3168
3169 function plugin (userOptions) {
3170 const self = this;
3171 const options = Object.assign({
3172 title: 'Untitled',
3173 headerClass: 'dropdown-header',
3174 titleRowClass: 'dropdown-header-title',
3175 labelClass: 'dropdown-header-label',
3176 closeClass: 'dropdown-header-close',
3177 html: data => {
3178 return '<div class="' + data.headerClass + '">' + '<div class="' + data.titleRowClass + '">' + '<span class="' + data.labelClass + '">' + data.title + '</span>' + '<a class="' + data.closeClass + '">&times;</a>' + '</div>' + '</div>';
3179 }
3180 }, userOptions);
3181 self.on('initialize', () => {
3182 var header = getDom(options.html(options));
3183 var close_link = header.querySelector('.' + options.closeClass);
3184 if (close_link) {
3185 close_link.addEventListener('click', evt => {
3186 preventDefault(evt, true);
3187 self.close();
3188 });
3189 }
3190 self.dropdown.insertBefore(header, self.dropdown.firstChild);
3191 });
3192 }
3193
3194
3195 //# sourceMappingURL=plugin.js.map
3196
3197
3198 /***/ },
3199
3200 /***/ "./node_modules/tom-select/dist/esm/plugins/dropdown_input/plugin.js"
3201 /*!***************************************************************************!*\
3202 !*** ./node_modules/tom-select/dist/esm/plugins/dropdown_input/plugin.js ***!
3203 \***************************************************************************/
3204 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3205
3206 __webpack_require__.r(__webpack_exports__);
3207 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3208 /* harmony export */ "default": () => (/* binding */ plugin)
3209 /* harmony export */ });
3210 /**
3211 * Tom Select v2.4.3
3212 * Licensed under the Apache License, Version 2.0 (the "License");
3213 */
3214
3215 const KEY_ESC = 27;
3216 const KEY_TAB = 9;
3217 // ctrl key or apple key for ma
3218
3219 /**
3220 * Converts a scalar to its best string representation
3221 * for hash keys and HTML attribute values.
3222 *
3223 * Transformations:
3224 * 'str' -> 'str'
3225 * null -> ''
3226 * undefined -> ''
3227 * true -> '1'
3228 * false -> '0'
3229 * 0 -> '0'
3230 * 1 -> '1'
3231 *
3232 */
3233
3234 /**
3235 * Prevent default
3236 *
3237 */
3238 const preventDefault = (evt, stop = false) => {
3239 if (evt) {
3240 evt.preventDefault();
3241 if (stop) {
3242 evt.stopPropagation();
3243 }
3244 }
3245 };
3246
3247 /**
3248 * Add event helper
3249 *
3250 */
3251 const addEvent = (target, type, callback, options) => {
3252 target.addEventListener(type, callback, options);
3253 };
3254
3255 /**
3256 * Iterates over arrays and hashes.
3257 *
3258 * ```
3259 * iterate(this.items, function(item, id) {
3260 * // invoked for each item
3261 * });
3262 * ```
3263 *
3264 */
3265 const iterate = (object, callback) => {
3266 if (Array.isArray(object)) {
3267 object.forEach(callback);
3268 } else {
3269 for (var key in object) {
3270 if (object.hasOwnProperty(key)) {
3271 callback(object[key], key);
3272 }
3273 }
3274 }
3275 };
3276
3277 /**
3278 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
3279 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
3280 *
3281 * param query should be {}
3282 */
3283 const getDom = query => {
3284 if (query.jquery) {
3285 return query[0];
3286 }
3287 if (query instanceof HTMLElement) {
3288 return query;
3289 }
3290 if (isHtmlString(query)) {
3291 var tpl = document.createElement('template');
3292 tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
3293 return tpl.content.firstChild;
3294 }
3295 return document.querySelector(query);
3296 };
3297 const isHtmlString = arg => {
3298 if (typeof arg === 'string' && arg.indexOf('<') > -1) {
3299 return true;
3300 }
3301 return false;
3302 };
3303
3304 /**
3305 * Add css classes
3306 *
3307 */
3308 const addClasses = (elmts, ...classes) => {
3309 var norm_classes = classesArray(classes);
3310 elmts = castAsArray(elmts);
3311 elmts.map(el => {
3312 norm_classes.map(cls => {
3313 el.classList.add(cls);
3314 });
3315 });
3316 };
3317
3318 /**
3319 * Return arguments
3320 *
3321 */
3322 const classesArray = args => {
3323 var classes = [];
3324 iterate(args, _classes => {
3325 if (typeof _classes === 'string') {
3326 _classes = _classes.trim().split(/[\t\n\f\r\s]/);
3327 }
3328 if (Array.isArray(_classes)) {
3329 classes = classes.concat(_classes);
3330 }
3331 });
3332 return classes.filter(Boolean);
3333 };
3334
3335 /**
3336 * Create an array from arg if it's not already an array
3337 *
3338 */
3339 const castAsArray = arg => {
3340 if (!Array.isArray(arg)) {
3341 arg = [arg];
3342 }
3343 return arg;
3344 };
3345
3346 /**
3347 * Plugin: "dropdown_input" (Tom Select)
3348 * Copyright (c) contributors
3349 *
3350 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3351 * file except in compliance with the License. You may obtain a copy of the License at:
3352 * http://www.apache.org/licenses/LICENSE-2.0
3353 *
3354 * Unless required by applicable law or agreed to in writing, software distributed under
3355 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3356 * ANY KIND, either express or implied. See the License for the specific language
3357 * governing permissions and limitations under the License.
3358 *
3359 */
3360
3361 function plugin () {
3362 const self = this;
3363 self.settings.shouldOpen = true; // make sure the input is shown even if there are no options to display in the dropdown
3364
3365 self.hook('before', 'setup', () => {
3366 self.focus_node = self.control;
3367 addClasses(self.control_input, 'dropdown-input');
3368 const div = getDom('<div class="dropdown-input-wrap">');
3369 div.append(self.control_input);
3370 self.dropdown.insertBefore(div, self.dropdown.firstChild);
3371
3372 // set a placeholder in the select control
3373 const placeholder = getDom('<input class="items-placeholder" tabindex="-1" />');
3374 placeholder.placeholder = self.settings.placeholder || '';
3375 self.control.append(placeholder);
3376 });
3377 self.on('initialize', () => {
3378 // set tabIndex on control to -1, otherwise [shift+tab] will put focus right back on control_input
3379 self.control_input.addEventListener('keydown', evt => {
3380 //addEvent(self.control_input,'keydown' as const,(evt:KeyboardEvent) =>{
3381 switch (evt.keyCode) {
3382 case KEY_ESC:
3383 if (self.isOpen) {
3384 preventDefault(evt, true);
3385 self.close();
3386 }
3387 self.clearActiveItems();
3388 return;
3389 case KEY_TAB:
3390 self.focus_node.tabIndex = -1;
3391 break;
3392 }
3393 return self.onKeyDown.call(self, evt);
3394 });
3395 self.on('blur', () => {
3396 self.focus_node.tabIndex = self.isDisabled ? -1 : self.tabIndex;
3397 });
3398
3399 // give the control_input focus when the dropdown is open
3400 self.on('dropdown_open', () => {
3401 self.control_input.focus();
3402 });
3403
3404 // prevent onBlur from closing when focus is on the control_input
3405 const orig_onBlur = self.onBlur;
3406 self.hook('instead', 'onBlur', evt => {
3407 if (evt && evt.relatedTarget == self.control_input) return;
3408 return orig_onBlur.call(self);
3409 });
3410 addEvent(self.control_input, 'blur', () => self.onBlur());
3411
3412 // return focus to control to allow further keyboard input
3413 self.hook('before', 'close', () => {
3414 if (!self.isOpen) return;
3415 self.focus_node.focus({
3416 preventScroll: true
3417 });
3418 });
3419 });
3420 }
3421
3422
3423 //# sourceMappingURL=plugin.js.map
3424
3425
3426 /***/ },
3427
3428 /***/ "./node_modules/tom-select/dist/esm/plugins/input_autogrow/plugin.js"
3429 /*!***************************************************************************!*\
3430 !*** ./node_modules/tom-select/dist/esm/plugins/input_autogrow/plugin.js ***!
3431 \***************************************************************************/
3432 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3433
3434 __webpack_require__.r(__webpack_exports__);
3435 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3436 /* harmony export */ "default": () => (/* binding */ plugin)
3437 /* harmony export */ });
3438 /**
3439 * Tom Select v2.4.3
3440 * Licensed under the Apache License, Version 2.0 (the "License");
3441 */
3442
3443 /**
3444 * Converts a scalar to its best string representation
3445 * for hash keys and HTML attribute values.
3446 *
3447 * Transformations:
3448 * 'str' -> 'str'
3449 * null -> ''
3450 * undefined -> ''
3451 * true -> '1'
3452 * false -> '0'
3453 * 0 -> '0'
3454 * 1 -> '1'
3455 *
3456 */
3457
3458 /**
3459 * Add event helper
3460 *
3461 */
3462 const addEvent = (target, type, callback, options) => {
3463 target.addEventListener(type, callback, options);
3464 };
3465
3466 /**
3467 * Plugin: "input_autogrow" (Tom Select)
3468 *
3469 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3470 * file except in compliance with the License. You may obtain a copy of the License at:
3471 * http://www.apache.org/licenses/LICENSE-2.0
3472 *
3473 * Unless required by applicable law or agreed to in writing, software distributed under
3474 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3475 * ANY KIND, either express or implied. See the License for the specific language
3476 * governing permissions and limitations under the License.
3477 *
3478 */
3479
3480 function plugin () {
3481 var self = this;
3482 self.on('initialize', () => {
3483 var test_input = document.createElement('span');
3484 var control = self.control_input;
3485 test_input.style.cssText = 'position:absolute; top:-99999px; left:-99999px; width:auto; padding:0; white-space:pre; ';
3486 self.wrapper.appendChild(test_input);
3487 var transfer_styles = ['letterSpacing', 'fontSize', 'fontFamily', 'fontWeight', 'textTransform'];
3488 for (const style_name of transfer_styles) {
3489 // @ts-ignore TS7015 https://stackoverflow.com/a/50506154/697576
3490 test_input.style[style_name] = control.style[style_name];
3491 }
3492
3493 /**
3494 * Set the control width
3495 *
3496 */
3497 var resize = () => {
3498 test_input.textContent = control.value;
3499 control.style.width = test_input.clientWidth + 'px';
3500 };
3501 resize();
3502 self.on('update item_add item_remove', resize);
3503 addEvent(control, 'input', resize);
3504 addEvent(control, 'keyup', resize);
3505 addEvent(control, 'blur', resize);
3506 addEvent(control, 'update', resize);
3507 });
3508 }
3509
3510
3511 //# sourceMappingURL=plugin.js.map
3512
3513
3514 /***/ },
3515
3516 /***/ "./node_modules/tom-select/dist/esm/plugins/no_active_items/plugin.js"
3517 /*!****************************************************************************!*\
3518 !*** ./node_modules/tom-select/dist/esm/plugins/no_active_items/plugin.js ***!
3519 \****************************************************************************/
3520 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3521
3522 __webpack_require__.r(__webpack_exports__);
3523 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3524 /* harmony export */ "default": () => (/* binding */ plugin)
3525 /* harmony export */ });
3526 /**
3527 * Tom Select v2.4.3
3528 * Licensed under the Apache License, Version 2.0 (the "License");
3529 */
3530
3531 /**
3532 * Plugin: "no_active_items" (Tom Select)
3533 *
3534 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3535 * file except in compliance with the License. You may obtain a copy of the License at:
3536 * http://www.apache.org/licenses/LICENSE-2.0
3537 *
3538 * Unless required by applicable law or agreed to in writing, software distributed under
3539 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3540 * ANY KIND, either express or implied. See the License for the specific language
3541 * governing permissions and limitations under the License.
3542 *
3543 */
3544
3545 function plugin () {
3546 this.hook('instead', 'setActiveItem', () => {});
3547 this.hook('instead', 'selectAll', () => {});
3548 }
3549
3550
3551 //# sourceMappingURL=plugin.js.map
3552
3553
3554 /***/ },
3555
3556 /***/ "./node_modules/tom-select/dist/esm/plugins/no_backspace_delete/plugin.js"
3557 /*!********************************************************************************!*\
3558 !*** ./node_modules/tom-select/dist/esm/plugins/no_backspace_delete/plugin.js ***!
3559 \********************************************************************************/
3560 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3561
3562 __webpack_require__.r(__webpack_exports__);
3563 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3564 /* harmony export */ "default": () => (/* binding */ plugin)
3565 /* harmony export */ });
3566 /**
3567 * Tom Select v2.4.3
3568 * Licensed under the Apache License, Version 2.0 (the "License");
3569 */
3570
3571 /**
3572 * Plugin: "input_autogrow" (Tom Select)
3573 *
3574 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3575 * file except in compliance with the License. You may obtain a copy of the License at:
3576 * http://www.apache.org/licenses/LICENSE-2.0
3577 *
3578 * Unless required by applicable law or agreed to in writing, software distributed under
3579 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3580 * ANY KIND, either express or implied. See the License for the specific language
3581 * governing permissions and limitations under the License.
3582 *
3583 */
3584
3585 function plugin () {
3586 var self = this;
3587 var orig_deleteSelection = self.deleteSelection;
3588 this.hook('instead', 'deleteSelection', evt => {
3589 if (self.activeItems.length) {
3590 return orig_deleteSelection.call(self, evt);
3591 }
3592 return false;
3593 });
3594 }
3595
3596
3597 //# sourceMappingURL=plugin.js.map
3598
3599
3600 /***/ },
3601
3602 /***/ "./node_modules/tom-select/dist/esm/plugins/optgroup_columns/plugin.js"
3603 /*!*****************************************************************************!*\
3604 !*** ./node_modules/tom-select/dist/esm/plugins/optgroup_columns/plugin.js ***!
3605 \*****************************************************************************/
3606 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3607
3608 __webpack_require__.r(__webpack_exports__);
3609 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3610 /* harmony export */ "default": () => (/* binding */ plugin)
3611 /* harmony export */ });
3612 /**
3613 * Tom Select v2.4.3
3614 * Licensed under the Apache License, Version 2.0 (the "License");
3615 */
3616
3617 const KEY_LEFT = 37;
3618 const KEY_RIGHT = 39;
3619 // ctrl key or apple key for ma
3620
3621 /**
3622 * Get the closest node to the evt.target matching the selector
3623 * Stops at wrapper
3624 *
3625 */
3626 const parentMatch = (target, selector, wrapper) => {
3627 while (target && target.matches) {
3628 if (target.matches(selector)) {
3629 return target;
3630 }
3631 target = target.parentNode;
3632 }
3633 };
3634
3635 /**
3636 * Get the index of an element amongst sibling nodes of the same type
3637 *
3638 */
3639 const nodeIndex = (el, amongst) => {
3640 if (!el) return -1;
3641 amongst = amongst || el.nodeName;
3642 var i = 0;
3643 while (el = el.previousElementSibling) {
3644 if (el.matches(amongst)) {
3645 i++;
3646 }
3647 }
3648 return i;
3649 };
3650
3651 /**
3652 * Plugin: "optgroup_columns" (Tom Select.js)
3653 * Copyright (c) contributors
3654 *
3655 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3656 * file except in compliance with the License. You may obtain a copy of the License at:
3657 * http://www.apache.org/licenses/LICENSE-2.0
3658 *
3659 * Unless required by applicable law or agreed to in writing, software distributed under
3660 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3661 * ANY KIND, either express or implied. See the License for the specific language
3662 * governing permissions and limitations under the License.
3663 *
3664 */
3665
3666 function plugin () {
3667 var self = this;
3668 var orig_keydown = self.onKeyDown;
3669 self.hook('instead', 'onKeyDown', evt => {
3670 var index, option, options, optgroup;
3671 if (!self.isOpen || !(evt.keyCode === KEY_LEFT || evt.keyCode === KEY_RIGHT)) {
3672 return orig_keydown.call(self, evt);
3673 }
3674 self.ignoreHover = true;
3675 optgroup = parentMatch(self.activeOption, '[data-group]');
3676 index = nodeIndex(self.activeOption, '[data-selectable]');
3677 if (!optgroup) {
3678 return;
3679 }
3680 if (evt.keyCode === KEY_LEFT) {
3681 optgroup = optgroup.previousSibling;
3682 } else {
3683 optgroup = optgroup.nextSibling;
3684 }
3685 if (!optgroup) {
3686 return;
3687 }
3688 options = optgroup.querySelectorAll('[data-selectable]');
3689 option = options[Math.min(options.length - 1, index)];
3690 if (option) {
3691 self.setActiveOption(option);
3692 }
3693 });
3694 }
3695
3696
3697 //# sourceMappingURL=plugin.js.map
3698
3699
3700 /***/ },
3701
3702 /***/ "./node_modules/tom-select/dist/esm/plugins/remove_button/plugin.js"
3703 /*!**************************************************************************!*\
3704 !*** ./node_modules/tom-select/dist/esm/plugins/remove_button/plugin.js ***!
3705 \**************************************************************************/
3706 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3707
3708 __webpack_require__.r(__webpack_exports__);
3709 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3710 /* harmony export */ "default": () => (/* binding */ plugin)
3711 /* harmony export */ });
3712 /**
3713 * Tom Select v2.4.3
3714 * Licensed under the Apache License, Version 2.0 (the "License");
3715 */
3716
3717 /**
3718 * Converts a scalar to its best string representation
3719 * for hash keys and HTML attribute values.
3720 *
3721 * Transformations:
3722 * 'str' -> 'str'
3723 * null -> ''
3724 * undefined -> ''
3725 * true -> '1'
3726 * false -> '0'
3727 * 0 -> '0'
3728 * 1 -> '1'
3729 *
3730 */
3731
3732 /**
3733 * Escapes a string for use within HTML.
3734 *
3735 */
3736 const escape_html = str => {
3737 return (str + '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
3738 };
3739
3740 /**
3741 * Prevent default
3742 *
3743 */
3744 const preventDefault = (evt, stop = false) => {
3745 if (evt) {
3746 evt.preventDefault();
3747 if (stop) {
3748 evt.stopPropagation();
3749 }
3750 }
3751 };
3752
3753 /**
3754 * Add event helper
3755 *
3756 */
3757 const addEvent = (target, type, callback, options) => {
3758 target.addEventListener(type, callback, options);
3759 };
3760
3761 /**
3762 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
3763 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
3764 *
3765 * param query should be {}
3766 */
3767 const getDom = query => {
3768 if (query.jquery) {
3769 return query[0];
3770 }
3771 if (query instanceof HTMLElement) {
3772 return query;
3773 }
3774 if (isHtmlString(query)) {
3775 var tpl = document.createElement('template');
3776 tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
3777 return tpl.content.firstChild;
3778 }
3779 return document.querySelector(query);
3780 };
3781 const isHtmlString = arg => {
3782 if (typeof arg === 'string' && arg.indexOf('<') > -1) {
3783 return true;
3784 }
3785 return false;
3786 };
3787
3788 /**
3789 * Plugin: "remove_button" (Tom Select)
3790 * Copyright (c) contributors
3791 *
3792 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3793 * file except in compliance with the License. You may obtain a copy of the License at:
3794 * http://www.apache.org/licenses/LICENSE-2.0
3795 *
3796 * Unless required by applicable law or agreed to in writing, software distributed under
3797 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3798 * ANY KIND, either express or implied. See the License for the specific language
3799 * governing permissions and limitations under the License.
3800 *
3801 */
3802
3803 function plugin (userOptions) {
3804 const options = Object.assign({
3805 label: '&times;',
3806 title: 'Remove',
3807 className: 'remove',
3808 append: true
3809 }, userOptions);
3810
3811 //options.className = 'remove-single';
3812 var self = this;
3813
3814 // override the render method to add remove button to each item
3815 if (!options.append) {
3816 return;
3817 }
3818 var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';
3819 self.hook('after', 'setupTemplates', () => {
3820 var orig_render_item = self.settings.render.item;
3821 self.settings.render.item = (data, escape) => {
3822 var item = getDom(orig_render_item.call(self, data, escape));
3823 var close_button = getDom(html);
3824 item.appendChild(close_button);
3825 addEvent(close_button, 'mousedown', evt => {
3826 preventDefault(evt, true);
3827 });
3828 addEvent(close_button, 'click', evt => {
3829 if (self.isLocked) return;
3830
3831 // propagating will trigger the dropdown to show for single mode
3832 preventDefault(evt, true);
3833 if (self.isLocked) return;
3834 if (!self.shouldDelete([item], evt)) return;
3835 self.removeItem(item);
3836 self.refreshOptions(false);
3837 self.inputState();
3838 });
3839 return item;
3840 };
3841 });
3842 }
3843
3844
3845 //# sourceMappingURL=plugin.js.map
3846
3847
3848 /***/ },
3849
3850 /***/ "./node_modules/tom-select/dist/esm/plugins/restore_on_backspace/plugin.js"
3851 /*!*********************************************************************************!*\
3852 !*** ./node_modules/tom-select/dist/esm/plugins/restore_on_backspace/plugin.js ***!
3853 \*********************************************************************************/
3854 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3855
3856 __webpack_require__.r(__webpack_exports__);
3857 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3858 /* harmony export */ "default": () => (/* binding */ plugin)
3859 /* harmony export */ });
3860 /**
3861 * Tom Select v2.4.3
3862 * Licensed under the Apache License, Version 2.0 (the "License");
3863 */
3864
3865 /**
3866 * Plugin: "restore_on_backspace" (Tom Select)
3867 * Copyright (c) contributors
3868 *
3869 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
3870 * file except in compliance with the License. You may obtain a copy of the License at:
3871 * http://www.apache.org/licenses/LICENSE-2.0
3872 *
3873 * Unless required by applicable law or agreed to in writing, software distributed under
3874 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
3875 * ANY KIND, either express or implied. See the License for the specific language
3876 * governing permissions and limitations under the License.
3877 *
3878 */
3879
3880 function plugin (userOptions) {
3881 const self = this;
3882 const options = Object.assign({
3883 text: option => {
3884 return option[self.settings.labelField];
3885 }
3886 }, userOptions);
3887 self.on('item_remove', function (value) {
3888 if (!self.isFocused) {
3889 return;
3890 }
3891 if (self.control_input.value.trim() === '') {
3892 var option = self.options[value];
3893 if (option) {
3894 self.setTextboxValue(options.text.call(self, option));
3895 }
3896 }
3897 });
3898 }
3899
3900
3901 //# sourceMappingURL=plugin.js.map
3902
3903
3904 /***/ },
3905
3906 /***/ "./node_modules/tom-select/dist/esm/plugins/virtual_scroll/plugin.js"
3907 /*!***************************************************************************!*\
3908 !*** ./node_modules/tom-select/dist/esm/plugins/virtual_scroll/plugin.js ***!
3909 \***************************************************************************/
3910 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3911
3912 __webpack_require__.r(__webpack_exports__);
3913 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3914 /* harmony export */ "default": () => (/* binding */ plugin)
3915 /* harmony export */ });
3916 /**
3917 * Tom Select v2.4.3
3918 * Licensed under the Apache License, Version 2.0 (the "License");
3919 */
3920
3921 /**
3922 * Converts a scalar to its best string representation
3923 * for hash keys and HTML attribute values.
3924 *
3925 * Transformations:
3926 * 'str' -> 'str'
3927 * null -> ''
3928 * undefined -> ''
3929 * true -> '1'
3930 * false -> '0'
3931 * 0 -> '0'
3932 * 1 -> '1'
3933 *
3934 */
3935
3936 /**
3937 * Iterates over arrays and hashes.
3938 *
3939 * ```
3940 * iterate(this.items, function(item, id) {
3941 * // invoked for each item
3942 * });
3943 * ```
3944 *
3945 */
3946 const iterate = (object, callback) => {
3947 if (Array.isArray(object)) {
3948 object.forEach(callback);
3949 } else {
3950 for (var key in object) {
3951 if (object.hasOwnProperty(key)) {
3952 callback(object[key], key);
3953 }
3954 }
3955 }
3956 };
3957
3958 /**
3959 * Add css classes
3960 *
3961 */
3962 const addClasses = (elmts, ...classes) => {
3963 var norm_classes = classesArray(classes);
3964 elmts = castAsArray(elmts);
3965 elmts.map(el => {
3966 norm_classes.map(cls => {
3967 el.classList.add(cls);
3968 });
3969 });
3970 };
3971
3972 /**
3973 * Return arguments
3974 *
3975 */
3976 const classesArray = args => {
3977 var classes = [];
3978 iterate(args, _classes => {
3979 if (typeof _classes === 'string') {
3980 _classes = _classes.trim().split(/[\t\n\f\r\s]/);
3981 }
3982 if (Array.isArray(_classes)) {
3983 classes = classes.concat(_classes);
3984 }
3985 });
3986 return classes.filter(Boolean);
3987 };
3988
3989 /**
3990 * Create an array from arg if it's not already an array
3991 *
3992 */
3993 const castAsArray = arg => {
3994 if (!Array.isArray(arg)) {
3995 arg = [arg];
3996 }
3997 return arg;
3998 };
3999
4000 /**
4001 * Plugin: "restore_on_backspace" (Tom Select)
4002 * Copyright (c) contributors
4003 *
4004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4005 * file except in compliance with the License. You may obtain a copy of the License at:
4006 * http://www.apache.org/licenses/LICENSE-2.0
4007 *
4008 * Unless required by applicable law or agreed to in writing, software distributed under
4009 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4010 * ANY KIND, either express or implied. See the License for the specific language
4011 * governing permissions and limitations under the License.
4012 *
4013 */
4014
4015 function plugin () {
4016 const self = this;
4017 const orig_canLoad = self.canLoad;
4018 const orig_clearActiveOption = self.clearActiveOption;
4019 const orig_loadCallback = self.loadCallback;
4020 var pagination = {};
4021 var dropdown_content;
4022 var loading_more = false;
4023 var load_more_opt;
4024 var default_values = [];
4025 if (!self.settings.shouldLoadMore) {
4026 // return true if additional results should be loaded
4027 self.settings.shouldLoadMore = () => {
4028 const scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);
4029 if (scroll_percent > 0.9) {
4030 return true;
4031 }
4032 if (self.activeOption) {
4033 var selectable = self.selectable();
4034 var index = Array.from(selectable).indexOf(self.activeOption);
4035 if (index >= selectable.length - 2) {
4036 return true;
4037 }
4038 }
4039 return false;
4040 };
4041 }
4042 if (!self.settings.firstUrl) {
4043 throw 'virtual_scroll plugin requires a firstUrl() method';
4044 }
4045
4046 // in order for virtual scrolling to work,
4047 // options need to be ordered the same way they're returned from the remote data source
4048 self.settings.sortField = [{
4049 field: '$order'
4050 }, {
4051 field: '$score'
4052 }];
4053
4054 // can we load more results for given query?
4055 const canLoadMore = query => {
4056 if (typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions) {
4057 return false;
4058 }
4059 if (query in pagination && pagination[query]) {
4060 return true;
4061 }
4062 return false;
4063 };
4064 const clearFilter = (option, value) => {
4065 if (self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0) {
4066 return true;
4067 }
4068 return false;
4069 };
4070
4071 // set the next url that will be
4072 self.setNextUrl = (value, next_url) => {
4073 pagination[value] = next_url;
4074 };
4075
4076 // getUrl() to be used in settings.load()
4077 self.getUrl = query => {
4078 if (query in pagination) {
4079 const next_url = pagination[query];
4080 pagination[query] = false;
4081 return next_url;
4082 }
4083
4084 // if the user goes back to a previous query
4085 // we need to load the first page again
4086 self.clearPagination();
4087 return self.settings.firstUrl.call(self, query);
4088 };
4089
4090 // clear pagination
4091 self.clearPagination = () => {
4092 pagination = {};
4093 };
4094
4095 // don't clear the active option (and cause unwanted dropdown scroll)
4096 // while loading more results
4097 self.hook('instead', 'clearActiveOption', () => {
4098 if (loading_more) {
4099 return;
4100 }
4101 return orig_clearActiveOption.call(self);
4102 });
4103
4104 // override the canLoad method
4105 self.hook('instead', 'canLoad', query => {
4106 // first time the query has been seen
4107 if (!(query in pagination)) {
4108 return orig_canLoad.call(self, query);
4109 }
4110 return canLoadMore(query);
4111 });
4112
4113 // wrap the load
4114 self.hook('instead', 'loadCallback', (options, optgroups) => {
4115 if (!loading_more) {
4116 self.clearOptions(clearFilter);
4117 } else if (load_more_opt) {
4118 const first_option = options[0];
4119 if (first_option !== undefined) {
4120 load_more_opt.dataset.value = first_option[self.settings.valueField];
4121 }
4122 }
4123 orig_loadCallback.call(self, options, optgroups);
4124 loading_more = false;
4125 });
4126
4127 // add templates to dropdown
4128 // loading_more if we have another url in the queue
4129 // no_more_results if we don't have another url in the queue
4130 self.hook('after', 'refreshOptions', () => {
4131 const query = self.lastValue;
4132 var option;
4133 if (canLoadMore(query)) {
4134 option = self.render('loading_more', {
4135 query: query
4136 });
4137 if (option) {
4138 option.setAttribute('data-selectable', ''); // so that navigating dropdown with [down] keypresses can navigate to this node
4139 load_more_opt = option;
4140 }
4141 } else if (query in pagination && !dropdown_content.querySelector('.no-results')) {
4142 option = self.render('no_more_results', {
4143 query: query
4144 });
4145 }
4146 if (option) {
4147 addClasses(option, self.settings.optionClass);
4148 dropdown_content.append(option);
4149 }
4150 });
4151
4152 // add scroll listener and default templates
4153 self.on('initialize', () => {
4154 default_values = Object.keys(self.options);
4155 dropdown_content = self.dropdown_content;
4156
4157 // default templates
4158 self.settings.render = Object.assign({}, {
4159 loading_more: () => {
4160 return `<div class="loading-more-results">Loading more results ... </div>`;
4161 },
4162 no_more_results: () => {
4163 return `<div class="no-more-results">No more results</div>`;
4164 }
4165 }, self.settings.render);
4166
4167 // watch dropdown content scroll position
4168 dropdown_content.addEventListener('scroll', () => {
4169 if (!self.settings.shouldLoadMore.call(self)) {
4170 return;
4171 }
4172
4173 // !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true
4174 if (!canLoadMore(self.lastValue)) {
4175 return;
4176 }
4177
4178 // don't call load() too much
4179 if (loading_more) return;
4180 loading_more = true;
4181 self.load.call(self, self.lastValue);
4182 });
4183 });
4184 }
4185
4186
4187 //# sourceMappingURL=plugin.js.map
4188
4189
4190 /***/ },
4191
4192 /***/ "./node_modules/tom-select/dist/esm/tom-select.complete.js"
4193 /*!*****************************************************************!*\
4194 !*** ./node_modules/tom-select/dist/esm/tom-select.complete.js ***!
4195 \*****************************************************************/
4196 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
4197
4198 __webpack_require__.r(__webpack_exports__);
4199 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4200 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
4201 /* harmony export */ });
4202 /* harmony import */ var _tom_select_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tom-select.js */ "./node_modules/tom-select/dist/esm/tom-select.js");
4203 /* harmony import */ var _plugins_change_listener_plugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./plugins/change_listener/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/change_listener/plugin.js");
4204 /* harmony import */ var _plugins_checkbox_options_plugin_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./plugins/checkbox_options/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/checkbox_options/plugin.js");
4205 /* harmony import */ var _plugins_clear_button_plugin_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./plugins/clear_button/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/clear_button/plugin.js");
4206 /* harmony import */ var _plugins_drag_drop_plugin_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./plugins/drag_drop/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/drag_drop/plugin.js");
4207 /* harmony import */ var _plugins_dropdown_header_plugin_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./plugins/dropdown_header/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/dropdown_header/plugin.js");
4208 /* harmony import */ var _plugins_caret_position_plugin_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./plugins/caret_position/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/caret_position/plugin.js");
4209 /* harmony import */ var _plugins_dropdown_input_plugin_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./plugins/dropdown_input/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/dropdown_input/plugin.js");
4210 /* harmony import */ var _plugins_input_autogrow_plugin_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./plugins/input_autogrow/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/input_autogrow/plugin.js");
4211 /* harmony import */ var _plugins_no_backspace_delete_plugin_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./plugins/no_backspace_delete/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/no_backspace_delete/plugin.js");
4212 /* harmony import */ var _plugins_no_active_items_plugin_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./plugins/no_active_items/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/no_active_items/plugin.js");
4213 /* harmony import */ var _plugins_optgroup_columns_plugin_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./plugins/optgroup_columns/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/optgroup_columns/plugin.js");
4214 /* harmony import */ var _plugins_remove_button_plugin_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./plugins/remove_button/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/remove_button/plugin.js");
4215 /* harmony import */ var _plugins_restore_on_backspace_plugin_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./plugins/restore_on_backspace/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/restore_on_backspace/plugin.js");
4216 /* harmony import */ var _plugins_virtual_scroll_plugin_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./plugins/virtual_scroll/plugin.js */ "./node_modules/tom-select/dist/esm/plugins/virtual_scroll/plugin.js");
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('change_listener', _plugins_change_listener_plugin_js__WEBPACK_IMPORTED_MODULE_1__["default"]);
4233 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('checkbox_options', _plugins_checkbox_options_plugin_js__WEBPACK_IMPORTED_MODULE_2__["default"]);
4234 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('clear_button', _plugins_clear_button_plugin_js__WEBPACK_IMPORTED_MODULE_3__["default"]);
4235 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('drag_drop', _plugins_drag_drop_plugin_js__WEBPACK_IMPORTED_MODULE_4__["default"]);
4236 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('dropdown_header', _plugins_dropdown_header_plugin_js__WEBPACK_IMPORTED_MODULE_5__["default"]);
4237 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('caret_position', _plugins_caret_position_plugin_js__WEBPACK_IMPORTED_MODULE_6__["default"]);
4238 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('dropdown_input', _plugins_dropdown_input_plugin_js__WEBPACK_IMPORTED_MODULE_7__["default"]);
4239 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('input_autogrow', _plugins_input_autogrow_plugin_js__WEBPACK_IMPORTED_MODULE_8__["default"]);
4240 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('no_backspace_delete', _plugins_no_backspace_delete_plugin_js__WEBPACK_IMPORTED_MODULE_9__["default"]);
4241 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('no_active_items', _plugins_no_active_items_plugin_js__WEBPACK_IMPORTED_MODULE_10__["default"]);
4242 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('optgroup_columns', _plugins_optgroup_columns_plugin_js__WEBPACK_IMPORTED_MODULE_11__["default"]);
4243 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('remove_button', _plugins_remove_button_plugin_js__WEBPACK_IMPORTED_MODULE_12__["default"]);
4244 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('restore_on_backspace', _plugins_restore_on_backspace_plugin_js__WEBPACK_IMPORTED_MODULE_13__["default"]);
4245 _tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"].define('virtual_scroll', _plugins_virtual_scroll_plugin_js__WEBPACK_IMPORTED_MODULE_14__["default"]);
4246 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_tom_select_js__WEBPACK_IMPORTED_MODULE_0__["default"]);
4247 //# sourceMappingURL=tom-select.complete.js.map
4248
4249 /***/ },
4250
4251 /***/ "./node_modules/tom-select/dist/esm/tom-select.js"
4252 /*!********************************************************!*\
4253 !*** ./node_modules/tom-select/dist/esm/tom-select.js ***!
4254 \********************************************************/
4255 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
4256
4257 __webpack_require__.r(__webpack_exports__);
4258 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4259 /* harmony export */ "default": () => (/* binding */ TomSelect)
4260 /* harmony export */ });
4261 /* harmony import */ var _contrib_microevent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./contrib/microevent.js */ "./node_modules/tom-select/dist/esm/contrib/microevent.js");
4262 /* harmony import */ var _contrib_microplugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./contrib/microplugin.js */ "./node_modules/tom-select/dist/esm/contrib/microplugin.js");
4263 /* harmony import */ var _orchidjs_sifter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @orchidjs/sifter */ "./node_modules/@orchidjs/sifter/dist/esm/sifter.js");
4264 /* harmony import */ var _orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @orchidjs/unicode-variants */ "./node_modules/@orchidjs/unicode-variants/dist/esm/index.js");
4265 /* harmony import */ var _contrib_highlight_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./contrib/highlight.js */ "./node_modules/tom-select/dist/esm/contrib/highlight.js");
4266 /* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./constants.js */ "./node_modules/tom-select/dist/esm/constants.js");
4267 /* harmony import */ var _getSettings_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./getSettings.js */ "./node_modules/tom-select/dist/esm/getSettings.js");
4268 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./utils.js */ "./node_modules/tom-select/dist/esm/utils.js");
4269 /* harmony import */ var _vanilla_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./vanilla.js */ "./node_modules/tom-select/dist/esm/vanilla.js");
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279 var instance_i = 0;
4280 class TomSelect extends (0,_contrib_microplugin_js__WEBPACK_IMPORTED_MODULE_1__["default"])(_contrib_microevent_js__WEBPACK_IMPORTED_MODULE_0__["default"]) {
4281 constructor(input_arg, user_settings) {
4282 super();
4283 this.order = 0;
4284 this.isOpen = false;
4285 this.isDisabled = false;
4286 this.isReadOnly = false;
4287 this.isInvalid = false; // @deprecated 1.8
4288 this.isValid = true;
4289 this.isLocked = false;
4290 this.isFocused = false;
4291 this.isInputHidden = false;
4292 this.isSetup = false;
4293 this.ignoreFocus = false;
4294 this.ignoreHover = false;
4295 this.hasOptions = false;
4296 this.lastValue = '';
4297 this.caretPos = 0;
4298 this.loading = 0;
4299 this.loadedSearches = {};
4300 this.activeOption = null;
4301 this.activeItems = [];
4302 this.optgroups = {};
4303 this.options = {};
4304 this.userOptions = {};
4305 this.items = [];
4306 this.refreshTimeout = null;
4307 instance_i++;
4308 var dir;
4309 var input = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)(input_arg);
4310 if (input.tomselect) {
4311 throw new Error('Tom Select already initialized on this element');
4312 }
4313 input.tomselect = this;
4314 // detect rtl environment
4315 var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null);
4316 dir = computedStyle.getPropertyValue('direction');
4317 // setup default state
4318 const settings = (0,_getSettings_js__WEBPACK_IMPORTED_MODULE_6__["default"])(input, user_settings);
4319 this.settings = settings;
4320 this.input = input;
4321 this.tabIndex = input.tabIndex || 0;
4322 this.is_select_tag = input.tagName.toLowerCase() === 'select';
4323 this.rtl = /rtl/i.test(dir);
4324 this.inputId = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.getId)(input, 'tomselect-' + instance_i);
4325 this.isRequired = input.required;
4326 // search system
4327 this.sifter = new _orchidjs_sifter__WEBPACK_IMPORTED_MODULE_2__.Sifter(this.options, { diacritics: settings.diacritics });
4328 // option-dependent defaults
4329 settings.mode = settings.mode || (settings.maxItems === 1 ? 'single' : 'multi');
4330 if (typeof settings.hideSelected !== 'boolean') {
4331 settings.hideSelected = settings.mode === 'multi';
4332 }
4333 if (typeof settings.hidePlaceholder !== 'boolean') {
4334 settings.hidePlaceholder = settings.mode !== 'multi';
4335 }
4336 // set up createFilter callback
4337 var filter = settings.createFilter;
4338 if (typeof filter !== 'function') {
4339 if (typeof filter === 'string') {
4340 filter = new RegExp(filter);
4341 }
4342 if (filter instanceof RegExp) {
4343 settings.createFilter = (input) => filter.test(input);
4344 }
4345 else {
4346 settings.createFilter = (value) => {
4347 return this.settings.duplicates || !this.options[value];
4348 };
4349 }
4350 }
4351 this.initializePlugins(settings.plugins);
4352 this.setupCallbacks();
4353 this.setupTemplates();
4354 // Create all elements
4355 const wrapper = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)('<div>');
4356 const control = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)('<div>');
4357 const dropdown = this._render('dropdown');
4358 const dropdown_content = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)(`<div role="listbox" tabindex="-1">`);
4359 const classes = this.input.getAttribute('class') || '';
4360 const inputMode = settings.mode;
4361 var control_input;
4362 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(wrapper, settings.wrapperClass, classes, inputMode);
4363 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(control, settings.controlClass);
4364 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.append)(wrapper, control);
4365 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(dropdown, settings.dropdownClass, inputMode);
4366 if (settings.copyClassesToDropdown) {
4367 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(dropdown, classes);
4368 }
4369 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(dropdown_content, settings.dropdownContentClass);
4370 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.append)(dropdown, dropdown_content);
4371 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)(settings.dropdownParent || wrapper).appendChild(dropdown);
4372 // default controlInput
4373 if ((0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.isHtmlString)(settings.controlInput)) {
4374 control_input = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)(settings.controlInput);
4375 // set attributes
4376 var attrs = ['autocorrect', 'autocapitalize', 'autocomplete', 'spellcheck'];
4377 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(attrs, (attr) => {
4378 if (input.getAttribute(attr)) {
4379 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(control_input, { [attr]: input.getAttribute(attr) });
4380 }
4381 });
4382 control_input.tabIndex = -1;
4383 control.appendChild(control_input);
4384 this.focus_node = control_input;
4385 // dom element
4386 }
4387 else if (settings.controlInput) {
4388 control_input = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)(settings.controlInput);
4389 this.focus_node = control_input;
4390 }
4391 else {
4392 control_input = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)('<input/>');
4393 this.focus_node = control;
4394 }
4395 this.wrapper = wrapper;
4396 this.dropdown = dropdown;
4397 this.dropdown_content = dropdown_content;
4398 this.control = control;
4399 this.control_input = control_input;
4400 this.setup();
4401 }
4402 /**
4403 * set up event bindings.
4404 *
4405 */
4406 setup() {
4407 const self = this;
4408 const settings = self.settings;
4409 const control_input = self.control_input;
4410 const dropdown = self.dropdown;
4411 const dropdown_content = self.dropdown_content;
4412 const wrapper = self.wrapper;
4413 const control = self.control;
4414 const input = self.input;
4415 const focus_node = self.focus_node;
4416 const passive_event = { passive: true };
4417 const listboxId = self.inputId + '-ts-dropdown';
4418 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(dropdown_content, {
4419 id: listboxId
4420 });
4421 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(focus_node, {
4422 role: 'combobox',
4423 'aria-haspopup': 'listbox',
4424 'aria-expanded': 'false',
4425 'aria-controls': listboxId
4426 });
4427 const control_id = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.getId)(focus_node, self.inputId + '-ts-control');
4428 const query = "label[for='" + (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.escapeQuery)(self.inputId) + "']";
4429 const label = document.querySelector(query);
4430 const label_click = self.focus.bind(self);
4431 if (label) {
4432 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(label, 'click', label_click);
4433 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(label, { for: control_id });
4434 const label_id = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.getId)(label, self.inputId + '-ts-label');
4435 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(focus_node, { 'aria-labelledby': label_id });
4436 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(dropdown_content, { 'aria-labelledby': label_id });
4437 }
4438 wrapper.style.width = input.style.width;
4439 if (self.plugins.names.length) {
4440 const classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-');
4441 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)([wrapper, dropdown], classes_plugins);
4442 }
4443 if ((settings.maxItems === null || settings.maxItems > 1) && self.is_select_tag) {
4444 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(input, { multiple: 'multiple' });
4445 }
4446 if (settings.placeholder) {
4447 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(control_input, { placeholder: settings.placeholder });
4448 }
4449 // if splitOn was not passed in, construct it from the delimiter to allow pasting universally
4450 if (!settings.splitOn && settings.delimiter) {
4451 settings.splitOn = new RegExp('\\s*' + (0,_orchidjs_unicode_variants__WEBPACK_IMPORTED_MODULE_3__.escape_regex)(settings.delimiter) + '+\\s*');
4452 }
4453 // debounce user defined load() if loadThrottle > 0
4454 // after initializePlugins() so plugins can create/modify user defined loaders
4455 if (settings.load && settings.loadThrottle) {
4456 settings.load = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.loadDebounce)(settings.load, settings.loadThrottle);
4457 }
4458 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(dropdown, 'mousemove', () => {
4459 self.ignoreHover = false;
4460 });
4461 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(dropdown, 'mouseenter', (e) => {
4462 var target_match = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.parentMatch)(e.target, '[data-selectable]', dropdown);
4463 if (target_match)
4464 self.onOptionHover(e, target_match);
4465 }, { capture: true });
4466 // clicking on an option should select it
4467 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(dropdown, 'click', (evt) => {
4468 const option = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.parentMatch)(evt.target, '[data-selectable]');
4469 if (option) {
4470 self.onOptionSelect(evt, option);
4471 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(evt, true);
4472 }
4473 });
4474 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(control, 'click', (evt) => {
4475 var target_match = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.parentMatch)(evt.target, '[data-ts-item]', control);
4476 if (target_match && self.onItemSelect(evt, target_match)) {
4477 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(evt, true);
4478 return;
4479 }
4480 // retain focus (see control_input mousedown)
4481 if (control_input.value != '') {
4482 return;
4483 }
4484 self.onClick();
4485 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(evt, true);
4486 });
4487 // keydown on focus_node for arrow_down/arrow_up
4488 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(focus_node, 'keydown', (e) => self.onKeyDown(e));
4489 // keypress and input/keyup
4490 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(control_input, 'keypress', (e) => self.onKeyPress(e));
4491 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(control_input, 'input', (e) => self.onInput(e));
4492 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(focus_node, 'blur', (e) => self.onBlur(e));
4493 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(focus_node, 'focus', (e) => self.onFocus(e));
4494 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(control_input, 'paste', (e) => self.onPaste(e));
4495 const doc_mousedown = (evt) => {
4496 // blur if target is outside of this instance
4497 // dropdown is not always inside wrapper
4498 const target = evt.composedPath()[0];
4499 if (!wrapper.contains(target) && !dropdown.contains(target)) {
4500 if (self.isFocused) {
4501 self.blur();
4502 }
4503 self.inputState();
4504 return;
4505 }
4506 // retain focus by preventing native handling. if the
4507 // event target is the input it should not be modified.
4508 // otherwise, text selection within the input won't work.
4509 // Fixes bug #212 which is no covered by tests
4510 if (target == control_input && self.isOpen) {
4511 evt.stopPropagation();
4512 // clicking anywhere in the control should not blur the control_input (which would close the dropdown)
4513 }
4514 else {
4515 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(evt, true);
4516 }
4517 };
4518 const win_scroll = () => {
4519 if (self.isOpen) {
4520 self.positionDropdown();
4521 }
4522 };
4523 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(document, 'mousedown', doc_mousedown);
4524 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(window, 'scroll', win_scroll, passive_event);
4525 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(window, 'resize', win_scroll, passive_event);
4526 this._destroy = () => {
4527 document.removeEventListener('mousedown', doc_mousedown);
4528 window.removeEventListener('scroll', win_scroll);
4529 window.removeEventListener('resize', win_scroll);
4530 if (label)
4531 label.removeEventListener('click', label_click);
4532 };
4533 // store original html and tab index so that they can be
4534 // restored when the destroy() method is called.
4535 this.revertSettings = {
4536 innerHTML: input.innerHTML,
4537 tabIndex: input.tabIndex
4538 };
4539 input.tabIndex = -1;
4540 input.insertAdjacentElement('afterend', self.wrapper);
4541 self.sync(false);
4542 settings.items = [];
4543 delete settings.optgroups;
4544 delete settings.options;
4545 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addEvent)(input, 'invalid', () => {
4546 if (self.isValid) {
4547 self.isValid = false;
4548 self.isInvalid = true;
4549 self.refreshState();
4550 }
4551 });
4552 self.updateOriginalInput();
4553 self.refreshItems();
4554 self.close(false);
4555 self.inputState();
4556 self.isSetup = true;
4557 if (input.disabled) {
4558 self.disable();
4559 }
4560 else if (input.readOnly) {
4561 self.setReadOnly(true);
4562 }
4563 else {
4564 self.enable(); //sets tabIndex
4565 }
4566 self.on('change', this.onChange);
4567 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(input, 'tomselected', 'ts-hidden-accessible');
4568 self.trigger('initialize');
4569 // preload options
4570 if (settings.preload === true) {
4571 self.preload();
4572 }
4573 }
4574 /**
4575 * Register options and optgroups
4576 *
4577 */
4578 setupOptions(options = [], optgroups = []) {
4579 // build options table
4580 this.addOptions(options);
4581 // build optgroup table
4582 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(optgroups, (optgroup) => {
4583 this.registerOptionGroup(optgroup);
4584 });
4585 }
4586 /**
4587 * Sets up default rendering functions.
4588 */
4589 setupTemplates() {
4590 var self = this;
4591 var field_label = self.settings.labelField;
4592 var field_optgroup = self.settings.optgroupLabelField;
4593 var templates = {
4594 'optgroup': (data) => {
4595 let optgroup = document.createElement('div');
4596 optgroup.className = 'optgroup';
4597 optgroup.appendChild(data.options);
4598 return optgroup;
4599 },
4600 'optgroup_header': (data, escape) => {
4601 return '<div class="optgroup-header">' + escape(data[field_optgroup]) + '</div>';
4602 },
4603 'option': (data, escape) => {
4604 return '<div>' + escape(data[field_label]) + '</div>';
4605 },
4606 'item': (data, escape) => {
4607 return '<div>' + escape(data[field_label]) + '</div>';
4608 },
4609 'option_create': (data, escape) => {
4610 return '<div class="create">Add <strong>' + escape(data.input) + '</strong>&hellip;</div>';
4611 },
4612 'no_results': () => {
4613 return '<div class="no-results">No results found</div>';
4614 },
4615 'loading': () => {
4616 return '<div class="spinner"></div>';
4617 },
4618 'not_loading': () => { },
4619 'dropdown': () => {
4620 return '<div></div>';
4621 }
4622 };
4623 self.settings.render = Object.assign({}, templates, self.settings.render);
4624 }
4625 /**
4626 * Maps fired events to callbacks provided
4627 * in the settings used when creating the control.
4628 */
4629 setupCallbacks() {
4630 var key, fn;
4631 var callbacks = {
4632 'initialize': 'onInitialize',
4633 'change': 'onChange',
4634 'item_add': 'onItemAdd',
4635 'item_remove': 'onItemRemove',
4636 'item_select': 'onItemSelect',
4637 'clear': 'onClear',
4638 'option_add': 'onOptionAdd',
4639 'option_remove': 'onOptionRemove',
4640 'option_clear': 'onOptionClear',
4641 'optgroup_add': 'onOptionGroupAdd',
4642 'optgroup_remove': 'onOptionGroupRemove',
4643 'optgroup_clear': 'onOptionGroupClear',
4644 'dropdown_open': 'onDropdownOpen',
4645 'dropdown_close': 'onDropdownClose',
4646 'type': 'onType',
4647 'load': 'onLoad',
4648 'focus': 'onFocus',
4649 'blur': 'onBlur'
4650 };
4651 for (key in callbacks) {
4652 fn = this.settings[callbacks[key]];
4653 if (fn)
4654 this.on(key, fn);
4655 }
4656 }
4657 /**
4658 * Sync the Tom Select instance with the original input or select
4659 *
4660 */
4661 sync(get_settings = true) {
4662 const self = this;
4663 const settings = get_settings ? (0,_getSettings_js__WEBPACK_IMPORTED_MODULE_6__["default"])(self.input, { delimiter: self.settings.delimiter }) : self.settings;
4664 self.setupOptions(settings.options, settings.optgroups);
4665 self.setValue(settings.items || [], true); // silent prevents recursion
4666 self.lastQuery = null; // so updated options will be displayed in dropdown
4667 }
4668 /**
4669 * Triggered when the main control element
4670 * has a click event.
4671 *
4672 */
4673 onClick() {
4674 var self = this;
4675 if (self.activeItems.length > 0) {
4676 self.clearActiveItems();
4677 self.focus();
4678 return;
4679 }
4680 if (self.isFocused && self.isOpen) {
4681 self.blur();
4682 }
4683 else {
4684 self.focus();
4685 }
4686 }
4687 /**
4688 * @deprecated v1.7
4689 *
4690 */
4691 onMouseDown() { }
4692 /**
4693 * Triggered when the value of the control has been changed.
4694 * This should propagate the event to the original DOM
4695 * input / select element.
4696 */
4697 onChange() {
4698 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.triggerEvent)(this.input, 'input');
4699 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.triggerEvent)(this.input, 'change');
4700 }
4701 /**
4702 * Triggered on <input> paste.
4703 *
4704 */
4705 onPaste(e) {
4706 var self = this;
4707 if (self.isInputHidden || self.isLocked) {
4708 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4709 return;
4710 }
4711 // If a regex or string is included, this will split the pasted
4712 // input and create Items for each separate value
4713 if (!self.settings.splitOn) {
4714 return;
4715 }
4716 // Wait for pasted text to be recognized in value
4717 setTimeout(() => {
4718 var pastedText = self.inputValue();
4719 if (!pastedText.match(self.settings.splitOn)) {
4720 return;
4721 }
4722 var splitInput = pastedText.trim().split(self.settings.splitOn);
4723 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(splitInput, (piece) => {
4724 const hash = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(piece);
4725 if (hash) {
4726 if (this.options[piece]) {
4727 self.addItem(piece);
4728 }
4729 else {
4730 self.createItem(piece);
4731 }
4732 }
4733 });
4734 }, 0);
4735 }
4736 /**
4737 * Triggered on <input> keypress.
4738 *
4739 */
4740 onKeyPress(e) {
4741 var self = this;
4742 if (self.isLocked) {
4743 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4744 return;
4745 }
4746 var character = String.fromCharCode(e.keyCode || e.which);
4747 if (self.settings.create && self.settings.mode === 'multi' && character === self.settings.delimiter) {
4748 self.createItem();
4749 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4750 return;
4751 }
4752 }
4753 /**
4754 * Triggered on <input> keydown.
4755 *
4756 */
4757 onKeyDown(e) {
4758 var self = this;
4759 self.ignoreHover = true;
4760 if (self.isLocked) {
4761 if (e.keyCode !== _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_TAB) {
4762 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4763 }
4764 return;
4765 }
4766 switch (e.keyCode) {
4767 // ctrl+A: select all
4768 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_A:
4769 if ((0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.isKeyDown)(_constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_SHORTCUT, e)) {
4770 if (self.control_input.value == '') {
4771 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4772 self.selectAll();
4773 return;
4774 }
4775 }
4776 break;
4777 // esc: close dropdown
4778 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_ESC:
4779 if (self.isOpen) {
4780 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e, true);
4781 self.close();
4782 }
4783 self.clearActiveItems();
4784 return;
4785 // down: open dropdown or move selection down
4786 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_DOWN:
4787 if (!self.isOpen && self.hasOptions) {
4788 self.open();
4789 }
4790 else if (self.activeOption) {
4791 let next = self.getAdjacent(self.activeOption, 1);
4792 if (next)
4793 self.setActiveOption(next);
4794 }
4795 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4796 return;
4797 // up: move selection up
4798 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_UP:
4799 if (self.activeOption) {
4800 let prev = self.getAdjacent(self.activeOption, -1);
4801 if (prev)
4802 self.setActiveOption(prev);
4803 }
4804 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4805 return;
4806 // return: select active option
4807 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_RETURN:
4808 if (self.canSelect(self.activeOption)) {
4809 self.onOptionSelect(e, self.activeOption);
4810 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4811 // if the option_create=null, the dropdown might be closed
4812 }
4813 else if (self.settings.create && self.createItem()) {
4814 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4815 // don't submit form when searching for a value
4816 }
4817 else if (document.activeElement == self.control_input && self.isOpen) {
4818 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4819 }
4820 return;
4821 // left: modifiy item selection to the left
4822 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_LEFT:
4823 self.advanceSelection(-1, e);
4824 return;
4825 // right: modifiy item selection to the right
4826 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_RIGHT:
4827 self.advanceSelection(1, e);
4828 return;
4829 // tab: select active option and/or create item
4830 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_TAB:
4831 if (self.settings.selectOnTab) {
4832 if (self.canSelect(self.activeOption)) {
4833 self.onOptionSelect(e, self.activeOption);
4834 // prevent default [tab] behaviour of jump to the next field
4835 // if select isFull, then the dropdown won't be open and [tab] will work normally
4836 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4837 }
4838 if (self.settings.create && self.createItem()) {
4839 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4840 }
4841 }
4842 return;
4843 // delete|backspace: delete items
4844 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_BACKSPACE:
4845 case _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_DELETE:
4846 self.deleteSelection(e);
4847 return;
4848 }
4849 // don't enter text in the control_input when active items are selected
4850 if (self.isInputHidden && !(0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.isKeyDown)(_constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_SHORTCUT, e)) {
4851 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4852 }
4853 }
4854 /**
4855 * Triggered on <input> keyup.
4856 *
4857 */
4858 onInput(e) {
4859 if (this.isLocked) {
4860 return;
4861 }
4862 const value = this.inputValue();
4863 if (this.lastValue === value)
4864 return;
4865 this.lastValue = value;
4866 if (value == '') {
4867 this._onInput();
4868 return;
4869 }
4870 if (this.refreshTimeout) {
4871 window.clearTimeout(this.refreshTimeout);
4872 }
4873 this.refreshTimeout = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.timeout)(() => {
4874 this.refreshTimeout = null;
4875 this._onInput();
4876 }, this.settings.refreshThrottle);
4877 }
4878 _onInput() {
4879 const value = this.lastValue;
4880 if (this.settings.shouldLoad.call(this, value)) {
4881 this.load(value);
4882 }
4883 this.refreshOptions();
4884 this.trigger('type', value);
4885 }
4886 /**
4887 * Triggered when the user rolls over
4888 * an option in the autocomplete dropdown menu.
4889 *
4890 */
4891 onOptionHover(evt, option) {
4892 if (this.ignoreHover)
4893 return;
4894 this.setActiveOption(option, false);
4895 }
4896 /**
4897 * Triggered on <input> focus.
4898 *
4899 */
4900 onFocus(e) {
4901 var self = this;
4902 var wasFocused = self.isFocused;
4903 if (self.isDisabled || self.isReadOnly) {
4904 self.blur();
4905 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
4906 return;
4907 }
4908 if (self.ignoreFocus)
4909 return;
4910 self.isFocused = true;
4911 if (self.settings.preload === 'focus')
4912 self.preload();
4913 if (!wasFocused)
4914 self.trigger('focus');
4915 if (!self.activeItems.length) {
4916 self.inputState();
4917 self.refreshOptions(!!self.settings.openOnFocus);
4918 }
4919 self.refreshState();
4920 }
4921 /**
4922 * Triggered on <input> blur.
4923 *
4924 */
4925 onBlur(e) {
4926 if (document.hasFocus() === false)
4927 return;
4928 var self = this;
4929 if (!self.isFocused)
4930 return;
4931 self.isFocused = false;
4932 self.ignoreFocus = false;
4933 var deactivate = () => {
4934 self.close();
4935 self.setActiveItem();
4936 self.setCaret(self.items.length);
4937 self.trigger('blur');
4938 };
4939 if (self.settings.create && self.settings.createOnBlur) {
4940 self.createItem(null, deactivate);
4941 }
4942 else {
4943 deactivate();
4944 }
4945 }
4946 /**
4947 * Triggered when the user clicks on an option
4948 * in the autocomplete dropdown menu.
4949 *
4950 */
4951 onOptionSelect(evt, option) {
4952 var value, self = this;
4953 // should not be possible to trigger a option under a disabled optgroup
4954 if (option.parentElement && option.parentElement.matches('[data-disabled]')) {
4955 return;
4956 }
4957 if (option.classList.contains('create')) {
4958 self.createItem(null, () => {
4959 if (self.settings.closeAfterSelect) {
4960 self.close();
4961 }
4962 });
4963 }
4964 else {
4965 value = option.dataset.value;
4966 if (typeof value !== 'undefined') {
4967 self.lastQuery = null;
4968 self.addItem(value);
4969 if (self.settings.closeAfterSelect) {
4970 self.close();
4971 }
4972 if (!self.settings.hideSelected && evt.type && /click/.test(evt.type)) {
4973 self.setActiveOption(option);
4974 }
4975 }
4976 }
4977 }
4978 /**
4979 * Return true if the given option can be selected
4980 *
4981 */
4982 canSelect(option) {
4983 if (this.isOpen && option && this.dropdown_content.contains(option)) {
4984 return true;
4985 }
4986 return false;
4987 }
4988 /**
4989 * Triggered when the user clicks on an item
4990 * that has been selected.
4991 *
4992 */
4993 onItemSelect(evt, item) {
4994 var self = this;
4995 if (!self.isLocked && self.settings.mode === 'multi') {
4996 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(evt);
4997 self.setActiveItem(item, evt);
4998 return true;
4999 }
5000 return false;
5001 }
5002 /**
5003 * Determines whether or not to invoke
5004 * the user-provided option provider / loader
5005 *
5006 * Note, there is a subtle difference between
5007 * this.canLoad() and this.settings.shouldLoad();
5008 *
5009 * - settings.shouldLoad() is a user-input validator.
5010 * When false is returned, the not_loading template
5011 * will be added to the dropdown
5012 *
5013 * - canLoad() is lower level validator that checks
5014 * the Tom Select instance. There is no inherent user
5015 * feedback when canLoad returns false
5016 *
5017 */
5018 canLoad(value) {
5019 if (!this.settings.load)
5020 return false;
5021 if (this.loadedSearches.hasOwnProperty(value))
5022 return false;
5023 return true;
5024 }
5025 /**
5026 * Invokes the user-provided option provider / loader.
5027 *
5028 */
5029 load(value) {
5030 const self = this;
5031 if (!self.canLoad(value))
5032 return;
5033 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(self.wrapper, self.settings.loadingClass);
5034 self.loading++;
5035 const callback = self.loadCallback.bind(self);
5036 self.settings.load.call(self, value, callback);
5037 }
5038 /**
5039 * Invoked by the user-provided option provider
5040 *
5041 */
5042 loadCallback(options, optgroups) {
5043 const self = this;
5044 self.loading = Math.max(self.loading - 1, 0);
5045 self.lastQuery = null;
5046 self.clearActiveOption(); // when new results load, focus should be on first option
5047 self.setupOptions(options, optgroups);
5048 self.refreshOptions(self.isFocused && !self.isInputHidden);
5049 if (!self.loading) {
5050 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(self.wrapper, self.settings.loadingClass);
5051 }
5052 self.trigger('load', options, optgroups);
5053 }
5054 preload() {
5055 var classList = this.wrapper.classList;
5056 if (classList.contains('preloaded'))
5057 return;
5058 classList.add('preloaded');
5059 this.load('');
5060 }
5061 /**
5062 * Sets the input field of the control to the specified value.
5063 *
5064 */
5065 setTextboxValue(value = '') {
5066 var input = this.control_input;
5067 var changed = input.value !== value;
5068 if (changed) {
5069 input.value = value;
5070 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.triggerEvent)(input, 'update');
5071 this.lastValue = value;
5072 }
5073 }
5074 /**
5075 * Returns the value of the control. If multiple items
5076 * can be selected (e.g. <select multiple>), this returns
5077 * an array. If only one item can be selected, this
5078 * returns a string.
5079 *
5080 */
5081 getValue() {
5082 if (this.is_select_tag && this.input.hasAttribute('multiple')) {
5083 return this.items;
5084 }
5085 return this.items.join(this.settings.delimiter);
5086 }
5087 /**
5088 * Resets the selected items to the given value.
5089 *
5090 */
5091 setValue(value, silent) {
5092 var events = silent ? [] : ['change'];
5093 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.debounce_events)(this, events, () => {
5094 this.clear(silent);
5095 this.addItems(value, silent);
5096 });
5097 }
5098 /**
5099 * Resets the number of max items to the given value
5100 *
5101 */
5102 setMaxItems(value) {
5103 if (value === 0)
5104 value = null; //reset to unlimited items.
5105 this.settings.maxItems = value;
5106 this.refreshState();
5107 }
5108 /**
5109 * Sets the selected item.
5110 *
5111 */
5112 setActiveItem(item, e) {
5113 var self = this;
5114 var eventName;
5115 var i, begin, end, swap;
5116 var last;
5117 if (self.settings.mode === 'single')
5118 return;
5119 // clear the active selection
5120 if (!item) {
5121 self.clearActiveItems();
5122 if (self.isFocused) {
5123 self.inputState();
5124 }
5125 return;
5126 }
5127 // modify selection
5128 eventName = e && e.type.toLowerCase();
5129 if (eventName === 'click' && (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.isKeyDown)('shiftKey', e) && self.activeItems.length) {
5130 last = self.getLastActive();
5131 begin = Array.prototype.indexOf.call(self.control.children, last);
5132 end = Array.prototype.indexOf.call(self.control.children, item);
5133 if (begin > end) {
5134 swap = begin;
5135 begin = end;
5136 end = swap;
5137 }
5138 for (i = begin; i <= end; i++) {
5139 item = self.control.children[i];
5140 if (self.activeItems.indexOf(item) === -1) {
5141 self.setActiveItemClass(item);
5142 }
5143 }
5144 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e);
5145 }
5146 else if ((eventName === 'click' && (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.isKeyDown)(_constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_SHORTCUT, e)) || (eventName === 'keydown' && (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.isKeyDown)('shiftKey', e))) {
5147 if (item.classList.contains('active')) {
5148 self.removeActiveItem(item);
5149 }
5150 else {
5151 self.setActiveItemClass(item);
5152 }
5153 }
5154 else {
5155 self.clearActiveItems();
5156 self.setActiveItemClass(item);
5157 }
5158 // ensure control has focus
5159 self.inputState();
5160 if (!self.isFocused) {
5161 self.focus();
5162 }
5163 }
5164 /**
5165 * Set the active and last-active classes
5166 *
5167 */
5168 setActiveItemClass(item) {
5169 const self = this;
5170 const last_active = self.control.querySelector('.last-active');
5171 if (last_active)
5172 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(last_active, 'last-active');
5173 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(item, 'active last-active');
5174 self.trigger('item_select', item);
5175 if (self.activeItems.indexOf(item) == -1) {
5176 self.activeItems.push(item);
5177 }
5178 }
5179 /**
5180 * Remove active item
5181 *
5182 */
5183 removeActiveItem(item) {
5184 var idx = this.activeItems.indexOf(item);
5185 this.activeItems.splice(idx, 1);
5186 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(item, 'active');
5187 }
5188 /**
5189 * Clears all the active items
5190 *
5191 */
5192 clearActiveItems() {
5193 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(this.activeItems, 'active');
5194 this.activeItems = [];
5195 }
5196 /**
5197 * Sets the selected item in the dropdown menu
5198 * of available options.
5199 *
5200 */
5201 setActiveOption(option, scroll = true) {
5202 if (option === this.activeOption) {
5203 return;
5204 }
5205 this.clearActiveOption();
5206 if (!option)
5207 return;
5208 this.activeOption = option;
5209 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(this.focus_node, { 'aria-activedescendant': option.getAttribute('id') });
5210 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(option, { 'aria-selected': 'true' });
5211 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(option, 'active');
5212 if (scroll)
5213 this.scrollToOption(option);
5214 }
5215 /**
5216 * Sets the dropdown_content scrollTop to display the option
5217 *
5218 */
5219 scrollToOption(option, behavior) {
5220 if (!option)
5221 return;
5222 const content = this.dropdown_content;
5223 const height_menu = content.clientHeight;
5224 const scrollTop = content.scrollTop || 0;
5225 const height_item = option.offsetHeight;
5226 const y = option.getBoundingClientRect().top - content.getBoundingClientRect().top + scrollTop;
5227 if (y + height_item > height_menu + scrollTop) {
5228 this.scroll(y - height_menu + height_item, behavior);
5229 }
5230 else if (y < scrollTop) {
5231 this.scroll(y, behavior);
5232 }
5233 }
5234 /**
5235 * Scroll the dropdown to the given position
5236 *
5237 */
5238 scroll(scrollTop, behavior) {
5239 const content = this.dropdown_content;
5240 if (behavior) {
5241 content.style.scrollBehavior = behavior;
5242 }
5243 content.scrollTop = scrollTop;
5244 content.style.scrollBehavior = '';
5245 }
5246 /**
5247 * Clears the active option
5248 *
5249 */
5250 clearActiveOption() {
5251 if (this.activeOption) {
5252 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(this.activeOption, 'active');
5253 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(this.activeOption, { 'aria-selected': null });
5254 }
5255 this.activeOption = null;
5256 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(this.focus_node, { 'aria-activedescendant': null });
5257 }
5258 /**
5259 * Selects all items (CTRL + A).
5260 */
5261 selectAll() {
5262 const self = this;
5263 if (self.settings.mode === 'single')
5264 return;
5265 const activeItems = self.controlChildren();
5266 if (!activeItems.length)
5267 return;
5268 self.inputState();
5269 self.close();
5270 self.activeItems = activeItems;
5271 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(activeItems, (item) => {
5272 self.setActiveItemClass(item);
5273 });
5274 }
5275 /**
5276 * Determines if the control_input should be in a hidden or visible state
5277 *
5278 */
5279 inputState() {
5280 var self = this;
5281 if (!self.control.contains(self.control_input))
5282 return;
5283 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(self.control_input, { placeholder: self.settings.placeholder });
5284 if (self.activeItems.length > 0 || (!self.isFocused && self.settings.hidePlaceholder && self.items.length > 0)) {
5285 self.setTextboxValue();
5286 self.isInputHidden = true;
5287 }
5288 else {
5289 if (self.settings.hidePlaceholder && self.items.length > 0) {
5290 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(self.control_input, { placeholder: '' });
5291 }
5292 self.isInputHidden = false;
5293 }
5294 self.wrapper.classList.toggle('input-hidden', self.isInputHidden);
5295 }
5296 /**
5297 * Get the input value
5298 */
5299 inputValue() {
5300 return this.control_input.value.trim();
5301 }
5302 /**
5303 * Gives the control focus.
5304 */
5305 focus() {
5306 var self = this;
5307 if (self.isDisabled || self.isReadOnly)
5308 return;
5309 self.ignoreFocus = true;
5310 if (self.control_input.offsetWidth) {
5311 self.control_input.focus();
5312 }
5313 else {
5314 self.focus_node.focus();
5315 }
5316 setTimeout(() => {
5317 self.ignoreFocus = false;
5318 self.onFocus();
5319 }, 0);
5320 }
5321 /**
5322 * Forces the control out of focus.
5323 *
5324 */
5325 blur() {
5326 this.focus_node.blur();
5327 this.onBlur();
5328 }
5329 /**
5330 * Returns a function that scores an object
5331 * to show how good of a match it is to the
5332 * provided query.
5333 *
5334 * @return {function}
5335 */
5336 getScoreFunction(query) {
5337 return this.sifter.getScoreFunction(query, this.getSearchOptions());
5338 }
5339 /**
5340 * Returns search options for sifter (the system
5341 * for scoring and sorting results).
5342 *
5343 * @see https://github.com/orchidjs/sifter.js
5344 * @return {object}
5345 */
5346 getSearchOptions() {
5347 var settings = this.settings;
5348 var sort = settings.sortField;
5349 if (typeof settings.sortField === 'string') {
5350 sort = [{ field: settings.sortField }];
5351 }
5352 return {
5353 fields: settings.searchField,
5354 conjunction: settings.searchConjunction,
5355 sort: sort,
5356 nesting: settings.nesting
5357 };
5358 }
5359 /**
5360 * Searches through available options and returns
5361 * a sorted array of matches.
5362 *
5363 */
5364 search(query) {
5365 var result, calculateScore;
5366 var self = this;
5367 var options = this.getSearchOptions();
5368 // validate user-provided result scoring function
5369 if (self.settings.score) {
5370 calculateScore = self.settings.score.call(self, query);
5371 if (typeof calculateScore !== 'function') {
5372 throw new Error('Tom Select "score" setting must be a function that returns a function');
5373 }
5374 }
5375 // perform search
5376 if (query !== self.lastQuery) {
5377 self.lastQuery = query;
5378 result = self.sifter.search(query, Object.assign(options, { score: calculateScore }));
5379 self.currentResults = result;
5380 }
5381 else {
5382 result = Object.assign({}, self.currentResults);
5383 }
5384 // filter out selected items
5385 if (self.settings.hideSelected) {
5386 result.items = result.items.filter((item) => {
5387 let hashed = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(item.id);
5388 return !(hashed && self.items.indexOf(hashed) !== -1);
5389 });
5390 }
5391 return result;
5392 }
5393 /**
5394 * Refreshes the list of available options shown
5395 * in the autocomplete dropdown menu.
5396 *
5397 */
5398 refreshOptions(triggerDropdown = true) {
5399 var i, j, k, n, optgroup, optgroups, html, has_create_option, active_group;
5400 var create;
5401 const groups = {};
5402 const groups_order = [];
5403 var self = this;
5404 var query = self.inputValue();
5405 const same_query = query === self.lastQuery || (query == '' && self.lastQuery == null);
5406 var results = self.search(query);
5407 var active_option = null;
5408 var show_dropdown = self.settings.shouldOpen || false;
5409 var dropdown_content = self.dropdown_content;
5410 if (same_query) {
5411 active_option = self.activeOption;
5412 if (active_option) {
5413 active_group = active_option.closest('[data-group]');
5414 }
5415 }
5416 // build markup
5417 n = results.items.length;
5418 if (typeof self.settings.maxOptions === 'number') {
5419 n = Math.min(n, self.settings.maxOptions);
5420 }
5421 if (n > 0) {
5422 show_dropdown = true;
5423 }
5424 // get fragment for group and the position of the group in group_order
5425 const getGroupFragment = (optgroup, order) => {
5426 let group_order_i = groups[optgroup];
5427 if (group_order_i !== undefined) {
5428 let order_group = groups_order[group_order_i];
5429 if (order_group !== undefined) {
5430 return [group_order_i, order_group.fragment];
5431 }
5432 }
5433 let group_fragment = document.createDocumentFragment();
5434 group_order_i = groups_order.length;
5435 groups_order.push({ fragment: group_fragment, order, optgroup });
5436 return [group_order_i, group_fragment];
5437 };
5438 // render and group available options individually
5439 for (i = 0; i < n; i++) {
5440 // get option dom element
5441 let item = results.items[i];
5442 if (!item)
5443 continue;
5444 let opt_value = item.id;
5445 let option = self.options[opt_value];
5446 if (option === undefined)
5447 continue;
5448 let opt_hash = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.get_hash)(opt_value);
5449 let option_el = self.getOption(opt_hash, true);
5450 // toggle 'selected' class
5451 if (!self.settings.hideSelected) {
5452 option_el.classList.toggle('selected', self.items.includes(opt_hash));
5453 }
5454 optgroup = option[self.settings.optgroupField] || '';
5455 optgroups = Array.isArray(optgroup) ? optgroup : [optgroup];
5456 for (j = 0, k = optgroups && optgroups.length; j < k; j++) {
5457 optgroup = optgroups[j];
5458 let order = option.$order;
5459 let self_optgroup = self.optgroups[optgroup];
5460 if (self_optgroup === undefined) {
5461 optgroup = '';
5462 }
5463 else {
5464 order = self_optgroup.$order;
5465 }
5466 const [group_order_i, group_fragment] = getGroupFragment(optgroup, order);
5467 // nodes can only have one parent, so if the option is in mutple groups, we need a clone
5468 if (j > 0) {
5469 option_el = option_el.cloneNode(true);
5470 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(option_el, { id: option.$id + '-clone-' + j, 'aria-selected': null });
5471 option_el.classList.add('ts-cloned');
5472 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(option_el, 'active');
5473 // make sure we keep the activeOption in the same group
5474 if (self.activeOption && self.activeOption.dataset.value == opt_value) {
5475 if (active_group && active_group.dataset.group === optgroup.toString()) {
5476 active_option = option_el;
5477 }
5478 }
5479 }
5480 group_fragment.appendChild(option_el);
5481 if (optgroup != '') {
5482 groups[optgroup] = group_order_i;
5483 }
5484 }
5485 }
5486 // sort optgroups
5487 if (self.settings.lockOptgroupOrder) {
5488 groups_order.sort((a, b) => {
5489 return a.order - b.order;
5490 });
5491 }
5492 // render optgroup headers & join groups
5493 html = document.createDocumentFragment();
5494 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(groups_order, (group_order) => {
5495 let group_fragment = group_order.fragment;
5496 let optgroup = group_order.optgroup;
5497 if (!group_fragment || !group_fragment.children.length)
5498 return;
5499 let group_heading = self.optgroups[optgroup];
5500 if (group_heading !== undefined) {
5501 let group_options = document.createDocumentFragment();
5502 let header = self.render('optgroup_header', group_heading);
5503 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.append)(group_options, header);
5504 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.append)(group_options, group_fragment);
5505 let group_html = self.render('optgroup', { group: group_heading, options: group_options });
5506 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.append)(html, group_html);
5507 }
5508 else {
5509 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.append)(html, group_fragment);
5510 }
5511 });
5512 dropdown_content.innerHTML = '';
5513 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.append)(dropdown_content, html);
5514 // highlight matching terms inline
5515 if (self.settings.highlight) {
5516 (0,_contrib_highlight_js__WEBPACK_IMPORTED_MODULE_4__.removeHighlight)(dropdown_content);
5517 if (results.query.length && results.tokens.length) {
5518 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(results.tokens, (tok) => {
5519 (0,_contrib_highlight_js__WEBPACK_IMPORTED_MODULE_4__.highlight)(dropdown_content, tok.regex);
5520 });
5521 }
5522 }
5523 // helper method for adding templates to dropdown
5524 var add_template = (template) => {
5525 let content = self.render(template, { input: query });
5526 if (content) {
5527 show_dropdown = true;
5528 dropdown_content.insertBefore(content, dropdown_content.firstChild);
5529 }
5530 return content;
5531 };
5532 // add loading message
5533 if (self.loading) {
5534 add_template('loading');
5535 // invalid query
5536 }
5537 else if (!self.settings.shouldLoad.call(self, query)) {
5538 add_template('not_loading');
5539 // add no_results message
5540 }
5541 else if (results.items.length === 0) {
5542 add_template('no_results');
5543 }
5544 // add create option
5545 has_create_option = self.canCreate(query);
5546 if (has_create_option) {
5547 create = add_template('option_create');
5548 }
5549 // activate
5550 self.hasOptions = results.items.length > 0 || has_create_option;
5551 if (show_dropdown) {
5552 if (results.items.length > 0) {
5553 if (!active_option && self.settings.mode === 'single' && self.items[0] != undefined) {
5554 active_option = self.getOption(self.items[0]);
5555 }
5556 if (!dropdown_content.contains(active_option)) {
5557 let active_index = 0;
5558 if (create && !self.settings.addPrecedence) {
5559 active_index = 1;
5560 }
5561 active_option = self.selectable()[active_index];
5562 }
5563 }
5564 else if (create) {
5565 active_option = create;
5566 }
5567 if (triggerDropdown && !self.isOpen) {
5568 self.open();
5569 self.scrollToOption(active_option, 'auto');
5570 }
5571 self.setActiveOption(active_option);
5572 }
5573 else {
5574 self.clearActiveOption();
5575 if (triggerDropdown && self.isOpen) {
5576 self.close(false); // if create_option=null, we want the dropdown to close but not reset the textbox value
5577 }
5578 }
5579 }
5580 /**
5581 * Return list of selectable options
5582 *
5583 */
5584 selectable() {
5585 return this.dropdown_content.querySelectorAll('[data-selectable]');
5586 }
5587 /**
5588 * Adds an available option. If it already exists,
5589 * nothing will happen. Note: this does not refresh
5590 * the options list dropdown (use `refreshOptions`
5591 * for that).
5592 *
5593 * Usage:
5594 *
5595 * this.addOption(data)
5596 *
5597 */
5598 addOption(data, user_created = false) {
5599 const self = this;
5600 // @deprecated 1.7.7
5601 // use addOptions( array, user_created ) for adding multiple options
5602 if (Array.isArray(data)) {
5603 self.addOptions(data, user_created);
5604 return false;
5605 }
5606 const key = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(data[self.settings.valueField]);
5607 if (key === null || self.options.hasOwnProperty(key)) {
5608 return false;
5609 }
5610 data.$order = data.$order || ++self.order;
5611 data.$id = self.inputId + '-opt-' + data.$order;
5612 self.options[key] = data;
5613 self.lastQuery = null;
5614 if (user_created) {
5615 self.userOptions[key] = user_created;
5616 self.trigger('option_add', key, data);
5617 }
5618 return key;
5619 }
5620 /**
5621 * Add multiple options
5622 *
5623 */
5624 addOptions(data, user_created = false) {
5625 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(data, (dat) => {
5626 this.addOption(dat, user_created);
5627 });
5628 }
5629 /**
5630 * @deprecated 1.7.7
5631 */
5632 registerOption(data) {
5633 return this.addOption(data);
5634 }
5635 /**
5636 * Registers an option group to the pool of option groups.
5637 *
5638 * @return {boolean|string}
5639 */
5640 registerOptionGroup(data) {
5641 var key = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(data[this.settings.optgroupValueField]);
5642 if (key === null)
5643 return false;
5644 data.$order = data.$order || ++this.order;
5645 this.optgroups[key] = data;
5646 return key;
5647 }
5648 /**
5649 * Registers a new optgroup for options
5650 * to be bucketed into.
5651 *
5652 */
5653 addOptionGroup(id, data) {
5654 var hashed_id;
5655 data[this.settings.optgroupValueField] = id;
5656 if (hashed_id = this.registerOptionGroup(data)) {
5657 this.trigger('optgroup_add', hashed_id, data);
5658 }
5659 }
5660 /**
5661 * Removes an existing option group.
5662 *
5663 */
5664 removeOptionGroup(id) {
5665 if (this.optgroups.hasOwnProperty(id)) {
5666 delete this.optgroups[id];
5667 this.clearCache();
5668 this.trigger('optgroup_remove', id);
5669 }
5670 }
5671 /**
5672 * Clears all existing option groups.
5673 */
5674 clearOptionGroups() {
5675 this.optgroups = {};
5676 this.clearCache();
5677 this.trigger('optgroup_clear');
5678 }
5679 /**
5680 * Updates an option available for selection. If
5681 * it is visible in the selected items or options
5682 * dropdown, it will be re-rendered automatically.
5683 *
5684 */
5685 updateOption(value, data) {
5686 const self = this;
5687 var item_new;
5688 var index_item;
5689 const value_old = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(value);
5690 const value_new = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(data[self.settings.valueField]);
5691 // sanity checks
5692 if (value_old === null)
5693 return;
5694 const data_old = self.options[value_old];
5695 if (data_old == undefined)
5696 return;
5697 if (typeof value_new !== 'string')
5698 throw new Error('Value must be set in option data');
5699 const option = self.getOption(value_old);
5700 const item = self.getItem(value_old);
5701 data.$order = data.$order || data_old.$order;
5702 delete self.options[value_old];
5703 // invalidate render cache
5704 // don't remove existing node yet, we'll remove it after replacing it
5705 self.uncacheValue(value_new);
5706 self.options[value_new] = data;
5707 // update the option if it's in the dropdown
5708 if (option) {
5709 if (self.dropdown_content.contains(option)) {
5710 const option_new = self._render('option', data);
5711 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.replaceNode)(option, option_new);
5712 if (self.activeOption === option) {
5713 self.setActiveOption(option_new);
5714 }
5715 }
5716 option.remove();
5717 }
5718 // update the item if we have one
5719 if (item) {
5720 index_item = self.items.indexOf(value_old);
5721 if (index_item !== -1) {
5722 self.items.splice(index_item, 1, value_new);
5723 }
5724 item_new = self._render('item', data);
5725 if (item.classList.contains('active'))
5726 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(item_new, 'active');
5727 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.replaceNode)(item, item_new);
5728 }
5729 // invalidate last query because we might have updated the sortField
5730 self.lastQuery = null;
5731 }
5732 /**
5733 * Removes a single option.
5734 *
5735 */
5736 removeOption(value, silent) {
5737 const self = this;
5738 value = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.get_hash)(value);
5739 self.uncacheValue(value);
5740 delete self.userOptions[value];
5741 delete self.options[value];
5742 self.lastQuery = null;
5743 self.trigger('option_remove', value);
5744 self.removeItem(value, silent);
5745 }
5746 /**
5747 * Clears all options.
5748 */
5749 clearOptions(filter) {
5750 const boundFilter = (filter || this.clearFilter).bind(this);
5751 this.loadedSearches = {};
5752 this.userOptions = {};
5753 this.clearCache();
5754 const selected = {};
5755 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(this.options, (option, key) => {
5756 if (boundFilter(option, key)) {
5757 selected[key] = option;
5758 }
5759 });
5760 this.options = this.sifter.items = selected;
5761 this.lastQuery = null;
5762 this.trigger('option_clear');
5763 }
5764 /**
5765 * Used by clearOptions() to decide whether or not an option should be removed
5766 * Return true to keep an option, false to remove
5767 *
5768 */
5769 clearFilter(option, value) {
5770 if (this.items.indexOf(value) >= 0) {
5771 return true;
5772 }
5773 return false;
5774 }
5775 /**
5776 * Returns the dom element of the option
5777 * matching the given value.
5778 *
5779 */
5780 getOption(value, create = false) {
5781 const hashed = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(value);
5782 if (hashed === null)
5783 return null;
5784 const option = this.options[hashed];
5785 if (option != undefined) {
5786 if (option.$div) {
5787 return option.$div;
5788 }
5789 if (create) {
5790 return this._render('option', option);
5791 }
5792 }
5793 return null;
5794 }
5795 /**
5796 * Returns the dom element of the next or previous dom element of the same type
5797 * Note: adjacent options may not be adjacent DOM elements (optgroups)
5798 *
5799 */
5800 getAdjacent(option, direction, type = 'option') {
5801 var self = this, all;
5802 if (!option) {
5803 return null;
5804 }
5805 if (type == 'item') {
5806 all = self.controlChildren();
5807 }
5808 else {
5809 all = self.dropdown_content.querySelectorAll('[data-selectable]');
5810 }
5811 for (let i = 0; i < all.length; i++) {
5812 if (all[i] != option) {
5813 continue;
5814 }
5815 if (direction > 0) {
5816 return all[i + 1];
5817 }
5818 return all[i - 1];
5819 }
5820 return null;
5821 }
5822 /**
5823 * Returns the dom element of the item
5824 * matching the given value.
5825 *
5826 */
5827 getItem(item) {
5828 if (typeof item == 'object') {
5829 return item;
5830 }
5831 var value = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(item);
5832 return value !== null
5833 ? this.control.querySelector(`[data-value="${(0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addSlashes)(value)}"]`)
5834 : null;
5835 }
5836 /**
5837 * "Selects" multiple items at once. Adds them to the list
5838 * at the current caret position.
5839 *
5840 */
5841 addItems(values, silent) {
5842 var self = this;
5843 var items = Array.isArray(values) ? values : [values];
5844 items = items.filter(x => self.items.indexOf(x) === -1);
5845 const last_item = items[items.length - 1];
5846 items.forEach(item => {
5847 self.isPending = (item !== last_item);
5848 self.addItem(item, silent);
5849 });
5850 }
5851 /**
5852 * "Selects" an item. Adds it to the list
5853 * at the current caret position.
5854 *
5855 */
5856 addItem(value, silent) {
5857 var events = silent ? [] : ['change', 'dropdown_close'];
5858 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.debounce_events)(this, events, () => {
5859 var item, wasFull;
5860 const self = this;
5861 const inputMode = self.settings.mode;
5862 const hashed = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(value);
5863 if (hashed && self.items.indexOf(hashed) !== -1) {
5864 if (inputMode === 'single') {
5865 self.close();
5866 }
5867 if (inputMode === 'single' || !self.settings.duplicates) {
5868 return;
5869 }
5870 }
5871 if (hashed === null || !self.options.hasOwnProperty(hashed))
5872 return;
5873 if (inputMode === 'single')
5874 self.clear(silent);
5875 if (inputMode === 'multi' && self.isFull())
5876 return;
5877 item = self._render('item', self.options[hashed]);
5878 if (self.control.contains(item)) { // duplicates
5879 item = item.cloneNode(true);
5880 }
5881 wasFull = self.isFull();
5882 self.items.splice(self.caretPos, 0, hashed);
5883 self.insertAtCaret(item);
5884 if (self.isSetup) {
5885 // update menu / remove the option (if this is not one item being added as part of series)
5886 if (!self.isPending && self.settings.hideSelected) {
5887 let option = self.getOption(hashed);
5888 let next = self.getAdjacent(option, 1);
5889 if (next) {
5890 self.setActiveOption(next);
5891 }
5892 }
5893 // refreshOptions after setActiveOption(),
5894 // otherwise setActiveOption() will be called by refreshOptions() with the wrong value
5895 if (!self.isPending && !self.settings.closeAfterSelect) {
5896 self.refreshOptions(self.isFocused && inputMode !== 'single');
5897 }
5898 // hide the menu if the maximum number of items have been selected or no options are left
5899 if (self.settings.closeAfterSelect != false && self.isFull()) {
5900 self.close();
5901 }
5902 else if (!self.isPending) {
5903 self.positionDropdown();
5904 }
5905 self.trigger('item_add', hashed, item);
5906 if (!self.isPending) {
5907 self.updateOriginalInput({ silent: silent });
5908 }
5909 }
5910 if (!self.isPending || (!wasFull && self.isFull())) {
5911 self.inputState();
5912 self.refreshState();
5913 }
5914 });
5915 }
5916 /**
5917 * Removes the selected item matching
5918 * the provided value.
5919 *
5920 */
5921 removeItem(item = null, silent) {
5922 const self = this;
5923 item = self.getItem(item);
5924 if (!item)
5925 return;
5926 var i, idx;
5927 const value = item.dataset.value;
5928 i = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.nodeIndex)(item);
5929 item.remove();
5930 if (item.classList.contains('active')) {
5931 idx = self.activeItems.indexOf(item);
5932 self.activeItems.splice(idx, 1);
5933 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(item, 'active');
5934 }
5935 self.items.splice(i, 1);
5936 self.lastQuery = null;
5937 if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {
5938 self.removeOption(value, silent);
5939 }
5940 if (i < self.caretPos) {
5941 self.setCaret(self.caretPos - 1);
5942 }
5943 self.updateOriginalInput({ silent: silent });
5944 self.refreshState();
5945 self.positionDropdown();
5946 self.trigger('item_remove', value, item);
5947 }
5948 /**
5949 * Invokes the `create` method provided in the
5950 * TomSelect options that should provide the data
5951 * for the new item, given the user input.
5952 *
5953 * Once this completes, it will be added
5954 * to the item list.
5955 *
5956 */
5957 createItem(input = null, callback = () => { }) {
5958 // triggerDropdown parameter @deprecated 2.1.1
5959 if (arguments.length === 3) {
5960 callback = arguments[2];
5961 }
5962 if (typeof callback != 'function') {
5963 callback = () => { };
5964 }
5965 var self = this;
5966 var caret = self.caretPos;
5967 var output;
5968 input = input || self.inputValue();
5969 if (!self.canCreate(input)) {
5970 callback();
5971 return false;
5972 }
5973 self.lock();
5974 var created = false;
5975 var create = (data) => {
5976 self.unlock();
5977 if (!data || typeof data !== 'object')
5978 return callback();
5979 var value = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.hash_key)(data[self.settings.valueField]);
5980 if (typeof value !== 'string') {
5981 return callback();
5982 }
5983 self.setTextboxValue();
5984 self.addOption(data, true);
5985 self.setCaret(caret);
5986 self.addItem(value);
5987 callback(data);
5988 created = true;
5989 };
5990 if (typeof self.settings.create === 'function') {
5991 output = self.settings.create.call(this, input, create);
5992 }
5993 else {
5994 output = {
5995 [self.settings.labelField]: input,
5996 [self.settings.valueField]: input,
5997 };
5998 }
5999 if (!created) {
6000 create(output);
6001 }
6002 return true;
6003 }
6004 /**
6005 * Re-renders the selected item lists.
6006 */
6007 refreshItems() {
6008 var self = this;
6009 self.lastQuery = null;
6010 if (self.isSetup) {
6011 self.addItems(self.items);
6012 }
6013 self.updateOriginalInput();
6014 self.refreshState();
6015 }
6016 /**
6017 * Updates all state-dependent attributes
6018 * and CSS classes.
6019 */
6020 refreshState() {
6021 const self = this;
6022 self.refreshValidityState();
6023 const isFull = self.isFull();
6024 const isLocked = self.isLocked;
6025 self.wrapper.classList.toggle('rtl', self.rtl);
6026 const wrap_classList = self.wrapper.classList;
6027 wrap_classList.toggle('focus', self.isFocused);
6028 wrap_classList.toggle('disabled', self.isDisabled);
6029 wrap_classList.toggle('readonly', self.isReadOnly);
6030 wrap_classList.toggle('required', self.isRequired);
6031 wrap_classList.toggle('invalid', !self.isValid);
6032 wrap_classList.toggle('locked', isLocked);
6033 wrap_classList.toggle('full', isFull);
6034 wrap_classList.toggle('input-active', self.isFocused && !self.isInputHidden);
6035 wrap_classList.toggle('dropdown-active', self.isOpen);
6036 wrap_classList.toggle('has-options', (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.isEmptyObject)(self.options));
6037 wrap_classList.toggle('has-items', self.items.length > 0);
6038 }
6039 /**
6040 * Update the `required` attribute of both input and control input.
6041 *
6042 * The `required` property needs to be activated on the control input
6043 * for the error to be displayed at the right place. `required` also
6044 * needs to be temporarily deactivated on the input since the input is
6045 * hidden and can't show errors.
6046 */
6047 refreshValidityState() {
6048 var self = this;
6049 if (!self.input.validity) {
6050 return;
6051 }
6052 self.isValid = self.input.validity.valid;
6053 self.isInvalid = !self.isValid;
6054 }
6055 /**
6056 * Determines whether or not more items can be added
6057 * to the control without exceeding the user-defined maximum.
6058 *
6059 * @returns {boolean}
6060 */
6061 isFull() {
6062 return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems;
6063 }
6064 /**
6065 * Refreshes the original <select> or <input>
6066 * element to reflect the current state.
6067 *
6068 */
6069 updateOriginalInput(opts = {}) {
6070 const self = this;
6071 var option, label;
6072 const empty_option = self.input.querySelector('option[value=""]');
6073 if (self.is_select_tag) {
6074 const selected = [];
6075 const has_selected = self.input.querySelectorAll('option:checked').length;
6076 function AddSelected(option_el, value, label) {
6077 if (!option_el) {
6078 option_el = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)('<option value="' + (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.escape_html)(value) + '">' + (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.escape_html)(label) + '</option>');
6079 }
6080 // don't move empty option from top of list
6081 // fixes bug in firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1725293
6082 if (option_el != empty_option) {
6083 self.input.append(option_el);
6084 }
6085 selected.push(option_el);
6086 // marking empty option as selected can break validation
6087 // fixes https://github.com/orchidjs/tom-select/issues/303
6088 if (option_el != empty_option || has_selected > 0) {
6089 option_el.selected = true;
6090 }
6091 return option_el;
6092 }
6093 // unselect all selected options
6094 self.input.querySelectorAll('option:checked').forEach((option_el) => {
6095 option_el.selected = false;
6096 });
6097 // nothing selected?
6098 if (self.items.length == 0 && self.settings.mode == 'single') {
6099 AddSelected(empty_option, "", "");
6100 // order selected <option> tags for values in self.items
6101 }
6102 else {
6103 self.items.forEach((value) => {
6104 option = self.options[value];
6105 label = option[self.settings.labelField] || '';
6106 if (selected.includes(option.$option)) {
6107 const reuse_opt = self.input.querySelector(`option[value="${(0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.addSlashes)(value)}"]:not(:checked)`);
6108 AddSelected(reuse_opt, value, label);
6109 }
6110 else {
6111 option.$option = AddSelected(option.$option, value, label);
6112 }
6113 });
6114 }
6115 }
6116 else {
6117 self.input.value = self.getValue();
6118 }
6119 if (self.isSetup) {
6120 if (!opts.silent) {
6121 self.trigger('change', self.getValue());
6122 }
6123 }
6124 }
6125 /**
6126 * Shows the autocomplete dropdown containing
6127 * the available options.
6128 */
6129 open() {
6130 var self = this;
6131 if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull()))
6132 return;
6133 self.isOpen = true;
6134 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(self.focus_node, { 'aria-expanded': 'true' });
6135 self.refreshState();
6136 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.applyCSS)(self.dropdown, { visibility: 'hidden', display: 'block' });
6137 self.positionDropdown();
6138 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.applyCSS)(self.dropdown, { visibility: 'visible', display: 'block' });
6139 self.focus();
6140 self.trigger('dropdown_open', self.dropdown);
6141 }
6142 /**
6143 * Closes the autocomplete dropdown menu.
6144 */
6145 close(setTextboxValue = true) {
6146 var self = this;
6147 var trigger = self.isOpen;
6148 if (setTextboxValue) {
6149 // before blur() to prevent form onchange event
6150 self.setTextboxValue();
6151 if (self.settings.mode === 'single' && self.items.length) {
6152 self.inputState();
6153 }
6154 }
6155 self.isOpen = false;
6156 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(self.focus_node, { 'aria-expanded': 'false' });
6157 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.applyCSS)(self.dropdown, { display: 'none' });
6158 if (self.settings.hideSelected) {
6159 self.clearActiveOption();
6160 }
6161 self.refreshState();
6162 if (trigger)
6163 self.trigger('dropdown_close', self.dropdown);
6164 }
6165 /**
6166 * Calculates and applies the appropriate
6167 * position of the dropdown if dropdownParent = 'body'.
6168 * Otherwise, position is determined by css
6169 */
6170 positionDropdown() {
6171 if (this.settings.dropdownParent !== 'body') {
6172 return;
6173 }
6174 var context = this.control;
6175 var rect = context.getBoundingClientRect();
6176 var top = context.offsetHeight + rect.top + window.scrollY;
6177 var left = rect.left + window.scrollX;
6178 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.applyCSS)(this.dropdown, {
6179 width: rect.width + 'px',
6180 top: top + 'px',
6181 left: left + 'px'
6182 });
6183 }
6184 /**
6185 * Resets / clears all selected items
6186 * from the control.
6187 *
6188 */
6189 clear(silent) {
6190 var self = this;
6191 if (!self.items.length)
6192 return;
6193 var items = self.controlChildren();
6194 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(items, (item) => {
6195 self.removeItem(item, true);
6196 });
6197 self.inputState();
6198 if (!silent)
6199 self.updateOriginalInput();
6200 self.trigger('clear');
6201 }
6202 /**
6203 * A helper method for inserting an element
6204 * at the current caret position.
6205 *
6206 */
6207 insertAtCaret(el) {
6208 const self = this;
6209 const caret = self.caretPos;
6210 const target = self.control;
6211 target.insertBefore(el, target.children[caret] || null);
6212 self.setCaret(caret + 1);
6213 }
6214 /**
6215 * Removes the current selected item(s).
6216 *
6217 */
6218 deleteSelection(e) {
6219 var direction, selection, caret, tail;
6220 var self = this;
6221 direction = (e && e.keyCode === _constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_BACKSPACE) ? -1 : 1;
6222 selection = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.getSelection)(self.control_input);
6223 // determine items that will be removed
6224 const rm_items = [];
6225 if (self.activeItems.length) {
6226 tail = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getTail)(self.activeItems, direction);
6227 caret = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.nodeIndex)(tail);
6228 if (direction > 0) {
6229 caret++;
6230 }
6231 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(self.activeItems, (item) => rm_items.push(item));
6232 }
6233 else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) {
6234 const items = self.controlChildren();
6235 let rm_item;
6236 if (direction < 0 && selection.start === 0 && selection.length === 0) {
6237 rm_item = items[self.caretPos - 1];
6238 }
6239 else if (direction > 0 && selection.start === self.inputValue().length) {
6240 rm_item = items[self.caretPos];
6241 }
6242 if (rm_item !== undefined) {
6243 rm_items.push(rm_item);
6244 }
6245 }
6246 if (!self.shouldDelete(rm_items, e)) {
6247 return false;
6248 }
6249 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.preventDefault)(e, true);
6250 // perform removal
6251 if (typeof caret !== 'undefined') {
6252 self.setCaret(caret);
6253 }
6254 while (rm_items.length) {
6255 self.removeItem(rm_items.pop());
6256 }
6257 self.inputState();
6258 self.positionDropdown();
6259 self.refreshOptions(false);
6260 return true;
6261 }
6262 /**
6263 * Return true if the items should be deleted
6264 */
6265 shouldDelete(items, evt) {
6266 const values = items.map(item => item.dataset.value);
6267 // allow the callback to abort
6268 if (!values.length || (typeof this.settings.onDelete === 'function' && this.settings.onDelete(values, evt) === false)) {
6269 return false;
6270 }
6271 return true;
6272 }
6273 /**
6274 * Selects the previous / next item (depending on the `direction` argument).
6275 *
6276 * > 0 - right
6277 * < 0 - left
6278 *
6279 */
6280 advanceSelection(direction, e) {
6281 var last_active, adjacent, self = this;
6282 if (self.rtl)
6283 direction *= -1;
6284 if (self.inputValue().length)
6285 return;
6286 // add or remove to active items
6287 if ((0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.isKeyDown)(_constants_js__WEBPACK_IMPORTED_MODULE_5__.KEY_SHORTCUT, e) || (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.isKeyDown)('shiftKey', e)) {
6288 last_active = self.getLastActive(direction);
6289 if (last_active) {
6290 if (!last_active.classList.contains('active')) {
6291 adjacent = last_active;
6292 }
6293 else {
6294 adjacent = self.getAdjacent(last_active, direction, 'item');
6295 }
6296 // if no active item, get items adjacent to the control input
6297 }
6298 else if (direction > 0) {
6299 adjacent = self.control_input.nextElementSibling;
6300 }
6301 else {
6302 adjacent = self.control_input.previousElementSibling;
6303 }
6304 if (adjacent) {
6305 if (adjacent.classList.contains('active')) {
6306 self.removeActiveItem(last_active);
6307 }
6308 self.setActiveItemClass(adjacent); // mark as last_active !! after removeActiveItem() on last_active
6309 }
6310 // move caret to the left or right
6311 }
6312 else {
6313 self.moveCaret(direction);
6314 }
6315 }
6316 moveCaret(direction) { }
6317 /**
6318 * Get the last active item
6319 *
6320 */
6321 getLastActive(direction) {
6322 let last_active = this.control.querySelector('.last-active');
6323 if (last_active) {
6324 return last_active;
6325 }
6326 var result = this.control.querySelectorAll('.active');
6327 if (result) {
6328 return (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getTail)(result, direction);
6329 }
6330 }
6331 /**
6332 * Moves the caret to the specified index.
6333 *
6334 * The input must be moved by leaving it in place and moving the
6335 * siblings, due to the fact that focus cannot be restored once lost
6336 * on mobile webkit devices
6337 *
6338 */
6339 setCaret(new_pos) {
6340 this.caretPos = this.items.length;
6341 }
6342 /**
6343 * Return list of item dom elements
6344 *
6345 */
6346 controlChildren() {
6347 return Array.from(this.control.querySelectorAll('[data-ts-item]'));
6348 }
6349 /**
6350 * Disables user input on the control. Used while
6351 * items are being asynchronously created.
6352 */
6353 lock() {
6354 this.setLocked(true);
6355 }
6356 /**
6357 * Re-enables user input on the control.
6358 */
6359 unlock() {
6360 this.setLocked(false);
6361 }
6362 /**
6363 * Disable or enable user input on the control
6364 */
6365 setLocked(lock = this.isReadOnly || this.isDisabled) {
6366 this.isLocked = lock;
6367 this.refreshState();
6368 }
6369 /**
6370 * Disables user input on the control completely.
6371 * While disabled, it cannot receive focus.
6372 */
6373 disable() {
6374 this.setDisabled(true);
6375 this.close();
6376 }
6377 /**
6378 * Enables the control so that it can respond
6379 * to focus and user input.
6380 */
6381 enable() {
6382 this.setDisabled(false);
6383 }
6384 setDisabled(disabled) {
6385 this.focus_node.tabIndex = disabled ? -1 : this.tabIndex;
6386 this.isDisabled = disabled;
6387 this.input.disabled = disabled;
6388 this.control_input.disabled = disabled;
6389 this.setLocked();
6390 }
6391 setReadOnly(isReadOnly) {
6392 this.isReadOnly = isReadOnly;
6393 this.input.readOnly = isReadOnly;
6394 this.control_input.readOnly = isReadOnly;
6395 this.setLocked();
6396 }
6397 /**
6398 * Completely destroys the control and
6399 * unbinds all event listeners so that it can
6400 * be garbage collected.
6401 */
6402 destroy() {
6403 var self = this;
6404 var revertSettings = self.revertSettings;
6405 self.trigger('destroy');
6406 self.off();
6407 self.wrapper.remove();
6408 self.dropdown.remove();
6409 self.input.innerHTML = revertSettings.innerHTML;
6410 self.input.tabIndex = revertSettings.tabIndex;
6411 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.removeClasses)(self.input, 'tomselected', 'ts-hidden-accessible');
6412 self._destroy();
6413 delete self.input.tomselect;
6414 }
6415 /**
6416 * A helper method for rendering "item" and
6417 * "option" templates, given the data.
6418 *
6419 */
6420 render(templateName, data) {
6421 var id, html;
6422 const self = this;
6423 if (typeof this.settings.render[templateName] !== 'function') {
6424 return null;
6425 }
6426 // render markup
6427 html = self.settings.render[templateName].call(this, data, _utils_js__WEBPACK_IMPORTED_MODULE_7__.escape_html);
6428 if (!html) {
6429 return null;
6430 }
6431 html = (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.getDom)(html);
6432 // add mandatory attributes
6433 if (templateName === 'option' || templateName === 'option_create') {
6434 if (data[self.settings.disabledField]) {
6435 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(html, { 'aria-disabled': 'true' });
6436 }
6437 else {
6438 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(html, { 'data-selectable': '' });
6439 }
6440 }
6441 else if (templateName === 'optgroup') {
6442 id = data.group[self.settings.optgroupValueField];
6443 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(html, { 'data-group': id });
6444 if (data.group[self.settings.disabledField]) {
6445 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(html, { 'data-disabled': '' });
6446 }
6447 }
6448 if (templateName === 'option' || templateName === 'item') {
6449 const value = (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.get_hash)(data[self.settings.valueField]);
6450 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(html, { 'data-value': value });
6451 // make sure we have some classes if a template is overwritten
6452 if (templateName === 'item') {
6453 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(html, self.settings.itemClass);
6454 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(html, { 'data-ts-item': '' });
6455 }
6456 else {
6457 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.addClasses)(html, self.settings.optionClass);
6458 (0,_vanilla_js__WEBPACK_IMPORTED_MODULE_8__.setAttr)(html, {
6459 role: 'option',
6460 id: data.$id
6461 });
6462 // update cache
6463 data.$div = html;
6464 self.options[value] = data;
6465 }
6466 }
6467 return html;
6468 }
6469 /**
6470 * Type guarded rendering
6471 *
6472 */
6473 _render(templateName, data) {
6474 const html = this.render(templateName, data);
6475 if (html == null) {
6476 throw 'HTMLElement expected';
6477 }
6478 return html;
6479 }
6480 /**
6481 * Clears the render cache for a template. If
6482 * no template is given, clears all render
6483 * caches.
6484 *
6485 */
6486 clearCache() {
6487 (0,_utils_js__WEBPACK_IMPORTED_MODULE_7__.iterate)(this.options, (option) => {
6488 if (option.$div) {
6489 option.$div.remove();
6490 delete option.$div;
6491 }
6492 });
6493 }
6494 /**
6495 * Removes a value from item and option caches
6496 *
6497 */
6498 uncacheValue(value) {
6499 const option_el = this.getOption(value);
6500 if (option_el)
6501 option_el.remove();
6502 }
6503 /**
6504 * Determines whether or not to display the
6505 * create item prompt, given a user input.
6506 *
6507 */
6508 canCreate(input) {
6509 return this.settings.create && (input.length > 0) && this.settings.createFilter.call(this, input);
6510 }
6511 /**
6512 * Wraps this.`method` so that `new_fn` can be invoked 'before', 'after', or 'instead' of the original method
6513 *
6514 * this.hook('instead','onKeyDown',function( arg1, arg2 ...){
6515 *
6516 * });
6517 */
6518 hook(when, method, new_fn) {
6519 var self = this;
6520 var orig_method = self[method];
6521 self[method] = function () {
6522 var result, result_new;
6523 if (when === 'after') {
6524 result = orig_method.apply(self, arguments);
6525 }
6526 result_new = new_fn.apply(self, arguments);
6527 if (when === 'instead') {
6528 return result_new;
6529 }
6530 if (when === 'before') {
6531 result = orig_method.apply(self, arguments);
6532 }
6533 return result;
6534 };
6535 }
6536 }
6537 ;
6538 //# sourceMappingURL=tom-select.js.map
6539
6540 /***/ },
6541
6542 /***/ "./node_modules/tom-select/dist/esm/utils.js"
6543 /*!***************************************************!*\
6544 !*** ./node_modules/tom-select/dist/esm/utils.js ***!
6545 \***************************************************/
6546 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
6547
6548 __webpack_require__.r(__webpack_exports__);
6549 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6550 /* harmony export */ addEvent: () => (/* binding */ addEvent),
6551 /* harmony export */ addSlashes: () => (/* binding */ addSlashes),
6552 /* harmony export */ append: () => (/* binding */ append),
6553 /* harmony export */ debounce_events: () => (/* binding */ debounce_events),
6554 /* harmony export */ escape_html: () => (/* binding */ escape_html),
6555 /* harmony export */ getId: () => (/* binding */ getId),
6556 /* harmony export */ getSelection: () => (/* binding */ getSelection),
6557 /* harmony export */ get_hash: () => (/* binding */ get_hash),
6558 /* harmony export */ hash_key: () => (/* binding */ hash_key),
6559 /* harmony export */ isKeyDown: () => (/* binding */ isKeyDown),
6560 /* harmony export */ iterate: () => (/* binding */ iterate),
6561 /* harmony export */ loadDebounce: () => (/* binding */ loadDebounce),
6562 /* harmony export */ preventDefault: () => (/* binding */ preventDefault),
6563 /* harmony export */ timeout: () => (/* binding */ timeout)
6564 /* harmony export */ });
6565 /**
6566 * Converts a scalar to its best string representation
6567 * for hash keys and HTML attribute values.
6568 *
6569 * Transformations:
6570 * 'str' -> 'str'
6571 * null -> ''
6572 * undefined -> ''
6573 * true -> '1'
6574 * false -> '0'
6575 * 0 -> '0'
6576 * 1 -> '1'
6577 *
6578 */
6579 const hash_key = (value) => {
6580 if (typeof value === 'undefined' || value === null)
6581 return null;
6582 return get_hash(value);
6583 };
6584 const get_hash = (value) => {
6585 if (typeof value === 'boolean')
6586 return value ? '1' : '0';
6587 return value + '';
6588 };
6589 /**
6590 * Escapes a string for use within HTML.
6591 *
6592 */
6593 const escape_html = (str) => {
6594 return (str + '')
6595 .replace(/&/g, '&amp;')
6596 .replace(/</g, '&lt;')
6597 .replace(/>/g, '&gt;')
6598 .replace(/"/g, '&quot;');
6599 };
6600 /**
6601 * use setTimeout if timeout > 0
6602 */
6603 const timeout = (fn, timeout) => {
6604 if (timeout > 0) {
6605 return window.setTimeout(fn, timeout);
6606 }
6607 fn.call(null);
6608 return null;
6609 };
6610 /**
6611 * Debounce the user provided load function
6612 *
6613 */
6614 const loadDebounce = (fn, delay) => {
6615 var timeout;
6616 return function (value, callback) {
6617 var self = this;
6618 if (timeout) {
6619 self.loading = Math.max(self.loading - 1, 0);
6620 clearTimeout(timeout);
6621 }
6622 timeout = setTimeout(function () {
6623 timeout = null;
6624 self.loadedSearches[value] = true;
6625 fn.call(self, value, callback);
6626 }, delay);
6627 };
6628 };
6629 /**
6630 * Debounce all fired events types listed in `types`
6631 * while executing the provided `fn`.
6632 *
6633 */
6634 const debounce_events = (self, types, fn) => {
6635 var type;
6636 var trigger = self.trigger;
6637 var event_args = {};
6638 // override trigger method
6639 self.trigger = function () {
6640 var type = arguments[0];
6641 if (types.indexOf(type) !== -1) {
6642 event_args[type] = arguments;
6643 }
6644 else {
6645 return trigger.apply(self, arguments);
6646 }
6647 };
6648 // invoke provided function
6649 fn.apply(self, []);
6650 self.trigger = trigger;
6651 // trigger queued events
6652 for (type of types) {
6653 if (type in event_args) {
6654 trigger.apply(self, event_args[type]);
6655 }
6656 }
6657 };
6658 /**
6659 * Determines the current selection within a text input control.
6660 * Returns an object containing:
6661 * - start
6662 * - length
6663 *
6664 * Note: "selectionStart, selectionEnd ... apply only to inputs of types text, search, URL, tel and password"
6665 * - https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
6666 */
6667 const getSelection = (input) => {
6668 return {
6669 start: input.selectionStart || 0,
6670 length: (input.selectionEnd || 0) - (input.selectionStart || 0),
6671 };
6672 };
6673 /**
6674 * Prevent default
6675 *
6676 */
6677 const preventDefault = (evt, stop = false) => {
6678 if (evt) {
6679 evt.preventDefault();
6680 if (stop) {
6681 evt.stopPropagation();
6682 }
6683 }
6684 };
6685 /**
6686 * Add event helper
6687 *
6688 */
6689 const addEvent = (target, type, callback, options) => {
6690 target.addEventListener(type, callback, options);
6691 };
6692 /**
6693 * Return true if the requested key is down
6694 * Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )
6695 * The current evt may not always set ( eg calling advanceSelection() )
6696 *
6697 */
6698 const isKeyDown = (key_name, evt) => {
6699 if (!evt) {
6700 return false;
6701 }
6702 if (!evt[key_name]) {
6703 return false;
6704 }
6705 var count = (evt.altKey ? 1 : 0) + (evt.ctrlKey ? 1 : 0) + (evt.shiftKey ? 1 : 0) + (evt.metaKey ? 1 : 0);
6706 if (count === 1) {
6707 return true;
6708 }
6709 return false;
6710 };
6711 /**
6712 * Get the id of an element
6713 * If the id attribute is not set, set the attribute with the given id
6714 *
6715 */
6716 const getId = (el, id) => {
6717 const existing_id = el.getAttribute('id');
6718 if (existing_id) {
6719 return existing_id;
6720 }
6721 el.setAttribute('id', id);
6722 return id;
6723 };
6724 /**
6725 * Returns a string with backslashes added before characters that need to be escaped.
6726 */
6727 const addSlashes = (str) => {
6728 return str.replace(/[\\"']/g, '\\$&');
6729 };
6730 /**
6731 *
6732 */
6733 const append = (parent, node) => {
6734 if (node)
6735 parent.append(node);
6736 };
6737 /**
6738 * Iterates over arrays and hashes.
6739 *
6740 * ```
6741 * iterate(this.items, function(item, id) {
6742 * // invoked for each item
6743 * });
6744 * ```
6745 *
6746 */
6747 const iterate = (object, callback) => {
6748 if (Array.isArray(object)) {
6749 object.forEach(callback);
6750 }
6751 else {
6752 for (var key in object) {
6753 if (object.hasOwnProperty(key)) {
6754 callback(object[key], key);
6755 }
6756 }
6757 }
6758 };
6759 //# sourceMappingURL=utils.js.map
6760
6761 /***/ },
6762
6763 /***/ "./node_modules/tom-select/dist/esm/vanilla.js"
6764 /*!*****************************************************!*\
6765 !*** ./node_modules/tom-select/dist/esm/vanilla.js ***!
6766 \*****************************************************/
6767 (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
6768
6769 __webpack_require__.r(__webpack_exports__);
6770 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6771 /* harmony export */ addClasses: () => (/* binding */ addClasses),
6772 /* harmony export */ applyCSS: () => (/* binding */ applyCSS),
6773 /* harmony export */ castAsArray: () => (/* binding */ castAsArray),
6774 /* harmony export */ classesArray: () => (/* binding */ classesArray),
6775 /* harmony export */ escapeQuery: () => (/* binding */ escapeQuery),
6776 /* harmony export */ getDom: () => (/* binding */ getDom),
6777 /* harmony export */ getTail: () => (/* binding */ getTail),
6778 /* harmony export */ isEmptyObject: () => (/* binding */ isEmptyObject),
6779 /* harmony export */ isHtmlString: () => (/* binding */ isHtmlString),
6780 /* harmony export */ nodeIndex: () => (/* binding */ nodeIndex),
6781 /* harmony export */ parentMatch: () => (/* binding */ parentMatch),
6782 /* harmony export */ removeClasses: () => (/* binding */ removeClasses),
6783 /* harmony export */ replaceNode: () => (/* binding */ replaceNode),
6784 /* harmony export */ setAttr: () => (/* binding */ setAttr),
6785 /* harmony export */ triggerEvent: () => (/* binding */ triggerEvent)
6786 /* harmony export */ });
6787 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils.js */ "./node_modules/tom-select/dist/esm/utils.js");
6788
6789 /**
6790 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
6791 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
6792 *
6793 * param query should be {}
6794 */
6795 const getDom = (query) => {
6796 if (query.jquery) {
6797 return query[0];
6798 }
6799 if (query instanceof HTMLElement) {
6800 return query;
6801 }
6802 if (isHtmlString(query)) {
6803 var tpl = document.createElement('template');
6804 tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
6805 return tpl.content.firstChild;
6806 }
6807 return document.querySelector(query);
6808 };
6809 const isHtmlString = (arg) => {
6810 if (typeof arg === 'string' && arg.indexOf('<') > -1) {
6811 return true;
6812 }
6813 return false;
6814 };
6815 const escapeQuery = (query) => {
6816 return query.replace(/['"\\]/g, '\\$&');
6817 };
6818 /**
6819 * Dispatch an event
6820 *
6821 */
6822 const triggerEvent = (dom_el, event_name) => {
6823 var event = document.createEvent('HTMLEvents');
6824 event.initEvent(event_name, true, false);
6825 dom_el.dispatchEvent(event);
6826 };
6827 /**
6828 * Apply CSS rules to a dom element
6829 *
6830 */
6831 const applyCSS = (dom_el, css) => {
6832 Object.assign(dom_el.style, css);
6833 };
6834 /**
6835 * Add css classes
6836 *
6837 */
6838 const addClasses = (elmts, ...classes) => {
6839 var norm_classes = classesArray(classes);
6840 elmts = castAsArray(elmts);
6841 elmts.map(el => {
6842 norm_classes.map(cls => {
6843 el.classList.add(cls);
6844 });
6845 });
6846 };
6847 /**
6848 * Remove css classes
6849 *
6850 */
6851 const removeClasses = (elmts, ...classes) => {
6852 var norm_classes = classesArray(classes);
6853 elmts = castAsArray(elmts);
6854 elmts.map(el => {
6855 norm_classes.map(cls => {
6856 el.classList.remove(cls);
6857 });
6858 });
6859 };
6860 /**
6861 * Return arguments
6862 *
6863 */
6864 const classesArray = (args) => {
6865 var classes = [];
6866 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.iterate)(args, (_classes) => {
6867 if (typeof _classes === 'string') {
6868 _classes = _classes.trim().split(/[\t\n\f\r\s]/);
6869 }
6870 if (Array.isArray(_classes)) {
6871 classes = classes.concat(_classes);
6872 }
6873 });
6874 return classes.filter(Boolean);
6875 };
6876 /**
6877 * Create an array from arg if it's not already an array
6878 *
6879 */
6880 const castAsArray = (arg) => {
6881 if (!Array.isArray(arg)) {
6882 arg = [arg];
6883 }
6884 return arg;
6885 };
6886 /**
6887 * Get the closest node to the evt.target matching the selector
6888 * Stops at wrapper
6889 *
6890 */
6891 const parentMatch = (target, selector, wrapper) => {
6892 if (wrapper && !wrapper.contains(target)) {
6893 return;
6894 }
6895 while (target && target.matches) {
6896 if (target.matches(selector)) {
6897 return target;
6898 }
6899 target = target.parentNode;
6900 }
6901 };
6902 /**
6903 * Get the first or last item from an array
6904 *
6905 * > 0 - right (last)
6906 * <= 0 - left (first)
6907 *
6908 */
6909 const getTail = (list, direction = 0) => {
6910 if (direction > 0) {
6911 return list[list.length - 1];
6912 }
6913 return list[0];
6914 };
6915 /**
6916 * Return true if an object is empty
6917 *
6918 */
6919 const isEmptyObject = (obj) => {
6920 return (Object.keys(obj).length === 0);
6921 };
6922 /**
6923 * Get the index of an element amongst sibling nodes of the same type
6924 *
6925 */
6926 const nodeIndex = (el, amongst) => {
6927 if (!el)
6928 return -1;
6929 amongst = amongst || el.nodeName;
6930 var i = 0;
6931 while (el = el.previousElementSibling) {
6932 if (el.matches(amongst)) {
6933 i++;
6934 }
6935 }
6936 return i;
6937 };
6938 /**
6939 * Set attributes of an element
6940 *
6941 */
6942 const setAttr = (el, attrs) => {
6943 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.iterate)(attrs, (val, attr) => {
6944 if (val == null) {
6945 el.removeAttribute(attr);
6946 }
6947 else {
6948 el.setAttribute(attr, '' + val);
6949 }
6950 });
6951 };
6952 /**
6953 * Replace a node
6954 */
6955 const replaceNode = (existing, replacement) => {
6956 if (existing.parentNode)
6957 existing.parentNode.replaceChild(replacement, existing);
6958 };
6959 //# sourceMappingURL=vanilla.js.map
6960
6961 /***/ }
6962
6963 /******/ });
6964 /************************************************************************/
6965 /******/ // The module cache
6966 /******/ var __webpack_module_cache__ = {};
6967 /******/
6968 /******/ // The require function
6969 /******/ function __webpack_require__(moduleId) {
6970 /******/ // Check if module is in cache
6971 /******/ var cachedModule = __webpack_module_cache__[moduleId];
6972 /******/ if (cachedModule !== undefined) {
6973 /******/ return cachedModule.exports;
6974 /******/ }
6975 /******/ // Create a new module (and put it into the cache)
6976 /******/ var module = __webpack_module_cache__[moduleId] = {
6977 /******/ // no module.id needed
6978 /******/ // no module.loaded needed
6979 /******/ exports: {}
6980 /******/ };
6981 /******/
6982 /******/ // Execute the module function
6983 /******/ if (!(moduleId in __webpack_modules__)) {
6984 /******/ delete __webpack_module_cache__[moduleId];
6985 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
6986 /******/ e.code = 'MODULE_NOT_FOUND';
6987 /******/ throw e;
6988 /******/ }
6989 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
6990 /******/
6991 /******/ // Return the exports of the module
6992 /******/ return module.exports;
6993 /******/ }
6994 /******/
6995 /************************************************************************/
6996 /******/ /* webpack/runtime/define property getters */
6997 /******/ (() => {
6998 /******/ // define getter functions for harmony exports
6999 /******/ __webpack_require__.d = (exports, definition) => {
7000 /******/ for(var key in definition) {
7001 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
7002 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
7003 /******/ }
7004 /******/ }
7005 /******/ };
7006 /******/ })();
7007 /******/
7008 /******/ /* webpack/runtime/hasOwnProperty shorthand */
7009 /******/ (() => {
7010 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
7011 /******/ })();
7012 /******/
7013 /******/ /* webpack/runtime/make namespace object */
7014 /******/ (() => {
7015 /******/ // define __esModule on exports
7016 /******/ __webpack_require__.r = (exports) => {
7017 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
7018 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7019 /******/ }
7020 /******/ Object.defineProperty(exports, '__esModule', { value: true });
7021 /******/ };
7022 /******/ })();
7023 /******/
7024 /************************************************************************/
7025 var __webpack_exports__ = {};
7026 // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
7027 (() => {
7028 /*!********************************************!*\
7029 !*** ./assets/src/js/admin/admin-tools.js ***!
7030 \********************************************/
7031 __webpack_require__.r(__webpack_exports__);
7032 /* harmony import */ var _tools_assign_user_course__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tools/assign-user-course */ "./assets/src/js/admin/tools/assign-user-course.js");
7033
7034 (0,_tools_assign_user_course__WEBPACK_IMPORTED_MODULE_0__["default"])();
7035 })();
7036
7037 /******/ })()
7038 ;
7039 //# sourceMappingURL=admin-tools.js.map