PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.6
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.6
4.4.8 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 All 139 releases
learnpress / assets / dist / js / admin / edit-question.js

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

11,094 lines 395.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./assets/src/js/lpToastify.js"
5 /*!*************************************!*\
6 !*** ./assets/src/js/lpToastify.js ***!
7 \*************************************/
8 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
9
10 "use strict";
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ show: () => (/* binding */ show)
14 /* harmony export */ });
15 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
16 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
17 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
18 /**
19 * Utils functions
20 *
21 * @param url
22 * @param data
23 * @param functions
24 * @since 4.3.0
25 * @version 1.0.0
26 */
27
28
29 const argsToastify = {
30 text: '',
31 gravity: lpData.toast.gravity,
32 // `top` or `bottom`
33 position: lpData.toast.position,
34 // `left`, `center` or `right`
35 className: `${lpData.toast.classPrefix}`,
36 close: lpData.toast.close == 1,
37 stopOnFocus: lpData.toast.stopOnFocus == 1,
38 duration: lpData.toast.duration
39 };
40 const show = (message, status = 'success', argsCustom) => {
41 let args = argsToastify;
42 if (argsCustom) {
43 args = {
44 ...args,
45 ...argsCustom
46 };
47 }
48 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
49 ...args,
50 text: message,
51 className: `${lpData.toast.classPrefix} ${status}`
52 });
53 toastify.showToast();
54 };
55
56 /***/ },
57
58 /***/ "./assets/src/js/utils.js"
59 /*!********************************!*\
60 !*** ./assets/src/js/utils.js ***!
61 \********************************/
62 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
63
64 "use strict";
65 __webpack_require__.r(__webpack_exports__);
66 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
67 /* harmony export */ debounce: () => (/* binding */ debounce),
68 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
69 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
70 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
71 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
72 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
73 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
74 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
75 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
76 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
77 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
78 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
79 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
80 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
81 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
82 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
83 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
84 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
85 /* harmony export */ });
86 /**
87 * Utils functions
88 *
89 * @param url
90 * @param data
91 * @param functions
92 * @since 4.2.5.1
93 * @version 1.0.7
94 */
95 const lpClassName = {
96 hidden: 'lp-hidden',
97 loading: 'loading',
98 elCollapse: 'lp-collapse',
99 elSectionToggle: '.lp-section-toggle',
100 elTriggerToggle: '.lp-trigger-toggle',
101 elBtnFullScreen: '.lp-btn-full-screen-view',
102 elFullScreen: 'lp-full-screen-view',
103 elBtnFullScreenClose: 'lp-full-screen-view__close'
104 };
105 const lpFetchAPI = (url, data = {}, functions = {}) => {
106 if ('function' === typeof functions.before) {
107 functions.before();
108 }
109 fetch(url, {
110 method: 'GET',
111 ...data
112 }).then(response => response.json()).then(response => {
113 if ('function' === typeof functions.success) {
114 functions.success(response);
115 }
116 }).catch(err => {
117 if ('function' === typeof functions.error) {
118 functions.error(err);
119 }
120 }).finally(() => {
121 if ('function' === typeof functions.completed) {
122 functions.completed();
123 }
124 });
125 };
126
127 /**
128 * Get current URL without params.
129 *
130 * @since 4.2.5.1
131 */
132 const lpGetCurrentURLNoParam = () => {
133 let currentUrl = window.location.href;
134 const hasParams = currentUrl.includes('?');
135 if (hasParams) {
136 currentUrl = currentUrl.split('?')[0];
137 }
138 return currentUrl;
139 };
140 const lpAddQueryArgs = (endpoint, args) => {
141 const url = new URL(endpoint);
142 Object.keys(args).forEach(arg => {
143 url.searchParams.set(arg, args[arg]);
144 });
145 return url;
146 };
147
148 /**
149 * Listen element viewed.
150 *
151 * @param el
152 * @param callback
153 * @since 4.2.5.8
154 */
155 const listenElementViewed = (el, callback) => {
156 const observerSeeItem = new IntersectionObserver(function (entries) {
157 for (const entry of entries) {
158 if (entry.isIntersecting) {
159 callback(entry);
160 }
161 }
162 });
163 observerSeeItem.observe(el);
164 };
165
166 /**
167 * Listen element created.
168 *
169 * @param callback
170 * @since 4.2.5.8
171 */
172 const listenElementCreated = callback => {
173 const observerCreateItem = new MutationObserver(function (mutations) {
174 mutations.forEach(function (mutation) {
175 if (mutation.addedNodes) {
176 mutation.addedNodes.forEach(function (node) {
177 if (node.nodeType === 1) {
178 callback(node);
179 }
180 });
181 }
182 });
183 });
184 observerCreateItem.observe(document, {
185 childList: true,
186 subtree: true
187 });
188 // End.
189 };
190
191 /**
192 * Listen element created.
193 *
194 * @param selector
195 * @param callback
196 * @since 4.2.7.1
197 */
198 const lpOnElementReady = (selector, callback) => {
199 const element = document.querySelector(selector);
200 if (element) {
201 callback(element);
202 return;
203 }
204 const observer = new MutationObserver((mutations, obs) => {
205 const element = document.querySelector(selector);
206 if (element) {
207 obs.disconnect();
208 callback(element);
209 }
210 });
211 observer.observe(document.documentElement, {
212 childList: true,
213 subtree: true
214 });
215 };
216
217 // Parse JSON from string with content include LP_AJAX_START.
218 const lpAjaxParseJsonOld = data => {
219 if (typeof data !== 'string') {
220 return data;
221 }
222 const m = String.raw({
223 raw: data
224 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
225 try {
226 if (m) {
227 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
228 } else {
229 data = JSON.parse(data);
230 }
231 } catch (e) {
232 data = {};
233 }
234 return data;
235 };
236
237 // status 0: hide, 1: show
238 const lpShowHideEl = (el, status = 0) => {
239 if (!el) {
240 return;
241 }
242 if (!status) {
243 el.classList.add(lpClassName.hidden);
244 } else {
245 el.classList.remove(lpClassName.hidden);
246 }
247 };
248
249 // status 0: hide, 1: show
250 const lpSetLoadingEl = (el, status) => {
251 if (!el) {
252 return;
253 }
254 if (!status) {
255 el.classList.remove(lpClassName.loading);
256 } else {
257 el.classList.add(lpClassName.loading);
258 }
259 };
260
261 // Toggle collapse section
262 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
263 if (!elTriggerClassName) {
264 elTriggerClassName = lpClassName.elTriggerToggle;
265 }
266
267 // Exclude elements, which should not trigger the collapse toggle
268 if (elsExclude && elsExclude.length > 0) {
269 for (const elExclude of elsExclude) {
270 if (target.closest(elExclude)) {
271 return;
272 }
273 }
274 }
275 const elTrigger = target.closest(elTriggerClassName);
276 if (!elTrigger) {
277 return;
278 }
279
280 //console.log( 'elTrigger', elTrigger );
281
282 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
283 if (!elSectionToggle) {
284 return;
285 }
286 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
287 if ('function' === typeof callback) {
288 callback(elSectionToggle);
289 }
290 };
291
292 // Get data of form
293 const getDataOfForm = form => {
294 const dataSend = {};
295 const formData = new FormData(form);
296 for (const pair of formData.entries()) {
297 const key = pair[0];
298 const value = formData.getAll(key);
299 if (!dataSend.hasOwnProperty(key)) {
300 // Convert value array to string.
301 dataSend[key] = value.join(',');
302 }
303 }
304 return dataSend;
305 };
306
307 // Get field keys of form
308 const getFieldKeysOfForm = form => {
309 const keys = [];
310 const elements = form.elements;
311 for (let i = 0; i < elements.length; i++) {
312 const name = elements[i].name;
313 if (name && !keys.includes(name)) {
314 keys.push(name);
315 }
316 }
317 return keys;
318 };
319
320 // Merge data handle with data form.
321 const mergeDataWithDatForm = (elForm, dataHandle) => {
322 const dataForm = getDataOfForm(elForm);
323 const keys = getFieldKeysOfForm(elForm);
324 keys.forEach(key => {
325 if (!dataForm.hasOwnProperty(key)) {
326 delete dataHandle[key];
327 } else if (dataForm[key][0] === '') {
328 delete dataForm[key];
329 delete dataHandle[key];
330 }
331 });
332 dataHandle = {
333 ...dataHandle,
334 ...dataForm
335 };
336 return dataHandle;
337 };
338
339 /**
340 * Event trigger
341 * For each list of event handlers, listen event on document.
342 *
343 * eventName: 'click', 'change', ...
344 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
345 *
346 * @param eventName
347 * @param eventHandlers
348 */
349 const eventHandlers = (eventName, eventHandlers) => {
350 document.addEventListener(eventName, e => {
351 const target = e.target;
352 let args = {
353 e,
354 target
355 };
356 eventHandlers.forEach(eventHandler => {
357 args = {
358 ...args,
359 ...eventHandler
360 };
361
362 //console.log( args );
363
364 // Check condition before call back
365 if (eventHandler.conditionBeforeCallBack) {
366 if (eventHandler.conditionBeforeCallBack(args) !== true) {
367 return;
368 }
369 }
370
371 // Special check for keydown event with checkIsEventEnter = true
372 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
373 if (e.key !== 'Enter') {
374 return;
375 }
376 }
377 if (target.closest(eventHandler.selector)) {
378 if (eventHandler.class) {
379 // Call method of class, function callBack will understand exactly {this} is class object.
380 eventHandler.class[eventHandler.callBack](args);
381 } else {
382 // For send args is objected, {this} is eventHandler object, not class object.
383 eventHandler.callBack(args);
384 }
385 }
386 });
387 });
388 };
389
390 /**
391 * Debounce - delays function execution until after `wait` ms of inactivity.
392 *
393 * Each call resets the timer. Only the last call in a burst executes.
394 *
395 * USE CASES:
396 * - Search inputs, form validation, window resize
397 * - Multiple elements need independent timers
398 * - When you need to call with different arguments
399 *
400 * EXAMPLES:
401 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
402 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
403 *
404 * const debouncedResize = debounce( recalculateLayout, 250 );
405 * window.addEventListener('resize', debouncedResize);
406 *
407 * ⚠️ Create ONCE outside event handlers, not inside.
408 *
409 * @param {Function} func - Function to debounce (can be anonymous)
410 * @param {number} wait - Milliseconds to wait (default: 500)
411 * @return {Function} Debounced wrapper function
412 * @since 4.3.7
413 * @version 1.0.0
414 */
415 const debounce = (func, wait = 500) => {
416 let timer;
417 return args => {
418 clearTimeout(timer);
419 timer = setTimeout(() => func(args), wait);
420 };
421 };
422
423 /**
424 * Initialize lp-toggle-enable components.
425 *
426 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
427 * Reads initial state from `data-enabled` attribute ("true"/"false").
428 * Calls `data-on-toggle` callback (if provided via options) on state change.
429 *
430 * HTML structure:
431 * <label class="lp-toggle-enable" data-enabled="true">
432 * <input type="checkbox" class="lp-toggle-enable__input" />
433 * <span class="lp-toggle-enable__track"></span>
434 * </label>
435 *
436 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
437 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
438 * @since 4.4.5
439 * @version 1.0.0
440 */
441 window.lpToggleEnableInit = 0;
442 const toggleEnable = (onToggle = null) => {
443 if (window.lpToggleEnableInit) {
444 return;
445 }
446 window.lpToggleEnableInit = 1;
447 const selector = '.lp-toggle-enable';
448 const updateUI = (toggle, isEnabled) => {
449 toggle.classList.toggle('is-enabled', isEnabled);
450 const input = toggle.querySelector('.lp-toggle-enable__input');
451 if (input) {
452 input.checked = isEnabled;
453 input.value = isEnabled ? '1' : '0';
454 }
455 };
456
457 // Delegate click handling via eventHandlers.
458 eventHandlers('click', [{
459 selector,
460 callBack: args => {
461 const {
462 e,
463 target
464 } = args;
465 const toggle = target.closest(selector);
466 if (!toggle || toggle.classList.contains('is-disabled')) {
467 return;
468 }
469 e.preventDefault();
470 const isEnabled = !toggle.classList.contains('is-enabled');
471 updateUI(toggle, isEnabled);
472 if ('function' === typeof onToggle) {
473 onToggle(toggle, isEnabled);
474 }
475 }
476 }]);
477 };
478
479 /**
480 * Initialize custom fullscreen view buttons.
481 *
482 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
483 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
484 * target element. Falls back to the button's parent element when
485 * `data-target` is not provided.
486 *
487 * @since 4.4.5
488 * @version 1.0.0
489 */
490 window.lpFullScreenViewInit = 0;
491 const fullScreenView = () => {
492 if (window.lpFullScreenViewInit) {
493 return;
494 }
495 window.lpFullScreenViewInit = 1;
496 let lastScrollY = 0;
497 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
498 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
499 if (isFullscreen) {
500 elTarget.classList.remove(lpClassName.elFullScreen);
501 document.documentElement.classList.remove('lp-full-screen-active');
502 window.scrollTo(0, lastScrollY);
503 } else {
504 lastScrollY = window.scrollY;
505 elTarget.classList.add(lpClassName.elFullScreen);
506 document.documentElement.classList.add('lp-full-screen-active');
507 }
508 if (!isFullscreen) {
509 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
510 const closeButton = document.createElement('button');
511 closeButton.type = 'button';
512 closeButton.className = lpClassName.elBtnFullScreenClose;
513 closeButton.setAttribute('aria-label', 'Close');
514 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
515 closeButton.addEventListener('click', e => {
516 e.preventDefault();
517 lpToggleFullscreenView(elTarget);
518 });
519 elTarget.appendChild(closeButton);
520 }
521 } else {
522 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
523 if (closeButton) {
524 closeButton.remove();
525 }
526 }
527 };
528 eventHandlers('click', [{
529 selector: lpClassName.elBtnFullScreen,
530 callBack: args => {
531 const {
532 e,
533 target
534 } = args;
535 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
536 if (!elBtnFullScreen) {
537 console.log('No full screen button found');
538 return;
539 }
540 e.preventDefault();
541 let elTarget = null;
542 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
543 console.log(targetSelector);
544 if (targetSelector) {
545 elTarget = document.querySelector(targetSelector);
546 }
547 if (!elTarget) {
548 console.log('No target element found');
549 return;
550 }
551 lpToggleFullscreenView(elTarget, elBtnFullScreen);
552 }
553 }]);
554 };
555
556 /***/ },
557
558 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
559 /*!*****************************************************************************************!*\
560 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
561 \*****************************************************************************************/
562 (module, __webpack_exports__, __webpack_require__) {
563
564 "use strict";
565 __webpack_require__.r(__webpack_exports__);
566 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
567 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
568 /* harmony export */ });
569 /* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../css-loader/dist/runtime/sourceMaps.js */ "./node_modules/css-loader/dist/runtime/sourceMaps.js");
570 /* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
571 /* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
572 /* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
573 // Imports
574
575
576 var ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
577 // Module
578 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
579 * Toastify js 1.12.0
580 * https://github.com/apvarun/toastify-js
581 * @license MIT licensed
582 *
583 * Copyright (C) 2018 Varun A P
584 */
585
586 .toastify {
587 padding: 12px 20px;
588 color: #ffffff;
589 display: inline-block;
590 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
591 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
592 background: linear-gradient(135deg, #73a5ff, #5477f5);
593 position: fixed;
594 opacity: 0;
595 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
596 border-radius: 2px;
597 cursor: pointer;
598 text-decoration: none;
599 max-width: calc(50% - 20px);
600 z-index: 2147483647;
601 }
602
603 .toastify.on {
604 opacity: 1;
605 }
606
607 .toast-close {
608 background: transparent;
609 border: 0;
610 color: white;
611 cursor: pointer;
612 font-family: inherit;
613 font-size: 1em;
614 opacity: 0.4;
615 padding: 0 5px;
616 }
617
618 .toastify-right {
619 right: 15px;
620 }
621
622 .toastify-left {
623 left: 15px;
624 }
625
626 .toastify-top {
627 top: -150px;
628 }
629
630 .toastify-bottom {
631 bottom: -150px;
632 }
633
634 .toastify-rounded {
635 border-radius: 25px;
636 }
637
638 .toastify-avatar {
639 width: 1.5em;
640 height: 1.5em;
641 margin: -7px 5px;
642 border-radius: 2px;
643 }
644
645 .toastify-center {
646 margin-left: auto;
647 margin-right: auto;
648 left: 0;
649 right: 0;
650 max-width: fit-content;
651 max-width: -moz-fit-content;
652 }
653
654 @media only screen and (max-width: 360px) {
655 .toastify-right, .toastify-left {
656 margin-left: auto;
657 margin-right: auto;
658 left: 0;
659 right: 0;
660 max-width: fit-content;
661 }
662 }
663 `, "",{"version":3,"sources":["webpack://./node_modules/toastify-js/src/toastify.css"],"names":[],"mappings":"AAAA;;;;;;EAME;;AAEF;IACI,kBAAkB;IAClB,cAAc;IACd,qBAAqB;IACrB,uFAAuF;IACvF,6DAA6D;IAC7D,qDAAqD;IACrD,eAAe;IACf,UAAU;IACV,wDAAwD;IACxD,kBAAkB;IAClB,eAAe;IACf,qBAAqB;IACrB,2BAA2B;IAC3B,mBAAmB;AACvB;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,uBAAuB;IACvB,SAAS;IACT,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,cAAc;IACd,YAAY;IACZ,cAAc;AAClB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,YAAY;IACZ,aAAa;IACb,gBAAgB;IAChB,kBAAkB;AACtB;;AAEA;IACI,iBAAiB;IACjB,kBAAkB;IAClB,OAAO;IACP,QAAQ;IACR,sBAAsB;IACtB,2BAA2B;AAC/B;;AAEA;IACI;QACI,iBAAiB;QACjB,kBAAkB;QAClB,OAAO;QACP,QAAQ;QACR,sBAAsB;IAC1B;AACJ","sourcesContent":["/*!\n * Toastify js 1.12.0\n * https://github.com/apvarun/toastify-js\n * @license MIT licensed\n *\n * Copyright (C) 2018 Varun A P\n */\n\n.toastify {\n padding: 12px 20px;\n color: #ffffff;\n display: inline-block;\n box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);\n background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);\n background: linear-gradient(135deg, #73a5ff, #5477f5);\n position: fixed;\n opacity: 0;\n transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);\n border-radius: 2px;\n cursor: pointer;\n text-decoration: none;\n max-width: calc(50% - 20px);\n z-index: 2147483647;\n}\n\n.toastify.on {\n opacity: 1;\n}\n\n.toast-close {\n background: transparent;\n border: 0;\n color: white;\n cursor: pointer;\n font-family: inherit;\n font-size: 1em;\n opacity: 0.4;\n padding: 0 5px;\n}\n\n.toastify-right {\n right: 15px;\n}\n\n.toastify-left {\n left: 15px;\n}\n\n.toastify-top {\n top: -150px;\n}\n\n.toastify-bottom {\n bottom: -150px;\n}\n\n.toastify-rounded {\n border-radius: 25px;\n}\n\n.toastify-avatar {\n width: 1.5em;\n height: 1.5em;\n margin: -7px 5px;\n border-radius: 2px;\n}\n\n.toastify-center {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n max-width: -moz-fit-content;\n}\n\n@media only screen and (max-width: 360px) {\n .toastify-right, .toastify-left {\n margin-left: auto;\n margin-right: auto;\n left: 0;\n right: 0;\n max-width: fit-content;\n }\n}\n"],"sourceRoot":""}]);
664 // Exports
665 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
666
667
668 /***/ },
669
670 /***/ "./node_modules/css-loader/dist/runtime/api.js"
671 /*!*****************************************************!*\
672 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
673 \*****************************************************/
674 (module) {
675
676 "use strict";
677
678
679 /*
680 MIT License http://www.opensource.org/licenses/mit-license.php
681 Author Tobias Koppers @sokra
682 */
683 module.exports = function (cssWithMappingToString) {
684 var list = [];
685
686 // return the list of modules as css string
687 list.toString = function toString() {
688 return this.map(function (item) {
689 var content = "";
690 var needLayer = typeof item[5] !== "undefined";
691 if (item[4]) {
692 content += "@supports (".concat(item[4], ") {");
693 }
694 if (item[2]) {
695 content += "@media ".concat(item[2], " {");
696 }
697 if (needLayer) {
698 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
699 }
700 content += cssWithMappingToString(item);
701 if (needLayer) {
702 content += "}";
703 }
704 if (item[2]) {
705 content += "}";
706 }
707 if (item[4]) {
708 content += "}";
709 }
710 return content;
711 }).join("");
712 };
713
714 // import a list of modules into the list
715 list.i = function i(modules, media, dedupe, supports, layer) {
716 if (typeof modules === "string") {
717 modules = [[null, modules, undefined]];
718 }
719 var alreadyImportedModules = {};
720 if (dedupe) {
721 for (var k = 0; k < this.length; k++) {
722 var id = this[k][0];
723 if (id != null) {
724 alreadyImportedModules[id] = true;
725 }
726 }
727 }
728 for (var _k = 0; _k < modules.length; _k++) {
729 var item = [].concat(modules[_k]);
730 if (dedupe && alreadyImportedModules[item[0]]) {
731 continue;
732 }
733 if (typeof layer !== "undefined") {
734 if (typeof item[5] === "undefined") {
735 item[5] = layer;
736 } else {
737 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
738 item[5] = layer;
739 }
740 }
741 if (media) {
742 if (!item[2]) {
743 item[2] = media;
744 } else {
745 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
746 item[2] = media;
747 }
748 }
749 if (supports) {
750 if (!item[4]) {
751 item[4] = "".concat(supports);
752 } else {
753 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
754 item[4] = supports;
755 }
756 }
757 list.push(item);
758 }
759 };
760 return list;
761 };
762
763 /***/ },
764
765 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
766 /*!************************************************************!*\
767 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
768 \************************************************************/
769 (module) {
770
771 "use strict";
772
773
774 module.exports = function (item) {
775 var content = item[1];
776 var cssMapping = item[3];
777 if (!cssMapping) {
778 return content;
779 }
780 if (typeof btoa === "function") {
781 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
782 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
783 var sourceMapping = "/*# ".concat(data, " */");
784 return [content].concat([sourceMapping]).join("\n");
785 }
786 return [content].join("\n");
787 };
788
789 /***/ },
790
791 /***/ "./node_modules/sortablejs/modular/sortable.esm.js"
792 /*!*********************************************************!*\
793 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
794 \*********************************************************/
795 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
796
797 "use strict";
798 __webpack_require__.r(__webpack_exports__);
799 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
800 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
801 /* harmony export */ Sortable: () => (/* binding */ Sortable),
802 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
803 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
804 /* harmony export */ });
805 /**!
806 * Sortable 1.15.7
807 * @author RubaXa <trash@rubaxa.org>
808 * @author owenm <owen23355@gmail.com>
809 * @license MIT
810 */
811 function _arrayLikeToArray(r, a) {
812 (null == a || a > r.length) && (a = r.length);
813 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
814 return n;
815 }
816 function _arrayWithoutHoles(r) {
817 if (Array.isArray(r)) return _arrayLikeToArray(r);
818 }
819 function _defineProperty(e, r, t) {
820 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
821 value: t,
822 enumerable: !0,
823 configurable: !0,
824 writable: !0
825 }) : e[r] = t, e;
826 }
827 function _extends() {
828 return _extends = Object.assign ? Object.assign.bind() : function (n) {
829 for (var e = 1; e < arguments.length; e++) {
830 var t = arguments[e];
831 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
832 }
833 return n;
834 }, _extends.apply(null, arguments);
835 }
836 function _iterableToArray(r) {
837 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
838 }
839 function _nonIterableSpread() {
840 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
841 }
842 function ownKeys(e, r) {
843 var t = Object.keys(e);
844 if (Object.getOwnPropertySymbols) {
845 var o = Object.getOwnPropertySymbols(e);
846 r && (o = o.filter(function (r) {
847 return Object.getOwnPropertyDescriptor(e, r).enumerable;
848 })), t.push.apply(t, o);
849 }
850 return t;
851 }
852 function _objectSpread2(e) {
853 for (var r = 1; r < arguments.length; r++) {
854 var t = null != arguments[r] ? arguments[r] : {};
855 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
856 _defineProperty(e, r, t[r]);
857 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
858 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
859 });
860 }
861 return e;
862 }
863 function _objectWithoutProperties(e, t) {
864 if (null == e) return {};
865 var o,
866 r,
867 i = _objectWithoutPropertiesLoose(e, t);
868 if (Object.getOwnPropertySymbols) {
869 var n = Object.getOwnPropertySymbols(e);
870 for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
871 }
872 return i;
873 }
874 function _objectWithoutPropertiesLoose(r, e) {
875 if (null == r) return {};
876 var t = {};
877 for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
878 if (-1 !== e.indexOf(n)) continue;
879 t[n] = r[n];
880 }
881 return t;
882 }
883 function _toConsumableArray(r) {
884 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
885 }
886 function _toPrimitive(t, r) {
887 if ("object" != typeof t || !t) return t;
888 var e = t[Symbol.toPrimitive];
889 if (void 0 !== e) {
890 var i = e.call(t, r || "default");
891 if ("object" != typeof i) return i;
892 throw new TypeError("@@toPrimitive must return a primitive value.");
893 }
894 return ("string" === r ? String : Number)(t);
895 }
896 function _toPropertyKey(t) {
897 var i = _toPrimitive(t, "string");
898 return "symbol" == typeof i ? i : i + "";
899 }
900 function _typeof(o) {
901 "@babel/helpers - typeof";
902
903 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
904 return typeof o;
905 } : function (o) {
906 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
907 }, _typeof(o);
908 }
909 function _unsupportedIterableToArray(r, a) {
910 if (r) {
911 if ("string" == typeof r) return _arrayLikeToArray(r, a);
912 var t = {}.toString.call(r).slice(8, -1);
913 return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
914 }
915 }
916
917 var version = "1.15.7";
918
919 function userAgent(pattern) {
920 if (typeof window !== 'undefined' && window.navigator) {
921 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
922 }
923 }
924 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
925 var Edge = userAgent(/Edge/i);
926 var FireFox = userAgent(/firefox/i);
927 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
928 var IOS = userAgent(/iP(ad|od|hone)/i);
929 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
930
931 var captureMode = {
932 capture: false,
933 passive: false
934 };
935 function on(el, event, fn) {
936 el.addEventListener(event, fn, !IE11OrLess && captureMode);
937 }
938 function off(el, event, fn) {
939 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
940 }
941 function matches( /**HTMLElement*/el, /**String*/selector) {
942 if (!selector) return;
943 selector[0] === '>' && (selector = selector.substring(1));
944 if (el) {
945 try {
946 if (el.matches) {
947 return el.matches(selector);
948 } else if (el.msMatchesSelector) {
949 return el.msMatchesSelector(selector);
950 } else if (el.webkitMatchesSelector) {
951 return el.webkitMatchesSelector(selector);
952 }
953 } catch (_) {
954 return false;
955 }
956 }
957 return false;
958 }
959 function getParentOrHost(el) {
960 return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
961 }
962 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
963 if (el) {
964 ctx = ctx || document;
965 do {
966 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
967 return el;
968 }
969 if (el === ctx) break;
970 /* jshint boss:true */
971 } while (el = getParentOrHost(el));
972 }
973 return null;
974 }
975 var R_SPACE = /\s+/g;
976 function toggleClass(el, name, state) {
977 if (el && name) {
978 if (el.classList) {
979 el.classList[state ? 'add' : 'remove'](name);
980 } else {
981 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
982 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
983 }
984 }
985 }
986 function css(el, prop, val) {
987 var style = el && el.style;
988 if (style) {
989 if (val === void 0) {
990 if (document.defaultView && document.defaultView.getComputedStyle) {
991 val = document.defaultView.getComputedStyle(el, '');
992 } else if (el.currentStyle) {
993 val = el.currentStyle;
994 }
995 return prop === void 0 ? val : val[prop];
996 } else {
997 if (!(prop in style) && prop.indexOf('webkit') === -1) {
998 prop = '-webkit-' + prop;
999 }
1000 style[prop] = val + (typeof val === 'string' ? '' : 'px');
1001 }
1002 }
1003 }
1004 function matrix(el, selfOnly) {
1005 var appliedTransforms = '';
1006 if (typeof el === 'string') {
1007 appliedTransforms = el;
1008 } else {
1009 do {
1010 var transform = css(el, 'transform');
1011 if (transform && transform !== 'none') {
1012 appliedTransforms = transform + ' ' + appliedTransforms;
1013 }
1014 /* jshint boss:true */
1015 } while (!selfOnly && (el = el.parentNode));
1016 }
1017 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
1018 /*jshint -W056 */
1019 return matrixFn && new matrixFn(appliedTransforms);
1020 }
1021 function find(ctx, tagName, iterator) {
1022 if (ctx) {
1023 var list = ctx.getElementsByTagName(tagName),
1024 i = 0,
1025 n = list.length;
1026 if (iterator) {
1027 for (; i < n; i++) {
1028 iterator(list[i], i);
1029 }
1030 }
1031 return list;
1032 }
1033 return [];
1034 }
1035 function getWindowScrollingElement() {
1036 var scrollingElement = document.scrollingElement;
1037 if (scrollingElement) {
1038 return scrollingElement;
1039 } else {
1040 return document.documentElement;
1041 }
1042 }
1043
1044 /**
1045 * Returns the "bounding client rect" of given element
1046 * @param {HTMLElement} el The element whose boundingClientRect is wanted
1047 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
1048 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
1049 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
1050 * @param {[HTMLElement]} container The parent the element will be placed in
1051 * @return {Object} The boundingClientRect of el, with specified adjustments
1052 */
1053 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
1054 if (!el.getBoundingClientRect && el !== window) return;
1055 var elRect, top, left, bottom, right, height, width;
1056 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
1057 elRect = el.getBoundingClientRect();
1058 top = elRect.top;
1059 left = elRect.left;
1060 bottom = elRect.bottom;
1061 right = elRect.right;
1062 height = elRect.height;
1063 width = elRect.width;
1064 } else {
1065 top = 0;
1066 left = 0;
1067 bottom = window.innerHeight;
1068 right = window.innerWidth;
1069 height = window.innerHeight;
1070 width = window.innerWidth;
1071 }
1072 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
1073 // Adjust for translate()
1074 container = container || el.parentNode;
1075
1076 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
1077 // Not needed on <= IE11
1078 if (!IE11OrLess) {
1079 do {
1080 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
1081 var containerRect = container.getBoundingClientRect();
1082
1083 // Set relative to edges of padding box of container
1084 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
1085 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
1086 bottom = top + elRect.height;
1087 right = left + elRect.width;
1088 break;
1089 }
1090 /* jshint boss:true */
1091 } while (container = container.parentNode);
1092 }
1093 }
1094 if (undoScale && el !== window) {
1095 // Adjust for scale()
1096 var elMatrix = matrix(container || el),
1097 scaleX = elMatrix && elMatrix.a,
1098 scaleY = elMatrix && elMatrix.d;
1099 if (elMatrix) {
1100 top /= scaleY;
1101 left /= scaleX;
1102 width /= scaleX;
1103 height /= scaleY;
1104 bottom = top + height;
1105 right = left + width;
1106 }
1107 }
1108 return {
1109 top: top,
1110 left: left,
1111 bottom: bottom,
1112 right: right,
1113 width: width,
1114 height: height
1115 };
1116 }
1117
1118 /**
1119 * Checks if a side of an element is scrolled past a side of its parents
1120 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
1121 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
1122 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
1123 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
1124 */
1125 function isScrolledPast(el, elSide, parentSide) {
1126 var parent = getParentAutoScrollElement(el, true),
1127 elSideVal = getRect(el)[elSide];
1128
1129 /* jshint boss:true */
1130 while (parent) {
1131 var parentSideVal = getRect(parent)[parentSide],
1132 visible = void 0;
1133 if (parentSide === 'top' || parentSide === 'left') {
1134 visible = elSideVal >= parentSideVal;
1135 } else {
1136 visible = elSideVal <= parentSideVal;
1137 }
1138 if (!visible) return parent;
1139 if (parent === getWindowScrollingElement()) break;
1140 parent = getParentAutoScrollElement(parent, false);
1141 }
1142 return false;
1143 }
1144
1145 /**
1146 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
1147 * and non-draggable elements
1148 * @param {HTMLElement} el The parent element
1149 * @param {Number} childNum The index of the child
1150 * @param {Object} options Parent Sortable's options
1151 * @return {HTMLElement} The child at index childNum, or null if not found
1152 */
1153 function getChild(el, childNum, options, includeDragEl) {
1154 var currentChild = 0,
1155 i = 0,
1156 children = el.children;
1157 while (i < children.length) {
1158 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
1159 if (currentChild === childNum) {
1160 return children[i];
1161 }
1162 currentChild++;
1163 }
1164 i++;
1165 }
1166 return null;
1167 }
1168
1169 /**
1170 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
1171 * @param {HTMLElement} el Parent element
1172 * @param {selector} selector Any other elements that should be ignored
1173 * @return {HTMLElement} The last child, ignoring ghostEl
1174 */
1175 function lastChild(el, selector) {
1176 var last = el.lastElementChild;
1177 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
1178 last = last.previousElementSibling;
1179 }
1180 return last || null;
1181 }
1182
1183 /**
1184 * Returns the index of an element within its parent for a selected set of
1185 * elements
1186 * @param {HTMLElement} el
1187 * @param {selector} selector
1188 * @return {number}
1189 */
1190 function index(el, selector) {
1191 var index = 0;
1192 if (!el || !el.parentNode) {
1193 return -1;
1194 }
1195
1196 /* jshint boss:true */
1197 while (el = el.previousElementSibling) {
1198 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
1199 index++;
1200 }
1201 }
1202 return index;
1203 }
1204
1205 /**
1206 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
1207 * The value is returned in real pixels.
1208 * @param {HTMLElement} el
1209 * @return {Array} Offsets in the format of [left, top]
1210 */
1211 function getRelativeScrollOffset(el) {
1212 var offsetLeft = 0,
1213 offsetTop = 0,
1214 winScroller = getWindowScrollingElement();
1215 if (el) {
1216 do {
1217 var elMatrix = matrix(el),
1218 scaleX = elMatrix.a,
1219 scaleY = elMatrix.d;
1220 offsetLeft += el.scrollLeft * scaleX;
1221 offsetTop += el.scrollTop * scaleY;
1222 } while (el !== winScroller && (el = el.parentNode));
1223 }
1224 return [offsetLeft, offsetTop];
1225 }
1226
1227 /**
1228 * Returns the index of the object within the given array
1229 * @param {Array} arr Array that may or may not hold the object
1230 * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find
1231 * @return {Number} The index of the object in the array, or -1
1232 */
1233 function indexOfObject(arr, obj) {
1234 for (var i in arr) {
1235 if (!arr.hasOwnProperty(i)) continue;
1236 for (var key in obj) {
1237 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
1238 }
1239 }
1240 return -1;
1241 }
1242 function getParentAutoScrollElement(el, includeSelf) {
1243 // skip to window
1244 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
1245 var elem = el;
1246 var gotSelf = false;
1247 do {
1248 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
1249 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
1250 var elemCSS = css(elem);
1251 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
1252 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
1253 if (gotSelf || includeSelf) return elem;
1254 gotSelf = true;
1255 }
1256 }
1257 /* jshint boss:true */
1258 } while (elem = elem.parentNode);
1259 return getWindowScrollingElement();
1260 }
1261 function extend(dst, src) {
1262 if (dst && src) {
1263 for (var key in src) {
1264 if (src.hasOwnProperty(key)) {
1265 dst[key] = src[key];
1266 }
1267 }
1268 }
1269 return dst;
1270 }
1271 function isRectEqual(rect1, rect2) {
1272 return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width);
1273 }
1274 var _throttleTimeout;
1275 function throttle(callback, ms) {
1276 return function () {
1277 if (!_throttleTimeout) {
1278 var args = arguments,
1279 _this = this;
1280 if (args.length === 1) {
1281 callback.call(_this, args[0]);
1282 } else {
1283 callback.apply(_this, args);
1284 }
1285 _throttleTimeout = setTimeout(function () {
1286 _throttleTimeout = void 0;
1287 }, ms);
1288 }
1289 };
1290 }
1291 function cancelThrottle() {
1292 clearTimeout(_throttleTimeout);
1293 _throttleTimeout = void 0;
1294 }
1295 function scrollBy(el, x, y) {
1296 el.scrollLeft += x;
1297 el.scrollTop += y;
1298 }
1299 function clone(el) {
1300 var Polymer = window.Polymer;
1301 var $ = window.jQuery || window.Zepto;
1302 if (Polymer && Polymer.dom) {
1303 return Polymer.dom(el).cloneNode(true);
1304 } else if ($) {
1305 return $(el).clone(true)[0];
1306 } else {
1307 return el.cloneNode(true);
1308 }
1309 }
1310 function setRect(el, rect) {
1311 css(el, 'position', 'absolute');
1312 css(el, 'top', rect.top);
1313 css(el, 'left', rect.left);
1314 css(el, 'width', rect.width);
1315 css(el, 'height', rect.height);
1316 }
1317 function unsetRect(el) {
1318 css(el, 'position', '');
1319 css(el, 'top', '');
1320 css(el, 'left', '');
1321 css(el, 'width', '');
1322 css(el, 'height', '');
1323 }
1324 function getChildContainingRectFromElement(container, options, ghostEl) {
1325 var rect = {};
1326 Array.from(container.children).forEach(function (child) {
1327 var _rect$left, _rect$top, _rect$right, _rect$bottom;
1328 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
1329 var childRect = getRect(child);
1330 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
1331 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
1332 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
1333 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
1334 });
1335 rect.width = rect.right - rect.left;
1336 rect.height = rect.bottom - rect.top;
1337 rect.x = rect.left;
1338 rect.y = rect.top;
1339 return rect;
1340 }
1341 var expando = 'Sortable' + new Date().getTime();
1342
1343 function AnimationStateManager() {
1344 var animationStates = [],
1345 animationCallbackId;
1346 return {
1347 captureAnimationState: function captureAnimationState() {
1348 animationStates = [];
1349 if (!this.options.animation) return;
1350 var children = [].slice.call(this.el.children);
1351 children.forEach(function (child) {
1352 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
1353 animationStates.push({
1354 target: child,
1355 rect: getRect(child)
1356 });
1357 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
1358
1359 // If animating: compensate for current animation
1360 if (child.thisAnimationDuration) {
1361 var childMatrix = matrix(child, true);
1362 if (childMatrix) {
1363 fromRect.top -= childMatrix.f;
1364 fromRect.left -= childMatrix.e;
1365 }
1366 }
1367 child.fromRect = fromRect;
1368 });
1369 },
1370 addAnimationState: function addAnimationState(state) {
1371 animationStates.push(state);
1372 },
1373 removeAnimationState: function removeAnimationState(target) {
1374 animationStates.splice(indexOfObject(animationStates, {
1375 target: target
1376 }), 1);
1377 },
1378 animateAll: function animateAll(callback) {
1379 var _this = this;
1380 if (!this.options.animation) {
1381 clearTimeout(animationCallbackId);
1382 if (typeof callback === 'function') callback();
1383 return;
1384 }
1385 var animating = false,
1386 animationTime = 0;
1387 animationStates.forEach(function (state) {
1388 var time = 0,
1389 target = state.target,
1390 fromRect = target.fromRect,
1391 toRect = getRect(target),
1392 prevFromRect = target.prevFromRect,
1393 prevToRect = target.prevToRect,
1394 animatingRect = state.rect,
1395 targetMatrix = matrix(target, true);
1396 if (targetMatrix) {
1397 // Compensate for current animation
1398 toRect.top -= targetMatrix.f;
1399 toRect.left -= targetMatrix.e;
1400 }
1401 target.toRect = toRect;
1402 if (target.thisAnimationDuration) {
1403 // Could also check if animatingRect is between fromRect and toRect
1404 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
1405 // Make sure animatingRect is on line between toRect & fromRect
1406 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
1407 // If returning to same place as started from animation and on same axis
1408 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
1409 }
1410 }
1411
1412 // if fromRect != toRect: animate
1413 if (!isRectEqual(toRect, fromRect)) {
1414 target.prevFromRect = fromRect;
1415 target.prevToRect = toRect;
1416 if (!time) {
1417 time = _this.options.animation;
1418 }
1419 _this.animate(target, animatingRect, toRect, time);
1420 }
1421 if (time) {
1422 animating = true;
1423 animationTime = Math.max(animationTime, time);
1424 clearTimeout(target.animationResetTimer);
1425 target.animationResetTimer = setTimeout(function () {
1426 target.animationTime = 0;
1427 target.prevFromRect = null;
1428 target.fromRect = null;
1429 target.prevToRect = null;
1430 target.thisAnimationDuration = null;
1431 }, time);
1432 target.thisAnimationDuration = time;
1433 }
1434 });
1435 clearTimeout(animationCallbackId);
1436 if (!animating) {
1437 if (typeof callback === 'function') callback();
1438 } else {
1439 animationCallbackId = setTimeout(function () {
1440 if (typeof callback === 'function') callback();
1441 }, animationTime);
1442 }
1443 animationStates = [];
1444 },
1445 animate: function animate(target, currentRect, toRect, duration) {
1446 if (duration) {
1447 css(target, 'transition', '');
1448 css(target, 'transform', '');
1449 var elMatrix = matrix(this.el),
1450 scaleX = elMatrix && elMatrix.a,
1451 scaleY = elMatrix && elMatrix.d,
1452 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
1453 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
1454 target.animatingX = !!translateX;
1455 target.animatingY = !!translateY;
1456 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
1457 this.forRepaintDummy = repaint(target); // repaint
1458
1459 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
1460 css(target, 'transform', 'translate3d(0,0,0)');
1461 typeof target.animated === 'number' && clearTimeout(target.animated);
1462 target.animated = setTimeout(function () {
1463 css(target, 'transition', '');
1464 css(target, 'transform', '');
1465 target.animated = false;
1466 target.animatingX = false;
1467 target.animatingY = false;
1468 }, duration);
1469 }
1470 }
1471 };
1472 }
1473 function repaint(target) {
1474 return target.offsetWidth;
1475 }
1476 function calculateRealTime(animatingRect, fromRect, toRect, options) {
1477 return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation;
1478 }
1479
1480 var plugins = [];
1481 var defaults = {
1482 initializeByDefault: true
1483 };
1484 var PluginManager = {
1485 mount: function mount(plugin) {
1486 // Set default static properties
1487 for (var option in defaults) {
1488 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
1489 plugin[option] = defaults[option];
1490 }
1491 }
1492 plugins.forEach(function (p) {
1493 if (p.pluginName === plugin.pluginName) {
1494 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
1495 }
1496 });
1497 plugins.push(plugin);
1498 },
1499 pluginEvent: function pluginEvent(eventName, sortable, evt) {
1500 var _this = this;
1501 this.eventCanceled = false;
1502 evt.cancel = function () {
1503 _this.eventCanceled = true;
1504 };
1505 var eventNameGlobal = eventName + 'Global';
1506 plugins.forEach(function (plugin) {
1507 if (!sortable[plugin.pluginName]) return;
1508 // Fire global events if it exists in this sortable
1509 if (sortable[plugin.pluginName][eventNameGlobal]) {
1510 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
1511 sortable: sortable
1512 }, evt));
1513 }
1514
1515 // Only fire plugin event if plugin is enabled in this sortable,
1516 // and plugin has event defined
1517 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
1518 sortable[plugin.pluginName][eventName](_objectSpread2({
1519 sortable: sortable
1520 }, evt));
1521 }
1522 });
1523 },
1524 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
1525 plugins.forEach(function (plugin) {
1526 var pluginName = plugin.pluginName;
1527 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
1528 var initialized = new plugin(sortable, el, sortable.options);
1529 initialized.sortable = sortable;
1530 initialized.options = sortable.options;
1531 sortable[pluginName] = initialized;
1532
1533 // Add default options from plugin
1534 _extends(defaults, initialized.defaults);
1535 });
1536 for (var option in sortable.options) {
1537 if (!sortable.options.hasOwnProperty(option)) continue;
1538 var modified = this.modifyOption(sortable, option, sortable.options[option]);
1539 if (typeof modified !== 'undefined') {
1540 sortable.options[option] = modified;
1541 }
1542 }
1543 },
1544 getEventProperties: function getEventProperties(name, sortable) {
1545 var eventProperties = {};
1546 plugins.forEach(function (plugin) {
1547 if (typeof plugin.eventProperties !== 'function') return;
1548 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
1549 });
1550 return eventProperties;
1551 },
1552 modifyOption: function modifyOption(sortable, name, value) {
1553 var modifiedValue;
1554 plugins.forEach(function (plugin) {
1555 // Plugin must exist on the Sortable
1556 if (!sortable[plugin.pluginName]) return;
1557
1558 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
1559 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
1560 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
1561 }
1562 });
1563 return modifiedValue;
1564 }
1565 };
1566
1567 function dispatchEvent(_ref) {
1568 var sortable = _ref.sortable,
1569 rootEl = _ref.rootEl,
1570 name = _ref.name,
1571 targetEl = _ref.targetEl,
1572 cloneEl = _ref.cloneEl,
1573 toEl = _ref.toEl,
1574 fromEl = _ref.fromEl,
1575 oldIndex = _ref.oldIndex,
1576 newIndex = _ref.newIndex,
1577 oldDraggableIndex = _ref.oldDraggableIndex,
1578 newDraggableIndex = _ref.newDraggableIndex,
1579 originalEvent = _ref.originalEvent,
1580 putSortable = _ref.putSortable,
1581 extraEventProperties = _ref.extraEventProperties;
1582 sortable = sortable || rootEl && rootEl[expando];
1583 if (!sortable) return;
1584 var evt,
1585 options = sortable.options,
1586 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
1587 // Support for new CustomEvent feature
1588 if (window.CustomEvent && !IE11OrLess && !Edge) {
1589 evt = new CustomEvent(name, {
1590 bubbles: true,
1591 cancelable: true
1592 });
1593 } else {
1594 evt = document.createEvent('Event');
1595 evt.initEvent(name, true, true);
1596 }
1597 evt.to = toEl || rootEl;
1598 evt.from = fromEl || rootEl;
1599 evt.item = targetEl || rootEl;
1600 evt.clone = cloneEl;
1601 evt.oldIndex = oldIndex;
1602 evt.newIndex = newIndex;
1603 evt.oldDraggableIndex = oldDraggableIndex;
1604 evt.newDraggableIndex = newDraggableIndex;
1605 evt.originalEvent = originalEvent;
1606 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
1607 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
1608 for (var option in allEventProperties) {
1609 evt[option] = allEventProperties[option];
1610 }
1611 if (rootEl) {
1612 rootEl.dispatchEvent(evt);
1613 }
1614 if (options[onName]) {
1615 options[onName].call(sortable, evt);
1616 }
1617 }
1618
1619 var _excluded = ["evt"];
1620 var pluginEvent = function pluginEvent(eventName, sortable) {
1621 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
1622 originalEvent = _ref.evt,
1623 data = _objectWithoutProperties(_ref, _excluded);
1624 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
1625 dragEl: dragEl,
1626 parentEl: parentEl,
1627 ghostEl: ghostEl,
1628 rootEl: rootEl,
1629 nextEl: nextEl,
1630 lastDownEl: lastDownEl,
1631 cloneEl: cloneEl,
1632 cloneHidden: cloneHidden,
1633 dragStarted: moved,
1634 putSortable: putSortable,
1635 activeSortable: Sortable.active,
1636 originalEvent: originalEvent,
1637 oldIndex: oldIndex,
1638 oldDraggableIndex: oldDraggableIndex,
1639 newIndex: newIndex,
1640 newDraggableIndex: newDraggableIndex,
1641 hideGhostForTarget: _hideGhostForTarget,
1642 unhideGhostForTarget: _unhideGhostForTarget,
1643 cloneNowHidden: function cloneNowHidden() {
1644 cloneHidden = true;
1645 },
1646 cloneNowShown: function cloneNowShown() {
1647 cloneHidden = false;
1648 },
1649 dispatchSortableEvent: function dispatchSortableEvent(name) {
1650 _dispatchEvent({
1651 sortable: sortable,
1652 name: name,
1653 originalEvent: originalEvent
1654 });
1655 }
1656 }, data));
1657 };
1658 function _dispatchEvent(info) {
1659 dispatchEvent(_objectSpread2({
1660 putSortable: putSortable,
1661 cloneEl: cloneEl,
1662 targetEl: dragEl,
1663 rootEl: rootEl,
1664 oldIndex: oldIndex,
1665 oldDraggableIndex: oldDraggableIndex,
1666 newIndex: newIndex,
1667 newDraggableIndex: newDraggableIndex
1668 }, info));
1669 }
1670 var dragEl,
1671 parentEl,
1672 ghostEl,
1673 rootEl,
1674 nextEl,
1675 lastDownEl,
1676 cloneEl,
1677 cloneHidden,
1678 oldIndex,
1679 newIndex,
1680 oldDraggableIndex,
1681 newDraggableIndex,
1682 activeGroup,
1683 putSortable,
1684 awaitingDragStarted = false,
1685 ignoreNextClick = false,
1686 sortables = [],
1687 tapEvt,
1688 touchEvt,
1689 lastDx,
1690 lastDy,
1691 tapDistanceLeft,
1692 tapDistanceTop,
1693 moved,
1694 lastTarget,
1695 lastDirection,
1696 pastFirstInvertThresh = false,
1697 isCircumstantialInvert = false,
1698 targetMoveDistance,
1699 // For positioning ghost absolutely
1700 ghostRelativeParent,
1701 ghostRelativeParentInitialScroll = [],
1702 // (left, top)
1703
1704 _silent = false,
1705 savedInputChecked = [];
1706
1707 /** @const */
1708 var documentExists = typeof document !== 'undefined',
1709 PositionGhostAbsolutely = IOS,
1710 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
1711 // This will not pass for IE9, because IE9 DnD only works on anchors
1712 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
1713 supportCssPointerEvents = function () {
1714 if (!documentExists) return;
1715 // false when <= IE11
1716 if (IE11OrLess) {
1717 return false;
1718 }
1719 var el = document.createElement('x');
1720 el.style.cssText = 'pointer-events:auto';
1721 return el.style.pointerEvents === 'auto';
1722 }(),
1723 _detectDirection = function _detectDirection(el, options) {
1724 var elCSS = css(el),
1725 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
1726 child1 = getChild(el, 0, options),
1727 child2 = getChild(el, 1, options),
1728 firstChildCSS = child1 && css(child1),
1729 secondChildCSS = child2 && css(child2),
1730 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
1731 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
1732 if (elCSS.display === 'flex') {
1733 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
1734 }
1735 if (elCSS.display === 'grid') {
1736 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
1737 }
1738 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
1739 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
1740 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
1741 }
1742 return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal';
1743 },
1744 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
1745 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
1746 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
1747 dragElOppLength = vertical ? dragRect.width : dragRect.height,
1748 targetS1Opp = vertical ? targetRect.left : targetRect.top,
1749 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
1750 targetOppLength = vertical ? targetRect.width : targetRect.height;
1751 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
1752 },
1753 /**
1754 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
1755 * @param {Number} x X position
1756 * @param {Number} y Y position
1757 * @return {HTMLElement} Element of the first found nearest Sortable
1758 */
1759 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
1760 var ret;
1761 sortables.some(function (sortable) {
1762 var threshold = sortable[expando].options.emptyInsertThreshold;
1763 if (!threshold || lastChild(sortable)) return;
1764 var rect = getRect(sortable),
1765 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
1766 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
1767 if (insideHorizontally && insideVertically) {
1768 return ret = sortable;
1769 }
1770 });
1771 return ret;
1772 },
1773 _prepareGroup = function _prepareGroup(options) {
1774 function toFn(value, pull) {
1775 return function (to, from, dragEl, evt) {
1776 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
1777 if (value == null && (pull || sameGroup)) {
1778 // Default pull value
1779 // Default pull and put value if same group
1780 return true;
1781 } else if (value == null || value === false) {
1782 return false;
1783 } else if (pull && value === 'clone') {
1784 return value;
1785 } else if (typeof value === 'function') {
1786 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
1787 } else {
1788 var otherGroup = (pull ? to : from).options.group.name;
1789 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
1790 }
1791 };
1792 }
1793 var group = {};
1794 var originalGroup = options.group;
1795 if (!originalGroup || _typeof(originalGroup) != 'object') {
1796 originalGroup = {
1797 name: originalGroup
1798 };
1799 }
1800 group.name = originalGroup.name;
1801 group.checkPull = toFn(originalGroup.pull, true);
1802 group.checkPut = toFn(originalGroup.put);
1803 group.revertClone = originalGroup.revertClone;
1804 options.group = group;
1805 },
1806 _hideGhostForTarget = function _hideGhostForTarget() {
1807 if (!supportCssPointerEvents && ghostEl) {
1808 css(ghostEl, 'display', 'none');
1809 }
1810 },
1811 _unhideGhostForTarget = function _unhideGhostForTarget() {
1812 if (!supportCssPointerEvents && ghostEl) {
1813 css(ghostEl, 'display', '');
1814 }
1815 };
1816
1817 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
1818 if (documentExists && !ChromeForAndroid) {
1819 document.addEventListener('click', function (evt) {
1820 if (ignoreNextClick) {
1821 evt.preventDefault();
1822 evt.stopPropagation && evt.stopPropagation();
1823 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
1824 ignoreNextClick = false;
1825 return false;
1826 }
1827 }, true);
1828 }
1829 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
1830 if (dragEl) {
1831 evt = evt.touches ? evt.touches[0] : evt;
1832 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
1833 if (nearest) {
1834 // Create imitation event
1835 var event = {};
1836 for (var i in evt) {
1837 if (evt.hasOwnProperty(i)) {
1838 event[i] = evt[i];
1839 }
1840 }
1841 event.target = event.rootEl = nearest;
1842 event.preventDefault = void 0;
1843 event.stopPropagation = void 0;
1844 nearest[expando]._onDragOver(event);
1845 }
1846 }
1847 };
1848 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
1849 if (dragEl) {
1850 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
1851 }
1852 };
1853
1854 /**
1855 * @class Sortable
1856 * @param {HTMLElement} el
1857 * @param {Object} [options]
1858 */
1859 function Sortable(el, options) {
1860 if (!(el && el.nodeType && el.nodeType === 1)) {
1861 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
1862 }
1863 this.el = el; // root element
1864 this.options = options = _extends({}, options);
1865
1866 // Export instance
1867 el[expando] = this;
1868 var defaults = {
1869 group: null,
1870 sort: true,
1871 disabled: false,
1872 store: null,
1873 handle: null,
1874 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
1875 swapThreshold: 1,
1876 // percentage; 0 <= x <= 1
1877 invertSwap: false,
1878 // invert always
1879 invertedSwapThreshold: null,
1880 // will be set to same as swapThreshold if default
1881 removeCloneOnHide: true,
1882 direction: function direction() {
1883 return _detectDirection(el, this.options);
1884 },
1885 ghostClass: 'sortable-ghost',
1886 chosenClass: 'sortable-chosen',
1887 dragClass: 'sortable-drag',
1888 ignore: 'a, img',
1889 filter: null,
1890 preventOnFilter: true,
1891 animation: 0,
1892 easing: null,
1893 setData: function setData(dataTransfer, dragEl) {
1894 dataTransfer.setData('Text', dragEl.textContent);
1895 },
1896 dropBubble: false,
1897 dragoverBubble: false,
1898 dataIdAttr: 'data-id',
1899 delay: 0,
1900 delayOnTouchOnly: false,
1901 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
1902 forceFallback: false,
1903 fallbackClass: 'sortable-fallback',
1904 fallbackOnBody: false,
1905 fallbackTolerance: 0,
1906 fallbackOffset: {
1907 x: 0,
1908 y: 0
1909 },
1910 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
1911 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
1912 emptyInsertThreshold: 5
1913 };
1914 PluginManager.initializePlugins(this, el, defaults);
1915
1916 // Set default options
1917 for (var name in defaults) {
1918 !(name in options) && (options[name] = defaults[name]);
1919 }
1920 _prepareGroup(options);
1921
1922 // Bind all private methods
1923 for (var fn in this) {
1924 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
1925 this[fn] = this[fn].bind(this);
1926 }
1927 }
1928
1929 // Setup drag mode
1930 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
1931 if (this.nativeDraggable) {
1932 // Touch start threshold cannot be greater than the native dragstart threshold
1933 this.options.touchStartThreshold = 1;
1934 }
1935
1936 // Bind events
1937 if (options.supportPointer) {
1938 on(el, 'pointerdown', this._onTapStart);
1939 } else {
1940 on(el, 'mousedown', this._onTapStart);
1941 on(el, 'touchstart', this._onTapStart);
1942 }
1943 if (this.nativeDraggable) {
1944 on(el, 'dragover', this);
1945 on(el, 'dragenter', this);
1946 }
1947 sortables.push(this.el);
1948
1949 // Restore sorting
1950 options.store && options.store.get && this.sort(options.store.get(this) || []);
1951
1952 // Add animation state manager
1953 _extends(this, AnimationStateManager());
1954 }
1955 Sortable.prototype = /** @lends Sortable.prototype */{
1956 constructor: Sortable,
1957 _isOutsideThisEl: function _isOutsideThisEl(target) {
1958 if (!this.el.contains(target) && target !== this.el) {
1959 lastTarget = null;
1960 }
1961 },
1962 _getDirection: function _getDirection(evt, target) {
1963 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
1964 },
1965 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
1966 if (!evt.cancelable) return;
1967 var _this = this,
1968 el = this.el,
1969 options = this.options,
1970 preventOnFilter = options.preventOnFilter,
1971 type = evt.type,
1972 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
1973 target = (touch || evt).target,
1974 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
1975 filter = options.filter;
1976 _saveInputCheckedState(el);
1977
1978 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
1979 if (dragEl) {
1980 return;
1981 }
1982 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
1983 return; // only left button and enabled
1984 }
1985
1986 // cancel dnd if original target is content editable
1987 if (originalTarget.isContentEditable) {
1988 return;
1989 }
1990
1991 // Safari ignores further event handling after mousedown
1992 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
1993 return;
1994 }
1995 target = closest(target, options.draggable, el, false);
1996 if (target && target.animated) {
1997 return;
1998 }
1999 if (lastDownEl === target) {
2000 // Ignoring duplicate `down`
2001 return;
2002 }
2003
2004 // Get the index of the dragged element within its parent
2005 oldIndex = index(target);
2006 oldDraggableIndex = index(target, options.draggable);
2007
2008 // Check filter
2009 if (typeof filter === 'function') {
2010 if (filter.call(this, evt, target, this)) {
2011 _dispatchEvent({
2012 sortable: _this,
2013 rootEl: originalTarget,
2014 name: 'filter',
2015 targetEl: target,
2016 toEl: el,
2017 fromEl: el
2018 });
2019 pluginEvent('filter', _this, {
2020 evt: evt
2021 });
2022 preventOnFilter && evt.preventDefault();
2023 return; // cancel dnd
2024 }
2025 } else if (filter) {
2026 filter = filter.split(',').some(function (criteria) {
2027 criteria = closest(originalTarget, criteria.trim(), el, false);
2028 if (criteria) {
2029 _dispatchEvent({
2030 sortable: _this,
2031 rootEl: criteria,
2032 name: 'filter',
2033 targetEl: target,
2034 fromEl: el,
2035 toEl: el
2036 });
2037 pluginEvent('filter', _this, {
2038 evt: evt
2039 });
2040 return true;
2041 }
2042 });
2043 if (filter) {
2044 preventOnFilter && evt.preventDefault();
2045 return; // cancel dnd
2046 }
2047 }
2048 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
2049 return;
2050 }
2051
2052 // Prepare `dragstart`
2053 this._prepareDragStart(evt, touch, target);
2054 },
2055 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
2056 var _this = this,
2057 el = _this.el,
2058 options = _this.options,
2059 ownerDocument = el.ownerDocument,
2060 dragStartFn;
2061 if (target && !dragEl && target.parentNode === el) {
2062 var dragRect = getRect(target);
2063 rootEl = el;
2064 dragEl = target;
2065 parentEl = dragEl.parentNode;
2066 nextEl = dragEl.nextSibling;
2067 lastDownEl = target;
2068 activeGroup = options.group;
2069 Sortable.dragged = dragEl;
2070 tapEvt = {
2071 target: dragEl,
2072 clientX: (touch || evt).clientX,
2073 clientY: (touch || evt).clientY
2074 };
2075 tapDistanceLeft = tapEvt.clientX - dragRect.left;
2076 tapDistanceTop = tapEvt.clientY - dragRect.top;
2077 this._lastX = (touch || evt).clientX;
2078 this._lastY = (touch || evt).clientY;
2079 dragEl.style['will-change'] = 'all';
2080 dragStartFn = function dragStartFn() {
2081 pluginEvent('delayEnded', _this, {
2082 evt: evt
2083 });
2084 if (Sortable.eventCanceled) {
2085 _this._onDrop();
2086 return;
2087 }
2088 // Delayed drag has been triggered
2089 // we can re-enable the events: touchmove/mousemove
2090 _this._disableDelayedDragEvents();
2091 if (!FireFox && _this.nativeDraggable) {
2092 dragEl.draggable = true;
2093 }
2094
2095 // Bind the events: dragstart/dragend
2096 _this._triggerDragStart(evt, touch);
2097
2098 // Drag start event
2099 _dispatchEvent({
2100 sortable: _this,
2101 name: 'choose',
2102 originalEvent: evt
2103 });
2104
2105 // Chosen item
2106 toggleClass(dragEl, options.chosenClass, true);
2107 };
2108
2109 // Disable "draggable"
2110 options.ignore.split(',').forEach(function (criteria) {
2111 find(dragEl, criteria.trim(), _disableDraggable);
2112 });
2113 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
2114 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
2115 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
2116 if (options.supportPointer) {
2117 on(ownerDocument, 'pointerup', _this._onDrop);
2118 // Native D&D triggers pointercancel
2119 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
2120 } else {
2121 on(ownerDocument, 'mouseup', _this._onDrop);
2122 on(ownerDocument, 'touchend', _this._onDrop);
2123 on(ownerDocument, 'touchcancel', _this._onDrop);
2124 }
2125
2126 // Make dragEl draggable (must be before delay for FireFox)
2127 if (FireFox && this.nativeDraggable) {
2128 this.options.touchStartThreshold = 4;
2129 dragEl.draggable = true;
2130 }
2131 pluginEvent('delayStart', this, {
2132 evt: evt
2133 });
2134
2135 // Delay is impossible for native DnD in Edge or IE
2136 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
2137 if (Sortable.eventCanceled) {
2138 this._onDrop();
2139 return;
2140 }
2141 // If the user moves the pointer or let go the click or touch
2142 // before the delay has been reached:
2143 // disable the delayed drag
2144 if (options.supportPointer) {
2145 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
2146 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
2147 } else {
2148 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
2149 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
2150 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
2151 }
2152 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
2153 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
2154 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
2155 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
2156 } else {
2157 dragStartFn();
2158 }
2159 }
2160 },
2161 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
2162 var touch = e.touches ? e.touches[0] : e;
2163 if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) {
2164 this._disableDelayedDrag();
2165 }
2166 },
2167 _disableDelayedDrag: function _disableDelayedDrag() {
2168 dragEl && _disableDraggable(dragEl);
2169 clearTimeout(this._dragStartTimer);
2170 this._disableDelayedDragEvents();
2171 },
2172 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
2173 var ownerDocument = this.el.ownerDocument;
2174 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
2175 off(ownerDocument, 'touchend', this._disableDelayedDrag);
2176 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
2177 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
2178 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
2179 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
2180 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
2181 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
2182 },
2183 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
2184 touch = touch || evt.pointerType == 'touch' && evt;
2185 if (!this.nativeDraggable || touch) {
2186 if (this.options.supportPointer) {
2187 on(document, 'pointermove', this._onTouchMove);
2188 } else if (touch) {
2189 on(document, 'touchmove', this._onTouchMove);
2190 } else {
2191 on(document, 'mousemove', this._onTouchMove);
2192 }
2193 } else {
2194 on(dragEl, 'dragend', this);
2195 on(rootEl, 'dragstart', this._onDragStart);
2196 }
2197 try {
2198 if (document.selection) {
2199 _nextTick(function () {
2200 document.selection.empty();
2201 });
2202 } else {
2203 window.getSelection().removeAllRanges();
2204 }
2205 } catch (err) {}
2206 },
2207 _dragStarted: function _dragStarted(fallback, evt) {
2208 awaitingDragStarted = false;
2209 if (rootEl && dragEl) {
2210 pluginEvent('dragStarted', this, {
2211 evt: evt
2212 });
2213 if (this.nativeDraggable) {
2214 on(document, 'dragover', _checkOutsideTargetEl);
2215 }
2216 var options = this.options;
2217
2218 // Apply effect
2219 !fallback && toggleClass(dragEl, options.dragClass, false);
2220 toggleClass(dragEl, options.ghostClass, true);
2221 Sortable.active = this;
2222 fallback && this._appendGhost();
2223
2224 // Drag start event
2225 _dispatchEvent({
2226 sortable: this,
2227 name: 'start',
2228 originalEvent: evt
2229 });
2230 } else {
2231 this._nulling();
2232 }
2233 },
2234 _emulateDragOver: function _emulateDragOver() {
2235 if (touchEvt) {
2236 this._lastX = touchEvt.clientX;
2237 this._lastY = touchEvt.clientY;
2238 _hideGhostForTarget();
2239 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
2240 var parent = target;
2241 while (target && target.shadowRoot) {
2242 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
2243 if (target === parent) break;
2244 parent = target;
2245 }
2246 dragEl.parentNode[expando]._isOutsideThisEl(target);
2247 if (parent) {
2248 do {
2249 if (parent[expando]) {
2250 var inserted = void 0;
2251 inserted = parent[expando]._onDragOver({
2252 clientX: touchEvt.clientX,
2253 clientY: touchEvt.clientY,
2254 target: target,
2255 rootEl: parent
2256 });
2257 if (inserted && !this.options.dragoverBubble) {
2258 break;
2259 }
2260 }
2261 target = parent; // store last element
2262 }
2263 /* jshint boss:true */ while (parent = getParentOrHost(parent));
2264 }
2265 _unhideGhostForTarget();
2266 }
2267 },
2268 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
2269 if (tapEvt) {
2270 var options = this.options,
2271 fallbackTolerance = options.fallbackTolerance,
2272 fallbackOffset = options.fallbackOffset,
2273 touch = evt.touches ? evt.touches[0] : evt,
2274 ghostMatrix = ghostEl && matrix(ghostEl, true),
2275 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
2276 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
2277 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
2278 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
2279 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
2280
2281 // only set the status to dragging, when we are actually dragging
2282 if (!Sortable.active && !awaitingDragStarted) {
2283 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
2284 return;
2285 }
2286 this._onDragStart(evt, true);
2287 }
2288 if (ghostEl) {
2289 if (ghostMatrix) {
2290 ghostMatrix.e += dx - (lastDx || 0);
2291 ghostMatrix.f += dy - (lastDy || 0);
2292 } else {
2293 ghostMatrix = {
2294 a: 1,
2295 b: 0,
2296 c: 0,
2297 d: 1,
2298 e: dx,
2299 f: dy
2300 };
2301 }
2302 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
2303 css(ghostEl, 'webkitTransform', cssMatrix);
2304 css(ghostEl, 'mozTransform', cssMatrix);
2305 css(ghostEl, 'msTransform', cssMatrix);
2306 css(ghostEl, 'transform', cssMatrix);
2307 lastDx = dx;
2308 lastDy = dy;
2309 touchEvt = touch;
2310 }
2311 evt.cancelable && evt.preventDefault();
2312 }
2313 },
2314 _appendGhost: function _appendGhost() {
2315 // Bug if using scale(): https://stackoverflow.com/questions/2637058
2316 // Not being adjusted for
2317 if (!ghostEl) {
2318 var container = this.options.fallbackOnBody ? document.body : rootEl,
2319 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
2320 options = this.options;
2321
2322 // Position absolutely
2323 if (PositionGhostAbsolutely) {
2324 // Get relatively positioned parent
2325 ghostRelativeParent = container;
2326 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
2327 ghostRelativeParent = ghostRelativeParent.parentNode;
2328 }
2329 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
2330 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
2331 rect.top += ghostRelativeParent.scrollTop;
2332 rect.left += ghostRelativeParent.scrollLeft;
2333 } else {
2334 ghostRelativeParent = getWindowScrollingElement();
2335 }
2336 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
2337 }
2338 ghostEl = dragEl.cloneNode(true);
2339 toggleClass(ghostEl, options.ghostClass, false);
2340 toggleClass(ghostEl, options.fallbackClass, true);
2341 toggleClass(ghostEl, options.dragClass, true);
2342 css(ghostEl, 'transition', '');
2343 css(ghostEl, 'transform', '');
2344 css(ghostEl, 'box-sizing', 'border-box');
2345 css(ghostEl, 'margin', 0);
2346 css(ghostEl, 'top', rect.top);
2347 css(ghostEl, 'left', rect.left);
2348 css(ghostEl, 'width', rect.width);
2349 css(ghostEl, 'height', rect.height);
2350 css(ghostEl, 'opacity', '0.8');
2351 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
2352 css(ghostEl, 'zIndex', '100000');
2353 css(ghostEl, 'pointerEvents', 'none');
2354 Sortable.ghost = ghostEl;
2355 container.appendChild(ghostEl);
2356
2357 // Set transform-origin
2358 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
2359 }
2360 },
2361 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
2362 var _this = this;
2363 var dataTransfer = evt.dataTransfer;
2364 var options = _this.options;
2365 pluginEvent('dragStart', this, {
2366 evt: evt
2367 });
2368 if (Sortable.eventCanceled) {
2369 this._onDrop();
2370 return;
2371 }
2372 pluginEvent('setupClone', this);
2373 if (!Sortable.eventCanceled) {
2374 cloneEl = clone(dragEl);
2375 cloneEl.removeAttribute("id");
2376 cloneEl.draggable = false;
2377 cloneEl.style['will-change'] = '';
2378 this._hideClone();
2379 toggleClass(cloneEl, this.options.chosenClass, false);
2380 Sortable.clone = cloneEl;
2381 }
2382
2383 // #1143: IFrame support workaround
2384 _this.cloneId = _nextTick(function () {
2385 pluginEvent('clone', _this);
2386 if (Sortable.eventCanceled) return;
2387 if (!_this.options.removeCloneOnHide) {
2388 rootEl.insertBefore(cloneEl, dragEl);
2389 }
2390 _this._hideClone();
2391 _dispatchEvent({
2392 sortable: _this,
2393 name: 'clone'
2394 });
2395 });
2396 !fallback && toggleClass(dragEl, options.dragClass, true);
2397
2398 // Set proper drop events
2399 if (fallback) {
2400 ignoreNextClick = true;
2401 _this._loopId = setInterval(_this._emulateDragOver, 50);
2402 } else {
2403 // Undo what was set in _prepareDragStart before drag started
2404 off(document, 'mouseup', _this._onDrop);
2405 off(document, 'touchend', _this._onDrop);
2406 off(document, 'touchcancel', _this._onDrop);
2407 if (dataTransfer) {
2408 dataTransfer.effectAllowed = 'move';
2409 options.setData && options.setData.call(_this, dataTransfer, dragEl);
2410 }
2411 on(document, 'drop', _this);
2412
2413 // #1276 fix:
2414 css(dragEl, 'transform', 'translateZ(0)');
2415 }
2416 awaitingDragStarted = true;
2417 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
2418 on(document, 'selectstart', _this);
2419 moved = true;
2420 window.getSelection().removeAllRanges();
2421 if (Safari) {
2422 css(document.body, 'user-select', 'none');
2423 }
2424 },
2425 // Returns true - if no further action is needed (either inserted or another condition)
2426 _onDragOver: function _onDragOver( /**Event*/evt) {
2427 var el = this.el,
2428 target = evt.target,
2429 dragRect,
2430 targetRect,
2431 revert,
2432 options = this.options,
2433 group = options.group,
2434 activeSortable = Sortable.active,
2435 isOwner = activeGroup === group,
2436 canSort = options.sort,
2437 fromSortable = putSortable || activeSortable,
2438 vertical,
2439 _this = this,
2440 completedFired = false;
2441 if (_silent) return;
2442 function dragOverEvent(name, extra) {
2443 pluginEvent(name, _this, _objectSpread2({
2444 evt: evt,
2445 isOwner: isOwner,
2446 axis: vertical ? 'vertical' : 'horizontal',
2447 revert: revert,
2448 dragRect: dragRect,
2449 targetRect: targetRect,
2450 canSort: canSort,
2451 fromSortable: fromSortable,
2452 target: target,
2453 completed: completed,
2454 onMove: function onMove(target, after) {
2455 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
2456 },
2457 changed: changed
2458 }, extra));
2459 }
2460
2461 // Capture animation state
2462 function capture() {
2463 dragOverEvent('dragOverAnimationCapture');
2464 _this.captureAnimationState();
2465 if (_this !== fromSortable) {
2466 fromSortable.captureAnimationState();
2467 }
2468 }
2469
2470 // Return invocation when dragEl is inserted (or completed)
2471 function completed(insertion) {
2472 dragOverEvent('dragOverCompleted', {
2473 insertion: insertion
2474 });
2475 if (insertion) {
2476 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
2477 if (isOwner) {
2478 activeSortable._hideClone();
2479 } else {
2480 activeSortable._showClone(_this);
2481 }
2482 if (_this !== fromSortable) {
2483 // Set ghost class to new sortable's ghost class
2484 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
2485 toggleClass(dragEl, options.ghostClass, true);
2486 }
2487 if (putSortable !== _this && _this !== Sortable.active) {
2488 putSortable = _this;
2489 } else if (_this === Sortable.active && putSortable) {
2490 putSortable = null;
2491 }
2492
2493 // Animation
2494 if (fromSortable === _this) {
2495 _this._ignoreWhileAnimating = target;
2496 }
2497 _this.animateAll(function () {
2498 dragOverEvent('dragOverAnimationComplete');
2499 _this._ignoreWhileAnimating = null;
2500 });
2501 if (_this !== fromSortable) {
2502 fromSortable.animateAll();
2503 fromSortable._ignoreWhileAnimating = null;
2504 }
2505 }
2506
2507 // Null lastTarget if it is not inside a previously swapped element
2508 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
2509 lastTarget = null;
2510 }
2511
2512 // no bubbling and not fallback
2513 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
2514 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
2515
2516 // Do not detect for empty insert if already inserted
2517 !insertion && nearestEmptyInsertDetectEvent(evt);
2518 }
2519 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
2520 return completedFired = true;
2521 }
2522
2523 // Call when dragEl has been inserted
2524 function changed() {
2525 newIndex = index(dragEl);
2526 newDraggableIndex = index(dragEl, options.draggable);
2527 _dispatchEvent({
2528 sortable: _this,
2529 name: 'change',
2530 toEl: el,
2531 newIndex: newIndex,
2532 newDraggableIndex: newDraggableIndex,
2533 originalEvent: evt
2534 });
2535 }
2536 if (evt.preventDefault !== void 0) {
2537 evt.cancelable && evt.preventDefault();
2538 }
2539 target = closest(target, options.draggable, el, true);
2540 dragOverEvent('dragOver');
2541 if (Sortable.eventCanceled) return completedFired;
2542 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
2543 return completed(false);
2544 }
2545 ignoreNextClick = false;
2546 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
2547 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
2548 vertical = this._getDirection(evt, target) === 'vertical';
2549 dragRect = getRect(dragEl);
2550 dragOverEvent('dragOverValid');
2551 if (Sortable.eventCanceled) return completedFired;
2552 if (revert) {
2553 parentEl = rootEl; // actualization
2554 capture();
2555 this._hideClone();
2556 dragOverEvent('revert');
2557 if (!Sortable.eventCanceled) {
2558 if (nextEl) {
2559 rootEl.insertBefore(dragEl, nextEl);
2560 } else {
2561 rootEl.appendChild(dragEl);
2562 }
2563 }
2564 return completed(true);
2565 }
2566 var elLastChild = lastChild(el, options.draggable);
2567 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
2568 // Insert to end of list
2569
2570 // If already at end of list: Do not insert
2571 if (elLastChild === dragEl) {
2572 return completed(false);
2573 }
2574
2575 // if there is a last element, it is the target
2576 if (elLastChild && el === evt.target) {
2577 target = elLastChild;
2578 }
2579 if (target) {
2580 targetRect = getRect(target);
2581 }
2582 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
2583 capture();
2584 if (elLastChild && elLastChild.nextSibling) {
2585 // the last draggable element is not the last node
2586 el.insertBefore(dragEl, elLastChild.nextSibling);
2587 } else {
2588 el.appendChild(dragEl);
2589 }
2590 parentEl = el; // actualization
2591
2592 changed();
2593 return completed(true);
2594 }
2595 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
2596 // Insert to start of list
2597 var firstChild = getChild(el, 0, options, true);
2598 if (firstChild === dragEl) {
2599 return completed(false);
2600 }
2601 target = firstChild;
2602 targetRect = getRect(target);
2603 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
2604 capture();
2605 el.insertBefore(dragEl, firstChild);
2606 parentEl = el; // actualization
2607
2608 changed();
2609 return completed(true);
2610 }
2611 } else if (target.parentNode === el) {
2612 targetRect = getRect(target);
2613 var direction = 0,
2614 targetBeforeFirstSwap,
2615 differentLevel = dragEl.parentNode !== el,
2616 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
2617 side1 = vertical ? 'top' : 'left',
2618 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
2619 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
2620 if (lastTarget !== target) {
2621 targetBeforeFirstSwap = targetRect[side1];
2622 pastFirstInvertThresh = false;
2623 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
2624 }
2625 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
2626 var sibling;
2627 if (direction !== 0) {
2628 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
2629 var dragIndex = index(dragEl);
2630 do {
2631 dragIndex -= direction;
2632 sibling = parentEl.children[dragIndex];
2633 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
2634 }
2635 // If dragEl is already beside target: Do not insert
2636 if (direction === 0 || sibling === target) {
2637 return completed(false);
2638 }
2639 lastTarget = target;
2640 lastDirection = direction;
2641 var nextSibling = target.nextElementSibling,
2642 after = false;
2643 after = direction === 1;
2644 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
2645 if (moveVector !== false) {
2646 if (moveVector === 1 || moveVector === -1) {
2647 after = moveVector === 1;
2648 }
2649 _silent = true;
2650 setTimeout(_unsilent, 30);
2651 capture();
2652 if (after && !nextSibling) {
2653 el.appendChild(dragEl);
2654 } else {
2655 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
2656 }
2657
2658 // Undo chrome's scroll adjustment (has no effect on other browsers)
2659 if (scrolledPastTop) {
2660 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
2661 }
2662 parentEl = dragEl.parentNode; // actualization
2663
2664 // must be done before animation
2665 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
2666 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
2667 }
2668 changed();
2669 return completed(true);
2670 }
2671 }
2672 if (el.contains(dragEl)) {
2673 return completed(false);
2674 }
2675 }
2676 return false;
2677 },
2678 _ignoreWhileAnimating: null,
2679 _offMoveEvents: function _offMoveEvents() {
2680 off(document, 'mousemove', this._onTouchMove);
2681 off(document, 'touchmove', this._onTouchMove);
2682 off(document, 'pointermove', this._onTouchMove);
2683 off(document, 'dragover', nearestEmptyInsertDetectEvent);
2684 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
2685 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
2686 },
2687 _offUpEvents: function _offUpEvents() {
2688 var ownerDocument = this.el.ownerDocument;
2689 off(ownerDocument, 'mouseup', this._onDrop);
2690 off(ownerDocument, 'touchend', this._onDrop);
2691 off(ownerDocument, 'pointerup', this._onDrop);
2692 off(ownerDocument, 'pointercancel', this._onDrop);
2693 off(ownerDocument, 'touchcancel', this._onDrop);
2694 off(document, 'selectstart', this);
2695 },
2696 _onDrop: function _onDrop( /**Event*/evt) {
2697 var el = this.el,
2698 options = this.options;
2699
2700 // Get the index of the dragged element within its parent
2701 newIndex = index(dragEl);
2702 newDraggableIndex = index(dragEl, options.draggable);
2703 pluginEvent('drop', this, {
2704 evt: evt
2705 });
2706 parentEl = dragEl && dragEl.parentNode;
2707
2708 // Get again after plugin event
2709 newIndex = index(dragEl);
2710 newDraggableIndex = index(dragEl, options.draggable);
2711 if (Sortable.eventCanceled) {
2712 this._nulling();
2713 return;
2714 }
2715 awaitingDragStarted = false;
2716 isCircumstantialInvert = false;
2717 pastFirstInvertThresh = false;
2718 clearInterval(this._loopId);
2719 clearTimeout(this._dragStartTimer);
2720 _cancelNextTick(this.cloneId);
2721 _cancelNextTick(this._dragStartId);
2722
2723 // Unbind events
2724 if (this.nativeDraggable) {
2725 off(document, 'drop', this);
2726 off(el, 'dragstart', this._onDragStart);
2727 }
2728 this._offMoveEvents();
2729 this._offUpEvents();
2730 if (Safari) {
2731 css(document.body, 'user-select', '');
2732 }
2733 css(dragEl, 'transform', '');
2734 if (evt) {
2735 if (moved) {
2736 evt.cancelable && evt.preventDefault();
2737 !options.dropBubble && evt.stopPropagation();
2738 }
2739 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
2740 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
2741 // Remove clone(s)
2742 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
2743 }
2744 if (dragEl) {
2745 if (this.nativeDraggable) {
2746 off(dragEl, 'dragend', this);
2747 }
2748 _disableDraggable(dragEl);
2749 dragEl.style['will-change'] = '';
2750
2751 // Remove classes
2752 // ghostClass is added in dragStarted
2753 if (moved && !awaitingDragStarted) {
2754 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
2755 }
2756 toggleClass(dragEl, this.options.chosenClass, false);
2757
2758 // Drag stop event
2759 _dispatchEvent({
2760 sortable: this,
2761 name: 'unchoose',
2762 toEl: parentEl,
2763 newIndex: null,
2764 newDraggableIndex: null,
2765 originalEvent: evt
2766 });
2767 if (rootEl !== parentEl) {
2768 if (newIndex >= 0) {
2769 // Add event
2770 _dispatchEvent({
2771 rootEl: parentEl,
2772 name: 'add',
2773 toEl: parentEl,
2774 fromEl: rootEl,
2775 originalEvent: evt
2776 });
2777
2778 // Remove event
2779 _dispatchEvent({
2780 sortable: this,
2781 name: 'remove',
2782 toEl: parentEl,
2783 originalEvent: evt
2784 });
2785
2786 // drag from one list and drop into another
2787 _dispatchEvent({
2788 rootEl: parentEl,
2789 name: 'sort',
2790 toEl: parentEl,
2791 fromEl: rootEl,
2792 originalEvent: evt
2793 });
2794 _dispatchEvent({
2795 sortable: this,
2796 name: 'sort',
2797 toEl: parentEl,
2798 originalEvent: evt
2799 });
2800 }
2801 putSortable && putSortable.save();
2802 } else {
2803 if (newIndex !== oldIndex) {
2804 if (newIndex >= 0) {
2805 // drag & drop within the same list
2806 _dispatchEvent({
2807 sortable: this,
2808 name: 'update',
2809 toEl: parentEl,
2810 originalEvent: evt
2811 });
2812 _dispatchEvent({
2813 sortable: this,
2814 name: 'sort',
2815 toEl: parentEl,
2816 originalEvent: evt
2817 });
2818 }
2819 }
2820 }
2821 if (Sortable.active) {
2822 /* jshint eqnull:true */
2823 if (newIndex == null || newIndex === -1) {
2824 newIndex = oldIndex;
2825 newDraggableIndex = oldDraggableIndex;
2826 }
2827 _dispatchEvent({
2828 sortable: this,
2829 name: 'end',
2830 toEl: parentEl,
2831 originalEvent: evt
2832 });
2833
2834 // Save sorting
2835 this.save();
2836 }
2837 }
2838 }
2839 this._nulling();
2840 },
2841 _nulling: function _nulling() {
2842 pluginEvent('nulling', this);
2843 rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null;
2844 var el = this.el;
2845 savedInputChecked.forEach(function (checkEl) {
2846 if (el.contains(checkEl)) {
2847 checkEl.checked = true;
2848 }
2849 });
2850 savedInputChecked.length = lastDx = lastDy = 0;
2851 },
2852 handleEvent: function handleEvent( /**Event*/evt) {
2853 switch (evt.type) {
2854 case 'drop':
2855 case 'dragend':
2856 this._onDrop(evt);
2857 break;
2858 case 'dragenter':
2859 case 'dragover':
2860 if (dragEl) {
2861 this._onDragOver(evt);
2862 _globalDragOver(evt);
2863 }
2864 break;
2865 case 'selectstart':
2866 evt.preventDefault();
2867 break;
2868 }
2869 },
2870 /**
2871 * Serializes the item into an array of string.
2872 * @returns {String[]}
2873 */
2874 toArray: function toArray() {
2875 var order = [],
2876 el,
2877 children = this.el.children,
2878 i = 0,
2879 n = children.length,
2880 options = this.options;
2881 for (; i < n; i++) {
2882 el = children[i];
2883 if (closest(el, options.draggable, this.el, false)) {
2884 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
2885 }
2886 }
2887 return order;
2888 },
2889 /**
2890 * Sorts the elements according to the array.
2891 * @param {String[]} order order of the items
2892 */
2893 sort: function sort(order, useAnimation) {
2894 var items = {},
2895 rootEl = this.el;
2896 this.toArray().forEach(function (id, i) {
2897 var el = rootEl.children[i];
2898 if (closest(el, this.options.draggable, rootEl, false)) {
2899 items[id] = el;
2900 }
2901 }, this);
2902 useAnimation && this.captureAnimationState();
2903 order.forEach(function (id) {
2904 if (items[id]) {
2905 rootEl.removeChild(items[id]);
2906 rootEl.appendChild(items[id]);
2907 }
2908 });
2909 useAnimation && this.animateAll();
2910 },
2911 /**
2912 * Save the current sorting
2913 */
2914 save: function save() {
2915 var store = this.options.store;
2916 store && store.set && store.set(this);
2917 },
2918 /**
2919 * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
2920 * @param {HTMLElement} el
2921 * @param {String} [selector] default: `options.draggable`
2922 * @returns {HTMLElement|null}
2923 */
2924 closest: function closest$1(el, selector) {
2925 return closest(el, selector || this.options.draggable, this.el, false);
2926 },
2927 /**
2928 * Set/get option
2929 * @param {string} name
2930 * @param {*} [value]
2931 * @returns {*}
2932 */
2933 option: function option(name, value) {
2934 var options = this.options;
2935 if (value === void 0) {
2936 return options[name];
2937 } else {
2938 var modifiedValue = PluginManager.modifyOption(this, name, value);
2939 if (typeof modifiedValue !== 'undefined') {
2940 options[name] = modifiedValue;
2941 } else {
2942 options[name] = value;
2943 }
2944 if (name === 'group') {
2945 _prepareGroup(options);
2946 }
2947 }
2948 },
2949 /**
2950 * Destroy
2951 */
2952 destroy: function destroy() {
2953 pluginEvent('destroy', this);
2954 var el = this.el;
2955 el[expando] = null;
2956 off(el, 'mousedown', this._onTapStart);
2957 off(el, 'touchstart', this._onTapStart);
2958 off(el, 'pointerdown', this._onTapStart);
2959 if (this.nativeDraggable) {
2960 off(el, 'dragover', this);
2961 off(el, 'dragenter', this);
2962 }
2963 // Remove draggable attributes
2964 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
2965 el.removeAttribute('draggable');
2966 });
2967 this._onDrop();
2968 this._disableDelayedDragEvents();
2969 sortables.splice(sortables.indexOf(this.el), 1);
2970 this.el = el = null;
2971 },
2972 _hideClone: function _hideClone() {
2973 if (!cloneHidden) {
2974 pluginEvent('hideClone', this);
2975 if (Sortable.eventCanceled) return;
2976 css(cloneEl, 'display', 'none');
2977 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
2978 cloneEl.parentNode.removeChild(cloneEl);
2979 }
2980 cloneHidden = true;
2981 }
2982 },
2983 _showClone: function _showClone(putSortable) {
2984 if (putSortable.lastPutMode !== 'clone') {
2985 this._hideClone();
2986 return;
2987 }
2988 if (cloneHidden) {
2989 pluginEvent('showClone', this);
2990 if (Sortable.eventCanceled) return;
2991
2992 // show clone at dragEl or original position
2993 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
2994 rootEl.insertBefore(cloneEl, dragEl);
2995 } else if (nextEl) {
2996 rootEl.insertBefore(cloneEl, nextEl);
2997 } else {
2998 rootEl.appendChild(cloneEl);
2999 }
3000 if (this.options.group.revertClone) {
3001 this.animate(dragEl, cloneEl);
3002 }
3003 css(cloneEl, 'display', '');
3004 cloneHidden = false;
3005 }
3006 }
3007 };
3008 function _globalDragOver( /**Event*/evt) {
3009 if (evt.dataTransfer) {
3010 evt.dataTransfer.dropEffect = 'move';
3011 }
3012 evt.cancelable && evt.preventDefault();
3013 }
3014 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
3015 var evt,
3016 sortable = fromEl[expando],
3017 onMoveFn = sortable.options.onMove,
3018 retVal;
3019 // Support for new CustomEvent feature
3020 if (window.CustomEvent && !IE11OrLess && !Edge) {
3021 evt = new CustomEvent('move', {
3022 bubbles: true,
3023 cancelable: true
3024 });
3025 } else {
3026 evt = document.createEvent('Event');
3027 evt.initEvent('move', true, true);
3028 }
3029 evt.to = toEl;
3030 evt.from = fromEl;
3031 evt.dragged = dragEl;
3032 evt.draggedRect = dragRect;
3033 evt.related = targetEl || toEl;
3034 evt.relatedRect = targetRect || getRect(toEl);
3035 evt.willInsertAfter = willInsertAfter;
3036 evt.originalEvent = originalEvent;
3037 fromEl.dispatchEvent(evt);
3038 if (onMoveFn) {
3039 retVal = onMoveFn.call(sortable, evt, originalEvent);
3040 }
3041 return retVal;
3042 }
3043 function _disableDraggable(el) {
3044 el.draggable = false;
3045 }
3046 function _unsilent() {
3047 _silent = false;
3048 }
3049 function _ghostIsFirst(evt, vertical, sortable) {
3050 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
3051 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
3052 var spacer = 10;
3053 return vertical ? evt.clientX < childContainingRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < childContainingRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left;
3054 }
3055 function _ghostIsLast(evt, vertical, sortable) {
3056 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
3057 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
3058 var spacer = 10;
3059 return vertical ? evt.clientX > childContainingRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > childContainingRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top;
3060 }
3061 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
3062 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
3063 targetLength = vertical ? targetRect.height : targetRect.width,
3064 targetS1 = vertical ? targetRect.top : targetRect.left,
3065 targetS2 = vertical ? targetRect.bottom : targetRect.right,
3066 invert = false;
3067 if (!invertSwap) {
3068 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
3069 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
3070 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
3071 // check if past first invert threshold on side opposite of lastDirection
3072 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
3073 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
3074 pastFirstInvertThresh = true;
3075 }
3076 if (!pastFirstInvertThresh) {
3077 // dragEl shadow (target move distance shadow)
3078 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
3079 : mouseOnAxis > targetS2 - targetMoveDistance) {
3080 return -lastDirection;
3081 }
3082 } else {
3083 invert = true;
3084 }
3085 } else {
3086 // Regular
3087 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
3088 return _getInsertDirection(target);
3089 }
3090 }
3091 }
3092 invert = invert || invertSwap;
3093 if (invert) {
3094 // Invert of regular
3095 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
3096 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
3097 }
3098 }
3099 return 0;
3100 }
3101
3102 /**
3103 * Gets the direction dragEl must be swapped relative to target in order to make it
3104 * seem that dragEl has been "inserted" into that element's position
3105 * @param {HTMLElement} target The target whose position dragEl is being inserted at
3106 * @return {Number} Direction dragEl must be swapped
3107 */
3108 function _getInsertDirection(target) {
3109 if (index(dragEl) < index(target)) {
3110 return 1;
3111 } else {
3112 return -1;
3113 }
3114 }
3115
3116 /**
3117 * Generate id
3118 * @param {HTMLElement} el
3119 * @returns {String}
3120 * @private
3121 */
3122 function _generateId(el) {
3123 var str = el.tagName + el.className + el.src + el.href + el.textContent,
3124 i = str.length,
3125 sum = 0;
3126 while (i--) {
3127 sum += str.charCodeAt(i);
3128 }
3129 return sum.toString(36);
3130 }
3131 function _saveInputCheckedState(root) {
3132 savedInputChecked.length = 0;
3133 var inputs = root.getElementsByTagName('input');
3134 var idx = inputs.length;
3135 while (idx--) {
3136 var el = inputs[idx];
3137 el.checked && savedInputChecked.push(el);
3138 }
3139 }
3140 function _nextTick(fn) {
3141 return setTimeout(fn, 0);
3142 }
3143 function _cancelNextTick(id) {
3144 return clearTimeout(id);
3145 }
3146
3147 // Fixed #973:
3148 if (documentExists) {
3149 on(document, 'touchmove', function (evt) {
3150 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
3151 evt.preventDefault();
3152 }
3153 });
3154 }
3155
3156 // Export utils
3157 Sortable.utils = {
3158 on: on,
3159 off: off,
3160 css: css,
3161 find: find,
3162 is: function is(el, selector) {
3163 return !!closest(el, selector, el, false);
3164 },
3165 extend: extend,
3166 throttle: throttle,
3167 closest: closest,
3168 toggleClass: toggleClass,
3169 clone: clone,
3170 index: index,
3171 nextTick: _nextTick,
3172 cancelNextTick: _cancelNextTick,
3173 detectDirection: _detectDirection,
3174 getChild: getChild,
3175 expando: expando
3176 };
3177
3178 /**
3179 * Get the Sortable instance of an element
3180 * @param {HTMLElement} element The element
3181 * @return {Sortable|undefined} The instance of Sortable
3182 */
3183 Sortable.get = function (element) {
3184 return element[expando];
3185 };
3186
3187 /**
3188 * Mount a plugin to Sortable
3189 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
3190 */
3191 Sortable.mount = function () {
3192 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
3193 plugins[_key] = arguments[_key];
3194 }
3195 if (plugins[0].constructor === Array) plugins = plugins[0];
3196 plugins.forEach(function (plugin) {
3197 if (!plugin.prototype || !plugin.prototype.constructor) {
3198 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
3199 }
3200 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
3201 PluginManager.mount(plugin);
3202 });
3203 };
3204
3205 /**
3206 * Create sortable instance
3207 * @param {HTMLElement} el
3208 * @param {Object} [options]
3209 */
3210 Sortable.create = function (el, options) {
3211 return new Sortable(el, options);
3212 };
3213
3214 // Export
3215 Sortable.version = version;
3216
3217 var autoScrolls = [],
3218 scrollEl,
3219 scrollRootEl,
3220 scrolling = false,
3221 lastAutoScrollX,
3222 lastAutoScrollY,
3223 touchEvt$1,
3224 pointerElemChangedInterval;
3225 function AutoScrollPlugin() {
3226 function AutoScroll() {
3227 this.defaults = {
3228 scroll: true,
3229 forceAutoScrollFallback: false,
3230 scrollSensitivity: 30,
3231 scrollSpeed: 10,
3232 bubbleScroll: true
3233 };
3234
3235 // Bind all private methods
3236 for (var fn in this) {
3237 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3238 this[fn] = this[fn].bind(this);
3239 }
3240 }
3241 }
3242 AutoScroll.prototype = {
3243 dragStarted: function dragStarted(_ref) {
3244 var originalEvent = _ref.originalEvent;
3245 if (this.sortable.nativeDraggable) {
3246 on(document, 'dragover', this._handleAutoScroll);
3247 } else {
3248 if (this.options.supportPointer) {
3249 on(document, 'pointermove', this._handleFallbackAutoScroll);
3250 } else if (originalEvent.touches) {
3251 on(document, 'touchmove', this._handleFallbackAutoScroll);
3252 } else {
3253 on(document, 'mousemove', this._handleFallbackAutoScroll);
3254 }
3255 }
3256 },
3257 dragOverCompleted: function dragOverCompleted(_ref2) {
3258 var originalEvent = _ref2.originalEvent;
3259 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
3260 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
3261 this._handleAutoScroll(originalEvent);
3262 }
3263 },
3264 drop: function drop() {
3265 if (this.sortable.nativeDraggable) {
3266 off(document, 'dragover', this._handleAutoScroll);
3267 } else {
3268 off(document, 'pointermove', this._handleFallbackAutoScroll);
3269 off(document, 'touchmove', this._handleFallbackAutoScroll);
3270 off(document, 'mousemove', this._handleFallbackAutoScroll);
3271 }
3272 clearPointerElemChangedInterval();
3273 clearAutoScrolls();
3274 cancelThrottle();
3275 },
3276 nulling: function nulling() {
3277 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
3278 autoScrolls.length = 0;
3279 },
3280 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
3281 this._handleAutoScroll(evt, true);
3282 },
3283 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
3284 var _this = this;
3285 var x = (evt.touches ? evt.touches[0] : evt).clientX,
3286 y = (evt.touches ? evt.touches[0] : evt).clientY,
3287 elem = document.elementFromPoint(x, y);
3288 touchEvt$1 = evt;
3289
3290 // IE does not seem to have native autoscroll,
3291 // Edge's autoscroll seems too conditional,
3292 // MACOS Safari does not have autoscroll,
3293 // Firefox and Chrome are good
3294 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
3295 autoScroll(evt, this.options, elem, fallback);
3296
3297 // Listener for pointer element change
3298 var ogElemScroller = getParentAutoScrollElement(elem, true);
3299 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
3300 pointerElemChangedInterval && clearPointerElemChangedInterval();
3301 // Detect for pointer elem change, emulating native DnD behaviour
3302 pointerElemChangedInterval = setInterval(function () {
3303 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
3304 if (newElem !== ogElemScroller) {
3305 ogElemScroller = newElem;
3306 clearAutoScrolls();
3307 }
3308 autoScroll(evt, _this.options, newElem, fallback);
3309 }, 10);
3310 lastAutoScrollX = x;
3311 lastAutoScrollY = y;
3312 }
3313 } else {
3314 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
3315 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
3316 clearAutoScrolls();
3317 return;
3318 }
3319 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
3320 }
3321 }
3322 };
3323 return _extends(AutoScroll, {
3324 pluginName: 'scroll',
3325 initializeByDefault: true
3326 });
3327 }
3328 function clearAutoScrolls() {
3329 autoScrolls.forEach(function (autoScroll) {
3330 clearInterval(autoScroll.pid);
3331 });
3332 autoScrolls = [];
3333 }
3334 function clearPointerElemChangedInterval() {
3335 clearInterval(pointerElemChangedInterval);
3336 }
3337 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
3338 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
3339 if (!options.scroll) return;
3340 var x = (evt.touches ? evt.touches[0] : evt).clientX,
3341 y = (evt.touches ? evt.touches[0] : evt).clientY,
3342 sens = options.scrollSensitivity,
3343 speed = options.scrollSpeed,
3344 winScroller = getWindowScrollingElement();
3345 var scrollThisInstance = false,
3346 scrollCustomFn;
3347
3348 // New scroll root, set scrollEl
3349 if (scrollRootEl !== rootEl) {
3350 scrollRootEl = rootEl;
3351 clearAutoScrolls();
3352 scrollEl = options.scroll;
3353 scrollCustomFn = options.scrollFn;
3354 if (scrollEl === true) {
3355 scrollEl = getParentAutoScrollElement(rootEl, true);
3356 }
3357 }
3358 var layersOut = 0;
3359 var currentParent = scrollEl;
3360 do {
3361 var el = currentParent,
3362 rect = getRect(el),
3363 top = rect.top,
3364 bottom = rect.bottom,
3365 left = rect.left,
3366 right = rect.right,
3367 width = rect.width,
3368 height = rect.height,
3369 canScrollX = void 0,
3370 canScrollY = void 0,
3371 scrollWidth = el.scrollWidth,
3372 scrollHeight = el.scrollHeight,
3373 elCSS = css(el),
3374 scrollPosX = el.scrollLeft,
3375 scrollPosY = el.scrollTop;
3376 if (el === winScroller) {
3377 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
3378 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
3379 } else {
3380 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
3381 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
3382 }
3383 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
3384 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
3385 if (!autoScrolls[layersOut]) {
3386 for (var i = 0; i <= layersOut; i++) {
3387 if (!autoScrolls[i]) {
3388 autoScrolls[i] = {};
3389 }
3390 }
3391 }
3392 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
3393 autoScrolls[layersOut].el = el;
3394 autoScrolls[layersOut].vx = vx;
3395 autoScrolls[layersOut].vy = vy;
3396 clearInterval(autoScrolls[layersOut].pid);
3397 if (vx != 0 || vy != 0) {
3398 scrollThisInstance = true;
3399 /* jshint loopfunc:true */
3400 autoScrolls[layersOut].pid = setInterval(function () {
3401 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
3402 if (isFallback && this.layer === 0) {
3403 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
3404 }
3405 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
3406 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
3407 if (typeof scrollCustomFn === 'function') {
3408 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
3409 return;
3410 }
3411 }
3412 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
3413 }.bind({
3414 layer: layersOut
3415 }), 24);
3416 }
3417 }
3418 layersOut++;
3419 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
3420 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
3421 }, 30);
3422
3423 var drop = function drop(_ref) {
3424 var originalEvent = _ref.originalEvent,
3425 putSortable = _ref.putSortable,
3426 dragEl = _ref.dragEl,
3427 activeSortable = _ref.activeSortable,
3428 dispatchSortableEvent = _ref.dispatchSortableEvent,
3429 hideGhostForTarget = _ref.hideGhostForTarget,
3430 unhideGhostForTarget = _ref.unhideGhostForTarget;
3431 if (!originalEvent) return;
3432 var toSortable = putSortable || activeSortable;
3433 hideGhostForTarget();
3434 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
3435 var target = document.elementFromPoint(touch.clientX, touch.clientY);
3436 unhideGhostForTarget();
3437 if (toSortable && !toSortable.el.contains(target)) {
3438 dispatchSortableEvent('spill');
3439 this.onSpill({
3440 dragEl: dragEl,
3441 putSortable: putSortable
3442 });
3443 }
3444 };
3445 function Revert() {}
3446 Revert.prototype = {
3447 startIndex: null,
3448 dragStart: function dragStart(_ref2) {
3449 var oldDraggableIndex = _ref2.oldDraggableIndex;
3450 this.startIndex = oldDraggableIndex;
3451 },
3452 onSpill: function onSpill(_ref3) {
3453 var dragEl = _ref3.dragEl,
3454 putSortable = _ref3.putSortable;
3455 this.sortable.captureAnimationState();
3456 if (putSortable) {
3457 putSortable.captureAnimationState();
3458 }
3459 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
3460 if (nextSibling) {
3461 this.sortable.el.insertBefore(dragEl, nextSibling);
3462 } else {
3463 this.sortable.el.appendChild(dragEl);
3464 }
3465 this.sortable.animateAll();
3466 if (putSortable) {
3467 putSortable.animateAll();
3468 }
3469 },
3470 drop: drop
3471 };
3472 _extends(Revert, {
3473 pluginName: 'revertOnSpill'
3474 });
3475 function Remove() {}
3476 Remove.prototype = {
3477 onSpill: function onSpill(_ref4) {
3478 var dragEl = _ref4.dragEl,
3479 putSortable = _ref4.putSortable;
3480 var parentSortable = putSortable || this.sortable;
3481 parentSortable.captureAnimationState();
3482 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
3483 parentSortable.animateAll();
3484 },
3485 drop: drop
3486 };
3487 _extends(Remove, {
3488 pluginName: 'removeOnSpill'
3489 });
3490
3491 var lastSwapEl;
3492 function SwapPlugin() {
3493 function Swap() {
3494 this.defaults = {
3495 swapClass: 'sortable-swap-highlight'
3496 };
3497 }
3498 Swap.prototype = {
3499 dragStart: function dragStart(_ref) {
3500 var dragEl = _ref.dragEl;
3501 lastSwapEl = dragEl;
3502 },
3503 dragOverValid: function dragOverValid(_ref2) {
3504 var completed = _ref2.completed,
3505 target = _ref2.target,
3506 onMove = _ref2.onMove,
3507 activeSortable = _ref2.activeSortable,
3508 changed = _ref2.changed,
3509 cancel = _ref2.cancel;
3510 if (!activeSortable.options.swap) return;
3511 var el = this.sortable.el,
3512 options = this.options;
3513 if (target && target !== el) {
3514 var prevSwapEl = lastSwapEl;
3515 if (onMove(target) !== false) {
3516 toggleClass(target, options.swapClass, true);
3517 lastSwapEl = target;
3518 } else {
3519 lastSwapEl = null;
3520 }
3521 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
3522 toggleClass(prevSwapEl, options.swapClass, false);
3523 }
3524 }
3525 changed();
3526 completed(true);
3527 cancel();
3528 },
3529 drop: function drop(_ref3) {
3530 var activeSortable = _ref3.activeSortable,
3531 putSortable = _ref3.putSortable,
3532 dragEl = _ref3.dragEl;
3533 var toSortable = putSortable || this.sortable;
3534 var options = this.options;
3535 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
3536 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
3537 if (dragEl !== lastSwapEl) {
3538 toSortable.captureAnimationState();
3539 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
3540 swapNodes(dragEl, lastSwapEl);
3541 toSortable.animateAll();
3542 if (toSortable !== activeSortable) activeSortable.animateAll();
3543 }
3544 }
3545 },
3546 nulling: function nulling() {
3547 lastSwapEl = null;
3548 }
3549 };
3550 return _extends(Swap, {
3551 pluginName: 'swap',
3552 eventProperties: function eventProperties() {
3553 return {
3554 swapItem: lastSwapEl
3555 };
3556 }
3557 });
3558 }
3559 function swapNodes(n1, n2) {
3560 var p1 = n1.parentNode,
3561 p2 = n2.parentNode,
3562 i1,
3563 i2;
3564 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
3565 i1 = index(n1);
3566 i2 = index(n2);
3567 if (p1.isEqualNode(p2) && i1 < i2) {
3568 i2++;
3569 }
3570 p1.insertBefore(n2, p1.children[i1]);
3571 p2.insertBefore(n1, p2.children[i2]);
3572 }
3573
3574 var multiDragElements = [],
3575 multiDragClones = [],
3576 lastMultiDragSelect,
3577 // for selection with modifier key down (SHIFT)
3578 multiDragSortable,
3579 initialFolding = false,
3580 // Initial multi-drag fold when drag started
3581 folding = false,
3582 // Folding any other time
3583 dragStarted = false,
3584 dragEl$1,
3585 clonesFromRect,
3586 clonesHidden;
3587 function MultiDragPlugin() {
3588 function MultiDrag(sortable) {
3589 // Bind all private methods
3590 for (var fn in this) {
3591 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3592 this[fn] = this[fn].bind(this);
3593 }
3594 }
3595 if (!sortable.options.avoidImplicitDeselect) {
3596 if (sortable.options.supportPointer) {
3597 on(document, 'pointerup', this._deselectMultiDrag);
3598 } else {
3599 on(document, 'mouseup', this._deselectMultiDrag);
3600 on(document, 'touchend', this._deselectMultiDrag);
3601 }
3602 }
3603 on(document, 'keydown', this._checkKeyDown);
3604 on(document, 'keyup', this._checkKeyUp);
3605 this.defaults = {
3606 selectedClass: 'sortable-selected',
3607 multiDragKey: null,
3608 avoidImplicitDeselect: false,
3609 setData: function setData(dataTransfer, dragEl) {
3610 var data = '';
3611 if (multiDragElements.length && multiDragSortable === sortable) {
3612 multiDragElements.forEach(function (multiDragElement, i) {
3613 data += (!i ? '' : ', ') + multiDragElement.textContent;
3614 });
3615 } else {
3616 data = dragEl.textContent;
3617 }
3618 dataTransfer.setData('Text', data);
3619 }
3620 };
3621 }
3622 MultiDrag.prototype = {
3623 multiDragKeyDown: false,
3624 isMultiDrag: false,
3625 delayStartGlobal: function delayStartGlobal(_ref) {
3626 var dragged = _ref.dragEl;
3627 dragEl$1 = dragged;
3628 },
3629 delayEnded: function delayEnded() {
3630 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
3631 },
3632 setupClone: function setupClone(_ref2) {
3633 var sortable = _ref2.sortable,
3634 cancel = _ref2.cancel;
3635 if (!this.isMultiDrag) return;
3636 for (var i = 0; i < multiDragElements.length; i++) {
3637 multiDragClones.push(clone(multiDragElements[i]));
3638 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
3639 multiDragClones[i].draggable = false;
3640 multiDragClones[i].style['will-change'] = '';
3641 toggleClass(multiDragClones[i], this.options.selectedClass, false);
3642 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
3643 }
3644 sortable._hideClone();
3645 cancel();
3646 },
3647 clone: function clone(_ref3) {
3648 var sortable = _ref3.sortable,
3649 rootEl = _ref3.rootEl,
3650 dispatchSortableEvent = _ref3.dispatchSortableEvent,
3651 cancel = _ref3.cancel;
3652 if (!this.isMultiDrag) return;
3653 if (!this.options.removeCloneOnHide) {
3654 if (multiDragElements.length && multiDragSortable === sortable) {
3655 insertMultiDragClones(true, rootEl);
3656 dispatchSortableEvent('clone');
3657 cancel();
3658 }
3659 }
3660 },
3661 showClone: function showClone(_ref4) {
3662 var cloneNowShown = _ref4.cloneNowShown,
3663 rootEl = _ref4.rootEl,
3664 cancel = _ref4.cancel;
3665 if (!this.isMultiDrag) return;
3666 insertMultiDragClones(false, rootEl);
3667 multiDragClones.forEach(function (clone) {
3668 css(clone, 'display', '');
3669 });
3670 cloneNowShown();
3671 clonesHidden = false;
3672 cancel();
3673 },
3674 hideClone: function hideClone(_ref5) {
3675 var _this = this;
3676 var sortable = _ref5.sortable,
3677 cloneNowHidden = _ref5.cloneNowHidden,
3678 cancel = _ref5.cancel;
3679 if (!this.isMultiDrag) return;
3680 multiDragClones.forEach(function (clone) {
3681 css(clone, 'display', 'none');
3682 if (_this.options.removeCloneOnHide && clone.parentNode) {
3683 clone.parentNode.removeChild(clone);
3684 }
3685 });
3686 cloneNowHidden();
3687 clonesHidden = true;
3688 cancel();
3689 },
3690 dragStartGlobal: function dragStartGlobal(_ref6) {
3691 var sortable = _ref6.sortable;
3692 if (!this.isMultiDrag && multiDragSortable) {
3693 multiDragSortable.multiDrag._deselectMultiDrag();
3694 }
3695 multiDragElements.forEach(function (multiDragElement) {
3696 multiDragElement.sortableIndex = index(multiDragElement);
3697 });
3698
3699 // Sort multi-drag elements
3700 multiDragElements = multiDragElements.sort(function (a, b) {
3701 return a.sortableIndex - b.sortableIndex;
3702 });
3703 dragStarted = true;
3704 },
3705 dragStarted: function dragStarted(_ref7) {
3706 var _this2 = this;
3707 var sortable = _ref7.sortable;
3708 if (!this.isMultiDrag) return;
3709 if (this.options.sort) {
3710 // Capture rects,
3711 // hide multi drag elements (by positioning them absolute),
3712 // set multi drag elements rects to dragRect,
3713 // show multi drag elements,
3714 // animate to rects,
3715 // unset rects & remove from DOM
3716
3717 sortable.captureAnimationState();
3718 if (this.options.animation) {
3719 multiDragElements.forEach(function (multiDragElement) {
3720 if (multiDragElement === dragEl$1) return;
3721 css(multiDragElement, 'position', 'absolute');
3722 });
3723 var dragRect = getRect(dragEl$1, false, true, true);
3724 multiDragElements.forEach(function (multiDragElement) {
3725 if (multiDragElement === dragEl$1) return;
3726 setRect(multiDragElement, dragRect);
3727 });
3728 folding = true;
3729 initialFolding = true;
3730 }
3731 }
3732 sortable.animateAll(function () {
3733 folding = false;
3734 initialFolding = false;
3735 if (_this2.options.animation) {
3736 multiDragElements.forEach(function (multiDragElement) {
3737 unsetRect(multiDragElement);
3738 });
3739 }
3740
3741 // Remove all auxiliary multidrag items from el, if sorting enabled
3742 if (_this2.options.sort) {
3743 removeMultiDragElements();
3744 }
3745 });
3746 },
3747 dragOver: function dragOver(_ref8) {
3748 var target = _ref8.target,
3749 completed = _ref8.completed,
3750 cancel = _ref8.cancel;
3751 if (folding && ~multiDragElements.indexOf(target)) {
3752 completed(false);
3753 cancel();
3754 }
3755 },
3756 revert: function revert(_ref9) {
3757 var fromSortable = _ref9.fromSortable,
3758 rootEl = _ref9.rootEl,
3759 sortable = _ref9.sortable,
3760 dragRect = _ref9.dragRect;
3761 if (multiDragElements.length > 1) {
3762 // Setup unfold animation
3763 multiDragElements.forEach(function (multiDragElement) {
3764 sortable.addAnimationState({
3765 target: multiDragElement,
3766 rect: folding ? getRect(multiDragElement) : dragRect
3767 });
3768 unsetRect(multiDragElement);
3769 multiDragElement.fromRect = dragRect;
3770 fromSortable.removeAnimationState(multiDragElement);
3771 });
3772 folding = false;
3773 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
3774 }
3775 },
3776 dragOverCompleted: function dragOverCompleted(_ref10) {
3777 var sortable = _ref10.sortable,
3778 isOwner = _ref10.isOwner,
3779 insertion = _ref10.insertion,
3780 activeSortable = _ref10.activeSortable,
3781 parentEl = _ref10.parentEl,
3782 putSortable = _ref10.putSortable;
3783 var options = this.options;
3784 if (insertion) {
3785 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
3786 if (isOwner) {
3787 activeSortable._hideClone();
3788 }
3789 initialFolding = false;
3790 // If leaving sort:false root, or already folding - Fold to new location
3791 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
3792 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
3793 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
3794 multiDragElements.forEach(function (multiDragElement) {
3795 if (multiDragElement === dragEl$1) return;
3796 setRect(multiDragElement, dragRectAbsolute);
3797
3798 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
3799 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
3800 parentEl.appendChild(multiDragElement);
3801 });
3802 folding = true;
3803 }
3804
3805 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
3806 if (!isOwner) {
3807 // Only remove if not folding (folding will remove them anyways)
3808 if (!folding) {
3809 removeMultiDragElements();
3810 }
3811 if (multiDragElements.length > 1) {
3812 var clonesHiddenBefore = clonesHidden;
3813 activeSortable._showClone(sortable);
3814
3815 // Unfold animation for clones if showing from hidden
3816 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
3817 multiDragClones.forEach(function (clone) {
3818 activeSortable.addAnimationState({
3819 target: clone,
3820 rect: clonesFromRect
3821 });
3822 clone.fromRect = clonesFromRect;
3823 clone.thisAnimationDuration = null;
3824 });
3825 }
3826 } else {
3827 activeSortable._showClone(sortable);
3828 }
3829 }
3830 }
3831 },
3832 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
3833 var dragRect = _ref11.dragRect,
3834 isOwner = _ref11.isOwner,
3835 activeSortable = _ref11.activeSortable;
3836 multiDragElements.forEach(function (multiDragElement) {
3837 multiDragElement.thisAnimationDuration = null;
3838 });
3839 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
3840 clonesFromRect = _extends({}, dragRect);
3841 var dragMatrix = matrix(dragEl$1, true);
3842 clonesFromRect.top -= dragMatrix.f;
3843 clonesFromRect.left -= dragMatrix.e;
3844 }
3845 },
3846 dragOverAnimationComplete: function dragOverAnimationComplete() {
3847 if (folding) {
3848 folding = false;
3849 removeMultiDragElements();
3850 }
3851 },
3852 drop: function drop(_ref12) {
3853 var evt = _ref12.originalEvent,
3854 rootEl = _ref12.rootEl,
3855 parentEl = _ref12.parentEl,
3856 sortable = _ref12.sortable,
3857 dispatchSortableEvent = _ref12.dispatchSortableEvent,
3858 oldIndex = _ref12.oldIndex,
3859 putSortable = _ref12.putSortable;
3860 var toSortable = putSortable || this.sortable;
3861 if (!evt) return;
3862 var options = this.options,
3863 children = parentEl.children;
3864
3865 // Multi-drag selection
3866 if (!dragStarted) {
3867 if (options.multiDragKey && !this.multiDragKeyDown) {
3868 this._deselectMultiDrag();
3869 }
3870 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
3871 if (!~multiDragElements.indexOf(dragEl$1)) {
3872 multiDragElements.push(dragEl$1);
3873 dispatchEvent({
3874 sortable: sortable,
3875 rootEl: rootEl,
3876 name: 'select',
3877 targetEl: dragEl$1,
3878 originalEvent: evt
3879 });
3880
3881 // Modifier activated, select from last to dragEl
3882 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
3883 var lastIndex = index(lastMultiDragSelect),
3884 currentIndex = index(dragEl$1);
3885 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
3886 (function () {
3887 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
3888 // (but previous selection existed)
3889 var n, i;
3890 if (currentIndex > lastIndex) {
3891 i = lastIndex;
3892 n = currentIndex;
3893 } else {
3894 i = currentIndex;
3895 n = lastIndex + 1;
3896 }
3897 var filter = options.filter;
3898 for (; i < n; i++) {
3899 if (~multiDragElements.indexOf(children[i])) continue;
3900 // Check if element is draggable
3901 if (!closest(children[i], options.draggable, parentEl, false)) continue;
3902 // Check if element is filtered
3903 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
3904 return closest(children[i], criteria.trim(), parentEl, false);
3905 }));
3906 if (filtered) continue;
3907 toggleClass(children[i], options.selectedClass, true);
3908 multiDragElements.push(children[i]);
3909 dispatchEvent({
3910 sortable: sortable,
3911 rootEl: rootEl,
3912 name: 'select',
3913 targetEl: children[i],
3914 originalEvent: evt
3915 });
3916 }
3917 })();
3918 }
3919 } else {
3920 lastMultiDragSelect = dragEl$1;
3921 }
3922 multiDragSortable = toSortable;
3923 } else {
3924 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
3925 lastMultiDragSelect = null;
3926 dispatchEvent({
3927 sortable: sortable,
3928 rootEl: rootEl,
3929 name: 'deselect',
3930 targetEl: dragEl$1,
3931 originalEvent: evt
3932 });
3933 }
3934 }
3935
3936 // Multi-drag drop
3937 if (dragStarted && this.isMultiDrag) {
3938 folding = false;
3939 // Do not "unfold" after around dragEl if reverted
3940 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
3941 var dragRect = getRect(dragEl$1),
3942 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
3943 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
3944 toSortable.captureAnimationState();
3945 if (!initialFolding) {
3946 if (options.animation) {
3947 dragEl$1.fromRect = dragRect;
3948 multiDragElements.forEach(function (multiDragElement) {
3949 multiDragElement.thisAnimationDuration = null;
3950 if (multiDragElement !== dragEl$1) {
3951 var rect = folding ? getRect(multiDragElement) : dragRect;
3952 multiDragElement.fromRect = rect;
3953
3954 // Prepare unfold animation
3955 toSortable.addAnimationState({
3956 target: multiDragElement,
3957 rect: rect
3958 });
3959 }
3960 });
3961 }
3962
3963 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
3964 // properly they must all be removed
3965 removeMultiDragElements();
3966 multiDragElements.forEach(function (multiDragElement) {
3967 if (children[multiDragIndex]) {
3968 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
3969 } else {
3970 parentEl.appendChild(multiDragElement);
3971 }
3972 multiDragIndex++;
3973 });
3974
3975 // If initial folding is done, the elements may have changed position because they are now
3976 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
3977 // must be fired here as Sortable will not.
3978 if (oldIndex === index(dragEl$1)) {
3979 var update = false;
3980 multiDragElements.forEach(function (multiDragElement) {
3981 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
3982 update = true;
3983 return;
3984 }
3985 });
3986 if (update) {
3987 dispatchSortableEvent('update');
3988 dispatchSortableEvent('sort');
3989 }
3990 }
3991 }
3992
3993 // Must be done after capturing individual rects (scroll bar)
3994 multiDragElements.forEach(function (multiDragElement) {
3995 unsetRect(multiDragElement);
3996 });
3997 toSortable.animateAll();
3998 }
3999 multiDragSortable = toSortable;
4000 }
4001
4002 // Remove clones if necessary
4003 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
4004 multiDragClones.forEach(function (clone) {
4005 clone.parentNode && clone.parentNode.removeChild(clone);
4006 });
4007 }
4008 },
4009 nullingGlobal: function nullingGlobal() {
4010 this.isMultiDrag = dragStarted = false;
4011 multiDragClones.length = 0;
4012 },
4013 destroyGlobal: function destroyGlobal() {
4014 this._deselectMultiDrag();
4015 off(document, 'pointerup', this._deselectMultiDrag);
4016 off(document, 'mouseup', this._deselectMultiDrag);
4017 off(document, 'touchend', this._deselectMultiDrag);
4018 off(document, 'keydown', this._checkKeyDown);
4019 off(document, 'keyup', this._checkKeyUp);
4020 },
4021 _deselectMultiDrag: function _deselectMultiDrag(evt) {
4022 if (typeof dragStarted !== "undefined" && dragStarted) return;
4023
4024 // Only deselect if selection is in this sortable
4025 if (multiDragSortable !== this.sortable) return;
4026
4027 // Only deselect if target is not item in this sortable
4028 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
4029
4030 // Only deselect if left click
4031 if (evt && evt.button !== 0) return;
4032 while (multiDragElements.length) {
4033 var el = multiDragElements[0];
4034 toggleClass(el, this.options.selectedClass, false);
4035 multiDragElements.shift();
4036 dispatchEvent({
4037 sortable: this.sortable,
4038 rootEl: this.sortable.el,
4039 name: 'deselect',
4040 targetEl: el,
4041 originalEvent: evt
4042 });
4043 }
4044 },
4045 _checkKeyDown: function _checkKeyDown(evt) {
4046 if (evt.key === this.options.multiDragKey) {
4047 this.multiDragKeyDown = true;
4048 }
4049 },
4050 _checkKeyUp: function _checkKeyUp(evt) {
4051 if (evt.key === this.options.multiDragKey) {
4052 this.multiDragKeyDown = false;
4053 }
4054 }
4055 };
4056 return _extends(MultiDrag, {
4057 // Static methods & properties
4058 pluginName: 'multiDrag',
4059 utils: {
4060 /**
4061 * Selects the provided multi-drag item
4062 * @param {HTMLElement} el The element to be selected
4063 */
4064 select: function select(el) {
4065 var sortable = el.parentNode[expando];
4066 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
4067 if (multiDragSortable && multiDragSortable !== sortable) {
4068 multiDragSortable.multiDrag._deselectMultiDrag();
4069 multiDragSortable = sortable;
4070 }
4071 toggleClass(el, sortable.options.selectedClass, true);
4072 multiDragElements.push(el);
4073 },
4074 /**
4075 * Deselects the provided multi-drag item
4076 * @param {HTMLElement} el The element to be deselected
4077 */
4078 deselect: function deselect(el) {
4079 var sortable = el.parentNode[expando],
4080 index = multiDragElements.indexOf(el);
4081 if (!sortable || !sortable.options.multiDrag || !~index) return;
4082 toggleClass(el, sortable.options.selectedClass, false);
4083 multiDragElements.splice(index, 1);
4084 }
4085 },
4086 eventProperties: function eventProperties() {
4087 var _this3 = this;
4088 var oldIndicies = [],
4089 newIndicies = [];
4090 multiDragElements.forEach(function (multiDragElement) {
4091 oldIndicies.push({
4092 multiDragElement: multiDragElement,
4093 index: multiDragElement.sortableIndex
4094 });
4095
4096 // multiDragElements will already be sorted if folding
4097 var newIndex;
4098 if (folding && multiDragElement !== dragEl$1) {
4099 newIndex = -1;
4100 } else if (folding) {
4101 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
4102 } else {
4103 newIndex = index(multiDragElement);
4104 }
4105 newIndicies.push({
4106 multiDragElement: multiDragElement,
4107 index: newIndex
4108 });
4109 });
4110 return {
4111 items: _toConsumableArray(multiDragElements),
4112 clones: [].concat(multiDragClones),
4113 oldIndicies: oldIndicies,
4114 newIndicies: newIndicies
4115 };
4116 },
4117 optionListeners: {
4118 multiDragKey: function multiDragKey(key) {
4119 key = key.toLowerCase();
4120 if (key === 'ctrl') {
4121 key = 'Control';
4122 } else if (key.length > 1) {
4123 key = key.charAt(0).toUpperCase() + key.substr(1);
4124 }
4125 return key;
4126 }
4127 }
4128 });
4129 }
4130 function insertMultiDragElements(clonesInserted, rootEl) {
4131 multiDragElements.forEach(function (multiDragElement, i) {
4132 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
4133 if (target) {
4134 rootEl.insertBefore(multiDragElement, target);
4135 } else {
4136 rootEl.appendChild(multiDragElement);
4137 }
4138 });
4139 }
4140
4141 /**
4142 * Insert multi-drag clones
4143 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
4144 * @param {HTMLElement} rootEl
4145 */
4146 function insertMultiDragClones(elementsInserted, rootEl) {
4147 multiDragClones.forEach(function (clone, i) {
4148 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
4149 if (target) {
4150 rootEl.insertBefore(clone, target);
4151 } else {
4152 rootEl.appendChild(clone);
4153 }
4154 });
4155 }
4156 function removeMultiDragElements() {
4157 multiDragElements.forEach(function (multiDragElement) {
4158 if (multiDragElement === dragEl$1) return;
4159 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
4160 });
4161 }
4162
4163 Sortable.mount(new AutoScrollPlugin());
4164 Sortable.mount(Remove, Revert);
4165
4166 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
4167
4168
4169
4170 /***/ },
4171
4172 /***/ "./node_modules/toastify-js/src/toastify.css"
4173 /*!***************************************************!*\
4174 !*** ./node_modules/toastify-js/src/toastify.css ***!
4175 \***************************************************/
4176 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
4177
4178 "use strict";
4179 __webpack_require__.r(__webpack_exports__);
4180 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4181 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
4182 /* harmony export */ });
4183 /* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../../style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
4184 /* harmony import */ var _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);
4185 /* harmony import */ var _style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../../style-loader/dist/runtime/styleDomAPI.js */ "./node_modules/style-loader/dist/runtime/styleDomAPI.js");
4186 /* harmony import */ var _style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);
4187 /* harmony import */ var _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../../style-loader/dist/runtime/insertBySelector.js */ "./node_modules/style-loader/dist/runtime/insertBySelector.js");
4188 /* harmony import */ var _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);
4189 /* harmony import */ var _style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../../style-loader/dist/runtime/setAttributesWithoutAttributes.js */ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js");
4190 /* harmony import */ var _style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);
4191 /* harmony import */ var _style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../../style-loader/dist/runtime/insertStyleElement.js */ "./node_modules/style-loader/dist/runtime/insertStyleElement.js");
4192 /* harmony import */ var _style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);
4193 /* harmony import */ var _style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../../style-loader/dist/runtime/styleTagTransform.js */ "./node_modules/style-loader/dist/runtime/styleTagTransform.js");
4194 /* harmony import */ var _style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);
4195 /* harmony import */ var _css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../../css-loader/dist/cjs.js!./toastify.css */ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css");
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207 var options = {};
4208
4209 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
4210 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
4211
4212 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
4213
4214 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
4215 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
4216
4217 var update = _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"], options);
4218
4219
4220
4221
4222 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _css_loader_dist_cjs_js_toastify_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
4223
4224
4225 /***/ },
4226
4227 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
4228 /*!****************************************************************************!*\
4229 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
4230 \****************************************************************************/
4231 (module) {
4232
4233 "use strict";
4234
4235
4236 var stylesInDOM = [];
4237 function getIndexByIdentifier(identifier) {
4238 var result = -1;
4239 for (var i = 0; i < stylesInDOM.length; i++) {
4240 if (stylesInDOM[i].identifier === identifier) {
4241 result = i;
4242 break;
4243 }
4244 }
4245 return result;
4246 }
4247 function modulesToDom(list, options) {
4248 var idCountMap = {};
4249 var identifiers = [];
4250 for (var i = 0; i < list.length; i++) {
4251 var item = list[i];
4252 var id = options.base ? item[0] + options.base : item[0];
4253 var count = idCountMap[id] || 0;
4254 var identifier = "".concat(id, " ").concat(count);
4255 idCountMap[id] = count + 1;
4256 var indexByIdentifier = getIndexByIdentifier(identifier);
4257 var obj = {
4258 css: item[1],
4259 media: item[2],
4260 sourceMap: item[3],
4261 supports: item[4],
4262 layer: item[5]
4263 };
4264 if (indexByIdentifier !== -1) {
4265 stylesInDOM[indexByIdentifier].references++;
4266 stylesInDOM[indexByIdentifier].updater(obj);
4267 } else {
4268 var updater = addElementStyle(obj, options);
4269 options.byIndex = i;
4270 stylesInDOM.splice(i, 0, {
4271 identifier: identifier,
4272 updater: updater,
4273 references: 1
4274 });
4275 }
4276 identifiers.push(identifier);
4277 }
4278 return identifiers;
4279 }
4280 function addElementStyle(obj, options) {
4281 var api = options.domAPI(options);
4282 api.update(obj);
4283 var updater = function updater(newObj) {
4284 if (newObj) {
4285 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
4286 return;
4287 }
4288 api.update(obj = newObj);
4289 } else {
4290 api.remove();
4291 }
4292 };
4293 return updater;
4294 }
4295 module.exports = function (list, options) {
4296 options = options || {};
4297 list = list || [];
4298 var lastIdentifiers = modulesToDom(list, options);
4299 return function update(newList) {
4300 newList = newList || [];
4301 for (var i = 0; i < lastIdentifiers.length; i++) {
4302 var identifier = lastIdentifiers[i];
4303 var index = getIndexByIdentifier(identifier);
4304 stylesInDOM[index].references--;
4305 }
4306 var newLastIdentifiers = modulesToDom(newList, options);
4307 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
4308 var _identifier = lastIdentifiers[_i];
4309 var _index = getIndexByIdentifier(_identifier);
4310 if (stylesInDOM[_index].references === 0) {
4311 stylesInDOM[_index].updater();
4312 stylesInDOM.splice(_index, 1);
4313 }
4314 }
4315 lastIdentifiers = newLastIdentifiers;
4316 };
4317 };
4318
4319 /***/ },
4320
4321 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
4322 /*!********************************************************************!*\
4323 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
4324 \********************************************************************/
4325 (module) {
4326
4327 "use strict";
4328
4329
4330 var memo = {};
4331
4332 /* istanbul ignore next */
4333 function getTarget(target) {
4334 if (typeof memo[target] === "undefined") {
4335 var styleTarget = document.querySelector(target);
4336
4337 // Special case to return head of iframe instead of iframe itself
4338 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
4339 try {
4340 // This will throw an exception if access to iframe is blocked
4341 // due to cross-origin restrictions
4342 styleTarget = styleTarget.contentDocument.head;
4343 } catch (e) {
4344 // istanbul ignore next
4345 styleTarget = null;
4346 }
4347 }
4348 memo[target] = styleTarget;
4349 }
4350 return memo[target];
4351 }
4352
4353 /* istanbul ignore next */
4354 function insertBySelector(insert, style) {
4355 var target = getTarget(insert);
4356 if (!target) {
4357 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
4358 }
4359 target.appendChild(style);
4360 }
4361 module.exports = insertBySelector;
4362
4363 /***/ },
4364
4365 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
4366 /*!**********************************************************************!*\
4367 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
4368 \**********************************************************************/
4369 (module) {
4370
4371 "use strict";
4372
4373
4374 /* istanbul ignore next */
4375 function insertStyleElement(options) {
4376 var element = document.createElement("style");
4377 options.setAttributes(element, options.attributes);
4378 options.insert(element, options.options);
4379 return element;
4380 }
4381 module.exports = insertStyleElement;
4382
4383 /***/ },
4384
4385 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
4386 /*!**********************************************************************************!*\
4387 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
4388 \**********************************************************************************/
4389 (module, __unused_webpack_exports, __webpack_require__) {
4390
4391 "use strict";
4392
4393
4394 /* istanbul ignore next */
4395 function setAttributesWithoutAttributes(styleElement) {
4396 var nonce = true ? __webpack_require__.nc : 0;
4397 if (nonce) {
4398 styleElement.setAttribute("nonce", nonce);
4399 }
4400 }
4401 module.exports = setAttributesWithoutAttributes;
4402
4403 /***/ },
4404
4405 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
4406 /*!***************************************************************!*\
4407 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
4408 \***************************************************************/
4409 (module) {
4410
4411 "use strict";
4412
4413
4414 /* istanbul ignore next */
4415 function apply(styleElement, options, obj) {
4416 var css = "";
4417 if (obj.supports) {
4418 css += "@supports (".concat(obj.supports, ") {");
4419 }
4420 if (obj.media) {
4421 css += "@media ".concat(obj.media, " {");
4422 }
4423 var needLayer = typeof obj.layer !== "undefined";
4424 if (needLayer) {
4425 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
4426 }
4427 css += obj.css;
4428 if (needLayer) {
4429 css += "}";
4430 }
4431 if (obj.media) {
4432 css += "}";
4433 }
4434 if (obj.supports) {
4435 css += "}";
4436 }
4437 var sourceMap = obj.sourceMap;
4438 if (sourceMap && typeof btoa !== "undefined") {
4439 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
4440 }
4441
4442 // For old IE
4443 /* istanbul ignore if */
4444 options.styleTagTransform(css, styleElement, options.options);
4445 }
4446 function removeStyleElement(styleElement) {
4447 // istanbul ignore if
4448 if (styleElement.parentNode === null) {
4449 return false;
4450 }
4451 styleElement.parentNode.removeChild(styleElement);
4452 }
4453
4454 /* istanbul ignore next */
4455 function domAPI(options) {
4456 if (typeof document === "undefined") {
4457 return {
4458 update: function update() {},
4459 remove: function remove() {}
4460 };
4461 }
4462 var styleElement = options.insertStyleElement(options);
4463 return {
4464 update: function update(obj) {
4465 apply(styleElement, options, obj);
4466 },
4467 remove: function remove() {
4468 removeStyleElement(styleElement);
4469 }
4470 };
4471 }
4472 module.exports = domAPI;
4473
4474 /***/ },
4475
4476 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
4477 /*!*********************************************************************!*\
4478 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
4479 \*********************************************************************/
4480 (module) {
4481
4482 "use strict";
4483
4484
4485 /* istanbul ignore next */
4486 function styleTagTransform(css, styleElement) {
4487 if (styleElement.styleSheet) {
4488 styleElement.styleSheet.cssText = css;
4489 } else {
4490 while (styleElement.firstChild) {
4491 styleElement.removeChild(styleElement.firstChild);
4492 }
4493 styleElement.appendChild(document.createTextNode(css));
4494 }
4495 }
4496 module.exports = styleTagTransform;
4497
4498 /***/ },
4499
4500 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
4501 /*!**********************************************************!*\
4502 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
4503 \**********************************************************/
4504 (module) {
4505
4506 /*!
4507 * sweetalert2 v11.26.17
4508 * Released under the MIT License.
4509 */
4510 (function (global, factory) {
4511 true ? module.exports = factory() :
4512 0;
4513 })(this, (function () { 'use strict';
4514
4515 function _assertClassBrand(e, t, n) {
4516 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
4517 throw new TypeError("Private element is not present on this object");
4518 }
4519 function _checkPrivateRedeclaration(e, t) {
4520 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
4521 }
4522 function _classPrivateFieldGet2(s, a) {
4523 return s.get(_assertClassBrand(s, a));
4524 }
4525 function _classPrivateFieldInitSpec(e, t, a) {
4526 _checkPrivateRedeclaration(e, t), t.set(e, a);
4527 }
4528 function _classPrivateFieldSet2(s, a, r) {
4529 return s.set(_assertClassBrand(s, a), r), r;
4530 }
4531
4532 const RESTORE_FOCUS_TIMEOUT = 100;
4533
4534 /** @type {GlobalState} */
4535 const globalState = {};
4536 const focusPreviousActiveElement = () => {
4537 if (globalState.previousActiveElement instanceof HTMLElement) {
4538 globalState.previousActiveElement.focus();
4539 globalState.previousActiveElement = null;
4540 } else if (document.body) {
4541 document.body.focus();
4542 }
4543 };
4544
4545 /**
4546 * Restore previous active (focused) element
4547 *
4548 * @param {boolean} returnFocus
4549 * @returns {Promise<void>}
4550 */
4551 const restoreActiveElement = returnFocus => {
4552 return new Promise(resolve => {
4553 if (!returnFocus) {
4554 return resolve();
4555 }
4556 const x = window.scrollX;
4557 const y = window.scrollY;
4558 globalState.restoreFocusTimeout = setTimeout(() => {
4559 focusPreviousActiveElement();
4560 resolve();
4561 }, RESTORE_FOCUS_TIMEOUT); // issues/900
4562
4563 window.scrollTo(x, y);
4564 });
4565 };
4566
4567 const swalPrefix = 'swal2-';
4568
4569 /**
4570 * @typedef {Record<SwalClass, string>} SwalClasses
4571 */
4572
4573 /**
4574 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
4575 * @typedef {Record<SwalIcon, string>} SwalIcons
4576 */
4577
4578 /** @type {SwalClass[]} */
4579 const classNames = ['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'footer', 'icon', 'icon-content', 'image', 'input', 'file', 'range', 'select', 'radio', 'checkbox', 'label', 'textarea', 'inputerror', 'input-label', 'validation-message', 'progress-steps', 'active-progress-step', 'progress-step', 'progress-step-line', 'loader', 'loading', 'styled', 'top', 'top-start', 'top-end', 'top-left', 'top-right', 'center', 'center-start', 'center-end', 'center-left', 'center-right', 'bottom', 'bottom-start', 'bottom-end', 'bottom-left', 'bottom-right', 'grow-row', 'grow-column', 'grow-fullscreen', 'rtl', 'timer-progress-bar', 'timer-progress-bar-container', 'scrollbar-measure', 'icon-success', 'icon-warning', 'icon-info', 'icon-question', 'icon-error', 'draggable', 'dragging'];
4580 const swalClasses = classNames.reduce((acc, className) => {
4581 acc[className] = swalPrefix + className;
4582 return acc;
4583 }, /** @type {SwalClasses} */{});
4584
4585 /** @type {SwalIcon[]} */
4586 const icons = ['success', 'warning', 'info', 'question', 'error'];
4587 const iconTypes = icons.reduce((acc, icon) => {
4588 acc[icon] = swalPrefix + icon;
4589 return acc;
4590 }, /** @type {SwalIcons} */{});
4591
4592 const consolePrefix = 'SweetAlert2:';
4593
4594 /**
4595 * Capitalize the first letter of a string
4596 *
4597 * @param {string} str
4598 * @returns {string}
4599 */
4600 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
4601
4602 /**
4603 * Standardize console warnings
4604 *
4605 * @param {string | string[]} message
4606 */
4607 const warn = message => {
4608 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
4609 };
4610
4611 /**
4612 * Standardize console errors
4613 *
4614 * @param {string} message
4615 */
4616 const error = message => {
4617 console.error(`${consolePrefix} ${message}`);
4618 };
4619
4620 /**
4621 * Private global state for `warnOnce`
4622 *
4623 * @type {string[]}
4624 * @private
4625 */
4626 const previousWarnOnceMessages = [];
4627
4628 /**
4629 * Show a console warning, but only if it hasn't already been shown
4630 *
4631 * @param {string} message
4632 */
4633 const warnOnce = message => {
4634 if (!previousWarnOnceMessages.includes(message)) {
4635 previousWarnOnceMessages.push(message);
4636 warn(message);
4637 }
4638 };
4639
4640 /**
4641 * Show a one-time console warning about deprecated params/methods
4642 *
4643 * @param {string} deprecatedParam
4644 * @param {string?} useInstead
4645 */
4646 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
4647 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
4648 };
4649
4650 /**
4651 * If `arg` is a function, call it (with no arguments or context) and return the result.
4652 * Otherwise, just pass the value through
4653 *
4654 * @param {(() => *) | *} arg
4655 * @returns {*}
4656 */
4657 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
4658
4659 /**
4660 * @param {*} arg
4661 * @returns {boolean}
4662 */
4663 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
4664
4665 /**
4666 * @param {*} arg
4667 * @returns {Promise<*>}
4668 */
4669 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
4670
4671 /**
4672 * @param {*} arg
4673 * @returns {boolean}
4674 */
4675 const isPromise = arg => arg && Promise.resolve(arg) === arg;
4676
4677 /**
4678 * Gets the popup container which contains the backdrop and the popup itself.
4679 *
4680 * @returns {HTMLElement | null}
4681 */
4682 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
4683
4684 /**
4685 * @param {string} selectorString
4686 * @returns {HTMLElement | null}
4687 */
4688 const elementBySelector = selectorString => {
4689 const container = getContainer();
4690 return container ? container.querySelector(selectorString) : null;
4691 };
4692
4693 /**
4694 * @param {string} className
4695 * @returns {HTMLElement | null}
4696 */
4697 const elementByClass = className => {
4698 return elementBySelector(`.${className}`);
4699 };
4700
4701 /**
4702 * @returns {HTMLElement | null}
4703 */
4704 const getPopup = () => elementByClass(swalClasses.popup);
4705
4706 /**
4707 * @returns {HTMLElement | null}
4708 */
4709 const getIcon = () => elementByClass(swalClasses.icon);
4710
4711 /**
4712 * @returns {HTMLElement | null}
4713 */
4714 const getIconContent = () => elementByClass(swalClasses['icon-content']);
4715
4716 /**
4717 * @returns {HTMLElement | null}
4718 */
4719 const getTitle = () => elementByClass(swalClasses.title);
4720
4721 /**
4722 * @returns {HTMLElement | null}
4723 */
4724 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
4725
4726 /**
4727 * @returns {HTMLElement | null}
4728 */
4729 const getImage = () => elementByClass(swalClasses.image);
4730
4731 /**
4732 * @returns {HTMLElement | null}
4733 */
4734 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
4735
4736 /**
4737 * @returns {HTMLElement | null}
4738 */
4739 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
4740
4741 /**
4742 * @returns {HTMLButtonElement | null}
4743 */
4744 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
4745
4746 /**
4747 * @returns {HTMLButtonElement | null}
4748 */
4749 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
4750
4751 /**
4752 * @returns {HTMLButtonElement | null}
4753 */
4754 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
4755
4756 /**
4757 * @returns {HTMLElement | null}
4758 */
4759 const getInputLabel = () => elementByClass(swalClasses['input-label']);
4760
4761 /**
4762 * @returns {HTMLElement | null}
4763 */
4764 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
4765
4766 /**
4767 * @returns {HTMLElement | null}
4768 */
4769 const getActions = () => elementByClass(swalClasses.actions);
4770
4771 /**
4772 * @returns {HTMLElement | null}
4773 */
4774 const getFooter = () => elementByClass(swalClasses.footer);
4775
4776 /**
4777 * @returns {HTMLElement | null}
4778 */
4779 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
4780
4781 /**
4782 * @returns {HTMLElement | null}
4783 */
4784 const getCloseButton = () => elementByClass(swalClasses.close);
4785
4786 // https://github.com/jkup/focusable/blob/master/index.js
4787 const focusable = `
4788 a[href],
4789 area[href],
4790 input:not([disabled]),
4791 select:not([disabled]),
4792 textarea:not([disabled]),
4793 button:not([disabled]),
4794 iframe,
4795 object,
4796 embed,
4797 [tabindex="0"],
4798 [contenteditable],
4799 audio[controls],
4800 video[controls],
4801 summary
4802 `;
4803 /**
4804 * @returns {HTMLElement[]}
4805 */
4806 const getFocusableElements = () => {
4807 const popup = getPopup();
4808 if (!popup) {
4809 return [];
4810 }
4811 /** @type {NodeListOf<HTMLElement>} */
4812 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
4813 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
4814 // sort according to tabindex
4815 .sort((a, b) => {
4816 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
4817 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
4818 if (tabindexA > tabindexB) {
4819 return 1;
4820 } else if (tabindexA < tabindexB) {
4821 return -1;
4822 }
4823 return 0;
4824 });
4825
4826 /** @type {NodeListOf<HTMLElement>} */
4827 const otherFocusableElements = popup.querySelectorAll(focusable);
4828 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
4829 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
4830 };
4831
4832 /**
4833 * @returns {boolean}
4834 */
4835 const isModal = () => {
4836 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
4837 };
4838
4839 /**
4840 * @returns {boolean}
4841 */
4842 const isToast = () => {
4843 const popup = getPopup();
4844 if (!popup) {
4845 return false;
4846 }
4847 return hasClass(popup, swalClasses.toast);
4848 };
4849
4850 /**
4851 * @returns {boolean}
4852 */
4853 const isLoading = () => {
4854 const popup = getPopup();
4855 if (!popup) {
4856 return false;
4857 }
4858 return popup.hasAttribute('data-loading');
4859 };
4860
4861 /**
4862 * Securely set innerHTML of an element
4863 * https://github.com/sweetalert2/sweetalert2/issues/1926
4864 *
4865 * @param {HTMLElement} elem
4866 * @param {string} html
4867 */
4868 const setInnerHtml = (elem, html) => {
4869 elem.textContent = '';
4870 if (html) {
4871 const parser = new DOMParser();
4872 const parsed = parser.parseFromString(html, `text/html`);
4873 const head = parsed.querySelector('head');
4874 if (head) {
4875 Array.from(head.childNodes).forEach(child => {
4876 elem.appendChild(child);
4877 });
4878 }
4879 const body = parsed.querySelector('body');
4880 if (body) {
4881 Array.from(body.childNodes).forEach(child => {
4882 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
4883 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
4884 } else {
4885 elem.appendChild(child);
4886 }
4887 });
4888 }
4889 }
4890 };
4891
4892 /**
4893 * @param {HTMLElement} elem
4894 * @param {string} className
4895 * @returns {boolean}
4896 */
4897 const hasClass = (elem, className) => {
4898 if (!className) {
4899 return false;
4900 }
4901 const classList = className.split(/\s+/);
4902 for (let i = 0; i < classList.length; i++) {
4903 if (!elem.classList.contains(classList[i])) {
4904 return false;
4905 }
4906 }
4907 return true;
4908 };
4909
4910 /**
4911 * @param {HTMLElement} elem
4912 * @param {SweetAlertOptions} params
4913 */
4914 const removeCustomClasses = (elem, params) => {
4915 Array.from(elem.classList).forEach(className => {
4916 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
4917 elem.classList.remove(className);
4918 }
4919 });
4920 };
4921
4922 /**
4923 * @param {HTMLElement} elem
4924 * @param {SweetAlertOptions} params
4925 * @param {string} className
4926 */
4927 const applyCustomClass = (elem, params, className) => {
4928 removeCustomClasses(elem, params);
4929 if (!params.customClass) {
4930 return;
4931 }
4932 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
4933 if (!customClass) {
4934 return;
4935 }
4936 if (typeof customClass !== 'string' && !customClass.forEach) {
4937 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
4938 return;
4939 }
4940 addClass(elem, customClass);
4941 };
4942
4943 /**
4944 * @param {HTMLElement} popup
4945 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
4946 * @returns {HTMLInputElement | null}
4947 */
4948 const getInput$1 = (popup, inputClass) => {
4949 if (!inputClass) {
4950 return null;
4951 }
4952 switch (inputClass) {
4953 case 'select':
4954 case 'textarea':
4955 case 'file':
4956 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
4957 case 'checkbox':
4958 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
4959 case 'radio':
4960 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
4961 case 'range':
4962 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
4963 default:
4964 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
4965 }
4966 };
4967
4968 /**
4969 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
4970 */
4971 const focusInput = input => {
4972 input.focus();
4973
4974 // place cursor at end of text in text input
4975 if (input.type !== 'file') {
4976 // http://stackoverflow.com/a/2345915
4977 const val = input.value;
4978 input.value = '';
4979 input.value = val;
4980 }
4981 };
4982
4983 /**
4984 * @param {HTMLElement | HTMLElement[] | null} target
4985 * @param {string | string[] | readonly string[] | undefined} classList
4986 * @param {boolean} condition
4987 */
4988 const toggleClass = (target, classList, condition) => {
4989 if (!target || !classList) {
4990 return;
4991 }
4992 if (typeof classList === 'string') {
4993 classList = classList.split(/\s+/).filter(Boolean);
4994 }
4995 classList.forEach(className => {
4996 if (Array.isArray(target)) {
4997 target.forEach(elem => {
4998 if (condition) {
4999 elem.classList.add(className);
5000 } else {
5001 elem.classList.remove(className);
5002 }
5003 });
5004 } else {
5005 if (condition) {
5006 target.classList.add(className);
5007 } else {
5008 target.classList.remove(className);
5009 }
5010 }
5011 });
5012 };
5013
5014 /**
5015 * @param {HTMLElement | HTMLElement[] | null} target
5016 * @param {string | string[] | readonly string[] | undefined} classList
5017 */
5018 const addClass = (target, classList) => {
5019 toggleClass(target, classList, true);
5020 };
5021
5022 /**
5023 * @param {HTMLElement | HTMLElement[] | null} target
5024 * @param {string | string[] | readonly string[] | undefined} classList
5025 */
5026 const removeClass = (target, classList) => {
5027 toggleClass(target, classList, false);
5028 };
5029
5030 /**
5031 * Get direct child of an element by class name
5032 *
5033 * @param {HTMLElement} elem
5034 * @param {string} className
5035 * @returns {HTMLElement | undefined}
5036 */
5037 const getDirectChildByClass = (elem, className) => {
5038 const children = Array.from(elem.children);
5039 for (let i = 0; i < children.length; i++) {
5040 const child = children[i];
5041 if (child instanceof HTMLElement && hasClass(child, className)) {
5042 return child;
5043 }
5044 }
5045 };
5046
5047 /**
5048 * @param {HTMLElement} elem
5049 * @param {string} property
5050 * @param {string | number | null | undefined} value
5051 */
5052 const applyNumericalStyle = (elem, property, value) => {
5053 if (value === `${parseInt(`${value}`)}`) {
5054 value = parseInt(value);
5055 }
5056 if (value || parseInt(`${value}`) === 0) {
5057 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
5058 } else {
5059 elem.style.removeProperty(property);
5060 }
5061 };
5062
5063 /**
5064 * @param {HTMLElement | null} elem
5065 * @param {string} display
5066 */
5067 const show = (elem, display = 'flex') => {
5068 if (!elem) {
5069 return;
5070 }
5071 elem.style.display = display;
5072 };
5073
5074 /**
5075 * @param {HTMLElement | null} elem
5076 */
5077 const hide = elem => {
5078 if (!elem) {
5079 return;
5080 }
5081 elem.style.display = 'none';
5082 };
5083
5084 /**
5085 * @param {HTMLElement | null} elem
5086 * @param {string} display
5087 */
5088 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
5089 if (!elem) {
5090 return;
5091 }
5092 new MutationObserver(() => {
5093 toggle(elem, elem.innerHTML, display);
5094 }).observe(elem, {
5095 childList: true,
5096 subtree: true
5097 });
5098 };
5099
5100 /**
5101 * @param {HTMLElement} parent
5102 * @param {string} selector
5103 * @param {string} property
5104 * @param {string} value
5105 */
5106 const setStyle = (parent, selector, property, value) => {
5107 /** @type {HTMLElement | null} */
5108 const el = parent.querySelector(selector);
5109 if (el) {
5110 el.style.setProperty(property, value);
5111 }
5112 };
5113
5114 /**
5115 * @param {HTMLElement} elem
5116 * @param {boolean | string | null | undefined} condition
5117 * @param {string} display
5118 */
5119 const toggle = (elem, condition, display = 'flex') => {
5120 if (condition) {
5121 show(elem, display);
5122 } else {
5123 hide(elem);
5124 }
5125 };
5126
5127 /**
5128 * borrowed from jquery $(elem).is(':visible') implementation
5129 *
5130 * @param {HTMLElement | null} elem
5131 * @returns {boolean}
5132 */
5133 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
5134
5135 /**
5136 * @returns {boolean}
5137 */
5138 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
5139
5140 /**
5141 * @param {HTMLElement} elem
5142 * @returns {boolean}
5143 */
5144 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
5145
5146 /**
5147 * @param {HTMLElement} element
5148 * @param {HTMLElement} stopElement
5149 * @returns {boolean}
5150 */
5151 const selfOrParentIsScrollable = (element, stopElement) => {
5152 let parent = /** @type {HTMLElement | null} */element;
5153 while (parent && parent !== stopElement) {
5154 if (isScrollable(parent)) {
5155 return true;
5156 }
5157 parent = parent.parentElement;
5158 }
5159 return false;
5160 };
5161
5162 /**
5163 * borrowed from https://stackoverflow.com/a/46352119
5164 *
5165 * @param {HTMLElement} elem
5166 * @returns {boolean}
5167 */
5168 const hasCssAnimation = elem => {
5169 const style = window.getComputedStyle(elem);
5170 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
5171 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
5172 return animDuration > 0 || transDuration > 0;
5173 };
5174
5175 /**
5176 * @param {number} timer
5177 * @param {boolean} reset
5178 */
5179 const animateTimerProgressBar = (timer, reset = false) => {
5180 const timerProgressBar = getTimerProgressBar();
5181 if (!timerProgressBar) {
5182 return;
5183 }
5184 if (isVisible$1(timerProgressBar)) {
5185 if (reset) {
5186 timerProgressBar.style.transition = 'none';
5187 timerProgressBar.style.width = '100%';
5188 }
5189 setTimeout(() => {
5190 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
5191 timerProgressBar.style.width = '0%';
5192 }, 10);
5193 }
5194 };
5195 const stopTimerProgressBar = () => {
5196 const timerProgressBar = getTimerProgressBar();
5197 if (!timerProgressBar) {
5198 return;
5199 }
5200 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
5201 timerProgressBar.style.removeProperty('transition');
5202 timerProgressBar.style.width = '100%';
5203 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
5204 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
5205 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
5206 };
5207
5208 /**
5209 * Detect Node env
5210 *
5211 * @returns {boolean}
5212 */
5213 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
5214
5215 const sweetHTML = `
5216 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
5217 <button type="button" class="${swalClasses.close}"></button>
5218 <ul class="${swalClasses['progress-steps']}"></ul>
5219 <div class="${swalClasses.icon}"></div>
5220 <img class="${swalClasses.image}" />
5221 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
5222 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
5223 <input class="${swalClasses.input}" id="${swalClasses.input}" />
5224 <input type="file" class="${swalClasses.file}" />
5225 <div class="${swalClasses.range}">
5226 <input type="range" />
5227 <output></output>
5228 </div>
5229 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
5230 <div class="${swalClasses.radio}"></div>
5231 <label class="${swalClasses.checkbox}">
5232 <input type="checkbox" id="${swalClasses.checkbox}" />
5233 <span class="${swalClasses.label}"></span>
5234 </label>
5235 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
5236 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
5237 <div class="${swalClasses.actions}">
5238 <div class="${swalClasses.loader}"></div>
5239 <button type="button" class="${swalClasses.confirm}"></button>
5240 <button type="button" class="${swalClasses.deny}"></button>
5241 <button type="button" class="${swalClasses.cancel}"></button>
5242 </div>
5243 <div class="${swalClasses.footer}"></div>
5244 <div class="${swalClasses['timer-progress-bar-container']}">
5245 <div class="${swalClasses['timer-progress-bar']}"></div>
5246 </div>
5247 </div>
5248 `.replace(/(^|\n)\s*/g, '');
5249
5250 /**
5251 * @returns {boolean}
5252 */
5253 const resetOldContainer = () => {
5254 const oldContainer = getContainer();
5255 if (!oldContainer) {
5256 return false;
5257 }
5258 oldContainer.remove();
5259 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
5260 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
5261 swalClasses['has-column']]);
5262 return true;
5263 };
5264 const resetValidationMessage$1 = () => {
5265 if (globalState.currentInstance) {
5266 globalState.currentInstance.resetValidationMessage();
5267 }
5268 };
5269 const addInputChangeListeners = () => {
5270 const popup = getPopup();
5271 if (!popup) {
5272 return;
5273 }
5274 const input = getDirectChildByClass(popup, swalClasses.input);
5275 const file = getDirectChildByClass(popup, swalClasses.file);
5276 /** @type {HTMLInputElement | null} */
5277 const range = popup.querySelector(`.${swalClasses.range} input`);
5278 /** @type {HTMLOutputElement | null} */
5279 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
5280 const select = getDirectChildByClass(popup, swalClasses.select);
5281 /** @type {HTMLInputElement | null} */
5282 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
5283 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
5284 if (input) {
5285 input.oninput = resetValidationMessage$1;
5286 }
5287 if (file) {
5288 file.onchange = resetValidationMessage$1;
5289 }
5290 if (select) {
5291 select.onchange = resetValidationMessage$1;
5292 }
5293 if (checkbox) {
5294 checkbox.onchange = resetValidationMessage$1;
5295 }
5296 if (textarea) {
5297 textarea.oninput = resetValidationMessage$1;
5298 }
5299 if (range && rangeOutput) {
5300 range.oninput = () => {
5301 resetValidationMessage$1();
5302 rangeOutput.value = range.value;
5303 };
5304 range.onchange = () => {
5305 resetValidationMessage$1();
5306 rangeOutput.value = range.value;
5307 };
5308 }
5309 };
5310
5311 /**
5312 * @param {string | HTMLElement} target
5313 * @returns {HTMLElement}
5314 */
5315 const getTarget = target => {
5316 if (typeof target === 'string') {
5317 const element = document.querySelector(target);
5318 if (!element) {
5319 throw new Error(`Target element "${target}" not found`);
5320 }
5321 return /** @type {HTMLElement} */element;
5322 }
5323 return target;
5324 };
5325
5326 /**
5327 * @param {SweetAlertOptions} params
5328 */
5329 const setupAccessibility = params => {
5330 const popup = getPopup();
5331 if (!popup) {
5332 return;
5333 }
5334 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
5335 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
5336 if (!params.toast) {
5337 popup.setAttribute('aria-modal', 'true');
5338 }
5339 };
5340
5341 /**
5342 * @param {HTMLElement} targetElement
5343 */
5344 const setupRTL = targetElement => {
5345 if (window.getComputedStyle(targetElement).direction === 'rtl') {
5346 addClass(getContainer(), swalClasses.rtl);
5347 globalState.isRTL = true;
5348 }
5349 };
5350
5351 /**
5352 * Add modal + backdrop to DOM
5353 *
5354 * @param {SweetAlertOptions} params
5355 */
5356 const init = params => {
5357 // Clean up the old popup container if it exists
5358 const oldContainerExisted = resetOldContainer();
5359 if (isNodeEnv()) {
5360 error('SweetAlert2 requires document to initialize');
5361 return;
5362 }
5363 const container = document.createElement('div');
5364 container.className = swalClasses.container;
5365 if (oldContainerExisted) {
5366 addClass(container, swalClasses['no-transition']);
5367 }
5368 setInnerHtml(container, sweetHTML);
5369 container.dataset['swal2Theme'] = params.theme;
5370 const targetElement = getTarget(params.target || 'body');
5371 targetElement.appendChild(container);
5372 if (params.topLayer) {
5373 container.setAttribute('popover', '');
5374 container.showPopover();
5375 }
5376 setupAccessibility(params);
5377 setupRTL(targetElement);
5378 addInputChangeListeners();
5379 };
5380
5381 /**
5382 * @param {HTMLElement | object | string} param
5383 * @param {HTMLElement} target
5384 */
5385 const parseHtmlToContainer = (param, target) => {
5386 // DOM element
5387 if (param instanceof HTMLElement) {
5388 target.appendChild(param);
5389 }
5390
5391 // Object
5392 else if (typeof param === 'object') {
5393 handleObject(param, target);
5394 }
5395
5396 // Plain string
5397 else if (param) {
5398 setInnerHtml(target, param);
5399 }
5400 };
5401
5402 /**
5403 * @param {object} param
5404 * @param {HTMLElement} target
5405 */
5406 const handleObject = (param, target) => {
5407 // JQuery element(s)
5408 if ('jquery' in param) {
5409 handleJqueryElem(target, param);
5410 }
5411
5412 // For other objects use their string representation
5413 else {
5414 setInnerHtml(target, param.toString());
5415 }
5416 };
5417
5418 /**
5419 * @param {HTMLElement} target
5420 * @param {any} elem
5421 */
5422 const handleJqueryElem = (target, elem) => {
5423 target.textContent = '';
5424 if (0 in elem) {
5425 for (let i = 0; i in elem; i++) {
5426 target.appendChild(elem[i].cloneNode(true));
5427 }
5428 } else {
5429 target.appendChild(elem.cloneNode(true));
5430 }
5431 };
5432
5433 /**
5434 * @param {SweetAlert} instance
5435 * @param {SweetAlertOptions} params
5436 */
5437 const renderActions = (instance, params) => {
5438 const actions = getActions();
5439 const loader = getLoader();
5440 if (!actions || !loader) {
5441 return;
5442 }
5443
5444 // Actions (buttons) wrapper
5445 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
5446 hide(actions);
5447 } else {
5448 show(actions);
5449 }
5450
5451 // Custom class
5452 applyCustomClass(actions, params, 'actions');
5453
5454 // Render all the buttons
5455 renderButtons(actions, loader, params);
5456
5457 // Loader
5458 setInnerHtml(loader, params.loaderHtml || '');
5459 applyCustomClass(loader, params, 'loader');
5460 };
5461
5462 /**
5463 * @param {HTMLElement} actions
5464 * @param {HTMLElement} loader
5465 * @param {SweetAlertOptions} params
5466 */
5467 function renderButtons(actions, loader, params) {
5468 const confirmButton = getConfirmButton();
5469 const denyButton = getDenyButton();
5470 const cancelButton = getCancelButton();
5471 if (!confirmButton || !denyButton || !cancelButton) {
5472 return;
5473 }
5474
5475 // Render buttons
5476 renderButton(confirmButton, 'confirm', params);
5477 renderButton(denyButton, 'deny', params);
5478 renderButton(cancelButton, 'cancel', params);
5479 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
5480 if (params.reverseButtons) {
5481 if (params.toast) {
5482 actions.insertBefore(cancelButton, confirmButton);
5483 actions.insertBefore(denyButton, confirmButton);
5484 } else {
5485 actions.insertBefore(cancelButton, loader);
5486 actions.insertBefore(denyButton, loader);
5487 actions.insertBefore(confirmButton, loader);
5488 }
5489 }
5490 }
5491
5492 /**
5493 * @param {HTMLElement} confirmButton
5494 * @param {HTMLElement} denyButton
5495 * @param {HTMLElement} cancelButton
5496 * @param {SweetAlertOptions} params
5497 */
5498 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
5499 if (!params.buttonsStyling) {
5500 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
5501 return;
5502 }
5503 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
5504
5505 // Apply custom background colors to action buttons
5506 if (params.confirmButtonColor) {
5507 confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
5508 }
5509 if (params.denyButtonColor) {
5510 denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
5511 }
5512 if (params.cancelButtonColor) {
5513 cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
5514 }
5515
5516 // Apply the outline color to action buttons
5517 applyOutlineColor(confirmButton);
5518 applyOutlineColor(denyButton);
5519 applyOutlineColor(cancelButton);
5520 }
5521
5522 /**
5523 * @param {HTMLElement} button
5524 */
5525 function applyOutlineColor(button) {
5526 const buttonStyle = window.getComputedStyle(button);
5527 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
5528 // If the button already has a custom outline color, no need to change it
5529 return;
5530 }
5531 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
5532 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
5533 }
5534
5535 /**
5536 * @param {HTMLElement} button
5537 * @param {'confirm' | 'deny' | 'cancel'} buttonType
5538 * @param {SweetAlertOptions} params
5539 */
5540 function renderButton(button, buttonType, params) {
5541 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
5542 toggle(button, params[`show${buttonName}Button`], 'inline-block');
5543 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
5544 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
5545
5546 // Add buttons custom classes
5547 button.className = swalClasses[buttonType];
5548 applyCustomClass(button, params, `${buttonType}Button`);
5549 }
5550
5551 /**
5552 * @param {SweetAlert} instance
5553 * @param {SweetAlertOptions} params
5554 */
5555 const renderCloseButton = (instance, params) => {
5556 const closeButton = getCloseButton();
5557 if (!closeButton) {
5558 return;
5559 }
5560 setInnerHtml(closeButton, params.closeButtonHtml || '');
5561
5562 // Custom class
5563 applyCustomClass(closeButton, params, 'closeButton');
5564 toggle(closeButton, params.showCloseButton);
5565 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
5566 };
5567
5568 /**
5569 * @param {SweetAlert} instance
5570 * @param {SweetAlertOptions} params
5571 */
5572 const renderContainer = (instance, params) => {
5573 const container = getContainer();
5574 if (!container) {
5575 return;
5576 }
5577 handleBackdropParam(container, params.backdrop);
5578 handlePositionParam(container, params.position);
5579 handleGrowParam(container, params.grow);
5580
5581 // Custom class
5582 applyCustomClass(container, params, 'container');
5583 };
5584
5585 /**
5586 * @param {HTMLElement} container
5587 * @param {SweetAlertOptions['backdrop']} backdrop
5588 */
5589 function handleBackdropParam(container, backdrop) {
5590 if (typeof backdrop === 'string') {
5591 container.style.background = backdrop;
5592 } else if (!backdrop) {
5593 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
5594 }
5595 }
5596
5597 /**
5598 * @param {HTMLElement} container
5599 * @param {SweetAlertOptions['position']} position
5600 */
5601 function handlePositionParam(container, position) {
5602 if (!position) {
5603 return;
5604 }
5605 if (position in swalClasses) {
5606 addClass(container, swalClasses[position]);
5607 } else {
5608 warn('The "position" parameter is not valid, defaulting to "center"');
5609 addClass(container, swalClasses.center);
5610 }
5611 }
5612
5613 /**
5614 * @param {HTMLElement} container
5615 * @param {SweetAlertOptions['grow']} grow
5616 */
5617 function handleGrowParam(container, grow) {
5618 if (!grow) {
5619 return;
5620 }
5621 addClass(container, swalClasses[`grow-${grow}`]);
5622 }
5623
5624 /**
5625 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
5626 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
5627 * This is the approach that Babel will probably take to implement private methods/fields
5628 * https://github.com/tc39/proposal-private-methods
5629 * https://github.com/babel/babel/pull/7555
5630 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
5631 * then we can use that language feature.
5632 */
5633
5634 var privateProps = {
5635 innerParams: new WeakMap(),
5636 domCache: new WeakMap()
5637 };
5638
5639 /// <reference path="../../../../sweetalert2.d.ts"/>
5640
5641
5642 /** @type {InputClass[]} */
5643 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
5644
5645 /**
5646 * @param {SweetAlert} instance
5647 * @param {SweetAlertOptions} params
5648 */
5649 const renderInput = (instance, params) => {
5650 const popup = getPopup();
5651 if (!popup) {
5652 return;
5653 }
5654 const innerParams = privateProps.innerParams.get(instance);
5655 const rerender = !innerParams || params.input !== innerParams.input;
5656 inputClasses.forEach(inputClass => {
5657 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
5658 if (!inputContainer) {
5659 return;
5660 }
5661
5662 // set attributes
5663 setAttributes(inputClass, params.inputAttributes);
5664
5665 // set class
5666 inputContainer.className = swalClasses[inputClass];
5667 if (rerender) {
5668 hide(inputContainer);
5669 }
5670 });
5671 if (params.input) {
5672 if (rerender) {
5673 showInput(params);
5674 }
5675 // set custom class
5676 setCustomClass(params);
5677 }
5678 };
5679
5680 /**
5681 * @param {SweetAlertOptions} params
5682 */
5683 const showInput = params => {
5684 if (!params.input) {
5685 return;
5686 }
5687 if (!renderInputType[params.input]) {
5688 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
5689 return;
5690 }
5691 const inputContainer = getInputContainer(params.input);
5692 if (!inputContainer) {
5693 return;
5694 }
5695 const input = renderInputType[params.input](inputContainer, params);
5696 show(inputContainer);
5697
5698 // input autofocus
5699 if (params.inputAutoFocus) {
5700 setTimeout(() => {
5701 focusInput(input);
5702 });
5703 }
5704 };
5705
5706 /**
5707 * @param {HTMLInputElement} input
5708 */
5709 const removeAttributes = input => {
5710 for (let i = 0; i < input.attributes.length; i++) {
5711 const attrName = input.attributes[i].name;
5712 if (!['id', 'type', 'value', 'style'].includes(attrName)) {
5713 input.removeAttribute(attrName);
5714 }
5715 }
5716 };
5717
5718 /**
5719 * @param {InputClass} inputClass
5720 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
5721 */
5722 const setAttributes = (inputClass, inputAttributes) => {
5723 const popup = getPopup();
5724 if (!popup) {
5725 return;
5726 }
5727 const input = getInput$1(popup, inputClass);
5728 if (!input) {
5729 return;
5730 }
5731 removeAttributes(input);
5732 for (const attr in inputAttributes) {
5733 input.setAttribute(attr, inputAttributes[attr]);
5734 }
5735 };
5736
5737 /**
5738 * @param {SweetAlertOptions} params
5739 */
5740 const setCustomClass = params => {
5741 if (!params.input) {
5742 return;
5743 }
5744 const inputContainer = getInputContainer(params.input);
5745 if (inputContainer) {
5746 applyCustomClass(inputContainer, params, 'input');
5747 }
5748 };
5749
5750 /**
5751 * @param {HTMLInputElement | HTMLTextAreaElement} input
5752 * @param {SweetAlertOptions} params
5753 */
5754 const setInputPlaceholder = (input, params) => {
5755 if (!input.placeholder && params.inputPlaceholder) {
5756 input.placeholder = params.inputPlaceholder;
5757 }
5758 };
5759
5760 /**
5761 * @param {Input} input
5762 * @param {Input} prependTo
5763 * @param {SweetAlertOptions} params
5764 */
5765 const setInputLabel = (input, prependTo, params) => {
5766 if (params.inputLabel) {
5767 const label = document.createElement('label');
5768 const labelClass = swalClasses['input-label'];
5769 label.setAttribute('for', input.id);
5770 label.className = labelClass;
5771 if (typeof params.customClass === 'object') {
5772 addClass(label, params.customClass.inputLabel);
5773 }
5774 label.innerText = params.inputLabel;
5775 prependTo.insertAdjacentElement('beforebegin', label);
5776 }
5777 };
5778
5779 /**
5780 * @param {SweetAlertInput} inputType
5781 * @returns {HTMLElement | undefined}
5782 */
5783 const getInputContainer = inputType => {
5784 const popup = getPopup();
5785 if (!popup) {
5786 return;
5787 }
5788 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
5789 };
5790
5791 /**
5792 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
5793 * @param {SweetAlertOptions['inputValue']} inputValue
5794 */
5795 const checkAndSetInputValue = (input, inputValue) => {
5796 if (['string', 'number'].includes(typeof inputValue)) {
5797 input.value = `${inputValue}`;
5798 } else if (!isPromise(inputValue)) {
5799 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
5800 }
5801 };
5802
5803 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
5804 const renderInputType = {};
5805
5806 /**
5807 * @param {Input | HTMLElement} input
5808 * @param {SweetAlertOptions} params
5809 * @returns {Input}
5810 */
5811 renderInputType.text = renderInputType.email = renderInputType.password = renderInputType.number = renderInputType.tel = renderInputType.url = renderInputType.search = renderInputType.date = renderInputType['datetime-local'] = renderInputType.time = renderInputType.week = renderInputType.month = /** @type {(input: Input | HTMLElement, params: SweetAlertOptions) => Input} */
5812 (input, params) => {
5813 const inputElement = /** @type {HTMLInputElement} */input;
5814 checkAndSetInputValue(inputElement, params.inputValue);
5815 setInputLabel(inputElement, inputElement, params);
5816 setInputPlaceholder(inputElement, params);
5817 inputElement.type = /** @type {string} */params.input;
5818 return inputElement;
5819 };
5820
5821 /**
5822 * @param {Input | HTMLElement} input
5823 * @param {SweetAlertOptions} params
5824 * @returns {Input}
5825 */
5826 renderInputType.file = (input, params) => {
5827 const inputElement = /** @type {HTMLInputElement} */input;
5828 setInputLabel(inputElement, inputElement, params);
5829 setInputPlaceholder(inputElement, params);
5830 return inputElement;
5831 };
5832
5833 /**
5834 * @param {Input | HTMLElement} range
5835 * @param {SweetAlertOptions} params
5836 * @returns {Input}
5837 */
5838 renderInputType.range = (range, params) => {
5839 const rangeContainer = /** @type {HTMLElement} */range;
5840 const rangeInput = rangeContainer.querySelector('input');
5841 const rangeOutput = rangeContainer.querySelector('output');
5842 if (rangeInput) {
5843 checkAndSetInputValue(rangeInput, params.inputValue);
5844 rangeInput.type = /** @type {string} */params.input;
5845 setInputLabel(rangeInput, /** @type {Input} */range, params);
5846 }
5847 if (rangeOutput) {
5848 checkAndSetInputValue(rangeOutput, params.inputValue);
5849 }
5850 return /** @type {Input} */range;
5851 };
5852
5853 /**
5854 * @param {Input | HTMLElement} select
5855 * @param {SweetAlertOptions} params
5856 * @returns {Input}
5857 */
5858 renderInputType.select = (select, params) => {
5859 const selectElement = /** @type {HTMLSelectElement} */select;
5860 selectElement.textContent = '';
5861 if (params.inputPlaceholder) {
5862 const placeholder = document.createElement('option');
5863 setInnerHtml(placeholder, params.inputPlaceholder);
5864 placeholder.value = '';
5865 placeholder.disabled = true;
5866 placeholder.selected = true;
5867 selectElement.appendChild(placeholder);
5868 }
5869 setInputLabel(selectElement, selectElement, params);
5870 return selectElement;
5871 };
5872
5873 /**
5874 * @param {Input | HTMLElement} radio
5875 * @returns {Input}
5876 */
5877 renderInputType.radio = radio => {
5878 const radioElement = /** @type {HTMLElement} */radio;
5879 radioElement.textContent = '';
5880 return /** @type {Input} */radio;
5881 };
5882
5883 /**
5884 * @param {Input | HTMLElement} checkboxContainer
5885 * @param {SweetAlertOptions} params
5886 * @returns {Input}
5887 */
5888 renderInputType.checkbox = (checkboxContainer, params) => {
5889 const popup = getPopup();
5890 if (!popup) {
5891 throw new Error('Popup not found');
5892 }
5893 const checkbox = getInput$1(popup, 'checkbox');
5894 if (!checkbox) {
5895 throw new Error('Checkbox input not found');
5896 }
5897 checkbox.value = '1';
5898 checkbox.checked = Boolean(params.inputValue);
5899 const containerElement = /** @type {HTMLElement} */checkboxContainer;
5900 const label = containerElement.querySelector('span');
5901 if (label) {
5902 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
5903 if (placeholderOrLabel) {
5904 setInnerHtml(label, placeholderOrLabel);
5905 }
5906 }
5907 return checkbox;
5908 };
5909
5910 /**
5911 * @param {Input | HTMLElement} textarea
5912 * @param {SweetAlertOptions} params
5913 * @returns {Input}
5914 */
5915 renderInputType.textarea = (textarea, params) => {
5916 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
5917 checkAndSetInputValue(textareaElement, params.inputValue);
5918 setInputPlaceholder(textareaElement, params);
5919 setInputLabel(textareaElement, textareaElement, params);
5920
5921 /**
5922 * @param {HTMLElement} el
5923 * @returns {number}
5924 */
5925 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
5926
5927 // https://github.com/sweetalert2/sweetalert2/issues/2291
5928 setTimeout(() => {
5929 // https://github.com/sweetalert2/sweetalert2/issues/1699
5930 if ('MutationObserver' in window) {
5931 const popup = getPopup();
5932 if (!popup) {
5933 return;
5934 }
5935 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
5936 const textareaResizeHandler = () => {
5937 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
5938 if (!document.body.contains(textareaElement)) {
5939 return;
5940 }
5941 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
5942 const popupElement = getPopup();
5943 if (popupElement) {
5944 if (textareaWidth > initialPopupWidth) {
5945 popupElement.style.width = `${textareaWidth}px`;
5946 } else {
5947 applyNumericalStyle(popupElement, 'width', params.width);
5948 }
5949 }
5950 };
5951 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
5952 attributes: true,
5953 attributeFilter: ['style']
5954 });
5955 }
5956 });
5957 return textareaElement;
5958 };
5959
5960 /**
5961 * @param {SweetAlert} instance
5962 * @param {SweetAlertOptions} params
5963 */
5964 const renderContent = (instance, params) => {
5965 const htmlContainer = getHtmlContainer();
5966 if (!htmlContainer) {
5967 return;
5968 }
5969 showWhenInnerHtmlPresent(htmlContainer);
5970 applyCustomClass(htmlContainer, params, 'htmlContainer');
5971
5972 // Content as HTML
5973 if (params.html) {
5974 parseHtmlToContainer(params.html, htmlContainer);
5975 show(htmlContainer, 'block');
5976 }
5977
5978 // Content as plain text
5979 else if (params.text) {
5980 htmlContainer.textContent = params.text;
5981 show(htmlContainer, 'block');
5982 }
5983
5984 // No content
5985 else {
5986 hide(htmlContainer);
5987 }
5988 renderInput(instance, params);
5989 };
5990
5991 /**
5992 * @param {SweetAlert} instance
5993 * @param {SweetAlertOptions} params
5994 */
5995 const renderFooter = (instance, params) => {
5996 const footer = getFooter();
5997 if (!footer) {
5998 return;
5999 }
6000 showWhenInnerHtmlPresent(footer);
6001 toggle(footer, Boolean(params.footer), 'block');
6002 if (params.footer) {
6003 parseHtmlToContainer(params.footer, footer);
6004 }
6005
6006 // Custom class
6007 applyCustomClass(footer, params, 'footer');
6008 };
6009
6010 /**
6011 * @param {SweetAlert} instance
6012 * @param {SweetAlertOptions} params
6013 */
6014 const renderIcon = (instance, params) => {
6015 const innerParams = privateProps.innerParams.get(instance);
6016 const icon = getIcon();
6017 if (!icon) {
6018 return;
6019 }
6020
6021 // if the given icon already rendered, apply the styling without re-rendering the icon
6022 if (innerParams && params.icon === innerParams.icon) {
6023 // Custom or default content
6024 setContent(icon, params);
6025 applyStyles(icon, params);
6026 return;
6027 }
6028 if (!params.icon && !params.iconHtml) {
6029 hide(icon);
6030 return;
6031 }
6032 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
6033 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
6034 hide(icon);
6035 return;
6036 }
6037 show(icon);
6038
6039 // Custom or default content
6040 setContent(icon, params);
6041 applyStyles(icon, params);
6042
6043 // Animate icon
6044 addClass(icon, params.showClass && params.showClass.icon);
6045
6046 // Re-adjust the success icon on system theme change
6047 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
6048 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
6049 };
6050
6051 /**
6052 * @param {HTMLElement} icon
6053 * @param {SweetAlertOptions} params
6054 */
6055 const applyStyles = (icon, params) => {
6056 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
6057 if (params.icon !== iconType) {
6058 removeClass(icon, iconClassName);
6059 }
6060 }
6061 addClass(icon, params.icon && iconTypes[params.icon]);
6062
6063 // Icon color
6064 setColor(icon, params);
6065
6066 // Success icon background color
6067 adjustSuccessIconBackgroundColor();
6068
6069 // Custom class
6070 applyCustomClass(icon, params, 'icon');
6071 };
6072
6073 // Adjust success icon background color to match the popup background color
6074 const adjustSuccessIconBackgroundColor = () => {
6075 const popup = getPopup();
6076 if (!popup) {
6077 return;
6078 }
6079 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
6080 /** @type {NodeListOf<HTMLElement>} */
6081 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
6082 for (let i = 0; i < successIconParts.length; i++) {
6083 successIconParts[i].style.backgroundColor = popupBackgroundColor;
6084 }
6085 };
6086
6087 /**
6088 *
6089 * @param {SweetAlertOptions} params
6090 * @returns {string}
6091 */
6092 const successIconHtml = params => `
6093 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
6094 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
6095 <div class="swal2-success-ring"></div>
6096 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
6097 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
6098 `;
6099 const errorIconHtml = `
6100 <span class="swal2-x-mark">
6101 <span class="swal2-x-mark-line-left"></span>
6102 <span class="swal2-x-mark-line-right"></span>
6103 </span>
6104 `;
6105
6106 /**
6107 * @param {HTMLElement} icon
6108 * @param {SweetAlertOptions} params
6109 */
6110 const setContent = (icon, params) => {
6111 if (!params.icon && !params.iconHtml) {
6112 return;
6113 }
6114 let oldContent = icon.innerHTML;
6115 let newContent = '';
6116 if (params.iconHtml) {
6117 newContent = iconContent(params.iconHtml);
6118 } else if (params.icon === 'success') {
6119 newContent = successIconHtml(params);
6120 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
6121 } else if (params.icon === 'error') {
6122 newContent = errorIconHtml;
6123 } else if (params.icon) {
6124 const defaultIconHtml = {
6125 question: '?',
6126 warning: '!',
6127 info: 'i'
6128 };
6129 newContent = iconContent(defaultIconHtml[params.icon]);
6130 }
6131 if (oldContent.trim() !== newContent.trim()) {
6132 setInnerHtml(icon, newContent);
6133 }
6134 };
6135
6136 /**
6137 * @param {HTMLElement} icon
6138 * @param {SweetAlertOptions} params
6139 */
6140 const setColor = (icon, params) => {
6141 if (!params.iconColor) {
6142 return;
6143 }
6144 icon.style.color = params.iconColor;
6145 icon.style.borderColor = params.iconColor;
6146 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
6147 setStyle(icon, sel, 'background-color', params.iconColor);
6148 }
6149 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
6150 };
6151
6152 /**
6153 * @param {string} content
6154 * @returns {string}
6155 */
6156 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
6157
6158 /**
6159 * @param {SweetAlert} instance
6160 * @param {SweetAlertOptions} params
6161 */
6162 const renderImage = (instance, params) => {
6163 const image = getImage();
6164 if (!image) {
6165 return;
6166 }
6167 if (!params.imageUrl) {
6168 hide(image);
6169 return;
6170 }
6171 show(image, '');
6172
6173 // Src, alt
6174 image.setAttribute('src', params.imageUrl);
6175 image.setAttribute('alt', params.imageAlt || '');
6176
6177 // Width, height
6178 applyNumericalStyle(image, 'width', params.imageWidth);
6179 applyNumericalStyle(image, 'height', params.imageHeight);
6180
6181 // Class
6182 image.className = swalClasses.image;
6183 applyCustomClass(image, params, 'image');
6184 };
6185
6186 let dragging = false;
6187 let mousedownX = 0;
6188 let mousedownY = 0;
6189 let initialX = 0;
6190 let initialY = 0;
6191
6192 /**
6193 * @param {HTMLElement} popup
6194 */
6195 const addDraggableListeners = popup => {
6196 popup.addEventListener('mousedown', down);
6197 document.body.addEventListener('mousemove', move);
6198 popup.addEventListener('mouseup', up);
6199 popup.addEventListener('touchstart', down);
6200 document.body.addEventListener('touchmove', move);
6201 popup.addEventListener('touchend', up);
6202 };
6203
6204 /**
6205 * @param {HTMLElement} popup
6206 */
6207 const removeDraggableListeners = popup => {
6208 popup.removeEventListener('mousedown', down);
6209 document.body.removeEventListener('mousemove', move);
6210 popup.removeEventListener('mouseup', up);
6211 popup.removeEventListener('touchstart', down);
6212 document.body.removeEventListener('touchmove', move);
6213 popup.removeEventListener('touchend', up);
6214 };
6215
6216 /**
6217 * @param {MouseEvent | TouchEvent} event
6218 */
6219 const down = event => {
6220 const popup = getPopup();
6221 if (!popup) {
6222 return;
6223 }
6224 const icon = getIcon();
6225 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
6226 dragging = true;
6227 const clientXY = getClientXY(event);
6228 mousedownX = clientXY.clientX;
6229 mousedownY = clientXY.clientY;
6230 initialX = parseInt(popup.style.insetInlineStart) || 0;
6231 initialY = parseInt(popup.style.insetBlockStart) || 0;
6232 addClass(popup, 'swal2-dragging');
6233 }
6234 };
6235
6236 /**
6237 * @param {MouseEvent | TouchEvent} event
6238 */
6239 const move = event => {
6240 const popup = getPopup();
6241 if (!popup) {
6242 return;
6243 }
6244 if (dragging) {
6245 let {
6246 clientX,
6247 clientY
6248 } = getClientXY(event);
6249 const deltaX = clientX - mousedownX;
6250 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
6251 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
6252 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
6253 }
6254 };
6255 const up = () => {
6256 const popup = getPopup();
6257 dragging = false;
6258 removeClass(popup, 'swal2-dragging');
6259 };
6260
6261 /**
6262 * @param {MouseEvent | TouchEvent} event
6263 * @returns {{ clientX: number, clientY: number }}
6264 */
6265 const getClientXY = event => {
6266 let clientX = 0,
6267 clientY = 0;
6268 if (event.type.startsWith('mouse')) {
6269 clientX = /** @type {MouseEvent} */event.clientX;
6270 clientY = /** @type {MouseEvent} */event.clientY;
6271 } else if (event.type.startsWith('touch')) {
6272 clientX = /** @type {TouchEvent} */event.touches[0].clientX;
6273 clientY = /** @type {TouchEvent} */event.touches[0].clientY;
6274 }
6275 return {
6276 clientX,
6277 clientY
6278 };
6279 };
6280
6281 /**
6282 * @param {SweetAlert} instance
6283 * @param {SweetAlertOptions} params
6284 */
6285 const renderPopup = (instance, params) => {
6286 const container = getContainer();
6287 const popup = getPopup();
6288 if (!container || !popup) {
6289 return;
6290 }
6291
6292 // Width
6293 // https://github.com/sweetalert2/sweetalert2/issues/2170
6294 if (params.toast) {
6295 applyNumericalStyle(container, 'width', params.width);
6296 popup.style.width = '100%';
6297 const loader = getLoader();
6298 if (loader) {
6299 popup.insertBefore(loader, getIcon());
6300 }
6301 } else {
6302 applyNumericalStyle(popup, 'width', params.width);
6303 }
6304
6305 // Padding
6306 applyNumericalStyle(popup, 'padding', params.padding);
6307
6308 // Color
6309 if (params.color) {
6310 popup.style.color = params.color;
6311 }
6312
6313 // Background
6314 if (params.background) {
6315 popup.style.background = params.background;
6316 }
6317 hide(getValidationMessage());
6318
6319 // Classes
6320 addClasses$1(popup, params);
6321 if (params.draggable && !params.toast) {
6322 addClass(popup, swalClasses.draggable);
6323 addDraggableListeners(popup);
6324 } else {
6325 removeClass(popup, swalClasses.draggable);
6326 removeDraggableListeners(popup);
6327 }
6328 };
6329
6330 /**
6331 * @param {HTMLElement} popup
6332 * @param {SweetAlertOptions} params
6333 */
6334 const addClasses$1 = (popup, params) => {
6335 const showClass = params.showClass || {};
6336 // Default Class + showClass when updating Swal.update({})
6337 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
6338 if (params.toast) {
6339 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
6340 addClass(popup, swalClasses.toast);
6341 } else {
6342 addClass(popup, swalClasses.modal);
6343 }
6344
6345 // Custom class
6346 applyCustomClass(popup, params, 'popup');
6347 // TODO: remove in the next major
6348 if (typeof params.customClass === 'string') {
6349 addClass(popup, params.customClass);
6350 }
6351
6352 // Icon class (#1842)
6353 if (params.icon) {
6354 addClass(popup, swalClasses[`icon-${params.icon}`]);
6355 }
6356 };
6357
6358 /**
6359 * @param {SweetAlert} instance
6360 * @param {SweetAlertOptions} params
6361 */
6362 const renderProgressSteps = (instance, params) => {
6363 const progressStepsContainer = getProgressSteps();
6364 if (!progressStepsContainer) {
6365 return;
6366 }
6367 const {
6368 progressSteps,
6369 currentProgressStep
6370 } = params;
6371 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
6372 hide(progressStepsContainer);
6373 return;
6374 }
6375 show(progressStepsContainer);
6376 progressStepsContainer.textContent = '';
6377 if (currentProgressStep >= progressSteps.length) {
6378 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
6379 }
6380 progressSteps.forEach((step, index) => {
6381 const stepEl = createStepElement(step);
6382 progressStepsContainer.appendChild(stepEl);
6383 if (index === currentProgressStep) {
6384 addClass(stepEl, swalClasses['active-progress-step']);
6385 }
6386 if (index !== progressSteps.length - 1) {
6387 const lineEl = createLineElement(params);
6388 progressStepsContainer.appendChild(lineEl);
6389 }
6390 });
6391 };
6392
6393 /**
6394 * @param {string} step
6395 * @returns {HTMLLIElement}
6396 */
6397 const createStepElement = step => {
6398 const stepEl = document.createElement('li');
6399 addClass(stepEl, swalClasses['progress-step']);
6400 setInnerHtml(stepEl, step);
6401 return stepEl;
6402 };
6403
6404 /**
6405 * @param {SweetAlertOptions} params
6406 * @returns {HTMLLIElement}
6407 */
6408 const createLineElement = params => {
6409 const lineEl = document.createElement('li');
6410 addClass(lineEl, swalClasses['progress-step-line']);
6411 if (params.progressStepsDistance) {
6412 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
6413 }
6414 return lineEl;
6415 };
6416
6417 /**
6418 * @param {SweetAlert} instance
6419 * @param {SweetAlertOptions} params
6420 */
6421 const renderTitle = (instance, params) => {
6422 const title = getTitle();
6423 if (!title) {
6424 return;
6425 }
6426 showWhenInnerHtmlPresent(title);
6427 toggle(title, Boolean(params.title || params.titleText), 'block');
6428 if (params.title) {
6429 parseHtmlToContainer(params.title, title);
6430 }
6431 if (params.titleText) {
6432 title.innerText = params.titleText;
6433 }
6434
6435 // Custom class
6436 applyCustomClass(title, params, 'title');
6437 };
6438
6439 /**
6440 * @param {SweetAlert} instance
6441 * @param {SweetAlertOptions} params
6442 */
6443 const render = (instance, params) => {
6444 var _globalState$eventEmi;
6445 renderPopup(instance, params);
6446 renderContainer(instance, params);
6447 renderProgressSteps(instance, params);
6448 renderIcon(instance, params);
6449 renderImage(instance, params);
6450 renderTitle(instance, params);
6451 renderCloseButton(instance, params);
6452 renderContent(instance, params);
6453 renderActions(instance, params);
6454 renderFooter(instance, params);
6455 const popup = getPopup();
6456 if (typeof params.didRender === 'function' && popup) {
6457 params.didRender(popup);
6458 }
6459 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
6460 };
6461
6462 /*
6463 * Global function to determine if SweetAlert2 popup is shown
6464 */
6465 const isVisible = () => {
6466 return isVisible$1(getPopup());
6467 };
6468
6469 /*
6470 * Global function to click 'Confirm' button
6471 */
6472 const clickConfirm = () => {
6473 var _dom$getConfirmButton;
6474 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
6475 };
6476
6477 /*
6478 * Global function to click 'Deny' button
6479 */
6480 const clickDeny = () => {
6481 var _dom$getDenyButton;
6482 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
6483 };
6484
6485 /*
6486 * Global function to click 'Cancel' button
6487 */
6488 const clickCancel = () => {
6489 var _dom$getCancelButton;
6490 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
6491 };
6492
6493 /** @type {Record<DismissReason, DismissReason>} */
6494 const DismissReason = Object.freeze({
6495 cancel: 'cancel',
6496 backdrop: 'backdrop',
6497 close: 'close',
6498 esc: 'esc',
6499 timer: 'timer'
6500 });
6501
6502 /**
6503 * @param {GlobalState} globalState
6504 */
6505 const removeKeydownHandler = globalState => {
6506 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
6507 const handler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */globalState.keydownHandler;
6508 globalState.keydownTarget.removeEventListener('keydown', handler, {
6509 capture: globalState.keydownListenerCapture
6510 });
6511 globalState.keydownHandlerAdded = false;
6512 }
6513 };
6514
6515 /**
6516 * @param {GlobalState} globalState
6517 * @param {SweetAlertOptions} innerParams
6518 * @param {(dismiss: DismissReason) => void} dismissWith
6519 */
6520 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
6521 removeKeydownHandler(globalState);
6522 if (!innerParams.toast) {
6523 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
6524 const handler = e => keydownHandler(innerParams, e, dismissWith);
6525 globalState.keydownHandler = handler;
6526 const target = innerParams.keydownListenerCapture ? window : getPopup();
6527 if (target) {
6528 globalState.keydownTarget = target;
6529 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
6530 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
6531 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
6532 capture: globalState.keydownListenerCapture
6533 });
6534 globalState.keydownHandlerAdded = true;
6535 }
6536 }
6537 };
6538
6539 /**
6540 * @param {number} index
6541 * @param {number} increment
6542 */
6543 const setFocus = (index, increment) => {
6544 var _dom$getPopup;
6545 const focusableElements = getFocusableElements();
6546 // search for visible elements and select the next possible match
6547 if (focusableElements.length) {
6548 index = index + increment;
6549
6550 // shift + tab when .swal2-popup is focused
6551 if (index === -2) {
6552 index = focusableElements.length - 1;
6553 }
6554
6555 // rollover to first item
6556 if (index === focusableElements.length) {
6557 index = 0;
6558
6559 // go to last item
6560 } else if (index === -1) {
6561 index = focusableElements.length - 1;
6562 }
6563 focusableElements[index].focus();
6564 return;
6565 }
6566 // no visible focusable elements, focus the popup
6567 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
6568 };
6569 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
6570 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
6571
6572 /**
6573 * @param {SweetAlertOptions} innerParams
6574 * @param {KeyboardEvent} event
6575 * @param {(dismiss: DismissReason) => void} dismissWith
6576 */
6577 const keydownHandler = (innerParams, event, dismissWith) => {
6578 if (!innerParams) {
6579 return; // This instance has already been destroyed
6580 }
6581
6582 // Ignore keydown during IME composition
6583 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
6584 // https://github.com/sweetalert2/sweetalert2/issues/720
6585 // https://github.com/sweetalert2/sweetalert2/issues/2406
6586 if (event.isComposing || event.keyCode === 229) {
6587 return;
6588 }
6589 if (innerParams.stopKeydownPropagation) {
6590 event.stopPropagation();
6591 }
6592
6593 // ENTER
6594 if (event.key === 'Enter') {
6595 handleEnter(event, innerParams);
6596 }
6597
6598 // TAB
6599 else if (event.key === 'Tab') {
6600 handleTab(event);
6601 }
6602
6603 // ARROWS - switch focus between buttons
6604 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
6605 handleArrows(event.key);
6606 }
6607
6608 // ESC
6609 else if (event.key === 'Escape') {
6610 handleEsc(event, innerParams, dismissWith);
6611 }
6612 };
6613
6614 /**
6615 * @param {KeyboardEvent} event
6616 * @param {SweetAlertOptions} innerParams
6617 */
6618 const handleEnter = (event, innerParams) => {
6619 // https://github.com/sweetalert2/sweetalert2/issues/2386
6620 if (!callIfFunction(innerParams.allowEnterKey)) {
6621 return;
6622 }
6623 const popup = getPopup();
6624 if (!popup || !innerParams.input) {
6625 return;
6626 }
6627 const input = getInput$1(popup, innerParams.input);
6628 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
6629 if (['textarea', 'file'].includes(innerParams.input)) {
6630 return; // do not submit
6631 }
6632 clickConfirm();
6633 event.preventDefault();
6634 }
6635 };
6636
6637 /**
6638 * @param {KeyboardEvent} event
6639 */
6640 const handleTab = event => {
6641 const targetElement = event.target;
6642 const focusableElements = getFocusableElements();
6643 let btnIndex = -1;
6644 for (let i = 0; i < focusableElements.length; i++) {
6645 if (targetElement === focusableElements[i]) {
6646 btnIndex = i;
6647 break;
6648 }
6649 }
6650
6651 // Cycle to the next button
6652 if (!event.shiftKey) {
6653 setFocus(btnIndex, 1);
6654 }
6655
6656 // Cycle to the prev button
6657 else {
6658 setFocus(btnIndex, -1);
6659 }
6660 event.stopPropagation();
6661 event.preventDefault();
6662 };
6663
6664 /**
6665 * @param {string} key
6666 */
6667 const handleArrows = key => {
6668 const actions = getActions();
6669 const confirmButton = getConfirmButton();
6670 const denyButton = getDenyButton();
6671 const cancelButton = getCancelButton();
6672 if (!actions || !confirmButton || !denyButton || !cancelButton) {
6673 return;
6674 }
6675 /** @type HTMLElement[] */
6676 const buttons = [confirmButton, denyButton, cancelButton];
6677 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
6678 return;
6679 }
6680 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
6681 let buttonToFocus = document.activeElement;
6682 if (!buttonToFocus) {
6683 return;
6684 }
6685 for (let i = 0; i < actions.children.length; i++) {
6686 buttonToFocus = buttonToFocus[sibling];
6687 if (!buttonToFocus) {
6688 return;
6689 }
6690 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
6691 break;
6692 }
6693 }
6694 if (buttonToFocus instanceof HTMLButtonElement) {
6695 buttonToFocus.focus();
6696 }
6697 };
6698
6699 /**
6700 * @param {KeyboardEvent} event
6701 * @param {SweetAlertOptions} innerParams
6702 * @param {(dismiss: DismissReason) => void} dismissWith
6703 */
6704 const handleEsc = (event, innerParams, dismissWith) => {
6705 event.preventDefault();
6706 if (callIfFunction(innerParams.allowEscapeKey)) {
6707 dismissWith(DismissReason.esc);
6708 }
6709 };
6710
6711 /**
6712 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
6713 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
6714 * This is the approach that Babel will probably take to implement private methods/fields
6715 * https://github.com/tc39/proposal-private-methods
6716 * https://github.com/babel/babel/pull/7555
6717 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
6718 * then we can use that language feature.
6719 */
6720
6721 var privateMethods = {
6722 swalPromiseResolve: new WeakMap(),
6723 swalPromiseReject: new WeakMap()
6724 };
6725
6726 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
6727 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
6728 // elements not within the active modal dialog will not be surfaced if a user opens a screen
6729 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
6730
6731 const setAriaHidden = () => {
6732 const container = getContainer();
6733 const bodyChildren = Array.from(document.body.children);
6734 bodyChildren.forEach(el => {
6735 if (el.contains(container)) {
6736 return;
6737 }
6738 if (el.hasAttribute('aria-hidden')) {
6739 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
6740 }
6741 el.setAttribute('aria-hidden', 'true');
6742 });
6743 };
6744 const unsetAriaHidden = () => {
6745 const bodyChildren = Array.from(document.body.children);
6746 bodyChildren.forEach(el => {
6747 if (el.hasAttribute('data-previous-aria-hidden')) {
6748 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
6749 el.removeAttribute('data-previous-aria-hidden');
6750 } else {
6751 el.removeAttribute('aria-hidden');
6752 }
6753 });
6754 };
6755
6756 // @ts-ignore
6757 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
6758
6759 /**
6760 * Fix iOS scrolling
6761 * http://stackoverflow.com/q/39626302
6762 */
6763 const iOSfix = () => {
6764 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
6765 const offset = document.body.scrollTop;
6766 document.body.style.top = `${offset * -1}px`;
6767 addClass(document.body, swalClasses.iosfix);
6768 lockBodyScroll();
6769 }
6770 };
6771
6772 /**
6773 * https://github.com/sweetalert2/sweetalert2/issues/1246
6774 */
6775 const lockBodyScroll = () => {
6776 const container = getContainer();
6777 if (!container) {
6778 return;
6779 }
6780 /** @type {boolean} */
6781 let preventTouchMove;
6782 /**
6783 * @param {TouchEvent} event
6784 */
6785 container.ontouchstart = event => {
6786 preventTouchMove = shouldPreventTouchMove(event);
6787 };
6788 /**
6789 * @param {TouchEvent} event
6790 */
6791 container.ontouchmove = event => {
6792 if (preventTouchMove) {
6793 event.preventDefault();
6794 event.stopPropagation();
6795 }
6796 };
6797 };
6798
6799 /**
6800 * @param {TouchEvent} event
6801 * @returns {boolean}
6802 */
6803 const shouldPreventTouchMove = event => {
6804 const target = event.target;
6805 const container = getContainer();
6806 const htmlContainer = getHtmlContainer();
6807 if (!container || !htmlContainer) {
6808 return false;
6809 }
6810 if (isStylus(event) || isZoom(event)) {
6811 return false;
6812 }
6813 if (target === container) {
6814 return true;
6815 }
6816 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
6817 // #2823
6818 target.tagName !== 'INPUT' &&
6819 // #1603
6820 target.tagName !== 'TEXTAREA' &&
6821 // #2266
6822 !(isScrollable(htmlContainer) &&
6823 // #1944
6824 htmlContainer.contains(target))) {
6825 return true;
6826 }
6827 return false;
6828 };
6829
6830 /**
6831 * https://github.com/sweetalert2/sweetalert2/issues/1786
6832 *
6833 * @param {TouchEvent} event
6834 * @returns {boolean}
6835 */
6836 const isStylus = event => {
6837 return Boolean(event.touches && event.touches.length &&
6838 // @ts-ignore - touchType is not a standard property
6839 event.touches[0].touchType === 'stylus');
6840 };
6841
6842 /**
6843 * https://github.com/sweetalert2/sweetalert2/issues/1891
6844 *
6845 * @param {TouchEvent} event
6846 * @returns {boolean}
6847 */
6848 const isZoom = event => {
6849 return event.touches && event.touches.length > 1;
6850 };
6851 const undoIOSfix = () => {
6852 if (hasClass(document.body, swalClasses.iosfix)) {
6853 const offset = parseInt(document.body.style.top, 10);
6854 removeClass(document.body, swalClasses.iosfix);
6855 document.body.style.top = '';
6856 document.body.scrollTop = offset * -1;
6857 }
6858 };
6859
6860 /**
6861 * Measure scrollbar width for padding body during modal show/hide
6862 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
6863 *
6864 * @returns {number}
6865 */
6866 const measureScrollbar = () => {
6867 const scrollDiv = document.createElement('div');
6868 scrollDiv.className = swalClasses['scrollbar-measure'];
6869 document.body.appendChild(scrollDiv);
6870 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
6871 document.body.removeChild(scrollDiv);
6872 return scrollbarWidth;
6873 };
6874
6875 /**
6876 * Remember state in cases where opening and handling a modal will fiddle with it.
6877 * @type {number | null}
6878 */
6879 let previousBodyPadding = null;
6880
6881 /**
6882 * @param {string} initialBodyOverflow
6883 */
6884 const replaceScrollbarWithPadding = initialBodyOverflow => {
6885 // for queues, do not do this more than once
6886 if (previousBodyPadding !== null) {
6887 return;
6888 }
6889 // if the body has overflow
6890 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
6891 ) {
6892 // add padding so the content doesn't shift after removal of scrollbar
6893 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
6894 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
6895 }
6896 };
6897 const undoReplaceScrollbarWithPadding = () => {
6898 if (previousBodyPadding !== null) {
6899 document.body.style.paddingRight = `${previousBodyPadding}px`;
6900 previousBodyPadding = null;
6901 }
6902 };
6903
6904 /**
6905 * @param {SweetAlert} instance
6906 * @param {HTMLElement} container
6907 * @param {boolean} returnFocus
6908 * @param {(() => void) | undefined} didClose
6909 */
6910 function removePopupAndResetState(instance, container, returnFocus, didClose) {
6911 if (isToast()) {
6912 triggerDidCloseAndDispose(instance, didClose);
6913 } else {
6914 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
6915 removeKeydownHandler(globalState);
6916 }
6917
6918 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
6919 // for some reason removing the container in Safari will scroll the document to bottom
6920 if (isSafariOrIOS) {
6921 container.setAttribute('style', 'display:none !important');
6922 container.removeAttribute('class');
6923 container.innerHTML = '';
6924 } else {
6925 container.remove();
6926 }
6927 if (isModal()) {
6928 undoReplaceScrollbarWithPadding();
6929 undoIOSfix();
6930 unsetAriaHidden();
6931 }
6932 removeBodyClasses();
6933 }
6934
6935 /**
6936 * Remove SweetAlert2 classes from body
6937 */
6938 function removeBodyClasses() {
6939 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
6940 }
6941
6942 /**
6943 * Instance method to close sweetAlert
6944 *
6945 * @param {SweetAlertResult | undefined} resolveValue
6946 * @this {SweetAlert}
6947 */
6948 function close(resolveValue) {
6949 resolveValue = prepareResolveValue(resolveValue);
6950 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
6951 const didClose = triggerClosePopup(this);
6952 if (this.isAwaitingPromise) {
6953 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
6954 if (!resolveValue.isDismissed) {
6955 handleAwaitingPromise(this);
6956 swalPromiseResolve(resolveValue);
6957 }
6958 } else if (didClose) {
6959 // Resolve Swal promise
6960 swalPromiseResolve(resolveValue);
6961 }
6962 }
6963
6964 /**
6965 * @param {SweetAlert} instance
6966 * @returns {boolean}
6967 */
6968 const triggerClosePopup = instance => {
6969 const popup = getPopup();
6970 if (!popup) {
6971 return false;
6972 }
6973 const innerParams = privateProps.innerParams.get(instance);
6974 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
6975 return false;
6976 }
6977 removeClass(popup, innerParams.showClass.popup);
6978 addClass(popup, innerParams.hideClass.popup);
6979 const backdrop = getContainer();
6980 removeClass(backdrop, innerParams.showClass.backdrop);
6981 addClass(backdrop, innerParams.hideClass.backdrop);
6982 handlePopupAnimation(instance, popup, innerParams);
6983 return true;
6984 };
6985
6986 /**
6987 * @param {Error | string} error
6988 * @this {SweetAlert}
6989 */
6990 function rejectPromise(error) {
6991 const rejectPromise = privateMethods.swalPromiseReject.get(this);
6992 handleAwaitingPromise(this);
6993 if (rejectPromise) {
6994 // Reject Swal promise
6995 rejectPromise(error);
6996 }
6997 }
6998
6999 /**
7000 * @param {SweetAlert} instance
7001 */
7002 const handleAwaitingPromise = instance => {
7003 if (instance.isAwaitingPromise) {
7004 // @ts-ignore
7005 delete instance.isAwaitingPromise;
7006 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
7007 if (!privateProps.innerParams.get(instance)) {
7008 instance._destroy();
7009 }
7010 }
7011 };
7012
7013 /**
7014 * @param {SweetAlertResult | undefined} resolveValue
7015 * @returns {SweetAlertResult}
7016 */
7017 const prepareResolveValue = resolveValue => {
7018 // When user calls Swal.close()
7019 if (typeof resolveValue === 'undefined') {
7020 return {
7021 isConfirmed: false,
7022 isDenied: false,
7023 isDismissed: true
7024 };
7025 }
7026 return Object.assign({
7027 isConfirmed: false,
7028 isDenied: false,
7029 isDismissed: false
7030 }, resolveValue);
7031 };
7032
7033 /**
7034 * @param {SweetAlert} instance
7035 * @param {HTMLElement} popup
7036 * @param {SweetAlertOptions} innerParams
7037 */
7038 const handlePopupAnimation = (instance, popup, innerParams) => {
7039 var _globalState$eventEmi;
7040 const container = getContainer();
7041 // If animation is supported, animate
7042 const animationIsSupported = hasCssAnimation(popup);
7043 if (typeof innerParams.willClose === 'function') {
7044 innerParams.willClose(popup);
7045 }
7046 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
7047 if (animationIsSupported && container) {
7048 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
7049 } else if (container) {
7050 // Otherwise, remove immediately
7051 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
7052 }
7053 };
7054
7055 /**
7056 * @param {SweetAlert} instance
7057 * @param {HTMLElement} popup
7058 * @param {HTMLElement} container
7059 * @param {boolean} returnFocus
7060 * @param {(() => void) | undefined} didClose
7061 */
7062 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
7063 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
7064 /**
7065 * @param {AnimationEvent | TransitionEvent} e
7066 */
7067 const swalCloseAnimationFinished = function (e) {
7068 if (e.target === popup) {
7069 var _globalState$swalClos;
7070 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
7071 delete globalState.swalCloseEventFinishedCallback;
7072 popup.removeEventListener('animationend', swalCloseAnimationFinished);
7073 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
7074 }
7075 };
7076 popup.addEventListener('animationend', swalCloseAnimationFinished);
7077 popup.addEventListener('transitionend', swalCloseAnimationFinished);
7078 };
7079
7080 /**
7081 * @param {SweetAlert} instance
7082 * @param {(() => void) | undefined} didClose
7083 */
7084 const triggerDidCloseAndDispose = (instance, didClose) => {
7085 setTimeout(() => {
7086 var _globalState$eventEmi2;
7087 if (typeof didClose === 'function') {
7088 didClose.bind(instance.params)();
7089 }
7090 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
7091 // instance might have been destroyed already
7092 if (instance._destroy) {
7093 instance._destroy();
7094 }
7095 });
7096 };
7097
7098 /**
7099 * Shows loader (spinner), this is useful with AJAX requests.
7100 * By default the loader be shown instead of the "Confirm" button.
7101 *
7102 * @param {HTMLButtonElement | null} [buttonToReplace]
7103 */
7104 const showLoading = buttonToReplace => {
7105 let popup = getPopup();
7106 if (!popup) {
7107 new Swal();
7108 }
7109 popup = getPopup();
7110 if (!popup) {
7111 return;
7112 }
7113 const loader = getLoader();
7114 if (isToast()) {
7115 hide(getIcon());
7116 } else {
7117 replaceButton(popup, buttonToReplace);
7118 }
7119 show(loader);
7120 popup.setAttribute('data-loading', 'true');
7121 popup.setAttribute('aria-busy', 'true');
7122 popup.focus();
7123 };
7124
7125 /**
7126 * @param {HTMLElement} popup
7127 * @param {HTMLButtonElement | null} [buttonToReplace]
7128 */
7129 const replaceButton = (popup, buttonToReplace) => {
7130 const actions = getActions();
7131 const loader = getLoader();
7132 if (!actions || !loader) {
7133 return;
7134 }
7135 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
7136 buttonToReplace = getConfirmButton();
7137 }
7138 show(actions);
7139 if (buttonToReplace) {
7140 hide(buttonToReplace);
7141 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
7142 actions.insertBefore(loader, buttonToReplace);
7143 }
7144 addClass([popup, actions], swalClasses.loading);
7145 };
7146
7147 /**
7148 * @param {SweetAlert} instance
7149 * @param {SweetAlertOptions} params
7150 */
7151 const handleInputOptionsAndValue = (instance, params) => {
7152 if (params.input === 'select' || params.input === 'radio') {
7153 handleInputOptions(instance, params);
7154 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
7155 showLoading(getConfirmButton());
7156 handleInputValue(instance, params);
7157 }
7158 };
7159
7160 /**
7161 * @param {SweetAlert} instance
7162 * @param {SweetAlertOptions} innerParams
7163 * @returns {SweetAlertInputValue}
7164 */
7165 const getInputValue = (instance, innerParams) => {
7166 const input = instance.getInput();
7167 if (!input) {
7168 return null;
7169 }
7170 switch (innerParams.input) {
7171 case 'checkbox':
7172 return getCheckboxValue(input);
7173 case 'radio':
7174 return getRadioValue(input);
7175 case 'file':
7176 return getFileValue(input);
7177 default:
7178 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
7179 }
7180 };
7181
7182 /**
7183 * @param {HTMLInputElement} input
7184 * @returns {number}
7185 */
7186 const getCheckboxValue = input => input.checked ? 1 : 0;
7187
7188 /**
7189 * @param {HTMLInputElement} input
7190 * @returns {string | null}
7191 */
7192 const getRadioValue = input => input.checked ? input.value : null;
7193
7194 /**
7195 * @param {HTMLInputElement} input
7196 * @returns {FileList | File | null}
7197 */
7198 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
7199
7200 /**
7201 * @param {SweetAlert} instance
7202 * @param {SweetAlertOptions} params
7203 */
7204 const handleInputOptions = (instance, params) => {
7205 const popup = getPopup();
7206 if (!popup) {
7207 return;
7208 }
7209 /**
7210 * @param {*} inputOptions
7211 */
7212 const processInputOptions = inputOptions => {
7213 if (params.input === 'select') {
7214 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
7215 } else if (params.input === 'radio') {
7216 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
7217 }
7218 };
7219 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
7220 showLoading(getConfirmButton());
7221 asPromise(params.inputOptions).then(inputOptions => {
7222 instance.hideLoading();
7223 processInputOptions(inputOptions);
7224 });
7225 } else if (typeof params.inputOptions === 'object') {
7226 processInputOptions(params.inputOptions);
7227 } else {
7228 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
7229 }
7230 };
7231
7232 /**
7233 * @param {SweetAlert} instance
7234 * @param {SweetAlertOptions} params
7235 */
7236 const handleInputValue = (instance, params) => {
7237 const input = instance.getInput();
7238 if (!input) {
7239 return;
7240 }
7241 hide(input);
7242 asPromise(params.inputValue).then(inputValue => {
7243 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
7244 show(input);
7245 input.focus();
7246 instance.hideLoading();
7247 }).catch(err => {
7248 error(`Error in inputValue promise: ${err}`);
7249 input.value = '';
7250 show(input);
7251 input.focus();
7252 instance.hideLoading();
7253 });
7254 };
7255
7256 /**
7257 * @param {HTMLElement} popup
7258 * @param {InputOptionFlattened[]} inputOptions
7259 * @param {SweetAlertOptions} params
7260 */
7261 function populateSelectOptions(popup, inputOptions, params) {
7262 const select = getDirectChildByClass(popup, swalClasses.select);
7263 if (!select) {
7264 return;
7265 }
7266 /**
7267 * @param {HTMLElement} parent
7268 * @param {string} optionLabel
7269 * @param {string} optionValue
7270 */
7271 const renderOption = (parent, optionLabel, optionValue) => {
7272 const option = document.createElement('option');
7273 option.value = optionValue;
7274 setInnerHtml(option, optionLabel);
7275 option.selected = isSelected(optionValue, params.inputValue);
7276 parent.appendChild(option);
7277 };
7278 inputOptions.forEach(inputOption => {
7279 const optionValue = inputOption[0];
7280 const optionLabel = inputOption[1];
7281 // <optgroup> spec:
7282 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
7283 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
7284 // check whether this is a <optgroup>
7285 if (Array.isArray(optionLabel)) {
7286 // if it is an array, then it is an <optgroup>
7287 const optgroup = document.createElement('optgroup');
7288 optgroup.label = optionValue;
7289 optgroup.disabled = false; // not configurable for now
7290 select.appendChild(optgroup);
7291 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
7292 } else {
7293 // case of <option>
7294 renderOption(select, optionLabel, optionValue);
7295 }
7296 });
7297 select.focus();
7298 }
7299
7300 /**
7301 * @param {HTMLElement} popup
7302 * @param {InputOptionFlattened[]} inputOptions
7303 * @param {SweetAlertOptions} params
7304 */
7305 function populateRadioOptions(popup, inputOptions, params) {
7306 const radio = getDirectChildByClass(popup, swalClasses.radio);
7307 if (!radio) {
7308 return;
7309 }
7310 inputOptions.forEach(inputOption => {
7311 const radioValue = inputOption[0];
7312 const radioLabel = inputOption[1];
7313 const radioInput = document.createElement('input');
7314 const radioLabelElement = document.createElement('label');
7315 radioInput.type = 'radio';
7316 radioInput.name = swalClasses.radio;
7317 radioInput.value = radioValue;
7318 if (isSelected(radioValue, params.inputValue)) {
7319 radioInput.checked = true;
7320 }
7321 const label = document.createElement('span');
7322 setInnerHtml(label, radioLabel);
7323 label.className = swalClasses.label;
7324 radioLabelElement.appendChild(radioInput);
7325 radioLabelElement.appendChild(label);
7326 radio.appendChild(radioLabelElement);
7327 });
7328 const radios = radio.querySelectorAll('input');
7329 if (radios.length) {
7330 radios[0].focus();
7331 }
7332 }
7333
7334 /**
7335 * Converts `inputOptions` into an array of `[value, label]`s
7336 *
7337 * @param {*} inputOptions
7338 * @typedef {string[]} InputOptionFlattened
7339 * @returns {InputOptionFlattened[]}
7340 */
7341 const formatInputOptions = inputOptions => {
7342 /** @type {InputOptionFlattened[]} */
7343 const result = [];
7344 if (inputOptions instanceof Map) {
7345 inputOptions.forEach((value, key) => {
7346 let valueFormatted = value;
7347 if (typeof valueFormatted === 'object') {
7348 // case of <optgroup>
7349 valueFormatted = formatInputOptions(valueFormatted);
7350 }
7351 result.push([key, valueFormatted]);
7352 });
7353 } else {
7354 Object.keys(inputOptions).forEach(key => {
7355 let valueFormatted = inputOptions[key];
7356 if (typeof valueFormatted === 'object') {
7357 // case of <optgroup>
7358 valueFormatted = formatInputOptions(valueFormatted);
7359 }
7360 result.push([key, valueFormatted]);
7361 });
7362 }
7363 return result;
7364 };
7365
7366 /**
7367 * @param {string} optionValue
7368 * @param {SweetAlertInputValue} inputValue
7369 * @returns {boolean}
7370 */
7371 const isSelected = (optionValue, inputValue) => {
7372 return Boolean(inputValue) && inputValue !== null && inputValue !== undefined && inputValue.toString() === optionValue.toString();
7373 };
7374
7375 /**
7376 * @param {SweetAlert} instance
7377 */
7378 const handleConfirmButtonClick = instance => {
7379 const innerParams = privateProps.innerParams.get(instance);
7380 instance.disableButtons();
7381 if (innerParams.input) {
7382 handleConfirmOrDenyWithInput(instance, 'confirm');
7383 } else {
7384 confirm(instance, true);
7385 }
7386 };
7387
7388 /**
7389 * @param {SweetAlert} instance
7390 */
7391 const handleDenyButtonClick = instance => {
7392 const innerParams = privateProps.innerParams.get(instance);
7393 instance.disableButtons();
7394 if (innerParams.returnInputValueOnDeny) {
7395 handleConfirmOrDenyWithInput(instance, 'deny');
7396 } else {
7397 deny(instance, false);
7398 }
7399 };
7400
7401 /**
7402 * @param {SweetAlert} instance
7403 * @param {(dismiss: DismissReason) => void} dismissWith
7404 */
7405 const handleCancelButtonClick = (instance, dismissWith) => {
7406 instance.disableButtons();
7407 dismissWith(DismissReason.cancel);
7408 };
7409
7410 /**
7411 * @param {SweetAlert} instance
7412 * @param {'confirm' | 'deny'} type
7413 */
7414 const handleConfirmOrDenyWithInput = (instance, type) => {
7415 const innerParams = privateProps.innerParams.get(instance);
7416 if (!innerParams.input) {
7417 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
7418 return;
7419 }
7420 const input = instance.getInput();
7421 const inputValue = getInputValue(instance, innerParams);
7422 if (innerParams.inputValidator) {
7423 handleInputValidator(instance, inputValue, type);
7424 } else if (input && !input.checkValidity()) {
7425 instance.enableButtons();
7426 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
7427 } else if (type === 'deny') {
7428 deny(instance, inputValue);
7429 } else {
7430 confirm(instance, inputValue);
7431 }
7432 };
7433
7434 /**
7435 * @param {SweetAlert} instance
7436 * @param {SweetAlertInputValue} inputValue
7437 * @param {'confirm' | 'deny'} type
7438 */
7439 const handleInputValidator = (instance, inputValue, type) => {
7440 const innerParams = privateProps.innerParams.get(instance);
7441 instance.disableInput();
7442 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
7443 validationPromise.then(validationMessage => {
7444 instance.enableButtons();
7445 instance.enableInput();
7446 if (validationMessage) {
7447 instance.showValidationMessage(validationMessage);
7448 } else if (type === 'deny') {
7449 deny(instance, inputValue);
7450 } else {
7451 confirm(instance, inputValue);
7452 }
7453 });
7454 };
7455
7456 /**
7457 * @param {SweetAlert} instance
7458 * @param {*} value
7459 */
7460 const deny = (instance, value) => {
7461 const innerParams = privateProps.innerParams.get(instance);
7462 if (innerParams.showLoaderOnDeny) {
7463 showLoading(getDenyButton());
7464 }
7465 if (innerParams.preDeny) {
7466 instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preDeny's promise is received
7467 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
7468 preDenyPromise.then(preDenyValue => {
7469 if (preDenyValue === false) {
7470 instance.hideLoading();
7471 handleAwaitingPromise(instance);
7472 } else {
7473 instance.close(/** @type SweetAlertResult */{
7474 isDenied: true,
7475 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
7476 });
7477 }
7478 }).catch(error => rejectWith(instance, error));
7479 } else {
7480 instance.close(/** @type SweetAlertResult */{
7481 isDenied: true,
7482 value
7483 });
7484 }
7485 };
7486
7487 /**
7488 * @param {SweetAlert} instance
7489 * @param {*} value
7490 */
7491 const succeedWith = (instance, value) => {
7492 instance.close(/** @type SweetAlertResult */{
7493 isConfirmed: true,
7494 value
7495 });
7496 };
7497
7498 /**
7499 *
7500 * @param {SweetAlert} instance
7501 * @param {string} error
7502 */
7503 const rejectWith = (instance, error) => {
7504 instance.rejectPromise(error);
7505 };
7506
7507 /**
7508 *
7509 * @param {SweetAlert} instance
7510 * @param {*} value
7511 */
7512 const confirm = (instance, value) => {
7513 const innerParams = privateProps.innerParams.get(instance);
7514 if (innerParams.showLoaderOnConfirm) {
7515 showLoading();
7516 }
7517 if (innerParams.preConfirm) {
7518 instance.resetValidationMessage();
7519 instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preConfirm's promise is received
7520 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
7521 preConfirmPromise.then(preConfirmValue => {
7522 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
7523 instance.hideLoading();
7524 handleAwaitingPromise(instance);
7525 } else {
7526 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
7527 }
7528 }).catch(error => rejectWith(instance, error));
7529 } else {
7530 succeedWith(instance, value);
7531 }
7532 };
7533
7534 /**
7535 * Hides loader and shows back the button which was hidden by .showLoading()
7536 * @this {SweetAlert}
7537 */
7538 function hideLoading() {
7539 // do nothing if popup is closed
7540 const innerParams = privateProps.innerParams.get(this);
7541 if (!innerParams) {
7542 return;
7543 }
7544 const domCache = privateProps.domCache.get(this);
7545 hide(domCache.loader);
7546 if (isToast()) {
7547 if (innerParams.icon) {
7548 show(getIcon());
7549 }
7550 } else {
7551 showRelatedButton(domCache);
7552 }
7553 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
7554 domCache.popup.removeAttribute('aria-busy');
7555 domCache.popup.removeAttribute('data-loading');
7556 domCache.confirmButton.disabled = false;
7557 domCache.denyButton.disabled = false;
7558 domCache.cancelButton.disabled = false;
7559 }
7560
7561 /**
7562 * @param {DomCache} domCache
7563 */
7564 const showRelatedButton = domCache => {
7565 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
7566 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
7567 if (buttonToReplace.length) {
7568 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
7569 } else if (allButtonsAreHidden()) {
7570 hide(domCache.actions);
7571 }
7572 };
7573
7574 /**
7575 * Gets the input DOM node, this method works with input parameter.
7576 *
7577 * @returns {HTMLInputElement | null}
7578 * @this {SweetAlert}
7579 */
7580 function getInput() {
7581 const innerParams = privateProps.innerParams.get(this);
7582 const domCache = privateProps.domCache.get(this);
7583 if (!domCache) {
7584 return null;
7585 }
7586 return getInput$1(domCache.popup, innerParams.input);
7587 }
7588
7589 /**
7590 * @param {SweetAlert} instance
7591 * @param {string[]} buttons
7592 * @param {boolean} disabled
7593 */
7594 function setButtonsDisabled(instance, buttons, disabled) {
7595 const domCache = privateProps.domCache.get(instance);
7596 buttons.forEach(button => {
7597 domCache[button].disabled = disabled;
7598 });
7599 }
7600
7601 /**
7602 * @param {HTMLInputElement | null} input
7603 * @param {boolean} disabled
7604 */
7605 function setInputDisabled(input, disabled) {
7606 const popup = getPopup();
7607 if (!popup || !input) {
7608 return;
7609 }
7610 if (input.type === 'radio') {
7611 /** @type {NodeListOf<HTMLInputElement>} */
7612 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
7613 for (let i = 0; i < radios.length; i++) {
7614 radios[i].disabled = disabled;
7615 }
7616 } else {
7617 input.disabled = disabled;
7618 }
7619 }
7620
7621 /**
7622 * Enable all the buttons
7623 * @this {SweetAlert}
7624 */
7625 function enableButtons() {
7626 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
7627 }
7628
7629 /**
7630 * Disable all the buttons
7631 * @this {SweetAlert}
7632 */
7633 function disableButtons() {
7634 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
7635 }
7636
7637 /**
7638 * Enable the input field
7639 * @this {SweetAlert}
7640 */
7641 function enableInput() {
7642 setInputDisabled(this.getInput(), false);
7643 }
7644
7645 /**
7646 * Disable the input field
7647 * @this {SweetAlert}
7648 */
7649 function disableInput() {
7650 setInputDisabled(this.getInput(), true);
7651 }
7652
7653 /**
7654 * Show block with validation message
7655 *
7656 * @param {string} error
7657 * @this {SweetAlert}
7658 */
7659 function showValidationMessage(error) {
7660 const domCache = privateProps.domCache.get(this);
7661 const params = privateProps.innerParams.get(this);
7662 setInnerHtml(domCache.validationMessage, error);
7663 domCache.validationMessage.className = swalClasses['validation-message'];
7664 if (params.customClass && params.customClass.validationMessage) {
7665 addClass(domCache.validationMessage, params.customClass.validationMessage);
7666 }
7667 show(domCache.validationMessage);
7668 const input = this.getInput();
7669 if (input) {
7670 input.setAttribute('aria-invalid', 'true');
7671 input.setAttribute('aria-describedby', swalClasses['validation-message']);
7672 focusInput(input);
7673 addClass(input, swalClasses.inputerror);
7674 }
7675 }
7676
7677 /**
7678 * Hide block with validation message
7679 *
7680 * @this {SweetAlert}
7681 */
7682 function resetValidationMessage() {
7683 const domCache = privateProps.domCache.get(this);
7684 if (domCache.validationMessage) {
7685 hide(domCache.validationMessage);
7686 }
7687 const input = this.getInput();
7688 if (input) {
7689 input.removeAttribute('aria-invalid');
7690 input.removeAttribute('aria-describedby');
7691 removeClass(input, swalClasses.inputerror);
7692 }
7693 }
7694
7695 const defaultParams = {
7696 title: '',
7697 titleText: '',
7698 text: '',
7699 html: '',
7700 footer: '',
7701 icon: undefined,
7702 iconColor: undefined,
7703 iconHtml: undefined,
7704 template: undefined,
7705 toast: false,
7706 draggable: false,
7707 animation: true,
7708 theme: 'light',
7709 showClass: {
7710 popup: 'swal2-show',
7711 backdrop: 'swal2-backdrop-show',
7712 icon: 'swal2-icon-show'
7713 },
7714 hideClass: {
7715 popup: 'swal2-hide',
7716 backdrop: 'swal2-backdrop-hide',
7717 icon: 'swal2-icon-hide'
7718 },
7719 customClass: {},
7720 target: 'body',
7721 color: undefined,
7722 backdrop: true,
7723 heightAuto: true,
7724 allowOutsideClick: true,
7725 allowEscapeKey: true,
7726 allowEnterKey: true,
7727 stopKeydownPropagation: true,
7728 keydownListenerCapture: false,
7729 showConfirmButton: true,
7730 showDenyButton: false,
7731 showCancelButton: false,
7732 preConfirm: undefined,
7733 preDeny: undefined,
7734 confirmButtonText: 'OK',
7735 confirmButtonAriaLabel: '',
7736 confirmButtonColor: undefined,
7737 denyButtonText: 'No',
7738 denyButtonAriaLabel: '',
7739 denyButtonColor: undefined,
7740 cancelButtonText: 'Cancel',
7741 cancelButtonAriaLabel: '',
7742 cancelButtonColor: undefined,
7743 buttonsStyling: true,
7744 reverseButtons: false,
7745 focusConfirm: true,
7746 focusDeny: false,
7747 focusCancel: false,
7748 returnFocus: true,
7749 showCloseButton: false,
7750 closeButtonHtml: '&times;',
7751 closeButtonAriaLabel: 'Close this dialog',
7752 loaderHtml: '',
7753 showLoaderOnConfirm: false,
7754 showLoaderOnDeny: false,
7755 imageUrl: undefined,
7756 imageWidth: undefined,
7757 imageHeight: undefined,
7758 imageAlt: '',
7759 timer: undefined,
7760 timerProgressBar: false,
7761 width: undefined,
7762 padding: undefined,
7763 background: undefined,
7764 input: undefined,
7765 inputPlaceholder: '',
7766 inputLabel: '',
7767 inputValue: '',
7768 inputOptions: {},
7769 inputAutoFocus: true,
7770 inputAutoTrim: true,
7771 inputAttributes: {},
7772 inputValidator: undefined,
7773 returnInputValueOnDeny: false,
7774 validationMessage: undefined,
7775 grow: false,
7776 position: 'center',
7777 progressSteps: [],
7778 currentProgressStep: undefined,
7779 progressStepsDistance: undefined,
7780 willOpen: undefined,
7781 didOpen: undefined,
7782 didRender: undefined,
7783 willClose: undefined,
7784 didClose: undefined,
7785 didDestroy: undefined,
7786 scrollbarPadding: true,
7787 topLayer: false
7788 };
7789 const updatableParams = ['allowEscapeKey', 'allowOutsideClick', 'background', 'buttonsStyling', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonText', 'closeButtonAriaLabel', 'closeButtonHtml', 'color', 'confirmButtonAriaLabel', 'confirmButtonColor', 'confirmButtonText', 'currentProgressStep', 'customClass', 'denyButtonAriaLabel', 'denyButtonColor', 'denyButtonText', 'didClose', 'didDestroy', 'draggable', 'footer', 'hideClass', 'html', 'icon', 'iconColor', 'iconHtml', 'imageAlt', 'imageHeight', 'imageUrl', 'imageWidth', 'preConfirm', 'preDeny', 'progressSteps', 'returnFocus', 'reverseButtons', 'showCancelButton', 'showCloseButton', 'showConfirmButton', 'showDenyButton', 'text', 'title', 'titleText', 'theme', 'willClose'];
7790
7791 /** @type {Record<string, string | undefined>} */
7792 const deprecatedParams = {
7793 allowEnterKey: undefined
7794 };
7795 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
7796
7797 /**
7798 * Is valid parameter
7799 *
7800 * @param {string} paramName
7801 * @returns {boolean}
7802 */
7803 const isValidParameter = paramName => {
7804 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
7805 };
7806
7807 /**
7808 * Is valid parameter for Swal.update() method
7809 *
7810 * @param {string} paramName
7811 * @returns {boolean}
7812 */
7813 const isUpdatableParameter = paramName => {
7814 return updatableParams.indexOf(paramName) !== -1;
7815 };
7816
7817 /**
7818 * Is deprecated parameter
7819 *
7820 * @param {string} paramName
7821 * @returns {string | undefined}
7822 */
7823 const isDeprecatedParameter = paramName => {
7824 return deprecatedParams[paramName];
7825 };
7826
7827 /**
7828 * @param {string} param
7829 */
7830 const checkIfParamIsValid = param => {
7831 if (!isValidParameter(param)) {
7832 warn(`Unknown parameter "${param}"`);
7833 }
7834 };
7835
7836 /**
7837 * @param {string} param
7838 */
7839 const checkIfToastParamIsValid = param => {
7840 if (toastIncompatibleParams.includes(param)) {
7841 warn(`The parameter "${param}" is incompatible with toasts`);
7842 }
7843 };
7844
7845 /**
7846 * @param {string} param
7847 */
7848 const checkIfParamIsDeprecated = param => {
7849 const isDeprecated = isDeprecatedParameter(param);
7850 if (isDeprecated) {
7851 warnAboutDeprecation(param, isDeprecated);
7852 }
7853 };
7854
7855 /**
7856 * Show relevant warnings for given params
7857 *
7858 * @param {SweetAlertOptions} params
7859 */
7860 const showWarningsForParams = params => {
7861 if (params.backdrop === false && params.allowOutsideClick) {
7862 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
7863 }
7864 if (params.theme && !['light', 'dark', 'auto', 'minimal', 'borderless', 'bootstrap-4', 'bootstrap-4-light', 'bootstrap-4-dark', 'bootstrap-5', 'bootstrap-5-light', 'bootstrap-5-dark', 'material-ui', 'material-ui-light', 'material-ui-dark', 'embed-iframe', 'bulma', 'bulma-light', 'bulma-dark'].includes(params.theme)) {
7865 warn(`Invalid theme "${params.theme}"`);
7866 }
7867 for (const param in params) {
7868 checkIfParamIsValid(param);
7869 if (params.toast) {
7870 checkIfToastParamIsValid(param);
7871 }
7872 checkIfParamIsDeprecated(param);
7873 }
7874 };
7875
7876 /**
7877 * Updates popup parameters.
7878 *
7879 * @this {any}
7880 * @param {SweetAlertOptions} params
7881 */
7882 function update(params) {
7883 const container = getContainer();
7884 const popup = getPopup();
7885 const innerParams = privateProps.innerParams.get(this);
7886 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
7887 warn(`You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.`);
7888 return;
7889 }
7890 const validUpdatableParams = filterValidParams(params);
7891 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
7892 showWarningsForParams(updatedParams);
7893 if (container) {
7894 container.dataset['swal2Theme'] = updatedParams.theme;
7895 }
7896 render(this, updatedParams);
7897 privateProps.innerParams.set(this, updatedParams);
7898 Object.defineProperties(this, {
7899 params: {
7900 value: Object.assign({}, this.params, params),
7901 writable: false,
7902 enumerable: true
7903 }
7904 });
7905 }
7906
7907 /**
7908 * @param {SweetAlertOptions} params
7909 * @returns {SweetAlertOptions}
7910 */
7911 const filterValidParams = params => {
7912 /** @type {Record<string, any>} */
7913 const validUpdatableParams = {};
7914 Object.keys(params).forEach(param => {
7915 if (isUpdatableParameter(param)) {
7916 const typedParams = /** @type {Record<string, any>} */params;
7917 validUpdatableParams[param] = typedParams[param];
7918 } else {
7919 warn(`Invalid parameter to update: ${param}`);
7920 }
7921 });
7922 return validUpdatableParams;
7923 };
7924
7925 /**
7926 * Dispose the current SweetAlert2 instance
7927 * @this {SweetAlert}
7928 */
7929 function _destroy() {
7930 var _globalState$eventEmi;
7931 const domCache = privateProps.domCache.get(this);
7932 const innerParams = privateProps.innerParams.get(this);
7933 if (!innerParams) {
7934 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
7935 return; // This instance has already been destroyed
7936 }
7937
7938 // Check if there is another Swal closing
7939 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
7940 globalState.swalCloseEventFinishedCallback();
7941 delete globalState.swalCloseEventFinishedCallback;
7942 }
7943 if (typeof innerParams.didDestroy === 'function') {
7944 innerParams.didDestroy();
7945 }
7946 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
7947 disposeSwal(this);
7948 }
7949
7950 /**
7951 * @param {SweetAlert} instance
7952 */
7953 const disposeSwal = instance => {
7954 disposeWeakMaps(instance);
7955 // Unset this.params so GC will dispose it (#1569)
7956 // @ts-ignore
7957 delete instance.params;
7958 // Unset globalState props so GC will dispose globalState (#1569)
7959 delete globalState.keydownHandler;
7960 delete globalState.keydownTarget;
7961 // Unset currentInstance
7962 delete globalState.currentInstance;
7963 };
7964
7965 /**
7966 * @param {SweetAlert} instance
7967 */
7968 const disposeWeakMaps = instance => {
7969 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
7970 if (instance.isAwaitingPromise) {
7971 unsetWeakMaps(privateProps, instance);
7972 instance.isAwaitingPromise = true;
7973 } else {
7974 unsetWeakMaps(privateMethods, instance);
7975 unsetWeakMaps(privateProps, instance);
7976
7977 // @ts-ignore
7978 delete instance.isAwaitingPromise;
7979 // Unset instance methods
7980 // @ts-ignore
7981 delete instance.disableButtons;
7982 // @ts-ignore
7983 delete instance.enableButtons;
7984 // @ts-ignore
7985 delete instance.getInput;
7986 // @ts-ignore
7987 delete instance.disableInput;
7988 // @ts-ignore
7989 delete instance.enableInput;
7990 // @ts-ignore
7991 delete instance.hideLoading;
7992 // @ts-ignore
7993 delete instance.disableLoading;
7994 // @ts-ignore
7995 delete instance.showValidationMessage;
7996 // @ts-ignore
7997 delete instance.resetValidationMessage;
7998 // @ts-ignore
7999 delete instance.close;
8000 // @ts-ignore
8001 delete instance.closePopup;
8002 // @ts-ignore
8003 delete instance.closeModal;
8004 // @ts-ignore
8005 delete instance.closeToast;
8006 // @ts-ignore
8007 delete instance.rejectPromise;
8008 // @ts-ignore
8009 delete instance.update;
8010 // @ts-ignore
8011 delete instance._destroy;
8012 }
8013 };
8014
8015 /**
8016 * @param {Record<string, WeakMap<any, any>>} obj
8017 * @param {SweetAlert} instance
8018 */
8019 const unsetWeakMaps = (obj, instance) => {
8020 for (const i in obj) {
8021 obj[i].delete(instance);
8022 }
8023 };
8024
8025 var instanceMethods = /*#__PURE__*/Object.freeze({
8026 __proto__: null,
8027 _destroy: _destroy,
8028 close: close,
8029 closeModal: close,
8030 closePopup: close,
8031 closeToast: close,
8032 disableButtons: disableButtons,
8033 disableInput: disableInput,
8034 disableLoading: hideLoading,
8035 enableButtons: enableButtons,
8036 enableInput: enableInput,
8037 getInput: getInput,
8038 handleAwaitingPromise: handleAwaitingPromise,
8039 hideLoading: hideLoading,
8040 rejectPromise: rejectPromise,
8041 resetValidationMessage: resetValidationMessage,
8042 showValidationMessage: showValidationMessage,
8043 update: update
8044 });
8045
8046 /**
8047 * @param {SweetAlertOptions} innerParams
8048 * @param {DomCache} domCache
8049 * @param {(dismiss: DismissReason) => void} dismissWith
8050 */
8051 const handlePopupClick = (innerParams, domCache, dismissWith) => {
8052 if (innerParams.toast) {
8053 handleToastClick(innerParams, domCache, dismissWith);
8054 } else {
8055 // Ignore click events that had mousedown on the popup but mouseup on the container
8056 // This can happen when the user drags a slider
8057 handleModalMousedown(domCache);
8058
8059 // Ignore click events that had mousedown on the container but mouseup on the popup
8060 handleContainerMousedown(domCache);
8061 handleModalClick(innerParams, domCache, dismissWith);
8062 }
8063 };
8064
8065 /**
8066 * @param {SweetAlertOptions} innerParams
8067 * @param {DomCache} domCache
8068 * @param {(dismiss: DismissReason) => void} dismissWith
8069 */
8070 const handleToastClick = (innerParams, domCache, dismissWith) => {
8071 // Closing toast by internal click
8072 domCache.popup.onclick = () => {
8073 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
8074 return;
8075 }
8076 dismissWith(DismissReason.close);
8077 };
8078 };
8079
8080 /**
8081 * @param {SweetAlertOptions} innerParams
8082 * @returns {boolean}
8083 */
8084 const isAnyButtonShown = innerParams => {
8085 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
8086 };
8087 let ignoreOutsideClick = false;
8088
8089 /**
8090 * @param {DomCache} domCache
8091 */
8092 const handleModalMousedown = domCache => {
8093 domCache.popup.onmousedown = () => {
8094 domCache.container.onmouseup = function (e) {
8095 domCache.container.onmouseup = () => {};
8096 // We only check if the mouseup target is the container because usually it doesn't
8097 // have any other direct children aside of the popup
8098 if (e.target === domCache.container) {
8099 ignoreOutsideClick = true;
8100 }
8101 };
8102 };
8103 };
8104
8105 /**
8106 * @param {DomCache} domCache
8107 */
8108 const handleContainerMousedown = domCache => {
8109 domCache.container.onmousedown = e => {
8110 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
8111 if (e.target === domCache.container) {
8112 e.preventDefault();
8113 }
8114 domCache.popup.onmouseup = function (e) {
8115 domCache.popup.onmouseup = () => {};
8116 // We also need to check if the mouseup target is a child of the popup
8117 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
8118 ignoreOutsideClick = true;
8119 }
8120 };
8121 };
8122 };
8123
8124 /**
8125 * @param {SweetAlertOptions} innerParams
8126 * @param {DomCache} domCache
8127 * @param {(dismiss: DismissReason) => void} dismissWith
8128 */
8129 const handleModalClick = (innerParams, domCache, dismissWith) => {
8130 domCache.container.onclick = e => {
8131 if (ignoreOutsideClick) {
8132 ignoreOutsideClick = false;
8133 return;
8134 }
8135 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
8136 dismissWith(DismissReason.backdrop);
8137 }
8138 };
8139 };
8140
8141 /**
8142 * @param {any} elem
8143 * @returns {boolean}
8144 */
8145 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
8146
8147 /**
8148 * @param {any} elem
8149 * @returns {boolean}
8150 */
8151 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
8152
8153 /**
8154 * @param {any[]} args
8155 * @returns {SweetAlertOptions}
8156 */
8157 const argsToParams = args => {
8158 /** @type {Record<string, any>} */
8159 const params = {};
8160 if (typeof args[0] === 'object' && !isElement(args[0])) {
8161 Object.assign(params, args[0]);
8162 } else {
8163 ['title', 'html', 'icon'].forEach((name, index) => {
8164 const arg = args[index];
8165 if (typeof arg === 'string' || isElement(arg)) {
8166 params[name] = arg;
8167 } else if (arg !== undefined) {
8168 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
8169 }
8170 });
8171 }
8172 return params;
8173 };
8174
8175 /**
8176 * Main method to create a new SweetAlert2 popup
8177 *
8178 * @this {new (...args: any[]) => any}
8179 * @param {...SweetAlertOptions} args
8180 * @returns {Promise<SweetAlertResult>}
8181 */
8182 function fire(...args) {
8183 return new this(...args);
8184 }
8185
8186 /**
8187 * Returns an extended version of `Swal` containing `params` as defaults.
8188 * Useful for reusing Swal configuration.
8189 *
8190 * For example:
8191 *
8192 * Before:
8193 * const textPromptOptions = { input: 'text', showCancelButton: true }
8194 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
8195 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
8196 *
8197 * After:
8198 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
8199 * const {value: firstName} = await TextPrompt('What is your first name?')
8200 * const {value: lastName} = await TextPrompt('What is your last name?')
8201 *
8202 * @param {SweetAlertOptions} mixinParams
8203 * @returns {SweetAlert}
8204 * @this {typeof import('../SweetAlert.js').SweetAlert}
8205 */
8206 function mixin(mixinParams) {
8207 // @ts-ignore: 'this' refers to the SweetAlert constructor
8208 class MixinSwal extends this {
8209 /**
8210 * @param {any} params
8211 * @param {any} priorityMixinParams
8212 */
8213 _main(params, priorityMixinParams) {
8214 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
8215 }
8216 }
8217 // @ts-ignore
8218 return MixinSwal;
8219 }
8220
8221 /**
8222 * If `timer` parameter is set, returns number of milliseconds of timer remained.
8223 * Otherwise, returns undefined.
8224 *
8225 * @returns {number | undefined}
8226 */
8227 const getTimerLeft = () => {
8228 return globalState.timeout && globalState.timeout.getTimerLeft();
8229 };
8230
8231 /**
8232 * Stop timer. Returns number of milliseconds of timer remained.
8233 * If `timer` parameter isn't set, returns undefined.
8234 *
8235 * @returns {number | undefined}
8236 */
8237 const stopTimer = () => {
8238 if (globalState.timeout) {
8239 stopTimerProgressBar();
8240 return globalState.timeout.stop();
8241 }
8242 };
8243
8244 /**
8245 * Resume timer. Returns number of milliseconds of timer remained.
8246 * If `timer` parameter isn't set, returns undefined.
8247 *
8248 * @returns {number | undefined}
8249 */
8250 const resumeTimer = () => {
8251 if (globalState.timeout) {
8252 const remaining = globalState.timeout.start();
8253 animateTimerProgressBar(remaining);
8254 return remaining;
8255 }
8256 };
8257
8258 /**
8259 * Resume timer. Returns number of milliseconds of timer remained.
8260 * If `timer` parameter isn't set, returns undefined.
8261 *
8262 * @returns {number | undefined}
8263 */
8264 const toggleTimer = () => {
8265 const timer = globalState.timeout;
8266 return timer && (timer.running ? stopTimer() : resumeTimer());
8267 };
8268
8269 /**
8270 * Increase timer. Returns number of milliseconds of an updated timer.
8271 * If `timer` parameter isn't set, returns undefined.
8272 *
8273 * @param {number} ms
8274 * @returns {number | undefined}
8275 */
8276 const increaseTimer = ms => {
8277 if (globalState.timeout) {
8278 const remaining = globalState.timeout.increase(ms);
8279 animateTimerProgressBar(remaining, true);
8280 return remaining;
8281 }
8282 };
8283
8284 /**
8285 * Check if timer is running. Returns true if timer is running
8286 * or false if timer is paused or stopped.
8287 * If `timer` parameter isn't set, returns undefined
8288 *
8289 * @returns {boolean}
8290 */
8291 const isTimerRunning = () => {
8292 return Boolean(globalState.timeout && globalState.timeout.isRunning());
8293 };
8294
8295 let bodyClickListenerAdded = false;
8296 /** @type {Record<string, any>} */
8297 const clickHandlers = {};
8298
8299 /**
8300 * @this {any}
8301 * @param {string} attr
8302 */
8303 function bindClickHandler(attr = 'data-swal-template') {
8304 clickHandlers[attr] = this;
8305 if (!bodyClickListenerAdded) {
8306 document.body.addEventListener('click', bodyClickListener);
8307 bodyClickListenerAdded = true;
8308 }
8309 }
8310
8311 /**
8312 * @param {MouseEvent} event
8313 */
8314 const bodyClickListener = event => {
8315 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
8316 for (const attr in clickHandlers) {
8317 const template = el.getAttribute && el.getAttribute(attr);
8318 if (template) {
8319 clickHandlers[attr].fire({
8320 template
8321 });
8322 return;
8323 }
8324 }
8325 }
8326 };
8327
8328 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
8329
8330 class EventEmitter {
8331 constructor() {
8332 /** @type {Events} */
8333 this.events = {};
8334 }
8335
8336 /**
8337 * @param {string} eventName
8338 * @returns {EventHandlers}
8339 */
8340 _getHandlersByEventName(eventName) {
8341 if (typeof this.events[eventName] === 'undefined') {
8342 // not Set because we need to keep the FIFO order
8343 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
8344 this.events[eventName] = [];
8345 }
8346 return this.events[eventName];
8347 }
8348
8349 /**
8350 * @param {string} eventName
8351 * @param {EventHandler} eventHandler
8352 */
8353 on(eventName, eventHandler) {
8354 const currentHandlers = this._getHandlersByEventName(eventName);
8355 if (!currentHandlers.includes(eventHandler)) {
8356 currentHandlers.push(eventHandler);
8357 }
8358 }
8359
8360 /**
8361 * @param {string} eventName
8362 * @param {EventHandler} eventHandler
8363 */
8364 once(eventName, eventHandler) {
8365 /**
8366 * @param {...any} args
8367 */
8368 const onceFn = (...args) => {
8369 this.removeListener(eventName, onceFn);
8370 // @ts-ignore
8371 eventHandler.apply(this, args);
8372 };
8373 this.on(eventName, onceFn);
8374 }
8375
8376 /**
8377 * @param {string} eventName
8378 * @param {...any} args
8379 */
8380 emit(eventName, ...args) {
8381 this._getHandlersByEventName(eventName).forEach(
8382 /**
8383 * @param {EventHandler} eventHandler
8384 */
8385 eventHandler => {
8386 try {
8387 // @ts-ignore
8388 eventHandler.apply(this, args);
8389 } catch (error) {
8390 console.error(error);
8391 }
8392 });
8393 }
8394
8395 /**
8396 * @param {string} eventName
8397 * @param {EventHandler} eventHandler
8398 */
8399 removeListener(eventName, eventHandler) {
8400 const currentHandlers = this._getHandlersByEventName(eventName);
8401 const index = currentHandlers.indexOf(eventHandler);
8402 if (index > -1) {
8403 currentHandlers.splice(index, 1);
8404 }
8405 }
8406
8407 /**
8408 * @param {string} eventName
8409 */
8410 removeAllListeners(eventName) {
8411 if (this.events[eventName] !== undefined) {
8412 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
8413 this.events[eventName].length = 0;
8414 }
8415 }
8416 reset() {
8417 this.events = {};
8418 }
8419 }
8420
8421 globalState.eventEmitter = new EventEmitter();
8422
8423 /**
8424 * @param {string} eventName
8425 * @param {EventHandler} eventHandler
8426 */
8427 const on = (eventName, eventHandler) => {
8428 if (globalState.eventEmitter) {
8429 globalState.eventEmitter.on(eventName, eventHandler);
8430 }
8431 };
8432
8433 /**
8434 * @param {string} eventName
8435 * @param {EventHandler} eventHandler
8436 */
8437 const once = (eventName, eventHandler) => {
8438 if (globalState.eventEmitter) {
8439 globalState.eventEmitter.once(eventName, eventHandler);
8440 }
8441 };
8442
8443 /**
8444 * @param {string} [eventName]
8445 * @param {EventHandler} [eventHandler]
8446 */
8447 const off = (eventName, eventHandler) => {
8448 if (!globalState.eventEmitter) {
8449 return;
8450 }
8451
8452 // Remove all handlers for all events
8453 if (!eventName) {
8454 globalState.eventEmitter.reset();
8455 return;
8456 }
8457 if (eventHandler) {
8458 // Remove a specific handler
8459 globalState.eventEmitter.removeListener(eventName, eventHandler);
8460 } else {
8461 // Remove all handlers for a specific event
8462 globalState.eventEmitter.removeAllListeners(eventName);
8463 }
8464 };
8465
8466 var staticMethods = /*#__PURE__*/Object.freeze({
8467 __proto__: null,
8468 argsToParams: argsToParams,
8469 bindClickHandler: bindClickHandler,
8470 clickCancel: clickCancel,
8471 clickConfirm: clickConfirm,
8472 clickDeny: clickDeny,
8473 enableLoading: showLoading,
8474 fire: fire,
8475 getActions: getActions,
8476 getCancelButton: getCancelButton,
8477 getCloseButton: getCloseButton,
8478 getConfirmButton: getConfirmButton,
8479 getContainer: getContainer,
8480 getDenyButton: getDenyButton,
8481 getFocusableElements: getFocusableElements,
8482 getFooter: getFooter,
8483 getHtmlContainer: getHtmlContainer,
8484 getIcon: getIcon,
8485 getIconContent: getIconContent,
8486 getImage: getImage,
8487 getInputLabel: getInputLabel,
8488 getLoader: getLoader,
8489 getPopup: getPopup,
8490 getProgressSteps: getProgressSteps,
8491 getTimerLeft: getTimerLeft,
8492 getTimerProgressBar: getTimerProgressBar,
8493 getTitle: getTitle,
8494 getValidationMessage: getValidationMessage,
8495 increaseTimer: increaseTimer,
8496 isDeprecatedParameter: isDeprecatedParameter,
8497 isLoading: isLoading,
8498 isTimerRunning: isTimerRunning,
8499 isUpdatableParameter: isUpdatableParameter,
8500 isValidParameter: isValidParameter,
8501 isVisible: isVisible,
8502 mixin: mixin,
8503 off: off,
8504 on: on,
8505 once: once,
8506 resumeTimer: resumeTimer,
8507 showLoading: showLoading,
8508 stopTimer: stopTimer,
8509 toggleTimer: toggleTimer
8510 });
8511
8512 class Timer {
8513 /**
8514 * @param {() => void} callback
8515 * @param {number} delay
8516 */
8517 constructor(callback, delay) {
8518 this.callback = callback;
8519 this.remaining = delay;
8520 this.running = false;
8521 this.start();
8522 }
8523
8524 /**
8525 * @returns {number}
8526 */
8527 start() {
8528 if (!this.running) {
8529 this.running = true;
8530 this.started = new Date();
8531 this.id = setTimeout(this.callback, this.remaining);
8532 }
8533 return this.remaining;
8534 }
8535
8536 /**
8537 * @returns {number}
8538 */
8539 stop() {
8540 if (this.started && this.running) {
8541 this.running = false;
8542 clearTimeout(this.id);
8543 this.remaining -= new Date().getTime() - this.started.getTime();
8544 }
8545 return this.remaining;
8546 }
8547
8548 /**
8549 * @param {number} n
8550 * @returns {number}
8551 */
8552 increase(n) {
8553 const running = this.running;
8554 if (running) {
8555 this.stop();
8556 }
8557 this.remaining += n;
8558 if (running) {
8559 this.start();
8560 }
8561 return this.remaining;
8562 }
8563
8564 /**
8565 * @returns {number}
8566 */
8567 getTimerLeft() {
8568 if (this.running) {
8569 this.stop();
8570 this.start();
8571 }
8572 return this.remaining;
8573 }
8574
8575 /**
8576 * @returns {boolean}
8577 */
8578 isRunning() {
8579 return this.running;
8580 }
8581 }
8582
8583 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
8584
8585 /**
8586 * @param {SweetAlertOptions} params
8587 * @returns {SweetAlertOptions}
8588 */
8589 const getTemplateParams = params => {
8590 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
8591 if (!template) {
8592 return {};
8593 }
8594 /** @type {DocumentFragment} */
8595 const templateContent = template.content;
8596 showWarningsForElements(templateContent);
8597 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
8598 return result;
8599 };
8600
8601 /**
8602 * @param {DocumentFragment} templateContent
8603 * @returns {Record<string, string | boolean | number>}
8604 */
8605 const getSwalParams = templateContent => {
8606 /** @type {Record<string, string | boolean | number>} */
8607 const result = {};
8608 /** @type {HTMLElement[]} */
8609 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
8610 swalParams.forEach(param => {
8611 showWarningsForAttributes(param, ['name', 'value']);
8612 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
8613 const value = param.getAttribute('value');
8614 if (!paramName || !value) {
8615 return;
8616 }
8617 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
8618 result[paramName] = value !== 'false';
8619 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
8620 result[paramName] = JSON.parse(value);
8621 } else {
8622 result[paramName] = value;
8623 }
8624 });
8625 return result;
8626 };
8627
8628 /**
8629 * @param {DocumentFragment} templateContent
8630 * @returns {Record<string, () => void>}
8631 */
8632 const getSwalFunctionParams = templateContent => {
8633 /** @type {Record<string, () => void>} */
8634 const result = {};
8635 /** @type {HTMLElement[]} */
8636 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
8637 swalFunctions.forEach(param => {
8638 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
8639 const value = param.getAttribute('value');
8640 if (!paramName || !value) {
8641 return;
8642 }
8643 result[paramName] = new Function(`return ${value}`)();
8644 });
8645 return result;
8646 };
8647
8648 /**
8649 * @param {DocumentFragment} templateContent
8650 * @returns {Record<string, string | boolean>}
8651 */
8652 const getSwalButtons = templateContent => {
8653 /** @type {Record<string, string | boolean>} */
8654 const result = {};
8655 /** @type {HTMLElement[]} */
8656 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
8657 swalButtons.forEach(button => {
8658 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
8659 const type = button.getAttribute('type');
8660 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
8661 return;
8662 }
8663 result[`${type}ButtonText`] = button.innerHTML;
8664 result[`show${capitalizeFirstLetter(type)}Button`] = true;
8665 if (button.hasAttribute('color')) {
8666 const color = button.getAttribute('color');
8667 if (color !== null) {
8668 result[`${type}ButtonColor`] = color;
8669 }
8670 }
8671 if (button.hasAttribute('aria-label')) {
8672 const ariaLabel = button.getAttribute('aria-label');
8673 if (ariaLabel !== null) {
8674 result[`${type}ButtonAriaLabel`] = ariaLabel;
8675 }
8676 }
8677 });
8678 return result;
8679 };
8680
8681 /**
8682 * @param {DocumentFragment} templateContent
8683 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
8684 */
8685 const getSwalImage = templateContent => {
8686 const result = {};
8687 /** @type {HTMLElement | null} */
8688 const image = templateContent.querySelector('swal-image');
8689 if (image) {
8690 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
8691 if (image.hasAttribute('src')) {
8692 result.imageUrl = image.getAttribute('src') || undefined;
8693 }
8694 if (image.hasAttribute('width')) {
8695 result.imageWidth = image.getAttribute('width') || undefined;
8696 }
8697 if (image.hasAttribute('height')) {
8698 result.imageHeight = image.getAttribute('height') || undefined;
8699 }
8700 if (image.hasAttribute('alt')) {
8701 result.imageAlt = image.getAttribute('alt') || undefined;
8702 }
8703 }
8704 return result;
8705 };
8706
8707 /**
8708 * @param {DocumentFragment} templateContent
8709 * @returns {object}
8710 */
8711 const getSwalIcon = templateContent => {
8712 const result = {};
8713 /** @type {HTMLElement | null} */
8714 const icon = templateContent.querySelector('swal-icon');
8715 if (icon) {
8716 showWarningsForAttributes(icon, ['type', 'color']);
8717 if (icon.hasAttribute('type')) {
8718 result.icon = icon.getAttribute('type');
8719 }
8720 if (icon.hasAttribute('color')) {
8721 result.iconColor = icon.getAttribute('color');
8722 }
8723 result.iconHtml = icon.innerHTML;
8724 }
8725 return result;
8726 };
8727
8728 /**
8729 * @param {DocumentFragment} templateContent
8730 * @returns {object}
8731 */
8732 const getSwalInput = templateContent => {
8733 /** @type {Record<string, any>} */
8734 const result = {};
8735 /** @type {HTMLElement | null} */
8736 const input = templateContent.querySelector('swal-input');
8737 if (input) {
8738 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
8739 result.input = input.getAttribute('type') || 'text';
8740 if (input.hasAttribute('label')) {
8741 result.inputLabel = input.getAttribute('label');
8742 }
8743 if (input.hasAttribute('placeholder')) {
8744 result.inputPlaceholder = input.getAttribute('placeholder');
8745 }
8746 if (input.hasAttribute('value')) {
8747 result.inputValue = input.getAttribute('value');
8748 }
8749 }
8750 /** @type {HTMLElement[]} */
8751 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
8752 if (inputOptions.length) {
8753 result.inputOptions = {};
8754 inputOptions.forEach(option => {
8755 showWarningsForAttributes(option, ['value']);
8756 const optionValue = option.getAttribute('value');
8757 if (!optionValue) {
8758 return;
8759 }
8760 const optionName = option.innerHTML;
8761 result.inputOptions[optionValue] = optionName;
8762 });
8763 }
8764 return result;
8765 };
8766
8767 /**
8768 * @param {DocumentFragment} templateContent
8769 * @param {string[]} paramNames
8770 * @returns {Record<string, string>}
8771 */
8772 const getSwalStringParams = (templateContent, paramNames) => {
8773 /** @type {Record<string, string>} */
8774 const result = {};
8775 for (const i in paramNames) {
8776 const paramName = paramNames[i];
8777 /** @type {HTMLElement | null} */
8778 const tag = templateContent.querySelector(paramName);
8779 if (tag) {
8780 showWarningsForAttributes(tag, []);
8781 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
8782 }
8783 }
8784 return result;
8785 };
8786
8787 /**
8788 * @param {DocumentFragment} templateContent
8789 */
8790 const showWarningsForElements = templateContent => {
8791 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
8792 Array.from(templateContent.children).forEach(el => {
8793 const tagName = el.tagName.toLowerCase();
8794 if (!allowedElements.includes(tagName)) {
8795 warn(`Unrecognized element <${tagName}>`);
8796 }
8797 });
8798 };
8799
8800 /**
8801 * @param {HTMLElement} el
8802 * @param {string[]} allowedAttributes
8803 */
8804 const showWarningsForAttributes = (el, allowedAttributes) => {
8805 Array.from(el.attributes).forEach(attribute => {
8806 if (allowedAttributes.indexOf(attribute.name) === -1) {
8807 warn([`Unrecognized attribute "${attribute.name}" on <${el.tagName.toLowerCase()}>.`, `${allowedAttributes.length ? `Allowed attributes are: ${allowedAttributes.join(', ')}` : 'To set the value, use HTML within the element.'}`]);
8808 }
8809 });
8810 };
8811
8812 const SHOW_CLASS_TIMEOUT = 10;
8813
8814 /**
8815 * Open popup, add necessary classes and styles, fix scrollbar
8816 *
8817 * @param {SweetAlertOptions} params
8818 */
8819 const openPopup = params => {
8820 var _globalState$eventEmi, _globalState$eventEmi2;
8821 const container = getContainer();
8822 const popup = getPopup();
8823 if (!container || !popup) {
8824 return;
8825 }
8826 if (typeof params.willOpen === 'function') {
8827 params.willOpen(popup);
8828 }
8829 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
8830 const bodyStyles = window.getComputedStyle(document.body);
8831 const initialBodyOverflow = bodyStyles.overflowY;
8832 addClasses(container, popup, params);
8833
8834 // scrolling is 'hidden' until animation is done, after that 'auto'
8835 setTimeout(() => {
8836 setScrollingVisibility(container, popup);
8837 }, SHOW_CLASS_TIMEOUT);
8838 if (isModal()) {
8839 // Using ternary instead of ?? operator for Webpack 4 compatibility
8840 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
8841 setAriaHidden();
8842 }
8843 if (!isToast() && !globalState.previousActiveElement) {
8844 globalState.previousActiveElement = document.activeElement;
8845 }
8846 if (typeof params.didOpen === 'function') {
8847 const didOpen = params.didOpen;
8848 setTimeout(() => didOpen(popup));
8849 }
8850 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
8851 };
8852
8853 /**
8854 * @param {Event} event
8855 */
8856 const swalOpenAnimationFinished = event => {
8857 const popup = getPopup();
8858 if (!popup || event.target !== popup) {
8859 return;
8860 }
8861 const container = getContainer();
8862 if (!container) {
8863 return;
8864 }
8865 popup.removeEventListener('animationend', swalOpenAnimationFinished);
8866 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
8867 container.style.overflowY = 'auto';
8868
8869 // no-transition is added in init() in case one swal is opened right after another
8870 removeClass(container, swalClasses['no-transition']);
8871 };
8872
8873 /**
8874 * @param {HTMLElement} container
8875 * @param {HTMLElement} popup
8876 */
8877 const setScrollingVisibility = (container, popup) => {
8878 if (hasCssAnimation(popup)) {
8879 container.style.overflowY = 'hidden';
8880 popup.addEventListener('animationend', swalOpenAnimationFinished);
8881 popup.addEventListener('transitionend', swalOpenAnimationFinished);
8882 } else {
8883 container.style.overflowY = 'auto';
8884 }
8885 };
8886
8887 /**
8888 * @param {HTMLElement} container
8889 * @param {boolean} scrollbarPadding
8890 * @param {string} initialBodyOverflow
8891 */
8892 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
8893 iOSfix();
8894 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
8895 replaceScrollbarWithPadding(initialBodyOverflow);
8896 }
8897
8898 // sweetalert2/issues/1247
8899 setTimeout(() => {
8900 container.scrollTop = 0;
8901 });
8902 };
8903
8904 /**
8905 * @param {HTMLElement} container
8906 * @param {HTMLElement} popup
8907 * @param {SweetAlertOptions} params
8908 */
8909 const addClasses = (container, popup, params) => {
8910 var _params$showClass;
8911 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
8912 addClass(container, params.showClass.backdrop);
8913 }
8914 if (params.animation) {
8915 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
8916 popup.style.setProperty('opacity', '0', 'important');
8917 show(popup, 'grid');
8918 setTimeout(() => {
8919 var _params$showClass2;
8920 // Animate popup right after showing it
8921 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
8922 addClass(popup, params.showClass.popup);
8923 }
8924 // and remove the opacity workaround
8925 popup.style.removeProperty('opacity');
8926 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
8927 } else {
8928 show(popup, 'grid');
8929 }
8930 addClass([document.documentElement, document.body], swalClasses.shown);
8931 if (params.heightAuto && params.backdrop && !params.toast) {
8932 addClass([document.documentElement, document.body], swalClasses['height-auto']);
8933 }
8934 };
8935
8936 var defaultInputValidators = {
8937 /**
8938 * @param {string} string
8939 * @param {string} [validationMessage]
8940 * @returns {Promise<string | void>}
8941 */
8942 email: (string, validationMessage) => {
8943 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
8944 },
8945 /**
8946 * @param {string} string
8947 * @param {string} [validationMessage]
8948 * @returns {Promise<string | void>}
8949 */
8950 url: (string, validationMessage) => {
8951 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
8952 return /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid URL');
8953 }
8954 };
8955
8956 /**
8957 * @param {SweetAlertOptions} params
8958 */
8959 function setDefaultInputValidators(params) {
8960 // Use default `inputValidator` for supported input types if not provided
8961 if (params.inputValidator) {
8962 return;
8963 }
8964 if (params.input === 'email') {
8965 params.inputValidator = defaultInputValidators['email'];
8966 }
8967 if (params.input === 'url') {
8968 params.inputValidator = defaultInputValidators['url'];
8969 }
8970 }
8971
8972 /**
8973 * @param {SweetAlertOptions} params
8974 */
8975 function validateCustomTargetElement(params) {
8976 // Determine if the custom target element is valid
8977 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
8978 warn('Target parameter is not valid, defaulting to "body"');
8979 params.target = 'body';
8980 }
8981 }
8982
8983 /**
8984 * Set type, text and actions on popup
8985 *
8986 * @param {SweetAlertOptions} params
8987 */
8988 function setParameters(params) {
8989 setDefaultInputValidators(params);
8990
8991 // showLoaderOnConfirm && preConfirm
8992 if (params.showLoaderOnConfirm && !params.preConfirm) {
8993 warn('showLoaderOnConfirm is set to true, but preConfirm is not defined.\n' + 'showLoaderOnConfirm should be used together with preConfirm, see usage example:\n' + 'https://sweetalert2.github.io/#ajax-request');
8994 }
8995 validateCustomTargetElement(params);
8996
8997 // Replace newlines with <br> in title
8998 if (typeof params.title === 'string') {
8999 params.title = params.title.split('\n').join('<br />');
9000 }
9001 init(params);
9002 }
9003
9004 /** @type {SweetAlert} */
9005 let currentInstance;
9006 var _promise = /*#__PURE__*/new WeakMap();
9007 class SweetAlert {
9008 /**
9009 * @param {...(SweetAlertOptions | string)} args
9010 * @this {SweetAlert}
9011 */
9012 constructor(...args) {
9013 /**
9014 * @type {Promise<SweetAlertResult>}
9015 */
9016 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */Promise.resolve({
9017 isConfirmed: false,
9018 isDenied: false,
9019 isDismissed: true
9020 }));
9021 // Prevent run in Node env
9022 if (typeof window === 'undefined') {
9023 return;
9024 }
9025 currentInstance = this;
9026
9027 // @ts-ignore
9028 const outerParams = Object.freeze(this.constructor.argsToParams(args));
9029
9030 /** @type {Readonly<SweetAlertOptions>} */
9031 this.params = outerParams;
9032
9033 /** @type {boolean} */
9034 this.isAwaitingPromise = false;
9035 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
9036 }
9037
9038 /**
9039 * @param {any} userParams
9040 * @param {any} mixinParams
9041 */
9042 _main(userParams, mixinParams = {}) {
9043 showWarningsForParams(Object.assign({}, mixinParams, userParams));
9044 if (globalState.currentInstance) {
9045 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
9046 const {
9047 isAwaitingPromise
9048 } = globalState.currentInstance;
9049 globalState.currentInstance._destroy();
9050 if (!isAwaitingPromise) {
9051 swalPromiseResolve({
9052 isDismissed: true
9053 });
9054 }
9055 if (isModal()) {
9056 unsetAriaHidden();
9057 }
9058 }
9059 globalState.currentInstance = currentInstance;
9060 const innerParams = prepareParams(userParams, mixinParams);
9061 setParameters(innerParams);
9062 Object.freeze(innerParams);
9063
9064 // clear the previous timer
9065 if (globalState.timeout) {
9066 globalState.timeout.stop();
9067 delete globalState.timeout;
9068 }
9069
9070 // clear the restore focus timeout
9071 clearTimeout(globalState.restoreFocusTimeout);
9072 const domCache = populateDomCache(currentInstance);
9073 render(currentInstance, innerParams);
9074 privateProps.innerParams.set(currentInstance, innerParams);
9075 return swalPromise(currentInstance, domCache, innerParams);
9076 }
9077
9078 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
9079 /**
9080 * @param {any} onFulfilled
9081 */
9082 then(onFulfilled) {
9083 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
9084 }
9085
9086 /**
9087 * @param {any} onFinally
9088 */
9089 finally(onFinally) {
9090 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
9091 }
9092 }
9093
9094 /**
9095 * @param {SweetAlert} instance
9096 * @param {DomCache} domCache
9097 * @param {SweetAlertOptions} innerParams
9098 * @returns {Promise<SweetAlertResult>}
9099 */
9100 const swalPromise = (instance, domCache, innerParams) => {
9101 return new Promise((resolve, reject) => {
9102 // functions to handle all closings/dismissals
9103 /**
9104 * @param {DismissReason} dismiss
9105 */
9106 const dismissWith = dismiss => {
9107 instance.close({
9108 isDismissed: true,
9109 dismiss,
9110 isConfirmed: false,
9111 isDenied: false
9112 });
9113 };
9114 privateMethods.swalPromiseResolve.set(instance, resolve);
9115 privateMethods.swalPromiseReject.set(instance, reject);
9116 domCache.confirmButton.onclick = () => {
9117 handleConfirmButtonClick(instance);
9118 };
9119 domCache.denyButton.onclick = () => {
9120 handleDenyButtonClick(instance);
9121 };
9122 domCache.cancelButton.onclick = () => {
9123 handleCancelButtonClick(instance, dismissWith);
9124 };
9125 domCache.closeButton.onclick = () => {
9126 dismissWith(DismissReason.close);
9127 };
9128 handlePopupClick(innerParams, domCache, dismissWith);
9129 addKeydownHandler(globalState, innerParams, dismissWith);
9130 handleInputOptionsAndValue(instance, innerParams);
9131 openPopup(innerParams);
9132 setupTimer(globalState, innerParams, dismissWith);
9133 initFocus(domCache, innerParams);
9134
9135 // Scroll container to top on open (#1247, #1946)
9136 setTimeout(() => {
9137 domCache.container.scrollTop = 0;
9138 });
9139 });
9140 };
9141
9142 /**
9143 * @param {SweetAlertOptions} userParams
9144 * @param {SweetAlertOptions} mixinParams
9145 * @returns {SweetAlertOptions}
9146 */
9147 const prepareParams = (userParams, mixinParams) => {
9148 const templateParams = getTemplateParams(userParams);
9149 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
9150 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
9151 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
9152 if (params.animation === false) {
9153 params.showClass = {
9154 backdrop: 'swal2-noanimation'
9155 };
9156 params.hideClass = {};
9157 }
9158 return params;
9159 };
9160
9161 /**
9162 * @param {SweetAlert} instance
9163 * @returns {DomCache}
9164 */
9165 const populateDomCache = instance => {
9166 const domCache = /** @type {DomCache} */{
9167 popup: (/** @type {HTMLElement} */getPopup()),
9168 container: (/** @type {HTMLElement} */getContainer()),
9169 actions: (/** @type {HTMLElement} */getActions()),
9170 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
9171 denyButton: (/** @type {HTMLElement} */getDenyButton()),
9172 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
9173 loader: (/** @type {HTMLElement} */getLoader()),
9174 closeButton: (/** @type {HTMLElement} */getCloseButton()),
9175 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
9176 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
9177 };
9178 privateProps.domCache.set(instance, domCache);
9179 return domCache;
9180 };
9181
9182 /**
9183 * @param {GlobalState} globalState
9184 * @param {SweetAlertOptions} innerParams
9185 * @param {(dismiss: DismissReason) => void} dismissWith
9186 */
9187 const setupTimer = (globalState, innerParams, dismissWith) => {
9188 const timerProgressBar = getTimerProgressBar();
9189 hide(timerProgressBar);
9190 if (innerParams.timer) {
9191 globalState.timeout = new Timer(() => {
9192 dismissWith('timer');
9193 delete globalState.timeout;
9194 }, innerParams.timer);
9195 if (innerParams.timerProgressBar && timerProgressBar) {
9196 show(timerProgressBar);
9197 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
9198 setTimeout(() => {
9199 if (globalState.timeout && globalState.timeout.running) {
9200 // timer can be already stopped or unset at this point
9201 animateTimerProgressBar(/** @type {number} */innerParams.timer);
9202 }
9203 });
9204 }
9205 }
9206 };
9207
9208 /**
9209 * Initialize focus in the popup:
9210 *
9211 * 1. If `toast` is `true`, don't steal focus from the document.
9212 * 2. Else if there is an [autofocus] element, focus it.
9213 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
9214 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
9215 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
9216 * 6. Else focus the first focusable element in a popup (if any).
9217 *
9218 * @param {DomCache} domCache
9219 * @param {SweetAlertOptions} innerParams
9220 */
9221 const initFocus = (domCache, innerParams) => {
9222 if (innerParams.toast) {
9223 return;
9224 }
9225 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
9226 if (!callIfFunction(innerParams.allowEnterKey)) {
9227 warnAboutDeprecation('allowEnterKey');
9228 blurActiveElement();
9229 return;
9230 }
9231 if (focusAutofocus(domCache)) {
9232 return;
9233 }
9234 if (focusButton(domCache, innerParams)) {
9235 return;
9236 }
9237 setFocus(-1, 1);
9238 };
9239
9240 /**
9241 * @param {DomCache} domCache
9242 * @returns {boolean}
9243 */
9244 const focusAutofocus = domCache => {
9245 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
9246 for (const autofocusElement of autofocusElements) {
9247 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
9248 autofocusElement.focus();
9249 return true;
9250 }
9251 }
9252 return false;
9253 };
9254
9255 /**
9256 * @param {DomCache} domCache
9257 * @param {SweetAlertOptions} innerParams
9258 * @returns {boolean}
9259 */
9260 const focusButton = (domCache, innerParams) => {
9261 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
9262 domCache.denyButton.focus();
9263 return true;
9264 }
9265 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
9266 domCache.cancelButton.focus();
9267 return true;
9268 }
9269 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
9270 domCache.confirmButton.focus();
9271 return true;
9272 }
9273 return false;
9274 };
9275 const blurActiveElement = () => {
9276 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
9277 document.activeElement.blur();
9278 }
9279 };
9280
9281 // Assign instance methods from src/instanceMethods/*.js to prototype
9282 SweetAlert.prototype.disableButtons = disableButtons;
9283 SweetAlert.prototype.enableButtons = enableButtons;
9284 SweetAlert.prototype.getInput = getInput;
9285 SweetAlert.prototype.disableInput = disableInput;
9286 SweetAlert.prototype.enableInput = enableInput;
9287 SweetAlert.prototype.hideLoading = hideLoading;
9288 SweetAlert.prototype.disableLoading = hideLoading;
9289 SweetAlert.prototype.showValidationMessage = showValidationMessage;
9290 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
9291 SweetAlert.prototype.close = close;
9292 SweetAlert.prototype.closePopup = close;
9293 SweetAlert.prototype.closeModal = close;
9294 SweetAlert.prototype.closeToast = close;
9295 SweetAlert.prototype.rejectPromise = rejectPromise;
9296 SweetAlert.prototype.update = update;
9297 SweetAlert.prototype._destroy = _destroy;
9298
9299 // Assign static methods from src/staticMethods/*.js to constructor
9300 Object.assign(SweetAlert, staticMethods);
9301
9302 // Proxy to instance methods to constructor, for now, for backwards compatibility
9303 Object.keys(instanceMethods).forEach(key => {
9304 /**
9305 * @param {...(SweetAlertOptions | string | undefined)} args
9306 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
9307 */
9308 // @ts-ignore: Dynamic property assignment for backwards compatibility
9309 SweetAlert[key] = function (...args) {
9310 // @ts-ignore
9311 if (currentInstance && currentInstance[key]) {
9312 // @ts-ignore
9313 return currentInstance[key](...args);
9314 }
9315 return undefined;
9316 };
9317 });
9318 SweetAlert.DismissReason = DismissReason;
9319 SweetAlert.version = '11.26.17';
9320
9321 const Swal = SweetAlert;
9322 // @ts-ignore
9323 Swal.default = Swal;
9324
9325 return Swal;
9326
9327 }));
9328 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
9329 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-icon-animations: true;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem;container-name:swal2-popup}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}@container swal2-popup style(--swal2-icon-animations:true){.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
9330
9331 /***/ },
9332
9333 /***/ "./node_modules/toastify-js/src/toastify.js"
9334 /*!**************************************************!*\
9335 !*** ./node_modules/toastify-js/src/toastify.js ***!
9336 \**************************************************/
9337 (module) {
9338
9339 /*!
9340 * Toastify js 1.12.0
9341 * https://github.com/apvarun/toastify-js
9342 * @license MIT licensed
9343 *
9344 * Copyright (C) 2018 Varun A P
9345 */
9346 (function(root, factory) {
9347 if ( true && module.exports) {
9348 module.exports = factory();
9349 } else {
9350 root.Toastify = factory();
9351 }
9352 })(this, function(global) {
9353 // Object initialization
9354 var Toastify = function(options) {
9355 // Returning a new init object
9356 return new Toastify.lib.init(options);
9357 },
9358 // Library version
9359 version = "1.12.0";
9360
9361 // Set the default global options
9362 Toastify.defaults = {
9363 oldestFirst: true,
9364 text: "Toastify is awesome!",
9365 node: undefined,
9366 duration: 3000,
9367 selector: undefined,
9368 callback: function () {
9369 },
9370 destination: undefined,
9371 newWindow: false,
9372 close: false,
9373 gravity: "toastify-top",
9374 positionLeft: false,
9375 position: '',
9376 backgroundColor: '',
9377 avatar: "",
9378 className: "",
9379 stopOnFocus: true,
9380 onClick: function () {
9381 },
9382 offset: {x: 0, y: 0},
9383 escapeMarkup: true,
9384 ariaLive: 'polite',
9385 style: {background: ''}
9386 };
9387
9388 // Defining the prototype of the object
9389 Toastify.lib = Toastify.prototype = {
9390 toastify: version,
9391
9392 constructor: Toastify,
9393
9394 // Initializing the object with required parameters
9395 init: function(options) {
9396 // Verifying and validating the input object
9397 if (!options) {
9398 options = {};
9399 }
9400
9401 // Creating the options object
9402 this.options = {};
9403
9404 this.toastElement = null;
9405
9406 // Validating the options
9407 this.options.text = options.text || Toastify.defaults.text; // Display message
9408 this.options.node = options.node || Toastify.defaults.node; // Display content as node
9409 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
9410 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
9411 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
9412 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
9413 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
9414 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
9415 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
9416 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
9417 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
9418 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
9419 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
9420 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
9421 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
9422 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
9423 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
9424 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
9425 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
9426 this.options.style = options.style || Toastify.defaults.style;
9427 if(options.backgroundColor) {
9428 this.options.style.background = options.backgroundColor;
9429 }
9430
9431 // Returning the current object for chaining functions
9432 return this;
9433 },
9434
9435 // Building the DOM element
9436 buildToast: function() {
9437 // Validating if the options are defined
9438 if (!this.options) {
9439 throw "Toastify is not initialized";
9440 }
9441
9442 // Creating the DOM object
9443 var divElement = document.createElement("div");
9444 divElement.className = "toastify on " + this.options.className;
9445
9446 // Positioning toast to left or right or center
9447 if (!!this.options.position) {
9448 divElement.className += " toastify-" + this.options.position;
9449 } else {
9450 // To be depreciated in further versions
9451 if (this.options.positionLeft === true) {
9452 divElement.className += " toastify-left";
9453 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
9454 } else {
9455 // Default position
9456 divElement.className += " toastify-right";
9457 }
9458 }
9459
9460 // Assigning gravity of element
9461 divElement.className += " " + this.options.gravity;
9462
9463 if (this.options.backgroundColor) {
9464 // This is being deprecated in favor of using the style HTML DOM property
9465 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
9466 }
9467
9468 // Loop through our style object and apply styles to divElement
9469 for (var property in this.options.style) {
9470 divElement.style[property] = this.options.style[property];
9471 }
9472
9473 // Announce the toast to screen readers
9474 if (this.options.ariaLive) {
9475 divElement.setAttribute('aria-live', this.options.ariaLive)
9476 }
9477
9478 // Adding the toast message/node
9479 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
9480 // If we have a valid node, we insert it
9481 divElement.appendChild(this.options.node)
9482 } else {
9483 if (this.options.escapeMarkup) {
9484 divElement.innerText = this.options.text;
9485 } else {
9486 divElement.innerHTML = this.options.text;
9487 }
9488
9489 if (this.options.avatar !== "") {
9490 var avatarElement = document.createElement("img");
9491 avatarElement.src = this.options.avatar;
9492
9493 avatarElement.className = "toastify-avatar";
9494
9495 if (this.options.position == "left" || this.options.positionLeft === true) {
9496 // Adding close icon on the left of content
9497 divElement.appendChild(avatarElement);
9498 } else {
9499 // Adding close icon on the right of content
9500 divElement.insertAdjacentElement("afterbegin", avatarElement);
9501 }
9502 }
9503 }
9504
9505 // Adding a close icon to the toast
9506 if (this.options.close === true) {
9507 // Create a span for close element
9508 var closeElement = document.createElement("button");
9509 closeElement.type = "button";
9510 closeElement.setAttribute("aria-label", "Close");
9511 closeElement.className = "toast-close";
9512 closeElement.innerHTML = "&#10006;";
9513
9514 // Triggering the removal of toast from DOM on close click
9515 closeElement.addEventListener(
9516 "click",
9517 function(event) {
9518 event.stopPropagation();
9519 this.removeElement(this.toastElement);
9520 window.clearTimeout(this.toastElement.timeOutValue);
9521 }.bind(this)
9522 );
9523
9524 //Calculating screen width
9525 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
9526
9527 // Adding the close icon to the toast element
9528 // Display on the right if screen width is less than or equal to 360px
9529 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
9530 // Adding close icon on the left of content
9531 divElement.insertAdjacentElement("afterbegin", closeElement);
9532 } else {
9533 // Adding close icon on the right of content
9534 divElement.appendChild(closeElement);
9535 }
9536 }
9537
9538 // Clear timeout while toast is focused
9539 if (this.options.stopOnFocus && this.options.duration > 0) {
9540 var self = this;
9541 // stop countdown
9542 divElement.addEventListener(
9543 "mouseover",
9544 function(event) {
9545 window.clearTimeout(divElement.timeOutValue);
9546 }
9547 )
9548 // add back the timeout
9549 divElement.addEventListener(
9550 "mouseleave",
9551 function() {
9552 divElement.timeOutValue = window.setTimeout(
9553 function() {
9554 // Remove the toast from DOM
9555 self.removeElement(divElement);
9556 },
9557 self.options.duration
9558 )
9559 }
9560 )
9561 }
9562
9563 // Adding an on-click destination path
9564 if (typeof this.options.destination !== "undefined") {
9565 divElement.addEventListener(
9566 "click",
9567 function(event) {
9568 event.stopPropagation();
9569 if (this.options.newWindow === true) {
9570 window.open(this.options.destination, "_blank");
9571 } else {
9572 window.location = this.options.destination;
9573 }
9574 }.bind(this)
9575 );
9576 }
9577
9578 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
9579 divElement.addEventListener(
9580 "click",
9581 function(event) {
9582 event.stopPropagation();
9583 this.options.onClick();
9584 }.bind(this)
9585 );
9586 }
9587
9588 // Adding offset
9589 if(typeof this.options.offset === "object") {
9590
9591 var x = getAxisOffsetAValue("x", this.options);
9592 var y = getAxisOffsetAValue("y", this.options);
9593
9594 var xOffset = this.options.position == "left" ? x : "-" + x;
9595 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
9596
9597 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
9598
9599 }
9600
9601 // Returning the generated element
9602 return divElement;
9603 },
9604
9605 // Displaying the toast
9606 showToast: function() {
9607 // Creating the DOM object for the toast
9608 this.toastElement = this.buildToast();
9609
9610 // Getting the root element to with the toast needs to be added
9611 var rootElement;
9612 if (typeof this.options.selector === "string") {
9613 rootElement = document.getElementById(this.options.selector);
9614 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
9615 rootElement = this.options.selector;
9616 } else {
9617 rootElement = document.body;
9618 }
9619
9620 // Validating if root element is present in DOM
9621 if (!rootElement) {
9622 throw "Root element is not defined";
9623 }
9624
9625 // Adding the DOM element
9626 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
9627 rootElement.insertBefore(this.toastElement, elementToInsert);
9628
9629 // Repositioning the toasts in case multiple toasts are present
9630 Toastify.reposition();
9631
9632 if (this.options.duration > 0) {
9633 this.toastElement.timeOutValue = window.setTimeout(
9634 function() {
9635 // Remove the toast from DOM
9636 this.removeElement(this.toastElement);
9637 }.bind(this),
9638 this.options.duration
9639 ); // Binding `this` for function invocation
9640 }
9641
9642 // Supporting function chaining
9643 return this;
9644 },
9645
9646 hideToast: function() {
9647 if (this.toastElement.timeOutValue) {
9648 clearTimeout(this.toastElement.timeOutValue);
9649 }
9650 this.removeElement(this.toastElement);
9651 },
9652
9653 // Removing the element from the DOM
9654 removeElement: function(toastElement) {
9655 // Hiding the element
9656 // toastElement.classList.remove("on");
9657 toastElement.className = toastElement.className.replace(" on", "");
9658
9659 // Removing the element from DOM after transition end
9660 window.setTimeout(
9661 function() {
9662 // remove options node if any
9663 if (this.options.node && this.options.node.parentNode) {
9664 this.options.node.parentNode.removeChild(this.options.node);
9665 }
9666
9667 // Remove the element from the DOM, only when the parent node was not removed before.
9668 if (toastElement.parentNode) {
9669 toastElement.parentNode.removeChild(toastElement);
9670 }
9671
9672 // Calling the callback function
9673 this.options.callback.call(toastElement);
9674
9675 // Repositioning the toasts again
9676 Toastify.reposition();
9677 }.bind(this),
9678 400
9679 ); // Binding `this` for function invocation
9680 },
9681 };
9682
9683 // Positioning the toasts on the DOM
9684 Toastify.reposition = function() {
9685
9686 // Top margins with gravity
9687 var topLeftOffsetSize = {
9688 top: 15,
9689 bottom: 15,
9690 };
9691 var topRightOffsetSize = {
9692 top: 15,
9693 bottom: 15,
9694 };
9695 var offsetSize = {
9696 top: 15,
9697 bottom: 15,
9698 };
9699
9700 // Get all toast messages on the DOM
9701 var allToasts = document.getElementsByClassName("toastify");
9702
9703 var classUsed;
9704
9705 // Modifying the position of each toast element
9706 for (var i = 0; i < allToasts.length; i++) {
9707 // Getting the applied gravity
9708 if (containsClass(allToasts[i], "toastify-top") === true) {
9709 classUsed = "toastify-top";
9710 } else {
9711 classUsed = "toastify-bottom";
9712 }
9713
9714 var height = allToasts[i].offsetHeight;
9715 classUsed = classUsed.substr(9, classUsed.length-1)
9716 // Spacing between toasts
9717 var offset = 15;
9718
9719 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
9720
9721 // Show toast in center if screen with less than or equal to 360px
9722 if (width <= 360) {
9723 // Setting the position
9724 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
9725
9726 offsetSize[classUsed] += height + offset;
9727 } else {
9728 if (containsClass(allToasts[i], "toastify-left") === true) {
9729 // Setting the position
9730 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
9731
9732 topLeftOffsetSize[classUsed] += height + offset;
9733 } else {
9734 // Setting the position
9735 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
9736
9737 topRightOffsetSize[classUsed] += height + offset;
9738 }
9739 }
9740 }
9741
9742 // Supporting function chaining
9743 return this;
9744 };
9745
9746 // Helper function to get offset.
9747 function getAxisOffsetAValue(axis, options) {
9748
9749 if(options.offset[axis]) {
9750 if(isNaN(options.offset[axis])) {
9751 return options.offset[axis];
9752 }
9753 else {
9754 return options.offset[axis] + 'px';
9755 }
9756 }
9757
9758 return '0px';
9759
9760 }
9761
9762 function containsClass(elem, yourClass) {
9763 if (!elem || typeof yourClass !== "string") {
9764 return false;
9765 } else if (
9766 elem.className &&
9767 elem.className
9768 .trim()
9769 .split(/\s+/gi)
9770 .indexOf(yourClass) > -1
9771 ) {
9772 return true;
9773 } else {
9774 return false;
9775 }
9776 }
9777
9778 // Setting up the prototype for the init object
9779 Toastify.lib.init.prototype = Toastify.lib;
9780
9781 // Returning the Toastify function to be assigned to the window object/module
9782 return Toastify;
9783 });
9784
9785
9786 /***/ }
9787
9788 /******/ });
9789 /************************************************************************/
9790 /******/ // The module cache
9791 /******/ var __webpack_module_cache__ = {};
9792 /******/
9793 /******/ // The require function
9794 /******/ function __webpack_require__(moduleId) {
9795 /******/ // Check if module is in cache
9796 /******/ var cachedModule = __webpack_module_cache__[moduleId];
9797 /******/ if (cachedModule !== undefined) {
9798 /******/ return cachedModule.exports;
9799 /******/ }
9800 /******/ // Create a new module (and put it into the cache)
9801 /******/ var module = __webpack_module_cache__[moduleId] = {
9802 /******/ id: moduleId,
9803 /******/ // no module.loaded needed
9804 /******/ exports: {}
9805 /******/ };
9806 /******/
9807 /******/ // Execute the module function
9808 /******/ if (!(moduleId in __webpack_modules__)) {
9809 /******/ delete __webpack_module_cache__[moduleId];
9810 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
9811 /******/ e.code = 'MODULE_NOT_FOUND';
9812 /******/ throw e;
9813 /******/ }
9814 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
9815 /******/
9816 /******/ // Return the exports of the module
9817 /******/ return module.exports;
9818 /******/ }
9819 /******/
9820 /************************************************************************/
9821 /******/ /* webpack/runtime/compat get default export */
9822 /******/ (() => {
9823 /******/ // getDefaultExport function for compatibility with non-harmony modules
9824 /******/ __webpack_require__.n = (module) => {
9825 /******/ var getter = module && module.__esModule ?
9826 /******/ () => (module['default']) :
9827 /******/ () => (module);
9828 /******/ __webpack_require__.d(getter, { a: getter });
9829 /******/ return getter;
9830 /******/ };
9831 /******/ })();
9832 /******/
9833 /******/ /* webpack/runtime/define property getters */
9834 /******/ (() => {
9835 /******/ // define getter functions for harmony exports
9836 /******/ __webpack_require__.d = (exports, definition) => {
9837 /******/ for(var key in definition) {
9838 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
9839 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
9840 /******/ }
9841 /******/ }
9842 /******/ };
9843 /******/ })();
9844 /******/
9845 /******/ /* webpack/runtime/hasOwnProperty shorthand */
9846 /******/ (() => {
9847 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
9848 /******/ })();
9849 /******/
9850 /******/ /* webpack/runtime/make namespace object */
9851 /******/ (() => {
9852 /******/ // define __esModule on exports
9853 /******/ __webpack_require__.r = (exports) => {
9854 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
9855 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
9856 /******/ }
9857 /******/ Object.defineProperty(exports, '__esModule', { value: true });
9858 /******/ };
9859 /******/ })();
9860 /******/
9861 /******/ /* webpack/runtime/nonce */
9862 /******/ (() => {
9863 /******/ __webpack_require__.nc = undefined;
9864 /******/ })();
9865 /******/
9866 /************************************************************************/
9867 var __webpack_exports__ = {};
9868 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
9869 (() => {
9870 "use strict";
9871 /*!**********************************************!*\
9872 !*** ./assets/src/js/admin/edit-question.js ***!
9873 \**********************************************/
9874 __webpack_require__.r(__webpack_exports__);
9875 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9876 /* harmony export */ EditQuestion: () => (/* binding */ EditQuestion)
9877 /* harmony export */ });
9878 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
9879 /* harmony import */ var lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify */ "./assets/src/js/lpToastify.js");
9880 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
9881 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
9882 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
9883 /**
9884 * Edit question JS handler.
9885 *
9886 * @since 4.2.9
9887 * @version 1.0.0
9888 */
9889
9890
9891
9892
9893
9894 const idUrlHandle = 'edit-question';
9895 let fibSelection;
9896 let timeoutAutoUpdateAnswer, timeoutAutoUpdateFib, timeoutAutoUpdateQuestion;
9897
9898 // EditQuestion class
9899 class EditQuestion {
9900 static selectors = {
9901 elEditQuestionWrap: '.lp-edit-question-wrap',
9902 elQuestionEditMain: '.lp-question-edit-main',
9903 elQuestionToggleAll: '.lp-question-toggle-all',
9904 elEditListQuestions: '.lp-edit-list-questions',
9905 elQuestionToggle: '.lp-question-toggle',
9906 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
9907 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
9908 elBtnAddQuestion: '.lp-btn-add-question',
9909 elBtnRemoveQuestion: '.lp-btn-remove-question',
9910 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
9911 elBtnUpdateQuestionDes: '.lp-btn-update-question-des',
9912 elBtnUpdateQuestionHint: '.lp-btn-update-question-hint',
9913 elBtnUpdateQuestionExplain: '.lp-btn-update-question-explanation',
9914 elQuestionTitleNewInput: '.lp-question-title-new-input',
9915 elQuestionTitleInput: '.lp-question-title-input',
9916 elQuestionTypeLabel: '.lp-question-type-label',
9917 elQuestionTypeNew: '.lp-question-type-new',
9918 elAddNewQuestion: 'add-new-question',
9919 elQuestionClone: '.lp-question-item.clone',
9920 elAnswersConfig: '.lp-answers-config',
9921 elBtnAddAnswer: '.lp-btn-add-question-answer',
9922 elQuestionAnswerItemAddNew: '.lp-question-answer-item-add-new',
9923 elQuestionAnswerTitleNewInput: '.lp-question-answer-title-new-input',
9924 elQuestionAnswerTitleInput: '.lp-question-answer-title-input',
9925 elBtnDeleteAnswer: '.lp-btn-delete-question-answer',
9926 elQuestionByType: '.lp-question-by-type',
9927 elInputAnswerSetTrue: '.lp-input-answer-set-true',
9928 elQuestionAnswerItem: '.lp-question-answer-item',
9929 elBtnUpdateQuestionAnswer: '.lp-btn-update-question-answer',
9930 elBtnFibInsertBlank: '.lp-btn-fib-insert-blank',
9931 elBtnFibDeleteAllBlanks: '.lp-btn-fib-delete-all-blanks',
9932 elBtnFibSaveContent: '.lp-btn-fib-save-content',
9933 elBtnFibClearAllContent: '.lp-btn-fib-clear-all-content',
9934 elFibOptionTitleInput: '.lp-question-fib-option-title-input',
9935 elFibBlankOptions: '.lp-question-fib-blank-options',
9936 elFibBlankOptionItem: '.lp-question-fib-blank-option-item',
9937 elFibBlankOptionItemClone: '.lp-question-fib-blank-option-item.clone',
9938 elFibBlankOptionIndex: '.lp-question-fib-option-index',
9939 elBtnFibOptionDelete: '.lp-btn-fib-option-delete',
9940 elFibOptionMatchCaseWrap: '.lp-question-fib-option-match-case-wrap',
9941 elFibOptionMatchCaseInput: '.lp-question-fib-option-match-case-input',
9942 elQuestionFibOptionDetail: '.lp-question-fib-option-detail',
9943 elFibOptionComparisonInput: '.lp-question-fib-option-comparison-input',
9944 elAutoSaveFib: '.lp-auto-save-fib',
9945 LPTarget: '.lp-target',
9946 elCollapse: 'lp-collapse',
9947 elSectionToggle: '.lp-section-toggle',
9948 elTriggerToggle: '.lp-trigger-toggle',
9949 elAutoSaveQuestion: '.lp-auto-save-question',
9950 elAutoSaveAnswer: '.lp-auto-save-question-answer',
9951 elQuestionFibInput: 'lp-question-fib-input',
9952 elBtnQuestionCreateType: '.lp-btn-question-create-type'
9953 };
9954 constructor() {}
9955 init() {
9956 this.events();
9957 this.initTinyMCE().then();
9958 }
9959 events() {
9960 if (EditQuestion._loadedEvents) {
9961 return;
9962 }
9963 EditQuestion._loadedEvents = true;
9964
9965 // Sortable answers's question
9966 const elQuestionEditMains = document.querySelectorAll(`${EditQuestion.selectors.elQuestionEditMain}`);
9967 elQuestionEditMains.forEach(elQuestionEditMain => {
9968 this.sortAbleQuestionAnswer(elQuestionEditMain);
9969 });
9970 // End sortable
9971
9972 // Event click
9973 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
9974 selector: EditQuestion.selectors.elBtnQuestionCreateType,
9975 callBack: this.createQuestionType.name,
9976 class: this
9977 }, {
9978 selector: EditQuestion.selectors.elBtnAddAnswer,
9979 callBack: this.addQuestionAnswer.name,
9980 class: this
9981 }, {
9982 selector: EditQuestion.selectors.elBtnDeleteAnswer,
9983 callBack: this.deleteQuestionAnswer.name,
9984 class: this
9985 }, {
9986 selector: EditQuestion.selectors.elBtnFibInsertBlank,
9987 callBack: this.fibInsertBlank.name,
9988 class: this
9989 }, {
9990 selector: EditQuestion.selectors.elBtnFibDeleteAllBlanks,
9991 callBack: this.fibDeleteAllBlanks.name,
9992 class: this
9993 }, {
9994 selector: EditQuestion.selectors.elBtnFibSaveContent,
9995 callBack: this.fibSaveContent.name,
9996 class: this
9997 }, {
9998 selector: EditQuestion.selectors.elBtnFibClearAllContent,
9999 callBack: this.fibClearContent.name,
10000 class: this
10001 }, {
10002 selector: EditQuestion.selectors.elBtnFibOptionDelete,
10003 callBack: this.fibDeleteBlank.name,
10004 class: this
10005 }, {
10006 selector: EditQuestion.selectors.elFibOptionMatchCaseInput,
10007 callBack: this.fibShowHideMatchCaseOption.name,
10008 class: this
10009 }, {
10010 selector: EditQuestion.selectors.elFibOptionComparisonInput,
10011 callBack: args => {
10012 const {
10013 e,
10014 target
10015 } = args;
10016 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10017 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10018 elBtnFibSaveContent.click();
10019 }
10020 }]);
10021
10022 // Toggle collapse
10023 document.addEventListener('click', e => {
10024 const target = e.target;
10025 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuestion.selectors.elTriggerToggle);
10026 });
10027
10028 // Event keyup
10029 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
10030 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
10031 callBack: this.checkCanAddAnswer.name,
10032 class: this
10033 }, {
10034 selector: EditQuestion.selectors.elFibOptionTitleInput,
10035 callBack: this.fibOptionTitleInputChange.name,
10036 class: this
10037 }, {
10038 selector: EditQuestion.selectors.elAutoSaveQuestion,
10039 callBack: this.autoUpdateQuestion.name,
10040 class: this
10041 }]);
10042
10043 // Event keydown
10044 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
10045 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
10046 callBack: this.addQuestionAnswer.name,
10047 class: this,
10048 checkIsEventEnter: true
10049 }]);
10050
10051 // Event change
10052 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
10053 selector: EditQuestion.selectors.elAutoSaveAnswer,
10054 callBack: this.autoUpdateAnswer.name,
10055 class: this
10056 }]);
10057
10058 // TinyMCE events
10059 this.eventEditorTinymce();
10060 }
10061
10062 // Run async to re-init all TinyMCE editors, because it slow if have many editors
10063 async initTinyMCE() {
10064 const elTextareas = document.querySelectorAll('.lp-editor-tinymce');
10065 elTextareas.forEach(elTextarea => {
10066 const idTextarea = elTextarea.id;
10067 this.reInitTinymce(idTextarea);
10068 });
10069 }
10070 reInitTinymce(id) {
10071 window.tinymce.execCommand('mceRemoveEditor', true, id);
10072 window.tinymce.execCommand('mceAddEditor', true, id);
10073 }
10074 reInitQuickTags(id) {
10075 const toolbar = document.getElementById(`qt_${id}_toolbar`);
10076 if (!toolbar || toolbar.children.length || !window.quicktags) {
10077 return;
10078 }
10079 const settings = window.tinyMCEPreInit?.qtInit?.[id] || {
10080 id
10081 };
10082 window.quicktags(settings);
10083 if (window.QTags?._buttonsInit) {
10084 window.QTags._buttonsInit();
10085 }
10086 }
10087 setDefaultEditorTab(id) {
10088 const wrapEditor = document.getElementById(`wp-${id}-wrap`);
10089 if (!wrapEditor) {
10090 return;
10091 }
10092 if (wrapEditor.classList.contains('html-active') && window.switchEditors?.go) {
10093 window.switchEditors.go(id, 'tmce');
10094 const elTextarea = document.getElementById(id);
10095 if (elTextarea) {
10096 elTextarea.style.visibility = '';
10097 }
10098 }
10099 wrapEditor.classList.add('tmce-active');
10100 wrapEditor.classList.remove('html-active');
10101 const visualTab = document.getElementById(`${id}-tmce`);
10102 const codeTab = document.getElementById(`${id}-html`);
10103 visualTab?.setAttribute('aria-pressed', 'true');
10104 codeTab?.setAttribute('aria-pressed', 'false');
10105 }
10106
10107 // Events for TinyMCE editor
10108 eventEditorTinymce() {
10109 window.tinymce.on('AddEditor', eEditor => {
10110 const id = eEditor.editor.id;
10111 const editor = window.tinymce.get(id);
10112 if (!editor) {
10113 return;
10114 }
10115 if (id === 'content') {
10116 return;
10117 }
10118 const elTextarea = document.getElementById(id);
10119 if (!elTextarea) {
10120 return;
10121 }
10122 const elQuestionEditMain = elTextarea.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10123
10124 // Skip if not in question edit context
10125 if (!elQuestionEditMain) {
10126 return;
10127 }
10128 const questionId = elQuestionEditMain.dataset.questionId;
10129 editor.settings.force_p_newlines = false;
10130 editor.settings.forced_root_block = '';
10131 editor.settings.force_br_newlines = true;
10132
10133 // Config use absolute url
10134 editor.settings.relative_urls = false;
10135 editor.settings.remove_script_host = false;
10136 editor.settings.convert_urls = true;
10137 editor.settings.document_base_url = lpData.site_url;
10138 // End config use absolute url
10139
10140 // Add quick tags
10141 this.reInitQuickTags(id);
10142
10143 // Events focus in TinyMCE editor
10144 editor.on('change keyup', e => {
10145 // Auto save if it has class lp-auto-save
10146 elTextarea.value = editor.getContent();
10147 this.autoUpdateQuestion({
10148 e,
10149 target: elTextarea
10150 });
10151 });
10152 editor.on('blur', e => {
10153 //console.log( 'Editor blurred:', e.target.id );
10154 });
10155 editor.on('focusin', e => {});
10156 editor.on('init', () => {
10157 // Add style
10158 editor.dom.addStyle(`
10159 body {
10160 line-height: 2.2 !important;
10161 }
10162 .${EditQuestion.selectors.elQuestionFibInput} {
10163 border: 1px dashed rebeccapurple;
10164 padding: 5px;
10165 }
10166 `);
10167
10168 // Set default tab visual
10169 this.setDefaultEditorTab(id);
10170 });
10171 editor.on('setcontent', e => {
10172 const uniquid = this.randomString();
10173 const elementg = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${uniquid}"]`);
10174 if (elementg[0]) {
10175 elementg[0].focus();
10176 }
10177 editor.dom.bind(elementg[0], 'input', e => {
10178 //console.log( 'Input changed:', e.target.value );
10179 });
10180 });
10181 editor.on('selectionchange', e => {
10182 fibSelection = editor.selection;
10183
10184 // Check selection is blank, check empty blank content
10185 if (fibSelection.getNode().classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10186 const blankId = fibSelection.getNode().dataset.id;
10187 const textBlank = fibSelection.getNode().textContent.trim();
10188 if (textBlank.length === 0) {
10189 const editorId = editor.id;
10190 const questionId = editorId.replace(`${EditQuestion.selectors.elQuestionFibInput}-`, '');
10191 const elQuestionEditMain = document.querySelector(`${EditQuestion.selectors.elQuestionEditMain}[data-question-id="${questionId}"]`);
10192 const elQuestionBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10193 const elFibBlankOptionItem = elQuestionBlankOptions.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10194 if (elFibBlankOptionItem) {
10195 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 0);
10196 }
10197 } else {
10198 const elTextarea = document.getElementById(id);
10199 const elAnswersConfig = elTextarea.closest(`${EditQuestion.selectors.elAnswersConfig}`);
10200 const elFibBlankOptionItem = elAnswersConfig.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10201 if (elFibBlankOptionItem) {
10202 const elFibOptionTitleInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10203 if (elFibOptionTitleInput) {
10204 elFibOptionTitleInput.value = textBlank;
10205 }
10206 }
10207 }
10208 }
10209 });
10210 editor.on('Undo', e => {
10211 const contentUndo = editor.getContent();
10212 const selection = editor.selection;
10213 const nodeUndo = selection.getNode();
10214 if (nodeUndo.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10215 const blankId = nodeUndo.dataset.id;
10216 const elFibBlankOptionItem = document.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10217 if (elFibBlankOptionItem) {
10218 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 1);
10219 }
10220 }
10221 });
10222 editor.on('Redo', e => {});
10223 });
10224 }
10225 autoUpdateQuestion(args) {
10226 let {
10227 e,
10228 target,
10229 key,
10230 value
10231 } = args;
10232 const elAutoSave = target.closest(`${EditQuestion.selectors.elAutoSaveQuestion}`);
10233 if (!elAutoSave) {
10234 return;
10235 }
10236 const elQuestionEditMain = elAutoSave.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10237 const questionId = elQuestionEditMain.dataset.questionId;
10238 clearTimeout(timeoutAutoUpdateQuestion);
10239 timeoutAutoUpdateQuestion = setTimeout(() => {
10240 // Call ajax to update question description
10241 const callBack = {
10242 success: response => {
10243 const {
10244 message,
10245 status
10246 } = response;
10247 if (status === 'success') {
10248 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10249 } else {
10250 throw `Error: ${message}`;
10251 }
10252 },
10253 error: error => {
10254 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10255 },
10256 completed: () => {}
10257 };
10258 const dataSend = {
10259 action: 'update_question',
10260 question_id: questionId,
10261 args: {
10262 id_url: idUrlHandle
10263 }
10264 };
10265 if (undefined === key) {
10266 key = elAutoSave.dataset.keyAutoSave;
10267 if (!key) {
10268 if (!elAutoSave.classList.contains('lp-editor-tinymce')) {
10269 return;
10270 }
10271 const textAreaId = elAutoSave.id;
10272 key = textAreaId.replace(/lp-/g, '').replace(`-${questionId}`, '').replace(/-/g, '_');
10273 if (!key) {
10274 return;
10275 }
10276 }
10277 value = elAutoSave.value;
10278 }
10279 dataSend[key] = value;
10280 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10281 }, 700);
10282 }
10283 // Create question type
10284 createQuestionType(args) {
10285 const {
10286 e,
10287 target
10288 } = args;
10289 const elBtnQuestionCreateType = target.closest(`${EditQuestion.selectors.elBtnQuestionCreateType}`);
10290 if (!elBtnQuestionCreateType) {
10291 return;
10292 }
10293 const elQuestionEditMain = elBtnQuestionCreateType.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10294 if (!elQuestionEditMain) {
10295 return;
10296 }
10297 const questionId = elQuestionEditMain.dataset.questionId;
10298 const elQuestionTypeNew = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionTypeNew}`);
10299 if (!elQuestionTypeNew) {
10300 return;
10301 }
10302 const questionType = elQuestionTypeNew.value.trim();
10303 if (!questionType) {
10304 const message = elQuestionTypeNew.dataset.messEmptyType;
10305 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
10306 return;
10307 }
10308
10309 // Call ajax to create new question type
10310 const callBack = {
10311 success: response => {
10312 const {
10313 message,
10314 status,
10315 data
10316 } = response;
10317 if (status === 'success') {
10318 const {
10319 html_option_answers
10320 } = data;
10321 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10322 elAnswersConfig.outerHTML = html_option_answers;
10323 this.initTinyMCE();
10324 this.sortAbleQuestionAnswer(elQuestionEditMain);
10325 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10326 } else {
10327 throw `Error: ${message}`;
10328 }
10329 },
10330 error: error => {
10331 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10332 },
10333 completed: () => {}
10334 };
10335 const dataSend = {
10336 action: 'update_question',
10337 question_id: questionId,
10338 question_type: questionType,
10339 args: {
10340 id_url: idUrlHandle
10341 }
10342 };
10343 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10344 }
10345 addQuestionAnswer(args) {
10346 const {
10347 e,
10348 target
10349 } = args;
10350 const elQuestionAnswerItemAddNew = target.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
10351 if (!elQuestionAnswerItemAddNew) {
10352 return;
10353 }
10354 e.preventDefault();
10355 const elQuestionAnswerTitleNewInput = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleNewInput}`);
10356 if (!elQuestionAnswerTitleNewInput.value.trim()) {
10357 const message = elQuestionAnswerTitleNewInput.dataset.messEmptyTitle;
10358 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
10359 return;
10360 }
10361 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10362 const elQuestionAnswerClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}.clone`);
10363 const elQuestionAnswerNew = elQuestionAnswerClone.cloneNode(true);
10364 const elQuestionAnswerTitleInputNew = elQuestionAnswerNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
10365 elQuestionAnswerNew.classList.remove('clone');
10366 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionAnswerNew, 1);
10367 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 1);
10368 elQuestionAnswerClone.insertAdjacentElement('beforebegin', elQuestionAnswerNew);
10369 const answerTitle = elQuestionAnswerTitleNewInput.value.trim();
10370 elQuestionAnswerTitleInputNew.value = answerTitle;
10371 elQuestionAnswerTitleNewInput.value = '';
10372 const questionId = elQuestionEditMain.dataset.questionId;
10373
10374 // Call ajax to add new question answer
10375 const callBack = {
10376 success: response => {
10377 const {
10378 message,
10379 status,
10380 data
10381 } = response;
10382 if (status === 'success') {
10383 const {
10384 question_answer
10385 } = data;
10386 elQuestionAnswerNew.dataset.answerId = question_answer.question_answer_id;
10387 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 0);
10388
10389 // Set data lp-answers-config
10390 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10391 dataAnswers.push(question_answer);
10392 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10393 } else {
10394 throw `Error: ${message}`;
10395 }
10396 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10397 },
10398 error: error => {
10399 elQuestionAnswerNew.remove();
10400 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10401 },
10402 completed: () => {}
10403 };
10404 const dataSend = {
10405 action: 'add_question_answer',
10406 question_id: questionId,
10407 answer_title: answerTitle,
10408 args: {
10409 id_url: idUrlHandle
10410 }
10411 };
10412 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10413 }
10414
10415 // Check to enable or disable add new question button
10416 checkCanAddAnswer(args) {
10417 const {
10418 e,
10419 target
10420 } = args;
10421 const elTrigger = target.closest(EditQuestion.selectors.elQuestionAnswerTitleNewInput);
10422 if (!elTrigger) {
10423 return;
10424 }
10425 const elQuestionAnswerItemAddNew = elTrigger.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
10426 if (!elQuestionAnswerItemAddNew) {
10427 return;
10428 }
10429 const elBtnAddAnswer = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elBtnAddAnswer}`);
10430 if (!elBtnAddAnswer) {
10431 return;
10432 }
10433 const titleValue = elTrigger.value.trim();
10434 if (titleValue) {
10435 elBtnAddAnswer.classList.add('active');
10436 } else {
10437 elBtnAddAnswer.classList.remove('active');
10438 }
10439 }
10440
10441 // Auto update question answer
10442 autoUpdateAnswer(args) {
10443 const {
10444 e,
10445 target
10446 } = args;
10447 const elAutoSaveAnswer = target.closest(`${EditQuestion.selectors.elAutoSaveAnswer}`);
10448 if (!elAutoSaveAnswer) {
10449 return;
10450 }
10451 const elQuestionAnswerItem = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
10452 clearTimeout(timeoutAutoUpdateAnswer);
10453 timeoutAutoUpdateAnswer = setTimeout(() => {
10454 const elQuestionEditMain = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10455 const questionId = elQuestionEditMain.dataset.questionId;
10456 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10457 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10458
10459 // For both radio and checkbox.
10460 const dataAnswersOld = structuredClone(dataAnswers);
10461
10462 // Get position of answers
10463 const elQuestionAnswerItems = elAnswersConfig.querySelectorAll(`${EditQuestion.selectors.elQuestionAnswerItem}:not(.clone)`);
10464 const answersPosition = {};
10465 elQuestionAnswerItems.forEach((elQuestionAnswerItem, index) => {
10466 answersPosition[elQuestionAnswerItem.dataset.answerId] = index + 1; // Start from 1
10467 });
10468
10469 //console.log( 'answersPosition', answersPosition );
10470
10471 dataAnswers.map((answer, k) => {
10472 const elQuestionAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
10473 const elInputAnswerSetTrue = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
10474 const elInputAnswerTitle = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
10475
10476 // Set title
10477 if (elInputAnswerTitle) {
10478 answer.title = elInputAnswerTitle.value.trim();
10479 }
10480
10481 // Set true answer
10482 if (elInputAnswerSetTrue) {
10483 if (elInputAnswerSetTrue.checked) {
10484 answer.is_true = 'yes';
10485 } else {
10486 answer.is_true = '';
10487 }
10488 }
10489
10490 // Set position
10491 if (answersPosition[answer.question_answer_id]) {
10492 answer.order = answersPosition[answer.question_answer_id];
10493 }
10494 return answer;
10495 });
10496
10497 //console.log( dataAnswers );
10498
10499 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
10500
10501 // Call ajax to update answers config
10502 const callBack = {
10503 success: response => {
10504 const {
10505 message,
10506 status
10507 } = response;
10508 if (status === 'success') {} else {
10509 throw `Error: ${message}`;
10510 }
10511 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10512 },
10513 error: error => {
10514 // rollback changes to old data
10515 dataAnswersOld.forEach(answer => {
10516 const elAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
10517 const inputAnswerSetTrue = elAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
10518 if (answer.is_true === 'yes') {
10519 inputAnswerSetTrue.checked = true;
10520 }
10521 return answer;
10522 });
10523 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10524 },
10525 completed: () => {
10526 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
10527 }
10528 };
10529 const dataSend = {
10530 action: 'update_question_answers_config',
10531 question_id: questionId,
10532 answers: dataAnswers,
10533 args: {
10534 id_url: idUrlHandle
10535 }
10536 };
10537 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10538 }, 700);
10539 }
10540
10541 // Sortable answers's question
10542 sortAbleQuestionAnswer(elQuestionEditMain) {
10543 let isUpdateSectionPosition = 0;
10544 let timeout;
10545 const elQuestionAnswers = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elAnswersConfig}`);
10546 elQuestionAnswers.forEach(elAnswersConfig => {
10547 new sortablejs__WEBPACK_IMPORTED_MODULE_3__["default"](elAnswersConfig, {
10548 handle: '.drag',
10549 animation: 150,
10550 onEnd: evt => {
10551 const elQuestionAnswerItem = evt.item;
10552 if (!isUpdateSectionPosition) {
10553 // No change in section position, do nothing
10554 return;
10555 }
10556 clearTimeout(timeout);
10557 timeout = setTimeout(() => {
10558 const elAutoSaveAnswer = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elAutoSaveAnswer}`);
10559 this.autoUpdateAnswer({
10560 e: null,
10561 target: elAutoSaveAnswer
10562 });
10563 }, 1000);
10564 },
10565 onMove: evt => {
10566 clearTimeout(timeout);
10567 },
10568 onUpdate: evt => {
10569 isUpdateSectionPosition = 1;
10570 }
10571 });
10572 });
10573 }
10574
10575 // Delete question answer
10576 deleteQuestionAnswer(args) {
10577 const {
10578 e,
10579 target
10580 } = args;
10581 const elBtnDeleteAnswer = target.closest(`${EditQuestion.selectors.elBtnDeleteAnswer}`);
10582 if (!elBtnDeleteAnswer) {
10583 return;
10584 }
10585 const elQuestionAnswerItem = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
10586 if (!elQuestionAnswerItem) {
10587 return;
10588 }
10589 const elQuestionEditMain = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10590 const questionId = elQuestionEditMain.dataset.questionId;
10591 const questionAnswerId = elQuestionAnswerItem.dataset.answerId;
10592 if (!questionId || !questionAnswerId) {
10593 return;
10594 }
10595 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10596 title: elBtnDeleteAnswer.dataset.title || 'Are you sure?',
10597 text: elBtnDeleteAnswer.dataset.content || 'Do you want to delete this answer?',
10598 icon: 'warning',
10599 showCloseButton: true,
10600 showCancelButton: true,
10601 cancelButtonText: lpData.i18n.cancel,
10602 confirmButtonText: lpData.i18n.yes,
10603 reverseButtons: true
10604 }).then(result => {
10605 if (result.isConfirmed) {
10606 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
10607
10608 // Call ajax to delete item from section
10609 const callBack = {
10610 success: response => {
10611 const {
10612 message,
10613 status
10614 } = response;
10615 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10616 if (status === 'success') {
10617 const elQuestionAnswerId = parseInt(elQuestionAnswerItem.dataset.answerId);
10618 elQuestionAnswerItem.remove();
10619 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10620 if (dataAnswers) {
10621 const updatedAnswers = dataAnswers.filter(answer => parseInt(answer.question_answer_id) !== elQuestionAnswerId);
10622 this.setDataAnswersConfig(elQuestionEditMain, updatedAnswers);
10623 }
10624 }
10625 },
10626 error: error => {
10627 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10628 },
10629 completed: () => {
10630 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
10631 }
10632 };
10633 const dataSend = {
10634 action: 'delete_question_answer',
10635 question_id: questionId,
10636 question_answer_id: questionAnswerId,
10637 args: {
10638 id_url: idUrlHandle
10639 }
10640 };
10641 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10642 }
10643 });
10644 }
10645
10646 // Get data answers config
10647 getDataAnswersConfig(elQuestionEditMain) {
10648 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10649 if (!elAnswersConfig) {
10650 return null;
10651 }
10652 let dataAnswers = elAnswersConfig.dataset.answers || '[]';
10653 try {
10654 dataAnswers = JSON.parse(dataAnswers);
10655 } catch (e) {
10656 dataAnswers = [];
10657 }
10658 if (!dataAnswers.meta_data) {
10659 dataAnswers.meta_data = {};
10660 }
10661 return dataAnswers;
10662 }
10663
10664 // Set data answers config
10665 setDataAnswersConfig(elQuestionEditMain, dataAnswers) {
10666 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10667 if (!elAnswersConfig) {
10668 return;
10669 }
10670 if (!dataAnswers || typeof dataAnswers !== 'object') {
10671 dataAnswers = {};
10672 }
10673 elAnswersConfig.dataset.answers = JSON.stringify(dataAnswers);
10674 }
10675
10676 /***** Fill in the blank question type *****/
10677 // For FIB question type
10678 fibInsertBlank = args => {
10679 const {
10680 e,
10681 target
10682 } = args;
10683 const elBtnFibInsertBlank = target.closest(EditQuestion.selectors.elBtnFibInsertBlank);
10684 if (!elBtnFibInsertBlank) {
10685 return;
10686 }
10687 const textPlaceholder = elBtnFibInsertBlank.dataset.defaultText;
10688 const elQuestionEditMain = elBtnFibInsertBlank.closest(EditQuestion.selectors.elQuestionEditMain);
10689 const questionId = elQuestionEditMain.dataset.questionId;
10690 const messErrInserted = elBtnFibInsertBlank.dataset.messInserted;
10691 const messErrRequireSelectText = elBtnFibInsertBlank.dataset.messRequireSelectText;
10692 const idEditor = `${EditQuestion.selectors.elQuestionFibInput}-${questionId}`;
10693 const uniquid = this.randomString();
10694 let selectedText;
10695 if (fibSelection) {
10696 const elNode = fibSelection.getNode();
10697 if (!elNode) {
10698 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Event insert blank has error, please try again', 'error');
10699 return;
10700 }
10701 const findParent = elNode.closest(`body[data-id="${idEditor}"]`);
10702 if (!findParent) {
10703 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
10704 return;
10705 }
10706 if (elNode.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10707 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrInserted, 'error');
10708 return;
10709 }
10710 selectedText = fibSelection.getContent();
10711 if (selectedText.length === 0) {
10712 selectedText = textPlaceholder;
10713 }
10714 const elInputNew = `<span class="${EditQuestion.selectors.elQuestionFibInput}" data-id="${uniquid}">${selectedText}</span>`;
10715 fibSelection.setContent(elInputNew);
10716 } else {
10717 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
10718 return;
10719 }
10720 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10721 dataAnswers.meta_data = dataAnswers.meta_data || {};
10722 // Convert array to object
10723 if (Object.keys(dataAnswers.meta_data).length === 0) {
10724 dataAnswers.meta_data = {};
10725 }
10726 dataAnswers.meta_data[uniquid] = {
10727 id: uniquid,
10728 match_case: 0,
10729 comparison: 'equal',
10730 fill: selectedText,
10731 index: 1,
10732 open: false
10733 };
10734 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10735
10736 // Clone blank options
10737 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10738 const elFibBlankOptionItemClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptionItemClone}`);
10739 const elFibBlankOptionItemNew = elFibBlankOptionItemClone.cloneNode(true);
10740 const countOptions = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`).length;
10741 const elFibBlankOptionIndex = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibBlankOptionIndex}`);
10742 const elFibOptionTitleInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10743 const elFibOptionMatchCaseInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
10744 const elFibOptionComparisonInput = elFibBlankOptionItemNew.querySelectorAll(`${EditQuestion.selectors.elFibOptionComparisonInput}`);
10745 elFibBlankOptionItemNew.dataset.id = uniquid;
10746 elFibOptionTitleInput.name = `${EditQuestion.selectors.elFibOptionTitleInput}-${uniquid}`;
10747 elFibOptionTitleInput.value = this.decodeHtml(selectedText);
10748 elFibBlankOptionIndex.textContent = countOptions + 1 + '.';
10749 elFibOptionMatchCaseInput.name = `${EditQuestion.selectors.elFibOptionMatchCaseInput}-${uniquid}`.replace(/\./g, '');
10750 elFibOptionComparisonInput.forEach(elInput => {
10751 elInput.name = `${EditQuestion.selectors.elFibOptionComparisonInput}-${uniquid}`.replace(/\./g, '');
10752 if (elInput.value === 'equal') {
10753 elInput.checked = true;
10754 }
10755 });
10756 elFibBlankOptionItemClone.insertAdjacentElement('beforebegin', elFibBlankOptionItemNew);
10757 elFibBlankOptionItemNew.classList.remove('clone');
10758 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItemNew, 1);
10759 // End clone blank options
10760
10761 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10762 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 1);
10763 this.fibSaveContent({
10764 e: null,
10765 target: elBtnFibSaveContent,
10766 callBackCompleted: () => {
10767 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 0);
10768 }
10769 });
10770 };
10771
10772 // Delete all blanks
10773 fibDeleteAllBlanks(args) {
10774 const {
10775 e,
10776 target
10777 } = args;
10778 const elBtnFibDeleteAllBlanks = target.closest(`${EditQuestion.selectors.elBtnFibDeleteAllBlanks}`);
10779 if (!elBtnFibDeleteAllBlanks) {
10780 return;
10781 }
10782 const elQuestionEditMain = elBtnFibDeleteAllBlanks.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10783 if (!elQuestionEditMain) {
10784 return;
10785 }
10786 const questionId = elQuestionEditMain.dataset.questionId;
10787 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10788 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10789 title: elBtnFibDeleteAllBlanks.dataset.title,
10790 text: elBtnFibDeleteAllBlanks.dataset.content,
10791 icon: 'warning',
10792 showCloseButton: true,
10793 showCancelButton: true,
10794 cancelButtonText: lpData.i18n.cancel,
10795 confirmButtonText: lpData.i18n.yes,
10796 reverseButtons: true
10797 }).then(result => {
10798 if (result.isConfirmed) {
10799 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10800 const elBlanks = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}`);
10801 elBlanks.forEach(elBlank => {
10802 editor.dom.remove(elBlank, true);
10803 });
10804 dataAnswers.meta_data = {};
10805 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10806 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10807 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10808 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10809 elFibBlankOptionItem.remove();
10810 });
10811 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10812 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 1);
10813 this.fibSaveContent({
10814 e: null,
10815 target: elBtnFibSaveContent,
10816 callBackCompleted: () => {
10817 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 0);
10818 }
10819 });
10820 }
10821 });
10822 }
10823 // Clear content FIB question
10824 fibClearContent(args) {
10825 const {
10826 e,
10827 target
10828 } = args;
10829 const elBtnFibClearAllContent = target.closest(`${EditQuestion.selectors.elBtnFibClearAllContent}`);
10830 if (!elBtnFibClearAllContent) {
10831 return;
10832 }
10833 const elQuestionEditMain = elBtnFibClearAllContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10834 if (!elQuestionEditMain) {
10835 return;
10836 }
10837 const questionId = elQuestionEditMain.dataset.questionId;
10838 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10839 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10840 title: elBtnFibClearAllContent.dataset.title,
10841 text: elBtnFibClearAllContent.dataset.content,
10842 icon: 'warning',
10843 showCloseButton: true,
10844 showCancelButton: true,
10845 cancelButtonText: lpData.i18n.cancel,
10846 confirmButtonText: lpData.i18n.yes,
10847 reverseButtons: true
10848 }).then(result => {
10849 if (result.isConfirmed) {
10850 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
10851 editor.setContent('');
10852 dataAnswers.meta_data = {};
10853 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10854 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10855 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10856 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10857 elFibBlankOptionItem.remove();
10858 });
10859 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10860 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 1);
10861 this.fibSaveContent({
10862 e: null,
10863 target: elBtnFibSaveContent,
10864 callBackCompleted: () => {
10865 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 0);
10866 }
10867 });
10868 }
10869 });
10870 }
10871
10872 // Remove blank
10873 fibDeleteBlank(args) {
10874 const {
10875 e,
10876 target
10877 } = args;
10878 const elBtnFibOptionDelete = target.closest(`${EditQuestion.selectors.elBtnFibOptionDelete}`);
10879 if (!elBtnFibOptionDelete) {
10880 return;
10881 }
10882 const elQuestionEditMain = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10883 if (!elQuestionEditMain) {
10884 return;
10885 }
10886 const questionId = elQuestionEditMain.dataset.questionId;
10887 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10888 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10889 const elFibBlankOptionItem = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
10890 const blankId = elFibBlankOptionItem.dataset.id;
10891 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10892 title: elBtnFibOptionDelete.dataset.title,
10893 text: elBtnFibOptionDelete.dataset.content,
10894 icon: 'warning',
10895 showCloseButton: true,
10896 showCancelButton: true,
10897 cancelButtonText: lpData.i18n.cancel,
10898 confirmButtonText: lpData.i18n.yes,
10899 reverseButtons: true
10900 }).then(result => {
10901 if (result.isConfirmed) {
10902 // Find span with id on editor and remove it
10903 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10904 const elBlank = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${blankId}"]`);
10905 if (elBlank[0]) {
10906 // Remove tag html but keep content
10907 editor.dom.remove(elBlank[0], true);
10908 }
10909 elFibBlankOptionItem.remove();
10910 dataAnswers.meta_data = dataAnswers.meta_data || {};
10911 if (dataAnswers.meta_data[blankId]) {
10912 delete dataAnswers.meta_data[blankId];
10913 }
10914 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10915 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10916 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 1);
10917 this.fibSaveContent({
10918 e: null,
10919 target: elBtnFibSaveContent,
10920 callBackCompleted: () => {
10921 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 0);
10922 }
10923 });
10924 }
10925 });
10926 }
10927
10928 // Change title of blank option
10929 fibOptionTitleInputChange(args) {
10930 const {
10931 e,
10932 target
10933 } = args;
10934 const elFibOptionTitleInput = target.closest(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10935 if (!elFibOptionTitleInput) {
10936 return;
10937 }
10938 const elQuestionFibOptionItem = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
10939 if (!elQuestionFibOptionItem) {
10940 return;
10941 }
10942 const elQuestionEditMain = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10943 if (!elQuestionEditMain) {
10944 return;
10945 }
10946 const value = elFibOptionTitleInput.value.trim();
10947 const blankId = elQuestionFibOptionItem.dataset.id;
10948 const questionId = elQuestionEditMain.dataset.questionId;
10949 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
10950 const elBlank = editor.dom.select(`.lp-question-fib-input[data-id="${blankId}"]`);
10951 if (elBlank[0]) {
10952 // Update content of blank
10953 elBlank[0].textContent = value;
10954 }
10955 clearTimeout(timeoutAutoUpdateFib);
10956 timeoutAutoUpdateFib = setTimeout(() => {
10957 // Call ajax to update question description
10958 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10959 this.fibSaveContent({
10960 e: null,
10961 target: elBtnFibSaveContent
10962 });
10963 }, 700);
10964 }
10965
10966 // Save content FIB question
10967 fibSaveContent(args) {
10968 const {
10969 e,
10970 target,
10971 callBackCompleted = null
10972 } = args;
10973 const elBtnFibSaveContent = target.closest(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10974 if (!elBtnFibSaveContent) {
10975 return;
10976 }
10977 const elQuestionEditMain = elBtnFibSaveContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10978 const questionId = elQuestionEditMain.dataset.questionId;
10979 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10980 if (!dataAnswers) {
10981 return;
10982 }
10983 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10984 dataAnswers.title = editor.getContent();
10985 const elFibBlankOptionItems = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10986 if (elFibBlankOptionItems) {
10987 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10988 const blankId = elFibBlankOptionItem.dataset.id;
10989 const elFibOptionMatchCaseInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
10990 const elFibOptionComparisonInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionComparisonInput}:checked`);
10991 dataAnswers.meta_data[blankId].match_case = elFibOptionMatchCaseInput.checked ? 1 : 0;
10992 dataAnswers.meta_data[blankId].comparison = elFibOptionComparisonInput.value;
10993 });
10994 }
10995
10996 //console.log( 'dataAnswers', dataAnswers );
10997
10998 if (!callBackCompleted) {
10999 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 1);
11000 }
11001
11002 // Call ajax to update answers config
11003 const callBack = {
11004 success: response => {
11005 const {
11006 message,
11007 status
11008 } = response;
11009 if (status === 'success') {
11010 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
11011 } else {
11012 throw `Error: ${message}`;
11013 }
11014 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
11015 },
11016 error: error => {
11017 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
11018 },
11019 completed: () => {
11020 if (callBackCompleted && typeof callBackCompleted === 'function') {
11021 callBackCompleted();
11022 } else {
11023 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 0);
11024 }
11025 }
11026 };
11027
11028 //console.log( 'dataAnswers', dataAnswers );
11029
11030 const dataSend = {
11031 action: 'update_question_answers_config',
11032 question_id: questionId,
11033 answers: dataAnswers,
11034 args: {
11035 id_url: idUrlHandle
11036 }
11037 };
11038 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11039 }
11040 // Show/hide match case option
11041 fibShowHideMatchCaseOption(args) {
11042 const {
11043 e,
11044 target
11045 } = args;
11046 const elFibOptionMatchCaseInput = target.closest(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
11047 if (!elFibOptionMatchCaseInput) {
11048 return;
11049 }
11050 const elQuestionFibOptionDetail = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionFibOptionDetail}`);
11051 const elFibOptionMatchCaseWrap = elQuestionFibOptionDetail.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseWrap}`);
11052 if (!elQuestionFibOptionDetail || !elFibOptionMatchCaseWrap) {
11053 return;
11054 }
11055 if (elFibOptionMatchCaseInput.checked) {
11056 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 1);
11057 } else {
11058 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 0);
11059 }
11060 const elQuestionEditMain = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
11061 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
11062 elBtnFibSaveContent.click();
11063 }
11064 /***** End Fill in the blank question type *****/
11065
11066 // Generate a random string of specified length, for set unique id
11067 randomString(length = 10) {
11068 const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
11069 let result = '';
11070 for (let i = 0; i < length; i++) {
11071 result += chars.charAt(Math.floor(Math.random() * chars.length));
11072 }
11073 return result;
11074 }
11075 // Decode HTML entities
11076 decodeHtml(html) {
11077 const txt = document.createElement('textarea');
11078 txt.innerHTML = html;
11079 return txt.value;
11080 }
11081 }
11082 const editQuestion = new EditQuestion();
11083 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuestion.selectors.elEditQuestionWrap, elEditQuestionWrap => {
11084 const findClass = EditQuestion.selectors.elQuestionEditMain.replace('.', '');
11085 if (!elEditQuestionWrap.classList.contains(findClass)) {
11086 return;
11087 }
11088 editQuestion.init();
11089 });
11090 })();
11091
11092 /******/ })()
11093 ;
11094 //# sourceMappingURL=edit-question.js.map