PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
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.8, at assets/dist/js/admin/edit-question.js

11,071 lines 395.8 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.25
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 * @returns {boolean}
4679 */
4680 const isFirefox = () => navigator.userAgent.includes('Firefox');
4681
4682 /**
4683 * Gets the popup container which contains the backdrop and the popup itself.
4684 *
4685 * @returns {HTMLElement | null}
4686 */
4687 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
4688
4689 /**
4690 * @param {string} selectorString
4691 * @returns {HTMLElement | null}
4692 */
4693 const elementBySelector = selectorString => {
4694 const container = getContainer();
4695 return container ? container.querySelector(selectorString) : null;
4696 };
4697
4698 /**
4699 * @param {string} className
4700 * @returns {HTMLElement | null}
4701 */
4702 const elementByClass = className => {
4703 return elementBySelector(`.${className}`);
4704 };
4705
4706 /**
4707 * @returns {HTMLElement | null}
4708 */
4709 const getPopup = () => elementByClass(swalClasses.popup);
4710
4711 /**
4712 * @returns {HTMLElement | null}
4713 */
4714 const getIcon = () => elementByClass(swalClasses.icon);
4715
4716 /**
4717 * @returns {HTMLElement | null}
4718 */
4719 const getIconContent = () => elementByClass(swalClasses['icon-content']);
4720
4721 /**
4722 * @returns {HTMLElement | null}
4723 */
4724 const getTitle = () => elementByClass(swalClasses.title);
4725
4726 /**
4727 * @returns {HTMLElement | null}
4728 */
4729 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
4730
4731 /**
4732 * @returns {HTMLElement | null}
4733 */
4734 const getImage = () => elementByClass(swalClasses.image);
4735
4736 /**
4737 * @returns {HTMLElement | null}
4738 */
4739 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
4740
4741 /**
4742 * @returns {HTMLElement | null}
4743 */
4744 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
4745
4746 /**
4747 * @returns {HTMLButtonElement | null}
4748 */
4749 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
4750
4751 /**
4752 * @returns {HTMLButtonElement | null}
4753 */
4754 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
4755
4756 /**
4757 * @returns {HTMLButtonElement | null}
4758 */
4759 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
4760
4761 /**
4762 * @returns {HTMLElement | null}
4763 */
4764 const getInputLabel = () => elementByClass(swalClasses['input-label']);
4765
4766 /**
4767 * @returns {HTMLElement | null}
4768 */
4769 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
4770
4771 /**
4772 * @returns {HTMLElement | null}
4773 */
4774 const getActions = () => elementByClass(swalClasses.actions);
4775
4776 /**
4777 * @returns {HTMLElement | null}
4778 */
4779 const getFooter = () => elementByClass(swalClasses.footer);
4780
4781 /**
4782 * @returns {HTMLElement | null}
4783 */
4784 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
4785
4786 /**
4787 * @returns {HTMLElement | null}
4788 */
4789 const getCloseButton = () => elementByClass(swalClasses.close);
4790
4791 // https://github.com/jkup/focusable/blob/master/index.js
4792 const focusable = `
4793 a[href],
4794 area[href],
4795 input:not([disabled]),
4796 select:not([disabled]),
4797 textarea:not([disabled]),
4798 button:not([disabled]),
4799 iframe,
4800 object,
4801 embed,
4802 [tabindex="0"],
4803 [contenteditable],
4804 audio[controls],
4805 video[controls],
4806 summary
4807 `;
4808 /**
4809 * @returns {HTMLElement[]}
4810 */
4811 const getFocusableElements = () => {
4812 const popup = getPopup();
4813 if (!popup) {
4814 return [];
4815 }
4816 /** @type {NodeListOf<HTMLElement>} */
4817 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
4818 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
4819 // sort according to tabindex
4820 .sort((a, b) => {
4821 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
4822 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
4823 if (tabindexA > tabindexB) {
4824 return 1;
4825 } else if (tabindexA < tabindexB) {
4826 return -1;
4827 }
4828 return 0;
4829 });
4830
4831 /** @type {NodeListOf<HTMLElement>} */
4832 const otherFocusableElements = popup.querySelectorAll(focusable);
4833 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
4834 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
4835 };
4836
4837 /**
4838 * @returns {boolean}
4839 */
4840 const isModal = () => {
4841 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
4842 };
4843
4844 /**
4845 * @returns {boolean}
4846 */
4847 const isToast = () => {
4848 const popup = getPopup();
4849 if (!popup) {
4850 return false;
4851 }
4852 return hasClass(popup, swalClasses.toast);
4853 };
4854
4855 /**
4856 * @returns {boolean}
4857 */
4858 const isLoading = () => {
4859 const popup = getPopup();
4860 if (!popup) {
4861 return false;
4862 }
4863 return popup.hasAttribute('data-loading');
4864 };
4865
4866 /**
4867 * Securely set innerHTML of an element
4868 * https://github.com/sweetalert2/sweetalert2/issues/1926
4869 *
4870 * @param {HTMLElement} elem
4871 * @param {string} html
4872 */
4873 const setInnerHtml = (elem, html) => {
4874 elem.textContent = '';
4875 if (html) {
4876 const parser = new DOMParser();
4877 const parsed = parser.parseFromString(html, `text/html`);
4878 const head = parsed.querySelector('head');
4879 if (head) {
4880 Array.from(head.childNodes).forEach(child => {
4881 elem.appendChild(child);
4882 });
4883 }
4884 const body = parsed.querySelector('body');
4885 if (body) {
4886 Array.from(body.childNodes).forEach(child => {
4887 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
4888 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
4889 } else {
4890 elem.appendChild(child);
4891 }
4892 });
4893 }
4894 }
4895 };
4896
4897 /**
4898 * @param {HTMLElement} elem
4899 * @param {string} className
4900 * @returns {boolean}
4901 */
4902 const hasClass = (elem, className) => {
4903 if (!className) {
4904 return false;
4905 }
4906 return className.split(/\s+/).every(cls => elem.classList.contains(cls));
4907 };
4908
4909 /**
4910 * @param {HTMLElement} elem
4911 * @param {SweetAlertOptions} params
4912 */
4913 const removeCustomClasses = (elem, params) => {
4914 Array.from(elem.classList).forEach(className => {
4915 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
4916 elem.classList.remove(className);
4917 }
4918 });
4919 };
4920
4921 /**
4922 * @param {HTMLElement} elem
4923 * @param {SweetAlertOptions} params
4924 * @param {string} className
4925 */
4926 const applyCustomClass = (elem, params, className) => {
4927 removeCustomClasses(elem, params);
4928 if (!params.customClass) {
4929 return;
4930 }
4931 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
4932 if (!customClass) {
4933 return;
4934 }
4935 if (typeof customClass !== 'string' && !customClass.forEach) {
4936 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
4937 return;
4938 }
4939 addClass(elem, customClass);
4940 };
4941
4942 /**
4943 * @param {HTMLElement} popup
4944 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
4945 * @returns {HTMLInputElement | null}
4946 */
4947 const getInput$1 = (popup, inputClass) => {
4948 if (!inputClass) {
4949 return null;
4950 }
4951 switch (inputClass) {
4952 case 'select':
4953 case 'textarea':
4954 case 'file':
4955 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
4956 case 'checkbox':
4957 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
4958 case 'radio':
4959 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
4960 case 'range':
4961 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
4962 default:
4963 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
4964 }
4965 };
4966
4967 /**
4968 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
4969 */
4970 const focusInput = input => {
4971 input.focus();
4972
4973 // place cursor at end of text in text input
4974 if (input.type !== 'file') {
4975 // http://stackoverflow.com/a/2345915
4976 const val = input.value;
4977 input.value = '';
4978 input.value = val;
4979 }
4980 };
4981
4982 /**
4983 * @param {HTMLElement | HTMLElement[] | null} target
4984 * @param {string | string[] | readonly string[] | undefined} classList
4985 * @param {boolean} condition
4986 */
4987 const toggleClass = (target, classList, condition) => {
4988 if (!target || !classList) {
4989 return;
4990 }
4991 const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
4992 const targets = Array.isArray(target) ? target : [target];
4993 targets.forEach(elem => {
4994 classes.forEach(className => {
4995 if (condition) {
4996 elem.classList.add(className);
4997 } else {
4998 elem.classList.remove(className);
4999 }
5000 });
5001 });
5002 };
5003
5004 /**
5005 * @param {HTMLElement | HTMLElement[] | null} target
5006 * @param {string | string[] | readonly string[] | undefined} classList
5007 */
5008 const addClass = (target, classList) => {
5009 toggleClass(target, classList, true);
5010 };
5011
5012 /**
5013 * @param {HTMLElement | HTMLElement[] | null} target
5014 * @param {string | string[] | readonly string[] | undefined} classList
5015 */
5016 const removeClass = (target, classList) => {
5017 toggleClass(target, classList, false);
5018 };
5019
5020 /**
5021 * Get direct child of an element by class name
5022 *
5023 * @param {HTMLElement} elem
5024 * @param {string} className
5025 * @returns {HTMLElement | undefined}
5026 */
5027 const getDirectChildByClass = (elem, className) => (/** @type {HTMLElement | undefined} */
5028 Array.from(elem.children).find(child => child instanceof HTMLElement && hasClass(child, className)));
5029
5030 /**
5031 * @param {HTMLElement} elem
5032 * @param {string} property
5033 * @param {string | number | null | undefined} value
5034 */
5035 const applyNumericalStyle = (elem, property, value) => {
5036 if (value === `${parseInt(`${value}`)}`) {
5037 value = parseInt(value);
5038 }
5039 if (value || value === 0) {
5040 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
5041 } else {
5042 elem.style.removeProperty(property);
5043 }
5044 };
5045
5046 /**
5047 * @param {HTMLElement | null} elem
5048 * @param {string} display
5049 */
5050 const show = (elem, display = 'flex') => {
5051 if (!elem) {
5052 return;
5053 }
5054 elem.style.display = display;
5055 };
5056
5057 /**
5058 * @param {HTMLElement | null} elem
5059 */
5060 const hide = elem => {
5061 if (!elem) {
5062 return;
5063 }
5064 elem.style.display = 'none';
5065 };
5066
5067 /**
5068 * @param {HTMLElement | null} elem
5069 * @param {string} display
5070 */
5071 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
5072 if (!elem) {
5073 return;
5074 }
5075 new MutationObserver(() => {
5076 toggle(elem, elem.innerHTML, display);
5077 }).observe(elem, {
5078 childList: true,
5079 subtree: true
5080 });
5081 };
5082
5083 /**
5084 * @param {HTMLElement} parent
5085 * @param {string} selector
5086 * @param {string} property
5087 * @param {string} value
5088 */
5089 const setStyle = (parent, selector, property, value) => {
5090 /** @type {HTMLElement | null} */
5091 const el = parent.querySelector(selector);
5092 if (el) {
5093 el.style.setProperty(property, value);
5094 }
5095 };
5096
5097 /**
5098 * @param {HTMLElement} elem
5099 * @param {boolean | string | null | undefined} condition
5100 * @param {string} display
5101 */
5102 const toggle = (elem, condition, display = 'flex') => {
5103 if (condition) {
5104 show(elem, display);
5105 } else {
5106 hide(elem);
5107 }
5108 };
5109
5110 /**
5111 * borrowed from jquery $(elem).is(':visible') implementation
5112 *
5113 * @param {HTMLElement | null} elem
5114 * @returns {boolean}
5115 */
5116 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
5117
5118 /**
5119 * @returns {boolean}
5120 */
5121 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
5122
5123 /**
5124 * @param {HTMLElement} elem
5125 * @returns {boolean}
5126 */
5127 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
5128
5129 /**
5130 * @param {HTMLElement} element
5131 * @param {HTMLElement} stopElement
5132 * @returns {boolean}
5133 */
5134 const selfOrParentIsScrollable = (element, stopElement) => {
5135 let parent = /** @type {HTMLElement | null} */element;
5136 while (parent && parent !== stopElement) {
5137 if (isScrollable(parent)) {
5138 return true;
5139 }
5140 parent = parent.parentElement;
5141 }
5142 return false;
5143 };
5144
5145 /**
5146 * borrowed from https://stackoverflow.com/a/46352119
5147 *
5148 * @param {HTMLElement} elem
5149 * @returns {boolean}
5150 */
5151 const hasCssAnimation = elem => {
5152 const style = window.getComputedStyle(elem);
5153 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
5154 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
5155 return animDuration > 0 || transDuration > 0;
5156 };
5157
5158 /**
5159 * @param {number} timer
5160 * @param {boolean} reset
5161 */
5162 const animateTimerProgressBar = (timer, reset = false) => {
5163 const timerProgressBar = getTimerProgressBar();
5164 if (!timerProgressBar) {
5165 return;
5166 }
5167 if (isVisible$1(timerProgressBar)) {
5168 if (reset) {
5169 timerProgressBar.style.transition = 'none';
5170 timerProgressBar.style.width = '100%';
5171 }
5172 setTimeout(() => {
5173 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
5174 timerProgressBar.style.width = '0%';
5175 }, 10);
5176 }
5177 };
5178 const stopTimerProgressBar = () => {
5179 const timerProgressBar = getTimerProgressBar();
5180 if (!timerProgressBar) {
5181 return;
5182 }
5183 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
5184 timerProgressBar.style.removeProperty('transition');
5185 timerProgressBar.style.width = '100%';
5186 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
5187 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
5188 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
5189 };
5190
5191 /**
5192 * Detect Node env
5193 *
5194 * @returns {boolean}
5195 */
5196 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
5197
5198 const sweetHTML = `
5199 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
5200 <button type="button" class="${swalClasses.close}"></button>
5201 <ul class="${swalClasses['progress-steps']}"></ul>
5202 <div class="${swalClasses.icon}"></div>
5203 <img class="${swalClasses.image}" />
5204 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
5205 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
5206 <input class="${swalClasses.input}" id="${swalClasses.input}" />
5207 <input type="file" class="${swalClasses.file}" />
5208 <div class="${swalClasses.range}">
5209 <input type="range" />
5210 <output></output>
5211 </div>
5212 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
5213 <div class="${swalClasses.radio}"></div>
5214 <label class="${swalClasses.checkbox}">
5215 <input type="checkbox" id="${swalClasses.checkbox}" />
5216 <span class="${swalClasses.label}"></span>
5217 </label>
5218 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
5219 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
5220 <div class="${swalClasses.actions}">
5221 <div class="${swalClasses.loader}"></div>
5222 <button type="button" class="${swalClasses.confirm}"></button>
5223 <button type="button" class="${swalClasses.deny}"></button>
5224 <button type="button" class="${swalClasses.cancel}"></button>
5225 </div>
5226 <div class="${swalClasses.footer}"></div>
5227 <div class="${swalClasses['timer-progress-bar-container']}">
5228 <div class="${swalClasses['timer-progress-bar']}"></div>
5229 </div>
5230 </div>
5231 `.replace(/(^|\n)\s*/g, '');
5232
5233 /**
5234 * @returns {boolean}
5235 */
5236 const resetOldContainer = () => {
5237 const oldContainer = getContainer();
5238 if (!oldContainer) {
5239 return false;
5240 }
5241 oldContainer.remove();
5242 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
5243 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
5244 swalClasses['has-column']]);
5245 return true;
5246 };
5247 const resetValidationMessage$1 = () => {
5248 if (globalState.currentInstance) {
5249 globalState.currentInstance.resetValidationMessage();
5250 }
5251 };
5252 const addInputChangeListeners = () => {
5253 const popup = getPopup();
5254 if (!popup) {
5255 return;
5256 }
5257 const input = getDirectChildByClass(popup, swalClasses.input);
5258 const file = getDirectChildByClass(popup, swalClasses.file);
5259 /** @type {HTMLInputElement | null} */
5260 const range = popup.querySelector(`.${swalClasses.range} input`);
5261 /** @type {HTMLOutputElement | null} */
5262 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
5263 const select = getDirectChildByClass(popup, swalClasses.select);
5264 /** @type {HTMLInputElement | null} */
5265 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
5266 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
5267 if (input) {
5268 input.oninput = resetValidationMessage$1;
5269 }
5270 if (file) {
5271 file.onchange = resetValidationMessage$1;
5272 }
5273 if (select) {
5274 select.onchange = resetValidationMessage$1;
5275 }
5276 if (checkbox) {
5277 checkbox.onchange = resetValidationMessage$1;
5278 }
5279 if (textarea) {
5280 textarea.oninput = resetValidationMessage$1;
5281 }
5282 if (range && rangeOutput) {
5283 range.oninput = () => {
5284 resetValidationMessage$1();
5285 rangeOutput.value = range.value;
5286 };
5287 range.onchange = () => {
5288 resetValidationMessage$1();
5289 rangeOutput.value = range.value;
5290 };
5291 }
5292 };
5293
5294 /**
5295 * @param {string | HTMLElement} target
5296 * @returns {HTMLElement}
5297 */
5298 const getTarget = target => {
5299 if (typeof target === 'string') {
5300 const element = document.querySelector(target);
5301 if (!element) {
5302 throw new Error(`Target element "${target}" not found`);
5303 }
5304 return /** @type {HTMLElement} */element;
5305 }
5306 return target;
5307 };
5308
5309 /**
5310 * @param {SweetAlertOptions} params
5311 */
5312 const setupAccessibility = params => {
5313 const popup = getPopup();
5314 if (!popup) {
5315 return;
5316 }
5317 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
5318 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
5319 if (!params.toast) {
5320 popup.setAttribute('aria-modal', 'true');
5321 }
5322 };
5323
5324 /**
5325 * @param {HTMLElement} targetElement
5326 */
5327 const setupRTL = targetElement => {
5328 if (window.getComputedStyle(targetElement).direction === 'rtl') {
5329 addClass(getContainer(), swalClasses.rtl);
5330 globalState.isRTL = true;
5331 }
5332 };
5333
5334 /**
5335 * Add modal + backdrop to DOM
5336 *
5337 * @param {SweetAlertOptions} params
5338 */
5339 const init = params => {
5340 // Clean up the old popup container if it exists
5341 const oldContainerExisted = resetOldContainer();
5342 if (isNodeEnv()) {
5343 error('SweetAlert2 requires document to initialize');
5344 return;
5345 }
5346 const container = document.createElement('div');
5347 container.className = swalClasses.container;
5348 if (oldContainerExisted) {
5349 addClass(container, swalClasses['no-transition']);
5350 }
5351 setInnerHtml(container, sweetHTML);
5352 container.dataset['swal2Theme'] = params.theme;
5353 const targetElement = getTarget(params.target || 'body');
5354 targetElement.appendChild(container);
5355 if (params.topLayer) {
5356 container.setAttribute('popover', '');
5357 container.showPopover();
5358 }
5359 setupAccessibility(params);
5360 setupRTL(targetElement);
5361 addInputChangeListeners();
5362 };
5363
5364 /**
5365 * @param {HTMLElement | object | string} param
5366 * @param {HTMLElement} target
5367 */
5368 const parseHtmlToContainer = (param, target) => {
5369 // DOM element
5370 if (param instanceof HTMLElement) {
5371 target.appendChild(param);
5372 }
5373
5374 // Object
5375 else if (typeof param === 'object') {
5376 handleObject(param, target);
5377 }
5378
5379 // Plain string
5380 else if (param) {
5381 setInnerHtml(target, param);
5382 }
5383 };
5384
5385 /**
5386 * @param {object} param
5387 * @param {HTMLElement} target
5388 */
5389 const handleObject = (param, target) => {
5390 // JQuery element(s)
5391 if ('jquery' in param) {
5392 handleJqueryElem(target, param);
5393 }
5394
5395 // For other objects use their string representation
5396 else {
5397 setInnerHtml(target, param.toString());
5398 }
5399 };
5400
5401 /**
5402 * @param {HTMLElement} target
5403 * @param {any} elem
5404 */
5405 const handleJqueryElem = (target, elem) => {
5406 target.textContent = '';
5407 if (0 in elem) {
5408 for (let i = 0; i in elem; i++) {
5409 target.appendChild(elem[i].cloneNode(true));
5410 }
5411 } else {
5412 target.appendChild(elem.cloneNode(true));
5413 }
5414 };
5415
5416 /**
5417 * @param {SweetAlert} instance
5418 * @param {SweetAlertOptions} params
5419 */
5420 const renderActions = (instance, params) => {
5421 const actions = getActions();
5422 const loader = getLoader();
5423 if (!actions || !loader) {
5424 return;
5425 }
5426
5427 // Actions (buttons) wrapper
5428 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
5429 hide(actions);
5430 } else {
5431 show(actions);
5432 }
5433
5434 // Custom class
5435 applyCustomClass(actions, params, 'actions');
5436
5437 // Render all the buttons
5438 renderButtons(actions, loader, params);
5439
5440 // Loader
5441 setInnerHtml(loader, params.loaderHtml || '');
5442 applyCustomClass(loader, params, 'loader');
5443 };
5444
5445 /**
5446 * @param {HTMLElement} actions
5447 * @param {HTMLElement} loader
5448 * @param {SweetAlertOptions} params
5449 */
5450 function renderButtons(actions, loader, params) {
5451 const confirmButton = getConfirmButton();
5452 const denyButton = getDenyButton();
5453 const cancelButton = getCancelButton();
5454 if (!confirmButton || !denyButton || !cancelButton) {
5455 return;
5456 }
5457
5458 // Render buttons
5459 renderButton(confirmButton, 'confirm', params);
5460 renderButton(denyButton, 'deny', params);
5461 renderButton(cancelButton, 'cancel', params);
5462 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
5463 if (params.reverseButtons) {
5464 if (params.toast) {
5465 actions.insertBefore(cancelButton, confirmButton);
5466 actions.insertBefore(denyButton, confirmButton);
5467 } else {
5468 actions.insertBefore(cancelButton, loader);
5469 actions.insertBefore(denyButton, loader);
5470 actions.insertBefore(confirmButton, loader);
5471 }
5472 }
5473 }
5474
5475 /**
5476 * @param {HTMLElement} confirmButton
5477 * @param {HTMLElement} denyButton
5478 * @param {HTMLElement} cancelButton
5479 * @param {SweetAlertOptions} params
5480 */
5481 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
5482 if (!params.buttonsStyling) {
5483 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
5484 return;
5485 }
5486 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
5487
5488 // Apply custom background colors and outline colors to action buttons
5489 /** @type {[HTMLElement, string, string | undefined][]} */
5490 const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
5491 buttons.forEach(([button, type, color]) => {
5492 if (color) {
5493 button.style.setProperty(`--swal2-${type}-button-background-color`, color);
5494 }
5495 applyOutlineColor(button);
5496 });
5497 }
5498
5499 /**
5500 * @param {HTMLElement} button
5501 */
5502 function applyOutlineColor(button) {
5503 const buttonStyle = window.getComputedStyle(button);
5504 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
5505 // If the button already has a custom outline color, no need to change it
5506 return;
5507 }
5508 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
5509 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
5510 }
5511
5512 /**
5513 * @param {HTMLElement} button
5514 * @param {'confirm' | 'deny' | 'cancel'} buttonType
5515 * @param {SweetAlertOptions} params
5516 */
5517 function renderButton(button, buttonType, params) {
5518 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
5519 toggle(button, params[`show${buttonName}Button`], 'inline-block');
5520 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
5521 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
5522
5523 // Add buttons custom classes
5524 button.className = swalClasses[buttonType];
5525 applyCustomClass(button, params, `${buttonType}Button`);
5526 }
5527
5528 /**
5529 * @param {SweetAlert} instance
5530 * @param {SweetAlertOptions} params
5531 */
5532 const renderCloseButton = (instance, params) => {
5533 const closeButton = getCloseButton();
5534 if (!closeButton) {
5535 return;
5536 }
5537 setInnerHtml(closeButton, params.closeButtonHtml || '');
5538
5539 // Custom class
5540 applyCustomClass(closeButton, params, 'closeButton');
5541 toggle(closeButton, params.showCloseButton);
5542 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
5543 };
5544
5545 /**
5546 * @param {SweetAlert} instance
5547 * @param {SweetAlertOptions} params
5548 */
5549 const renderContainer = (instance, params) => {
5550 const container = getContainer();
5551 if (!container) {
5552 return;
5553 }
5554 handleBackdropParam(container, params.backdrop);
5555 handlePositionParam(container, params.position);
5556 handleGrowParam(container, params.grow);
5557
5558 // Custom class
5559 applyCustomClass(container, params, 'container');
5560 };
5561
5562 /**
5563 * @param {HTMLElement} container
5564 * @param {SweetAlertOptions['backdrop']} backdrop
5565 */
5566 function handleBackdropParam(container, backdrop) {
5567 if (typeof backdrop === 'string') {
5568 container.style.background = backdrop;
5569 } else if (!backdrop) {
5570 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
5571 }
5572 }
5573
5574 /**
5575 * @param {HTMLElement} container
5576 * @param {SweetAlertOptions['position']} position
5577 */
5578 function handlePositionParam(container, position) {
5579 if (!position) {
5580 return;
5581 }
5582 if (position in swalClasses) {
5583 addClass(container, swalClasses[position]);
5584 } else {
5585 warn('The "position" parameter is not valid, defaulting to "center"');
5586 addClass(container, swalClasses.center);
5587 }
5588 }
5589
5590 /**
5591 * @param {HTMLElement} container
5592 * @param {SweetAlertOptions['grow']} grow
5593 */
5594 function handleGrowParam(container, grow) {
5595 if (!grow) {
5596 return;
5597 }
5598 addClass(container, swalClasses[`grow-${grow}`]);
5599 }
5600
5601 /**
5602 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
5603 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
5604 * This is the approach that Babel will probably take to implement private methods/fields
5605 * https://github.com/tc39/proposal-private-methods
5606 * https://github.com/babel/babel/pull/7555
5607 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
5608 * then we can use that language feature.
5609 */
5610
5611 var privateProps = {
5612 innerParams: new WeakMap(),
5613 domCache: new WeakMap(),
5614 focusedElement: new WeakMap()
5615 };
5616
5617 /// <reference path="../../../../sweetalert2.d.ts"/>
5618
5619
5620 /** @type {InputClass[]} */
5621 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
5622
5623 /**
5624 * @param {SweetAlert} instance
5625 * @param {SweetAlertOptions} params
5626 */
5627 const renderInput = (instance, params) => {
5628 const popup = getPopup();
5629 if (!popup) {
5630 return;
5631 }
5632 const innerParams = privateProps.innerParams.get(instance);
5633 const rerender = !innerParams || params.input !== innerParams.input;
5634 inputClasses.forEach(inputClass => {
5635 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
5636 if (!inputContainer) {
5637 return;
5638 }
5639
5640 // set attributes
5641 setAttributes(inputClass, params.inputAttributes);
5642
5643 // set class
5644 inputContainer.className = swalClasses[inputClass];
5645 if (rerender) {
5646 hide(inputContainer);
5647 }
5648 });
5649 if (params.input) {
5650 if (rerender) {
5651 showInput(params);
5652 }
5653 // set custom class
5654 setCustomClass(params);
5655 }
5656 };
5657
5658 /**
5659 * @param {SweetAlertOptions} params
5660 */
5661 const showInput = params => {
5662 if (!params.input) {
5663 return;
5664 }
5665 if (!renderInputType[params.input]) {
5666 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
5667 return;
5668 }
5669 const inputContainer = getInputContainer(params.input);
5670 if (!inputContainer) {
5671 return;
5672 }
5673 const input = renderInputType[params.input](inputContainer, params);
5674 show(inputContainer);
5675
5676 // input autofocus
5677 if (params.inputAutoFocus) {
5678 setTimeout(() => {
5679 focusInput(input);
5680 });
5681 }
5682 };
5683
5684 /**
5685 * @param {HTMLInputElement} input
5686 */
5687 const removeAttributes = input => {
5688 for (const {
5689 name
5690 } of Array.from(input.attributes)) {
5691 if (!['id', 'type', 'value', 'style'].includes(name)) {
5692 input.removeAttribute(name);
5693 }
5694 }
5695 };
5696
5697 /**
5698 * @param {InputClass} inputClass
5699 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
5700 */
5701 const setAttributes = (inputClass, inputAttributes) => {
5702 const popup = getPopup();
5703 if (!popup) {
5704 return;
5705 }
5706 const input = getInput$1(popup, inputClass);
5707 if (!input) {
5708 return;
5709 }
5710 removeAttributes(input);
5711 for (const attr in inputAttributes) {
5712 input.setAttribute(attr, inputAttributes[attr]);
5713 }
5714 };
5715
5716 /**
5717 * @param {SweetAlertOptions} params
5718 */
5719 const setCustomClass = params => {
5720 if (!params.input) {
5721 return;
5722 }
5723 const inputContainer = getInputContainer(params.input);
5724 if (inputContainer) {
5725 applyCustomClass(inputContainer, params, 'input');
5726 }
5727 };
5728
5729 /**
5730 * @param {HTMLInputElement | HTMLTextAreaElement} input
5731 * @param {SweetAlertOptions} params
5732 */
5733 const setInputPlaceholder = (input, params) => {
5734 if (!input.placeholder && params.inputPlaceholder) {
5735 input.placeholder = params.inputPlaceholder;
5736 }
5737 };
5738
5739 /**
5740 * @param {Input} input
5741 * @param {Input} prependTo
5742 * @param {SweetAlertOptions} params
5743 */
5744 const setInputLabel = (input, prependTo, params) => {
5745 if (params.inputLabel) {
5746 const label = document.createElement('label');
5747 const labelClass = swalClasses['input-label'];
5748 label.setAttribute('for', input.id);
5749 label.className = labelClass;
5750 if (typeof params.customClass === 'object') {
5751 addClass(label, params.customClass.inputLabel);
5752 }
5753 label.innerText = params.inputLabel;
5754 prependTo.insertAdjacentElement('beforebegin', label);
5755 }
5756 };
5757
5758 /**
5759 * @param {SweetAlertInput} inputType
5760 * @returns {HTMLElement | undefined}
5761 */
5762 const getInputContainer = inputType => {
5763 const popup = getPopup();
5764 if (!popup) {
5765 return;
5766 }
5767 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
5768 };
5769
5770 /**
5771 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
5772 * @param {SweetAlertOptions['inputValue']} inputValue
5773 */
5774 const checkAndSetInputValue = (input, inputValue) => {
5775 if (['string', 'number'].includes(typeof inputValue)) {
5776 input.value = `${inputValue}`;
5777 } else if (!isPromise(inputValue)) {
5778 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
5779 }
5780 };
5781
5782 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
5783 const renderInputType = {};
5784
5785 /**
5786 * @param {Input | HTMLElement} input
5787 * @param {SweetAlertOptions} params
5788 * @returns {Input}
5789 */
5790 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} */
5791 (input, params) => {
5792 // oxfmt-ignore
5793 const inputElement = /** @type {HTMLInputElement} */input;
5794 checkAndSetInputValue(inputElement, params.inputValue);
5795 setInputLabel(inputElement, inputElement, params);
5796 setInputPlaceholder(inputElement, params);
5797 // oxfmt-ignore
5798 inputElement.type = /** @type {string} */params.input;
5799 return inputElement;
5800 };
5801
5802 /**
5803 * @param {Input | HTMLElement} input
5804 * @param {SweetAlertOptions} params
5805 * @returns {Input}
5806 */
5807 renderInputType.file = (input, params) => {
5808 const inputElement = /** @type {HTMLInputElement} */input;
5809 setInputLabel(inputElement, inputElement, params);
5810 setInputPlaceholder(inputElement, params);
5811 return inputElement;
5812 };
5813
5814 /**
5815 * @param {Input | HTMLElement} range
5816 * @param {SweetAlertOptions} params
5817 * @returns {Input}
5818 */
5819 renderInputType.range = (range, params) => {
5820 const rangeContainer = /** @type {HTMLElement} */range;
5821 const rangeInput = rangeContainer.querySelector('input');
5822 const rangeOutput = rangeContainer.querySelector('output');
5823 if (rangeInput) {
5824 checkAndSetInputValue(rangeInput, params.inputValue);
5825 rangeInput.type = /** @type {string} */params.input;
5826 setInputLabel(rangeInput, /** @type {Input} */range, params);
5827 }
5828 if (rangeOutput) {
5829 checkAndSetInputValue(rangeOutput, params.inputValue);
5830 }
5831 return /** @type {Input} */range;
5832 };
5833
5834 /**
5835 * @param {Input | HTMLElement} select
5836 * @param {SweetAlertOptions} params
5837 * @returns {Input}
5838 */
5839 renderInputType.select = (select, params) => {
5840 const selectElement = /** @type {HTMLSelectElement} */select;
5841 selectElement.textContent = '';
5842 if (params.inputPlaceholder) {
5843 const placeholder = document.createElement('option');
5844 setInnerHtml(placeholder, params.inputPlaceholder);
5845 placeholder.value = '';
5846 placeholder.disabled = true;
5847 placeholder.selected = true;
5848 selectElement.appendChild(placeholder);
5849 }
5850 setInputLabel(selectElement, selectElement, params);
5851 return selectElement;
5852 };
5853
5854 /**
5855 * @param {Input | HTMLElement} radio
5856 * @returns {Input}
5857 */
5858 renderInputType.radio = radio => {
5859 const radioElement = /** @type {HTMLElement} */radio;
5860 radioElement.textContent = '';
5861 return /** @type {Input} */radio;
5862 };
5863
5864 /**
5865 * @param {Input | HTMLElement} checkboxContainer
5866 * @param {SweetAlertOptions} params
5867 * @returns {Input}
5868 */
5869 renderInputType.checkbox = (checkboxContainer, params) => {
5870 const popup = getPopup();
5871 if (!popup) {
5872 throw new Error('Popup not found');
5873 }
5874 const checkbox = getInput$1(popup, 'checkbox');
5875 if (!checkbox) {
5876 throw new Error('Checkbox input not found');
5877 }
5878 checkbox.value = '1';
5879 checkbox.checked = Boolean(params.inputValue);
5880 const containerElement = /** @type {HTMLElement} */checkboxContainer;
5881 const label = containerElement.querySelector('span');
5882 if (label) {
5883 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
5884 if (placeholderOrLabel) {
5885 setInnerHtml(label, placeholderOrLabel);
5886 }
5887 }
5888 return checkbox;
5889 };
5890
5891 /**
5892 * @param {Input | HTMLElement} textarea
5893 * @param {SweetAlertOptions} params
5894 * @returns {Input}
5895 */
5896 renderInputType.textarea = (textarea, params) => {
5897 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
5898 checkAndSetInputValue(textareaElement, params.inputValue);
5899 setInputPlaceholder(textareaElement, params);
5900 setInputLabel(textareaElement, textareaElement, params);
5901
5902 /**
5903 * @param {HTMLElement} el
5904 * @returns {number}
5905 */
5906 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
5907
5908 // https://github.com/sweetalert2/sweetalert2/issues/2291
5909 setTimeout(() => {
5910 // https://github.com/sweetalert2/sweetalert2/issues/1699
5911 if ('MutationObserver' in window) {
5912 const popup = getPopup();
5913 if (!popup) {
5914 return;
5915 }
5916 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
5917 const textareaResizeHandler = () => {
5918 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
5919 if (!document.body.contains(textareaElement)) {
5920 return;
5921 }
5922 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
5923 const popupElement = getPopup();
5924 if (popupElement) {
5925 if (textareaWidth > initialPopupWidth) {
5926 popupElement.style.width = `${textareaWidth}px`;
5927 } else {
5928 applyNumericalStyle(popupElement, 'width', params.width);
5929 }
5930 }
5931 };
5932 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
5933 attributes: true,
5934 attributeFilter: ['style']
5935 });
5936 }
5937 });
5938 return textareaElement;
5939 };
5940
5941 /**
5942 * @param {SweetAlert} instance
5943 * @param {SweetAlertOptions} params
5944 */
5945 const renderContent = (instance, params) => {
5946 const htmlContainer = getHtmlContainer();
5947 if (!htmlContainer) {
5948 return;
5949 }
5950 showWhenInnerHtmlPresent(htmlContainer);
5951 applyCustomClass(htmlContainer, params, 'htmlContainer');
5952
5953 // Content as HTML
5954 if (params.html) {
5955 parseHtmlToContainer(params.html, htmlContainer);
5956 show(htmlContainer, 'block');
5957 }
5958
5959 // Content as plain text
5960 else if (params.text) {
5961 htmlContainer.textContent = params.text;
5962 show(htmlContainer, 'block');
5963 }
5964
5965 // No content
5966 else {
5967 hide(htmlContainer);
5968 }
5969 renderInput(instance, params);
5970 };
5971
5972 /**
5973 * @param {SweetAlert} instance
5974 * @param {SweetAlertOptions} params
5975 */
5976 const renderFooter = (instance, params) => {
5977 const footer = getFooter();
5978 if (!footer) {
5979 return;
5980 }
5981 showWhenInnerHtmlPresent(footer);
5982 toggle(footer, Boolean(params.footer), 'block');
5983 if (params.footer) {
5984 parseHtmlToContainer(params.footer, footer);
5985 }
5986
5987 // Custom class
5988 applyCustomClass(footer, params, 'footer');
5989 };
5990
5991 /**
5992 * @param {SweetAlert} instance
5993 * @param {SweetAlertOptions} params
5994 */
5995 const renderIcon = (instance, params) => {
5996 const innerParams = privateProps.innerParams.get(instance);
5997 const icon = getIcon();
5998 if (!icon) {
5999 return;
6000 }
6001
6002 // if the given icon already rendered, apply the styling without re-rendering the icon
6003 if (innerParams && params.icon === innerParams.icon) {
6004 // Custom or default content
6005 setContent(icon, params);
6006 applyStyles(icon, params);
6007 return;
6008 }
6009 if (!params.icon && !params.iconHtml) {
6010 hide(icon);
6011 return;
6012 }
6013 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
6014 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
6015 hide(icon);
6016 return;
6017 }
6018 show(icon);
6019
6020 // Custom or default content
6021 setContent(icon, params);
6022 applyStyles(icon, params);
6023
6024 // Animate icon
6025 addClass(icon, params.showClass && params.showClass.icon);
6026
6027 // Re-adjust the success icon on system theme change
6028 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
6029 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
6030 };
6031
6032 /**
6033 * @param {HTMLElement} icon
6034 * @param {SweetAlertOptions} params
6035 */
6036 const applyStyles = (icon, params) => {
6037 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
6038 if (params.icon !== iconType) {
6039 removeClass(icon, iconClassName);
6040 }
6041 }
6042 addClass(icon, params.icon && iconTypes[params.icon]);
6043
6044 // Icon color
6045 setColor(icon, params);
6046
6047 // Success icon background color
6048 adjustSuccessIconBackgroundColor();
6049
6050 // Custom class
6051 applyCustomClass(icon, params, 'icon');
6052 };
6053
6054 // Adjust success icon background color to match the popup background color
6055 const adjustSuccessIconBackgroundColor = () => {
6056 const popup = getPopup();
6057 if (!popup) {
6058 return;
6059 }
6060 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
6061 /** @type {NodeListOf<HTMLElement>} */
6062 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
6063 successIconParts.forEach(part => {
6064 part.style.backgroundColor = popupBackgroundColor;
6065 });
6066 };
6067
6068 /**
6069 *
6070 * @param {SweetAlertOptions} params
6071 * @returns {string}
6072 */
6073 const successIconHtml = params => `
6074 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
6075 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
6076 <div class="swal2-success-ring"></div>
6077 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
6078 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
6079 `;
6080 const errorIconHtml = `
6081 <span class="swal2-x-mark">
6082 <span class="swal2-x-mark-line-left"></span>
6083 <span class="swal2-x-mark-line-right"></span>
6084 </span>
6085 `;
6086
6087 /**
6088 * @param {HTMLElement} icon
6089 * @param {SweetAlertOptions} params
6090 */
6091 const setContent = (icon, params) => {
6092 if (!params.icon && !params.iconHtml) {
6093 return;
6094 }
6095 let oldContent = icon.innerHTML;
6096 let newContent = '';
6097 if (params.iconHtml) {
6098 newContent = iconContent(params.iconHtml);
6099 } else if (params.icon === 'success') {
6100 newContent = successIconHtml(params);
6101 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
6102 } else if (params.icon === 'error') {
6103 newContent = errorIconHtml;
6104 } else if (params.icon) {
6105 const defaultIconHtml = {
6106 question: '?',
6107 warning: '!',
6108 info: 'i'
6109 };
6110 newContent = iconContent(defaultIconHtml[params.icon]);
6111 }
6112 if (oldContent.trim() !== newContent.trim()) {
6113 setInnerHtml(icon, newContent);
6114 }
6115 };
6116
6117 /**
6118 * @param {HTMLElement} icon
6119 * @param {SweetAlertOptions} params
6120 */
6121 const setColor = (icon, params) => {
6122 if (!params.iconColor) {
6123 return;
6124 }
6125 icon.style.color = params.iconColor;
6126 icon.style.borderColor = params.iconColor;
6127 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
6128 setStyle(icon, sel, 'background-color', params.iconColor);
6129 }
6130 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
6131 };
6132
6133 /**
6134 * @param {string} content
6135 * @returns {string}
6136 */
6137 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
6138
6139 /**
6140 * @param {SweetAlert} instance
6141 * @param {SweetAlertOptions} params
6142 */
6143 const renderImage = (instance, params) => {
6144 const image = getImage();
6145 if (!image) {
6146 return;
6147 }
6148 if (!params.imageUrl) {
6149 hide(image);
6150 return;
6151 }
6152 show(image, '');
6153
6154 // Src, alt
6155 image.setAttribute('src', params.imageUrl);
6156 image.setAttribute('alt', params.imageAlt || '');
6157
6158 // Width, height
6159 applyNumericalStyle(image, 'width', params.imageWidth);
6160 applyNumericalStyle(image, 'height', params.imageHeight);
6161
6162 // Class
6163 image.className = swalClasses.image;
6164 applyCustomClass(image, params, 'image');
6165 };
6166
6167 let dragging = false;
6168 let mousedownX = 0;
6169 let mousedownY = 0;
6170 let initialX = 0;
6171 let initialY = 0;
6172
6173 /**
6174 * @param {HTMLElement} popup
6175 */
6176 const addDraggableListeners = popup => {
6177 popup.addEventListener('mousedown', down);
6178 document.body.addEventListener('mousemove', move);
6179 popup.addEventListener('mouseup', up);
6180 popup.addEventListener('touchstart', down);
6181 document.body.addEventListener('touchmove', move);
6182 popup.addEventListener('touchend', up);
6183 };
6184
6185 /**
6186 * @param {HTMLElement} popup
6187 */
6188 const removeDraggableListeners = popup => {
6189 popup.removeEventListener('mousedown', down);
6190 document.body.removeEventListener('mousemove', move);
6191 popup.removeEventListener('mouseup', up);
6192 popup.removeEventListener('touchstart', down);
6193 document.body.removeEventListener('touchmove', move);
6194 popup.removeEventListener('touchend', up);
6195 };
6196
6197 /**
6198 * @param {MouseEvent | TouchEvent} event
6199 */
6200 const down = event => {
6201 const popup = getPopup();
6202 if (!popup) {
6203 return;
6204 }
6205 const icon = getIcon();
6206 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
6207 dragging = true;
6208 const clientXY = getClientXY(event);
6209 mousedownX = clientXY.clientX;
6210 mousedownY = clientXY.clientY;
6211 initialX = parseInt(popup.style.insetInlineStart) || 0;
6212 initialY = parseInt(popup.style.insetBlockStart) || 0;
6213 addClass(popup, 'swal2-dragging');
6214 }
6215 };
6216
6217 /**
6218 * @param {MouseEvent | TouchEvent} event
6219 */
6220 const move = event => {
6221 const popup = getPopup();
6222 if (!popup) {
6223 return;
6224 }
6225 if (dragging) {
6226 let {
6227 clientX,
6228 clientY
6229 } = getClientXY(event);
6230 const deltaX = clientX - mousedownX;
6231 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
6232 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
6233 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
6234 }
6235 };
6236 const up = () => {
6237 const popup = getPopup();
6238 dragging = false;
6239 removeClass(popup, 'swal2-dragging');
6240 };
6241
6242 /**
6243 * @param {MouseEvent | TouchEvent} event
6244 * @returns {{ clientX: number, clientY: number }}
6245 */
6246 const getClientXY = event => {
6247 const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
6248 return {
6249 clientX: source.clientX,
6250 clientY: source.clientY
6251 };
6252 };
6253
6254 /**
6255 * @param {SweetAlert} instance
6256 * @param {SweetAlertOptions} params
6257 */
6258 const renderPopup = (instance, params) => {
6259 const container = getContainer();
6260 const popup = getPopup();
6261 if (!container || !popup) {
6262 return;
6263 }
6264
6265 // Width
6266 // https://github.com/sweetalert2/sweetalert2/issues/2170
6267 if (params.toast) {
6268 applyNumericalStyle(container, 'width', params.width);
6269 popup.style.width = '100%';
6270 const loader = getLoader();
6271 if (loader) {
6272 popup.insertBefore(loader, getIcon());
6273 }
6274 } else {
6275 applyNumericalStyle(popup, 'width', params.width);
6276 }
6277
6278 // Padding
6279 applyNumericalStyle(popup, 'padding', params.padding);
6280
6281 // Color
6282 if (params.color) {
6283 popup.style.color = params.color;
6284 }
6285
6286 // Background
6287 if (params.background) {
6288 popup.style.background = params.background;
6289 }
6290 hide(getValidationMessage());
6291
6292 // Classes
6293 addClasses$1(popup, params);
6294 if (params.draggable && !params.toast) {
6295 addClass(popup, swalClasses.draggable);
6296 addDraggableListeners(popup);
6297 } else {
6298 removeClass(popup, swalClasses.draggable);
6299 removeDraggableListeners(popup);
6300 }
6301 };
6302
6303 /**
6304 * @param {HTMLElement} popup
6305 * @param {SweetAlertOptions} params
6306 */
6307 const addClasses$1 = (popup, params) => {
6308 const showClass = params.showClass || {};
6309 // Default Class + showClass when updating Swal.update({})
6310 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
6311 if (params.toast) {
6312 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
6313 addClass(popup, swalClasses.toast);
6314 } else {
6315 addClass(popup, swalClasses.modal);
6316 }
6317
6318 // Custom class
6319 applyCustomClass(popup, params, 'popup');
6320 // TODO: remove in the next major
6321 if (typeof params.customClass === 'string') {
6322 addClass(popup, params.customClass);
6323 }
6324
6325 // Icon class (#1842)
6326 if (params.icon) {
6327 addClass(popup, swalClasses[`icon-${params.icon}`]);
6328 }
6329 };
6330
6331 /**
6332 * @param {SweetAlert} instance
6333 * @param {SweetAlertOptions} params
6334 */
6335 const renderProgressSteps = (instance, params) => {
6336 const progressStepsContainer = getProgressSteps();
6337 if (!progressStepsContainer) {
6338 return;
6339 }
6340 const {
6341 progressSteps,
6342 currentProgressStep
6343 } = params;
6344 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
6345 hide(progressStepsContainer);
6346 return;
6347 }
6348 show(progressStepsContainer);
6349 progressStepsContainer.textContent = '';
6350 if (currentProgressStep >= progressSteps.length) {
6351 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
6352 }
6353 progressSteps.forEach((step, index) => {
6354 const stepEl = createStepElement(step);
6355 progressStepsContainer.appendChild(stepEl);
6356 if (index === currentProgressStep) {
6357 addClass(stepEl, swalClasses['active-progress-step']);
6358 }
6359 if (index !== progressSteps.length - 1) {
6360 const lineEl = createLineElement(params);
6361 progressStepsContainer.appendChild(lineEl);
6362 }
6363 });
6364 };
6365
6366 /**
6367 * @param {string} step
6368 * @returns {HTMLLIElement}
6369 */
6370 const createStepElement = step => {
6371 const stepEl = document.createElement('li');
6372 addClass(stepEl, swalClasses['progress-step']);
6373 setInnerHtml(stepEl, step);
6374 return stepEl;
6375 };
6376
6377 /**
6378 * @param {SweetAlertOptions} params
6379 * @returns {HTMLLIElement}
6380 */
6381 const createLineElement = params => {
6382 const lineEl = document.createElement('li');
6383 addClass(lineEl, swalClasses['progress-step-line']);
6384 if (params.progressStepsDistance) {
6385 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
6386 }
6387 return lineEl;
6388 };
6389
6390 /**
6391 * @param {SweetAlert} instance
6392 * @param {SweetAlertOptions} params
6393 */
6394 const renderTitle = (instance, params) => {
6395 const title = getTitle();
6396 if (!title) {
6397 return;
6398 }
6399 showWhenInnerHtmlPresent(title);
6400 toggle(title, Boolean(params.title || params.titleText), 'block');
6401 if (params.title) {
6402 parseHtmlToContainer(params.title, title);
6403 }
6404 if (params.titleText) {
6405 title.innerText = params.titleText;
6406 }
6407
6408 // Custom class
6409 applyCustomClass(title, params, 'title');
6410 };
6411
6412 /**
6413 * @param {SweetAlert} instance
6414 * @param {SweetAlertOptions} params
6415 */
6416 const render = (instance, params) => {
6417 var _globalState$eventEmi;
6418 renderPopup(instance, params);
6419 renderContainer(instance, params);
6420 renderProgressSteps(instance, params);
6421 renderIcon(instance, params);
6422 renderImage(instance, params);
6423 renderTitle(instance, params);
6424 renderCloseButton(instance, params);
6425 renderContent(instance, params);
6426 renderActions(instance, params);
6427 renderFooter(instance, params);
6428 const popup = getPopup();
6429 if (typeof params.didRender === 'function' && popup) {
6430 params.didRender(popup);
6431 }
6432 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
6433 };
6434
6435 /*
6436 * Global function to determine if SweetAlert2 popup is shown
6437 */
6438 const isVisible = () => {
6439 return isVisible$1(getPopup());
6440 };
6441
6442 /*
6443 * Global function to click 'Confirm' button
6444 */
6445 const clickConfirm = () => {
6446 var _dom$getConfirmButton;
6447 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
6448 };
6449
6450 /*
6451 * Global function to click 'Deny' button
6452 */
6453 const clickDeny = () => {
6454 var _dom$getDenyButton;
6455 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
6456 };
6457
6458 /*
6459 * Global function to click 'Cancel' button
6460 */
6461 const clickCancel = () => {
6462 var _dom$getCancelButton;
6463 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
6464 };
6465
6466 /** @type {Record<DismissReason, DismissReason>} */
6467 const DismissReason = Object.freeze({
6468 cancel: 'cancel',
6469 backdrop: 'backdrop',
6470 close: 'close',
6471 esc: 'esc',
6472 timer: 'timer'
6473 });
6474
6475 /**
6476 * @param {GlobalState} globalState
6477 */
6478 const removeKeydownHandler = globalState => {
6479 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
6480 const handler = /** @type {EventListenerOrEventListenerObject} */
6481 /** @type {unknown} */globalState.keydownHandler;
6482 globalState.keydownTarget.removeEventListener('keydown', handler, {
6483 capture: globalState.keydownListenerCapture
6484 });
6485 globalState.keydownHandlerAdded = false;
6486 }
6487 };
6488
6489 /**
6490 * @param {GlobalState} globalState
6491 * @param {SweetAlertOptions} innerParams
6492 * @param {(dismiss: DismissReason) => void} dismissWith
6493 */
6494 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
6495 removeKeydownHandler(globalState);
6496 if (!innerParams.toast) {
6497 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
6498 const handler = e => keydownHandler(innerParams, e, dismissWith);
6499 globalState.keydownHandler = handler;
6500 const target = innerParams.keydownListenerCapture ? window : getPopup();
6501 if (target) {
6502 globalState.keydownTarget = target;
6503 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
6504 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
6505 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
6506 capture: globalState.keydownListenerCapture
6507 });
6508 globalState.keydownHandlerAdded = true;
6509 }
6510 }
6511 };
6512
6513 /**
6514 * @param {number} index
6515 * @param {number} increment
6516 * @returns {boolean} shouldPreventDefault
6517 */
6518 const setFocus = (index, increment) => {
6519 var _dom$getPopup;
6520 const focusableElements = getFocusableElements();
6521 // search for visible elements and select the next possible match
6522 if (focusableElements.length) {
6523 index = index + increment;
6524
6525 // shift + tab when .swal2-popup is focused
6526 if (index === -2) {
6527 index = focusableElements.length - 1;
6528 }
6529
6530 // rollover to first item
6531 if (index === focusableElements.length) {
6532 index = 0;
6533
6534 // go to last item
6535 } else if (index === -1) {
6536 index = focusableElements.length - 1;
6537 }
6538 focusableElements[index].focus();
6539
6540 // don't prevent default for iframes (Firefox fix)
6541 // https://github.com/sweetalert2/sweetalert2/issues/2931
6542 if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
6543 return false;
6544 }
6545 return true;
6546 }
6547 // no visible focusable elements, focus the popup
6548 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
6549 return true;
6550 };
6551 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
6552 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
6553
6554 /**
6555 * @param {SweetAlertOptions} innerParams
6556 * @param {KeyboardEvent} event
6557 * @param {(dismiss: DismissReason) => void} dismissWith
6558 */
6559 const keydownHandler = (innerParams, event, dismissWith) => {
6560 if (!innerParams) {
6561 return; // This instance has already been destroyed
6562 }
6563
6564 // Ignore keydown during IME composition
6565 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
6566 // https://github.com/sweetalert2/sweetalert2/issues/720
6567 // https://github.com/sweetalert2/sweetalert2/issues/2406
6568 if (event.isComposing || event.keyCode === 229) {
6569 return;
6570 }
6571 if (innerParams.stopKeydownPropagation) {
6572 event.stopPropagation();
6573 }
6574
6575 // ENTER
6576 if (event.key === 'Enter') {
6577 handleEnter(event, innerParams);
6578 }
6579
6580 // TAB
6581 else if (event.key === 'Tab') {
6582 handleTab(event);
6583 }
6584
6585 // ARROWS - switch focus between buttons
6586 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
6587 handleArrows(event.key);
6588 }
6589
6590 // ESC
6591 else if (event.key === 'Escape') {
6592 handleEsc(event, innerParams, dismissWith);
6593 }
6594 };
6595
6596 /**
6597 * @param {KeyboardEvent} event
6598 * @param {SweetAlertOptions} innerParams
6599 */
6600 const handleEnter = (event, innerParams) => {
6601 // https://github.com/sweetalert2/sweetalert2/issues/2386
6602 if (!callIfFunction(innerParams.allowEnterKey)) {
6603 return;
6604 }
6605 const popup = getPopup();
6606 if (!popup || !innerParams.input) {
6607 return;
6608 }
6609 const input = getInput$1(popup, innerParams.input);
6610 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
6611 if (['textarea', 'file'].includes(innerParams.input)) {
6612 return; // do not submit
6613 }
6614 clickConfirm();
6615 event.preventDefault();
6616 }
6617 };
6618
6619 /**
6620 * @param {KeyboardEvent} event
6621 */
6622 const handleTab = event => {
6623 const targetElement = event.target;
6624 const focusableElements = getFocusableElements();
6625 const btnIndex = focusableElements.findIndex(el => el === targetElement);
6626
6627 // don't prevent default for iframes (Firefox fix)
6628 // https://github.com/sweetalert2/sweetalert2/issues/2931
6629 let shouldPreventDefault = true;
6630
6631 // Cycle to the next button
6632 if (!event.shiftKey) {
6633 shouldPreventDefault = setFocus(btnIndex, 1);
6634 }
6635
6636 // Cycle to the prev button
6637 else {
6638 shouldPreventDefault = setFocus(btnIndex, -1);
6639 }
6640 event.stopPropagation();
6641 if (shouldPreventDefault) {
6642 event.preventDefault();
6643 }
6644 };
6645
6646 /**
6647 * @param {string} key
6648 */
6649 const handleArrows = key => {
6650 const actions = getActions();
6651 const confirmButton = getConfirmButton();
6652 const denyButton = getDenyButton();
6653 const cancelButton = getCancelButton();
6654 if (!actions || !confirmButton || !denyButton || !cancelButton) {
6655 return;
6656 }
6657 /** @type HTMLElement[] */
6658 const buttons = [confirmButton, denyButton, cancelButton];
6659 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
6660 return;
6661 }
6662 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
6663 let buttonToFocus = document.activeElement;
6664 if (!buttonToFocus) {
6665 return;
6666 }
6667 for (let i = 0; i < actions.children.length; i++) {
6668 buttonToFocus = buttonToFocus[sibling];
6669 if (!buttonToFocus) {
6670 return;
6671 }
6672 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
6673 break;
6674 }
6675 }
6676 if (buttonToFocus instanceof HTMLButtonElement) {
6677 buttonToFocus.focus();
6678 }
6679 };
6680
6681 /**
6682 * @param {KeyboardEvent} event
6683 * @param {SweetAlertOptions} innerParams
6684 * @param {(dismiss: DismissReason) => void} dismissWith
6685 */
6686 const handleEsc = (event, innerParams, dismissWith) => {
6687 event.preventDefault();
6688 if (callIfFunction(innerParams.allowEscapeKey)) {
6689 dismissWith(DismissReason.esc);
6690 }
6691 };
6692
6693 /**
6694 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
6695 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
6696 * This is the approach that Babel will probably take to implement private methods/fields
6697 * https://github.com/tc39/proposal-private-methods
6698 * https://github.com/babel/babel/pull/7555
6699 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
6700 * then we can use that language feature.
6701 */
6702
6703 var privateMethods = {
6704 swalPromiseResolve: new WeakMap(),
6705 swalPromiseReject: new WeakMap()
6706 };
6707
6708 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
6709 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
6710 // elements not within the active modal dialog will not be surfaced if a user opens a screen
6711 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
6712
6713 const setAriaHidden = () => {
6714 const container = getContainer();
6715 const bodyChildren = Array.from(document.body.children);
6716 bodyChildren.forEach(el => {
6717 if (el.contains(container)) {
6718 return;
6719 }
6720 if (el.hasAttribute('aria-hidden')) {
6721 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
6722 }
6723 el.setAttribute('aria-hidden', 'true');
6724 });
6725 };
6726 const unsetAriaHidden = () => {
6727 const bodyChildren = Array.from(document.body.children);
6728 bodyChildren.forEach(el => {
6729 if (el.hasAttribute('data-previous-aria-hidden')) {
6730 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
6731 el.removeAttribute('data-previous-aria-hidden');
6732 } else {
6733 el.removeAttribute('aria-hidden');
6734 }
6735 });
6736 };
6737
6738 // @ts-ignore
6739 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
6740
6741 // @ts-ignore
6742 const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
6743
6744 /**
6745 * Fix iOS scrolling
6746 * http://stackoverflow.com/q/39626302
6747 */
6748 const iOSfix = () => {
6749 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
6750 const offset = document.body.scrollTop;
6751 document.body.style.top = `${offset * -1}px`;
6752 addClass(document.body, swalClasses.iosfix);
6753 lockBodyScroll();
6754 }
6755 };
6756
6757 /**
6758 * https://github.com/sweetalert2/sweetalert2/issues/1246
6759 */
6760 const lockBodyScroll = () => {
6761 const container = getContainer();
6762 if (!container) {
6763 return;
6764 }
6765 /** @type {boolean} */
6766 let preventTouchMove;
6767 /**
6768 * @param {TouchEvent} event
6769 */
6770 container.ontouchstart = event => {
6771 preventTouchMove = shouldPreventTouchMove(event);
6772 };
6773 /**
6774 * @param {TouchEvent} event
6775 */
6776 container.ontouchmove = event => {
6777 if (preventTouchMove) {
6778 event.preventDefault();
6779 event.stopPropagation();
6780 }
6781 };
6782 };
6783
6784 /**
6785 * @param {TouchEvent} event
6786 * @returns {boolean}
6787 */
6788 const shouldPreventTouchMove = event => {
6789 const target = event.target;
6790 const container = getContainer();
6791 const htmlContainer = getHtmlContainer();
6792 if (!container || !htmlContainer) {
6793 return false;
6794 }
6795 if (isStylus(event) || isZoom(event)) {
6796 return false;
6797 }
6798 if (target === container) {
6799 return true;
6800 }
6801 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
6802 // #2823
6803 target.tagName !== 'INPUT' &&
6804 // #1603
6805 target.tagName !== 'TEXTAREA' &&
6806 // #2266
6807 !(isScrollable(htmlContainer) &&
6808 // #1944
6809 htmlContainer.contains(target))) {
6810 return true;
6811 }
6812 return false;
6813 };
6814
6815 /**
6816 * https://github.com/sweetalert2/sweetalert2/issues/1786
6817 *
6818 * @param {TouchEvent} event
6819 * @returns {boolean}
6820 */
6821 const isStylus = event => {
6822 return Boolean(event.touches && event.touches.length &&
6823 // @ts-ignore - touchType is not a standard property
6824 event.touches[0].touchType === 'stylus');
6825 };
6826
6827 /**
6828 * https://github.com/sweetalert2/sweetalert2/issues/1891
6829 *
6830 * @param {TouchEvent} event
6831 * @returns {boolean}
6832 */
6833 const isZoom = event => {
6834 return event.touches && event.touches.length > 1;
6835 };
6836 const undoIOSfix = () => {
6837 if (hasClass(document.body, swalClasses.iosfix)) {
6838 const offset = parseInt(document.body.style.top, 10);
6839 removeClass(document.body, swalClasses.iosfix);
6840 document.body.style.top = '';
6841 document.body.scrollTop = offset * -1;
6842 }
6843 };
6844
6845 /**
6846 * Measure scrollbar width for padding body during modal show/hide
6847 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
6848 *
6849 * @returns {number}
6850 */
6851 const measureScrollbar = () => {
6852 const scrollDiv = document.createElement('div');
6853 scrollDiv.className = swalClasses['scrollbar-measure'];
6854 document.body.appendChild(scrollDiv);
6855 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
6856 document.body.removeChild(scrollDiv);
6857 return scrollbarWidth;
6858 };
6859
6860 /**
6861 * Remember state in cases where opening and handling a modal will fiddle with it.
6862 * @type {number | null}
6863 */
6864 let previousBodyPadding = null;
6865
6866 /**
6867 * @param {string} initialBodyOverflow
6868 */
6869 const replaceScrollbarWithPadding = initialBodyOverflow => {
6870 // for queues, do not do this more than once
6871 if (previousBodyPadding !== null) {
6872 return;
6873 }
6874 // if the body has overflow
6875 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
6876 ) {
6877 // add padding so the content doesn't shift after removal of scrollbar
6878 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
6879 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
6880 }
6881 };
6882 const undoReplaceScrollbarWithPadding = () => {
6883 if (previousBodyPadding !== null) {
6884 document.body.style.paddingRight = `${previousBodyPadding}px`;
6885 previousBodyPadding = null;
6886 }
6887 };
6888
6889 /**
6890 * @param {SweetAlert} instance
6891 * @param {HTMLElement} container
6892 * @param {boolean} returnFocus
6893 * @param {(() => void) | undefined} didClose
6894 */
6895 function removePopupAndResetState(instance, container, returnFocus, didClose) {
6896 if (isToast()) {
6897 triggerDidCloseAndDispose(instance, didClose);
6898 } else {
6899 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
6900 removeKeydownHandler(globalState);
6901 }
6902
6903 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
6904 // for some reason removing the container in Safari will scroll the document to bottom
6905 if (isSafariOrIOS) {
6906 container.setAttribute('style', 'display:none !important');
6907 container.removeAttribute('class');
6908 container.innerHTML = '';
6909 } else {
6910 container.remove();
6911 }
6912 if (isModal()) {
6913 undoReplaceScrollbarWithPadding();
6914 undoIOSfix();
6915 unsetAriaHidden();
6916 }
6917 removeBodyClasses();
6918 }
6919
6920 /**
6921 * Remove SweetAlert2 classes from body
6922 */
6923 function removeBodyClasses() {
6924 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
6925 }
6926
6927 /**
6928 * Instance method to close sweetAlert
6929 *
6930 * @param {SweetAlertResult | undefined} resolveValue
6931 * @this {SweetAlert}
6932 */
6933 function close(resolveValue) {
6934 resolveValue = prepareResolveValue(resolveValue);
6935 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
6936 const didClose = triggerClosePopup(this);
6937 if (this.isAwaitingPromise) {
6938 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
6939 if (!resolveValue.isDismissed) {
6940 handleAwaitingPromise(this);
6941 swalPromiseResolve(resolveValue);
6942 }
6943 } else if (didClose) {
6944 // Resolve Swal promise
6945 swalPromiseResolve(resolveValue);
6946 }
6947 }
6948
6949 /**
6950 * @param {SweetAlert} instance
6951 * @returns {boolean}
6952 */
6953 const triggerClosePopup = instance => {
6954 const popup = getPopup();
6955 if (!popup) {
6956 return false;
6957 }
6958 const innerParams = privateProps.innerParams.get(instance);
6959 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
6960 return false;
6961 }
6962 removeClass(popup, innerParams.showClass.popup);
6963 addClass(popup, innerParams.hideClass.popup);
6964 const backdrop = getContainer();
6965 removeClass(backdrop, innerParams.showClass.backdrop);
6966 addClass(backdrop, innerParams.hideClass.backdrop);
6967 handlePopupAnimation(instance, popup, innerParams);
6968 return true;
6969 };
6970
6971 /**
6972 * @param {Error | string} error
6973 * @this {SweetAlert}
6974 */
6975 function rejectPromise(error) {
6976 const rejectPromise = privateMethods.swalPromiseReject.get(this);
6977 handleAwaitingPromise(this);
6978 if (rejectPromise) {
6979 // Reject Swal promise
6980 rejectPromise(error);
6981 }
6982 }
6983
6984 /**
6985 * @param {SweetAlert} instance
6986 */
6987 const handleAwaitingPromise = instance => {
6988 if (instance.isAwaitingPromise) {
6989 // @ts-ignore
6990 delete instance.isAwaitingPromise;
6991 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
6992 if (!privateProps.innerParams.get(instance)) {
6993 instance._destroy();
6994 }
6995 }
6996 };
6997
6998 /**
6999 * @param {SweetAlertResult | undefined} resolveValue
7000 * @returns {SweetAlertResult}
7001 */
7002 const prepareResolveValue = resolveValue => {
7003 // When user calls Swal.close()
7004 if (typeof resolveValue === 'undefined') {
7005 return {
7006 isConfirmed: false,
7007 isDenied: false,
7008 isDismissed: true
7009 };
7010 }
7011 return Object.assign({
7012 isConfirmed: false,
7013 isDenied: false,
7014 isDismissed: false
7015 }, resolveValue);
7016 };
7017
7018 /**
7019 * @param {SweetAlert} instance
7020 * @param {HTMLElement} popup
7021 * @param {SweetAlertOptions} innerParams
7022 */
7023 const handlePopupAnimation = (instance, popup, innerParams) => {
7024 var _globalState$eventEmi;
7025 const container = getContainer();
7026 // If animation is supported, animate
7027 const animationIsSupported = hasCssAnimation(popup);
7028 if (typeof innerParams.willClose === 'function') {
7029 innerParams.willClose(popup);
7030 }
7031 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
7032 if (animationIsSupported && container) {
7033 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
7034 } else if (container) {
7035 // Otherwise, remove immediately
7036 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
7037 }
7038 };
7039
7040 /**
7041 * @param {SweetAlert} instance
7042 * @param {HTMLElement} popup
7043 * @param {HTMLElement} container
7044 * @param {boolean} returnFocus
7045 * @param {(() => void) | undefined} didClose
7046 */
7047 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
7048 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
7049 /**
7050 * @param {AnimationEvent | TransitionEvent} e
7051 */
7052 const swalCloseAnimationFinished = function (e) {
7053 if (e.target === popup) {
7054 var _globalState$swalClos;
7055 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
7056 delete globalState.swalCloseEventFinishedCallback;
7057 popup.removeEventListener('animationend', swalCloseAnimationFinished);
7058 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
7059 }
7060 };
7061 popup.addEventListener('animationend', swalCloseAnimationFinished);
7062 popup.addEventListener('transitionend', swalCloseAnimationFinished);
7063 };
7064
7065 /**
7066 * @param {SweetAlert} instance
7067 * @param {(() => void) | undefined} didClose
7068 */
7069 const triggerDidCloseAndDispose = (instance, didClose) => {
7070 setTimeout(() => {
7071 var _globalState$eventEmi2;
7072 if (typeof didClose === 'function') {
7073 didClose.bind(instance.params)();
7074 }
7075 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
7076 // instance might have been destroyed already
7077 if (instance._destroy) {
7078 instance._destroy();
7079 }
7080 });
7081 };
7082
7083 /**
7084 * Shows loader (spinner), this is useful with AJAX requests.
7085 * By default the loader be shown instead of the "Confirm" button.
7086 *
7087 * @param {HTMLButtonElement | null} [buttonToReplace]
7088 */
7089 const showLoading = buttonToReplace => {
7090 let popup = getPopup();
7091 if (!popup) {
7092 new Swal();
7093 }
7094 popup = getPopup();
7095 if (!popup) {
7096 return;
7097 }
7098 const loader = getLoader();
7099 if (isToast()) {
7100 hide(getIcon());
7101 } else {
7102 replaceButton(popup, buttonToReplace);
7103 }
7104 show(loader);
7105 popup.setAttribute('data-loading', 'true');
7106 popup.setAttribute('aria-busy', 'true');
7107 popup.focus();
7108 };
7109
7110 /**
7111 * @param {HTMLElement} popup
7112 * @param {HTMLButtonElement | null} [buttonToReplace]
7113 */
7114 const replaceButton = (popup, buttonToReplace) => {
7115 const actions = getActions();
7116 const loader = getLoader();
7117 if (!actions || !loader) {
7118 return;
7119 }
7120 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
7121 buttonToReplace = getConfirmButton();
7122 }
7123 show(actions);
7124 if (buttonToReplace) {
7125 hide(buttonToReplace);
7126 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
7127 actions.insertBefore(loader, buttonToReplace);
7128 }
7129 addClass([popup, actions], swalClasses.loading);
7130 };
7131
7132 /**
7133 * @param {SweetAlert} instance
7134 * @param {SweetAlertOptions} params
7135 */
7136 const handleInputOptionsAndValue = (instance, params) => {
7137 if (params.input === 'select' || params.input === 'radio') {
7138 handleInputOptions(instance, params);
7139 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
7140 showLoading(getConfirmButton());
7141 handleInputValue(instance, params);
7142 }
7143 };
7144
7145 /**
7146 * @param {SweetAlert} instance
7147 * @param {SweetAlertOptions} innerParams
7148 * @returns {SweetAlertInputValue}
7149 */
7150 const getInputValue = (instance, innerParams) => {
7151 const input = instance.getInput();
7152 if (!input) {
7153 return null;
7154 }
7155 switch (innerParams.input) {
7156 case 'checkbox':
7157 return getCheckboxValue(input);
7158 case 'radio':
7159 return getRadioValue(input);
7160 case 'file':
7161 return getFileValue(input);
7162 default:
7163 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
7164 }
7165 };
7166
7167 /**
7168 * @param {HTMLInputElement} input
7169 * @returns {number}
7170 */
7171 const getCheckboxValue = input => input.checked ? 1 : 0;
7172
7173 /**
7174 * @param {HTMLInputElement} input
7175 * @returns {string | null}
7176 */
7177 const getRadioValue = input => input.checked ? input.value : null;
7178
7179 /**
7180 * @param {HTMLInputElement} input
7181 * @returns {FileList | File | null}
7182 */
7183 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
7184
7185 /**
7186 * @param {SweetAlert} instance
7187 * @param {SweetAlertOptions} params
7188 */
7189 const handleInputOptions = (instance, params) => {
7190 const popup = getPopup();
7191 if (!popup) {
7192 return;
7193 }
7194 /**
7195 * @param {*} inputOptions
7196 */
7197 const processInputOptions = inputOptions => {
7198 if (params.input === 'select') {
7199 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
7200 } else if (params.input === 'radio') {
7201 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
7202 }
7203 };
7204 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
7205 showLoading(getConfirmButton());
7206 asPromise(params.inputOptions).then(inputOptions => {
7207 instance.hideLoading();
7208 processInputOptions(inputOptions);
7209 });
7210 } else if (typeof params.inputOptions === 'object') {
7211 processInputOptions(params.inputOptions);
7212 } else {
7213 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
7214 }
7215 };
7216
7217 /**
7218 * @param {SweetAlert} instance
7219 * @param {SweetAlertOptions} params
7220 */
7221 const handleInputValue = (instance, params) => {
7222 const input = instance.getInput();
7223 if (!input) {
7224 return;
7225 }
7226 hide(input);
7227 asPromise(params.inputValue).then(inputValue => {
7228 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
7229 show(input);
7230 input.focus();
7231 instance.hideLoading();
7232 }).catch(err => {
7233 error(`Error in inputValue promise: ${err}`);
7234 input.value = '';
7235 show(input);
7236 input.focus();
7237 instance.hideLoading();
7238 });
7239 };
7240
7241 /**
7242 * @param {HTMLElement} popup
7243 * @param {InputOptionFlattened[]} inputOptions
7244 * @param {SweetAlertOptions} params
7245 */
7246 function populateSelectOptions(popup, inputOptions, params) {
7247 const select = getDirectChildByClass(popup, swalClasses.select);
7248 if (!select) {
7249 return;
7250 }
7251 /**
7252 * @param {HTMLElement} parent
7253 * @param {string} optionLabel
7254 * @param {string} optionValue
7255 */
7256 const renderOption = (parent, optionLabel, optionValue) => {
7257 const option = document.createElement('option');
7258 option.value = optionValue;
7259 setInnerHtml(option, optionLabel);
7260 option.selected = isSelected(optionValue, params.inputValue);
7261 parent.appendChild(option);
7262 };
7263 inputOptions.forEach(inputOption => {
7264 const optionValue = inputOption[0];
7265 const optionLabel = inputOption[1];
7266 // <optgroup> spec:
7267 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
7268 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
7269 // check whether this is a <optgroup>
7270 if (Array.isArray(optionLabel)) {
7271 // if it is an array, then it is an <optgroup>
7272 const optgroup = document.createElement('optgroup');
7273 optgroup.label = optionValue;
7274 optgroup.disabled = false; // not configurable for now
7275 select.appendChild(optgroup);
7276 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
7277 } else {
7278 // case of <option>
7279 renderOption(select, optionLabel, optionValue);
7280 }
7281 });
7282 select.focus();
7283 }
7284
7285 /**
7286 * @param {HTMLElement} popup
7287 * @param {InputOptionFlattened[]} inputOptions
7288 * @param {SweetAlertOptions} params
7289 */
7290 function populateRadioOptions(popup, inputOptions, params) {
7291 const radio = getDirectChildByClass(popup, swalClasses.radio);
7292 if (!radio) {
7293 return;
7294 }
7295 inputOptions.forEach(inputOption => {
7296 const radioValue = inputOption[0];
7297 const radioLabel = inputOption[1];
7298 const radioInput = document.createElement('input');
7299 const radioLabelElement = document.createElement('label');
7300 radioInput.type = 'radio';
7301 radioInput.name = swalClasses.radio;
7302 radioInput.value = radioValue;
7303 if (isSelected(radioValue, params.inputValue)) {
7304 radioInput.checked = true;
7305 }
7306 const label = document.createElement('span');
7307 setInnerHtml(label, radioLabel);
7308 label.className = swalClasses.label;
7309 radioLabelElement.appendChild(radioInput);
7310 radioLabelElement.appendChild(label);
7311 radio.appendChild(radioLabelElement);
7312 });
7313 const radios = radio.querySelectorAll('input');
7314 if (radios.length) {
7315 radios[0].focus();
7316 }
7317 }
7318
7319 /**
7320 * Converts `inputOptions` into an array of `[value, label]`s
7321 *
7322 * @param {*} inputOptions
7323 * @typedef {string[]} InputOptionFlattened
7324 * @returns {InputOptionFlattened[]}
7325 */
7326 const formatInputOptions = inputOptions => {
7327 const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
7328 return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
7329 };
7330
7331 /**
7332 * @param {string} optionValue
7333 * @param {SweetAlertInputValue} inputValue
7334 * @returns {boolean}
7335 */
7336 const isSelected = (optionValue, inputValue) => Boolean(inputValue) && inputValue != null && inputValue.toString() === optionValue.toString();
7337
7338 /**
7339 * @param {SweetAlert} instance
7340 */
7341 const handleConfirmButtonClick = instance => {
7342 const innerParams = privateProps.innerParams.get(instance);
7343 instance.disableButtons();
7344 if (innerParams.input) {
7345 handleConfirmOrDenyWithInput(instance, 'confirm');
7346 } else {
7347 confirm(instance, true);
7348 }
7349 };
7350
7351 /**
7352 * @param {SweetAlert} instance
7353 */
7354 const handleDenyButtonClick = instance => {
7355 const innerParams = privateProps.innerParams.get(instance);
7356 instance.disableButtons();
7357 if (innerParams.returnInputValueOnDeny) {
7358 handleConfirmOrDenyWithInput(instance, 'deny');
7359 } else {
7360 deny(instance, false);
7361 }
7362 };
7363
7364 /**
7365 * @param {SweetAlert} instance
7366 * @param {(dismiss: DismissReason) => void} dismissWith
7367 */
7368 const handleCancelButtonClick = (instance, dismissWith) => {
7369 instance.disableButtons();
7370 dismissWith(DismissReason.cancel);
7371 };
7372
7373 /**
7374 * @param {SweetAlert} instance
7375 * @param {'confirm' | 'deny'} type
7376 */
7377 const handleConfirmOrDenyWithInput = (instance, type) => {
7378 const innerParams = privateProps.innerParams.get(instance);
7379 if (!innerParams.input) {
7380 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
7381 return;
7382 }
7383 const input = instance.getInput();
7384 const inputValue = getInputValue(instance, innerParams);
7385 if (innerParams.inputValidator) {
7386 handleInputValidator(instance, inputValue, type);
7387 } else if (input && !input.checkValidity()) {
7388 instance.enableButtons();
7389 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
7390 } else if (type === 'deny') {
7391 deny(instance, inputValue);
7392 } else {
7393 confirm(instance, inputValue);
7394 }
7395 };
7396
7397 /**
7398 * @param {SweetAlert} instance
7399 * @param {SweetAlertInputValue} inputValue
7400 * @param {'confirm' | 'deny'} type
7401 */
7402 const handleInputValidator = (instance, inputValue, type) => {
7403 const innerParams = privateProps.innerParams.get(instance);
7404 instance.disableInput();
7405 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
7406 validationPromise.then(validationMessage => {
7407 instance.enableButtons();
7408 instance.enableInput();
7409 if (validationMessage) {
7410 instance.showValidationMessage(validationMessage);
7411 } else if (type === 'deny') {
7412 deny(instance, inputValue);
7413 } else {
7414 confirm(instance, inputValue);
7415 }
7416 });
7417 };
7418
7419 /**
7420 * @param {SweetAlert} instance
7421 * @param {*} value
7422 */
7423 const deny = (instance, value) => {
7424 const innerParams = privateProps.innerParams.get(instance);
7425 if (innerParams.showLoaderOnDeny) {
7426 showLoading(getDenyButton());
7427 }
7428 if (innerParams.preDeny) {
7429 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
7430 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
7431 preDenyPromise.then(preDenyValue => {
7432 if (preDenyValue === false) {
7433 instance.hideLoading();
7434 handleAwaitingPromise(instance);
7435 } else {
7436 instance.close(/** @type SweetAlertResult */{
7437 isDenied: true,
7438 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
7439 });
7440 }
7441 }).catch(error => rejectWith(instance, error));
7442 } else {
7443 instance.close(/** @type SweetAlertResult */{
7444 isDenied: true,
7445 value
7446 });
7447 }
7448 };
7449
7450 /**
7451 * @param {SweetAlert} instance
7452 * @param {*} value
7453 */
7454 const succeedWith = (instance, value) => {
7455 instance.close(/** @type SweetAlertResult */{
7456 isConfirmed: true,
7457 value
7458 });
7459 };
7460
7461 /**
7462 *
7463 * @param {SweetAlert} instance
7464 * @param {string} error
7465 */
7466 const rejectWith = (instance, error) => {
7467 instance.rejectPromise(error);
7468 };
7469
7470 /**
7471 *
7472 * @param {SweetAlert} instance
7473 * @param {*} value
7474 */
7475 const confirm = (instance, value) => {
7476 const innerParams = privateProps.innerParams.get(instance);
7477 if (innerParams.showLoaderOnConfirm) {
7478 showLoading();
7479 }
7480 if (innerParams.preConfirm) {
7481 instance.resetValidationMessage();
7482 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
7483 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
7484 preConfirmPromise.then(preConfirmValue => {
7485 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
7486 instance.hideLoading();
7487 handleAwaitingPromise(instance);
7488 } else {
7489 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
7490 }
7491 }).catch(error => rejectWith(instance, error));
7492 } else {
7493 succeedWith(instance, value);
7494 }
7495 };
7496
7497 /**
7498 * Hides loader and shows back the button which was hidden by .showLoading()
7499 * @this {SweetAlert}
7500 */
7501 function hideLoading() {
7502 // do nothing if popup is closed
7503 const innerParams = privateProps.innerParams.get(this);
7504 if (!innerParams) {
7505 return;
7506 }
7507 const domCache = privateProps.domCache.get(this);
7508 hide(domCache.loader);
7509 if (isToast()) {
7510 if (innerParams.icon) {
7511 show(getIcon());
7512 }
7513 } else {
7514 showRelatedButton(domCache);
7515 }
7516 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
7517 domCache.popup.removeAttribute('aria-busy');
7518 domCache.popup.removeAttribute('data-loading');
7519 this.enableButtons();
7520 }
7521
7522 /**
7523 * @param {DomCache} domCache
7524 */
7525 const showRelatedButton = domCache => {
7526 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
7527 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
7528 if (buttonToReplace.length) {
7529 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
7530 } else if (allButtonsAreHidden()) {
7531 hide(domCache.actions);
7532 }
7533 };
7534
7535 /**
7536 * Gets the input DOM node, this method works with input parameter.
7537 *
7538 * @returns {HTMLInputElement | null}
7539 * @this {SweetAlert}
7540 */
7541 function getInput() {
7542 const innerParams = privateProps.innerParams.get(this);
7543 const domCache = privateProps.domCache.get(this);
7544 if (!domCache) {
7545 return null;
7546 }
7547 return getInput$1(domCache.popup, innerParams.input);
7548 }
7549
7550 /**
7551 * @param {SweetAlert} instance
7552 * @param {string[]} buttons
7553 * @param {boolean} disabled
7554 */
7555 function setButtonsDisabled(instance, buttons, disabled) {
7556 const domCache = privateProps.domCache.get(instance);
7557 buttons.forEach(button => {
7558 domCache[button].disabled = disabled;
7559 });
7560 }
7561
7562 /**
7563 * @param {HTMLInputElement | null} input
7564 * @param {boolean} disabled
7565 */
7566 function setInputDisabled(input, disabled) {
7567 const popup = getPopup();
7568 if (!popup || !input) {
7569 return;
7570 }
7571 if (input.type === 'radio') {
7572 /** @type {NodeListOf<HTMLInputElement>} */
7573 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
7574 radios.forEach(radio => {
7575 radio.disabled = disabled;
7576 });
7577 } else {
7578 input.disabled = disabled;
7579 }
7580 }
7581
7582 /**
7583 * Enable all the buttons
7584 * @this {SweetAlert}
7585 */
7586 function enableButtons() {
7587 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
7588 const focusedElement = privateProps.focusedElement.get(this);
7589 if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
7590 focusedElement.focus();
7591 }
7592 privateProps.focusedElement.delete(this);
7593 }
7594
7595 /**
7596 * Disable all the buttons
7597 * @this {SweetAlert}
7598 */
7599 function disableButtons() {
7600 privateProps.focusedElement.set(this, document.activeElement);
7601 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
7602 }
7603
7604 /**
7605 * Enable the input field
7606 * @this {SweetAlert}
7607 */
7608 function enableInput() {
7609 setInputDisabled(this.getInput(), false);
7610 }
7611
7612 /**
7613 * Disable the input field
7614 * @this {SweetAlert}
7615 */
7616 function disableInput() {
7617 setInputDisabled(this.getInput(), true);
7618 }
7619
7620 /**
7621 * Show block with validation message
7622 *
7623 * @param {string} error
7624 * @this {SweetAlert}
7625 */
7626 function showValidationMessage(error) {
7627 const domCache = privateProps.domCache.get(this);
7628 const params = privateProps.innerParams.get(this);
7629 setInnerHtml(domCache.validationMessage, error);
7630 domCache.validationMessage.className = swalClasses['validation-message'];
7631 if (params.customClass && params.customClass.validationMessage) {
7632 addClass(domCache.validationMessage, params.customClass.validationMessage);
7633 }
7634 show(domCache.validationMessage);
7635 const input = this.getInput();
7636 if (input) {
7637 input.setAttribute('aria-invalid', 'true');
7638 input.setAttribute('aria-describedby', swalClasses['validation-message']);
7639 focusInput(input);
7640 addClass(input, swalClasses.inputerror);
7641 }
7642 }
7643
7644 /**
7645 * Hide block with validation message
7646 *
7647 * @this {SweetAlert}
7648 */
7649 function resetValidationMessage() {
7650 const domCache = privateProps.domCache.get(this);
7651 if (domCache.validationMessage) {
7652 hide(domCache.validationMessage);
7653 }
7654 const input = this.getInput();
7655 if (input) {
7656 input.removeAttribute('aria-invalid');
7657 input.removeAttribute('aria-describedby');
7658 removeClass(input, swalClasses.inputerror);
7659 }
7660 }
7661
7662 const defaultParams = {
7663 title: '',
7664 titleText: '',
7665 text: '',
7666 html: '',
7667 footer: '',
7668 icon: undefined,
7669 iconColor: undefined,
7670 iconHtml: undefined,
7671 template: undefined,
7672 toast: false,
7673 draggable: false,
7674 animation: true,
7675 theme: 'light',
7676 showClass: {
7677 popup: 'swal2-show',
7678 backdrop: 'swal2-backdrop-show',
7679 icon: 'swal2-icon-show'
7680 },
7681 hideClass: {
7682 popup: 'swal2-hide',
7683 backdrop: 'swal2-backdrop-hide',
7684 icon: 'swal2-icon-hide'
7685 },
7686 customClass: {},
7687 target: 'body',
7688 color: undefined,
7689 backdrop: true,
7690 heightAuto: true,
7691 allowOutsideClick: true,
7692 allowEscapeKey: true,
7693 allowEnterKey: true,
7694 stopKeydownPropagation: true,
7695 keydownListenerCapture: false,
7696 showConfirmButton: true,
7697 showDenyButton: false,
7698 showCancelButton: false,
7699 preConfirm: undefined,
7700 preDeny: undefined,
7701 confirmButtonText: 'OK',
7702 confirmButtonAriaLabel: '',
7703 confirmButtonColor: undefined,
7704 denyButtonText: 'No',
7705 denyButtonAriaLabel: '',
7706 denyButtonColor: undefined,
7707 cancelButtonText: 'Cancel',
7708 cancelButtonAriaLabel: '',
7709 cancelButtonColor: undefined,
7710 buttonsStyling: true,
7711 reverseButtons: false,
7712 focusConfirm: true,
7713 focusDeny: false,
7714 focusCancel: false,
7715 returnFocus: true,
7716 showCloseButton: false,
7717 closeButtonHtml: '&times;',
7718 closeButtonAriaLabel: 'Close this dialog',
7719 loaderHtml: '',
7720 showLoaderOnConfirm: false,
7721 showLoaderOnDeny: false,
7722 imageUrl: undefined,
7723 imageWidth: undefined,
7724 imageHeight: undefined,
7725 imageAlt: '',
7726 timer: undefined,
7727 timerProgressBar: false,
7728 width: undefined,
7729 padding: undefined,
7730 background: undefined,
7731 input: undefined,
7732 inputPlaceholder: '',
7733 inputLabel: '',
7734 inputValue: '',
7735 inputOptions: {},
7736 inputAutoFocus: true,
7737 inputAutoTrim: true,
7738 inputAttributes: {},
7739 inputValidator: undefined,
7740 returnInputValueOnDeny: false,
7741 validationMessage: undefined,
7742 grow: false,
7743 position: 'center',
7744 progressSteps: [],
7745 currentProgressStep: undefined,
7746 progressStepsDistance: undefined,
7747 willOpen: undefined,
7748 didOpen: undefined,
7749 didRender: undefined,
7750 willClose: undefined,
7751 didClose: undefined,
7752 didDestroy: undefined,
7753 scrollbarPadding: true,
7754 topLayer: false
7755 };
7756 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'];
7757
7758 /** @type {Record<string, string | undefined>} */
7759 const deprecatedParams = {
7760 allowEnterKey: undefined
7761 };
7762 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
7763
7764 /**
7765 * Is valid parameter
7766 *
7767 * @param {string} paramName
7768 * @returns {boolean}
7769 */
7770 const isValidParameter = paramName => {
7771 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
7772 };
7773
7774 /**
7775 * Is valid parameter for Swal.update() method
7776 *
7777 * @param {string} paramName
7778 * @returns {boolean}
7779 */
7780 const isUpdatableParameter = paramName => {
7781 return updatableParams.indexOf(paramName) !== -1;
7782 };
7783
7784 /**
7785 * Is deprecated parameter
7786 *
7787 * @param {string} paramName
7788 * @returns {string | undefined}
7789 */
7790 const isDeprecatedParameter = paramName => {
7791 return deprecatedParams[paramName];
7792 };
7793
7794 /**
7795 * @param {string} param
7796 */
7797 const checkIfParamIsValid = param => {
7798 if (!isValidParameter(param)) {
7799 warn(`Unknown parameter "${param}"`);
7800 }
7801 };
7802
7803 /**
7804 * @param {string} param
7805 */
7806 const checkIfToastParamIsValid = param => {
7807 if (toastIncompatibleParams.includes(param)) {
7808 warn(`The parameter "${param}" is incompatible with toasts`);
7809 }
7810 };
7811
7812 /**
7813 * @param {string} param
7814 */
7815 const checkIfParamIsDeprecated = param => {
7816 const isDeprecated = isDeprecatedParameter(param);
7817 if (isDeprecated) {
7818 warnAboutDeprecation(param, isDeprecated);
7819 }
7820 };
7821
7822 /**
7823 * Show relevant warnings for given params
7824 *
7825 * @param {SweetAlertOptions} params
7826 */
7827 const showWarningsForParams = params => {
7828 if (params.backdrop === false && params.allowOutsideClick) {
7829 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
7830 }
7831 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)) {
7832 warn(`Invalid theme "${params.theme}"`);
7833 }
7834 for (const param in params) {
7835 checkIfParamIsValid(param);
7836 if (params.toast) {
7837 checkIfToastParamIsValid(param);
7838 }
7839 checkIfParamIsDeprecated(param);
7840 }
7841 };
7842
7843 /**
7844 * Updates popup parameters.
7845 *
7846 * @this {any}
7847 * @param {SweetAlertOptions} params
7848 */
7849 function update(params) {
7850 const container = getContainer();
7851 const popup = getPopup();
7852 const innerParams = privateProps.innerParams.get(this);
7853 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
7854 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.`);
7855 return;
7856 }
7857 const validUpdatableParams = filterValidParams(params);
7858 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
7859 showWarningsForParams(updatedParams);
7860 if (container) {
7861 container.dataset['swal2Theme'] = updatedParams.theme;
7862 }
7863 render(this, updatedParams);
7864 privateProps.innerParams.set(this, updatedParams);
7865 Object.defineProperties(this, {
7866 params: {
7867 value: Object.assign({}, this.params, params),
7868 writable: false,
7869 enumerable: true
7870 }
7871 });
7872 }
7873
7874 /**
7875 * @param {SweetAlertOptions} params
7876 * @returns {SweetAlertOptions}
7877 */
7878 const filterValidParams = params => {
7879 /** @type {Record<string, any>} */
7880 const validUpdatableParams = {};
7881 Object.keys(params).forEach(param => {
7882 if (isUpdatableParameter(param)) {
7883 const typedParams = /** @type {Record<string, any>} */params;
7884 validUpdatableParams[param] = typedParams[param];
7885 } else {
7886 warn(`Invalid parameter to update: ${param}`);
7887 }
7888 });
7889 return validUpdatableParams;
7890 };
7891
7892 /**
7893 * Dispose the current SweetAlert2 instance
7894 * @this {SweetAlert}
7895 */
7896 function _destroy() {
7897 var _globalState$eventEmi;
7898 const domCache = privateProps.domCache.get(this);
7899 const innerParams = privateProps.innerParams.get(this);
7900 if (!innerParams) {
7901 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
7902 return; // This instance has already been destroyed
7903 }
7904
7905 // Check if there is another Swal closing
7906 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
7907 globalState.swalCloseEventFinishedCallback();
7908 delete globalState.swalCloseEventFinishedCallback;
7909 }
7910 if (typeof innerParams.didDestroy === 'function') {
7911 innerParams.didDestroy();
7912 }
7913 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
7914 disposeSwal(this);
7915 }
7916
7917 /**
7918 * @param {SweetAlert} instance
7919 */
7920 const disposeSwal = instance => {
7921 disposeWeakMaps(instance);
7922 // Unset this.params so GC will dispose it (#1569)
7923 // @ts-ignore
7924 delete instance.params;
7925 // Unset globalState props so GC will dispose globalState (#1569)
7926 delete globalState.keydownHandler;
7927 delete globalState.keydownTarget;
7928 // Unset currentInstance
7929 delete globalState.currentInstance;
7930 };
7931
7932 /**
7933 * @param {SweetAlert} instance
7934 */
7935 const disposeWeakMaps = instance => {
7936 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
7937 if (instance.isAwaitingPromise) {
7938 unsetWeakMaps(privateProps, instance);
7939 instance.isAwaitingPromise = true;
7940 } else {
7941 unsetWeakMaps(privateMethods, instance);
7942 unsetWeakMaps(privateProps, instance);
7943
7944 // @ts-ignore
7945 delete instance.isAwaitingPromise;
7946 // Unset instance methods
7947 // @ts-ignore
7948 delete instance.disableButtons;
7949 // @ts-ignore
7950 delete instance.enableButtons;
7951 // @ts-ignore
7952 delete instance.getInput;
7953 // @ts-ignore
7954 delete instance.disableInput;
7955 // @ts-ignore
7956 delete instance.enableInput;
7957 // @ts-ignore
7958 delete instance.hideLoading;
7959 // @ts-ignore
7960 delete instance.disableLoading;
7961 // @ts-ignore
7962 delete instance.showValidationMessage;
7963 // @ts-ignore
7964 delete instance.resetValidationMessage;
7965 // @ts-ignore
7966 delete instance.close;
7967 // @ts-ignore
7968 delete instance.closePopup;
7969 // @ts-ignore
7970 delete instance.closeModal;
7971 // @ts-ignore
7972 delete instance.closeToast;
7973 // @ts-ignore
7974 delete instance.rejectPromise;
7975 // @ts-ignore
7976 delete instance.update;
7977 // @ts-ignore
7978 delete instance._destroy;
7979 }
7980 };
7981
7982 /**
7983 * @param {Record<string, WeakMap<any, any>>} obj
7984 * @param {SweetAlert} instance
7985 */
7986 const unsetWeakMaps = (obj, instance) => {
7987 for (const i in obj) {
7988 obj[i].delete(instance);
7989 }
7990 };
7991
7992 var instanceMethods = /*#__PURE__*/Object.freeze({
7993 __proto__: null,
7994 _destroy: _destroy,
7995 close: close,
7996 closeModal: close,
7997 closePopup: close,
7998 closeToast: close,
7999 disableButtons: disableButtons,
8000 disableInput: disableInput,
8001 disableLoading: hideLoading,
8002 enableButtons: enableButtons,
8003 enableInput: enableInput,
8004 getInput: getInput,
8005 handleAwaitingPromise: handleAwaitingPromise,
8006 hideLoading: hideLoading,
8007 rejectPromise: rejectPromise,
8008 resetValidationMessage: resetValidationMessage,
8009 showValidationMessage: showValidationMessage,
8010 update: update
8011 });
8012
8013 /**
8014 * @param {SweetAlertOptions} innerParams
8015 * @param {DomCache} domCache
8016 * @param {(dismiss: DismissReason) => void} dismissWith
8017 */
8018 const handlePopupClick = (innerParams, domCache, dismissWith) => {
8019 if (innerParams.toast) {
8020 handleToastClick(innerParams, domCache, dismissWith);
8021 } else {
8022 // Ignore click events that had mousedown on the popup but mouseup on the container
8023 // This can happen when the user drags a slider
8024 handleModalMousedown(domCache);
8025
8026 // Ignore click events that had mousedown on the container but mouseup on the popup
8027 handleContainerMousedown(domCache);
8028 handleModalClick(innerParams, domCache, dismissWith);
8029 }
8030 };
8031
8032 /**
8033 * @param {SweetAlertOptions} innerParams
8034 * @param {DomCache} domCache
8035 * @param {(dismiss: DismissReason) => void} dismissWith
8036 */
8037 const handleToastClick = (innerParams, domCache, dismissWith) => {
8038 // Closing toast by internal click
8039 domCache.popup.onclick = () => {
8040 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
8041 return;
8042 }
8043 dismissWith(DismissReason.close);
8044 };
8045 };
8046
8047 /**
8048 * @param {SweetAlertOptions} innerParams
8049 * @returns {boolean}
8050 */
8051 const isAnyButtonShown = innerParams => {
8052 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
8053 };
8054 let ignoreOutsideClick = false;
8055
8056 /**
8057 * @param {DomCache} domCache
8058 */
8059 const handleModalMousedown = domCache => {
8060 domCache.popup.onmousedown = () => {
8061 domCache.container.onmouseup = function (e) {
8062 domCache.container.onmouseup = () => {};
8063 // We only check if the mouseup target is the container because usually it doesn't
8064 // have any other direct children aside of the popup
8065 if (e.target === domCache.container) {
8066 ignoreOutsideClick = true;
8067 }
8068 };
8069 };
8070 };
8071
8072 /**
8073 * @param {DomCache} domCache
8074 */
8075 const handleContainerMousedown = domCache => {
8076 domCache.container.onmousedown = e => {
8077 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
8078 if (e.target === domCache.container) {
8079 e.preventDefault();
8080 }
8081 domCache.popup.onmouseup = function (e) {
8082 domCache.popup.onmouseup = () => {};
8083 // We also need to check if the mouseup target is a child of the popup
8084 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
8085 ignoreOutsideClick = true;
8086 }
8087 };
8088 };
8089 };
8090
8091 /**
8092 * @param {SweetAlertOptions} innerParams
8093 * @param {DomCache} domCache
8094 * @param {(dismiss: DismissReason) => void} dismissWith
8095 */
8096 const handleModalClick = (innerParams, domCache, dismissWith) => {
8097 domCache.container.onclick = e => {
8098 if (ignoreOutsideClick) {
8099 ignoreOutsideClick = false;
8100 return;
8101 }
8102 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
8103 dismissWith(DismissReason.backdrop);
8104 }
8105 };
8106 };
8107
8108 /**
8109 * @param {unknown} elem
8110 * @returns {boolean}
8111 */
8112 const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
8113
8114 /**
8115 * @param {unknown} elem
8116 * @returns {boolean}
8117 */
8118 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
8119
8120 /**
8121 * @param {ReadonlyArray<unknown>} args
8122 * @returns {SweetAlertOptions}
8123 */
8124 const argsToParams = args => {
8125 /** @type {Record<string, unknown>} */
8126 const params = {};
8127 if (typeof args[0] === 'object' && !isElement(args[0])) {
8128 Object.assign(params, args[0]);
8129 } else {
8130 ['title', 'html', 'icon'].forEach((name, index) => {
8131 const arg = args[index];
8132 if (typeof arg === 'string' || isElement(arg)) {
8133 params[name] = arg;
8134 } else if (arg !== undefined) {
8135 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
8136 }
8137 });
8138 }
8139 return /** @type {SweetAlertOptions} */params;
8140 };
8141
8142 /**
8143 * Main method to create a new SweetAlert2 popup
8144 *
8145 * @this {new (...args: any[]) => any}
8146 * @param {...SweetAlertOptions} args
8147 * @returns {Promise<SweetAlertResult>}
8148 */
8149 function fire(...args) {
8150 return new this(...args);
8151 }
8152
8153 /**
8154 * Returns an extended version of `Swal` containing `params` as defaults.
8155 * Useful for reusing Swal configuration.
8156 *
8157 * For example:
8158 *
8159 * Before:
8160 * const textPromptOptions = { input: 'text', showCancelButton: true }
8161 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
8162 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
8163 *
8164 * After:
8165 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
8166 * const {value: firstName} = await TextPrompt('What is your first name?')
8167 * const {value: lastName} = await TextPrompt('What is your last name?')
8168 *
8169 * @param {SweetAlertOptions} mixinParams
8170 * @returns {SweetAlert}
8171 * @this {typeof import('../SweetAlert.js').SweetAlert}
8172 */
8173 function mixin(mixinParams) {
8174 // @ts-ignore: 'this' refers to the SweetAlert constructor
8175 class MixinSwal extends this {
8176 /**
8177 * @param {any} params
8178 * @param {any} priorityMixinParams
8179 */
8180 _main(params, priorityMixinParams) {
8181 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
8182 }
8183 }
8184 // @ts-ignore
8185 return MixinSwal;
8186 }
8187
8188 /**
8189 * If `timer` parameter is set, returns number of milliseconds of timer remained.
8190 * Otherwise, returns undefined.
8191 *
8192 * @returns {number | undefined}
8193 */
8194 const getTimerLeft = () => {
8195 return globalState.timeout && globalState.timeout.getTimerLeft();
8196 };
8197
8198 /**
8199 * Stop timer. Returns number of milliseconds of timer remained.
8200 * If `timer` parameter isn't set, returns undefined.
8201 *
8202 * @returns {number | undefined}
8203 */
8204 const stopTimer = () => {
8205 if (globalState.timeout) {
8206 stopTimerProgressBar();
8207 return globalState.timeout.stop();
8208 }
8209 };
8210
8211 /**
8212 * Resume timer. Returns number of milliseconds of timer remained.
8213 * If `timer` parameter isn't set, returns undefined.
8214 *
8215 * @returns {number | undefined}
8216 */
8217 const resumeTimer = () => {
8218 if (globalState.timeout) {
8219 const remaining = globalState.timeout.start();
8220 animateTimerProgressBar(remaining);
8221 return remaining;
8222 }
8223 };
8224
8225 /**
8226 * Resume timer. Returns number of milliseconds of timer remained.
8227 * If `timer` parameter isn't set, returns undefined.
8228 *
8229 * @returns {number | undefined}
8230 */
8231 const toggleTimer = () => {
8232 const timer = globalState.timeout;
8233 return timer && (timer.running ? stopTimer() : resumeTimer());
8234 };
8235
8236 /**
8237 * Increase timer. Returns number of milliseconds of an updated timer.
8238 * If `timer` parameter isn't set, returns undefined.
8239 *
8240 * @param {number} ms
8241 * @returns {number | undefined}
8242 */
8243 const increaseTimer = ms => {
8244 if (globalState.timeout) {
8245 const remaining = globalState.timeout.increase(ms);
8246 animateTimerProgressBar(remaining, true);
8247 return remaining;
8248 }
8249 };
8250
8251 /**
8252 * Check if timer is running. Returns true if timer is running
8253 * or false if timer is paused or stopped.
8254 * If `timer` parameter isn't set, returns undefined
8255 *
8256 * @returns {boolean}
8257 */
8258 const isTimerRunning = () => {
8259 return Boolean(globalState.timeout && globalState.timeout.isRunning());
8260 };
8261
8262 let bodyClickListenerAdded = false;
8263 /** @type {Record<string, any>} */
8264 const clickHandlers = {};
8265
8266 /**
8267 * @this {any}
8268 * @param {string} attr
8269 */
8270 function bindClickHandler(attr = 'data-swal-template') {
8271 clickHandlers[attr] = this;
8272 if (!bodyClickListenerAdded) {
8273 document.body.addEventListener('click', bodyClickListener);
8274 bodyClickListenerAdded = true;
8275 }
8276 }
8277
8278 /**
8279 * @param {MouseEvent} event
8280 */
8281 const bodyClickListener = event => {
8282 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
8283 for (const attr in clickHandlers) {
8284 const template = el.getAttribute && el.getAttribute(attr);
8285 if (template) {
8286 clickHandlers[attr].fire({
8287 template
8288 });
8289 return;
8290 }
8291 }
8292 }
8293 };
8294
8295 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
8296
8297 class EventEmitter {
8298 constructor() {
8299 /** @type {Events} */
8300 this.events = {};
8301 }
8302
8303 /**
8304 * @param {string} eventName
8305 * @returns {EventHandlers}
8306 */
8307 _getHandlersByEventName(eventName) {
8308 if (typeof this.events[eventName] === 'undefined') {
8309 // not Set because we need to keep the FIFO order
8310 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
8311 this.events[eventName] = [];
8312 }
8313 return this.events[eventName];
8314 }
8315
8316 /**
8317 * @param {string} eventName
8318 * @param {EventHandler} eventHandler
8319 */
8320 on(eventName, eventHandler) {
8321 const currentHandlers = this._getHandlersByEventName(eventName);
8322 if (!currentHandlers.includes(eventHandler)) {
8323 currentHandlers.push(eventHandler);
8324 }
8325 }
8326
8327 /**
8328 * @param {string} eventName
8329 * @param {EventHandler} eventHandler
8330 */
8331 once(eventName, eventHandler) {
8332 /**
8333 * @param {...any} args
8334 */
8335 const onceFn = (...args) => {
8336 this.removeListener(eventName, onceFn);
8337 // @ts-ignore
8338 eventHandler.apply(this, args);
8339 };
8340 this.on(eventName, onceFn);
8341 }
8342
8343 /**
8344 * @param {string} eventName
8345 * @param {...any} args
8346 */
8347 emit(eventName, ...args) {
8348 this._getHandlersByEventName(eventName).forEach(
8349 /**
8350 * @param {EventHandler} eventHandler
8351 */
8352 eventHandler => {
8353 try {
8354 // @ts-ignore
8355 eventHandler.apply(this, args);
8356 } catch (error) {
8357 console.error(error);
8358 }
8359 });
8360 }
8361
8362 /**
8363 * @param {string} eventName
8364 * @param {EventHandler} eventHandler
8365 */
8366 removeListener(eventName, eventHandler) {
8367 const currentHandlers = this._getHandlersByEventName(eventName);
8368 const index = currentHandlers.indexOf(eventHandler);
8369 if (index > -1) {
8370 currentHandlers.splice(index, 1);
8371 }
8372 }
8373
8374 /**
8375 * @param {string} eventName
8376 */
8377 removeAllListeners(eventName) {
8378 if (this.events[eventName] !== undefined) {
8379 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
8380 this.events[eventName].length = 0;
8381 }
8382 }
8383 reset() {
8384 this.events = {};
8385 }
8386 }
8387
8388 globalState.eventEmitter = new EventEmitter();
8389
8390 /**
8391 * @param {string} eventName
8392 * @param {EventHandler} eventHandler
8393 */
8394 const on = (eventName, eventHandler) => {
8395 if (globalState.eventEmitter) {
8396 globalState.eventEmitter.on(eventName, eventHandler);
8397 }
8398 };
8399
8400 /**
8401 * @param {string} eventName
8402 * @param {EventHandler} eventHandler
8403 */
8404 const once = (eventName, eventHandler) => {
8405 if (globalState.eventEmitter) {
8406 globalState.eventEmitter.once(eventName, eventHandler);
8407 }
8408 };
8409
8410 /**
8411 * @param {string} [eventName]
8412 * @param {EventHandler} [eventHandler]
8413 */
8414 const off = (eventName, eventHandler) => {
8415 if (!globalState.eventEmitter) {
8416 return;
8417 }
8418
8419 // Remove all handlers for all events
8420 if (!eventName) {
8421 globalState.eventEmitter.reset();
8422 return;
8423 }
8424 if (eventHandler) {
8425 // Remove a specific handler
8426 globalState.eventEmitter.removeListener(eventName, eventHandler);
8427 } else {
8428 // Remove all handlers for a specific event
8429 globalState.eventEmitter.removeAllListeners(eventName);
8430 }
8431 };
8432
8433 var staticMethods = /*#__PURE__*/Object.freeze({
8434 __proto__: null,
8435 argsToParams: argsToParams,
8436 bindClickHandler: bindClickHandler,
8437 clickCancel: clickCancel,
8438 clickConfirm: clickConfirm,
8439 clickDeny: clickDeny,
8440 enableLoading: showLoading,
8441 fire: fire,
8442 getActions: getActions,
8443 getCancelButton: getCancelButton,
8444 getCloseButton: getCloseButton,
8445 getConfirmButton: getConfirmButton,
8446 getContainer: getContainer,
8447 getDenyButton: getDenyButton,
8448 getFocusableElements: getFocusableElements,
8449 getFooter: getFooter,
8450 getHtmlContainer: getHtmlContainer,
8451 getIcon: getIcon,
8452 getIconContent: getIconContent,
8453 getImage: getImage,
8454 getInputLabel: getInputLabel,
8455 getLoader: getLoader,
8456 getPopup: getPopup,
8457 getProgressSteps: getProgressSteps,
8458 getTimerLeft: getTimerLeft,
8459 getTimerProgressBar: getTimerProgressBar,
8460 getTitle: getTitle,
8461 getValidationMessage: getValidationMessage,
8462 increaseTimer: increaseTimer,
8463 isDeprecatedParameter: isDeprecatedParameter,
8464 isLoading: isLoading,
8465 isTimerRunning: isTimerRunning,
8466 isUpdatableParameter: isUpdatableParameter,
8467 isValidParameter: isValidParameter,
8468 isVisible: isVisible,
8469 mixin: mixin,
8470 off: off,
8471 on: on,
8472 once: once,
8473 resumeTimer: resumeTimer,
8474 showLoading: showLoading,
8475 stopTimer: stopTimer,
8476 toggleTimer: toggleTimer
8477 });
8478
8479 class Timer {
8480 /**
8481 * @param {() => void} callback
8482 * @param {number} delay
8483 */
8484 constructor(callback, delay) {
8485 this.callback = callback;
8486 this.remaining = delay;
8487 this.running = false;
8488 this.start();
8489 }
8490
8491 /**
8492 * @returns {number}
8493 */
8494 start() {
8495 if (!this.running) {
8496 this.running = true;
8497 this.started = new Date();
8498 this.id = setTimeout(this.callback, this.remaining);
8499 }
8500 return this.remaining;
8501 }
8502
8503 /**
8504 * @returns {number}
8505 */
8506 stop() {
8507 if (this.started && this.running) {
8508 this.running = false;
8509 clearTimeout(this.id);
8510 this.remaining -= new Date().getTime() - this.started.getTime();
8511 }
8512 return this.remaining;
8513 }
8514
8515 /**
8516 * @param {number} n
8517 * @returns {number}
8518 */
8519 increase(n) {
8520 const running = this.running;
8521 if (running) {
8522 this.stop();
8523 }
8524 this.remaining += n;
8525 if (running) {
8526 this.start();
8527 }
8528 return this.remaining;
8529 }
8530
8531 /**
8532 * @returns {number}
8533 */
8534 getTimerLeft() {
8535 if (this.running) {
8536 this.stop();
8537 this.start();
8538 }
8539 return this.remaining;
8540 }
8541
8542 /**
8543 * @returns {boolean}
8544 */
8545 isRunning() {
8546 return this.running;
8547 }
8548 }
8549
8550 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
8551
8552 /**
8553 * @param {SweetAlertOptions} params
8554 * @returns {SweetAlertOptions}
8555 */
8556 const getTemplateParams = params => {
8557 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
8558 if (!template) {
8559 return {};
8560 }
8561 /** @type {DocumentFragment} */
8562 const templateContent = template.content;
8563 showWarningsForElements(templateContent);
8564 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
8565 return result;
8566 };
8567
8568 /**
8569 * @param {DocumentFragment} templateContent
8570 * @returns {Record<string, string | boolean | number>}
8571 */
8572 const getSwalParams = templateContent => {
8573 /** @type {Record<string, string | boolean | number>} */
8574 const result = {};
8575 /** @type {HTMLElement[]} */
8576 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
8577 swalParams.forEach(param => {
8578 showWarningsForAttributes(param, ['name', 'value']);
8579 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
8580 const value = param.getAttribute('value');
8581 if (!paramName || !value) {
8582 return;
8583 }
8584 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
8585 result[paramName] = value !== 'false';
8586 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
8587 result[paramName] = JSON.parse(value);
8588 } else {
8589 result[paramName] = value;
8590 }
8591 });
8592 return result;
8593 };
8594
8595 /**
8596 * @param {DocumentFragment} templateContent
8597 * @returns {Record<string, () => void>}
8598 */
8599 const getSwalFunctionParams = templateContent => {
8600 /** @type {Record<string, () => void>} */
8601 const result = {};
8602 /** @type {HTMLElement[]} */
8603 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
8604 swalFunctions.forEach(param => {
8605 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
8606 const value = param.getAttribute('value');
8607 if (!paramName || !value) {
8608 return;
8609 }
8610 result[paramName] = new Function(`return ${value}`)();
8611 });
8612 return result;
8613 };
8614
8615 /**
8616 * @param {DocumentFragment} templateContent
8617 * @returns {Record<string, string | boolean>}
8618 */
8619 const getSwalButtons = templateContent => {
8620 /** @type {Record<string, string | boolean>} */
8621 const result = {};
8622 /** @type {HTMLElement[]} */
8623 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
8624 swalButtons.forEach(button => {
8625 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
8626 const type = button.getAttribute('type');
8627 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
8628 return;
8629 }
8630 result[`${type}ButtonText`] = button.innerHTML;
8631 result[`show${capitalizeFirstLetter(type)}Button`] = true;
8632 const color = button.getAttribute('color');
8633 if (color !== null) {
8634 result[`${type}ButtonColor`] = color;
8635 }
8636 const ariaLabel = button.getAttribute('aria-label');
8637 if (ariaLabel !== null) {
8638 result[`${type}ButtonAriaLabel`] = ariaLabel;
8639 }
8640 });
8641 return result;
8642 };
8643
8644 /**
8645 * @param {DocumentFragment} templateContent
8646 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
8647 */
8648 const getSwalImage = templateContent => {
8649 const result = {};
8650 /** @type {HTMLElement | null} */
8651 const image = templateContent.querySelector('swal-image');
8652 if (image) {
8653 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
8654 // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
8655 const src = image.getAttribute('src');
8656 if (src !== null) result.imageUrl = src || undefined;
8657 const width = image.getAttribute('width');
8658 if (width !== null) result.imageWidth = width || undefined;
8659 const height = image.getAttribute('height');
8660 if (height !== null) result.imageHeight = height || undefined;
8661 const alt = image.getAttribute('alt');
8662 if (alt !== null) result.imageAlt = alt || undefined;
8663 }
8664 return result;
8665 };
8666
8667 /**
8668 * @param {DocumentFragment} templateContent
8669 * @returns {object}
8670 */
8671 const getSwalIcon = templateContent => {
8672 const result = {};
8673 /** @type {HTMLElement | null} */
8674 const icon = templateContent.querySelector('swal-icon');
8675 if (icon) {
8676 showWarningsForAttributes(icon, ['type', 'color']);
8677 if (icon.hasAttribute('type')) {
8678 result.icon = icon.getAttribute('type');
8679 }
8680 if (icon.hasAttribute('color')) {
8681 result.iconColor = icon.getAttribute('color');
8682 }
8683 result.iconHtml = icon.innerHTML;
8684 }
8685 return result;
8686 };
8687
8688 /**
8689 * @param {DocumentFragment} templateContent
8690 * @returns {object}
8691 */
8692 const getSwalInput = templateContent => {
8693 /** @type {Record<string, any>} */
8694 const result = {};
8695 /** @type {HTMLElement | null} */
8696 const input = templateContent.querySelector('swal-input');
8697 if (input) {
8698 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
8699 result.input = input.getAttribute('type') || 'text';
8700 if (input.hasAttribute('label')) {
8701 result.inputLabel = input.getAttribute('label');
8702 }
8703 if (input.hasAttribute('placeholder')) {
8704 result.inputPlaceholder = input.getAttribute('placeholder');
8705 }
8706 if (input.hasAttribute('value')) {
8707 result.inputValue = input.getAttribute('value');
8708 }
8709 }
8710 /** @type {HTMLElement[]} */
8711 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
8712 if (inputOptions.length) {
8713 result.inputOptions = {};
8714 inputOptions.forEach(option => {
8715 showWarningsForAttributes(option, ['value']);
8716 const optionValue = option.getAttribute('value');
8717 if (!optionValue) {
8718 return;
8719 }
8720 const optionName = option.innerHTML;
8721 result.inputOptions[optionValue] = optionName;
8722 });
8723 }
8724 return result;
8725 };
8726
8727 /**
8728 * @param {DocumentFragment} templateContent
8729 * @param {string[]} paramNames
8730 * @returns {Record<string, string>}
8731 */
8732 const getSwalStringParams = (templateContent, paramNames) => {
8733 /** @type {Record<string, string>} */
8734 const result = {};
8735 for (const i in paramNames) {
8736 const paramName = paramNames[i];
8737 /** @type {HTMLElement | null} */
8738 const tag = templateContent.querySelector(paramName);
8739 if (tag) {
8740 showWarningsForAttributes(tag, []);
8741 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
8742 }
8743 }
8744 return result;
8745 };
8746
8747 /**
8748 * @param {DocumentFragment} templateContent
8749 */
8750 const showWarningsForElements = templateContent => {
8751 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
8752 Array.from(templateContent.children).forEach(el => {
8753 const tagName = el.tagName.toLowerCase();
8754 if (!allowedElements.includes(tagName)) {
8755 warn(`Unrecognized element <${tagName}>`);
8756 }
8757 });
8758 };
8759
8760 /**
8761 * @param {HTMLElement} el
8762 * @param {string[]} allowedAttributes
8763 */
8764 const showWarningsForAttributes = (el, allowedAttributes) => {
8765 Array.from(el.attributes).forEach(attribute => {
8766 if (allowedAttributes.indexOf(attribute.name) === -1) {
8767 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.'}`]);
8768 }
8769 });
8770 };
8771
8772 const SHOW_CLASS_TIMEOUT = 10;
8773
8774 /**
8775 * Open popup, add necessary classes and styles, fix scrollbar
8776 *
8777 * @param {SweetAlertOptions} params
8778 */
8779 const openPopup = params => {
8780 var _globalState$eventEmi, _globalState$eventEmi2;
8781 const container = getContainer();
8782 const popup = getPopup();
8783 if (!container || !popup) {
8784 return;
8785 }
8786 if (typeof params.willOpen === 'function') {
8787 params.willOpen(popup);
8788 }
8789 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
8790 const bodyStyles = window.getComputedStyle(document.body);
8791 const initialBodyOverflow = bodyStyles.overflowY;
8792 addClasses(container, popup, params);
8793
8794 // scrolling is 'hidden' until animation is done, after that 'auto'
8795 setTimeout(() => {
8796 setScrollingVisibility(container, popup);
8797 }, SHOW_CLASS_TIMEOUT);
8798 if (isModal()) {
8799 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
8800 setAriaHidden();
8801 }
8802
8803 // https://github.com/sweetalert2/sweetalert2/issues/2923
8804 if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
8805 // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
8806 container.style.pointerEvents = 'auto';
8807 }
8808 if (!isToast() && !globalState.previousActiveElement) {
8809 globalState.previousActiveElement = document.activeElement;
8810 }
8811 if (typeof params.didOpen === 'function') {
8812 const didOpen = params.didOpen;
8813 setTimeout(() => didOpen(popup));
8814 }
8815 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
8816 };
8817
8818 /**
8819 * @param {Event} event
8820 */
8821 const swalOpenAnimationFinished = event => {
8822 const popup = getPopup();
8823 if (!popup || event.target !== popup) {
8824 return;
8825 }
8826 const container = getContainer();
8827 if (!container) {
8828 return;
8829 }
8830 popup.removeEventListener('animationend', swalOpenAnimationFinished);
8831 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
8832 container.style.overflowY = 'auto';
8833
8834 // no-transition is added in init() in case one swal is opened right after another
8835 removeClass(container, swalClasses['no-transition']);
8836 };
8837
8838 /**
8839 * @param {HTMLElement} container
8840 * @param {HTMLElement} popup
8841 */
8842 const setScrollingVisibility = (container, popup) => {
8843 if (hasCssAnimation(popup)) {
8844 container.style.overflowY = 'hidden';
8845 popup.addEventListener('animationend', swalOpenAnimationFinished);
8846 popup.addEventListener('transitionend', swalOpenAnimationFinished);
8847 } else {
8848 container.style.overflowY = 'auto';
8849 }
8850 };
8851
8852 /**
8853 * @param {HTMLElement} container
8854 * @param {boolean} scrollbarPadding
8855 * @param {string} initialBodyOverflow
8856 */
8857 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
8858 iOSfix();
8859 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
8860 replaceScrollbarWithPadding(initialBodyOverflow);
8861 }
8862
8863 // sweetalert2/issues/1247
8864 setTimeout(() => {
8865 container.scrollTop = 0;
8866 });
8867 };
8868
8869 /**
8870 * @param {HTMLElement} container
8871 * @param {HTMLElement} popup
8872 * @param {SweetAlertOptions} params
8873 */
8874 const addClasses = (container, popup, params) => {
8875 var _params$showClass;
8876 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
8877 addClass(container, params.showClass.backdrop);
8878 }
8879 if (params.animation) {
8880 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
8881 popup.style.setProperty('opacity', '0', 'important');
8882 show(popup, 'grid');
8883 setTimeout(() => {
8884 var _params$showClass2;
8885 // Animate popup right after showing it
8886 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
8887 addClass(popup, params.showClass.popup);
8888 }
8889 // and remove the opacity workaround
8890 popup.style.removeProperty('opacity');
8891 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
8892 } else {
8893 show(popup, 'grid');
8894 }
8895 addClass([document.documentElement, document.body], swalClasses.shown);
8896 if (params.heightAuto && params.backdrop && !params.toast) {
8897 addClass([document.documentElement, document.body], swalClasses['height-auto']);
8898 }
8899 };
8900
8901 var defaultInputValidators = {
8902 /**
8903 * @param {string} string
8904 * @param {string} [validationMessage]
8905 * @returns {Promise<string | void>}
8906 */
8907 email: (string, validationMessage) => {
8908 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
8909 },
8910 /**
8911 * @param {string} string
8912 * @param {string} [validationMessage]
8913 * @returns {Promise<string | void>}
8914 */
8915 url: (string, validationMessage) => {
8916 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
8917 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');
8918 }
8919 };
8920
8921 /**
8922 * @param {SweetAlertOptions} params
8923 */
8924 function setDefaultInputValidators(params) {
8925 // Use default `inputValidator` for supported input types if not provided
8926 if (params.inputValidator) {
8927 return;
8928 }
8929 if (params.input === 'email') {
8930 params.inputValidator = defaultInputValidators['email'];
8931 }
8932 if (params.input === 'url') {
8933 params.inputValidator = defaultInputValidators['url'];
8934 }
8935 }
8936
8937 /**
8938 * @param {SweetAlertOptions} params
8939 */
8940 function validateCustomTargetElement(params) {
8941 // Determine if the custom target element is valid
8942 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
8943 warn('Target parameter is not valid, defaulting to "body"');
8944 params.target = 'body';
8945 }
8946 }
8947
8948 /**
8949 * Set type, text and actions on popup
8950 *
8951 * @param {SweetAlertOptions} params
8952 */
8953 function setParameters(params) {
8954 setDefaultInputValidators(params);
8955
8956 // showLoaderOnConfirm && preConfirm
8957 if (params.showLoaderOnConfirm && !params.preConfirm) {
8958 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');
8959 }
8960 validateCustomTargetElement(params);
8961
8962 // Replace newlines with <br> in title
8963 if (typeof params.title === 'string') {
8964 params.title = params.title.split('\n').join('<br />');
8965 }
8966 init(params);
8967 }
8968
8969 /** @type {SweetAlert} */
8970 let currentInstance;
8971 var _promise = /*#__PURE__*/new WeakMap();
8972 class SweetAlert {
8973 /**
8974 * @param {...(SweetAlertOptions | string)} args
8975 * @this {SweetAlert}
8976 */
8977 constructor(...args) {
8978 /**
8979 * @type {Promise<SweetAlertResult>}
8980 */
8981 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
8982 Promise.resolve({
8983 isConfirmed: false,
8984 isDenied: false,
8985 isDismissed: true
8986 }));
8987 // Prevent run in Node env
8988 if (typeof window === 'undefined') {
8989 return;
8990 }
8991 currentInstance = this;
8992
8993 // @ts-ignore
8994 const outerParams = Object.freeze(this.constructor.argsToParams(args));
8995
8996 /** @type {Readonly<SweetAlertOptions>} */
8997 this.params = outerParams;
8998
8999 /** @type {boolean} */
9000 this.isAwaitingPromise = false;
9001 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
9002 }
9003
9004 /**
9005 * @param {any} userParams
9006 * @param {any} mixinParams
9007 */
9008 _main(userParams, mixinParams = {}) {
9009 showWarningsForParams(Object.assign({}, mixinParams, userParams));
9010 if (globalState.currentInstance) {
9011 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
9012 const {
9013 isAwaitingPromise
9014 } = globalState.currentInstance;
9015 globalState.currentInstance._destroy();
9016 if (!isAwaitingPromise) {
9017 swalPromiseResolve({
9018 isDismissed: true
9019 });
9020 }
9021 if (isModal()) {
9022 unsetAriaHidden();
9023 }
9024 }
9025 globalState.currentInstance = currentInstance;
9026 const innerParams = prepareParams(userParams, mixinParams);
9027 setParameters(innerParams);
9028 Object.freeze(innerParams);
9029
9030 // clear the previous timer
9031 if (globalState.timeout) {
9032 globalState.timeout.stop();
9033 delete globalState.timeout;
9034 }
9035
9036 // clear the restore focus timeout
9037 clearTimeout(globalState.restoreFocusTimeout);
9038 const domCache = populateDomCache(currentInstance);
9039 render(currentInstance, innerParams);
9040 privateProps.innerParams.set(currentInstance, innerParams);
9041 return swalPromise(currentInstance, domCache, innerParams);
9042 }
9043
9044 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
9045 /**
9046 * @param {any} onFulfilled
9047 */
9048 // oxlint-disable-next-line unicorn/no-thenable
9049 then(onFulfilled) {
9050 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
9051 }
9052
9053 /**
9054 * @param {any} onFinally
9055 */
9056 finally(onFinally) {
9057 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
9058 }
9059 }
9060
9061 /**
9062 * @param {SweetAlert} instance
9063 * @param {DomCache} domCache
9064 * @param {SweetAlertOptions} innerParams
9065 * @returns {Promise<SweetAlertResult>}
9066 */
9067 const swalPromise = (instance, domCache, innerParams) => {
9068 return new Promise((resolve, reject) => {
9069 // functions to handle all closings/dismissals
9070 /**
9071 * @param {DismissReason} dismiss
9072 */
9073 const dismissWith = dismiss => {
9074 instance.close({
9075 isDismissed: true,
9076 dismiss,
9077 isConfirmed: false,
9078 isDenied: false
9079 });
9080 };
9081 privateMethods.swalPromiseResolve.set(instance, resolve);
9082 privateMethods.swalPromiseReject.set(instance, reject);
9083 domCache.confirmButton.onclick = () => {
9084 handleConfirmButtonClick(instance);
9085 };
9086 domCache.denyButton.onclick = () => {
9087 handleDenyButtonClick(instance);
9088 };
9089 domCache.cancelButton.onclick = () => {
9090 handleCancelButtonClick(instance, dismissWith);
9091 };
9092 domCache.closeButton.onclick = () => {
9093 dismissWith(DismissReason.close);
9094 };
9095 handlePopupClick(innerParams, domCache, dismissWith);
9096 addKeydownHandler(globalState, innerParams, dismissWith);
9097 handleInputOptionsAndValue(instance, innerParams);
9098 openPopup(innerParams);
9099 setupTimer(globalState, innerParams, dismissWith);
9100 initFocus(domCache, innerParams);
9101
9102 // Scroll container to top on open (#1247, #1946)
9103 setTimeout(() => {
9104 domCache.container.scrollTop = 0;
9105 });
9106 });
9107 };
9108
9109 /**
9110 * @param {SweetAlertOptions} userParams
9111 * @param {SweetAlertOptions} mixinParams
9112 * @returns {SweetAlertOptions}
9113 */
9114 const prepareParams = (userParams, mixinParams) => {
9115 const templateParams = getTemplateParams(userParams);
9116 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
9117 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
9118 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
9119 if (params.animation === false) {
9120 params.showClass = {
9121 backdrop: 'swal2-noanimation'
9122 };
9123 params.hideClass = {};
9124 }
9125 return params;
9126 };
9127
9128 /**
9129 * @param {SweetAlert} instance
9130 * @returns {DomCache}
9131 */
9132 const populateDomCache = instance => {
9133 const domCache = /** @type {DomCache} */{
9134 popup: (/** @type {HTMLElement} */getPopup()),
9135 container: (/** @type {HTMLElement} */getContainer()),
9136 actions: (/** @type {HTMLElement} */getActions()),
9137 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
9138 denyButton: (/** @type {HTMLElement} */getDenyButton()),
9139 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
9140 loader: (/** @type {HTMLElement} */getLoader()),
9141 closeButton: (/** @type {HTMLElement} */getCloseButton()),
9142 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
9143 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
9144 };
9145 privateProps.domCache.set(instance, domCache);
9146 return domCache;
9147 };
9148
9149 /**
9150 * @param {GlobalState} globalState
9151 * @param {SweetAlertOptions} innerParams
9152 * @param {(dismiss: DismissReason) => void} dismissWith
9153 */
9154 const setupTimer = (globalState, innerParams, dismissWith) => {
9155 const timerProgressBar = getTimerProgressBar();
9156 hide(timerProgressBar);
9157 if (innerParams.timer) {
9158 globalState.timeout = new Timer(() => {
9159 dismissWith('timer');
9160 delete globalState.timeout;
9161 }, innerParams.timer);
9162 if (innerParams.timerProgressBar && timerProgressBar) {
9163 show(timerProgressBar);
9164 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
9165 setTimeout(() => {
9166 if (globalState.timeout && globalState.timeout.running) {
9167 // timer can be already stopped or unset at this point
9168 animateTimerProgressBar(/** @type {number} */innerParams.timer);
9169 }
9170 });
9171 }
9172 }
9173 };
9174
9175 /**
9176 * Initialize focus in the popup:
9177 *
9178 * 1. If `toast` is `true`, don't steal focus from the document.
9179 * 2. Else if there is an [autofocus] element, focus it.
9180 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
9181 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
9182 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
9183 * 6. Else focus the first focusable element in a popup (if any).
9184 *
9185 * @param {DomCache} domCache
9186 * @param {SweetAlertOptions} innerParams
9187 */
9188 const initFocus = (domCache, innerParams) => {
9189 if (innerParams.toast) {
9190 return;
9191 }
9192 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
9193 if (!callIfFunction(innerParams.allowEnterKey)) {
9194 warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
9195 domCache.popup.focus();
9196 return;
9197 }
9198 if (focusAutofocus(domCache)) {
9199 return;
9200 }
9201 if (focusButton(domCache, innerParams)) {
9202 return;
9203 }
9204 setFocus(-1, 1);
9205 };
9206
9207 /**
9208 * @param {DomCache} domCache
9209 * @returns {boolean}
9210 */
9211 const focusAutofocus = domCache => {
9212 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
9213 for (const autofocusElement of autofocusElements) {
9214 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
9215 autofocusElement.focus();
9216 return true;
9217 }
9218 }
9219 return false;
9220 };
9221
9222 /**
9223 * @param {DomCache} domCache
9224 * @param {SweetAlertOptions} innerParams
9225 * @returns {boolean}
9226 */
9227 const focusButton = (domCache, innerParams) => {
9228 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
9229 domCache.denyButton.focus();
9230 return true;
9231 }
9232 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
9233 domCache.cancelButton.focus();
9234 return true;
9235 }
9236 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
9237 domCache.confirmButton.focus();
9238 return true;
9239 }
9240 return false;
9241 };
9242
9243 // Assign instance methods from src/instanceMethods/*.js to prototype
9244 SweetAlert.prototype.disableButtons = disableButtons;
9245 SweetAlert.prototype.enableButtons = enableButtons;
9246 SweetAlert.prototype.getInput = getInput;
9247 SweetAlert.prototype.disableInput = disableInput;
9248 SweetAlert.prototype.enableInput = enableInput;
9249 SweetAlert.prototype.hideLoading = hideLoading;
9250 SweetAlert.prototype.disableLoading = hideLoading;
9251 SweetAlert.prototype.showValidationMessage = showValidationMessage;
9252 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
9253 SweetAlert.prototype.close = close;
9254 SweetAlert.prototype.closePopup = close;
9255 SweetAlert.prototype.closeModal = close;
9256 SweetAlert.prototype.closeToast = close;
9257 SweetAlert.prototype.rejectPromise = rejectPromise;
9258 SweetAlert.prototype.update = update;
9259 SweetAlert.prototype._destroy = _destroy;
9260
9261 // Assign static methods from src/staticMethods/*.js to constructor
9262 Object.assign(SweetAlert, staticMethods);
9263
9264 // Proxy to instance methods to constructor, for now, for backwards compatibility
9265 Object.keys(instanceMethods).forEach(key => {
9266 /**
9267 * @param {...(SweetAlertOptions | string | undefined)} args
9268 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
9269 */
9270 // @ts-ignore: Dynamic property assignment for backwards compatibility
9271 SweetAlert[key] = function (...args) {
9272 // @ts-ignore
9273 if (currentInstance && currentInstance[key]) {
9274 // @ts-ignore
9275 return currentInstance[key](...args);
9276 }
9277 return undefined;
9278 };
9279 });
9280 SweetAlert.DismissReason = DismissReason;
9281 SweetAlert.version = '11.26.25';
9282
9283 const Swal = SweetAlert;
9284 // @ts-ignore
9285 Swal.default = Swal;
9286
9287 return Swal;
9288
9289 }));
9290 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
9291 "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-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:auto}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}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)}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}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}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}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)}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:auto}.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}.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}}");
9292
9293 /***/ },
9294
9295 /***/ "./node_modules/toastify-js/src/toastify.js"
9296 /*!**************************************************!*\
9297 !*** ./node_modules/toastify-js/src/toastify.js ***!
9298 \**************************************************/
9299 (module) {
9300
9301 /*!
9302 * Toastify js 1.12.0
9303 * https://github.com/apvarun/toastify-js
9304 * @license MIT licensed
9305 *
9306 * Copyright (C) 2018 Varun A P
9307 */
9308 (function(root, factory) {
9309 if ( true && module.exports) {
9310 module.exports = factory();
9311 } else {
9312 root.Toastify = factory();
9313 }
9314 })(this, function(global) {
9315 // Object initialization
9316 var Toastify = function(options) {
9317 // Returning a new init object
9318 return new Toastify.lib.init(options);
9319 },
9320 // Library version
9321 version = "1.12.0";
9322
9323 // Set the default global options
9324 Toastify.defaults = {
9325 oldestFirst: true,
9326 text: "Toastify is awesome!",
9327 node: undefined,
9328 duration: 3000,
9329 selector: undefined,
9330 callback: function () {
9331 },
9332 destination: undefined,
9333 newWindow: false,
9334 close: false,
9335 gravity: "toastify-top",
9336 positionLeft: false,
9337 position: '',
9338 backgroundColor: '',
9339 avatar: "",
9340 className: "",
9341 stopOnFocus: true,
9342 onClick: function () {
9343 },
9344 offset: {x: 0, y: 0},
9345 escapeMarkup: true,
9346 ariaLive: 'polite',
9347 style: {background: ''}
9348 };
9349
9350 // Defining the prototype of the object
9351 Toastify.lib = Toastify.prototype = {
9352 toastify: version,
9353
9354 constructor: Toastify,
9355
9356 // Initializing the object with required parameters
9357 init: function(options) {
9358 // Verifying and validating the input object
9359 if (!options) {
9360 options = {};
9361 }
9362
9363 // Creating the options object
9364 this.options = {};
9365
9366 this.toastElement = null;
9367
9368 // Validating the options
9369 this.options.text = options.text || Toastify.defaults.text; // Display message
9370 this.options.node = options.node || Toastify.defaults.node; // Display content as node
9371 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
9372 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
9373 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
9374 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
9375 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
9376 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
9377 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
9378 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
9379 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
9380 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
9381 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
9382 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
9383 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
9384 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
9385 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
9386 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
9387 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
9388 this.options.style = options.style || Toastify.defaults.style;
9389 if(options.backgroundColor) {
9390 this.options.style.background = options.backgroundColor;
9391 }
9392
9393 // Returning the current object for chaining functions
9394 return this;
9395 },
9396
9397 // Building the DOM element
9398 buildToast: function() {
9399 // Validating if the options are defined
9400 if (!this.options) {
9401 throw "Toastify is not initialized";
9402 }
9403
9404 // Creating the DOM object
9405 var divElement = document.createElement("div");
9406 divElement.className = "toastify on " + this.options.className;
9407
9408 // Positioning toast to left or right or center
9409 if (!!this.options.position) {
9410 divElement.className += " toastify-" + this.options.position;
9411 } else {
9412 // To be depreciated in further versions
9413 if (this.options.positionLeft === true) {
9414 divElement.className += " toastify-left";
9415 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
9416 } else {
9417 // Default position
9418 divElement.className += " toastify-right";
9419 }
9420 }
9421
9422 // Assigning gravity of element
9423 divElement.className += " " + this.options.gravity;
9424
9425 if (this.options.backgroundColor) {
9426 // This is being deprecated in favor of using the style HTML DOM property
9427 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
9428 }
9429
9430 // Loop through our style object and apply styles to divElement
9431 for (var property in this.options.style) {
9432 divElement.style[property] = this.options.style[property];
9433 }
9434
9435 // Announce the toast to screen readers
9436 if (this.options.ariaLive) {
9437 divElement.setAttribute('aria-live', this.options.ariaLive)
9438 }
9439
9440 // Adding the toast message/node
9441 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
9442 // If we have a valid node, we insert it
9443 divElement.appendChild(this.options.node)
9444 } else {
9445 if (this.options.escapeMarkup) {
9446 divElement.innerText = this.options.text;
9447 } else {
9448 divElement.innerHTML = this.options.text;
9449 }
9450
9451 if (this.options.avatar !== "") {
9452 var avatarElement = document.createElement("img");
9453 avatarElement.src = this.options.avatar;
9454
9455 avatarElement.className = "toastify-avatar";
9456
9457 if (this.options.position == "left" || this.options.positionLeft === true) {
9458 // Adding close icon on the left of content
9459 divElement.appendChild(avatarElement);
9460 } else {
9461 // Adding close icon on the right of content
9462 divElement.insertAdjacentElement("afterbegin", avatarElement);
9463 }
9464 }
9465 }
9466
9467 // Adding a close icon to the toast
9468 if (this.options.close === true) {
9469 // Create a span for close element
9470 var closeElement = document.createElement("button");
9471 closeElement.type = "button";
9472 closeElement.setAttribute("aria-label", "Close");
9473 closeElement.className = "toast-close";
9474 closeElement.innerHTML = "&#10006;";
9475
9476 // Triggering the removal of toast from DOM on close click
9477 closeElement.addEventListener(
9478 "click",
9479 function(event) {
9480 event.stopPropagation();
9481 this.removeElement(this.toastElement);
9482 window.clearTimeout(this.toastElement.timeOutValue);
9483 }.bind(this)
9484 );
9485
9486 //Calculating screen width
9487 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
9488
9489 // Adding the close icon to the toast element
9490 // Display on the right if screen width is less than or equal to 360px
9491 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
9492 // Adding close icon on the left of content
9493 divElement.insertAdjacentElement("afterbegin", closeElement);
9494 } else {
9495 // Adding close icon on the right of content
9496 divElement.appendChild(closeElement);
9497 }
9498 }
9499
9500 // Clear timeout while toast is focused
9501 if (this.options.stopOnFocus && this.options.duration > 0) {
9502 var self = this;
9503 // stop countdown
9504 divElement.addEventListener(
9505 "mouseover",
9506 function(event) {
9507 window.clearTimeout(divElement.timeOutValue);
9508 }
9509 )
9510 // add back the timeout
9511 divElement.addEventListener(
9512 "mouseleave",
9513 function() {
9514 divElement.timeOutValue = window.setTimeout(
9515 function() {
9516 // Remove the toast from DOM
9517 self.removeElement(divElement);
9518 },
9519 self.options.duration
9520 )
9521 }
9522 )
9523 }
9524
9525 // Adding an on-click destination path
9526 if (typeof this.options.destination !== "undefined") {
9527 divElement.addEventListener(
9528 "click",
9529 function(event) {
9530 event.stopPropagation();
9531 if (this.options.newWindow === true) {
9532 window.open(this.options.destination, "_blank");
9533 } else {
9534 window.location = this.options.destination;
9535 }
9536 }.bind(this)
9537 );
9538 }
9539
9540 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
9541 divElement.addEventListener(
9542 "click",
9543 function(event) {
9544 event.stopPropagation();
9545 this.options.onClick();
9546 }.bind(this)
9547 );
9548 }
9549
9550 // Adding offset
9551 if(typeof this.options.offset === "object") {
9552
9553 var x = getAxisOffsetAValue("x", this.options);
9554 var y = getAxisOffsetAValue("y", this.options);
9555
9556 var xOffset = this.options.position == "left" ? x : "-" + x;
9557 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
9558
9559 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
9560
9561 }
9562
9563 // Returning the generated element
9564 return divElement;
9565 },
9566
9567 // Displaying the toast
9568 showToast: function() {
9569 // Creating the DOM object for the toast
9570 this.toastElement = this.buildToast();
9571
9572 // Getting the root element to with the toast needs to be added
9573 var rootElement;
9574 if (typeof this.options.selector === "string") {
9575 rootElement = document.getElementById(this.options.selector);
9576 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
9577 rootElement = this.options.selector;
9578 } else {
9579 rootElement = document.body;
9580 }
9581
9582 // Validating if root element is present in DOM
9583 if (!rootElement) {
9584 throw "Root element is not defined";
9585 }
9586
9587 // Adding the DOM element
9588 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
9589 rootElement.insertBefore(this.toastElement, elementToInsert);
9590
9591 // Repositioning the toasts in case multiple toasts are present
9592 Toastify.reposition();
9593
9594 if (this.options.duration > 0) {
9595 this.toastElement.timeOutValue = window.setTimeout(
9596 function() {
9597 // Remove the toast from DOM
9598 this.removeElement(this.toastElement);
9599 }.bind(this),
9600 this.options.duration
9601 ); // Binding `this` for function invocation
9602 }
9603
9604 // Supporting function chaining
9605 return this;
9606 },
9607
9608 hideToast: function() {
9609 if (this.toastElement.timeOutValue) {
9610 clearTimeout(this.toastElement.timeOutValue);
9611 }
9612 this.removeElement(this.toastElement);
9613 },
9614
9615 // Removing the element from the DOM
9616 removeElement: function(toastElement) {
9617 // Hiding the element
9618 // toastElement.classList.remove("on");
9619 toastElement.className = toastElement.className.replace(" on", "");
9620
9621 // Removing the element from DOM after transition end
9622 window.setTimeout(
9623 function() {
9624 // remove options node if any
9625 if (this.options.node && this.options.node.parentNode) {
9626 this.options.node.parentNode.removeChild(this.options.node);
9627 }
9628
9629 // Remove the element from the DOM, only when the parent node was not removed before.
9630 if (toastElement.parentNode) {
9631 toastElement.parentNode.removeChild(toastElement);
9632 }
9633
9634 // Calling the callback function
9635 this.options.callback.call(toastElement);
9636
9637 // Repositioning the toasts again
9638 Toastify.reposition();
9639 }.bind(this),
9640 400
9641 ); // Binding `this` for function invocation
9642 },
9643 };
9644
9645 // Positioning the toasts on the DOM
9646 Toastify.reposition = function() {
9647
9648 // Top margins with gravity
9649 var topLeftOffsetSize = {
9650 top: 15,
9651 bottom: 15,
9652 };
9653 var topRightOffsetSize = {
9654 top: 15,
9655 bottom: 15,
9656 };
9657 var offsetSize = {
9658 top: 15,
9659 bottom: 15,
9660 };
9661
9662 // Get all toast messages on the DOM
9663 var allToasts = document.getElementsByClassName("toastify");
9664
9665 var classUsed;
9666
9667 // Modifying the position of each toast element
9668 for (var i = 0; i < allToasts.length; i++) {
9669 // Getting the applied gravity
9670 if (containsClass(allToasts[i], "toastify-top") === true) {
9671 classUsed = "toastify-top";
9672 } else {
9673 classUsed = "toastify-bottom";
9674 }
9675
9676 var height = allToasts[i].offsetHeight;
9677 classUsed = classUsed.substr(9, classUsed.length-1)
9678 // Spacing between toasts
9679 var offset = 15;
9680
9681 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
9682
9683 // Show toast in center if screen with less than or equal to 360px
9684 if (width <= 360) {
9685 // Setting the position
9686 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
9687
9688 offsetSize[classUsed] += height + offset;
9689 } else {
9690 if (containsClass(allToasts[i], "toastify-left") === true) {
9691 // Setting the position
9692 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
9693
9694 topLeftOffsetSize[classUsed] += height + offset;
9695 } else {
9696 // Setting the position
9697 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
9698
9699 topRightOffsetSize[classUsed] += height + offset;
9700 }
9701 }
9702 }
9703
9704 // Supporting function chaining
9705 return this;
9706 };
9707
9708 // Helper function to get offset.
9709 function getAxisOffsetAValue(axis, options) {
9710
9711 if(options.offset[axis]) {
9712 if(isNaN(options.offset[axis])) {
9713 return options.offset[axis];
9714 }
9715 else {
9716 return options.offset[axis] + 'px';
9717 }
9718 }
9719
9720 return '0px';
9721
9722 }
9723
9724 function containsClass(elem, yourClass) {
9725 if (!elem || typeof yourClass !== "string") {
9726 return false;
9727 } else if (
9728 elem.className &&
9729 elem.className
9730 .trim()
9731 .split(/\s+/gi)
9732 .indexOf(yourClass) > -1
9733 ) {
9734 return true;
9735 } else {
9736 return false;
9737 }
9738 }
9739
9740 // Setting up the prototype for the init object
9741 Toastify.lib.init.prototype = Toastify.lib;
9742
9743 // Returning the Toastify function to be assigned to the window object/module
9744 return Toastify;
9745 });
9746
9747
9748 /***/ }
9749
9750 /******/ });
9751 /************************************************************************/
9752 /******/ // The module cache
9753 /******/ const __webpack_module_cache__ = {};
9754 /******/
9755 /******/ // The require function
9756 /******/ function __webpack_require__(moduleId) {
9757 /******/ // Check if module is in cache
9758 /******/ const cachedModule = __webpack_module_cache__[moduleId];
9759 /******/ if (cachedModule !== undefined) {
9760 /******/ return cachedModule.exports;
9761 /******/ }
9762 /******/ // Create a new module (and put it into the cache)
9763 /******/ const module = __webpack_module_cache__[moduleId] = {
9764 /******/ id: moduleId,
9765 /******/ // no module.loaded needed
9766 /******/ exports: {}
9767 /******/ };
9768 /******/
9769 /******/ // Execute the module function
9770 /******/ if (!(moduleId in __webpack_modules__)) {
9771 /******/ delete __webpack_module_cache__[moduleId];
9772 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
9773 /******/ e.code = 'MODULE_NOT_FOUND';
9774 /******/ throw e;
9775 /******/ }
9776 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
9777 /******/
9778 /******/ // Return the exports of the module
9779 /******/ return module.exports;
9780 /******/ }
9781 /******/
9782 /************************************************************************/
9783 /******/ /* webpack/runtime/compat get default export */
9784 /******/ (() => {
9785 /******/ // getDefaultExport function for compatibility with non-harmony modules
9786 /******/ __webpack_require__.n = (module) => {
9787 /******/ const getter = module && module.__esModule ?
9788 /******/ () => (module['default']) :
9789 /******/ () => (module);
9790 /******/ __webpack_require__.d(getter, { a: getter });
9791 /******/ return getter;
9792 /******/ };
9793 /******/ })();
9794 /******/
9795 /******/ /* webpack/runtime/define property getters */
9796 /******/ (() => {
9797 /******/ // define getter/value functions for harmony exports
9798 /******/ __webpack_require__.d = (exports, definition) => {
9799 /******/ if(Array.isArray(definition)) {
9800 /******/ var i = 0;
9801 /******/ while(i < definition.length) {
9802 /******/ var key = definition[i++];
9803 /******/ var binding = definition[i++];
9804 /******/ if(!__webpack_require__.o(exports, key)) {
9805 /******/ if(binding === 0) {
9806 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
9807 /******/ } else {
9808 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
9809 /******/ }
9810 /******/ } else if(binding === 0) { i++; }
9811 /******/ }
9812 /******/ } else {
9813 /******/ for(var key in definition) {
9814 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
9815 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
9816 /******/ }
9817 /******/ }
9818 /******/ }
9819 /******/ };
9820 /******/ })();
9821 /******/
9822 /******/ /* webpack/runtime/hasOwnProperty shorthand */
9823 /******/ (() => {
9824 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
9825 /******/ })();
9826 /******/
9827 /******/ /* webpack/runtime/make namespace object */
9828 /******/ (() => {
9829 /******/ // define __esModule on exports
9830 /******/ __webpack_require__.r = (exports) => {
9831 /******/ if(Symbol.toStringTag) {
9832 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
9833 /******/ }
9834 /******/ Object.defineProperty(exports, '__esModule', { value: true });
9835 /******/ };
9836 /******/ })();
9837 /******/
9838 /******/ /* webpack/runtime/nonce */
9839 /******/ (() => {
9840 /******/ __webpack_require__.nc = undefined;
9841 /******/ })();
9842 /******/
9843 /************************************************************************/
9844 let __webpack_exports__ = {};
9845 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
9846 (() => {
9847 "use strict";
9848 /*!**********************************************!*\
9849 !*** ./assets/src/js/admin/edit-question.js ***!
9850 \**********************************************/
9851 __webpack_require__.r(__webpack_exports__);
9852 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9853 /* harmony export */ EditQuestion: () => (/* binding */ EditQuestion)
9854 /* harmony export */ });
9855 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
9856 /* harmony import */ var lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify */ "./assets/src/js/lpToastify.js");
9857 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
9858 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
9859 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
9860 /**
9861 * Edit question JS handler.
9862 *
9863 * @since 4.2.9
9864 * @version 1.0.0
9865 */
9866
9867
9868
9869
9870
9871 const idUrlHandle = 'edit-question';
9872 let fibSelection;
9873 let timeoutAutoUpdateAnswer, timeoutAutoUpdateFib, timeoutAutoUpdateQuestion;
9874
9875 // EditQuestion class
9876 class EditQuestion {
9877 static selectors = {
9878 elEditQuestionWrap: '.lp-edit-question-wrap',
9879 elQuestionEditMain: '.lp-question-edit-main',
9880 elQuestionToggleAll: '.lp-question-toggle-all',
9881 elEditListQuestions: '.lp-edit-list-questions',
9882 elQuestionToggle: '.lp-question-toggle',
9883 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
9884 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
9885 elBtnAddQuestion: '.lp-btn-add-question',
9886 elBtnRemoveQuestion: '.lp-btn-remove-question',
9887 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
9888 elBtnUpdateQuestionDes: '.lp-btn-update-question-des',
9889 elBtnUpdateQuestionHint: '.lp-btn-update-question-hint',
9890 elBtnUpdateQuestionExplain: '.lp-btn-update-question-explanation',
9891 elQuestionTitleNewInput: '.lp-question-title-new-input',
9892 elQuestionTitleInput: '.lp-question-title-input',
9893 elQuestionTypeLabel: '.lp-question-type-label',
9894 elQuestionTypeNew: '.lp-question-type-new',
9895 elAddNewQuestion: 'add-new-question',
9896 elQuestionClone: '.lp-question-item.clone',
9897 elAnswersConfig: '.lp-answers-config',
9898 elBtnAddAnswer: '.lp-btn-add-question-answer',
9899 elQuestionAnswerItemAddNew: '.lp-question-answer-item-add-new',
9900 elQuestionAnswerTitleNewInput: '.lp-question-answer-title-new-input',
9901 elQuestionAnswerTitleInput: '.lp-question-answer-title-input',
9902 elBtnDeleteAnswer: '.lp-btn-delete-question-answer',
9903 elQuestionByType: '.lp-question-by-type',
9904 elInputAnswerSetTrue: '.lp-input-answer-set-true',
9905 elQuestionAnswerItem: '.lp-question-answer-item',
9906 elBtnUpdateQuestionAnswer: '.lp-btn-update-question-answer',
9907 elBtnFibInsertBlank: '.lp-btn-fib-insert-blank',
9908 elBtnFibDeleteAllBlanks: '.lp-btn-fib-delete-all-blanks',
9909 elBtnFibSaveContent: '.lp-btn-fib-save-content',
9910 elBtnFibClearAllContent: '.lp-btn-fib-clear-all-content',
9911 elFibOptionTitleInput: '.lp-question-fib-option-title-input',
9912 elFibBlankOptions: '.lp-question-fib-blank-options',
9913 elFibBlankOptionItem: '.lp-question-fib-blank-option-item',
9914 elFibBlankOptionItemClone: '.lp-question-fib-blank-option-item.clone',
9915 elFibBlankOptionIndex: '.lp-question-fib-option-index',
9916 elBtnFibOptionDelete: '.lp-btn-fib-option-delete',
9917 elFibOptionMatchCaseWrap: '.lp-question-fib-option-match-case-wrap',
9918 elFibOptionMatchCaseInput: '.lp-question-fib-option-match-case-input',
9919 elQuestionFibOptionDetail: '.lp-question-fib-option-detail',
9920 elFibOptionComparisonInput: '.lp-question-fib-option-comparison-input',
9921 elAutoSaveFib: '.lp-auto-save-fib',
9922 LPTarget: '.lp-target',
9923 elCollapse: 'lp-collapse',
9924 elSectionToggle: '.lp-section-toggle',
9925 elTriggerToggle: '.lp-trigger-toggle',
9926 elAutoSaveQuestion: '.lp-auto-save-question',
9927 elAutoSaveAnswer: '.lp-auto-save-question-answer',
9928 elQuestionFibInput: 'lp-question-fib-input',
9929 elBtnQuestionCreateType: '.lp-btn-question-create-type'
9930 };
9931 constructor() {}
9932 init() {
9933 this.events();
9934 this.initTinyMCE().then();
9935 }
9936 events() {
9937 if (EditQuestion._loadedEvents) {
9938 return;
9939 }
9940 EditQuestion._loadedEvents = true;
9941
9942 // Sortable answers's question
9943 const elQuestionEditMains = document.querySelectorAll(`${EditQuestion.selectors.elQuestionEditMain}`);
9944 elQuestionEditMains.forEach(elQuestionEditMain => {
9945 this.sortAbleQuestionAnswer(elQuestionEditMain);
9946 });
9947 // End sortable
9948
9949 // Event click
9950 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
9951 selector: EditQuestion.selectors.elBtnQuestionCreateType,
9952 callBack: this.createQuestionType.name,
9953 class: this
9954 }, {
9955 selector: EditQuestion.selectors.elBtnAddAnswer,
9956 callBack: this.addQuestionAnswer.name,
9957 class: this
9958 }, {
9959 selector: EditQuestion.selectors.elBtnDeleteAnswer,
9960 callBack: this.deleteQuestionAnswer.name,
9961 class: this
9962 }, {
9963 selector: EditQuestion.selectors.elBtnFibInsertBlank,
9964 callBack: this.fibInsertBlank.name,
9965 class: this
9966 }, {
9967 selector: EditQuestion.selectors.elBtnFibDeleteAllBlanks,
9968 callBack: this.fibDeleteAllBlanks.name,
9969 class: this
9970 }, {
9971 selector: EditQuestion.selectors.elBtnFibSaveContent,
9972 callBack: this.fibSaveContent.name,
9973 class: this
9974 }, {
9975 selector: EditQuestion.selectors.elBtnFibClearAllContent,
9976 callBack: this.fibClearContent.name,
9977 class: this
9978 }, {
9979 selector: EditQuestion.selectors.elBtnFibOptionDelete,
9980 callBack: this.fibDeleteBlank.name,
9981 class: this
9982 }, {
9983 selector: EditQuestion.selectors.elFibOptionMatchCaseInput,
9984 callBack: this.fibShowHideMatchCaseOption.name,
9985 class: this
9986 }, {
9987 selector: EditQuestion.selectors.elFibOptionComparisonInput,
9988 callBack: args => {
9989 const {
9990 e,
9991 target
9992 } = args;
9993 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
9994 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
9995 elBtnFibSaveContent.click();
9996 }
9997 }]);
9998
9999 // Toggle collapse
10000 document.addEventListener('click', e => {
10001 const target = e.target;
10002 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuestion.selectors.elTriggerToggle);
10003 });
10004
10005 // Event keyup
10006 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
10007 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
10008 callBack: this.checkCanAddAnswer.name,
10009 class: this
10010 }, {
10011 selector: EditQuestion.selectors.elFibOptionTitleInput,
10012 callBack: this.fibOptionTitleInputChange.name,
10013 class: this
10014 }, {
10015 selector: EditQuestion.selectors.elAutoSaveQuestion,
10016 callBack: this.autoUpdateQuestion.name,
10017 class: this
10018 }]);
10019
10020 // Event keydown
10021 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
10022 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
10023 callBack: this.addQuestionAnswer.name,
10024 class: this,
10025 checkIsEventEnter: true
10026 }]);
10027
10028 // Event change
10029 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
10030 selector: EditQuestion.selectors.elAutoSaveAnswer,
10031 callBack: this.autoUpdateAnswer.name,
10032 class: this
10033 }]);
10034
10035 // TinyMCE events
10036 this.eventEditorTinymce();
10037 }
10038
10039 // Run async to re-init all TinyMCE editors, because it slow if have many editors
10040 async initTinyMCE() {
10041 const elTextareas = document.querySelectorAll('.lp-editor-tinymce');
10042 elTextareas.forEach(elTextarea => {
10043 const idTextarea = elTextarea.id;
10044 this.reInitTinymce(idTextarea);
10045 });
10046 }
10047 reInitTinymce(id) {
10048 window.tinymce.execCommand('mceRemoveEditor', true, id);
10049 window.tinymce.execCommand('mceAddEditor', true, id);
10050 }
10051 reInitQuickTags(id) {
10052 const toolbar = document.getElementById(`qt_${id}_toolbar`);
10053 if (!toolbar || toolbar.children.length || !window.quicktags) {
10054 return;
10055 }
10056 const settings = window.tinyMCEPreInit?.qtInit?.[id] || {
10057 id
10058 };
10059 window.quicktags(settings);
10060 if (window.QTags?._buttonsInit) {
10061 window.QTags._buttonsInit();
10062 }
10063 }
10064 setDefaultEditorTab(id) {
10065 const wrapEditor = document.getElementById(`wp-${id}-wrap`);
10066 if (!wrapEditor) {
10067 return;
10068 }
10069 if (wrapEditor.classList.contains('html-active') && window.switchEditors?.go) {
10070 window.switchEditors.go(id, 'tmce');
10071 const elTextarea = document.getElementById(id);
10072 if (elTextarea) {
10073 elTextarea.style.visibility = '';
10074 }
10075 }
10076 wrapEditor.classList.add('tmce-active');
10077 wrapEditor.classList.remove('html-active');
10078 const visualTab = document.getElementById(`${id}-tmce`);
10079 const codeTab = document.getElementById(`${id}-html`);
10080 visualTab?.setAttribute('aria-pressed', 'true');
10081 codeTab?.setAttribute('aria-pressed', 'false');
10082 }
10083
10084 // Events for TinyMCE editor
10085 eventEditorTinymce() {
10086 window.tinymce.on('AddEditor', eEditor => {
10087 const id = eEditor.editor.id;
10088 const editor = window.tinymce.get(id);
10089 if (!editor) {
10090 return;
10091 }
10092 if (id === 'content') {
10093 return;
10094 }
10095 const elTextarea = document.getElementById(id);
10096 if (!elTextarea) {
10097 return;
10098 }
10099 const elQuestionEditMain = elTextarea.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10100
10101 // Skip if not in question edit context
10102 if (!elQuestionEditMain) {
10103 return;
10104 }
10105 const questionId = elQuestionEditMain.dataset.questionId;
10106 editor.settings.force_p_newlines = false;
10107 editor.settings.forced_root_block = '';
10108 editor.settings.force_br_newlines = true;
10109
10110 // Config use absolute url
10111 editor.settings.relative_urls = false;
10112 editor.settings.remove_script_host = false;
10113 editor.settings.convert_urls = true;
10114 editor.settings.document_base_url = lpData.site_url;
10115 // End config use absolute url
10116
10117 // Add quick tags
10118 this.reInitQuickTags(id);
10119
10120 // Events focus in TinyMCE editor
10121 editor.on('change keyup', e => {
10122 // Auto save if it has class lp-auto-save
10123 elTextarea.value = editor.getContent();
10124 this.autoUpdateQuestion({
10125 e,
10126 target: elTextarea
10127 });
10128 });
10129 editor.on('blur', e => {
10130 //console.log( 'Editor blurred:', e.target.id );
10131 });
10132 editor.on('focusin', e => {});
10133 editor.on('init', () => {
10134 // Add style
10135 editor.dom.addStyle(`
10136 body {
10137 line-height: 2.2 !important;
10138 }
10139 .${EditQuestion.selectors.elQuestionFibInput} {
10140 border: 1px dashed rebeccapurple;
10141 padding: 5px;
10142 }
10143 `);
10144
10145 // Set default tab visual
10146 this.setDefaultEditorTab(id);
10147 });
10148 editor.on('setcontent', e => {
10149 const uniquid = this.randomString();
10150 const elementg = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${uniquid}"]`);
10151 if (elementg[0]) {
10152 elementg[0].focus();
10153 }
10154 editor.dom.bind(elementg[0], 'input', e => {
10155 //console.log( 'Input changed:', e.target.value );
10156 });
10157 });
10158 editor.on('selectionchange', e => {
10159 fibSelection = editor.selection;
10160
10161 // Check selection is blank, check empty blank content
10162 if (fibSelection.getNode().classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10163 const blankId = fibSelection.getNode().dataset.id;
10164 const textBlank = fibSelection.getNode().textContent.trim();
10165 if (textBlank.length === 0) {
10166 const editorId = editor.id;
10167 const questionId = editorId.replace(`${EditQuestion.selectors.elQuestionFibInput}-`, '');
10168 const elQuestionEditMain = document.querySelector(`${EditQuestion.selectors.elQuestionEditMain}[data-question-id="${questionId}"]`);
10169 const elQuestionBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10170 const elFibBlankOptionItem = elQuestionBlankOptions.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10171 if (elFibBlankOptionItem) {
10172 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 0);
10173 }
10174 } else {
10175 const elTextarea = document.getElementById(id);
10176 const elAnswersConfig = elTextarea.closest(`${EditQuestion.selectors.elAnswersConfig}`);
10177 const elFibBlankOptionItem = elAnswersConfig.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10178 if (elFibBlankOptionItem) {
10179 const elFibOptionTitleInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10180 if (elFibOptionTitleInput) {
10181 elFibOptionTitleInput.value = textBlank;
10182 }
10183 }
10184 }
10185 }
10186 });
10187 editor.on('Undo', e => {
10188 const contentUndo = editor.getContent();
10189 const selection = editor.selection;
10190 const nodeUndo = selection.getNode();
10191 if (nodeUndo.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10192 const blankId = nodeUndo.dataset.id;
10193 const elFibBlankOptionItem = document.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
10194 if (elFibBlankOptionItem) {
10195 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 1);
10196 }
10197 }
10198 });
10199 editor.on('Redo', e => {});
10200 });
10201 }
10202 autoUpdateQuestion(args) {
10203 let {
10204 e,
10205 target,
10206 key,
10207 value
10208 } = args;
10209 const elAutoSave = target.closest(`${EditQuestion.selectors.elAutoSaveQuestion}`);
10210 if (!elAutoSave) {
10211 return;
10212 }
10213 const elQuestionEditMain = elAutoSave.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10214 const questionId = elQuestionEditMain.dataset.questionId;
10215 clearTimeout(timeoutAutoUpdateQuestion);
10216 timeoutAutoUpdateQuestion = setTimeout(() => {
10217 // Call ajax to update question description
10218 const callBack = {
10219 success: response => {
10220 const {
10221 message,
10222 status
10223 } = response;
10224 if (status === 'success') {
10225 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10226 } else {
10227 throw `Error: ${message}`;
10228 }
10229 },
10230 error: error => {
10231 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10232 },
10233 completed: () => {}
10234 };
10235 const dataSend = {
10236 action: 'update_question',
10237 question_id: questionId,
10238 args: {
10239 id_url: idUrlHandle
10240 }
10241 };
10242 if (undefined === key) {
10243 key = elAutoSave.dataset.keyAutoSave;
10244 if (!key) {
10245 if (!elAutoSave.classList.contains('lp-editor-tinymce')) {
10246 return;
10247 }
10248 const textAreaId = elAutoSave.id;
10249 key = textAreaId.replace(/lp-/g, '').replace(`-${questionId}`, '').replace(/-/g, '_');
10250 if (!key) {
10251 return;
10252 }
10253 }
10254 value = elAutoSave.value;
10255 }
10256 dataSend[key] = value;
10257 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10258 }, 700);
10259 }
10260 // Create question type
10261 createQuestionType(args) {
10262 const {
10263 e,
10264 target
10265 } = args;
10266 const elBtnQuestionCreateType = target.closest(`${EditQuestion.selectors.elBtnQuestionCreateType}`);
10267 if (!elBtnQuestionCreateType) {
10268 return;
10269 }
10270 const elQuestionEditMain = elBtnQuestionCreateType.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10271 if (!elQuestionEditMain) {
10272 return;
10273 }
10274 const questionId = elQuestionEditMain.dataset.questionId;
10275 const elQuestionTypeNew = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionTypeNew}`);
10276 if (!elQuestionTypeNew) {
10277 return;
10278 }
10279 const questionType = elQuestionTypeNew.value.trim();
10280 if (!questionType) {
10281 const message = elQuestionTypeNew.dataset.messEmptyType;
10282 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
10283 return;
10284 }
10285
10286 // Call ajax to create new question type
10287 const callBack = {
10288 success: response => {
10289 const {
10290 message,
10291 status,
10292 data
10293 } = response;
10294 if (status === 'success') {
10295 const {
10296 html_option_answers
10297 } = data;
10298 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10299 elAnswersConfig.outerHTML = html_option_answers;
10300 this.initTinyMCE();
10301 this.sortAbleQuestionAnswer(elQuestionEditMain);
10302 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10303 } else {
10304 throw `Error: ${message}`;
10305 }
10306 },
10307 error: error => {
10308 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10309 },
10310 completed: () => {}
10311 };
10312 const dataSend = {
10313 action: 'update_question',
10314 question_id: questionId,
10315 question_type: questionType,
10316 args: {
10317 id_url: idUrlHandle
10318 }
10319 };
10320 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10321 }
10322 addQuestionAnswer(args) {
10323 const {
10324 e,
10325 target
10326 } = args;
10327 const elQuestionAnswerItemAddNew = target.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
10328 if (!elQuestionAnswerItemAddNew) {
10329 return;
10330 }
10331 e.preventDefault();
10332 const elQuestionAnswerTitleNewInput = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleNewInput}`);
10333 if (!elQuestionAnswerTitleNewInput.value.trim()) {
10334 const message = elQuestionAnswerTitleNewInput.dataset.messEmptyTitle;
10335 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
10336 return;
10337 }
10338 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10339 const elQuestionAnswerClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}.clone`);
10340 const elQuestionAnswerNew = elQuestionAnswerClone.cloneNode(true);
10341 const elQuestionAnswerTitleInputNew = elQuestionAnswerNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
10342 elQuestionAnswerNew.classList.remove('clone');
10343 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionAnswerNew, 1);
10344 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 1);
10345 elQuestionAnswerClone.insertAdjacentElement('beforebegin', elQuestionAnswerNew);
10346 const answerTitle = elQuestionAnswerTitleNewInput.value.trim();
10347 elQuestionAnswerTitleInputNew.value = answerTitle;
10348 elQuestionAnswerTitleNewInput.value = '';
10349 const questionId = elQuestionEditMain.dataset.questionId;
10350
10351 // Call ajax to add new question answer
10352 const callBack = {
10353 success: response => {
10354 const {
10355 message,
10356 status,
10357 data
10358 } = response;
10359 if (status === 'success') {
10360 const {
10361 question_answer
10362 } = data;
10363 elQuestionAnswerNew.dataset.answerId = question_answer.question_answer_id;
10364 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 0);
10365
10366 // Set data lp-answers-config
10367 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10368 dataAnswers.push(question_answer);
10369 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10370 } else {
10371 throw `Error: ${message}`;
10372 }
10373 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10374 },
10375 error: error => {
10376 elQuestionAnswerNew.remove();
10377 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10378 },
10379 completed: () => {}
10380 };
10381 const dataSend = {
10382 action: 'add_question_answer',
10383 question_id: questionId,
10384 answer_title: answerTitle,
10385 args: {
10386 id_url: idUrlHandle
10387 }
10388 };
10389 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10390 }
10391
10392 // Check to enable or disable add new question button
10393 checkCanAddAnswer(args) {
10394 const {
10395 e,
10396 target
10397 } = args;
10398 const elTrigger = target.closest(EditQuestion.selectors.elQuestionAnswerTitleNewInput);
10399 if (!elTrigger) {
10400 return;
10401 }
10402 const elQuestionAnswerItemAddNew = elTrigger.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
10403 if (!elQuestionAnswerItemAddNew) {
10404 return;
10405 }
10406 const elBtnAddAnswer = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elBtnAddAnswer}`);
10407 if (!elBtnAddAnswer) {
10408 return;
10409 }
10410 const titleValue = elTrigger.value.trim();
10411 if (titleValue) {
10412 elBtnAddAnswer.classList.add('active');
10413 } else {
10414 elBtnAddAnswer.classList.remove('active');
10415 }
10416 }
10417
10418 // Auto update question answer
10419 autoUpdateAnswer(args) {
10420 const {
10421 e,
10422 target
10423 } = args;
10424 const elAutoSaveAnswer = target.closest(`${EditQuestion.selectors.elAutoSaveAnswer}`);
10425 if (!elAutoSaveAnswer) {
10426 return;
10427 }
10428 const elQuestionAnswerItem = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
10429 clearTimeout(timeoutAutoUpdateAnswer);
10430 timeoutAutoUpdateAnswer = setTimeout(() => {
10431 const elQuestionEditMain = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10432 const questionId = elQuestionEditMain.dataset.questionId;
10433 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10434 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10435
10436 // For both radio and checkbox.
10437 const dataAnswersOld = structuredClone(dataAnswers);
10438
10439 // Get position of answers
10440 const elQuestionAnswerItems = elAnswersConfig.querySelectorAll(`${EditQuestion.selectors.elQuestionAnswerItem}:not(.clone)`);
10441 const answersPosition = {};
10442 elQuestionAnswerItems.forEach((elQuestionAnswerItem, index) => {
10443 answersPosition[elQuestionAnswerItem.dataset.answerId] = index + 1; // Start from 1
10444 });
10445
10446 //console.log( 'answersPosition', answersPosition );
10447
10448 dataAnswers.map((answer, k) => {
10449 const elQuestionAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
10450 const elInputAnswerSetTrue = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
10451 const elInputAnswerTitle = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
10452
10453 // Set title
10454 if (elInputAnswerTitle) {
10455 answer.title = elInputAnswerTitle.value.trim();
10456 }
10457
10458 // Set true answer
10459 if (elInputAnswerSetTrue) {
10460 if (elInputAnswerSetTrue.checked) {
10461 answer.is_true = 'yes';
10462 } else {
10463 answer.is_true = '';
10464 }
10465 }
10466
10467 // Set position
10468 if (answersPosition[answer.question_answer_id]) {
10469 answer.order = answersPosition[answer.question_answer_id];
10470 }
10471 return answer;
10472 });
10473
10474 //console.log( dataAnswers );
10475
10476 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
10477
10478 // Call ajax to update answers config
10479 const callBack = {
10480 success: response => {
10481 const {
10482 message,
10483 status
10484 } = response;
10485 if (status === 'success') {} else {
10486 throw `Error: ${message}`;
10487 }
10488 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10489 },
10490 error: error => {
10491 // rollback changes to old data
10492 dataAnswersOld.forEach(answer => {
10493 const elAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
10494 const inputAnswerSetTrue = elAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
10495 if (answer.is_true === 'yes') {
10496 inputAnswerSetTrue.checked = true;
10497 }
10498 return answer;
10499 });
10500 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10501 },
10502 completed: () => {
10503 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
10504 }
10505 };
10506 const dataSend = {
10507 action: 'update_question_answers_config',
10508 question_id: questionId,
10509 answers: dataAnswers,
10510 args: {
10511 id_url: idUrlHandle
10512 }
10513 };
10514 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10515 }, 700);
10516 }
10517
10518 // Sortable answers's question
10519 sortAbleQuestionAnswer(elQuestionEditMain) {
10520 let isUpdateSectionPosition = 0;
10521 let timeout;
10522 const elQuestionAnswers = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elAnswersConfig}`);
10523 elQuestionAnswers.forEach(elAnswersConfig => {
10524 new sortablejs__WEBPACK_IMPORTED_MODULE_3__["default"](elAnswersConfig, {
10525 handle: '.drag',
10526 animation: 150,
10527 onEnd: evt => {
10528 const elQuestionAnswerItem = evt.item;
10529 if (!isUpdateSectionPosition) {
10530 // No change in section position, do nothing
10531 return;
10532 }
10533 clearTimeout(timeout);
10534 timeout = setTimeout(() => {
10535 const elAutoSaveAnswer = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elAutoSaveAnswer}`);
10536 this.autoUpdateAnswer({
10537 e: null,
10538 target: elAutoSaveAnswer
10539 });
10540 }, 1000);
10541 },
10542 onMove: evt => {
10543 clearTimeout(timeout);
10544 },
10545 onUpdate: evt => {
10546 isUpdateSectionPosition = 1;
10547 }
10548 });
10549 });
10550 }
10551
10552 // Delete question answer
10553 deleteQuestionAnswer(args) {
10554 const {
10555 e,
10556 target
10557 } = args;
10558 const elBtnDeleteAnswer = target.closest(`${EditQuestion.selectors.elBtnDeleteAnswer}`);
10559 if (!elBtnDeleteAnswer) {
10560 return;
10561 }
10562 const elQuestionAnswerItem = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
10563 if (!elQuestionAnswerItem) {
10564 return;
10565 }
10566 const elQuestionEditMain = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10567 const questionId = elQuestionEditMain.dataset.questionId;
10568 const questionAnswerId = elQuestionAnswerItem.dataset.answerId;
10569 if (!questionId || !questionAnswerId) {
10570 return;
10571 }
10572 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10573 title: elBtnDeleteAnswer.dataset.title || 'Are you sure?',
10574 text: elBtnDeleteAnswer.dataset.content || 'Do you want to delete this answer?',
10575 icon: 'warning',
10576 showCloseButton: true,
10577 showCancelButton: true,
10578 cancelButtonText: lpData.i18n.cancel,
10579 confirmButtonText: lpData.i18n.yes,
10580 reverseButtons: true
10581 }).then(result => {
10582 if (result.isConfirmed) {
10583 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
10584
10585 // Call ajax to delete item from section
10586 const callBack = {
10587 success: response => {
10588 const {
10589 message,
10590 status
10591 } = response;
10592 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10593 if (status === 'success') {
10594 const elQuestionAnswerId = parseInt(elQuestionAnswerItem.dataset.answerId);
10595 elQuestionAnswerItem.remove();
10596 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10597 if (dataAnswers) {
10598 const updatedAnswers = dataAnswers.filter(answer => parseInt(answer.question_answer_id) !== elQuestionAnswerId);
10599 this.setDataAnswersConfig(elQuestionEditMain, updatedAnswers);
10600 }
10601 }
10602 },
10603 error: error => {
10604 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10605 },
10606 completed: () => {
10607 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
10608 }
10609 };
10610 const dataSend = {
10611 action: 'delete_question_answer',
10612 question_id: questionId,
10613 question_answer_id: questionAnswerId,
10614 args: {
10615 id_url: idUrlHandle
10616 }
10617 };
10618 window.lpAJAXG.fetchAJAX(dataSend, callBack);
10619 }
10620 });
10621 }
10622
10623 // Get data answers config
10624 getDataAnswersConfig(elQuestionEditMain) {
10625 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10626 if (!elAnswersConfig) {
10627 return null;
10628 }
10629 let dataAnswers = elAnswersConfig.dataset.answers || '[]';
10630 try {
10631 dataAnswers = JSON.parse(dataAnswers);
10632 } catch (e) {
10633 dataAnswers = [];
10634 }
10635 if (!dataAnswers.meta_data) {
10636 dataAnswers.meta_data = {};
10637 }
10638 return dataAnswers;
10639 }
10640
10641 // Set data answers config
10642 setDataAnswersConfig(elQuestionEditMain, dataAnswers) {
10643 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10644 if (!elAnswersConfig) {
10645 return;
10646 }
10647 if (!dataAnswers || typeof dataAnswers !== 'object') {
10648 dataAnswers = {};
10649 }
10650 elAnswersConfig.dataset.answers = JSON.stringify(dataAnswers);
10651 }
10652
10653 /***** Fill in the blank question type *****/
10654 // For FIB question type
10655 fibInsertBlank = args => {
10656 const {
10657 e,
10658 target
10659 } = args;
10660 const elBtnFibInsertBlank = target.closest(EditQuestion.selectors.elBtnFibInsertBlank);
10661 if (!elBtnFibInsertBlank) {
10662 return;
10663 }
10664 const textPlaceholder = elBtnFibInsertBlank.dataset.defaultText;
10665 const elQuestionEditMain = elBtnFibInsertBlank.closest(EditQuestion.selectors.elQuestionEditMain);
10666 const questionId = elQuestionEditMain.dataset.questionId;
10667 const messErrInserted = elBtnFibInsertBlank.dataset.messInserted;
10668 const messErrRequireSelectText = elBtnFibInsertBlank.dataset.messRequireSelectText;
10669 const idEditor = `${EditQuestion.selectors.elQuestionFibInput}-${questionId}`;
10670 const uniquid = this.randomString();
10671 let selectedText;
10672 if (fibSelection) {
10673 const elNode = fibSelection.getNode();
10674 if (!elNode) {
10675 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Event insert blank has error, please try again', 'error');
10676 return;
10677 }
10678 const findParent = elNode.closest(`body[data-id="${idEditor}"]`);
10679 if (!findParent) {
10680 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
10681 return;
10682 }
10683 if (elNode.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
10684 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrInserted, 'error');
10685 return;
10686 }
10687 selectedText = fibSelection.getContent();
10688 if (selectedText.length === 0) {
10689 selectedText = textPlaceholder;
10690 }
10691 const elInputNew = `<span class="${EditQuestion.selectors.elQuestionFibInput}" data-id="${uniquid}">${selectedText}</span>`;
10692 fibSelection.setContent(elInputNew);
10693 } else {
10694 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
10695 return;
10696 }
10697 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10698 dataAnswers.meta_data = dataAnswers.meta_data || {};
10699 // Convert array to object
10700 if (Object.keys(dataAnswers.meta_data).length === 0) {
10701 dataAnswers.meta_data = {};
10702 }
10703 dataAnswers.meta_data[uniquid] = {
10704 id: uniquid,
10705 match_case: 0,
10706 comparison: 'equal',
10707 fill: selectedText,
10708 index: 1,
10709 open: false
10710 };
10711 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10712
10713 // Clone blank options
10714 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10715 const elFibBlankOptionItemClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptionItemClone}`);
10716 const elFibBlankOptionItemNew = elFibBlankOptionItemClone.cloneNode(true);
10717 const countOptions = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`).length;
10718 const elFibBlankOptionIndex = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibBlankOptionIndex}`);
10719 const elFibOptionTitleInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10720 const elFibOptionMatchCaseInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
10721 const elFibOptionComparisonInput = elFibBlankOptionItemNew.querySelectorAll(`${EditQuestion.selectors.elFibOptionComparisonInput}`);
10722 elFibBlankOptionItemNew.dataset.id = uniquid;
10723 elFibOptionTitleInput.name = `${EditQuestion.selectors.elFibOptionTitleInput}-${uniquid}`;
10724 elFibOptionTitleInput.value = this.decodeHtml(selectedText);
10725 elFibBlankOptionIndex.textContent = countOptions + 1 + '.';
10726 elFibOptionMatchCaseInput.name = `${EditQuestion.selectors.elFibOptionMatchCaseInput}-${uniquid}`.replace(/\./g, '');
10727 elFibOptionComparisonInput.forEach(elInput => {
10728 elInput.name = `${EditQuestion.selectors.elFibOptionComparisonInput}-${uniquid}`.replace(/\./g, '');
10729 if (elInput.value === 'equal') {
10730 elInput.checked = true;
10731 }
10732 });
10733 elFibBlankOptionItemClone.insertAdjacentElement('beforebegin', elFibBlankOptionItemNew);
10734 elFibBlankOptionItemNew.classList.remove('clone');
10735 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItemNew, 1);
10736 // End clone blank options
10737
10738 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10739 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 1);
10740 this.fibSaveContent({
10741 e: null,
10742 target: elBtnFibSaveContent,
10743 callBackCompleted: () => {
10744 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 0);
10745 }
10746 });
10747 };
10748
10749 // Delete all blanks
10750 fibDeleteAllBlanks(args) {
10751 const {
10752 e,
10753 target
10754 } = args;
10755 const elBtnFibDeleteAllBlanks = target.closest(`${EditQuestion.selectors.elBtnFibDeleteAllBlanks}`);
10756 if (!elBtnFibDeleteAllBlanks) {
10757 return;
10758 }
10759 const elQuestionEditMain = elBtnFibDeleteAllBlanks.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10760 if (!elQuestionEditMain) {
10761 return;
10762 }
10763 const questionId = elQuestionEditMain.dataset.questionId;
10764 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10765 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10766 title: elBtnFibDeleteAllBlanks.dataset.title,
10767 text: elBtnFibDeleteAllBlanks.dataset.content,
10768 icon: 'warning',
10769 showCloseButton: true,
10770 showCancelButton: true,
10771 cancelButtonText: lpData.i18n.cancel,
10772 confirmButtonText: lpData.i18n.yes,
10773 reverseButtons: true
10774 }).then(result => {
10775 if (result.isConfirmed) {
10776 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10777 const elBlanks = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}`);
10778 elBlanks.forEach(elBlank => {
10779 editor.dom.remove(elBlank, true);
10780 });
10781 dataAnswers.meta_data = {};
10782 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10783 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10784 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10785 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10786 elFibBlankOptionItem.remove();
10787 });
10788 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10789 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 1);
10790 this.fibSaveContent({
10791 e: null,
10792 target: elBtnFibSaveContent,
10793 callBackCompleted: () => {
10794 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 0);
10795 }
10796 });
10797 }
10798 });
10799 }
10800 // Clear content FIB question
10801 fibClearContent(args) {
10802 const {
10803 e,
10804 target
10805 } = args;
10806 const elBtnFibClearAllContent = target.closest(`${EditQuestion.selectors.elBtnFibClearAllContent}`);
10807 if (!elBtnFibClearAllContent) {
10808 return;
10809 }
10810 const elQuestionEditMain = elBtnFibClearAllContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10811 if (!elQuestionEditMain) {
10812 return;
10813 }
10814 const questionId = elQuestionEditMain.dataset.questionId;
10815 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10816 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10817 title: elBtnFibClearAllContent.dataset.title,
10818 text: elBtnFibClearAllContent.dataset.content,
10819 icon: 'warning',
10820 showCloseButton: true,
10821 showCancelButton: true,
10822 cancelButtonText: lpData.i18n.cancel,
10823 confirmButtonText: lpData.i18n.yes,
10824 reverseButtons: true
10825 }).then(result => {
10826 if (result.isConfirmed) {
10827 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
10828 editor.setContent('');
10829 dataAnswers.meta_data = {};
10830 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10831 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
10832 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10833 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10834 elFibBlankOptionItem.remove();
10835 });
10836 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10837 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 1);
10838 this.fibSaveContent({
10839 e: null,
10840 target: elBtnFibSaveContent,
10841 callBackCompleted: () => {
10842 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 0);
10843 }
10844 });
10845 }
10846 });
10847 }
10848
10849 // Remove blank
10850 fibDeleteBlank(args) {
10851 const {
10852 e,
10853 target
10854 } = args;
10855 const elBtnFibOptionDelete = target.closest(`${EditQuestion.selectors.elBtnFibOptionDelete}`);
10856 if (!elBtnFibOptionDelete) {
10857 return;
10858 }
10859 const elQuestionEditMain = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10860 if (!elQuestionEditMain) {
10861 return;
10862 }
10863 const questionId = elQuestionEditMain.dataset.questionId;
10864 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
10865 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10866 const elFibBlankOptionItem = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
10867 const blankId = elFibBlankOptionItem.dataset.id;
10868 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
10869 title: elBtnFibOptionDelete.dataset.title,
10870 text: elBtnFibOptionDelete.dataset.content,
10871 icon: 'warning',
10872 showCloseButton: true,
10873 showCancelButton: true,
10874 cancelButtonText: lpData.i18n.cancel,
10875 confirmButtonText: lpData.i18n.yes,
10876 reverseButtons: true
10877 }).then(result => {
10878 if (result.isConfirmed) {
10879 // Find span with id on editor and remove it
10880 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10881 const elBlank = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${blankId}"]`);
10882 if (elBlank[0]) {
10883 // Remove tag html but keep content
10884 editor.dom.remove(elBlank[0], true);
10885 }
10886 elFibBlankOptionItem.remove();
10887 dataAnswers.meta_data = dataAnswers.meta_data || {};
10888 if (dataAnswers.meta_data[blankId]) {
10889 delete dataAnswers.meta_data[blankId];
10890 }
10891 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10892 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10893 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 1);
10894 this.fibSaveContent({
10895 e: null,
10896 target: elBtnFibSaveContent,
10897 callBackCompleted: () => {
10898 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 0);
10899 }
10900 });
10901 }
10902 });
10903 }
10904
10905 // Change title of blank option
10906 fibOptionTitleInputChange(args) {
10907 const {
10908 e,
10909 target
10910 } = args;
10911 const elFibOptionTitleInput = target.closest(`${EditQuestion.selectors.elFibOptionTitleInput}`);
10912 if (!elFibOptionTitleInput) {
10913 return;
10914 }
10915 const elQuestionFibOptionItem = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
10916 if (!elQuestionFibOptionItem) {
10917 return;
10918 }
10919 const elQuestionEditMain = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10920 if (!elQuestionEditMain) {
10921 return;
10922 }
10923 const value = elFibOptionTitleInput.value.trim();
10924 const blankId = elQuestionFibOptionItem.dataset.id;
10925 const questionId = elQuestionEditMain.dataset.questionId;
10926 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
10927 const elBlank = editor.dom.select(`.lp-question-fib-input[data-id="${blankId}"]`);
10928 if (elBlank[0]) {
10929 // Update content of blank
10930 elBlank[0].textContent = value;
10931 }
10932 clearTimeout(timeoutAutoUpdateFib);
10933 timeoutAutoUpdateFib = setTimeout(() => {
10934 // Call ajax to update question description
10935 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10936 this.fibSaveContent({
10937 e: null,
10938 target: elBtnFibSaveContent
10939 });
10940 }, 700);
10941 }
10942
10943 // Save content FIB question
10944 fibSaveContent(args) {
10945 const {
10946 e,
10947 target,
10948 callBackCompleted = null
10949 } = args;
10950 const elBtnFibSaveContent = target.closest(`${EditQuestion.selectors.elBtnFibSaveContent}`);
10951 if (!elBtnFibSaveContent) {
10952 return;
10953 }
10954 const elQuestionEditMain = elBtnFibSaveContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
10955 const questionId = elQuestionEditMain.dataset.questionId;
10956 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
10957 if (!dataAnswers) {
10958 return;
10959 }
10960 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
10961 dataAnswers.title = editor.getContent();
10962 const elFibBlankOptionItems = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
10963 if (elFibBlankOptionItems) {
10964 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
10965 const blankId = elFibBlankOptionItem.dataset.id;
10966 const elFibOptionMatchCaseInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
10967 const elFibOptionComparisonInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionComparisonInput}:checked`);
10968 dataAnswers.meta_data[blankId].match_case = elFibOptionMatchCaseInput.checked ? 1 : 0;
10969 dataAnswers.meta_data[blankId].comparison = elFibOptionComparisonInput.value;
10970 });
10971 }
10972
10973 //console.log( 'dataAnswers', dataAnswers );
10974
10975 if (!callBackCompleted) {
10976 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 1);
10977 }
10978
10979 // Call ajax to update answers config
10980 const callBack = {
10981 success: response => {
10982 const {
10983 message,
10984 status
10985 } = response;
10986 if (status === 'success') {
10987 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
10988 } else {
10989 throw `Error: ${message}`;
10990 }
10991 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
10992 },
10993 error: error => {
10994 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
10995 },
10996 completed: () => {
10997 if (callBackCompleted && typeof callBackCompleted === 'function') {
10998 callBackCompleted();
10999 } else {
11000 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 0);
11001 }
11002 }
11003 };
11004
11005 //console.log( 'dataAnswers', dataAnswers );
11006
11007 const dataSend = {
11008 action: 'update_question_answers_config',
11009 question_id: questionId,
11010 answers: dataAnswers,
11011 args: {
11012 id_url: idUrlHandle
11013 }
11014 };
11015 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11016 }
11017 // Show/hide match case option
11018 fibShowHideMatchCaseOption(args) {
11019 const {
11020 e,
11021 target
11022 } = args;
11023 const elFibOptionMatchCaseInput = target.closest(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
11024 if (!elFibOptionMatchCaseInput) {
11025 return;
11026 }
11027 const elQuestionFibOptionDetail = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionFibOptionDetail}`);
11028 const elFibOptionMatchCaseWrap = elQuestionFibOptionDetail.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseWrap}`);
11029 if (!elQuestionFibOptionDetail || !elFibOptionMatchCaseWrap) {
11030 return;
11031 }
11032 if (elFibOptionMatchCaseInput.checked) {
11033 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 1);
11034 } else {
11035 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 0);
11036 }
11037 const elQuestionEditMain = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
11038 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
11039 elBtnFibSaveContent.click();
11040 }
11041 /***** End Fill in the blank question type *****/
11042
11043 // Generate a random string of specified length, for set unique id
11044 randomString(length = 10) {
11045 const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
11046 let result = '';
11047 for (let i = 0; i < length; i++) {
11048 result += chars.charAt(Math.floor(Math.random() * chars.length));
11049 }
11050 return result;
11051 }
11052 // Decode HTML entities
11053 decodeHtml(html) {
11054 const txt = document.createElement('textarea');
11055 txt.innerHTML = html;
11056 return txt.value;
11057 }
11058 }
11059 const editQuestion = new EditQuestion();
11060 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuestion.selectors.elEditQuestionWrap, elEditQuestionWrap => {
11061 const findClass = EditQuestion.selectors.elQuestionEditMain.replace('.', '');
11062 if (!elEditQuestionWrap.classList.contains(findClass)) {
11063 return;
11064 }
11065 editQuestion.init();
11066 });
11067 })();
11068
11069 /******/ })()
11070 ;
11071 //# sourceMappingURL=edit-question.js.map