PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.9
4.4.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-quiz.js

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

11,967 lines 429.7 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/admin/edit-question.js"
5 /*!**********************************************!*\
6 !*** ./assets/src/js/admin/edit-question.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 */ EditQuestion: () => (/* binding */ EditQuestion)
14 /* harmony export */ });
15 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
16 /* harmony import */ var lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify */ "./assets/src/js/lpToastify.js");
17 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
18 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
19 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
20 /**
21 * Edit question JS handler.
22 *
23 * @since 4.2.9
24 * @version 1.0.0
25 */
26
27
28
29
30
31 const idUrlHandle = 'edit-question';
32 let fibSelection;
33 let timeoutAutoUpdateAnswer, timeoutAutoUpdateFib, timeoutAutoUpdateQuestion;
34
35 // EditQuestion class
36 class EditQuestion {
37 static selectors = {
38 elEditQuestionWrap: '.lp-edit-question-wrap',
39 elQuestionEditMain: '.lp-question-edit-main',
40 elQuestionToggleAll: '.lp-question-toggle-all',
41 elEditListQuestions: '.lp-edit-list-questions',
42 elQuestionToggle: '.lp-question-toggle',
43 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
44 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
45 elBtnAddQuestion: '.lp-btn-add-question',
46 elBtnRemoveQuestion: '.lp-btn-remove-question',
47 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
48 elBtnUpdateQuestionDes: '.lp-btn-update-question-des',
49 elBtnUpdateQuestionHint: '.lp-btn-update-question-hint',
50 elBtnUpdateQuestionExplain: '.lp-btn-update-question-explanation',
51 elQuestionTitleNewInput: '.lp-question-title-new-input',
52 elQuestionTitleInput: '.lp-question-title-input',
53 elQuestionTypeLabel: '.lp-question-type-label',
54 elQuestionTypeNew: '.lp-question-type-new',
55 elAddNewQuestion: 'add-new-question',
56 elQuestionClone: '.lp-question-item.clone',
57 elAnswersConfig: '.lp-answers-config',
58 elBtnAddAnswer: '.lp-btn-add-question-answer',
59 elQuestionAnswerItemAddNew: '.lp-question-answer-item-add-new',
60 elQuestionAnswerTitleNewInput: '.lp-question-answer-title-new-input',
61 elQuestionAnswerTitleInput: '.lp-question-answer-title-input',
62 elBtnDeleteAnswer: '.lp-btn-delete-question-answer',
63 elQuestionByType: '.lp-question-by-type',
64 elInputAnswerSetTrue: '.lp-input-answer-set-true',
65 elQuestionAnswerItem: '.lp-question-answer-item',
66 elBtnUpdateQuestionAnswer: '.lp-btn-update-question-answer',
67 elBtnFibInsertBlank: '.lp-btn-fib-insert-blank',
68 elBtnFibDeleteAllBlanks: '.lp-btn-fib-delete-all-blanks',
69 elBtnFibSaveContent: '.lp-btn-fib-save-content',
70 elBtnFibClearAllContent: '.lp-btn-fib-clear-all-content',
71 elFibOptionTitleInput: '.lp-question-fib-option-title-input',
72 elFibBlankOptions: '.lp-question-fib-blank-options',
73 elFibBlankOptionItem: '.lp-question-fib-blank-option-item',
74 elFibBlankOptionItemClone: '.lp-question-fib-blank-option-item.clone',
75 elFibBlankOptionIndex: '.lp-question-fib-option-index',
76 elBtnFibOptionDelete: '.lp-btn-fib-option-delete',
77 elFibOptionMatchCaseWrap: '.lp-question-fib-option-match-case-wrap',
78 elFibOptionMatchCaseInput: '.lp-question-fib-option-match-case-input',
79 elQuestionFibOptionDetail: '.lp-question-fib-option-detail',
80 elFibOptionComparisonInput: '.lp-question-fib-option-comparison-input',
81 elAutoSaveFib: '.lp-auto-save-fib',
82 LPTarget: '.lp-target',
83 elCollapse: 'lp-collapse',
84 elSectionToggle: '.lp-section-toggle',
85 elTriggerToggle: '.lp-trigger-toggle',
86 elAutoSaveQuestion: '.lp-auto-save-question',
87 elAutoSaveAnswer: '.lp-auto-save-question-answer',
88 elQuestionFibInput: 'lp-question-fib-input',
89 elBtnQuestionCreateType: '.lp-btn-question-create-type'
90 };
91 constructor() {}
92 init() {
93 this.events();
94 this.initTinyMCE().then();
95 }
96 events() {
97 if (EditQuestion._loadedEvents) {
98 return;
99 }
100 EditQuestion._loadedEvents = true;
101
102 // Sortable answers's question
103 const elQuestionEditMains = document.querySelectorAll(`${EditQuestion.selectors.elQuestionEditMain}`);
104 elQuestionEditMains.forEach(elQuestionEditMain => {
105 this.sortAbleQuestionAnswer(elQuestionEditMain);
106 });
107 // End sortable
108
109 // Event click
110 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
111 selector: EditQuestion.selectors.elBtnQuestionCreateType,
112 callBack: this.createQuestionType.name,
113 class: this
114 }, {
115 selector: EditQuestion.selectors.elBtnAddAnswer,
116 callBack: this.addQuestionAnswer.name,
117 class: this
118 }, {
119 selector: EditQuestion.selectors.elBtnDeleteAnswer,
120 callBack: this.deleteQuestionAnswer.name,
121 class: this
122 }, {
123 selector: EditQuestion.selectors.elBtnFibInsertBlank,
124 callBack: this.fibInsertBlank.name,
125 class: this
126 }, {
127 selector: EditQuestion.selectors.elBtnFibDeleteAllBlanks,
128 callBack: this.fibDeleteAllBlanks.name,
129 class: this
130 }, {
131 selector: EditQuestion.selectors.elBtnFibSaveContent,
132 callBack: this.fibSaveContent.name,
133 class: this
134 }, {
135 selector: EditQuestion.selectors.elBtnFibClearAllContent,
136 callBack: this.fibClearContent.name,
137 class: this
138 }, {
139 selector: EditQuestion.selectors.elBtnFibOptionDelete,
140 callBack: this.fibDeleteBlank.name,
141 class: this
142 }, {
143 selector: EditQuestion.selectors.elFibOptionMatchCaseInput,
144 callBack: this.fibShowHideMatchCaseOption.name,
145 class: this
146 }, {
147 selector: EditQuestion.selectors.elFibOptionComparisonInput,
148 callBack: args => {
149 const {
150 e,
151 target
152 } = args;
153 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
154 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
155 elBtnFibSaveContent.click();
156 }
157 }]);
158
159 // Toggle collapse
160 document.addEventListener('click', e => {
161 const target = e.target;
162 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuestion.selectors.elTriggerToggle);
163 });
164
165 // Event keyup
166 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
167 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
168 callBack: this.checkCanAddAnswer.name,
169 class: this
170 }, {
171 selector: EditQuestion.selectors.elFibOptionTitleInput,
172 callBack: this.fibOptionTitleInputChange.name,
173 class: this
174 }, {
175 selector: EditQuestion.selectors.elAutoSaveQuestion,
176 callBack: this.autoUpdateQuestion.name,
177 class: this
178 }]);
179
180 // Event keydown
181 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
182 selector: EditQuestion.selectors.elQuestionAnswerTitleNewInput,
183 callBack: this.addQuestionAnswer.name,
184 class: this,
185 checkIsEventEnter: true
186 }]);
187
188 // Event change
189 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
190 selector: EditQuestion.selectors.elAutoSaveAnswer,
191 callBack: this.autoUpdateAnswer.name,
192 class: this
193 }]);
194
195 // TinyMCE events
196 this.eventEditorTinymce();
197 }
198
199 // Run async to re-init all TinyMCE editors, because it slow if have many editors
200 async initTinyMCE() {
201 const elTextareas = document.querySelectorAll('.lp-editor-tinymce');
202 elTextareas.forEach(elTextarea => {
203 const idTextarea = elTextarea.id;
204 this.reInitTinymce(idTextarea);
205 });
206 }
207 reInitTinymce(id) {
208 if (!window.tinymce || !id) {
209 return;
210 }
211 const elTextarea = document.getElementById(id);
212 if (!elTextarea) {
213 return;
214 }
215 this.reInitQuicktags(id);
216 const editor = window.tinymce.get(id);
217 const editorContainer = editor?.getContainer?.();
218 const isEditorAttached = editor && (editor.targetElm === elTextarea || editor.getElement?.() === elTextarea || editorContainer?.contains(elTextarea));
219 if (isEditorAttached) {
220 this.setDefaultEditorTab(id);
221 return;
222 }
223 window.tinymce.execCommand('mceRemoveEditor', true, id);
224 window.tinymce.execCommand('mceAddEditor', true, id);
225 this.setDefaultEditorTab(id);
226 }
227 reInitQuicktags(id) {
228 const toolbar = document.getElementById(`qt_${id}_toolbar`);
229 if (!toolbar || toolbar.children.length || !window.quicktags) {
230 return;
231 }
232 const settings = window.tinyMCEPreInit?.qtInit?.[id] || {
233 id
234 };
235 window.quicktags(settings);
236 if (window.QTags?._buttonsInit) {
237 window.QTags._buttonsInit();
238 }
239 }
240 setDefaultEditorTab(id) {
241 const wrapEditor = document.getElementById(`wp-${id}-wrap`);
242 if (!wrapEditor) {
243 return;
244 }
245 if (wrapEditor.classList.contains('html-active') && window.switchEditors?.go) {
246 window.switchEditors.go(id, 'tmce');
247 }
248 wrapEditor.classList.add('tmce-active');
249 wrapEditor.classList.remove('html-active');
250 const visualTab = document.getElementById(`${id}-tmce`);
251 const codeTab = document.getElementById(`${id}-html`);
252 visualTab?.setAttribute('aria-pressed', 'true');
253 codeTab?.setAttribute('aria-pressed', 'false');
254 }
255
256 // Events for TinyMCE editor
257 eventEditorTinymce() {
258 window.tinymce.on('AddEditor', eEditor => {
259 const id = eEditor.editor.id;
260 const editor = window.tinymce.get(id);
261 if (!editor) {
262 return;
263 }
264 if (id === 'content') {
265 return;
266 }
267 this.setDefaultEditorTab(id);
268 const elTextarea = document.getElementById(id);
269 if (!elTextarea) {
270 return;
271 }
272 const elQuestionEditMain = elTextarea.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
273
274 // Skip if not in question edit context
275 if (!elQuestionEditMain) {
276 return;
277 }
278 const questionId = elQuestionEditMain.dataset.questionId;
279 editor.settings.force_p_newlines = false;
280 editor.settings.forced_root_block = '';
281 editor.settings.force_br_newlines = true;
282
283 // Config use absolute url
284 editor.settings.relative_urls = false;
285 editor.settings.remove_script_host = false;
286 editor.settings.convert_urls = true;
287 editor.settings.document_base_url = lpData.site_url;
288 // End config use absolute url
289
290 // Events focus in TinyMCE editor
291 editor.on('change keyup', e => {
292 // Auto save if it has class lp-auto-save
293 elTextarea.value = editor.getContent();
294 this.autoUpdateQuestion({
295 e,
296 target: elTextarea
297 });
298 });
299 editor.on('blur', e => {
300 //console.log( 'Editor blurred:', e.target.id );
301 });
302 editor.on('focusin', e => {});
303 editor.on('init', () => {
304 // Add style
305 editor.dom.addStyle(`
306 body {
307 line-height: 2.2 !important;
308 }
309 .${EditQuestion.selectors.elQuestionFibInput} {
310 border: 1px dashed rebeccapurple;
311 padding: 5px;
312 }
313 `);
314 });
315 editor.on('setcontent', e => {
316 const uniquid = this.randomString();
317 const elementg = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${uniquid}"]`);
318 if (elementg[0]) {
319 elementg[0].focus();
320 }
321 editor.dom.bind(elementg[0], 'input', e => {
322 //console.log( 'Input changed:', e.target.value );
323 });
324 });
325 editor.on('selectionchange', e => {
326 fibSelection = editor.selection;
327
328 // Check selection is blank, check empty blank content
329 if (fibSelection.getNode().classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
330 const blankId = fibSelection.getNode().dataset.id;
331 const textBlank = fibSelection.getNode().textContent.trim();
332 if (textBlank.length === 0) {
333 const editorId = editor.id;
334 const questionId = editorId.replace(`${EditQuestion.selectors.elQuestionFibInput}-`, '');
335 const elQuestionEditMain = document.querySelector(`${EditQuestion.selectors.elQuestionEditMain}[data-question-id="${questionId}"]`);
336 const elQuestionBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
337 const elFibBlankOptionItem = elQuestionBlankOptions.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
338 if (elFibBlankOptionItem) {
339 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 0);
340 }
341 } else {
342 const elTextarea = document.getElementById(id);
343 const elAnswersConfig = elTextarea.closest(`${EditQuestion.selectors.elAnswersConfig}`);
344 const elFibBlankOptionItem = elAnswersConfig.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
345 if (elFibBlankOptionItem) {
346 const elFibOptionTitleInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
347 if (elFibOptionTitleInput) {
348 elFibOptionTitleInput.value = textBlank;
349 }
350 }
351 }
352 }
353 });
354 editor.on('Undo', e => {
355 const contentUndo = editor.getContent();
356 const selection = editor.selection;
357 const nodeUndo = selection.getNode();
358 if (nodeUndo.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
359 const blankId = nodeUndo.dataset.id;
360 const elFibBlankOptionItem = document.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
361 if (elFibBlankOptionItem) {
362 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 1);
363 }
364 }
365 });
366 editor.on('Redo', e => {});
367 });
368 }
369 autoUpdateQuestion(args) {
370 let {
371 e,
372 target,
373 key,
374 value
375 } = args;
376 const elAutoSave = target.closest(`${EditQuestion.selectors.elAutoSaveQuestion}`);
377 if (!elAutoSave) {
378 return;
379 }
380 const elQuestionEditMain = elAutoSave.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
381 const questionId = elQuestionEditMain.dataset.questionId;
382 clearTimeout(timeoutAutoUpdateQuestion);
383 timeoutAutoUpdateQuestion = setTimeout(() => {
384 // Call ajax to update question description
385 const callBack = {
386 success: response => {
387 const {
388 message,
389 status
390 } = response;
391 if (status === 'success') {
392 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
393 } else {
394 throw `Error: ${message}`;
395 }
396 },
397 error: error => {
398 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
399 },
400 completed: () => {}
401 };
402 const dataSend = {
403 action: 'update_question',
404 question_id: questionId,
405 args: {
406 id_url: idUrlHandle
407 }
408 };
409 if (undefined === key) {
410 key = elAutoSave.dataset.keyAutoSave;
411 if (!key) {
412 if (!elAutoSave.classList.contains('lp-editor-tinymce')) {
413 return;
414 }
415 const textAreaId = elAutoSave.id;
416 key = textAreaId.replace(/lp-/g, '').replace(`-${questionId}`, '').replace(/-/g, '_');
417 if (!key) {
418 return;
419 }
420 }
421 value = elAutoSave.value;
422 }
423 dataSend[key] = value;
424 window.lpAJAXG.fetchAJAX(dataSend, callBack);
425 }, 700);
426 }
427 // Create question type
428 createQuestionType(args) {
429 const {
430 e,
431 target
432 } = args;
433 const elBtnQuestionCreateType = target.closest(`${EditQuestion.selectors.elBtnQuestionCreateType}`);
434 if (!elBtnQuestionCreateType) {
435 return;
436 }
437 const elQuestionEditMain = elBtnQuestionCreateType.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
438 if (!elQuestionEditMain) {
439 return;
440 }
441 const questionId = elQuestionEditMain.dataset.questionId;
442 const elQuestionTypeNew = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionTypeNew}`);
443 if (!elQuestionTypeNew) {
444 return;
445 }
446 const questionType = elQuestionTypeNew.value.trim();
447 if (!questionType) {
448 const message = elQuestionTypeNew.dataset.messEmptyType;
449 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
450 return;
451 }
452
453 // Call ajax to create new question type
454 const callBack = {
455 success: response => {
456 const {
457 message,
458 status,
459 data
460 } = response;
461 if (status === 'success') {
462 const {
463 html_option_answers
464 } = data;
465 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
466 elAnswersConfig.outerHTML = html_option_answers;
467 this.initTinyMCE();
468 this.sortAbleQuestionAnswer(elQuestionEditMain);
469 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
470 } else {
471 throw `Error: ${message}`;
472 }
473 },
474 error: error => {
475 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
476 },
477 completed: () => {}
478 };
479 const dataSend = {
480 action: 'update_question',
481 question_id: questionId,
482 question_type: questionType,
483 args: {
484 id_url: idUrlHandle
485 }
486 };
487 window.lpAJAXG.fetchAJAX(dataSend, callBack);
488 }
489 addQuestionAnswer(args) {
490 const {
491 e,
492 target
493 } = args;
494 const elQuestionAnswerItemAddNew = target.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
495 if (!elQuestionAnswerItemAddNew) {
496 return;
497 }
498 e.preventDefault();
499 const elQuestionAnswerTitleNewInput = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleNewInput}`);
500 if (!elQuestionAnswerTitleNewInput.value.trim()) {
501 const message = elQuestionAnswerTitleNewInput.dataset.messEmptyTitle;
502 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
503 return;
504 }
505 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
506 const elQuestionAnswerClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}.clone`);
507 const elQuestionAnswerNew = elQuestionAnswerClone.cloneNode(true);
508 const elQuestionAnswerTitleInputNew = elQuestionAnswerNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
509 elQuestionAnswerNew.classList.remove('clone');
510 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionAnswerNew, 1);
511 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 1);
512 elQuestionAnswerClone.insertAdjacentElement('beforebegin', elQuestionAnswerNew);
513 const answerTitle = elQuestionAnswerTitleNewInput.value.trim();
514 elQuestionAnswerTitleInputNew.value = answerTitle;
515 elQuestionAnswerTitleNewInput.value = '';
516 const questionId = elQuestionEditMain.dataset.questionId;
517
518 // Call ajax to add new question answer
519 const callBack = {
520 success: response => {
521 const {
522 message,
523 status,
524 data
525 } = response;
526 if (status === 'success') {
527 const {
528 question_answer
529 } = data;
530 elQuestionAnswerNew.dataset.answerId = question_answer.question_answer_id;
531 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 0);
532
533 // Set data lp-answers-config
534 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
535 dataAnswers.push(question_answer);
536 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
537 } else {
538 throw `Error: ${message}`;
539 }
540 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
541 },
542 error: error => {
543 elQuestionAnswerNew.remove();
544 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
545 },
546 completed: () => {}
547 };
548 const dataSend = {
549 action: 'add_question_answer',
550 question_id: questionId,
551 answer_title: answerTitle,
552 args: {
553 id_url: idUrlHandle
554 }
555 };
556 window.lpAJAXG.fetchAJAX(dataSend, callBack);
557 }
558
559 // Check to enable or disable add new question button
560 checkCanAddAnswer(args) {
561 const {
562 e,
563 target
564 } = args;
565 const elTrigger = target.closest(EditQuestion.selectors.elQuestionAnswerTitleNewInput);
566 if (!elTrigger) {
567 return;
568 }
569 const elQuestionAnswerItemAddNew = elTrigger.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
570 if (!elQuestionAnswerItemAddNew) {
571 return;
572 }
573 const elBtnAddAnswer = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elBtnAddAnswer}`);
574 if (!elBtnAddAnswer) {
575 return;
576 }
577 const titleValue = elTrigger.value.trim();
578 if (titleValue) {
579 elBtnAddAnswer.classList.add('active');
580 } else {
581 elBtnAddAnswer.classList.remove('active');
582 }
583 }
584
585 // Auto update question answer
586 autoUpdateAnswer(args) {
587 const {
588 e,
589 target
590 } = args;
591 const elAutoSaveAnswer = target.closest(`${EditQuestion.selectors.elAutoSaveAnswer}`);
592 if (!elAutoSaveAnswer) {
593 return;
594 }
595 const elQuestionAnswerItem = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
596 clearTimeout(timeoutAutoUpdateAnswer);
597 timeoutAutoUpdateAnswer = setTimeout(() => {
598 const elQuestionEditMain = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
599 const questionId = elQuestionEditMain.dataset.questionId;
600 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
601 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
602
603 // For both radio and checkbox.
604 const dataAnswersOld = structuredClone(dataAnswers);
605
606 // Get position of answers
607 const elQuestionAnswerItems = elAnswersConfig.querySelectorAll(`${EditQuestion.selectors.elQuestionAnswerItem}:not(.clone)`);
608 const answersPosition = {};
609 elQuestionAnswerItems.forEach((elQuestionAnswerItem, index) => {
610 answersPosition[elQuestionAnswerItem.dataset.answerId] = index + 1; // Start from 1
611 });
612
613 //console.log( 'answersPosition', answersPosition );
614
615 dataAnswers.map((answer, k) => {
616 const elQuestionAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
617 const elInputAnswerSetTrue = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
618 const elInputAnswerTitle = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
619
620 // Set title
621 if (elInputAnswerTitle) {
622 answer.title = elInputAnswerTitle.value.trim();
623 }
624
625 // Set true answer
626 if (elInputAnswerSetTrue) {
627 if (elInputAnswerSetTrue.checked) {
628 answer.is_true = 'yes';
629 } else {
630 answer.is_true = '';
631 }
632 }
633
634 // Set position
635 if (answersPosition[answer.question_answer_id]) {
636 answer.order = answersPosition[answer.question_answer_id];
637 }
638 return answer;
639 });
640
641 //console.log( dataAnswers );
642
643 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
644
645 // Call ajax to update answers config
646 const callBack = {
647 success: response => {
648 const {
649 message,
650 status
651 } = response;
652 if (status === 'success') {} else {
653 throw `Error: ${message}`;
654 }
655 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
656 },
657 error: error => {
658 // rollback changes to old data
659 dataAnswersOld.forEach(answer => {
660 const elAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
661 const inputAnswerSetTrue = elAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
662 if (answer.is_true === 'yes') {
663 inputAnswerSetTrue.checked = true;
664 }
665 return answer;
666 });
667 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
668 },
669 completed: () => {
670 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
671 }
672 };
673 const dataSend = {
674 action: 'update_question_answers_config',
675 question_id: questionId,
676 answers: dataAnswers,
677 args: {
678 id_url: idUrlHandle
679 }
680 };
681 window.lpAJAXG.fetchAJAX(dataSend, callBack);
682 }, 700);
683 }
684
685 // Sortable answers's question
686 sortAbleQuestionAnswer(elQuestionEditMain) {
687 let isUpdateSectionPosition = 0;
688 let timeout;
689 const elQuestionAnswers = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elAnswersConfig}`);
690 elQuestionAnswers.forEach(elAnswersConfig => {
691 new sortablejs__WEBPACK_IMPORTED_MODULE_3__["default"](elAnswersConfig, {
692 handle: '.drag',
693 animation: 150,
694 onEnd: evt => {
695 const elQuestionAnswerItem = evt.item;
696 if (!isUpdateSectionPosition) {
697 // No change in section position, do nothing
698 return;
699 }
700 clearTimeout(timeout);
701 timeout = setTimeout(() => {
702 const elAutoSaveAnswer = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elAutoSaveAnswer}`);
703 this.autoUpdateAnswer({
704 e: null,
705 target: elAutoSaveAnswer
706 });
707 }, 1000);
708 },
709 onMove: evt => {
710 clearTimeout(timeout);
711 },
712 onUpdate: evt => {
713 isUpdateSectionPosition = 1;
714 }
715 });
716 });
717 }
718
719 // Delete question answer
720 deleteQuestionAnswer(args) {
721 const {
722 e,
723 target
724 } = args;
725 const elBtnDeleteAnswer = target.closest(`${EditQuestion.selectors.elBtnDeleteAnswer}`);
726 if (!elBtnDeleteAnswer) {
727 return;
728 }
729 const elQuestionAnswerItem = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
730 if (!elQuestionAnswerItem) {
731 return;
732 }
733 const elQuestionEditMain = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
734 const questionId = elQuestionEditMain.dataset.questionId;
735 const questionAnswerId = elQuestionAnswerItem.dataset.answerId;
736 if (!questionId || !questionAnswerId) {
737 return;
738 }
739 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
740 title: elBtnDeleteAnswer.dataset.title || 'Are you sure?',
741 text: elBtnDeleteAnswer.dataset.content || 'Do you want to delete this answer?',
742 icon: 'warning',
743 showCloseButton: true,
744 showCancelButton: true,
745 cancelButtonText: lpData.i18n.cancel,
746 confirmButtonText: lpData.i18n.yes,
747 reverseButtons: true
748 }).then(result => {
749 if (result.isConfirmed) {
750 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
751
752 // Call ajax to delete item from section
753 const callBack = {
754 success: response => {
755 const {
756 message,
757 status
758 } = response;
759 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
760 if (status === 'success') {
761 const elQuestionAnswerId = parseInt(elQuestionAnswerItem.dataset.answerId);
762 elQuestionAnswerItem.remove();
763 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
764 if (dataAnswers) {
765 const updatedAnswers = dataAnswers.filter(answer => parseInt(answer.question_answer_id) !== elQuestionAnswerId);
766 this.setDataAnswersConfig(elQuestionEditMain, updatedAnswers);
767 }
768 }
769 },
770 error: error => {
771 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
772 },
773 completed: () => {
774 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
775 }
776 };
777 const dataSend = {
778 action: 'delete_question_answer',
779 question_id: questionId,
780 question_answer_id: questionAnswerId,
781 args: {
782 id_url: idUrlHandle
783 }
784 };
785 window.lpAJAXG.fetchAJAX(dataSend, callBack);
786 }
787 });
788 }
789
790 // Get data answers config
791 getDataAnswersConfig(elQuestionEditMain) {
792 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
793 if (!elAnswersConfig) {
794 return null;
795 }
796 let dataAnswers = elAnswersConfig.dataset.answers || '[]';
797 try {
798 dataAnswers = JSON.parse(dataAnswers);
799 } catch (e) {
800 dataAnswers = [];
801 }
802 if (!dataAnswers.meta_data) {
803 dataAnswers.meta_data = {};
804 }
805 return dataAnswers;
806 }
807
808 // Set data answers config
809 setDataAnswersConfig(elQuestionEditMain, dataAnswers) {
810 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
811 if (!elAnswersConfig) {
812 return;
813 }
814 if (!dataAnswers || typeof dataAnswers !== 'object') {
815 dataAnswers = {};
816 }
817 elAnswersConfig.dataset.answers = JSON.stringify(dataAnswers);
818 }
819
820 /***** Fill in the blank question type *****/
821 // For FIB question type
822 fibInsertBlank = args => {
823 const {
824 e,
825 target
826 } = args;
827 const elBtnFibInsertBlank = target.closest(EditQuestion.selectors.elBtnFibInsertBlank);
828 if (!elBtnFibInsertBlank) {
829 return;
830 }
831 const textPlaceholder = elBtnFibInsertBlank.dataset.defaultText;
832 const elQuestionEditMain = elBtnFibInsertBlank.closest(EditQuestion.selectors.elQuestionEditMain);
833 const questionId = elQuestionEditMain.dataset.questionId;
834 const messErrInserted = elBtnFibInsertBlank.dataset.messInserted;
835 const messErrRequireSelectText = elBtnFibInsertBlank.dataset.messRequireSelectText;
836 const idEditor = `${EditQuestion.selectors.elQuestionFibInput}-${questionId}`;
837 const uniquid = this.randomString();
838 let selectedText;
839 if (fibSelection) {
840 const elNode = fibSelection.getNode();
841 if (!elNode) {
842 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Event insert blank has error, please try again', 'error');
843 return;
844 }
845 const findParent = elNode.closest(`body[data-id="${idEditor}"]`);
846 if (!findParent) {
847 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
848 return;
849 }
850 if (elNode.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
851 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrInserted, 'error');
852 return;
853 }
854 selectedText = fibSelection.getContent();
855 if (selectedText.length === 0) {
856 selectedText = textPlaceholder;
857 }
858 const elInputNew = `<span class="${EditQuestion.selectors.elQuestionFibInput}" data-id="${uniquid}">${selectedText}</span>`;
859 fibSelection.setContent(elInputNew);
860 } else {
861 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
862 return;
863 }
864 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
865 dataAnswers.meta_data = dataAnswers.meta_data || {};
866 // Convert array to object
867 if (Object.keys(dataAnswers.meta_data).length === 0) {
868 dataAnswers.meta_data = {};
869 }
870 dataAnswers.meta_data[uniquid] = {
871 id: uniquid,
872 match_case: 0,
873 comparison: 'equal',
874 fill: selectedText,
875 index: 1,
876 open: false
877 };
878 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
879
880 // Clone blank options
881 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
882 const elFibBlankOptionItemClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptionItemClone}`);
883 const elFibBlankOptionItemNew = elFibBlankOptionItemClone.cloneNode(true);
884 const countOptions = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`).length;
885 const elFibBlankOptionIndex = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibBlankOptionIndex}`);
886 const elFibOptionTitleInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
887 const elFibOptionMatchCaseInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
888 const elFibOptionComparisonInput = elFibBlankOptionItemNew.querySelectorAll(`${EditQuestion.selectors.elFibOptionComparisonInput}`);
889 elFibBlankOptionItemNew.dataset.id = uniquid;
890 elFibOptionTitleInput.name = `${EditQuestion.selectors.elFibOptionTitleInput}-${uniquid}`;
891 elFibOptionTitleInput.value = this.decodeHtml(selectedText);
892 elFibBlankOptionIndex.textContent = countOptions + 1 + '.';
893 elFibOptionMatchCaseInput.name = `${EditQuestion.selectors.elFibOptionMatchCaseInput}-${uniquid}`.replace(/\./g, '');
894 elFibOptionComparisonInput.forEach(elInput => {
895 elInput.name = `${EditQuestion.selectors.elFibOptionComparisonInput}-${uniquid}`.replace(/\./g, '');
896 if (elInput.value === 'equal') {
897 elInput.checked = true;
898 }
899 });
900 elFibBlankOptionItemClone.insertAdjacentElement('beforebegin', elFibBlankOptionItemNew);
901 elFibBlankOptionItemNew.classList.remove('clone');
902 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItemNew, 1);
903 // End clone blank options
904
905 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
906 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 1);
907 this.fibSaveContent({
908 e: null,
909 target: elBtnFibSaveContent,
910 callBackCompleted: () => {
911 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 0);
912 }
913 });
914 };
915
916 // Delete all blanks
917 fibDeleteAllBlanks(args) {
918 const {
919 e,
920 target
921 } = args;
922 const elBtnFibDeleteAllBlanks = target.closest(`${EditQuestion.selectors.elBtnFibDeleteAllBlanks}`);
923 if (!elBtnFibDeleteAllBlanks) {
924 return;
925 }
926 const elQuestionEditMain = elBtnFibDeleteAllBlanks.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
927 if (!elQuestionEditMain) {
928 return;
929 }
930 const questionId = elQuestionEditMain.dataset.questionId;
931 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
932 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
933 title: elBtnFibDeleteAllBlanks.dataset.title,
934 text: elBtnFibDeleteAllBlanks.dataset.content,
935 icon: 'warning',
936 showCloseButton: true,
937 showCancelButton: true,
938 cancelButtonText: lpData.i18n.cancel,
939 confirmButtonText: lpData.i18n.yes,
940 reverseButtons: true
941 }).then(result => {
942 if (result.isConfirmed) {
943 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
944 const elBlanks = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}`);
945 elBlanks.forEach(elBlank => {
946 editor.dom.remove(elBlank, true);
947 });
948 dataAnswers.meta_data = {};
949 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
950 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
951 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
952 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
953 elFibBlankOptionItem.remove();
954 });
955 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
956 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 1);
957 this.fibSaveContent({
958 e: null,
959 target: elBtnFibSaveContent,
960 callBackCompleted: () => {
961 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 0);
962 }
963 });
964 }
965 });
966 }
967 // Clear content FIB question
968 fibClearContent(args) {
969 const {
970 e,
971 target
972 } = args;
973 const elBtnFibClearAllContent = target.closest(`${EditQuestion.selectors.elBtnFibClearAllContent}`);
974 if (!elBtnFibClearAllContent) {
975 return;
976 }
977 const elQuestionEditMain = elBtnFibClearAllContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
978 if (!elQuestionEditMain) {
979 return;
980 }
981 const questionId = elQuestionEditMain.dataset.questionId;
982 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
983 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
984 title: elBtnFibClearAllContent.dataset.title,
985 text: elBtnFibClearAllContent.dataset.content,
986 icon: 'warning',
987 showCloseButton: true,
988 showCancelButton: true,
989 cancelButtonText: lpData.i18n.cancel,
990 confirmButtonText: lpData.i18n.yes,
991 reverseButtons: true
992 }).then(result => {
993 if (result.isConfirmed) {
994 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
995 editor.setContent('');
996 dataAnswers.meta_data = {};
997 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
998 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
999 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
1000 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
1001 elFibBlankOptionItem.remove();
1002 });
1003 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1004 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 1);
1005 this.fibSaveContent({
1006 e: null,
1007 target: elBtnFibSaveContent,
1008 callBackCompleted: () => {
1009 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 0);
1010 }
1011 });
1012 }
1013 });
1014 }
1015
1016 // Remove blank
1017 fibDeleteBlank(args) {
1018 const {
1019 e,
1020 target
1021 } = args;
1022 const elBtnFibOptionDelete = target.closest(`${EditQuestion.selectors.elBtnFibOptionDelete}`);
1023 if (!elBtnFibOptionDelete) {
1024 return;
1025 }
1026 const elQuestionEditMain = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1027 if (!elQuestionEditMain) {
1028 return;
1029 }
1030 const questionId = elQuestionEditMain.dataset.questionId;
1031 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
1032 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
1033 const elFibBlankOptionItem = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
1034 const blankId = elFibBlankOptionItem.dataset.id;
1035 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
1036 title: elBtnFibOptionDelete.dataset.title,
1037 text: elBtnFibOptionDelete.dataset.content,
1038 icon: 'warning',
1039 showCloseButton: true,
1040 showCancelButton: true,
1041 cancelButtonText: lpData.i18n.cancel,
1042 confirmButtonText: lpData.i18n.yes,
1043 reverseButtons: true
1044 }).then(result => {
1045 if (result.isConfirmed) {
1046 // Find span with id on editor and remove it
1047 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
1048 const elBlank = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${blankId}"]`);
1049 if (elBlank[0]) {
1050 // Remove tag html but keep content
1051 editor.dom.remove(elBlank[0], true);
1052 }
1053 elFibBlankOptionItem.remove();
1054 dataAnswers.meta_data = dataAnswers.meta_data || {};
1055 if (dataAnswers.meta_data[blankId]) {
1056 delete dataAnswers.meta_data[blankId];
1057 }
1058 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
1059 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1060 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 1);
1061 this.fibSaveContent({
1062 e: null,
1063 target: elBtnFibSaveContent,
1064 callBackCompleted: () => {
1065 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 0);
1066 }
1067 });
1068 }
1069 });
1070 }
1071
1072 // Change title of blank option
1073 fibOptionTitleInputChange(args) {
1074 const {
1075 e,
1076 target
1077 } = args;
1078 const elFibOptionTitleInput = target.closest(`${EditQuestion.selectors.elFibOptionTitleInput}`);
1079 if (!elFibOptionTitleInput) {
1080 return;
1081 }
1082 const elQuestionFibOptionItem = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
1083 if (!elQuestionFibOptionItem) {
1084 return;
1085 }
1086 const elQuestionEditMain = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1087 if (!elQuestionEditMain) {
1088 return;
1089 }
1090 const value = elFibOptionTitleInput.value.trim();
1091 const blankId = elQuestionFibOptionItem.dataset.id;
1092 const questionId = elQuestionEditMain.dataset.questionId;
1093 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
1094 const elBlank = editor.dom.select(`.lp-question-fib-input[data-id="${blankId}"]`);
1095 if (elBlank[0]) {
1096 // Update content of blank
1097 elBlank[0].textContent = value;
1098 }
1099 clearTimeout(timeoutAutoUpdateFib);
1100 timeoutAutoUpdateFib = setTimeout(() => {
1101 // Call ajax to update question description
1102 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1103 this.fibSaveContent({
1104 e: null,
1105 target: elBtnFibSaveContent
1106 });
1107 }, 700);
1108 }
1109
1110 // Save content FIB question
1111 fibSaveContent(args) {
1112 const {
1113 e,
1114 target,
1115 callBackCompleted = null
1116 } = args;
1117 const elBtnFibSaveContent = target.closest(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1118 if (!elBtnFibSaveContent) {
1119 return;
1120 }
1121 const elQuestionEditMain = elBtnFibSaveContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1122 const questionId = elQuestionEditMain.dataset.questionId;
1123 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
1124 if (!dataAnswers) {
1125 return;
1126 }
1127 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
1128 dataAnswers.title = editor.getContent();
1129 const elFibBlankOptionItems = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
1130 if (elFibBlankOptionItems) {
1131 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
1132 const blankId = elFibBlankOptionItem.dataset.id;
1133 const elFibOptionMatchCaseInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
1134 const elFibOptionComparisonInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionComparisonInput}:checked`);
1135 dataAnswers.meta_data[blankId].match_case = elFibOptionMatchCaseInput.checked ? 1 : 0;
1136 dataAnswers.meta_data[blankId].comparison = elFibOptionComparisonInput.value;
1137 });
1138 }
1139
1140 //console.log( 'dataAnswers', dataAnswers );
1141
1142 if (!callBackCompleted) {
1143 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 1);
1144 }
1145
1146 // Call ajax to update answers config
1147 const callBack = {
1148 success: response => {
1149 const {
1150 message,
1151 status
1152 } = response;
1153 if (status === 'success') {
1154 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
1155 } else {
1156 throw `Error: ${message}`;
1157 }
1158 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
1159 },
1160 error: error => {
1161 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1162 },
1163 completed: () => {
1164 if (callBackCompleted && typeof callBackCompleted === 'function') {
1165 callBackCompleted();
1166 } else {
1167 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 0);
1168 }
1169 }
1170 };
1171
1172 //console.log( 'dataAnswers', dataAnswers );
1173
1174 const dataSend = {
1175 action: 'update_question_answers_config',
1176 question_id: questionId,
1177 answers: dataAnswers,
1178 args: {
1179 id_url: idUrlHandle
1180 }
1181 };
1182 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1183 }
1184 // Show/hide match case option
1185 fibShowHideMatchCaseOption(args) {
1186 const {
1187 e,
1188 target
1189 } = args;
1190 const elFibOptionMatchCaseInput = target.closest(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
1191 if (!elFibOptionMatchCaseInput) {
1192 return;
1193 }
1194 const elQuestionFibOptionDetail = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionFibOptionDetail}`);
1195 const elFibOptionMatchCaseWrap = elQuestionFibOptionDetail.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseWrap}`);
1196 if (!elQuestionFibOptionDetail || !elFibOptionMatchCaseWrap) {
1197 return;
1198 }
1199 if (elFibOptionMatchCaseInput.checked) {
1200 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 1);
1201 } else {
1202 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 0);
1203 }
1204 const elQuestionEditMain = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1205 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1206 elBtnFibSaveContent.click();
1207 }
1208 /***** End Fill in the blank question type *****/
1209
1210 // Generate a random string of specified length, for set unique id
1211 randomString(length = 10) {
1212 const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
1213 let result = '';
1214 for (let i = 0; i < length; i++) {
1215 result += chars.charAt(Math.floor(Math.random() * chars.length));
1216 }
1217 return result;
1218 }
1219 // Decode HTML entities
1220 decodeHtml(html) {
1221 const txt = document.createElement('textarea');
1222 txt.innerHTML = html;
1223 return txt.value;
1224 }
1225 }
1226 const editQuestion = new EditQuestion();
1227 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuestion.selectors.elEditQuestionWrap, elEditQuestionWrap => {
1228 const findClass = EditQuestion.selectors.elQuestionEditMain.replace('.', '');
1229 if (!elEditQuestionWrap.classList.contains(findClass)) {
1230 return;
1231 }
1232 editQuestion.init();
1233 });
1234
1235 /***/ },
1236
1237 /***/ "./assets/src/js/lpPopupSelectItemToAdd.js"
1238 /*!*************************************************!*\
1239 !*** ./assets/src/js/lpPopupSelectItemToAdd.js ***!
1240 \*************************************************/
1241 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1242
1243 "use strict";
1244 __webpack_require__.r(__webpack_exports__);
1245 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1246 /* harmony export */ LpPopupSelectItemToAdd: () => (/* binding */ LpPopupSelectItemToAdd)
1247 /* harmony export */ });
1248 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
1249 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
1250 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1251 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
1252 /**
1253 * LearnPress Popup Select Item
1254 *
1255 * Handles load(search) item from API, show in popup and select item.
1256 */
1257
1258
1259
1260
1261 let itemsSelectedData = [];
1262 let elPopup;
1263 let timeSearchTitleItem;
1264 class LpPopupSelectItemToAdd {
1265 constructor() {
1266 this.init();
1267 }
1268 static selectors = {
1269 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
1270 elBtnAddItemsSelected: '.lp-btn-add-items-selected',
1271 elBtnCountItemsSelected: '.lp-btn-count-items-selected',
1272 elHeaderCountItemSelected: '.header-count-items-selected',
1273 elSelectItem: '.lp-select-item',
1274 elListItems: '.list-items',
1275 elPopupItemsToSelect: '.lp-popup-items-to-select',
1276 elSearchTitleItem: '.lp-search-title-item',
1277 elBtnBackListItems: '.lp-btn-back-to-select-items',
1278 elListItemsWrap: '.list-items-wrap',
1279 elListItemsSelected: '.list-items-selected',
1280 elItemSelectedClone: '.li-item-selected.clone',
1281 elItemSelected: '.li-item-selected',
1282 LPTarget: '.lp-target'
1283 };
1284 init() {
1285 this.events();
1286 }
1287 events = () => {
1288 if (LpPopupSelectItemToAdd._loadedEvents) {
1289 return;
1290 }
1291 LpPopupSelectItemToAdd._loadedEvents = true;
1292 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
1293 selector: LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect,
1294 callBack: this.showPopupItemsToSelect.name,
1295 class: this
1296 }, {
1297 selector: LpPopupSelectItemToAdd.selectors.elSelectItem,
1298 callBack: this.selectItemsFromList.name,
1299 class: this
1300 }, {
1301 selector: LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected,
1302 callBack: this.showItemsSelected.name,
1303 class: this
1304 }, {
1305 selector: LpPopupSelectItemToAdd.selectors.elBtnBackListItems,
1306 callBack: this.backToSelectItems.name,
1307 class: this
1308 }, {
1309 selector: LpPopupSelectItemToAdd.selectors.elItemSelected,
1310 callBack: this.removeItemSelected.name,
1311 class: this
1312 }, {
1313 selector: '.tabs .tab',
1314 callBack: this.chooseTabItemsType.name,
1315 class: this
1316 }]);
1317 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
1318 selector: LpPopupSelectItemToAdd.selectors.elSearchTitleItem,
1319 callBack: this.searchTitleItemToSelect.name,
1320 class: this
1321 }]);
1322 };
1323
1324 // Show popup items to select
1325 showPopupItemsToSelect = args => {
1326 const {
1327 e,
1328 target = false,
1329 callBack
1330 } = args;
1331 const elBtnShowPopupItemsToSelect = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect}`);
1332 if (!elBtnShowPopupItemsToSelect) {
1333 return;
1334 }
1335
1336 // Reset items selected data when opening popup
1337 itemsSelectedData = [];
1338 const templateId = target.dataset.template || '';
1339 const modalTemplate = document.querySelector(templateId);
1340 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
1341 html: modalTemplate.innerHTML,
1342 showConfirmButton: false,
1343 showCloseButton: true,
1344 width: '60%',
1345 customClass: {
1346 popup: 'lp-select-items-popup',
1347 htmlContainer: 'lp-select-items-html-container',
1348 container: 'lp-select-items-container'
1349 },
1350 willOpen: () => {
1351 elPopup = sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().getPopup();
1352 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1353 if (elLPTarget) {
1354 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1355 dataSend.args.paged = 1;
1356 dataSend.args.item_selecting = itemsSelectedData || [];
1357 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
1358 window.lpAJAXG.fetchAJAX(dataSend, {
1359 success: response => {
1360 const {
1361 data
1362 } = response;
1363 const elSkeleton = elPopup.querySelector('.lp-skeleton-animation');
1364 elSkeleton.remove();
1365 elLPTarget.innerHTML = data.content || '';
1366 this.watchItemsSelectedDataChange();
1367 }
1368 });
1369 }
1370 }
1371 }).then(result => {
1372 if (result.isDismissed) {}
1373 });
1374 };
1375
1376 // Choose tab items type
1377 chooseTabItemsType = args => {
1378 const {
1379 e,
1380 target,
1381 callBack
1382 } = args;
1383 const elTabType = target.closest('.tab');
1384 if (!elTabType) {
1385 return;
1386 }
1387 e.preventDefault();
1388 const elTabs = elTabType.closest('.tabs');
1389 if (!elTabs) {
1390 return;
1391 }
1392 const elSelectItemsToAdd = elTabs.closest(`${LpPopupSelectItemToAdd.selectors.elPopupItemsToSelect}`);
1393 const elInputSearch = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.elSearchTitleItem}`);
1394 const itemType = elTabType.dataset.type;
1395 const elTabLis = elTabs.querySelectorAll('.tab');
1396 elTabLis.forEach(elTabLi => {
1397 if (elTabLi.classList.contains('active')) {
1398 elTabLi.classList.remove('active');
1399 }
1400 });
1401 elTabType.classList.add('active');
1402 // Reset search input
1403 elInputSearch.value = '';
1404 const elLPTarget = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1405 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1406 dataSend.args.item_type = itemType;
1407 dataSend.args.paged = 1;
1408 dataSend.args.item_selecting = itemsSelectedData || [];
1409 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
1410 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1411 window.lpAJAXG.fetchAJAX(dataSend, {
1412 success: response => {
1413 const {
1414 data
1415 } = response;
1416 elLPTarget.innerHTML = data.content || '';
1417 },
1418 error: error => {
1419 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1420 },
1421 completed: () => {
1422 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1423 this.watchItemsSelectedDataChange();
1424 }
1425 });
1426 };
1427
1428 // Choice items to add list items selected before adding to section
1429 selectItemsFromList = args => {
1430 const {
1431 e,
1432 target
1433 } = args;
1434 const elItemAttend = target.closest(`${LpPopupSelectItemToAdd.selectors.elSelectItem}`);
1435 if (!elItemAttend) {
1436 return;
1437 }
1438 const elInput = elItemAttend.querySelector('input[type="checkbox"]');
1439 if (target.tagName !== 'INPUT') {
1440 elInput.click();
1441 return;
1442 }
1443 const elUl = elItemAttend.closest(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
1444 if (!elUl) {
1445 return;
1446 }
1447 const itemSelected = {
1448 ...elInput.dataset
1449 };
1450 //console.log( 'itemSelected', itemSelected );
1451
1452 if (elInput.checked) {
1453 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
1454 if (!exists) {
1455 itemsSelectedData.push(itemSelected);
1456 }
1457 } else {
1458 const index = itemsSelectedData.findIndex(item => item.id === itemSelected.id);
1459 if (index !== -1) {
1460 itemsSelectedData.splice(index, 1);
1461 }
1462 }
1463 this.watchItemsSelectedDataChange();
1464 };
1465
1466 // Search title item
1467 searchTitleItemToSelect = args => {
1468 const {
1469 e,
1470 target
1471 } = args;
1472 const elInputSearch = target.closest(LpPopupSelectItemToAdd.selectors.elSearchTitleItem);
1473 if (!elInputSearch) {
1474 return;
1475 }
1476 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1477 clearTimeout(timeSearchTitleItem);
1478 timeSearchTitleItem = setTimeout(() => {
1479 const dataSet = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1480 dataSet.args.search_title = elInputSearch.value.trim();
1481 dataSet.args.item_selecting = itemsSelectedData;
1482 dataSet.args.paged = 1;
1483 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSet);
1484
1485 // Show loading
1486 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1487 window.lpAJAXG.fetchAJAX(dataSet, {
1488 success: response => {
1489 const {
1490 data
1491 } = response;
1492 elLPTarget.innerHTML = data.content || '';
1493 },
1494 error: error => {
1495 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1496 },
1497 completed: () => {
1498 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1499 }
1500 });
1501 }, 800);
1502 };
1503
1504 // Show list of items, to choose items to add to section
1505 showItemsSelected = args => {
1506 const {
1507 e,
1508 target
1509 } = args;
1510 const elBtnCountItemsSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1511 if (!elBtnCountItemsSelected) {
1512 return;
1513 }
1514 const elBtnBack = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
1515 const elTabs = elPopup.querySelector('.tabs');
1516 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
1517 const elHeaderItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1518 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
1519 const elItemClone = elListItemsSelected.querySelector(`${LpPopupSelectItemToAdd.selectors.elItemSelectedClone}`);
1520 elHeaderItemsSelected.innerHTML = elBtnCountItemsSelected.innerHTML;
1521 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 0);
1522 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 0);
1523 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 0);
1524 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 1);
1525 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderItemsSelected, 1);
1526 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 1);
1527 elListItemsSelected.querySelectorAll(`${LpPopupSelectItemToAdd.selectors.elItemSelected}:not(.clone)`).forEach(elItem => {
1528 elItem.remove();
1529 });
1530 itemsSelectedData.forEach(item => {
1531 const elItemSelected = elItemClone.cloneNode(true);
1532 elItemSelected.classList.remove('clone');
1533 Object.entries(item).forEach(([key, value]) => {
1534 elItemSelected.dataset[key] = value;
1535 });
1536 const elTitleDisplay = elItemSelected.querySelector('.title-display');
1537 elTitleDisplay.innerHTML = item.title;
1538 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elItemSelected, 1);
1539 elItemClone.insertAdjacentElement('beforebegin', elItemSelected);
1540 });
1541 };
1542
1543 // Back to list of items
1544 backToSelectItems = args => {
1545 const {
1546 e,
1547 target
1548 } = args;
1549 const elBtnBack = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
1550 if (!elBtnBack) {
1551 return;
1552 }
1553 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1554 const elTabs = elPopup.querySelector('.tabs');
1555 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
1556 const elHeaderCountItemSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1557 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
1558 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 1);
1559 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 1);
1560 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 1);
1561 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 0);
1562 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderCountItemSelected, 0);
1563 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 0);
1564 };
1565
1566 // Remove item selected from list items selected
1567 removeItemSelected = args => {
1568 const {
1569 e,
1570 target
1571 } = args;
1572 const elRemoveItemSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elItemSelected}`);
1573 if (!elRemoveItemSelected) {
1574 return;
1575 }
1576 const itemRemove = elRemoveItemSelected.dataset;
1577 const index = itemsSelectedData.findIndex(item => item.id === itemRemove.id);
1578 if (index !== -1) {
1579 itemsSelectedData.splice(index, 1);
1580 }
1581 elRemoveItemSelected.remove();
1582 this.watchItemsSelectedDataChange();
1583 };
1584
1585 // Watch items selected when data change
1586 watchItemsSelectedDataChange = () => {
1587 // Update count items selected, disable/enable buttons
1588 const elBtnAddItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected}`);
1589 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1590 const elSpanCount = elBtnCountItemsSelected.querySelector('span');
1591 const elHeaderCount = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1592 const elTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1593 if (itemsSelectedData.length !== 0) {
1594 elBtnCountItemsSelected.disabled = false;
1595 elBtnAddItemsSelected.disabled = false;
1596 elBtnAddItemsSelected.classList.add('active');
1597 elSpanCount.textContent = `(${itemsSelectedData.length})`;
1598 elHeaderCount.innerHTML = elBtnCountItemsSelected.innerHTML;
1599 } else {
1600 elBtnCountItemsSelected.disabled = true;
1601 elBtnAddItemsSelected.disabled = true;
1602 elBtnAddItemsSelected.classList.remove('active');
1603 elSpanCount.textContent = '';
1604 elHeaderCount.textContent = '';
1605 }
1606
1607 // Update list input checked, when items removed, or change tab type
1608 const elListItems = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
1609 const elInputs = elListItems.querySelectorAll('input[type="checkbox"]');
1610 elInputs.forEach(elInputItem => {
1611 const itemSelected = elInputItem.dataset;
1612 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
1613 elInputItem.checked = exists;
1614 });
1615
1616 // Set item selecting data to dataset for query.
1617 const dataSet = window.lpAJAXG.getDataSetCurrent(elTarget);
1618 dataSet.args.item_selecting = itemsSelectedData;
1619 window.lpAJAXG.setDataSetCurrent(elTarget, dataSet);
1620 };
1621
1622 // Add items selected to section
1623 addItemsSelectedToSection = args => {
1624 const {
1625 e,
1626 target,
1627 callBackHandle
1628 } = args;
1629 if (!elPopup) {
1630 return;
1631 }
1632 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().close();
1633 if (typeof callBackHandle === 'function') {
1634 callBackHandle(itemsSelectedData);
1635 itemsSelectedData = [];
1636 }
1637 };
1638 }
1639
1640 /***/ },
1641
1642 /***/ "./assets/src/js/lpToastify.js"
1643 /*!*************************************!*\
1644 !*** ./assets/src/js/lpToastify.js ***!
1645 \*************************************/
1646 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1647
1648 "use strict";
1649 __webpack_require__.r(__webpack_exports__);
1650 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1651 /* harmony export */ show: () => (/* binding */ show)
1652 /* harmony export */ });
1653 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
1654 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
1655 /* 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");
1656 /**
1657 * Utils functions
1658 *
1659 * @param url
1660 * @param data
1661 * @param functions
1662 * @since 4.3.0
1663 * @version 1.0.0
1664 */
1665
1666
1667 const argsToastify = {
1668 text: '',
1669 gravity: lpData.toast.gravity,
1670 // `top` or `bottom`
1671 position: lpData.toast.position,
1672 // `left`, `center` or `right`
1673 className: `${lpData.toast.classPrefix}`,
1674 close: lpData.toast.close == 1,
1675 stopOnFocus: lpData.toast.stopOnFocus == 1,
1676 duration: lpData.toast.duration
1677 };
1678 const show = (message, status = 'success', argsCustom) => {
1679 let args = argsToastify;
1680 if (argsCustom) {
1681 args = {
1682 ...args,
1683 ...argsCustom
1684 };
1685 }
1686 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
1687 ...args,
1688 text: message,
1689 className: `${lpData.toast.classPrefix} ${status}`
1690 });
1691 toastify.showToast();
1692 };
1693
1694 /***/ },
1695
1696 /***/ "./assets/src/js/utils.js"
1697 /*!********************************!*\
1698 !*** ./assets/src/js/utils.js ***!
1699 \********************************/
1700 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1701
1702 "use strict";
1703 __webpack_require__.r(__webpack_exports__);
1704 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1705 /* harmony export */ debounce: () => (/* binding */ debounce),
1706 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
1707 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
1708 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
1709 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
1710 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
1711 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
1712 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
1713 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
1714 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
1715 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
1716 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
1717 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
1718 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
1719 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
1720 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
1721 /* harmony export */ });
1722 /**
1723 * Utils functions
1724 *
1725 * @param url
1726 * @param data
1727 * @param functions
1728 * @since 4.2.5.1
1729 * @version 1.0.6
1730 */
1731 const lpClassName = {
1732 hidden: 'lp-hidden',
1733 loading: 'loading',
1734 elCollapse: 'lp-collapse',
1735 elSectionToggle: '.lp-section-toggle',
1736 elTriggerToggle: '.lp-trigger-toggle'
1737 };
1738 const lpFetchAPI = (url, data = {}, functions = {}) => {
1739 if ('function' === typeof functions.before) {
1740 functions.before();
1741 }
1742 fetch(url, {
1743 method: 'GET',
1744 ...data
1745 }).then(response => response.json()).then(response => {
1746 if ('function' === typeof functions.success) {
1747 functions.success(response);
1748 }
1749 }).catch(err => {
1750 if ('function' === typeof functions.error) {
1751 functions.error(err);
1752 }
1753 }).finally(() => {
1754 if ('function' === typeof functions.completed) {
1755 functions.completed();
1756 }
1757 });
1758 };
1759
1760 /**
1761 * Get current URL without params.
1762 *
1763 * @since 4.2.5.1
1764 */
1765 const lpGetCurrentURLNoParam = () => {
1766 let currentUrl = window.location.href;
1767 const hasParams = currentUrl.includes('?');
1768 if (hasParams) {
1769 currentUrl = currentUrl.split('?')[0];
1770 }
1771 return currentUrl;
1772 };
1773 const lpAddQueryArgs = (endpoint, args) => {
1774 const url = new URL(endpoint);
1775 Object.keys(args).forEach(arg => {
1776 url.searchParams.set(arg, args[arg]);
1777 });
1778 return url;
1779 };
1780
1781 /**
1782 * Listen element viewed.
1783 *
1784 * @param el
1785 * @param callback
1786 * @since 4.2.5.8
1787 */
1788 const listenElementViewed = (el, callback) => {
1789 const observerSeeItem = new IntersectionObserver(function (entries) {
1790 for (const entry of entries) {
1791 if (entry.isIntersecting) {
1792 callback(entry);
1793 }
1794 }
1795 });
1796 observerSeeItem.observe(el);
1797 };
1798
1799 /**
1800 * Listen element created.
1801 *
1802 * @param callback
1803 * @since 4.2.5.8
1804 */
1805 const listenElementCreated = callback => {
1806 const observerCreateItem = new MutationObserver(function (mutations) {
1807 mutations.forEach(function (mutation) {
1808 if (mutation.addedNodes) {
1809 mutation.addedNodes.forEach(function (node) {
1810 if (node.nodeType === 1) {
1811 callback(node);
1812 }
1813 });
1814 }
1815 });
1816 });
1817 observerCreateItem.observe(document, {
1818 childList: true,
1819 subtree: true
1820 });
1821 // End.
1822 };
1823
1824 /**
1825 * Listen element created.
1826 *
1827 * @param selector
1828 * @param callback
1829 * @since 4.2.7.1
1830 */
1831 const lpOnElementReady = (selector, callback) => {
1832 const element = document.querySelector(selector);
1833 if (element) {
1834 callback(element);
1835 return;
1836 }
1837 const observer = new MutationObserver((mutations, obs) => {
1838 const element = document.querySelector(selector);
1839 if (element) {
1840 obs.disconnect();
1841 callback(element);
1842 }
1843 });
1844 observer.observe(document.documentElement, {
1845 childList: true,
1846 subtree: true
1847 });
1848 };
1849
1850 // Parse JSON from string with content include LP_AJAX_START.
1851 const lpAjaxParseJsonOld = data => {
1852 if (typeof data !== 'string') {
1853 return data;
1854 }
1855 const m = String.raw({
1856 raw: data
1857 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
1858 try {
1859 if (m) {
1860 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
1861 } else {
1862 data = JSON.parse(data);
1863 }
1864 } catch (e) {
1865 data = {};
1866 }
1867 return data;
1868 };
1869
1870 // status 0: hide, 1: show
1871 const lpShowHideEl = (el, status = 0) => {
1872 if (!el) {
1873 return;
1874 }
1875 if (!status) {
1876 el.classList.add(lpClassName.hidden);
1877 } else {
1878 el.classList.remove(lpClassName.hidden);
1879 }
1880 };
1881
1882 // status 0: hide, 1: show
1883 const lpSetLoadingEl = (el, status) => {
1884 if (!el) {
1885 return;
1886 }
1887 if (!status) {
1888 el.classList.remove(lpClassName.loading);
1889 } else {
1890 el.classList.add(lpClassName.loading);
1891 }
1892 };
1893
1894 // Toggle collapse section
1895 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
1896 if (!elTriggerClassName) {
1897 elTriggerClassName = lpClassName.elTriggerToggle;
1898 }
1899
1900 // Exclude elements, which should not trigger the collapse toggle
1901 if (elsExclude && elsExclude.length > 0) {
1902 for (const elExclude of elsExclude) {
1903 if (target.closest(elExclude)) {
1904 return;
1905 }
1906 }
1907 }
1908 const elTrigger = target.closest(elTriggerClassName);
1909 if (!elTrigger) {
1910 return;
1911 }
1912
1913 //console.log( 'elTrigger', elTrigger );
1914
1915 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
1916 if (!elSectionToggle) {
1917 return;
1918 }
1919 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
1920 if ('function' === typeof callback) {
1921 callback(elSectionToggle);
1922 }
1923 };
1924
1925 // Get data of form
1926 const getDataOfForm = form => {
1927 const dataSend = {};
1928 const formData = new FormData(form);
1929 for (const pair of formData.entries()) {
1930 const key = pair[0];
1931 const value = formData.getAll(key);
1932 if (!dataSend.hasOwnProperty(key)) {
1933 // Convert value array to string.
1934 dataSend[key] = value.join(',');
1935 }
1936 }
1937 return dataSend;
1938 };
1939
1940 // Get field keys of form
1941 const getFieldKeysOfForm = form => {
1942 const keys = [];
1943 const elements = form.elements;
1944 for (let i = 0; i < elements.length; i++) {
1945 const name = elements[i].name;
1946 if (name && !keys.includes(name)) {
1947 keys.push(name);
1948 }
1949 }
1950 return keys;
1951 };
1952
1953 // Merge data handle with data form.
1954 const mergeDataWithDatForm = (elForm, dataHandle) => {
1955 const dataForm = getDataOfForm(elForm);
1956 const keys = getFieldKeysOfForm(elForm);
1957 keys.forEach(key => {
1958 if (!dataForm.hasOwnProperty(key)) {
1959 delete dataHandle[key];
1960 } else if (dataForm[key][0] === '') {
1961 delete dataForm[key];
1962 delete dataHandle[key];
1963 }
1964 });
1965 dataHandle = {
1966 ...dataHandle,
1967 ...dataForm
1968 };
1969 return dataHandle;
1970 };
1971
1972 /**
1973 * Event trigger
1974 * For each list of event handlers, listen event on document.
1975 *
1976 * eventName: 'click', 'change', ...
1977 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
1978 *
1979 * @param eventName
1980 * @param eventHandlers
1981 */
1982 const eventHandlers = (eventName, eventHandlers) => {
1983 document.addEventListener(eventName, e => {
1984 const target = e.target;
1985 let args = {
1986 e,
1987 target
1988 };
1989 eventHandlers.forEach(eventHandler => {
1990 args = {
1991 ...args,
1992 ...eventHandler
1993 };
1994
1995 //console.log( args );
1996
1997 // Check condition before call back
1998 if (eventHandler.conditionBeforeCallBack) {
1999 if (eventHandler.conditionBeforeCallBack(args) !== true) {
2000 return;
2001 }
2002 }
2003
2004 // Special check for keydown event with checkIsEventEnter = true
2005 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
2006 if (e.key !== 'Enter') {
2007 return;
2008 }
2009 }
2010 if (target.closest(eventHandler.selector)) {
2011 if (eventHandler.class) {
2012 // Call method of class, function callBack will understand exactly {this} is class object.
2013 eventHandler.class[eventHandler.callBack](args);
2014 } else {
2015 // For send args is objected, {this} is eventHandler object, not class object.
2016 eventHandler.callBack(args);
2017 }
2018 }
2019 });
2020 });
2021 };
2022
2023 /**
2024 * Debounce - delays function execution until after `wait` ms of inactivity.
2025 *
2026 * Each call resets the timer. Only the last call in a burst executes.
2027 *
2028 * USE CASES:
2029 * - Search inputs, form validation, window resize
2030 * - Multiple elements need independent timers
2031 * - When you need to call with different arguments
2032 *
2033 * EXAMPLES:
2034 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
2035 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
2036 *
2037 * const debouncedResize = debounce( recalculateLayout, 250 );
2038 * window.addEventListener('resize', debouncedResize);
2039 *
2040 * ⚠️ Create ONCE outside event handlers, not inside.
2041 *
2042 * @param {Function} func - Function to debounce (can be anonymous)
2043 * @param {number} wait - Milliseconds to wait (default: 500)
2044 * @return {Function} Debounced wrapper function
2045 * @since 4.3.7
2046 * @version 1.0.0
2047 */
2048 const debounce = (func, wait = 500) => {
2049 let timer;
2050 return args => {
2051 clearTimeout(timer);
2052 timer = setTimeout(() => func(args), wait);
2053 };
2054 };
2055
2056 /***/ },
2057
2058 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
2059 /*!*****************************************************************************************!*\
2060 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
2061 \*****************************************************************************************/
2062 (module, __webpack_exports__, __webpack_require__) {
2063
2064 "use strict";
2065 __webpack_require__.r(__webpack_exports__);
2066 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2067 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2068 /* harmony export */ });
2069 /* 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");
2070 /* 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__);
2071 /* 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");
2072 /* 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__);
2073 // Imports
2074
2075
2076 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()));
2077 // Module
2078 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
2079 * Toastify js 1.12.0
2080 * https://github.com/apvarun/toastify-js
2081 * @license MIT licensed
2082 *
2083 * Copyright (C) 2018 Varun A P
2084 */
2085
2086 .toastify {
2087 padding: 12px 20px;
2088 color: #ffffff;
2089 display: inline-block;
2090 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
2091 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
2092 background: linear-gradient(135deg, #73a5ff, #5477f5);
2093 position: fixed;
2094 opacity: 0;
2095 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
2096 border-radius: 2px;
2097 cursor: pointer;
2098 text-decoration: none;
2099 max-width: calc(50% - 20px);
2100 z-index: 2147483647;
2101 }
2102
2103 .toastify.on {
2104 opacity: 1;
2105 }
2106
2107 .toast-close {
2108 background: transparent;
2109 border: 0;
2110 color: white;
2111 cursor: pointer;
2112 font-family: inherit;
2113 font-size: 1em;
2114 opacity: 0.4;
2115 padding: 0 5px;
2116 }
2117
2118 .toastify-right {
2119 right: 15px;
2120 }
2121
2122 .toastify-left {
2123 left: 15px;
2124 }
2125
2126 .toastify-top {
2127 top: -150px;
2128 }
2129
2130 .toastify-bottom {
2131 bottom: -150px;
2132 }
2133
2134 .toastify-rounded {
2135 border-radius: 25px;
2136 }
2137
2138 .toastify-avatar {
2139 width: 1.5em;
2140 height: 1.5em;
2141 margin: -7px 5px;
2142 border-radius: 2px;
2143 }
2144
2145 .toastify-center {
2146 margin-left: auto;
2147 margin-right: auto;
2148 left: 0;
2149 right: 0;
2150 max-width: fit-content;
2151 max-width: -moz-fit-content;
2152 }
2153
2154 @media only screen and (max-width: 360px) {
2155 .toastify-right, .toastify-left {
2156 margin-left: auto;
2157 margin-right: auto;
2158 left: 0;
2159 right: 0;
2160 max-width: fit-content;
2161 }
2162 }
2163 `, "",{"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":""}]);
2164 // Exports
2165 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
2166
2167
2168 /***/ },
2169
2170 /***/ "./node_modules/css-loader/dist/runtime/api.js"
2171 /*!*****************************************************!*\
2172 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
2173 \*****************************************************/
2174 (module) {
2175
2176 "use strict";
2177
2178
2179 /*
2180 MIT License http://www.opensource.org/licenses/mit-license.php
2181 Author Tobias Koppers @sokra
2182 */
2183 module.exports = function (cssWithMappingToString) {
2184 var list = [];
2185
2186 // return the list of modules as css string
2187 list.toString = function toString() {
2188 return this.map(function (item) {
2189 var content = "";
2190 var needLayer = typeof item[5] !== "undefined";
2191 if (item[4]) {
2192 content += "@supports (".concat(item[4], ") {");
2193 }
2194 if (item[2]) {
2195 content += "@media ".concat(item[2], " {");
2196 }
2197 if (needLayer) {
2198 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
2199 }
2200 content += cssWithMappingToString(item);
2201 if (needLayer) {
2202 content += "}";
2203 }
2204 if (item[2]) {
2205 content += "}";
2206 }
2207 if (item[4]) {
2208 content += "}";
2209 }
2210 return content;
2211 }).join("");
2212 };
2213
2214 // import a list of modules into the list
2215 list.i = function i(modules, media, dedupe, supports, layer) {
2216 if (typeof modules === "string") {
2217 modules = [[null, modules, undefined]];
2218 }
2219 var alreadyImportedModules = {};
2220 if (dedupe) {
2221 for (var k = 0; k < this.length; k++) {
2222 var id = this[k][0];
2223 if (id != null) {
2224 alreadyImportedModules[id] = true;
2225 }
2226 }
2227 }
2228 for (var _k = 0; _k < modules.length; _k++) {
2229 var item = [].concat(modules[_k]);
2230 if (dedupe && alreadyImportedModules[item[0]]) {
2231 continue;
2232 }
2233 if (typeof layer !== "undefined") {
2234 if (typeof item[5] === "undefined") {
2235 item[5] = layer;
2236 } else {
2237 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
2238 item[5] = layer;
2239 }
2240 }
2241 if (media) {
2242 if (!item[2]) {
2243 item[2] = media;
2244 } else {
2245 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
2246 item[2] = media;
2247 }
2248 }
2249 if (supports) {
2250 if (!item[4]) {
2251 item[4] = "".concat(supports);
2252 } else {
2253 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
2254 item[4] = supports;
2255 }
2256 }
2257 list.push(item);
2258 }
2259 };
2260 return list;
2261 };
2262
2263 /***/ },
2264
2265 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
2266 /*!************************************************************!*\
2267 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
2268 \************************************************************/
2269 (module) {
2270
2271 "use strict";
2272
2273
2274 module.exports = function (item) {
2275 var content = item[1];
2276 var cssMapping = item[3];
2277 if (!cssMapping) {
2278 return content;
2279 }
2280 if (typeof btoa === "function") {
2281 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
2282 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
2283 var sourceMapping = "/*# ".concat(data, " */");
2284 return [content].concat([sourceMapping]).join("\n");
2285 }
2286 return [content].join("\n");
2287 };
2288
2289 /***/ },
2290
2291 /***/ "./node_modules/sortablejs/modular/sortable.esm.js"
2292 /*!*********************************************************!*\
2293 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
2294 \*********************************************************/
2295 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2296
2297 "use strict";
2298 __webpack_require__.r(__webpack_exports__);
2299 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2300 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
2301 /* harmony export */ Sortable: () => (/* binding */ Sortable),
2302 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
2303 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2304 /* harmony export */ });
2305 /**!
2306 * Sortable 1.15.7
2307 * @author RubaXa <trash@rubaxa.org>
2308 * @author owenm <owen23355@gmail.com>
2309 * @license MIT
2310 */
2311 function _arrayLikeToArray(r, a) {
2312 (null == a || a > r.length) && (a = r.length);
2313 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
2314 return n;
2315 }
2316 function _arrayWithoutHoles(r) {
2317 if (Array.isArray(r)) return _arrayLikeToArray(r);
2318 }
2319 function _defineProperty(e, r, t) {
2320 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
2321 value: t,
2322 enumerable: !0,
2323 configurable: !0,
2324 writable: !0
2325 }) : e[r] = t, e;
2326 }
2327 function _extends() {
2328 return _extends = Object.assign ? Object.assign.bind() : function (n) {
2329 for (var e = 1; e < arguments.length; e++) {
2330 var t = arguments[e];
2331 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
2332 }
2333 return n;
2334 }, _extends.apply(null, arguments);
2335 }
2336 function _iterableToArray(r) {
2337 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
2338 }
2339 function _nonIterableSpread() {
2340 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2341 }
2342 function ownKeys(e, r) {
2343 var t = Object.keys(e);
2344 if (Object.getOwnPropertySymbols) {
2345 var o = Object.getOwnPropertySymbols(e);
2346 r && (o = o.filter(function (r) {
2347 return Object.getOwnPropertyDescriptor(e, r).enumerable;
2348 })), t.push.apply(t, o);
2349 }
2350 return t;
2351 }
2352 function _objectSpread2(e) {
2353 for (var r = 1; r < arguments.length; r++) {
2354 var t = null != arguments[r] ? arguments[r] : {};
2355 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
2356 _defineProperty(e, r, t[r]);
2357 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
2358 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
2359 });
2360 }
2361 return e;
2362 }
2363 function _objectWithoutProperties(e, t) {
2364 if (null == e) return {};
2365 var o,
2366 r,
2367 i = _objectWithoutPropertiesLoose(e, t);
2368 if (Object.getOwnPropertySymbols) {
2369 var n = Object.getOwnPropertySymbols(e);
2370 for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
2371 }
2372 return i;
2373 }
2374 function _objectWithoutPropertiesLoose(r, e) {
2375 if (null == r) return {};
2376 var t = {};
2377 for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
2378 if (-1 !== e.indexOf(n)) continue;
2379 t[n] = r[n];
2380 }
2381 return t;
2382 }
2383 function _toConsumableArray(r) {
2384 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
2385 }
2386 function _toPrimitive(t, r) {
2387 if ("object" != typeof t || !t) return t;
2388 var e = t[Symbol.toPrimitive];
2389 if (void 0 !== e) {
2390 var i = e.call(t, r || "default");
2391 if ("object" != typeof i) return i;
2392 throw new TypeError("@@toPrimitive must return a primitive value.");
2393 }
2394 return ("string" === r ? String : Number)(t);
2395 }
2396 function _toPropertyKey(t) {
2397 var i = _toPrimitive(t, "string");
2398 return "symbol" == typeof i ? i : i + "";
2399 }
2400 function _typeof(o) {
2401 "@babel/helpers - typeof";
2402
2403 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
2404 return typeof o;
2405 } : function (o) {
2406 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
2407 }, _typeof(o);
2408 }
2409 function _unsupportedIterableToArray(r, a) {
2410 if (r) {
2411 if ("string" == typeof r) return _arrayLikeToArray(r, a);
2412 var t = {}.toString.call(r).slice(8, -1);
2413 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;
2414 }
2415 }
2416
2417 var version = "1.15.7";
2418
2419 function userAgent(pattern) {
2420 if (typeof window !== 'undefined' && window.navigator) {
2421 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
2422 }
2423 }
2424 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
2425 var Edge = userAgent(/Edge/i);
2426 var FireFox = userAgent(/firefox/i);
2427 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
2428 var IOS = userAgent(/iP(ad|od|hone)/i);
2429 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
2430
2431 var captureMode = {
2432 capture: false,
2433 passive: false
2434 };
2435 function on(el, event, fn) {
2436 el.addEventListener(event, fn, !IE11OrLess && captureMode);
2437 }
2438 function off(el, event, fn) {
2439 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
2440 }
2441 function matches( /**HTMLElement*/el, /**String*/selector) {
2442 if (!selector) return;
2443 selector[0] === '>' && (selector = selector.substring(1));
2444 if (el) {
2445 try {
2446 if (el.matches) {
2447 return el.matches(selector);
2448 } else if (el.msMatchesSelector) {
2449 return el.msMatchesSelector(selector);
2450 } else if (el.webkitMatchesSelector) {
2451 return el.webkitMatchesSelector(selector);
2452 }
2453 } catch (_) {
2454 return false;
2455 }
2456 }
2457 return false;
2458 }
2459 function getParentOrHost(el) {
2460 return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
2461 }
2462 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
2463 if (el) {
2464 ctx = ctx || document;
2465 do {
2466 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
2467 return el;
2468 }
2469 if (el === ctx) break;
2470 /* jshint boss:true */
2471 } while (el = getParentOrHost(el));
2472 }
2473 return null;
2474 }
2475 var R_SPACE = /\s+/g;
2476 function toggleClass(el, name, state) {
2477 if (el && name) {
2478 if (el.classList) {
2479 el.classList[state ? 'add' : 'remove'](name);
2480 } else {
2481 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
2482 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
2483 }
2484 }
2485 }
2486 function css(el, prop, val) {
2487 var style = el && el.style;
2488 if (style) {
2489 if (val === void 0) {
2490 if (document.defaultView && document.defaultView.getComputedStyle) {
2491 val = document.defaultView.getComputedStyle(el, '');
2492 } else if (el.currentStyle) {
2493 val = el.currentStyle;
2494 }
2495 return prop === void 0 ? val : val[prop];
2496 } else {
2497 if (!(prop in style) && prop.indexOf('webkit') === -1) {
2498 prop = '-webkit-' + prop;
2499 }
2500 style[prop] = val + (typeof val === 'string' ? '' : 'px');
2501 }
2502 }
2503 }
2504 function matrix(el, selfOnly) {
2505 var appliedTransforms = '';
2506 if (typeof el === 'string') {
2507 appliedTransforms = el;
2508 } else {
2509 do {
2510 var transform = css(el, 'transform');
2511 if (transform && transform !== 'none') {
2512 appliedTransforms = transform + ' ' + appliedTransforms;
2513 }
2514 /* jshint boss:true */
2515 } while (!selfOnly && (el = el.parentNode));
2516 }
2517 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
2518 /*jshint -W056 */
2519 return matrixFn && new matrixFn(appliedTransforms);
2520 }
2521 function find(ctx, tagName, iterator) {
2522 if (ctx) {
2523 var list = ctx.getElementsByTagName(tagName),
2524 i = 0,
2525 n = list.length;
2526 if (iterator) {
2527 for (; i < n; i++) {
2528 iterator(list[i], i);
2529 }
2530 }
2531 return list;
2532 }
2533 return [];
2534 }
2535 function getWindowScrollingElement() {
2536 var scrollingElement = document.scrollingElement;
2537 if (scrollingElement) {
2538 return scrollingElement;
2539 } else {
2540 return document.documentElement;
2541 }
2542 }
2543
2544 /**
2545 * Returns the "bounding client rect" of given element
2546 * @param {HTMLElement} el The element whose boundingClientRect is wanted
2547 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
2548 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
2549 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
2550 * @param {[HTMLElement]} container The parent the element will be placed in
2551 * @return {Object} The boundingClientRect of el, with specified adjustments
2552 */
2553 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
2554 if (!el.getBoundingClientRect && el !== window) return;
2555 var elRect, top, left, bottom, right, height, width;
2556 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
2557 elRect = el.getBoundingClientRect();
2558 top = elRect.top;
2559 left = elRect.left;
2560 bottom = elRect.bottom;
2561 right = elRect.right;
2562 height = elRect.height;
2563 width = elRect.width;
2564 } else {
2565 top = 0;
2566 left = 0;
2567 bottom = window.innerHeight;
2568 right = window.innerWidth;
2569 height = window.innerHeight;
2570 width = window.innerWidth;
2571 }
2572 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
2573 // Adjust for translate()
2574 container = container || el.parentNode;
2575
2576 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
2577 // Not needed on <= IE11
2578 if (!IE11OrLess) {
2579 do {
2580 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
2581 var containerRect = container.getBoundingClientRect();
2582
2583 // Set relative to edges of padding box of container
2584 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
2585 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
2586 bottom = top + elRect.height;
2587 right = left + elRect.width;
2588 break;
2589 }
2590 /* jshint boss:true */
2591 } while (container = container.parentNode);
2592 }
2593 }
2594 if (undoScale && el !== window) {
2595 // Adjust for scale()
2596 var elMatrix = matrix(container || el),
2597 scaleX = elMatrix && elMatrix.a,
2598 scaleY = elMatrix && elMatrix.d;
2599 if (elMatrix) {
2600 top /= scaleY;
2601 left /= scaleX;
2602 width /= scaleX;
2603 height /= scaleY;
2604 bottom = top + height;
2605 right = left + width;
2606 }
2607 }
2608 return {
2609 top: top,
2610 left: left,
2611 bottom: bottom,
2612 right: right,
2613 width: width,
2614 height: height
2615 };
2616 }
2617
2618 /**
2619 * Checks if a side of an element is scrolled past a side of its parents
2620 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
2621 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
2622 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
2623 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
2624 */
2625 function isScrolledPast(el, elSide, parentSide) {
2626 var parent = getParentAutoScrollElement(el, true),
2627 elSideVal = getRect(el)[elSide];
2628
2629 /* jshint boss:true */
2630 while (parent) {
2631 var parentSideVal = getRect(parent)[parentSide],
2632 visible = void 0;
2633 if (parentSide === 'top' || parentSide === 'left') {
2634 visible = elSideVal >= parentSideVal;
2635 } else {
2636 visible = elSideVal <= parentSideVal;
2637 }
2638 if (!visible) return parent;
2639 if (parent === getWindowScrollingElement()) break;
2640 parent = getParentAutoScrollElement(parent, false);
2641 }
2642 return false;
2643 }
2644
2645 /**
2646 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
2647 * and non-draggable elements
2648 * @param {HTMLElement} el The parent element
2649 * @param {Number} childNum The index of the child
2650 * @param {Object} options Parent Sortable's options
2651 * @return {HTMLElement} The child at index childNum, or null if not found
2652 */
2653 function getChild(el, childNum, options, includeDragEl) {
2654 var currentChild = 0,
2655 i = 0,
2656 children = el.children;
2657 while (i < children.length) {
2658 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
2659 if (currentChild === childNum) {
2660 return children[i];
2661 }
2662 currentChild++;
2663 }
2664 i++;
2665 }
2666 return null;
2667 }
2668
2669 /**
2670 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
2671 * @param {HTMLElement} el Parent element
2672 * @param {selector} selector Any other elements that should be ignored
2673 * @return {HTMLElement} The last child, ignoring ghostEl
2674 */
2675 function lastChild(el, selector) {
2676 var last = el.lastElementChild;
2677 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
2678 last = last.previousElementSibling;
2679 }
2680 return last || null;
2681 }
2682
2683 /**
2684 * Returns the index of an element within its parent for a selected set of
2685 * elements
2686 * @param {HTMLElement} el
2687 * @param {selector} selector
2688 * @return {number}
2689 */
2690 function index(el, selector) {
2691 var index = 0;
2692 if (!el || !el.parentNode) {
2693 return -1;
2694 }
2695
2696 /* jshint boss:true */
2697 while (el = el.previousElementSibling) {
2698 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
2699 index++;
2700 }
2701 }
2702 return index;
2703 }
2704
2705 /**
2706 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
2707 * The value is returned in real pixels.
2708 * @param {HTMLElement} el
2709 * @return {Array} Offsets in the format of [left, top]
2710 */
2711 function getRelativeScrollOffset(el) {
2712 var offsetLeft = 0,
2713 offsetTop = 0,
2714 winScroller = getWindowScrollingElement();
2715 if (el) {
2716 do {
2717 var elMatrix = matrix(el),
2718 scaleX = elMatrix.a,
2719 scaleY = elMatrix.d;
2720 offsetLeft += el.scrollLeft * scaleX;
2721 offsetTop += el.scrollTop * scaleY;
2722 } while (el !== winScroller && (el = el.parentNode));
2723 }
2724 return [offsetLeft, offsetTop];
2725 }
2726
2727 /**
2728 * Returns the index of the object within the given array
2729 * @param {Array} arr Array that may or may not hold the object
2730 * @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
2731 * @return {Number} The index of the object in the array, or -1
2732 */
2733 function indexOfObject(arr, obj) {
2734 for (var i in arr) {
2735 if (!arr.hasOwnProperty(i)) continue;
2736 for (var key in obj) {
2737 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
2738 }
2739 }
2740 return -1;
2741 }
2742 function getParentAutoScrollElement(el, includeSelf) {
2743 // skip to window
2744 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
2745 var elem = el;
2746 var gotSelf = false;
2747 do {
2748 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
2749 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
2750 var elemCSS = css(elem);
2751 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
2752 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
2753 if (gotSelf || includeSelf) return elem;
2754 gotSelf = true;
2755 }
2756 }
2757 /* jshint boss:true */
2758 } while (elem = elem.parentNode);
2759 return getWindowScrollingElement();
2760 }
2761 function extend(dst, src) {
2762 if (dst && src) {
2763 for (var key in src) {
2764 if (src.hasOwnProperty(key)) {
2765 dst[key] = src[key];
2766 }
2767 }
2768 }
2769 return dst;
2770 }
2771 function isRectEqual(rect1, rect2) {
2772 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);
2773 }
2774 var _throttleTimeout;
2775 function throttle(callback, ms) {
2776 return function () {
2777 if (!_throttleTimeout) {
2778 var args = arguments,
2779 _this = this;
2780 if (args.length === 1) {
2781 callback.call(_this, args[0]);
2782 } else {
2783 callback.apply(_this, args);
2784 }
2785 _throttleTimeout = setTimeout(function () {
2786 _throttleTimeout = void 0;
2787 }, ms);
2788 }
2789 };
2790 }
2791 function cancelThrottle() {
2792 clearTimeout(_throttleTimeout);
2793 _throttleTimeout = void 0;
2794 }
2795 function scrollBy(el, x, y) {
2796 el.scrollLeft += x;
2797 el.scrollTop += y;
2798 }
2799 function clone(el) {
2800 var Polymer = window.Polymer;
2801 var $ = window.jQuery || window.Zepto;
2802 if (Polymer && Polymer.dom) {
2803 return Polymer.dom(el).cloneNode(true);
2804 } else if ($) {
2805 return $(el).clone(true)[0];
2806 } else {
2807 return el.cloneNode(true);
2808 }
2809 }
2810 function setRect(el, rect) {
2811 css(el, 'position', 'absolute');
2812 css(el, 'top', rect.top);
2813 css(el, 'left', rect.left);
2814 css(el, 'width', rect.width);
2815 css(el, 'height', rect.height);
2816 }
2817 function unsetRect(el) {
2818 css(el, 'position', '');
2819 css(el, 'top', '');
2820 css(el, 'left', '');
2821 css(el, 'width', '');
2822 css(el, 'height', '');
2823 }
2824 function getChildContainingRectFromElement(container, options, ghostEl) {
2825 var rect = {};
2826 Array.from(container.children).forEach(function (child) {
2827 var _rect$left, _rect$top, _rect$right, _rect$bottom;
2828 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
2829 var childRect = getRect(child);
2830 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
2831 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
2832 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
2833 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
2834 });
2835 rect.width = rect.right - rect.left;
2836 rect.height = rect.bottom - rect.top;
2837 rect.x = rect.left;
2838 rect.y = rect.top;
2839 return rect;
2840 }
2841 var expando = 'Sortable' + new Date().getTime();
2842
2843 function AnimationStateManager() {
2844 var animationStates = [],
2845 animationCallbackId;
2846 return {
2847 captureAnimationState: function captureAnimationState() {
2848 animationStates = [];
2849 if (!this.options.animation) return;
2850 var children = [].slice.call(this.el.children);
2851 children.forEach(function (child) {
2852 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
2853 animationStates.push({
2854 target: child,
2855 rect: getRect(child)
2856 });
2857 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
2858
2859 // If animating: compensate for current animation
2860 if (child.thisAnimationDuration) {
2861 var childMatrix = matrix(child, true);
2862 if (childMatrix) {
2863 fromRect.top -= childMatrix.f;
2864 fromRect.left -= childMatrix.e;
2865 }
2866 }
2867 child.fromRect = fromRect;
2868 });
2869 },
2870 addAnimationState: function addAnimationState(state) {
2871 animationStates.push(state);
2872 },
2873 removeAnimationState: function removeAnimationState(target) {
2874 animationStates.splice(indexOfObject(animationStates, {
2875 target: target
2876 }), 1);
2877 },
2878 animateAll: function animateAll(callback) {
2879 var _this = this;
2880 if (!this.options.animation) {
2881 clearTimeout(animationCallbackId);
2882 if (typeof callback === 'function') callback();
2883 return;
2884 }
2885 var animating = false,
2886 animationTime = 0;
2887 animationStates.forEach(function (state) {
2888 var time = 0,
2889 target = state.target,
2890 fromRect = target.fromRect,
2891 toRect = getRect(target),
2892 prevFromRect = target.prevFromRect,
2893 prevToRect = target.prevToRect,
2894 animatingRect = state.rect,
2895 targetMatrix = matrix(target, true);
2896 if (targetMatrix) {
2897 // Compensate for current animation
2898 toRect.top -= targetMatrix.f;
2899 toRect.left -= targetMatrix.e;
2900 }
2901 target.toRect = toRect;
2902 if (target.thisAnimationDuration) {
2903 // Could also check if animatingRect is between fromRect and toRect
2904 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
2905 // Make sure animatingRect is on line between toRect & fromRect
2906 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
2907 // If returning to same place as started from animation and on same axis
2908 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
2909 }
2910 }
2911
2912 // if fromRect != toRect: animate
2913 if (!isRectEqual(toRect, fromRect)) {
2914 target.prevFromRect = fromRect;
2915 target.prevToRect = toRect;
2916 if (!time) {
2917 time = _this.options.animation;
2918 }
2919 _this.animate(target, animatingRect, toRect, time);
2920 }
2921 if (time) {
2922 animating = true;
2923 animationTime = Math.max(animationTime, time);
2924 clearTimeout(target.animationResetTimer);
2925 target.animationResetTimer = setTimeout(function () {
2926 target.animationTime = 0;
2927 target.prevFromRect = null;
2928 target.fromRect = null;
2929 target.prevToRect = null;
2930 target.thisAnimationDuration = null;
2931 }, time);
2932 target.thisAnimationDuration = time;
2933 }
2934 });
2935 clearTimeout(animationCallbackId);
2936 if (!animating) {
2937 if (typeof callback === 'function') callback();
2938 } else {
2939 animationCallbackId = setTimeout(function () {
2940 if (typeof callback === 'function') callback();
2941 }, animationTime);
2942 }
2943 animationStates = [];
2944 },
2945 animate: function animate(target, currentRect, toRect, duration) {
2946 if (duration) {
2947 css(target, 'transition', '');
2948 css(target, 'transform', '');
2949 var elMatrix = matrix(this.el),
2950 scaleX = elMatrix && elMatrix.a,
2951 scaleY = elMatrix && elMatrix.d,
2952 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
2953 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
2954 target.animatingX = !!translateX;
2955 target.animatingY = !!translateY;
2956 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
2957 this.forRepaintDummy = repaint(target); // repaint
2958
2959 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
2960 css(target, 'transform', 'translate3d(0,0,0)');
2961 typeof target.animated === 'number' && clearTimeout(target.animated);
2962 target.animated = setTimeout(function () {
2963 css(target, 'transition', '');
2964 css(target, 'transform', '');
2965 target.animated = false;
2966 target.animatingX = false;
2967 target.animatingY = false;
2968 }, duration);
2969 }
2970 }
2971 };
2972 }
2973 function repaint(target) {
2974 return target.offsetWidth;
2975 }
2976 function calculateRealTime(animatingRect, fromRect, toRect, options) {
2977 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;
2978 }
2979
2980 var plugins = [];
2981 var defaults = {
2982 initializeByDefault: true
2983 };
2984 var PluginManager = {
2985 mount: function mount(plugin) {
2986 // Set default static properties
2987 for (var option in defaults) {
2988 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
2989 plugin[option] = defaults[option];
2990 }
2991 }
2992 plugins.forEach(function (p) {
2993 if (p.pluginName === plugin.pluginName) {
2994 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
2995 }
2996 });
2997 plugins.push(plugin);
2998 },
2999 pluginEvent: function pluginEvent(eventName, sortable, evt) {
3000 var _this = this;
3001 this.eventCanceled = false;
3002 evt.cancel = function () {
3003 _this.eventCanceled = true;
3004 };
3005 var eventNameGlobal = eventName + 'Global';
3006 plugins.forEach(function (plugin) {
3007 if (!sortable[plugin.pluginName]) return;
3008 // Fire global events if it exists in this sortable
3009 if (sortable[plugin.pluginName][eventNameGlobal]) {
3010 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
3011 sortable: sortable
3012 }, evt));
3013 }
3014
3015 // Only fire plugin event if plugin is enabled in this sortable,
3016 // and plugin has event defined
3017 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
3018 sortable[plugin.pluginName][eventName](_objectSpread2({
3019 sortable: sortable
3020 }, evt));
3021 }
3022 });
3023 },
3024 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
3025 plugins.forEach(function (plugin) {
3026 var pluginName = plugin.pluginName;
3027 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
3028 var initialized = new plugin(sortable, el, sortable.options);
3029 initialized.sortable = sortable;
3030 initialized.options = sortable.options;
3031 sortable[pluginName] = initialized;
3032
3033 // Add default options from plugin
3034 _extends(defaults, initialized.defaults);
3035 });
3036 for (var option in sortable.options) {
3037 if (!sortable.options.hasOwnProperty(option)) continue;
3038 var modified = this.modifyOption(sortable, option, sortable.options[option]);
3039 if (typeof modified !== 'undefined') {
3040 sortable.options[option] = modified;
3041 }
3042 }
3043 },
3044 getEventProperties: function getEventProperties(name, sortable) {
3045 var eventProperties = {};
3046 plugins.forEach(function (plugin) {
3047 if (typeof plugin.eventProperties !== 'function') return;
3048 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
3049 });
3050 return eventProperties;
3051 },
3052 modifyOption: function modifyOption(sortable, name, value) {
3053 var modifiedValue;
3054 plugins.forEach(function (plugin) {
3055 // Plugin must exist on the Sortable
3056 if (!sortable[plugin.pluginName]) return;
3057
3058 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
3059 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
3060 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
3061 }
3062 });
3063 return modifiedValue;
3064 }
3065 };
3066
3067 function dispatchEvent(_ref) {
3068 var sortable = _ref.sortable,
3069 rootEl = _ref.rootEl,
3070 name = _ref.name,
3071 targetEl = _ref.targetEl,
3072 cloneEl = _ref.cloneEl,
3073 toEl = _ref.toEl,
3074 fromEl = _ref.fromEl,
3075 oldIndex = _ref.oldIndex,
3076 newIndex = _ref.newIndex,
3077 oldDraggableIndex = _ref.oldDraggableIndex,
3078 newDraggableIndex = _ref.newDraggableIndex,
3079 originalEvent = _ref.originalEvent,
3080 putSortable = _ref.putSortable,
3081 extraEventProperties = _ref.extraEventProperties;
3082 sortable = sortable || rootEl && rootEl[expando];
3083 if (!sortable) return;
3084 var evt,
3085 options = sortable.options,
3086 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
3087 // Support for new CustomEvent feature
3088 if (window.CustomEvent && !IE11OrLess && !Edge) {
3089 evt = new CustomEvent(name, {
3090 bubbles: true,
3091 cancelable: true
3092 });
3093 } else {
3094 evt = document.createEvent('Event');
3095 evt.initEvent(name, true, true);
3096 }
3097 evt.to = toEl || rootEl;
3098 evt.from = fromEl || rootEl;
3099 evt.item = targetEl || rootEl;
3100 evt.clone = cloneEl;
3101 evt.oldIndex = oldIndex;
3102 evt.newIndex = newIndex;
3103 evt.oldDraggableIndex = oldDraggableIndex;
3104 evt.newDraggableIndex = newDraggableIndex;
3105 evt.originalEvent = originalEvent;
3106 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
3107 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
3108 for (var option in allEventProperties) {
3109 evt[option] = allEventProperties[option];
3110 }
3111 if (rootEl) {
3112 rootEl.dispatchEvent(evt);
3113 }
3114 if (options[onName]) {
3115 options[onName].call(sortable, evt);
3116 }
3117 }
3118
3119 var _excluded = ["evt"];
3120 var pluginEvent = function pluginEvent(eventName, sortable) {
3121 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
3122 originalEvent = _ref.evt,
3123 data = _objectWithoutProperties(_ref, _excluded);
3124 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
3125 dragEl: dragEl,
3126 parentEl: parentEl,
3127 ghostEl: ghostEl,
3128 rootEl: rootEl,
3129 nextEl: nextEl,
3130 lastDownEl: lastDownEl,
3131 cloneEl: cloneEl,
3132 cloneHidden: cloneHidden,
3133 dragStarted: moved,
3134 putSortable: putSortable,
3135 activeSortable: Sortable.active,
3136 originalEvent: originalEvent,
3137 oldIndex: oldIndex,
3138 oldDraggableIndex: oldDraggableIndex,
3139 newIndex: newIndex,
3140 newDraggableIndex: newDraggableIndex,
3141 hideGhostForTarget: _hideGhostForTarget,
3142 unhideGhostForTarget: _unhideGhostForTarget,
3143 cloneNowHidden: function cloneNowHidden() {
3144 cloneHidden = true;
3145 },
3146 cloneNowShown: function cloneNowShown() {
3147 cloneHidden = false;
3148 },
3149 dispatchSortableEvent: function dispatchSortableEvent(name) {
3150 _dispatchEvent({
3151 sortable: sortable,
3152 name: name,
3153 originalEvent: originalEvent
3154 });
3155 }
3156 }, data));
3157 };
3158 function _dispatchEvent(info) {
3159 dispatchEvent(_objectSpread2({
3160 putSortable: putSortable,
3161 cloneEl: cloneEl,
3162 targetEl: dragEl,
3163 rootEl: rootEl,
3164 oldIndex: oldIndex,
3165 oldDraggableIndex: oldDraggableIndex,
3166 newIndex: newIndex,
3167 newDraggableIndex: newDraggableIndex
3168 }, info));
3169 }
3170 var dragEl,
3171 parentEl,
3172 ghostEl,
3173 rootEl,
3174 nextEl,
3175 lastDownEl,
3176 cloneEl,
3177 cloneHidden,
3178 oldIndex,
3179 newIndex,
3180 oldDraggableIndex,
3181 newDraggableIndex,
3182 activeGroup,
3183 putSortable,
3184 awaitingDragStarted = false,
3185 ignoreNextClick = false,
3186 sortables = [],
3187 tapEvt,
3188 touchEvt,
3189 lastDx,
3190 lastDy,
3191 tapDistanceLeft,
3192 tapDistanceTop,
3193 moved,
3194 lastTarget,
3195 lastDirection,
3196 pastFirstInvertThresh = false,
3197 isCircumstantialInvert = false,
3198 targetMoveDistance,
3199 // For positioning ghost absolutely
3200 ghostRelativeParent,
3201 ghostRelativeParentInitialScroll = [],
3202 // (left, top)
3203
3204 _silent = false,
3205 savedInputChecked = [];
3206
3207 /** @const */
3208 var documentExists = typeof document !== 'undefined',
3209 PositionGhostAbsolutely = IOS,
3210 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
3211 // This will not pass for IE9, because IE9 DnD only works on anchors
3212 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
3213 supportCssPointerEvents = function () {
3214 if (!documentExists) return;
3215 // false when <= IE11
3216 if (IE11OrLess) {
3217 return false;
3218 }
3219 var el = document.createElement('x');
3220 el.style.cssText = 'pointer-events:auto';
3221 return el.style.pointerEvents === 'auto';
3222 }(),
3223 _detectDirection = function _detectDirection(el, options) {
3224 var elCSS = css(el),
3225 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
3226 child1 = getChild(el, 0, options),
3227 child2 = getChild(el, 1, options),
3228 firstChildCSS = child1 && css(child1),
3229 secondChildCSS = child2 && css(child2),
3230 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
3231 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
3232 if (elCSS.display === 'flex') {
3233 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
3234 }
3235 if (elCSS.display === 'grid') {
3236 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
3237 }
3238 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
3239 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
3240 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
3241 }
3242 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';
3243 },
3244 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
3245 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
3246 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
3247 dragElOppLength = vertical ? dragRect.width : dragRect.height,
3248 targetS1Opp = vertical ? targetRect.left : targetRect.top,
3249 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
3250 targetOppLength = vertical ? targetRect.width : targetRect.height;
3251 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
3252 },
3253 /**
3254 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
3255 * @param {Number} x X position
3256 * @param {Number} y Y position
3257 * @return {HTMLElement} Element of the first found nearest Sortable
3258 */
3259 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
3260 var ret;
3261 sortables.some(function (sortable) {
3262 var threshold = sortable[expando].options.emptyInsertThreshold;
3263 if (!threshold || lastChild(sortable)) return;
3264 var rect = getRect(sortable),
3265 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
3266 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
3267 if (insideHorizontally && insideVertically) {
3268 return ret = sortable;
3269 }
3270 });
3271 return ret;
3272 },
3273 _prepareGroup = function _prepareGroup(options) {
3274 function toFn(value, pull) {
3275 return function (to, from, dragEl, evt) {
3276 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
3277 if (value == null && (pull || sameGroup)) {
3278 // Default pull value
3279 // Default pull and put value if same group
3280 return true;
3281 } else if (value == null || value === false) {
3282 return false;
3283 } else if (pull && value === 'clone') {
3284 return value;
3285 } else if (typeof value === 'function') {
3286 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
3287 } else {
3288 var otherGroup = (pull ? to : from).options.group.name;
3289 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
3290 }
3291 };
3292 }
3293 var group = {};
3294 var originalGroup = options.group;
3295 if (!originalGroup || _typeof(originalGroup) != 'object') {
3296 originalGroup = {
3297 name: originalGroup
3298 };
3299 }
3300 group.name = originalGroup.name;
3301 group.checkPull = toFn(originalGroup.pull, true);
3302 group.checkPut = toFn(originalGroup.put);
3303 group.revertClone = originalGroup.revertClone;
3304 options.group = group;
3305 },
3306 _hideGhostForTarget = function _hideGhostForTarget() {
3307 if (!supportCssPointerEvents && ghostEl) {
3308 css(ghostEl, 'display', 'none');
3309 }
3310 },
3311 _unhideGhostForTarget = function _unhideGhostForTarget() {
3312 if (!supportCssPointerEvents && ghostEl) {
3313 css(ghostEl, 'display', '');
3314 }
3315 };
3316
3317 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
3318 if (documentExists && !ChromeForAndroid) {
3319 document.addEventListener('click', function (evt) {
3320 if (ignoreNextClick) {
3321 evt.preventDefault();
3322 evt.stopPropagation && evt.stopPropagation();
3323 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
3324 ignoreNextClick = false;
3325 return false;
3326 }
3327 }, true);
3328 }
3329 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
3330 if (dragEl) {
3331 evt = evt.touches ? evt.touches[0] : evt;
3332 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
3333 if (nearest) {
3334 // Create imitation event
3335 var event = {};
3336 for (var i in evt) {
3337 if (evt.hasOwnProperty(i)) {
3338 event[i] = evt[i];
3339 }
3340 }
3341 event.target = event.rootEl = nearest;
3342 event.preventDefault = void 0;
3343 event.stopPropagation = void 0;
3344 nearest[expando]._onDragOver(event);
3345 }
3346 }
3347 };
3348 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
3349 if (dragEl) {
3350 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
3351 }
3352 };
3353
3354 /**
3355 * @class Sortable
3356 * @param {HTMLElement} el
3357 * @param {Object} [options]
3358 */
3359 function Sortable(el, options) {
3360 if (!(el && el.nodeType && el.nodeType === 1)) {
3361 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
3362 }
3363 this.el = el; // root element
3364 this.options = options = _extends({}, options);
3365
3366 // Export instance
3367 el[expando] = this;
3368 var defaults = {
3369 group: null,
3370 sort: true,
3371 disabled: false,
3372 store: null,
3373 handle: null,
3374 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
3375 swapThreshold: 1,
3376 // percentage; 0 <= x <= 1
3377 invertSwap: false,
3378 // invert always
3379 invertedSwapThreshold: null,
3380 // will be set to same as swapThreshold if default
3381 removeCloneOnHide: true,
3382 direction: function direction() {
3383 return _detectDirection(el, this.options);
3384 },
3385 ghostClass: 'sortable-ghost',
3386 chosenClass: 'sortable-chosen',
3387 dragClass: 'sortable-drag',
3388 ignore: 'a, img',
3389 filter: null,
3390 preventOnFilter: true,
3391 animation: 0,
3392 easing: null,
3393 setData: function setData(dataTransfer, dragEl) {
3394 dataTransfer.setData('Text', dragEl.textContent);
3395 },
3396 dropBubble: false,
3397 dragoverBubble: false,
3398 dataIdAttr: 'data-id',
3399 delay: 0,
3400 delayOnTouchOnly: false,
3401 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
3402 forceFallback: false,
3403 fallbackClass: 'sortable-fallback',
3404 fallbackOnBody: false,
3405 fallbackTolerance: 0,
3406 fallbackOffset: {
3407 x: 0,
3408 y: 0
3409 },
3410 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
3411 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
3412 emptyInsertThreshold: 5
3413 };
3414 PluginManager.initializePlugins(this, el, defaults);
3415
3416 // Set default options
3417 for (var name in defaults) {
3418 !(name in options) && (options[name] = defaults[name]);
3419 }
3420 _prepareGroup(options);
3421
3422 // Bind all private methods
3423 for (var fn in this) {
3424 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3425 this[fn] = this[fn].bind(this);
3426 }
3427 }
3428
3429 // Setup drag mode
3430 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
3431 if (this.nativeDraggable) {
3432 // Touch start threshold cannot be greater than the native dragstart threshold
3433 this.options.touchStartThreshold = 1;
3434 }
3435
3436 // Bind events
3437 if (options.supportPointer) {
3438 on(el, 'pointerdown', this._onTapStart);
3439 } else {
3440 on(el, 'mousedown', this._onTapStart);
3441 on(el, 'touchstart', this._onTapStart);
3442 }
3443 if (this.nativeDraggable) {
3444 on(el, 'dragover', this);
3445 on(el, 'dragenter', this);
3446 }
3447 sortables.push(this.el);
3448
3449 // Restore sorting
3450 options.store && options.store.get && this.sort(options.store.get(this) || []);
3451
3452 // Add animation state manager
3453 _extends(this, AnimationStateManager());
3454 }
3455 Sortable.prototype = /** @lends Sortable.prototype */{
3456 constructor: Sortable,
3457 _isOutsideThisEl: function _isOutsideThisEl(target) {
3458 if (!this.el.contains(target) && target !== this.el) {
3459 lastTarget = null;
3460 }
3461 },
3462 _getDirection: function _getDirection(evt, target) {
3463 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
3464 },
3465 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
3466 if (!evt.cancelable) return;
3467 var _this = this,
3468 el = this.el,
3469 options = this.options,
3470 preventOnFilter = options.preventOnFilter,
3471 type = evt.type,
3472 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
3473 target = (touch || evt).target,
3474 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
3475 filter = options.filter;
3476 _saveInputCheckedState(el);
3477
3478 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
3479 if (dragEl) {
3480 return;
3481 }
3482 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
3483 return; // only left button and enabled
3484 }
3485
3486 // cancel dnd if original target is content editable
3487 if (originalTarget.isContentEditable) {
3488 return;
3489 }
3490
3491 // Safari ignores further event handling after mousedown
3492 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
3493 return;
3494 }
3495 target = closest(target, options.draggable, el, false);
3496 if (target && target.animated) {
3497 return;
3498 }
3499 if (lastDownEl === target) {
3500 // Ignoring duplicate `down`
3501 return;
3502 }
3503
3504 // Get the index of the dragged element within its parent
3505 oldIndex = index(target);
3506 oldDraggableIndex = index(target, options.draggable);
3507
3508 // Check filter
3509 if (typeof filter === 'function') {
3510 if (filter.call(this, evt, target, this)) {
3511 _dispatchEvent({
3512 sortable: _this,
3513 rootEl: originalTarget,
3514 name: 'filter',
3515 targetEl: target,
3516 toEl: el,
3517 fromEl: el
3518 });
3519 pluginEvent('filter', _this, {
3520 evt: evt
3521 });
3522 preventOnFilter && evt.preventDefault();
3523 return; // cancel dnd
3524 }
3525 } else if (filter) {
3526 filter = filter.split(',').some(function (criteria) {
3527 criteria = closest(originalTarget, criteria.trim(), el, false);
3528 if (criteria) {
3529 _dispatchEvent({
3530 sortable: _this,
3531 rootEl: criteria,
3532 name: 'filter',
3533 targetEl: target,
3534 fromEl: el,
3535 toEl: el
3536 });
3537 pluginEvent('filter', _this, {
3538 evt: evt
3539 });
3540 return true;
3541 }
3542 });
3543 if (filter) {
3544 preventOnFilter && evt.preventDefault();
3545 return; // cancel dnd
3546 }
3547 }
3548 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
3549 return;
3550 }
3551
3552 // Prepare `dragstart`
3553 this._prepareDragStart(evt, touch, target);
3554 },
3555 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
3556 var _this = this,
3557 el = _this.el,
3558 options = _this.options,
3559 ownerDocument = el.ownerDocument,
3560 dragStartFn;
3561 if (target && !dragEl && target.parentNode === el) {
3562 var dragRect = getRect(target);
3563 rootEl = el;
3564 dragEl = target;
3565 parentEl = dragEl.parentNode;
3566 nextEl = dragEl.nextSibling;
3567 lastDownEl = target;
3568 activeGroup = options.group;
3569 Sortable.dragged = dragEl;
3570 tapEvt = {
3571 target: dragEl,
3572 clientX: (touch || evt).clientX,
3573 clientY: (touch || evt).clientY
3574 };
3575 tapDistanceLeft = tapEvt.clientX - dragRect.left;
3576 tapDistanceTop = tapEvt.clientY - dragRect.top;
3577 this._lastX = (touch || evt).clientX;
3578 this._lastY = (touch || evt).clientY;
3579 dragEl.style['will-change'] = 'all';
3580 dragStartFn = function dragStartFn() {
3581 pluginEvent('delayEnded', _this, {
3582 evt: evt
3583 });
3584 if (Sortable.eventCanceled) {
3585 _this._onDrop();
3586 return;
3587 }
3588 // Delayed drag has been triggered
3589 // we can re-enable the events: touchmove/mousemove
3590 _this._disableDelayedDragEvents();
3591 if (!FireFox && _this.nativeDraggable) {
3592 dragEl.draggable = true;
3593 }
3594
3595 // Bind the events: dragstart/dragend
3596 _this._triggerDragStart(evt, touch);
3597
3598 // Drag start event
3599 _dispatchEvent({
3600 sortable: _this,
3601 name: 'choose',
3602 originalEvent: evt
3603 });
3604
3605 // Chosen item
3606 toggleClass(dragEl, options.chosenClass, true);
3607 };
3608
3609 // Disable "draggable"
3610 options.ignore.split(',').forEach(function (criteria) {
3611 find(dragEl, criteria.trim(), _disableDraggable);
3612 });
3613 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
3614 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
3615 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
3616 if (options.supportPointer) {
3617 on(ownerDocument, 'pointerup', _this._onDrop);
3618 // Native D&D triggers pointercancel
3619 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
3620 } else {
3621 on(ownerDocument, 'mouseup', _this._onDrop);
3622 on(ownerDocument, 'touchend', _this._onDrop);
3623 on(ownerDocument, 'touchcancel', _this._onDrop);
3624 }
3625
3626 // Make dragEl draggable (must be before delay for FireFox)
3627 if (FireFox && this.nativeDraggable) {
3628 this.options.touchStartThreshold = 4;
3629 dragEl.draggable = true;
3630 }
3631 pluginEvent('delayStart', this, {
3632 evt: evt
3633 });
3634
3635 // Delay is impossible for native DnD in Edge or IE
3636 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
3637 if (Sortable.eventCanceled) {
3638 this._onDrop();
3639 return;
3640 }
3641 // If the user moves the pointer or let go the click or touch
3642 // before the delay has been reached:
3643 // disable the delayed drag
3644 if (options.supportPointer) {
3645 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
3646 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
3647 } else {
3648 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
3649 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
3650 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
3651 }
3652 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
3653 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
3654 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
3655 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
3656 } else {
3657 dragStartFn();
3658 }
3659 }
3660 },
3661 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
3662 var touch = e.touches ? e.touches[0] : e;
3663 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))) {
3664 this._disableDelayedDrag();
3665 }
3666 },
3667 _disableDelayedDrag: function _disableDelayedDrag() {
3668 dragEl && _disableDraggable(dragEl);
3669 clearTimeout(this._dragStartTimer);
3670 this._disableDelayedDragEvents();
3671 },
3672 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
3673 var ownerDocument = this.el.ownerDocument;
3674 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
3675 off(ownerDocument, 'touchend', this._disableDelayedDrag);
3676 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
3677 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
3678 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
3679 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
3680 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
3681 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
3682 },
3683 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
3684 touch = touch || evt.pointerType == 'touch' && evt;
3685 if (!this.nativeDraggable || touch) {
3686 if (this.options.supportPointer) {
3687 on(document, 'pointermove', this._onTouchMove);
3688 } else if (touch) {
3689 on(document, 'touchmove', this._onTouchMove);
3690 } else {
3691 on(document, 'mousemove', this._onTouchMove);
3692 }
3693 } else {
3694 on(dragEl, 'dragend', this);
3695 on(rootEl, 'dragstart', this._onDragStart);
3696 }
3697 try {
3698 if (document.selection) {
3699 _nextTick(function () {
3700 document.selection.empty();
3701 });
3702 } else {
3703 window.getSelection().removeAllRanges();
3704 }
3705 } catch (err) {}
3706 },
3707 _dragStarted: function _dragStarted(fallback, evt) {
3708 awaitingDragStarted = false;
3709 if (rootEl && dragEl) {
3710 pluginEvent('dragStarted', this, {
3711 evt: evt
3712 });
3713 if (this.nativeDraggable) {
3714 on(document, 'dragover', _checkOutsideTargetEl);
3715 }
3716 var options = this.options;
3717
3718 // Apply effect
3719 !fallback && toggleClass(dragEl, options.dragClass, false);
3720 toggleClass(dragEl, options.ghostClass, true);
3721 Sortable.active = this;
3722 fallback && this._appendGhost();
3723
3724 // Drag start event
3725 _dispatchEvent({
3726 sortable: this,
3727 name: 'start',
3728 originalEvent: evt
3729 });
3730 } else {
3731 this._nulling();
3732 }
3733 },
3734 _emulateDragOver: function _emulateDragOver() {
3735 if (touchEvt) {
3736 this._lastX = touchEvt.clientX;
3737 this._lastY = touchEvt.clientY;
3738 _hideGhostForTarget();
3739 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3740 var parent = target;
3741 while (target && target.shadowRoot) {
3742 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3743 if (target === parent) break;
3744 parent = target;
3745 }
3746 dragEl.parentNode[expando]._isOutsideThisEl(target);
3747 if (parent) {
3748 do {
3749 if (parent[expando]) {
3750 var inserted = void 0;
3751 inserted = parent[expando]._onDragOver({
3752 clientX: touchEvt.clientX,
3753 clientY: touchEvt.clientY,
3754 target: target,
3755 rootEl: parent
3756 });
3757 if (inserted && !this.options.dragoverBubble) {
3758 break;
3759 }
3760 }
3761 target = parent; // store last element
3762 }
3763 /* jshint boss:true */ while (parent = getParentOrHost(parent));
3764 }
3765 _unhideGhostForTarget();
3766 }
3767 },
3768 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
3769 if (tapEvt) {
3770 var options = this.options,
3771 fallbackTolerance = options.fallbackTolerance,
3772 fallbackOffset = options.fallbackOffset,
3773 touch = evt.touches ? evt.touches[0] : evt,
3774 ghostMatrix = ghostEl && matrix(ghostEl, true),
3775 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
3776 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
3777 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
3778 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
3779 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
3780
3781 // only set the status to dragging, when we are actually dragging
3782 if (!Sortable.active && !awaitingDragStarted) {
3783 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
3784 return;
3785 }
3786 this._onDragStart(evt, true);
3787 }
3788 if (ghostEl) {
3789 if (ghostMatrix) {
3790 ghostMatrix.e += dx - (lastDx || 0);
3791 ghostMatrix.f += dy - (lastDy || 0);
3792 } else {
3793 ghostMatrix = {
3794 a: 1,
3795 b: 0,
3796 c: 0,
3797 d: 1,
3798 e: dx,
3799 f: dy
3800 };
3801 }
3802 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
3803 css(ghostEl, 'webkitTransform', cssMatrix);
3804 css(ghostEl, 'mozTransform', cssMatrix);
3805 css(ghostEl, 'msTransform', cssMatrix);
3806 css(ghostEl, 'transform', cssMatrix);
3807 lastDx = dx;
3808 lastDy = dy;
3809 touchEvt = touch;
3810 }
3811 evt.cancelable && evt.preventDefault();
3812 }
3813 },
3814 _appendGhost: function _appendGhost() {
3815 // Bug if using scale(): https://stackoverflow.com/questions/2637058
3816 // Not being adjusted for
3817 if (!ghostEl) {
3818 var container = this.options.fallbackOnBody ? document.body : rootEl,
3819 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
3820 options = this.options;
3821
3822 // Position absolutely
3823 if (PositionGhostAbsolutely) {
3824 // Get relatively positioned parent
3825 ghostRelativeParent = container;
3826 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
3827 ghostRelativeParent = ghostRelativeParent.parentNode;
3828 }
3829 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
3830 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
3831 rect.top += ghostRelativeParent.scrollTop;
3832 rect.left += ghostRelativeParent.scrollLeft;
3833 } else {
3834 ghostRelativeParent = getWindowScrollingElement();
3835 }
3836 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
3837 }
3838 ghostEl = dragEl.cloneNode(true);
3839 toggleClass(ghostEl, options.ghostClass, false);
3840 toggleClass(ghostEl, options.fallbackClass, true);
3841 toggleClass(ghostEl, options.dragClass, true);
3842 css(ghostEl, 'transition', '');
3843 css(ghostEl, 'transform', '');
3844 css(ghostEl, 'box-sizing', 'border-box');
3845 css(ghostEl, 'margin', 0);
3846 css(ghostEl, 'top', rect.top);
3847 css(ghostEl, 'left', rect.left);
3848 css(ghostEl, 'width', rect.width);
3849 css(ghostEl, 'height', rect.height);
3850 css(ghostEl, 'opacity', '0.8');
3851 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
3852 css(ghostEl, 'zIndex', '100000');
3853 css(ghostEl, 'pointerEvents', 'none');
3854 Sortable.ghost = ghostEl;
3855 container.appendChild(ghostEl);
3856
3857 // Set transform-origin
3858 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
3859 }
3860 },
3861 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
3862 var _this = this;
3863 var dataTransfer = evt.dataTransfer;
3864 var options = _this.options;
3865 pluginEvent('dragStart', this, {
3866 evt: evt
3867 });
3868 if (Sortable.eventCanceled) {
3869 this._onDrop();
3870 return;
3871 }
3872 pluginEvent('setupClone', this);
3873 if (!Sortable.eventCanceled) {
3874 cloneEl = clone(dragEl);
3875 cloneEl.removeAttribute("id");
3876 cloneEl.draggable = false;
3877 cloneEl.style['will-change'] = '';
3878 this._hideClone();
3879 toggleClass(cloneEl, this.options.chosenClass, false);
3880 Sortable.clone = cloneEl;
3881 }
3882
3883 // #1143: IFrame support workaround
3884 _this.cloneId = _nextTick(function () {
3885 pluginEvent('clone', _this);
3886 if (Sortable.eventCanceled) return;
3887 if (!_this.options.removeCloneOnHide) {
3888 rootEl.insertBefore(cloneEl, dragEl);
3889 }
3890 _this._hideClone();
3891 _dispatchEvent({
3892 sortable: _this,
3893 name: 'clone'
3894 });
3895 });
3896 !fallback && toggleClass(dragEl, options.dragClass, true);
3897
3898 // Set proper drop events
3899 if (fallback) {
3900 ignoreNextClick = true;
3901 _this._loopId = setInterval(_this._emulateDragOver, 50);
3902 } else {
3903 // Undo what was set in _prepareDragStart before drag started
3904 off(document, 'mouseup', _this._onDrop);
3905 off(document, 'touchend', _this._onDrop);
3906 off(document, 'touchcancel', _this._onDrop);
3907 if (dataTransfer) {
3908 dataTransfer.effectAllowed = 'move';
3909 options.setData && options.setData.call(_this, dataTransfer, dragEl);
3910 }
3911 on(document, 'drop', _this);
3912
3913 // #1276 fix:
3914 css(dragEl, 'transform', 'translateZ(0)');
3915 }
3916 awaitingDragStarted = true;
3917 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
3918 on(document, 'selectstart', _this);
3919 moved = true;
3920 window.getSelection().removeAllRanges();
3921 if (Safari) {
3922 css(document.body, 'user-select', 'none');
3923 }
3924 },
3925 // Returns true - if no further action is needed (either inserted or another condition)
3926 _onDragOver: function _onDragOver( /**Event*/evt) {
3927 var el = this.el,
3928 target = evt.target,
3929 dragRect,
3930 targetRect,
3931 revert,
3932 options = this.options,
3933 group = options.group,
3934 activeSortable = Sortable.active,
3935 isOwner = activeGroup === group,
3936 canSort = options.sort,
3937 fromSortable = putSortable || activeSortable,
3938 vertical,
3939 _this = this,
3940 completedFired = false;
3941 if (_silent) return;
3942 function dragOverEvent(name, extra) {
3943 pluginEvent(name, _this, _objectSpread2({
3944 evt: evt,
3945 isOwner: isOwner,
3946 axis: vertical ? 'vertical' : 'horizontal',
3947 revert: revert,
3948 dragRect: dragRect,
3949 targetRect: targetRect,
3950 canSort: canSort,
3951 fromSortable: fromSortable,
3952 target: target,
3953 completed: completed,
3954 onMove: function onMove(target, after) {
3955 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
3956 },
3957 changed: changed
3958 }, extra));
3959 }
3960
3961 // Capture animation state
3962 function capture() {
3963 dragOverEvent('dragOverAnimationCapture');
3964 _this.captureAnimationState();
3965 if (_this !== fromSortable) {
3966 fromSortable.captureAnimationState();
3967 }
3968 }
3969
3970 // Return invocation when dragEl is inserted (or completed)
3971 function completed(insertion) {
3972 dragOverEvent('dragOverCompleted', {
3973 insertion: insertion
3974 });
3975 if (insertion) {
3976 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
3977 if (isOwner) {
3978 activeSortable._hideClone();
3979 } else {
3980 activeSortable._showClone(_this);
3981 }
3982 if (_this !== fromSortable) {
3983 // Set ghost class to new sortable's ghost class
3984 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
3985 toggleClass(dragEl, options.ghostClass, true);
3986 }
3987 if (putSortable !== _this && _this !== Sortable.active) {
3988 putSortable = _this;
3989 } else if (_this === Sortable.active && putSortable) {
3990 putSortable = null;
3991 }
3992
3993 // Animation
3994 if (fromSortable === _this) {
3995 _this._ignoreWhileAnimating = target;
3996 }
3997 _this.animateAll(function () {
3998 dragOverEvent('dragOverAnimationComplete');
3999 _this._ignoreWhileAnimating = null;
4000 });
4001 if (_this !== fromSortable) {
4002 fromSortable.animateAll();
4003 fromSortable._ignoreWhileAnimating = null;
4004 }
4005 }
4006
4007 // Null lastTarget if it is not inside a previously swapped element
4008 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
4009 lastTarget = null;
4010 }
4011
4012 // no bubbling and not fallback
4013 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
4014 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
4015
4016 // Do not detect for empty insert if already inserted
4017 !insertion && nearestEmptyInsertDetectEvent(evt);
4018 }
4019 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
4020 return completedFired = true;
4021 }
4022
4023 // Call when dragEl has been inserted
4024 function changed() {
4025 newIndex = index(dragEl);
4026 newDraggableIndex = index(dragEl, options.draggable);
4027 _dispatchEvent({
4028 sortable: _this,
4029 name: 'change',
4030 toEl: el,
4031 newIndex: newIndex,
4032 newDraggableIndex: newDraggableIndex,
4033 originalEvent: evt
4034 });
4035 }
4036 if (evt.preventDefault !== void 0) {
4037 evt.cancelable && evt.preventDefault();
4038 }
4039 target = closest(target, options.draggable, el, true);
4040 dragOverEvent('dragOver');
4041 if (Sortable.eventCanceled) return completedFired;
4042 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
4043 return completed(false);
4044 }
4045 ignoreNextClick = false;
4046 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
4047 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
4048 vertical = this._getDirection(evt, target) === 'vertical';
4049 dragRect = getRect(dragEl);
4050 dragOverEvent('dragOverValid');
4051 if (Sortable.eventCanceled) return completedFired;
4052 if (revert) {
4053 parentEl = rootEl; // actualization
4054 capture();
4055 this._hideClone();
4056 dragOverEvent('revert');
4057 if (!Sortable.eventCanceled) {
4058 if (nextEl) {
4059 rootEl.insertBefore(dragEl, nextEl);
4060 } else {
4061 rootEl.appendChild(dragEl);
4062 }
4063 }
4064 return completed(true);
4065 }
4066 var elLastChild = lastChild(el, options.draggable);
4067 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
4068 // Insert to end of list
4069
4070 // If already at end of list: Do not insert
4071 if (elLastChild === dragEl) {
4072 return completed(false);
4073 }
4074
4075 // if there is a last element, it is the target
4076 if (elLastChild && el === evt.target) {
4077 target = elLastChild;
4078 }
4079 if (target) {
4080 targetRect = getRect(target);
4081 }
4082 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
4083 capture();
4084 if (elLastChild && elLastChild.nextSibling) {
4085 // the last draggable element is not the last node
4086 el.insertBefore(dragEl, elLastChild.nextSibling);
4087 } else {
4088 el.appendChild(dragEl);
4089 }
4090 parentEl = el; // actualization
4091
4092 changed();
4093 return completed(true);
4094 }
4095 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
4096 // Insert to start of list
4097 var firstChild = getChild(el, 0, options, true);
4098 if (firstChild === dragEl) {
4099 return completed(false);
4100 }
4101 target = firstChild;
4102 targetRect = getRect(target);
4103 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
4104 capture();
4105 el.insertBefore(dragEl, firstChild);
4106 parentEl = el; // actualization
4107
4108 changed();
4109 return completed(true);
4110 }
4111 } else if (target.parentNode === el) {
4112 targetRect = getRect(target);
4113 var direction = 0,
4114 targetBeforeFirstSwap,
4115 differentLevel = dragEl.parentNode !== el,
4116 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
4117 side1 = vertical ? 'top' : 'left',
4118 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
4119 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
4120 if (lastTarget !== target) {
4121 targetBeforeFirstSwap = targetRect[side1];
4122 pastFirstInvertThresh = false;
4123 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
4124 }
4125 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
4126 var sibling;
4127 if (direction !== 0) {
4128 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
4129 var dragIndex = index(dragEl);
4130 do {
4131 dragIndex -= direction;
4132 sibling = parentEl.children[dragIndex];
4133 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
4134 }
4135 // If dragEl is already beside target: Do not insert
4136 if (direction === 0 || sibling === target) {
4137 return completed(false);
4138 }
4139 lastTarget = target;
4140 lastDirection = direction;
4141 var nextSibling = target.nextElementSibling,
4142 after = false;
4143 after = direction === 1;
4144 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
4145 if (moveVector !== false) {
4146 if (moveVector === 1 || moveVector === -1) {
4147 after = moveVector === 1;
4148 }
4149 _silent = true;
4150 setTimeout(_unsilent, 30);
4151 capture();
4152 if (after && !nextSibling) {
4153 el.appendChild(dragEl);
4154 } else {
4155 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
4156 }
4157
4158 // Undo chrome's scroll adjustment (has no effect on other browsers)
4159 if (scrolledPastTop) {
4160 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
4161 }
4162 parentEl = dragEl.parentNode; // actualization
4163
4164 // must be done before animation
4165 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
4166 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
4167 }
4168 changed();
4169 return completed(true);
4170 }
4171 }
4172 if (el.contains(dragEl)) {
4173 return completed(false);
4174 }
4175 }
4176 return false;
4177 },
4178 _ignoreWhileAnimating: null,
4179 _offMoveEvents: function _offMoveEvents() {
4180 off(document, 'mousemove', this._onTouchMove);
4181 off(document, 'touchmove', this._onTouchMove);
4182 off(document, 'pointermove', this._onTouchMove);
4183 off(document, 'dragover', nearestEmptyInsertDetectEvent);
4184 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
4185 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
4186 },
4187 _offUpEvents: function _offUpEvents() {
4188 var ownerDocument = this.el.ownerDocument;
4189 off(ownerDocument, 'mouseup', this._onDrop);
4190 off(ownerDocument, 'touchend', this._onDrop);
4191 off(ownerDocument, 'pointerup', this._onDrop);
4192 off(ownerDocument, 'pointercancel', this._onDrop);
4193 off(ownerDocument, 'touchcancel', this._onDrop);
4194 off(document, 'selectstart', this);
4195 },
4196 _onDrop: function _onDrop( /**Event*/evt) {
4197 var el = this.el,
4198 options = this.options;
4199
4200 // Get the index of the dragged element within its parent
4201 newIndex = index(dragEl);
4202 newDraggableIndex = index(dragEl, options.draggable);
4203 pluginEvent('drop', this, {
4204 evt: evt
4205 });
4206 parentEl = dragEl && dragEl.parentNode;
4207
4208 // Get again after plugin event
4209 newIndex = index(dragEl);
4210 newDraggableIndex = index(dragEl, options.draggable);
4211 if (Sortable.eventCanceled) {
4212 this._nulling();
4213 return;
4214 }
4215 awaitingDragStarted = false;
4216 isCircumstantialInvert = false;
4217 pastFirstInvertThresh = false;
4218 clearInterval(this._loopId);
4219 clearTimeout(this._dragStartTimer);
4220 _cancelNextTick(this.cloneId);
4221 _cancelNextTick(this._dragStartId);
4222
4223 // Unbind events
4224 if (this.nativeDraggable) {
4225 off(document, 'drop', this);
4226 off(el, 'dragstart', this._onDragStart);
4227 }
4228 this._offMoveEvents();
4229 this._offUpEvents();
4230 if (Safari) {
4231 css(document.body, 'user-select', '');
4232 }
4233 css(dragEl, 'transform', '');
4234 if (evt) {
4235 if (moved) {
4236 evt.cancelable && evt.preventDefault();
4237 !options.dropBubble && evt.stopPropagation();
4238 }
4239 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
4240 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
4241 // Remove clone(s)
4242 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
4243 }
4244 if (dragEl) {
4245 if (this.nativeDraggable) {
4246 off(dragEl, 'dragend', this);
4247 }
4248 _disableDraggable(dragEl);
4249 dragEl.style['will-change'] = '';
4250
4251 // Remove classes
4252 // ghostClass is added in dragStarted
4253 if (moved && !awaitingDragStarted) {
4254 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
4255 }
4256 toggleClass(dragEl, this.options.chosenClass, false);
4257
4258 // Drag stop event
4259 _dispatchEvent({
4260 sortable: this,
4261 name: 'unchoose',
4262 toEl: parentEl,
4263 newIndex: null,
4264 newDraggableIndex: null,
4265 originalEvent: evt
4266 });
4267 if (rootEl !== parentEl) {
4268 if (newIndex >= 0) {
4269 // Add event
4270 _dispatchEvent({
4271 rootEl: parentEl,
4272 name: 'add',
4273 toEl: parentEl,
4274 fromEl: rootEl,
4275 originalEvent: evt
4276 });
4277
4278 // Remove event
4279 _dispatchEvent({
4280 sortable: this,
4281 name: 'remove',
4282 toEl: parentEl,
4283 originalEvent: evt
4284 });
4285
4286 // drag from one list and drop into another
4287 _dispatchEvent({
4288 rootEl: parentEl,
4289 name: 'sort',
4290 toEl: parentEl,
4291 fromEl: rootEl,
4292 originalEvent: evt
4293 });
4294 _dispatchEvent({
4295 sortable: this,
4296 name: 'sort',
4297 toEl: parentEl,
4298 originalEvent: evt
4299 });
4300 }
4301 putSortable && putSortable.save();
4302 } else {
4303 if (newIndex !== oldIndex) {
4304 if (newIndex >= 0) {
4305 // drag & drop within the same list
4306 _dispatchEvent({
4307 sortable: this,
4308 name: 'update',
4309 toEl: parentEl,
4310 originalEvent: evt
4311 });
4312 _dispatchEvent({
4313 sortable: this,
4314 name: 'sort',
4315 toEl: parentEl,
4316 originalEvent: evt
4317 });
4318 }
4319 }
4320 }
4321 if (Sortable.active) {
4322 /* jshint eqnull:true */
4323 if (newIndex == null || newIndex === -1) {
4324 newIndex = oldIndex;
4325 newDraggableIndex = oldDraggableIndex;
4326 }
4327 _dispatchEvent({
4328 sortable: this,
4329 name: 'end',
4330 toEl: parentEl,
4331 originalEvent: evt
4332 });
4333
4334 // Save sorting
4335 this.save();
4336 }
4337 }
4338 }
4339 this._nulling();
4340 },
4341 _nulling: function _nulling() {
4342 pluginEvent('nulling', this);
4343 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;
4344 var el = this.el;
4345 savedInputChecked.forEach(function (checkEl) {
4346 if (el.contains(checkEl)) {
4347 checkEl.checked = true;
4348 }
4349 });
4350 savedInputChecked.length = lastDx = lastDy = 0;
4351 },
4352 handleEvent: function handleEvent( /**Event*/evt) {
4353 switch (evt.type) {
4354 case 'drop':
4355 case 'dragend':
4356 this._onDrop(evt);
4357 break;
4358 case 'dragenter':
4359 case 'dragover':
4360 if (dragEl) {
4361 this._onDragOver(evt);
4362 _globalDragOver(evt);
4363 }
4364 break;
4365 case 'selectstart':
4366 evt.preventDefault();
4367 break;
4368 }
4369 },
4370 /**
4371 * Serializes the item into an array of string.
4372 * @returns {String[]}
4373 */
4374 toArray: function toArray() {
4375 var order = [],
4376 el,
4377 children = this.el.children,
4378 i = 0,
4379 n = children.length,
4380 options = this.options;
4381 for (; i < n; i++) {
4382 el = children[i];
4383 if (closest(el, options.draggable, this.el, false)) {
4384 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
4385 }
4386 }
4387 return order;
4388 },
4389 /**
4390 * Sorts the elements according to the array.
4391 * @param {String[]} order order of the items
4392 */
4393 sort: function sort(order, useAnimation) {
4394 var items = {},
4395 rootEl = this.el;
4396 this.toArray().forEach(function (id, i) {
4397 var el = rootEl.children[i];
4398 if (closest(el, this.options.draggable, rootEl, false)) {
4399 items[id] = el;
4400 }
4401 }, this);
4402 useAnimation && this.captureAnimationState();
4403 order.forEach(function (id) {
4404 if (items[id]) {
4405 rootEl.removeChild(items[id]);
4406 rootEl.appendChild(items[id]);
4407 }
4408 });
4409 useAnimation && this.animateAll();
4410 },
4411 /**
4412 * Save the current sorting
4413 */
4414 save: function save() {
4415 var store = this.options.store;
4416 store && store.set && store.set(this);
4417 },
4418 /**
4419 * 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.
4420 * @param {HTMLElement} el
4421 * @param {String} [selector] default: `options.draggable`
4422 * @returns {HTMLElement|null}
4423 */
4424 closest: function closest$1(el, selector) {
4425 return closest(el, selector || this.options.draggable, this.el, false);
4426 },
4427 /**
4428 * Set/get option
4429 * @param {string} name
4430 * @param {*} [value]
4431 * @returns {*}
4432 */
4433 option: function option(name, value) {
4434 var options = this.options;
4435 if (value === void 0) {
4436 return options[name];
4437 } else {
4438 var modifiedValue = PluginManager.modifyOption(this, name, value);
4439 if (typeof modifiedValue !== 'undefined') {
4440 options[name] = modifiedValue;
4441 } else {
4442 options[name] = value;
4443 }
4444 if (name === 'group') {
4445 _prepareGroup(options);
4446 }
4447 }
4448 },
4449 /**
4450 * Destroy
4451 */
4452 destroy: function destroy() {
4453 pluginEvent('destroy', this);
4454 var el = this.el;
4455 el[expando] = null;
4456 off(el, 'mousedown', this._onTapStart);
4457 off(el, 'touchstart', this._onTapStart);
4458 off(el, 'pointerdown', this._onTapStart);
4459 if (this.nativeDraggable) {
4460 off(el, 'dragover', this);
4461 off(el, 'dragenter', this);
4462 }
4463 // Remove draggable attributes
4464 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
4465 el.removeAttribute('draggable');
4466 });
4467 this._onDrop();
4468 this._disableDelayedDragEvents();
4469 sortables.splice(sortables.indexOf(this.el), 1);
4470 this.el = el = null;
4471 },
4472 _hideClone: function _hideClone() {
4473 if (!cloneHidden) {
4474 pluginEvent('hideClone', this);
4475 if (Sortable.eventCanceled) return;
4476 css(cloneEl, 'display', 'none');
4477 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
4478 cloneEl.parentNode.removeChild(cloneEl);
4479 }
4480 cloneHidden = true;
4481 }
4482 },
4483 _showClone: function _showClone(putSortable) {
4484 if (putSortable.lastPutMode !== 'clone') {
4485 this._hideClone();
4486 return;
4487 }
4488 if (cloneHidden) {
4489 pluginEvent('showClone', this);
4490 if (Sortable.eventCanceled) return;
4491
4492 // show clone at dragEl or original position
4493 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
4494 rootEl.insertBefore(cloneEl, dragEl);
4495 } else if (nextEl) {
4496 rootEl.insertBefore(cloneEl, nextEl);
4497 } else {
4498 rootEl.appendChild(cloneEl);
4499 }
4500 if (this.options.group.revertClone) {
4501 this.animate(dragEl, cloneEl);
4502 }
4503 css(cloneEl, 'display', '');
4504 cloneHidden = false;
4505 }
4506 }
4507 };
4508 function _globalDragOver( /**Event*/evt) {
4509 if (evt.dataTransfer) {
4510 evt.dataTransfer.dropEffect = 'move';
4511 }
4512 evt.cancelable && evt.preventDefault();
4513 }
4514 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
4515 var evt,
4516 sortable = fromEl[expando],
4517 onMoveFn = sortable.options.onMove,
4518 retVal;
4519 // Support for new CustomEvent feature
4520 if (window.CustomEvent && !IE11OrLess && !Edge) {
4521 evt = new CustomEvent('move', {
4522 bubbles: true,
4523 cancelable: true
4524 });
4525 } else {
4526 evt = document.createEvent('Event');
4527 evt.initEvent('move', true, true);
4528 }
4529 evt.to = toEl;
4530 evt.from = fromEl;
4531 evt.dragged = dragEl;
4532 evt.draggedRect = dragRect;
4533 evt.related = targetEl || toEl;
4534 evt.relatedRect = targetRect || getRect(toEl);
4535 evt.willInsertAfter = willInsertAfter;
4536 evt.originalEvent = originalEvent;
4537 fromEl.dispatchEvent(evt);
4538 if (onMoveFn) {
4539 retVal = onMoveFn.call(sortable, evt, originalEvent);
4540 }
4541 return retVal;
4542 }
4543 function _disableDraggable(el) {
4544 el.draggable = false;
4545 }
4546 function _unsilent() {
4547 _silent = false;
4548 }
4549 function _ghostIsFirst(evt, vertical, sortable) {
4550 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
4551 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4552 var spacer = 10;
4553 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;
4554 }
4555 function _ghostIsLast(evt, vertical, sortable) {
4556 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
4557 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4558 var spacer = 10;
4559 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;
4560 }
4561 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
4562 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
4563 targetLength = vertical ? targetRect.height : targetRect.width,
4564 targetS1 = vertical ? targetRect.top : targetRect.left,
4565 targetS2 = vertical ? targetRect.bottom : targetRect.right,
4566 invert = false;
4567 if (!invertSwap) {
4568 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
4569 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
4570 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
4571 // check if past first invert threshold on side opposite of lastDirection
4572 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
4573 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
4574 pastFirstInvertThresh = true;
4575 }
4576 if (!pastFirstInvertThresh) {
4577 // dragEl shadow (target move distance shadow)
4578 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
4579 : mouseOnAxis > targetS2 - targetMoveDistance) {
4580 return -lastDirection;
4581 }
4582 } else {
4583 invert = true;
4584 }
4585 } else {
4586 // Regular
4587 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
4588 return _getInsertDirection(target);
4589 }
4590 }
4591 }
4592 invert = invert || invertSwap;
4593 if (invert) {
4594 // Invert of regular
4595 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
4596 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
4597 }
4598 }
4599 return 0;
4600 }
4601
4602 /**
4603 * Gets the direction dragEl must be swapped relative to target in order to make it
4604 * seem that dragEl has been "inserted" into that element's position
4605 * @param {HTMLElement} target The target whose position dragEl is being inserted at
4606 * @return {Number} Direction dragEl must be swapped
4607 */
4608 function _getInsertDirection(target) {
4609 if (index(dragEl) < index(target)) {
4610 return 1;
4611 } else {
4612 return -1;
4613 }
4614 }
4615
4616 /**
4617 * Generate id
4618 * @param {HTMLElement} el
4619 * @returns {String}
4620 * @private
4621 */
4622 function _generateId(el) {
4623 var str = el.tagName + el.className + el.src + el.href + el.textContent,
4624 i = str.length,
4625 sum = 0;
4626 while (i--) {
4627 sum += str.charCodeAt(i);
4628 }
4629 return sum.toString(36);
4630 }
4631 function _saveInputCheckedState(root) {
4632 savedInputChecked.length = 0;
4633 var inputs = root.getElementsByTagName('input');
4634 var idx = inputs.length;
4635 while (idx--) {
4636 var el = inputs[idx];
4637 el.checked && savedInputChecked.push(el);
4638 }
4639 }
4640 function _nextTick(fn) {
4641 return setTimeout(fn, 0);
4642 }
4643 function _cancelNextTick(id) {
4644 return clearTimeout(id);
4645 }
4646
4647 // Fixed #973:
4648 if (documentExists) {
4649 on(document, 'touchmove', function (evt) {
4650 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
4651 evt.preventDefault();
4652 }
4653 });
4654 }
4655
4656 // Export utils
4657 Sortable.utils = {
4658 on: on,
4659 off: off,
4660 css: css,
4661 find: find,
4662 is: function is(el, selector) {
4663 return !!closest(el, selector, el, false);
4664 },
4665 extend: extend,
4666 throttle: throttle,
4667 closest: closest,
4668 toggleClass: toggleClass,
4669 clone: clone,
4670 index: index,
4671 nextTick: _nextTick,
4672 cancelNextTick: _cancelNextTick,
4673 detectDirection: _detectDirection,
4674 getChild: getChild,
4675 expando: expando
4676 };
4677
4678 /**
4679 * Get the Sortable instance of an element
4680 * @param {HTMLElement} element The element
4681 * @return {Sortable|undefined} The instance of Sortable
4682 */
4683 Sortable.get = function (element) {
4684 return element[expando];
4685 };
4686
4687 /**
4688 * Mount a plugin to Sortable
4689 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
4690 */
4691 Sortable.mount = function () {
4692 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
4693 plugins[_key] = arguments[_key];
4694 }
4695 if (plugins[0].constructor === Array) plugins = plugins[0];
4696 plugins.forEach(function (plugin) {
4697 if (!plugin.prototype || !plugin.prototype.constructor) {
4698 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
4699 }
4700 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
4701 PluginManager.mount(plugin);
4702 });
4703 };
4704
4705 /**
4706 * Create sortable instance
4707 * @param {HTMLElement} el
4708 * @param {Object} [options]
4709 */
4710 Sortable.create = function (el, options) {
4711 return new Sortable(el, options);
4712 };
4713
4714 // Export
4715 Sortable.version = version;
4716
4717 var autoScrolls = [],
4718 scrollEl,
4719 scrollRootEl,
4720 scrolling = false,
4721 lastAutoScrollX,
4722 lastAutoScrollY,
4723 touchEvt$1,
4724 pointerElemChangedInterval;
4725 function AutoScrollPlugin() {
4726 function AutoScroll() {
4727 this.defaults = {
4728 scroll: true,
4729 forceAutoScrollFallback: false,
4730 scrollSensitivity: 30,
4731 scrollSpeed: 10,
4732 bubbleScroll: true
4733 };
4734
4735 // Bind all private methods
4736 for (var fn in this) {
4737 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
4738 this[fn] = this[fn].bind(this);
4739 }
4740 }
4741 }
4742 AutoScroll.prototype = {
4743 dragStarted: function dragStarted(_ref) {
4744 var originalEvent = _ref.originalEvent;
4745 if (this.sortable.nativeDraggable) {
4746 on(document, 'dragover', this._handleAutoScroll);
4747 } else {
4748 if (this.options.supportPointer) {
4749 on(document, 'pointermove', this._handleFallbackAutoScroll);
4750 } else if (originalEvent.touches) {
4751 on(document, 'touchmove', this._handleFallbackAutoScroll);
4752 } else {
4753 on(document, 'mousemove', this._handleFallbackAutoScroll);
4754 }
4755 }
4756 },
4757 dragOverCompleted: function dragOverCompleted(_ref2) {
4758 var originalEvent = _ref2.originalEvent;
4759 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
4760 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
4761 this._handleAutoScroll(originalEvent);
4762 }
4763 },
4764 drop: function drop() {
4765 if (this.sortable.nativeDraggable) {
4766 off(document, 'dragover', this._handleAutoScroll);
4767 } else {
4768 off(document, 'pointermove', this._handleFallbackAutoScroll);
4769 off(document, 'touchmove', this._handleFallbackAutoScroll);
4770 off(document, 'mousemove', this._handleFallbackAutoScroll);
4771 }
4772 clearPointerElemChangedInterval();
4773 clearAutoScrolls();
4774 cancelThrottle();
4775 },
4776 nulling: function nulling() {
4777 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
4778 autoScrolls.length = 0;
4779 },
4780 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
4781 this._handleAutoScroll(evt, true);
4782 },
4783 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
4784 var _this = this;
4785 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4786 y = (evt.touches ? evt.touches[0] : evt).clientY,
4787 elem = document.elementFromPoint(x, y);
4788 touchEvt$1 = evt;
4789
4790 // IE does not seem to have native autoscroll,
4791 // Edge's autoscroll seems too conditional,
4792 // MACOS Safari does not have autoscroll,
4793 // Firefox and Chrome are good
4794 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
4795 autoScroll(evt, this.options, elem, fallback);
4796
4797 // Listener for pointer element change
4798 var ogElemScroller = getParentAutoScrollElement(elem, true);
4799 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
4800 pointerElemChangedInterval && clearPointerElemChangedInterval();
4801 // Detect for pointer elem change, emulating native DnD behaviour
4802 pointerElemChangedInterval = setInterval(function () {
4803 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
4804 if (newElem !== ogElemScroller) {
4805 ogElemScroller = newElem;
4806 clearAutoScrolls();
4807 }
4808 autoScroll(evt, _this.options, newElem, fallback);
4809 }, 10);
4810 lastAutoScrollX = x;
4811 lastAutoScrollY = y;
4812 }
4813 } else {
4814 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
4815 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
4816 clearAutoScrolls();
4817 return;
4818 }
4819 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
4820 }
4821 }
4822 };
4823 return _extends(AutoScroll, {
4824 pluginName: 'scroll',
4825 initializeByDefault: true
4826 });
4827 }
4828 function clearAutoScrolls() {
4829 autoScrolls.forEach(function (autoScroll) {
4830 clearInterval(autoScroll.pid);
4831 });
4832 autoScrolls = [];
4833 }
4834 function clearPointerElemChangedInterval() {
4835 clearInterval(pointerElemChangedInterval);
4836 }
4837 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
4838 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
4839 if (!options.scroll) return;
4840 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4841 y = (evt.touches ? evt.touches[0] : evt).clientY,
4842 sens = options.scrollSensitivity,
4843 speed = options.scrollSpeed,
4844 winScroller = getWindowScrollingElement();
4845 var scrollThisInstance = false,
4846 scrollCustomFn;
4847
4848 // New scroll root, set scrollEl
4849 if (scrollRootEl !== rootEl) {
4850 scrollRootEl = rootEl;
4851 clearAutoScrolls();
4852 scrollEl = options.scroll;
4853 scrollCustomFn = options.scrollFn;
4854 if (scrollEl === true) {
4855 scrollEl = getParentAutoScrollElement(rootEl, true);
4856 }
4857 }
4858 var layersOut = 0;
4859 var currentParent = scrollEl;
4860 do {
4861 var el = currentParent,
4862 rect = getRect(el),
4863 top = rect.top,
4864 bottom = rect.bottom,
4865 left = rect.left,
4866 right = rect.right,
4867 width = rect.width,
4868 height = rect.height,
4869 canScrollX = void 0,
4870 canScrollY = void 0,
4871 scrollWidth = el.scrollWidth,
4872 scrollHeight = el.scrollHeight,
4873 elCSS = css(el),
4874 scrollPosX = el.scrollLeft,
4875 scrollPosY = el.scrollTop;
4876 if (el === winScroller) {
4877 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
4878 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
4879 } else {
4880 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
4881 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
4882 }
4883 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
4884 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
4885 if (!autoScrolls[layersOut]) {
4886 for (var i = 0; i <= layersOut; i++) {
4887 if (!autoScrolls[i]) {
4888 autoScrolls[i] = {};
4889 }
4890 }
4891 }
4892 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
4893 autoScrolls[layersOut].el = el;
4894 autoScrolls[layersOut].vx = vx;
4895 autoScrolls[layersOut].vy = vy;
4896 clearInterval(autoScrolls[layersOut].pid);
4897 if (vx != 0 || vy != 0) {
4898 scrollThisInstance = true;
4899 /* jshint loopfunc:true */
4900 autoScrolls[layersOut].pid = setInterval(function () {
4901 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
4902 if (isFallback && this.layer === 0) {
4903 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
4904 }
4905 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
4906 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
4907 if (typeof scrollCustomFn === 'function') {
4908 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
4909 return;
4910 }
4911 }
4912 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
4913 }.bind({
4914 layer: layersOut
4915 }), 24);
4916 }
4917 }
4918 layersOut++;
4919 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
4920 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
4921 }, 30);
4922
4923 var drop = function drop(_ref) {
4924 var originalEvent = _ref.originalEvent,
4925 putSortable = _ref.putSortable,
4926 dragEl = _ref.dragEl,
4927 activeSortable = _ref.activeSortable,
4928 dispatchSortableEvent = _ref.dispatchSortableEvent,
4929 hideGhostForTarget = _ref.hideGhostForTarget,
4930 unhideGhostForTarget = _ref.unhideGhostForTarget;
4931 if (!originalEvent) return;
4932 var toSortable = putSortable || activeSortable;
4933 hideGhostForTarget();
4934 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
4935 var target = document.elementFromPoint(touch.clientX, touch.clientY);
4936 unhideGhostForTarget();
4937 if (toSortable && !toSortable.el.contains(target)) {
4938 dispatchSortableEvent('spill');
4939 this.onSpill({
4940 dragEl: dragEl,
4941 putSortable: putSortable
4942 });
4943 }
4944 };
4945 function Revert() {}
4946 Revert.prototype = {
4947 startIndex: null,
4948 dragStart: function dragStart(_ref2) {
4949 var oldDraggableIndex = _ref2.oldDraggableIndex;
4950 this.startIndex = oldDraggableIndex;
4951 },
4952 onSpill: function onSpill(_ref3) {
4953 var dragEl = _ref3.dragEl,
4954 putSortable = _ref3.putSortable;
4955 this.sortable.captureAnimationState();
4956 if (putSortable) {
4957 putSortable.captureAnimationState();
4958 }
4959 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
4960 if (nextSibling) {
4961 this.sortable.el.insertBefore(dragEl, nextSibling);
4962 } else {
4963 this.sortable.el.appendChild(dragEl);
4964 }
4965 this.sortable.animateAll();
4966 if (putSortable) {
4967 putSortable.animateAll();
4968 }
4969 },
4970 drop: drop
4971 };
4972 _extends(Revert, {
4973 pluginName: 'revertOnSpill'
4974 });
4975 function Remove() {}
4976 Remove.prototype = {
4977 onSpill: function onSpill(_ref4) {
4978 var dragEl = _ref4.dragEl,
4979 putSortable = _ref4.putSortable;
4980 var parentSortable = putSortable || this.sortable;
4981 parentSortable.captureAnimationState();
4982 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
4983 parentSortable.animateAll();
4984 },
4985 drop: drop
4986 };
4987 _extends(Remove, {
4988 pluginName: 'removeOnSpill'
4989 });
4990
4991 var lastSwapEl;
4992 function SwapPlugin() {
4993 function Swap() {
4994 this.defaults = {
4995 swapClass: 'sortable-swap-highlight'
4996 };
4997 }
4998 Swap.prototype = {
4999 dragStart: function dragStart(_ref) {
5000 var dragEl = _ref.dragEl;
5001 lastSwapEl = dragEl;
5002 },
5003 dragOverValid: function dragOverValid(_ref2) {
5004 var completed = _ref2.completed,
5005 target = _ref2.target,
5006 onMove = _ref2.onMove,
5007 activeSortable = _ref2.activeSortable,
5008 changed = _ref2.changed,
5009 cancel = _ref2.cancel;
5010 if (!activeSortable.options.swap) return;
5011 var el = this.sortable.el,
5012 options = this.options;
5013 if (target && target !== el) {
5014 var prevSwapEl = lastSwapEl;
5015 if (onMove(target) !== false) {
5016 toggleClass(target, options.swapClass, true);
5017 lastSwapEl = target;
5018 } else {
5019 lastSwapEl = null;
5020 }
5021 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
5022 toggleClass(prevSwapEl, options.swapClass, false);
5023 }
5024 }
5025 changed();
5026 completed(true);
5027 cancel();
5028 },
5029 drop: function drop(_ref3) {
5030 var activeSortable = _ref3.activeSortable,
5031 putSortable = _ref3.putSortable,
5032 dragEl = _ref3.dragEl;
5033 var toSortable = putSortable || this.sortable;
5034 var options = this.options;
5035 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
5036 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
5037 if (dragEl !== lastSwapEl) {
5038 toSortable.captureAnimationState();
5039 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
5040 swapNodes(dragEl, lastSwapEl);
5041 toSortable.animateAll();
5042 if (toSortable !== activeSortable) activeSortable.animateAll();
5043 }
5044 }
5045 },
5046 nulling: function nulling() {
5047 lastSwapEl = null;
5048 }
5049 };
5050 return _extends(Swap, {
5051 pluginName: 'swap',
5052 eventProperties: function eventProperties() {
5053 return {
5054 swapItem: lastSwapEl
5055 };
5056 }
5057 });
5058 }
5059 function swapNodes(n1, n2) {
5060 var p1 = n1.parentNode,
5061 p2 = n2.parentNode,
5062 i1,
5063 i2;
5064 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
5065 i1 = index(n1);
5066 i2 = index(n2);
5067 if (p1.isEqualNode(p2) && i1 < i2) {
5068 i2++;
5069 }
5070 p1.insertBefore(n2, p1.children[i1]);
5071 p2.insertBefore(n1, p2.children[i2]);
5072 }
5073
5074 var multiDragElements = [],
5075 multiDragClones = [],
5076 lastMultiDragSelect,
5077 // for selection with modifier key down (SHIFT)
5078 multiDragSortable,
5079 initialFolding = false,
5080 // Initial multi-drag fold when drag started
5081 folding = false,
5082 // Folding any other time
5083 dragStarted = false,
5084 dragEl$1,
5085 clonesFromRect,
5086 clonesHidden;
5087 function MultiDragPlugin() {
5088 function MultiDrag(sortable) {
5089 // Bind all private methods
5090 for (var fn in this) {
5091 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
5092 this[fn] = this[fn].bind(this);
5093 }
5094 }
5095 if (!sortable.options.avoidImplicitDeselect) {
5096 if (sortable.options.supportPointer) {
5097 on(document, 'pointerup', this._deselectMultiDrag);
5098 } else {
5099 on(document, 'mouseup', this._deselectMultiDrag);
5100 on(document, 'touchend', this._deselectMultiDrag);
5101 }
5102 }
5103 on(document, 'keydown', this._checkKeyDown);
5104 on(document, 'keyup', this._checkKeyUp);
5105 this.defaults = {
5106 selectedClass: 'sortable-selected',
5107 multiDragKey: null,
5108 avoidImplicitDeselect: false,
5109 setData: function setData(dataTransfer, dragEl) {
5110 var data = '';
5111 if (multiDragElements.length && multiDragSortable === sortable) {
5112 multiDragElements.forEach(function (multiDragElement, i) {
5113 data += (!i ? '' : ', ') + multiDragElement.textContent;
5114 });
5115 } else {
5116 data = dragEl.textContent;
5117 }
5118 dataTransfer.setData('Text', data);
5119 }
5120 };
5121 }
5122 MultiDrag.prototype = {
5123 multiDragKeyDown: false,
5124 isMultiDrag: false,
5125 delayStartGlobal: function delayStartGlobal(_ref) {
5126 var dragged = _ref.dragEl;
5127 dragEl$1 = dragged;
5128 },
5129 delayEnded: function delayEnded() {
5130 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
5131 },
5132 setupClone: function setupClone(_ref2) {
5133 var sortable = _ref2.sortable,
5134 cancel = _ref2.cancel;
5135 if (!this.isMultiDrag) return;
5136 for (var i = 0; i < multiDragElements.length; i++) {
5137 multiDragClones.push(clone(multiDragElements[i]));
5138 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
5139 multiDragClones[i].draggable = false;
5140 multiDragClones[i].style['will-change'] = '';
5141 toggleClass(multiDragClones[i], this.options.selectedClass, false);
5142 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
5143 }
5144 sortable._hideClone();
5145 cancel();
5146 },
5147 clone: function clone(_ref3) {
5148 var sortable = _ref3.sortable,
5149 rootEl = _ref3.rootEl,
5150 dispatchSortableEvent = _ref3.dispatchSortableEvent,
5151 cancel = _ref3.cancel;
5152 if (!this.isMultiDrag) return;
5153 if (!this.options.removeCloneOnHide) {
5154 if (multiDragElements.length && multiDragSortable === sortable) {
5155 insertMultiDragClones(true, rootEl);
5156 dispatchSortableEvent('clone');
5157 cancel();
5158 }
5159 }
5160 },
5161 showClone: function showClone(_ref4) {
5162 var cloneNowShown = _ref4.cloneNowShown,
5163 rootEl = _ref4.rootEl,
5164 cancel = _ref4.cancel;
5165 if (!this.isMultiDrag) return;
5166 insertMultiDragClones(false, rootEl);
5167 multiDragClones.forEach(function (clone) {
5168 css(clone, 'display', '');
5169 });
5170 cloneNowShown();
5171 clonesHidden = false;
5172 cancel();
5173 },
5174 hideClone: function hideClone(_ref5) {
5175 var _this = this;
5176 var sortable = _ref5.sortable,
5177 cloneNowHidden = _ref5.cloneNowHidden,
5178 cancel = _ref5.cancel;
5179 if (!this.isMultiDrag) return;
5180 multiDragClones.forEach(function (clone) {
5181 css(clone, 'display', 'none');
5182 if (_this.options.removeCloneOnHide && clone.parentNode) {
5183 clone.parentNode.removeChild(clone);
5184 }
5185 });
5186 cloneNowHidden();
5187 clonesHidden = true;
5188 cancel();
5189 },
5190 dragStartGlobal: function dragStartGlobal(_ref6) {
5191 var sortable = _ref6.sortable;
5192 if (!this.isMultiDrag && multiDragSortable) {
5193 multiDragSortable.multiDrag._deselectMultiDrag();
5194 }
5195 multiDragElements.forEach(function (multiDragElement) {
5196 multiDragElement.sortableIndex = index(multiDragElement);
5197 });
5198
5199 // Sort multi-drag elements
5200 multiDragElements = multiDragElements.sort(function (a, b) {
5201 return a.sortableIndex - b.sortableIndex;
5202 });
5203 dragStarted = true;
5204 },
5205 dragStarted: function dragStarted(_ref7) {
5206 var _this2 = this;
5207 var sortable = _ref7.sortable;
5208 if (!this.isMultiDrag) return;
5209 if (this.options.sort) {
5210 // Capture rects,
5211 // hide multi drag elements (by positioning them absolute),
5212 // set multi drag elements rects to dragRect,
5213 // show multi drag elements,
5214 // animate to rects,
5215 // unset rects & remove from DOM
5216
5217 sortable.captureAnimationState();
5218 if (this.options.animation) {
5219 multiDragElements.forEach(function (multiDragElement) {
5220 if (multiDragElement === dragEl$1) return;
5221 css(multiDragElement, 'position', 'absolute');
5222 });
5223 var dragRect = getRect(dragEl$1, false, true, true);
5224 multiDragElements.forEach(function (multiDragElement) {
5225 if (multiDragElement === dragEl$1) return;
5226 setRect(multiDragElement, dragRect);
5227 });
5228 folding = true;
5229 initialFolding = true;
5230 }
5231 }
5232 sortable.animateAll(function () {
5233 folding = false;
5234 initialFolding = false;
5235 if (_this2.options.animation) {
5236 multiDragElements.forEach(function (multiDragElement) {
5237 unsetRect(multiDragElement);
5238 });
5239 }
5240
5241 // Remove all auxiliary multidrag items from el, if sorting enabled
5242 if (_this2.options.sort) {
5243 removeMultiDragElements();
5244 }
5245 });
5246 },
5247 dragOver: function dragOver(_ref8) {
5248 var target = _ref8.target,
5249 completed = _ref8.completed,
5250 cancel = _ref8.cancel;
5251 if (folding && ~multiDragElements.indexOf(target)) {
5252 completed(false);
5253 cancel();
5254 }
5255 },
5256 revert: function revert(_ref9) {
5257 var fromSortable = _ref9.fromSortable,
5258 rootEl = _ref9.rootEl,
5259 sortable = _ref9.sortable,
5260 dragRect = _ref9.dragRect;
5261 if (multiDragElements.length > 1) {
5262 // Setup unfold animation
5263 multiDragElements.forEach(function (multiDragElement) {
5264 sortable.addAnimationState({
5265 target: multiDragElement,
5266 rect: folding ? getRect(multiDragElement) : dragRect
5267 });
5268 unsetRect(multiDragElement);
5269 multiDragElement.fromRect = dragRect;
5270 fromSortable.removeAnimationState(multiDragElement);
5271 });
5272 folding = false;
5273 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
5274 }
5275 },
5276 dragOverCompleted: function dragOverCompleted(_ref10) {
5277 var sortable = _ref10.sortable,
5278 isOwner = _ref10.isOwner,
5279 insertion = _ref10.insertion,
5280 activeSortable = _ref10.activeSortable,
5281 parentEl = _ref10.parentEl,
5282 putSortable = _ref10.putSortable;
5283 var options = this.options;
5284 if (insertion) {
5285 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
5286 if (isOwner) {
5287 activeSortable._hideClone();
5288 }
5289 initialFolding = false;
5290 // If leaving sort:false root, or already folding - Fold to new location
5291 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
5292 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
5293 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
5294 multiDragElements.forEach(function (multiDragElement) {
5295 if (multiDragElement === dragEl$1) return;
5296 setRect(multiDragElement, dragRectAbsolute);
5297
5298 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
5299 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
5300 parentEl.appendChild(multiDragElement);
5301 });
5302 folding = true;
5303 }
5304
5305 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
5306 if (!isOwner) {
5307 // Only remove if not folding (folding will remove them anyways)
5308 if (!folding) {
5309 removeMultiDragElements();
5310 }
5311 if (multiDragElements.length > 1) {
5312 var clonesHiddenBefore = clonesHidden;
5313 activeSortable._showClone(sortable);
5314
5315 // Unfold animation for clones if showing from hidden
5316 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
5317 multiDragClones.forEach(function (clone) {
5318 activeSortable.addAnimationState({
5319 target: clone,
5320 rect: clonesFromRect
5321 });
5322 clone.fromRect = clonesFromRect;
5323 clone.thisAnimationDuration = null;
5324 });
5325 }
5326 } else {
5327 activeSortable._showClone(sortable);
5328 }
5329 }
5330 }
5331 },
5332 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
5333 var dragRect = _ref11.dragRect,
5334 isOwner = _ref11.isOwner,
5335 activeSortable = _ref11.activeSortable;
5336 multiDragElements.forEach(function (multiDragElement) {
5337 multiDragElement.thisAnimationDuration = null;
5338 });
5339 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
5340 clonesFromRect = _extends({}, dragRect);
5341 var dragMatrix = matrix(dragEl$1, true);
5342 clonesFromRect.top -= dragMatrix.f;
5343 clonesFromRect.left -= dragMatrix.e;
5344 }
5345 },
5346 dragOverAnimationComplete: function dragOverAnimationComplete() {
5347 if (folding) {
5348 folding = false;
5349 removeMultiDragElements();
5350 }
5351 },
5352 drop: function drop(_ref12) {
5353 var evt = _ref12.originalEvent,
5354 rootEl = _ref12.rootEl,
5355 parentEl = _ref12.parentEl,
5356 sortable = _ref12.sortable,
5357 dispatchSortableEvent = _ref12.dispatchSortableEvent,
5358 oldIndex = _ref12.oldIndex,
5359 putSortable = _ref12.putSortable;
5360 var toSortable = putSortable || this.sortable;
5361 if (!evt) return;
5362 var options = this.options,
5363 children = parentEl.children;
5364
5365 // Multi-drag selection
5366 if (!dragStarted) {
5367 if (options.multiDragKey && !this.multiDragKeyDown) {
5368 this._deselectMultiDrag();
5369 }
5370 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
5371 if (!~multiDragElements.indexOf(dragEl$1)) {
5372 multiDragElements.push(dragEl$1);
5373 dispatchEvent({
5374 sortable: sortable,
5375 rootEl: rootEl,
5376 name: 'select',
5377 targetEl: dragEl$1,
5378 originalEvent: evt
5379 });
5380
5381 // Modifier activated, select from last to dragEl
5382 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
5383 var lastIndex = index(lastMultiDragSelect),
5384 currentIndex = index(dragEl$1);
5385 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
5386 (function () {
5387 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
5388 // (but previous selection existed)
5389 var n, i;
5390 if (currentIndex > lastIndex) {
5391 i = lastIndex;
5392 n = currentIndex;
5393 } else {
5394 i = currentIndex;
5395 n = lastIndex + 1;
5396 }
5397 var filter = options.filter;
5398 for (; i < n; i++) {
5399 if (~multiDragElements.indexOf(children[i])) continue;
5400 // Check if element is draggable
5401 if (!closest(children[i], options.draggable, parentEl, false)) continue;
5402 // Check if element is filtered
5403 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
5404 return closest(children[i], criteria.trim(), parentEl, false);
5405 }));
5406 if (filtered) continue;
5407 toggleClass(children[i], options.selectedClass, true);
5408 multiDragElements.push(children[i]);
5409 dispatchEvent({
5410 sortable: sortable,
5411 rootEl: rootEl,
5412 name: 'select',
5413 targetEl: children[i],
5414 originalEvent: evt
5415 });
5416 }
5417 })();
5418 }
5419 } else {
5420 lastMultiDragSelect = dragEl$1;
5421 }
5422 multiDragSortable = toSortable;
5423 } else {
5424 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
5425 lastMultiDragSelect = null;
5426 dispatchEvent({
5427 sortable: sortable,
5428 rootEl: rootEl,
5429 name: 'deselect',
5430 targetEl: dragEl$1,
5431 originalEvent: evt
5432 });
5433 }
5434 }
5435
5436 // Multi-drag drop
5437 if (dragStarted && this.isMultiDrag) {
5438 folding = false;
5439 // Do not "unfold" after around dragEl if reverted
5440 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
5441 var dragRect = getRect(dragEl$1),
5442 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
5443 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
5444 toSortable.captureAnimationState();
5445 if (!initialFolding) {
5446 if (options.animation) {
5447 dragEl$1.fromRect = dragRect;
5448 multiDragElements.forEach(function (multiDragElement) {
5449 multiDragElement.thisAnimationDuration = null;
5450 if (multiDragElement !== dragEl$1) {
5451 var rect = folding ? getRect(multiDragElement) : dragRect;
5452 multiDragElement.fromRect = rect;
5453
5454 // Prepare unfold animation
5455 toSortable.addAnimationState({
5456 target: multiDragElement,
5457 rect: rect
5458 });
5459 }
5460 });
5461 }
5462
5463 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
5464 // properly they must all be removed
5465 removeMultiDragElements();
5466 multiDragElements.forEach(function (multiDragElement) {
5467 if (children[multiDragIndex]) {
5468 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
5469 } else {
5470 parentEl.appendChild(multiDragElement);
5471 }
5472 multiDragIndex++;
5473 });
5474
5475 // If initial folding is done, the elements may have changed position because they are now
5476 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
5477 // must be fired here as Sortable will not.
5478 if (oldIndex === index(dragEl$1)) {
5479 var update = false;
5480 multiDragElements.forEach(function (multiDragElement) {
5481 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
5482 update = true;
5483 return;
5484 }
5485 });
5486 if (update) {
5487 dispatchSortableEvent('update');
5488 dispatchSortableEvent('sort');
5489 }
5490 }
5491 }
5492
5493 // Must be done after capturing individual rects (scroll bar)
5494 multiDragElements.forEach(function (multiDragElement) {
5495 unsetRect(multiDragElement);
5496 });
5497 toSortable.animateAll();
5498 }
5499 multiDragSortable = toSortable;
5500 }
5501
5502 // Remove clones if necessary
5503 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
5504 multiDragClones.forEach(function (clone) {
5505 clone.parentNode && clone.parentNode.removeChild(clone);
5506 });
5507 }
5508 },
5509 nullingGlobal: function nullingGlobal() {
5510 this.isMultiDrag = dragStarted = false;
5511 multiDragClones.length = 0;
5512 },
5513 destroyGlobal: function destroyGlobal() {
5514 this._deselectMultiDrag();
5515 off(document, 'pointerup', this._deselectMultiDrag);
5516 off(document, 'mouseup', this._deselectMultiDrag);
5517 off(document, 'touchend', this._deselectMultiDrag);
5518 off(document, 'keydown', this._checkKeyDown);
5519 off(document, 'keyup', this._checkKeyUp);
5520 },
5521 _deselectMultiDrag: function _deselectMultiDrag(evt) {
5522 if (typeof dragStarted !== "undefined" && dragStarted) return;
5523
5524 // Only deselect if selection is in this sortable
5525 if (multiDragSortable !== this.sortable) return;
5526
5527 // Only deselect if target is not item in this sortable
5528 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
5529
5530 // Only deselect if left click
5531 if (evt && evt.button !== 0) return;
5532 while (multiDragElements.length) {
5533 var el = multiDragElements[0];
5534 toggleClass(el, this.options.selectedClass, false);
5535 multiDragElements.shift();
5536 dispatchEvent({
5537 sortable: this.sortable,
5538 rootEl: this.sortable.el,
5539 name: 'deselect',
5540 targetEl: el,
5541 originalEvent: evt
5542 });
5543 }
5544 },
5545 _checkKeyDown: function _checkKeyDown(evt) {
5546 if (evt.key === this.options.multiDragKey) {
5547 this.multiDragKeyDown = true;
5548 }
5549 },
5550 _checkKeyUp: function _checkKeyUp(evt) {
5551 if (evt.key === this.options.multiDragKey) {
5552 this.multiDragKeyDown = false;
5553 }
5554 }
5555 };
5556 return _extends(MultiDrag, {
5557 // Static methods & properties
5558 pluginName: 'multiDrag',
5559 utils: {
5560 /**
5561 * Selects the provided multi-drag item
5562 * @param {HTMLElement} el The element to be selected
5563 */
5564 select: function select(el) {
5565 var sortable = el.parentNode[expando];
5566 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
5567 if (multiDragSortable && multiDragSortable !== sortable) {
5568 multiDragSortable.multiDrag._deselectMultiDrag();
5569 multiDragSortable = sortable;
5570 }
5571 toggleClass(el, sortable.options.selectedClass, true);
5572 multiDragElements.push(el);
5573 },
5574 /**
5575 * Deselects the provided multi-drag item
5576 * @param {HTMLElement} el The element to be deselected
5577 */
5578 deselect: function deselect(el) {
5579 var sortable = el.parentNode[expando],
5580 index = multiDragElements.indexOf(el);
5581 if (!sortable || !sortable.options.multiDrag || !~index) return;
5582 toggleClass(el, sortable.options.selectedClass, false);
5583 multiDragElements.splice(index, 1);
5584 }
5585 },
5586 eventProperties: function eventProperties() {
5587 var _this3 = this;
5588 var oldIndicies = [],
5589 newIndicies = [];
5590 multiDragElements.forEach(function (multiDragElement) {
5591 oldIndicies.push({
5592 multiDragElement: multiDragElement,
5593 index: multiDragElement.sortableIndex
5594 });
5595
5596 // multiDragElements will already be sorted if folding
5597 var newIndex;
5598 if (folding && multiDragElement !== dragEl$1) {
5599 newIndex = -1;
5600 } else if (folding) {
5601 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
5602 } else {
5603 newIndex = index(multiDragElement);
5604 }
5605 newIndicies.push({
5606 multiDragElement: multiDragElement,
5607 index: newIndex
5608 });
5609 });
5610 return {
5611 items: _toConsumableArray(multiDragElements),
5612 clones: [].concat(multiDragClones),
5613 oldIndicies: oldIndicies,
5614 newIndicies: newIndicies
5615 };
5616 },
5617 optionListeners: {
5618 multiDragKey: function multiDragKey(key) {
5619 key = key.toLowerCase();
5620 if (key === 'ctrl') {
5621 key = 'Control';
5622 } else if (key.length > 1) {
5623 key = key.charAt(0).toUpperCase() + key.substr(1);
5624 }
5625 return key;
5626 }
5627 }
5628 });
5629 }
5630 function insertMultiDragElements(clonesInserted, rootEl) {
5631 multiDragElements.forEach(function (multiDragElement, i) {
5632 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
5633 if (target) {
5634 rootEl.insertBefore(multiDragElement, target);
5635 } else {
5636 rootEl.appendChild(multiDragElement);
5637 }
5638 });
5639 }
5640
5641 /**
5642 * Insert multi-drag clones
5643 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
5644 * @param {HTMLElement} rootEl
5645 */
5646 function insertMultiDragClones(elementsInserted, rootEl) {
5647 multiDragClones.forEach(function (clone, i) {
5648 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
5649 if (target) {
5650 rootEl.insertBefore(clone, target);
5651 } else {
5652 rootEl.appendChild(clone);
5653 }
5654 });
5655 }
5656 function removeMultiDragElements() {
5657 multiDragElements.forEach(function (multiDragElement) {
5658 if (multiDragElement === dragEl$1) return;
5659 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
5660 });
5661 }
5662
5663 Sortable.mount(new AutoScrollPlugin());
5664 Sortable.mount(Remove, Revert);
5665
5666 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
5667
5668
5669
5670 /***/ },
5671
5672 /***/ "./node_modules/toastify-js/src/toastify.css"
5673 /*!***************************************************!*\
5674 !*** ./node_modules/toastify-js/src/toastify.css ***!
5675 \***************************************************/
5676 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5677
5678 "use strict";
5679 __webpack_require__.r(__webpack_exports__);
5680 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5681 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5682 /* harmony export */ });
5683 /* 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");
5684 /* 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__);
5685 /* 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");
5686 /* 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__);
5687 /* 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");
5688 /* 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__);
5689 /* 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");
5690 /* 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__);
5691 /* 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");
5692 /* 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__);
5693 /* 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");
5694 /* 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__);
5695 /* 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");
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707 var options = {};
5708
5709 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5710 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5711
5712 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5713
5714 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5715 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5716
5717 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);
5718
5719
5720
5721
5722 /* 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);
5723
5724
5725 /***/ },
5726
5727 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
5728 /*!****************************************************************************!*\
5729 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
5730 \****************************************************************************/
5731 (module) {
5732
5733 "use strict";
5734
5735
5736 var stylesInDOM = [];
5737 function getIndexByIdentifier(identifier) {
5738 var result = -1;
5739 for (var i = 0; i < stylesInDOM.length; i++) {
5740 if (stylesInDOM[i].identifier === identifier) {
5741 result = i;
5742 break;
5743 }
5744 }
5745 return result;
5746 }
5747 function modulesToDom(list, options) {
5748 var idCountMap = {};
5749 var identifiers = [];
5750 for (var i = 0; i < list.length; i++) {
5751 var item = list[i];
5752 var id = options.base ? item[0] + options.base : item[0];
5753 var count = idCountMap[id] || 0;
5754 var identifier = "".concat(id, " ").concat(count);
5755 idCountMap[id] = count + 1;
5756 var indexByIdentifier = getIndexByIdentifier(identifier);
5757 var obj = {
5758 css: item[1],
5759 media: item[2],
5760 sourceMap: item[3],
5761 supports: item[4],
5762 layer: item[5]
5763 };
5764 if (indexByIdentifier !== -1) {
5765 stylesInDOM[indexByIdentifier].references++;
5766 stylesInDOM[indexByIdentifier].updater(obj);
5767 } else {
5768 var updater = addElementStyle(obj, options);
5769 options.byIndex = i;
5770 stylesInDOM.splice(i, 0, {
5771 identifier: identifier,
5772 updater: updater,
5773 references: 1
5774 });
5775 }
5776 identifiers.push(identifier);
5777 }
5778 return identifiers;
5779 }
5780 function addElementStyle(obj, options) {
5781 var api = options.domAPI(options);
5782 api.update(obj);
5783 var updater = function updater(newObj) {
5784 if (newObj) {
5785 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
5786 return;
5787 }
5788 api.update(obj = newObj);
5789 } else {
5790 api.remove();
5791 }
5792 };
5793 return updater;
5794 }
5795 module.exports = function (list, options) {
5796 options = options || {};
5797 list = list || [];
5798 var lastIdentifiers = modulesToDom(list, options);
5799 return function update(newList) {
5800 newList = newList || [];
5801 for (var i = 0; i < lastIdentifiers.length; i++) {
5802 var identifier = lastIdentifiers[i];
5803 var index = getIndexByIdentifier(identifier);
5804 stylesInDOM[index].references--;
5805 }
5806 var newLastIdentifiers = modulesToDom(newList, options);
5807 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
5808 var _identifier = lastIdentifiers[_i];
5809 var _index = getIndexByIdentifier(_identifier);
5810 if (stylesInDOM[_index].references === 0) {
5811 stylesInDOM[_index].updater();
5812 stylesInDOM.splice(_index, 1);
5813 }
5814 }
5815 lastIdentifiers = newLastIdentifiers;
5816 };
5817 };
5818
5819 /***/ },
5820
5821 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
5822 /*!********************************************************************!*\
5823 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
5824 \********************************************************************/
5825 (module) {
5826
5827 "use strict";
5828
5829
5830 var memo = {};
5831
5832 /* istanbul ignore next */
5833 function getTarget(target) {
5834 if (typeof memo[target] === "undefined") {
5835 var styleTarget = document.querySelector(target);
5836
5837 // Special case to return head of iframe instead of iframe itself
5838 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
5839 try {
5840 // This will throw an exception if access to iframe is blocked
5841 // due to cross-origin restrictions
5842 styleTarget = styleTarget.contentDocument.head;
5843 } catch (e) {
5844 // istanbul ignore next
5845 styleTarget = null;
5846 }
5847 }
5848 memo[target] = styleTarget;
5849 }
5850 return memo[target];
5851 }
5852
5853 /* istanbul ignore next */
5854 function insertBySelector(insert, style) {
5855 var target = getTarget(insert);
5856 if (!target) {
5857 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
5858 }
5859 target.appendChild(style);
5860 }
5861 module.exports = insertBySelector;
5862
5863 /***/ },
5864
5865 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
5866 /*!**********************************************************************!*\
5867 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
5868 \**********************************************************************/
5869 (module) {
5870
5871 "use strict";
5872
5873
5874 /* istanbul ignore next */
5875 function insertStyleElement(options) {
5876 var element = document.createElement("style");
5877 options.setAttributes(element, options.attributes);
5878 options.insert(element, options.options);
5879 return element;
5880 }
5881 module.exports = insertStyleElement;
5882
5883 /***/ },
5884
5885 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
5886 /*!**********************************************************************************!*\
5887 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
5888 \**********************************************************************************/
5889 (module, __unused_webpack_exports, __webpack_require__) {
5890
5891 "use strict";
5892
5893
5894 /* istanbul ignore next */
5895 function setAttributesWithoutAttributes(styleElement) {
5896 var nonce = true ? __webpack_require__.nc : 0;
5897 if (nonce) {
5898 styleElement.setAttribute("nonce", nonce);
5899 }
5900 }
5901 module.exports = setAttributesWithoutAttributes;
5902
5903 /***/ },
5904
5905 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
5906 /*!***************************************************************!*\
5907 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
5908 \***************************************************************/
5909 (module) {
5910
5911 "use strict";
5912
5913
5914 /* istanbul ignore next */
5915 function apply(styleElement, options, obj) {
5916 var css = "";
5917 if (obj.supports) {
5918 css += "@supports (".concat(obj.supports, ") {");
5919 }
5920 if (obj.media) {
5921 css += "@media ".concat(obj.media, " {");
5922 }
5923 var needLayer = typeof obj.layer !== "undefined";
5924 if (needLayer) {
5925 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
5926 }
5927 css += obj.css;
5928 if (needLayer) {
5929 css += "}";
5930 }
5931 if (obj.media) {
5932 css += "}";
5933 }
5934 if (obj.supports) {
5935 css += "}";
5936 }
5937 var sourceMap = obj.sourceMap;
5938 if (sourceMap && typeof btoa !== "undefined") {
5939 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
5940 }
5941
5942 // For old IE
5943 /* istanbul ignore if */
5944 options.styleTagTransform(css, styleElement, options.options);
5945 }
5946 function removeStyleElement(styleElement) {
5947 // istanbul ignore if
5948 if (styleElement.parentNode === null) {
5949 return false;
5950 }
5951 styleElement.parentNode.removeChild(styleElement);
5952 }
5953
5954 /* istanbul ignore next */
5955 function domAPI(options) {
5956 if (typeof document === "undefined") {
5957 return {
5958 update: function update() {},
5959 remove: function remove() {}
5960 };
5961 }
5962 var styleElement = options.insertStyleElement(options);
5963 return {
5964 update: function update(obj) {
5965 apply(styleElement, options, obj);
5966 },
5967 remove: function remove() {
5968 removeStyleElement(styleElement);
5969 }
5970 };
5971 }
5972 module.exports = domAPI;
5973
5974 /***/ },
5975
5976 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
5977 /*!*********************************************************************!*\
5978 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
5979 \*********************************************************************/
5980 (module) {
5981
5982 "use strict";
5983
5984
5985 /* istanbul ignore next */
5986 function styleTagTransform(css, styleElement) {
5987 if (styleElement.styleSheet) {
5988 styleElement.styleSheet.cssText = css;
5989 } else {
5990 while (styleElement.firstChild) {
5991 styleElement.removeChild(styleElement.firstChild);
5992 }
5993 styleElement.appendChild(document.createTextNode(css));
5994 }
5995 }
5996 module.exports = styleTagTransform;
5997
5998 /***/ },
5999
6000 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
6001 /*!**********************************************************!*\
6002 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
6003 \**********************************************************/
6004 (module) {
6005
6006 /*!
6007 * sweetalert2 v11.26.17
6008 * Released under the MIT License.
6009 */
6010 (function (global, factory) {
6011 true ? module.exports = factory() :
6012 0;
6013 })(this, (function () { 'use strict';
6014
6015 function _assertClassBrand(e, t, n) {
6016 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
6017 throw new TypeError("Private element is not present on this object");
6018 }
6019 function _checkPrivateRedeclaration(e, t) {
6020 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
6021 }
6022 function _classPrivateFieldGet2(s, a) {
6023 return s.get(_assertClassBrand(s, a));
6024 }
6025 function _classPrivateFieldInitSpec(e, t, a) {
6026 _checkPrivateRedeclaration(e, t), t.set(e, a);
6027 }
6028 function _classPrivateFieldSet2(s, a, r) {
6029 return s.set(_assertClassBrand(s, a), r), r;
6030 }
6031
6032 const RESTORE_FOCUS_TIMEOUT = 100;
6033
6034 /** @type {GlobalState} */
6035 const globalState = {};
6036 const focusPreviousActiveElement = () => {
6037 if (globalState.previousActiveElement instanceof HTMLElement) {
6038 globalState.previousActiveElement.focus();
6039 globalState.previousActiveElement = null;
6040 } else if (document.body) {
6041 document.body.focus();
6042 }
6043 };
6044
6045 /**
6046 * Restore previous active (focused) element
6047 *
6048 * @param {boolean} returnFocus
6049 * @returns {Promise<void>}
6050 */
6051 const restoreActiveElement = returnFocus => {
6052 return new Promise(resolve => {
6053 if (!returnFocus) {
6054 return resolve();
6055 }
6056 const x = window.scrollX;
6057 const y = window.scrollY;
6058 globalState.restoreFocusTimeout = setTimeout(() => {
6059 focusPreviousActiveElement();
6060 resolve();
6061 }, RESTORE_FOCUS_TIMEOUT); // issues/900
6062
6063 window.scrollTo(x, y);
6064 });
6065 };
6066
6067 const swalPrefix = 'swal2-';
6068
6069 /**
6070 * @typedef {Record<SwalClass, string>} SwalClasses
6071 */
6072
6073 /**
6074 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
6075 * @typedef {Record<SwalIcon, string>} SwalIcons
6076 */
6077
6078 /** @type {SwalClass[]} */
6079 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'];
6080 const swalClasses = classNames.reduce((acc, className) => {
6081 acc[className] = swalPrefix + className;
6082 return acc;
6083 }, /** @type {SwalClasses} */{});
6084
6085 /** @type {SwalIcon[]} */
6086 const icons = ['success', 'warning', 'info', 'question', 'error'];
6087 const iconTypes = icons.reduce((acc, icon) => {
6088 acc[icon] = swalPrefix + icon;
6089 return acc;
6090 }, /** @type {SwalIcons} */{});
6091
6092 const consolePrefix = 'SweetAlert2:';
6093
6094 /**
6095 * Capitalize the first letter of a string
6096 *
6097 * @param {string} str
6098 * @returns {string}
6099 */
6100 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
6101
6102 /**
6103 * Standardize console warnings
6104 *
6105 * @param {string | string[]} message
6106 */
6107 const warn = message => {
6108 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
6109 };
6110
6111 /**
6112 * Standardize console errors
6113 *
6114 * @param {string} message
6115 */
6116 const error = message => {
6117 console.error(`${consolePrefix} ${message}`);
6118 };
6119
6120 /**
6121 * Private global state for `warnOnce`
6122 *
6123 * @type {string[]}
6124 * @private
6125 */
6126 const previousWarnOnceMessages = [];
6127
6128 /**
6129 * Show a console warning, but only if it hasn't already been shown
6130 *
6131 * @param {string} message
6132 */
6133 const warnOnce = message => {
6134 if (!previousWarnOnceMessages.includes(message)) {
6135 previousWarnOnceMessages.push(message);
6136 warn(message);
6137 }
6138 };
6139
6140 /**
6141 * Show a one-time console warning about deprecated params/methods
6142 *
6143 * @param {string} deprecatedParam
6144 * @param {string?} useInstead
6145 */
6146 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
6147 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
6148 };
6149
6150 /**
6151 * If `arg` is a function, call it (with no arguments or context) and return the result.
6152 * Otherwise, just pass the value through
6153 *
6154 * @param {(() => *) | *} arg
6155 * @returns {*}
6156 */
6157 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
6158
6159 /**
6160 * @param {*} arg
6161 * @returns {boolean}
6162 */
6163 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
6164
6165 /**
6166 * @param {*} arg
6167 * @returns {Promise<*>}
6168 */
6169 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
6170
6171 /**
6172 * @param {*} arg
6173 * @returns {boolean}
6174 */
6175 const isPromise = arg => arg && Promise.resolve(arg) === arg;
6176
6177 /**
6178 * Gets the popup container which contains the backdrop and the popup itself.
6179 *
6180 * @returns {HTMLElement | null}
6181 */
6182 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
6183
6184 /**
6185 * @param {string} selectorString
6186 * @returns {HTMLElement | null}
6187 */
6188 const elementBySelector = selectorString => {
6189 const container = getContainer();
6190 return container ? container.querySelector(selectorString) : null;
6191 };
6192
6193 /**
6194 * @param {string} className
6195 * @returns {HTMLElement | null}
6196 */
6197 const elementByClass = className => {
6198 return elementBySelector(`.${className}`);
6199 };
6200
6201 /**
6202 * @returns {HTMLElement | null}
6203 */
6204 const getPopup = () => elementByClass(swalClasses.popup);
6205
6206 /**
6207 * @returns {HTMLElement | null}
6208 */
6209 const getIcon = () => elementByClass(swalClasses.icon);
6210
6211 /**
6212 * @returns {HTMLElement | null}
6213 */
6214 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6215
6216 /**
6217 * @returns {HTMLElement | null}
6218 */
6219 const getTitle = () => elementByClass(swalClasses.title);
6220
6221 /**
6222 * @returns {HTMLElement | null}
6223 */
6224 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6225
6226 /**
6227 * @returns {HTMLElement | null}
6228 */
6229 const getImage = () => elementByClass(swalClasses.image);
6230
6231 /**
6232 * @returns {HTMLElement | null}
6233 */
6234 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6235
6236 /**
6237 * @returns {HTMLElement | null}
6238 */
6239 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6240
6241 /**
6242 * @returns {HTMLButtonElement | null}
6243 */
6244 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6245
6246 /**
6247 * @returns {HTMLButtonElement | null}
6248 */
6249 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6250
6251 /**
6252 * @returns {HTMLButtonElement | null}
6253 */
6254 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6255
6256 /**
6257 * @returns {HTMLElement | null}
6258 */
6259 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6260
6261 /**
6262 * @returns {HTMLElement | null}
6263 */
6264 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6265
6266 /**
6267 * @returns {HTMLElement | null}
6268 */
6269 const getActions = () => elementByClass(swalClasses.actions);
6270
6271 /**
6272 * @returns {HTMLElement | null}
6273 */
6274 const getFooter = () => elementByClass(swalClasses.footer);
6275
6276 /**
6277 * @returns {HTMLElement | null}
6278 */
6279 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6280
6281 /**
6282 * @returns {HTMLElement | null}
6283 */
6284 const getCloseButton = () => elementByClass(swalClasses.close);
6285
6286 // https://github.com/jkup/focusable/blob/master/index.js
6287 const focusable = `
6288 a[href],
6289 area[href],
6290 input:not([disabled]),
6291 select:not([disabled]),
6292 textarea:not([disabled]),
6293 button:not([disabled]),
6294 iframe,
6295 object,
6296 embed,
6297 [tabindex="0"],
6298 [contenteditable],
6299 audio[controls],
6300 video[controls],
6301 summary
6302 `;
6303 /**
6304 * @returns {HTMLElement[]}
6305 */
6306 const getFocusableElements = () => {
6307 const popup = getPopup();
6308 if (!popup) {
6309 return [];
6310 }
6311 /** @type {NodeListOf<HTMLElement>} */
6312 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6313 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6314 // sort according to tabindex
6315 .sort((a, b) => {
6316 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6317 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6318 if (tabindexA > tabindexB) {
6319 return 1;
6320 } else if (tabindexA < tabindexB) {
6321 return -1;
6322 }
6323 return 0;
6324 });
6325
6326 /** @type {NodeListOf<HTMLElement>} */
6327 const otherFocusableElements = popup.querySelectorAll(focusable);
6328 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6329 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6330 };
6331
6332 /**
6333 * @returns {boolean}
6334 */
6335 const isModal = () => {
6336 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6337 };
6338
6339 /**
6340 * @returns {boolean}
6341 */
6342 const isToast = () => {
6343 const popup = getPopup();
6344 if (!popup) {
6345 return false;
6346 }
6347 return hasClass(popup, swalClasses.toast);
6348 };
6349
6350 /**
6351 * @returns {boolean}
6352 */
6353 const isLoading = () => {
6354 const popup = getPopup();
6355 if (!popup) {
6356 return false;
6357 }
6358 return popup.hasAttribute('data-loading');
6359 };
6360
6361 /**
6362 * Securely set innerHTML of an element
6363 * https://github.com/sweetalert2/sweetalert2/issues/1926
6364 *
6365 * @param {HTMLElement} elem
6366 * @param {string} html
6367 */
6368 const setInnerHtml = (elem, html) => {
6369 elem.textContent = '';
6370 if (html) {
6371 const parser = new DOMParser();
6372 const parsed = parser.parseFromString(html, `text/html`);
6373 const head = parsed.querySelector('head');
6374 if (head) {
6375 Array.from(head.childNodes).forEach(child => {
6376 elem.appendChild(child);
6377 });
6378 }
6379 const body = parsed.querySelector('body');
6380 if (body) {
6381 Array.from(body.childNodes).forEach(child => {
6382 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6383 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6384 } else {
6385 elem.appendChild(child);
6386 }
6387 });
6388 }
6389 }
6390 };
6391
6392 /**
6393 * @param {HTMLElement} elem
6394 * @param {string} className
6395 * @returns {boolean}
6396 */
6397 const hasClass = (elem, className) => {
6398 if (!className) {
6399 return false;
6400 }
6401 const classList = className.split(/\s+/);
6402 for (let i = 0; i < classList.length; i++) {
6403 if (!elem.classList.contains(classList[i])) {
6404 return false;
6405 }
6406 }
6407 return true;
6408 };
6409
6410 /**
6411 * @param {HTMLElement} elem
6412 * @param {SweetAlertOptions} params
6413 */
6414 const removeCustomClasses = (elem, params) => {
6415 Array.from(elem.classList).forEach(className => {
6416 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6417 elem.classList.remove(className);
6418 }
6419 });
6420 };
6421
6422 /**
6423 * @param {HTMLElement} elem
6424 * @param {SweetAlertOptions} params
6425 * @param {string} className
6426 */
6427 const applyCustomClass = (elem, params, className) => {
6428 removeCustomClasses(elem, params);
6429 if (!params.customClass) {
6430 return;
6431 }
6432 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6433 if (!customClass) {
6434 return;
6435 }
6436 if (typeof customClass !== 'string' && !customClass.forEach) {
6437 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6438 return;
6439 }
6440 addClass(elem, customClass);
6441 };
6442
6443 /**
6444 * @param {HTMLElement} popup
6445 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6446 * @returns {HTMLInputElement | null}
6447 */
6448 const getInput$1 = (popup, inputClass) => {
6449 if (!inputClass) {
6450 return null;
6451 }
6452 switch (inputClass) {
6453 case 'select':
6454 case 'textarea':
6455 case 'file':
6456 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6457 case 'checkbox':
6458 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6459 case 'radio':
6460 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6461 case 'range':
6462 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6463 default:
6464 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6465 }
6466 };
6467
6468 /**
6469 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6470 */
6471 const focusInput = input => {
6472 input.focus();
6473
6474 // place cursor at end of text in text input
6475 if (input.type !== 'file') {
6476 // http://stackoverflow.com/a/2345915
6477 const val = input.value;
6478 input.value = '';
6479 input.value = val;
6480 }
6481 };
6482
6483 /**
6484 * @param {HTMLElement | HTMLElement[] | null} target
6485 * @param {string | string[] | readonly string[] | undefined} classList
6486 * @param {boolean} condition
6487 */
6488 const toggleClass = (target, classList, condition) => {
6489 if (!target || !classList) {
6490 return;
6491 }
6492 if (typeof classList === 'string') {
6493 classList = classList.split(/\s+/).filter(Boolean);
6494 }
6495 classList.forEach(className => {
6496 if (Array.isArray(target)) {
6497 target.forEach(elem => {
6498 if (condition) {
6499 elem.classList.add(className);
6500 } else {
6501 elem.classList.remove(className);
6502 }
6503 });
6504 } else {
6505 if (condition) {
6506 target.classList.add(className);
6507 } else {
6508 target.classList.remove(className);
6509 }
6510 }
6511 });
6512 };
6513
6514 /**
6515 * @param {HTMLElement | HTMLElement[] | null} target
6516 * @param {string | string[] | readonly string[] | undefined} classList
6517 */
6518 const addClass = (target, classList) => {
6519 toggleClass(target, classList, true);
6520 };
6521
6522 /**
6523 * @param {HTMLElement | HTMLElement[] | null} target
6524 * @param {string | string[] | readonly string[] | undefined} classList
6525 */
6526 const removeClass = (target, classList) => {
6527 toggleClass(target, classList, false);
6528 };
6529
6530 /**
6531 * Get direct child of an element by class name
6532 *
6533 * @param {HTMLElement} elem
6534 * @param {string} className
6535 * @returns {HTMLElement | undefined}
6536 */
6537 const getDirectChildByClass = (elem, className) => {
6538 const children = Array.from(elem.children);
6539 for (let i = 0; i < children.length; i++) {
6540 const child = children[i];
6541 if (child instanceof HTMLElement && hasClass(child, className)) {
6542 return child;
6543 }
6544 }
6545 };
6546
6547 /**
6548 * @param {HTMLElement} elem
6549 * @param {string} property
6550 * @param {string | number | null | undefined} value
6551 */
6552 const applyNumericalStyle = (elem, property, value) => {
6553 if (value === `${parseInt(`${value}`)}`) {
6554 value = parseInt(value);
6555 }
6556 if (value || parseInt(`${value}`) === 0) {
6557 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
6558 } else {
6559 elem.style.removeProperty(property);
6560 }
6561 };
6562
6563 /**
6564 * @param {HTMLElement | null} elem
6565 * @param {string} display
6566 */
6567 const show = (elem, display = 'flex') => {
6568 if (!elem) {
6569 return;
6570 }
6571 elem.style.display = display;
6572 };
6573
6574 /**
6575 * @param {HTMLElement | null} elem
6576 */
6577 const hide = elem => {
6578 if (!elem) {
6579 return;
6580 }
6581 elem.style.display = 'none';
6582 };
6583
6584 /**
6585 * @param {HTMLElement | null} elem
6586 * @param {string} display
6587 */
6588 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6589 if (!elem) {
6590 return;
6591 }
6592 new MutationObserver(() => {
6593 toggle(elem, elem.innerHTML, display);
6594 }).observe(elem, {
6595 childList: true,
6596 subtree: true
6597 });
6598 };
6599
6600 /**
6601 * @param {HTMLElement} parent
6602 * @param {string} selector
6603 * @param {string} property
6604 * @param {string} value
6605 */
6606 const setStyle = (parent, selector, property, value) => {
6607 /** @type {HTMLElement | null} */
6608 const el = parent.querySelector(selector);
6609 if (el) {
6610 el.style.setProperty(property, value);
6611 }
6612 };
6613
6614 /**
6615 * @param {HTMLElement} elem
6616 * @param {boolean | string | null | undefined} condition
6617 * @param {string} display
6618 */
6619 const toggle = (elem, condition, display = 'flex') => {
6620 if (condition) {
6621 show(elem, display);
6622 } else {
6623 hide(elem);
6624 }
6625 };
6626
6627 /**
6628 * borrowed from jquery $(elem).is(':visible') implementation
6629 *
6630 * @param {HTMLElement | null} elem
6631 * @returns {boolean}
6632 */
6633 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6634
6635 /**
6636 * @returns {boolean}
6637 */
6638 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6639
6640 /**
6641 * @param {HTMLElement} elem
6642 * @returns {boolean}
6643 */
6644 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
6645
6646 /**
6647 * @param {HTMLElement} element
6648 * @param {HTMLElement} stopElement
6649 * @returns {boolean}
6650 */
6651 const selfOrParentIsScrollable = (element, stopElement) => {
6652 let parent = /** @type {HTMLElement | null} */element;
6653 while (parent && parent !== stopElement) {
6654 if (isScrollable(parent)) {
6655 return true;
6656 }
6657 parent = parent.parentElement;
6658 }
6659 return false;
6660 };
6661
6662 /**
6663 * borrowed from https://stackoverflow.com/a/46352119
6664 *
6665 * @param {HTMLElement} elem
6666 * @returns {boolean}
6667 */
6668 const hasCssAnimation = elem => {
6669 const style = window.getComputedStyle(elem);
6670 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6671 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6672 return animDuration > 0 || transDuration > 0;
6673 };
6674
6675 /**
6676 * @param {number} timer
6677 * @param {boolean} reset
6678 */
6679 const animateTimerProgressBar = (timer, reset = false) => {
6680 const timerProgressBar = getTimerProgressBar();
6681 if (!timerProgressBar) {
6682 return;
6683 }
6684 if (isVisible$1(timerProgressBar)) {
6685 if (reset) {
6686 timerProgressBar.style.transition = 'none';
6687 timerProgressBar.style.width = '100%';
6688 }
6689 setTimeout(() => {
6690 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6691 timerProgressBar.style.width = '0%';
6692 }, 10);
6693 }
6694 };
6695 const stopTimerProgressBar = () => {
6696 const timerProgressBar = getTimerProgressBar();
6697 if (!timerProgressBar) {
6698 return;
6699 }
6700 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6701 timerProgressBar.style.removeProperty('transition');
6702 timerProgressBar.style.width = '100%';
6703 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6704 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6705 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6706 };
6707
6708 /**
6709 * Detect Node env
6710 *
6711 * @returns {boolean}
6712 */
6713 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6714
6715 const sweetHTML = `
6716 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6717 <button type="button" class="${swalClasses.close}"></button>
6718 <ul class="${swalClasses['progress-steps']}"></ul>
6719 <div class="${swalClasses.icon}"></div>
6720 <img class="${swalClasses.image}" />
6721 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6722 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6723 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6724 <input type="file" class="${swalClasses.file}" />
6725 <div class="${swalClasses.range}">
6726 <input type="range" />
6727 <output></output>
6728 </div>
6729 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6730 <div class="${swalClasses.radio}"></div>
6731 <label class="${swalClasses.checkbox}">
6732 <input type="checkbox" id="${swalClasses.checkbox}" />
6733 <span class="${swalClasses.label}"></span>
6734 </label>
6735 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6736 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6737 <div class="${swalClasses.actions}">
6738 <div class="${swalClasses.loader}"></div>
6739 <button type="button" class="${swalClasses.confirm}"></button>
6740 <button type="button" class="${swalClasses.deny}"></button>
6741 <button type="button" class="${swalClasses.cancel}"></button>
6742 </div>
6743 <div class="${swalClasses.footer}"></div>
6744 <div class="${swalClasses['timer-progress-bar-container']}">
6745 <div class="${swalClasses['timer-progress-bar']}"></div>
6746 </div>
6747 </div>
6748 `.replace(/(^|\n)\s*/g, '');
6749
6750 /**
6751 * @returns {boolean}
6752 */
6753 const resetOldContainer = () => {
6754 const oldContainer = getContainer();
6755 if (!oldContainer) {
6756 return false;
6757 }
6758 oldContainer.remove();
6759 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
6760 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
6761 swalClasses['has-column']]);
6762 return true;
6763 };
6764 const resetValidationMessage$1 = () => {
6765 if (globalState.currentInstance) {
6766 globalState.currentInstance.resetValidationMessage();
6767 }
6768 };
6769 const addInputChangeListeners = () => {
6770 const popup = getPopup();
6771 if (!popup) {
6772 return;
6773 }
6774 const input = getDirectChildByClass(popup, swalClasses.input);
6775 const file = getDirectChildByClass(popup, swalClasses.file);
6776 /** @type {HTMLInputElement | null} */
6777 const range = popup.querySelector(`.${swalClasses.range} input`);
6778 /** @type {HTMLOutputElement | null} */
6779 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6780 const select = getDirectChildByClass(popup, swalClasses.select);
6781 /** @type {HTMLInputElement | null} */
6782 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6783 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6784 if (input) {
6785 input.oninput = resetValidationMessage$1;
6786 }
6787 if (file) {
6788 file.onchange = resetValidationMessage$1;
6789 }
6790 if (select) {
6791 select.onchange = resetValidationMessage$1;
6792 }
6793 if (checkbox) {
6794 checkbox.onchange = resetValidationMessage$1;
6795 }
6796 if (textarea) {
6797 textarea.oninput = resetValidationMessage$1;
6798 }
6799 if (range && rangeOutput) {
6800 range.oninput = () => {
6801 resetValidationMessage$1();
6802 rangeOutput.value = range.value;
6803 };
6804 range.onchange = () => {
6805 resetValidationMessage$1();
6806 rangeOutput.value = range.value;
6807 };
6808 }
6809 };
6810
6811 /**
6812 * @param {string | HTMLElement} target
6813 * @returns {HTMLElement}
6814 */
6815 const getTarget = target => {
6816 if (typeof target === 'string') {
6817 const element = document.querySelector(target);
6818 if (!element) {
6819 throw new Error(`Target element "${target}" not found`);
6820 }
6821 return /** @type {HTMLElement} */element;
6822 }
6823 return target;
6824 };
6825
6826 /**
6827 * @param {SweetAlertOptions} params
6828 */
6829 const setupAccessibility = params => {
6830 const popup = getPopup();
6831 if (!popup) {
6832 return;
6833 }
6834 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6835 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6836 if (!params.toast) {
6837 popup.setAttribute('aria-modal', 'true');
6838 }
6839 };
6840
6841 /**
6842 * @param {HTMLElement} targetElement
6843 */
6844 const setupRTL = targetElement => {
6845 if (window.getComputedStyle(targetElement).direction === 'rtl') {
6846 addClass(getContainer(), swalClasses.rtl);
6847 globalState.isRTL = true;
6848 }
6849 };
6850
6851 /**
6852 * Add modal + backdrop to DOM
6853 *
6854 * @param {SweetAlertOptions} params
6855 */
6856 const init = params => {
6857 // Clean up the old popup container if it exists
6858 const oldContainerExisted = resetOldContainer();
6859 if (isNodeEnv()) {
6860 error('SweetAlert2 requires document to initialize');
6861 return;
6862 }
6863 const container = document.createElement('div');
6864 container.className = swalClasses.container;
6865 if (oldContainerExisted) {
6866 addClass(container, swalClasses['no-transition']);
6867 }
6868 setInnerHtml(container, sweetHTML);
6869 container.dataset['swal2Theme'] = params.theme;
6870 const targetElement = getTarget(params.target || 'body');
6871 targetElement.appendChild(container);
6872 if (params.topLayer) {
6873 container.setAttribute('popover', '');
6874 container.showPopover();
6875 }
6876 setupAccessibility(params);
6877 setupRTL(targetElement);
6878 addInputChangeListeners();
6879 };
6880
6881 /**
6882 * @param {HTMLElement | object | string} param
6883 * @param {HTMLElement} target
6884 */
6885 const parseHtmlToContainer = (param, target) => {
6886 // DOM element
6887 if (param instanceof HTMLElement) {
6888 target.appendChild(param);
6889 }
6890
6891 // Object
6892 else if (typeof param === 'object') {
6893 handleObject(param, target);
6894 }
6895
6896 // Plain string
6897 else if (param) {
6898 setInnerHtml(target, param);
6899 }
6900 };
6901
6902 /**
6903 * @param {object} param
6904 * @param {HTMLElement} target
6905 */
6906 const handleObject = (param, target) => {
6907 // JQuery element(s)
6908 if ('jquery' in param) {
6909 handleJqueryElem(target, param);
6910 }
6911
6912 // For other objects use their string representation
6913 else {
6914 setInnerHtml(target, param.toString());
6915 }
6916 };
6917
6918 /**
6919 * @param {HTMLElement} target
6920 * @param {any} elem
6921 */
6922 const handleJqueryElem = (target, elem) => {
6923 target.textContent = '';
6924 if (0 in elem) {
6925 for (let i = 0; i in elem; i++) {
6926 target.appendChild(elem[i].cloneNode(true));
6927 }
6928 } else {
6929 target.appendChild(elem.cloneNode(true));
6930 }
6931 };
6932
6933 /**
6934 * @param {SweetAlert} instance
6935 * @param {SweetAlertOptions} params
6936 */
6937 const renderActions = (instance, params) => {
6938 const actions = getActions();
6939 const loader = getLoader();
6940 if (!actions || !loader) {
6941 return;
6942 }
6943
6944 // Actions (buttons) wrapper
6945 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
6946 hide(actions);
6947 } else {
6948 show(actions);
6949 }
6950
6951 // Custom class
6952 applyCustomClass(actions, params, 'actions');
6953
6954 // Render all the buttons
6955 renderButtons(actions, loader, params);
6956
6957 // Loader
6958 setInnerHtml(loader, params.loaderHtml || '');
6959 applyCustomClass(loader, params, 'loader');
6960 };
6961
6962 /**
6963 * @param {HTMLElement} actions
6964 * @param {HTMLElement} loader
6965 * @param {SweetAlertOptions} params
6966 */
6967 function renderButtons(actions, loader, params) {
6968 const confirmButton = getConfirmButton();
6969 const denyButton = getDenyButton();
6970 const cancelButton = getCancelButton();
6971 if (!confirmButton || !denyButton || !cancelButton) {
6972 return;
6973 }
6974
6975 // Render buttons
6976 renderButton(confirmButton, 'confirm', params);
6977 renderButton(denyButton, 'deny', params);
6978 renderButton(cancelButton, 'cancel', params);
6979 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
6980 if (params.reverseButtons) {
6981 if (params.toast) {
6982 actions.insertBefore(cancelButton, confirmButton);
6983 actions.insertBefore(denyButton, confirmButton);
6984 } else {
6985 actions.insertBefore(cancelButton, loader);
6986 actions.insertBefore(denyButton, loader);
6987 actions.insertBefore(confirmButton, loader);
6988 }
6989 }
6990 }
6991
6992 /**
6993 * @param {HTMLElement} confirmButton
6994 * @param {HTMLElement} denyButton
6995 * @param {HTMLElement} cancelButton
6996 * @param {SweetAlertOptions} params
6997 */
6998 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
6999 if (!params.buttonsStyling) {
7000 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7001 return;
7002 }
7003 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7004
7005 // Apply custom background colors to action buttons
7006 if (params.confirmButtonColor) {
7007 confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
7008 }
7009 if (params.denyButtonColor) {
7010 denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
7011 }
7012 if (params.cancelButtonColor) {
7013 cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
7014 }
7015
7016 // Apply the outline color to action buttons
7017 applyOutlineColor(confirmButton);
7018 applyOutlineColor(denyButton);
7019 applyOutlineColor(cancelButton);
7020 }
7021
7022 /**
7023 * @param {HTMLElement} button
7024 */
7025 function applyOutlineColor(button) {
7026 const buttonStyle = window.getComputedStyle(button);
7027 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
7028 // If the button already has a custom outline color, no need to change it
7029 return;
7030 }
7031 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
7032 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
7033 }
7034
7035 /**
7036 * @param {HTMLElement} button
7037 * @param {'confirm' | 'deny' | 'cancel'} buttonType
7038 * @param {SweetAlertOptions} params
7039 */
7040 function renderButton(button, buttonType, params) {
7041 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
7042 toggle(button, params[`show${buttonName}Button`], 'inline-block');
7043 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
7044 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
7045
7046 // Add buttons custom classes
7047 button.className = swalClasses[buttonType];
7048 applyCustomClass(button, params, `${buttonType}Button`);
7049 }
7050
7051 /**
7052 * @param {SweetAlert} instance
7053 * @param {SweetAlertOptions} params
7054 */
7055 const renderCloseButton = (instance, params) => {
7056 const closeButton = getCloseButton();
7057 if (!closeButton) {
7058 return;
7059 }
7060 setInnerHtml(closeButton, params.closeButtonHtml || '');
7061
7062 // Custom class
7063 applyCustomClass(closeButton, params, 'closeButton');
7064 toggle(closeButton, params.showCloseButton);
7065 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
7066 };
7067
7068 /**
7069 * @param {SweetAlert} instance
7070 * @param {SweetAlertOptions} params
7071 */
7072 const renderContainer = (instance, params) => {
7073 const container = getContainer();
7074 if (!container) {
7075 return;
7076 }
7077 handleBackdropParam(container, params.backdrop);
7078 handlePositionParam(container, params.position);
7079 handleGrowParam(container, params.grow);
7080
7081 // Custom class
7082 applyCustomClass(container, params, 'container');
7083 };
7084
7085 /**
7086 * @param {HTMLElement} container
7087 * @param {SweetAlertOptions['backdrop']} backdrop
7088 */
7089 function handleBackdropParam(container, backdrop) {
7090 if (typeof backdrop === 'string') {
7091 container.style.background = backdrop;
7092 } else if (!backdrop) {
7093 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
7094 }
7095 }
7096
7097 /**
7098 * @param {HTMLElement} container
7099 * @param {SweetAlertOptions['position']} position
7100 */
7101 function handlePositionParam(container, position) {
7102 if (!position) {
7103 return;
7104 }
7105 if (position in swalClasses) {
7106 addClass(container, swalClasses[position]);
7107 } else {
7108 warn('The "position" parameter is not valid, defaulting to "center"');
7109 addClass(container, swalClasses.center);
7110 }
7111 }
7112
7113 /**
7114 * @param {HTMLElement} container
7115 * @param {SweetAlertOptions['grow']} grow
7116 */
7117 function handleGrowParam(container, grow) {
7118 if (!grow) {
7119 return;
7120 }
7121 addClass(container, swalClasses[`grow-${grow}`]);
7122 }
7123
7124 /**
7125 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7126 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7127 * This is the approach that Babel will probably take to implement private methods/fields
7128 * https://github.com/tc39/proposal-private-methods
7129 * https://github.com/babel/babel/pull/7555
7130 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7131 * then we can use that language feature.
7132 */
7133
7134 var privateProps = {
7135 innerParams: new WeakMap(),
7136 domCache: new WeakMap()
7137 };
7138
7139 /// <reference path="../../../../sweetalert2.d.ts"/>
7140
7141
7142 /** @type {InputClass[]} */
7143 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
7144
7145 /**
7146 * @param {SweetAlert} instance
7147 * @param {SweetAlertOptions} params
7148 */
7149 const renderInput = (instance, params) => {
7150 const popup = getPopup();
7151 if (!popup) {
7152 return;
7153 }
7154 const innerParams = privateProps.innerParams.get(instance);
7155 const rerender = !innerParams || params.input !== innerParams.input;
7156 inputClasses.forEach(inputClass => {
7157 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
7158 if (!inputContainer) {
7159 return;
7160 }
7161
7162 // set attributes
7163 setAttributes(inputClass, params.inputAttributes);
7164
7165 // set class
7166 inputContainer.className = swalClasses[inputClass];
7167 if (rerender) {
7168 hide(inputContainer);
7169 }
7170 });
7171 if (params.input) {
7172 if (rerender) {
7173 showInput(params);
7174 }
7175 // set custom class
7176 setCustomClass(params);
7177 }
7178 };
7179
7180 /**
7181 * @param {SweetAlertOptions} params
7182 */
7183 const showInput = params => {
7184 if (!params.input) {
7185 return;
7186 }
7187 if (!renderInputType[params.input]) {
7188 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
7189 return;
7190 }
7191 const inputContainer = getInputContainer(params.input);
7192 if (!inputContainer) {
7193 return;
7194 }
7195 const input = renderInputType[params.input](inputContainer, params);
7196 show(inputContainer);
7197
7198 // input autofocus
7199 if (params.inputAutoFocus) {
7200 setTimeout(() => {
7201 focusInput(input);
7202 });
7203 }
7204 };
7205
7206 /**
7207 * @param {HTMLInputElement} input
7208 */
7209 const removeAttributes = input => {
7210 for (let i = 0; i < input.attributes.length; i++) {
7211 const attrName = input.attributes[i].name;
7212 if (!['id', 'type', 'value', 'style'].includes(attrName)) {
7213 input.removeAttribute(attrName);
7214 }
7215 }
7216 };
7217
7218 /**
7219 * @param {InputClass} inputClass
7220 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
7221 */
7222 const setAttributes = (inputClass, inputAttributes) => {
7223 const popup = getPopup();
7224 if (!popup) {
7225 return;
7226 }
7227 const input = getInput$1(popup, inputClass);
7228 if (!input) {
7229 return;
7230 }
7231 removeAttributes(input);
7232 for (const attr in inputAttributes) {
7233 input.setAttribute(attr, inputAttributes[attr]);
7234 }
7235 };
7236
7237 /**
7238 * @param {SweetAlertOptions} params
7239 */
7240 const setCustomClass = params => {
7241 if (!params.input) {
7242 return;
7243 }
7244 const inputContainer = getInputContainer(params.input);
7245 if (inputContainer) {
7246 applyCustomClass(inputContainer, params, 'input');
7247 }
7248 };
7249
7250 /**
7251 * @param {HTMLInputElement | HTMLTextAreaElement} input
7252 * @param {SweetAlertOptions} params
7253 */
7254 const setInputPlaceholder = (input, params) => {
7255 if (!input.placeholder && params.inputPlaceholder) {
7256 input.placeholder = params.inputPlaceholder;
7257 }
7258 };
7259
7260 /**
7261 * @param {Input} input
7262 * @param {Input} prependTo
7263 * @param {SweetAlertOptions} params
7264 */
7265 const setInputLabel = (input, prependTo, params) => {
7266 if (params.inputLabel) {
7267 const label = document.createElement('label');
7268 const labelClass = swalClasses['input-label'];
7269 label.setAttribute('for', input.id);
7270 label.className = labelClass;
7271 if (typeof params.customClass === 'object') {
7272 addClass(label, params.customClass.inputLabel);
7273 }
7274 label.innerText = params.inputLabel;
7275 prependTo.insertAdjacentElement('beforebegin', label);
7276 }
7277 };
7278
7279 /**
7280 * @param {SweetAlertInput} inputType
7281 * @returns {HTMLElement | undefined}
7282 */
7283 const getInputContainer = inputType => {
7284 const popup = getPopup();
7285 if (!popup) {
7286 return;
7287 }
7288 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7289 };
7290
7291 /**
7292 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7293 * @param {SweetAlertOptions['inputValue']} inputValue
7294 */
7295 const checkAndSetInputValue = (input, inputValue) => {
7296 if (['string', 'number'].includes(typeof inputValue)) {
7297 input.value = `${inputValue}`;
7298 } else if (!isPromise(inputValue)) {
7299 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7300 }
7301 };
7302
7303 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7304 const renderInputType = {};
7305
7306 /**
7307 * @param {Input | HTMLElement} input
7308 * @param {SweetAlertOptions} params
7309 * @returns {Input}
7310 */
7311 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} */
7312 (input, params) => {
7313 const inputElement = /** @type {HTMLInputElement} */input;
7314 checkAndSetInputValue(inputElement, params.inputValue);
7315 setInputLabel(inputElement, inputElement, params);
7316 setInputPlaceholder(inputElement, params);
7317 inputElement.type = /** @type {string} */params.input;
7318 return inputElement;
7319 };
7320
7321 /**
7322 * @param {Input | HTMLElement} input
7323 * @param {SweetAlertOptions} params
7324 * @returns {Input}
7325 */
7326 renderInputType.file = (input, params) => {
7327 const inputElement = /** @type {HTMLInputElement} */input;
7328 setInputLabel(inputElement, inputElement, params);
7329 setInputPlaceholder(inputElement, params);
7330 return inputElement;
7331 };
7332
7333 /**
7334 * @param {Input | HTMLElement} range
7335 * @param {SweetAlertOptions} params
7336 * @returns {Input}
7337 */
7338 renderInputType.range = (range, params) => {
7339 const rangeContainer = /** @type {HTMLElement} */range;
7340 const rangeInput = rangeContainer.querySelector('input');
7341 const rangeOutput = rangeContainer.querySelector('output');
7342 if (rangeInput) {
7343 checkAndSetInputValue(rangeInput, params.inputValue);
7344 rangeInput.type = /** @type {string} */params.input;
7345 setInputLabel(rangeInput, /** @type {Input} */range, params);
7346 }
7347 if (rangeOutput) {
7348 checkAndSetInputValue(rangeOutput, params.inputValue);
7349 }
7350 return /** @type {Input} */range;
7351 };
7352
7353 /**
7354 * @param {Input | HTMLElement} select
7355 * @param {SweetAlertOptions} params
7356 * @returns {Input}
7357 */
7358 renderInputType.select = (select, params) => {
7359 const selectElement = /** @type {HTMLSelectElement} */select;
7360 selectElement.textContent = '';
7361 if (params.inputPlaceholder) {
7362 const placeholder = document.createElement('option');
7363 setInnerHtml(placeholder, params.inputPlaceholder);
7364 placeholder.value = '';
7365 placeholder.disabled = true;
7366 placeholder.selected = true;
7367 selectElement.appendChild(placeholder);
7368 }
7369 setInputLabel(selectElement, selectElement, params);
7370 return selectElement;
7371 };
7372
7373 /**
7374 * @param {Input | HTMLElement} radio
7375 * @returns {Input}
7376 */
7377 renderInputType.radio = radio => {
7378 const radioElement = /** @type {HTMLElement} */radio;
7379 radioElement.textContent = '';
7380 return /** @type {Input} */radio;
7381 };
7382
7383 /**
7384 * @param {Input | HTMLElement} checkboxContainer
7385 * @param {SweetAlertOptions} params
7386 * @returns {Input}
7387 */
7388 renderInputType.checkbox = (checkboxContainer, params) => {
7389 const popup = getPopup();
7390 if (!popup) {
7391 throw new Error('Popup not found');
7392 }
7393 const checkbox = getInput$1(popup, 'checkbox');
7394 if (!checkbox) {
7395 throw new Error('Checkbox input not found');
7396 }
7397 checkbox.value = '1';
7398 checkbox.checked = Boolean(params.inputValue);
7399 const containerElement = /** @type {HTMLElement} */checkboxContainer;
7400 const label = containerElement.querySelector('span');
7401 if (label) {
7402 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
7403 if (placeholderOrLabel) {
7404 setInnerHtml(label, placeholderOrLabel);
7405 }
7406 }
7407 return checkbox;
7408 };
7409
7410 /**
7411 * @param {Input | HTMLElement} textarea
7412 * @param {SweetAlertOptions} params
7413 * @returns {Input}
7414 */
7415 renderInputType.textarea = (textarea, params) => {
7416 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
7417 checkAndSetInputValue(textareaElement, params.inputValue);
7418 setInputPlaceholder(textareaElement, params);
7419 setInputLabel(textareaElement, textareaElement, params);
7420
7421 /**
7422 * @param {HTMLElement} el
7423 * @returns {number}
7424 */
7425 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7426
7427 // https://github.com/sweetalert2/sweetalert2/issues/2291
7428 setTimeout(() => {
7429 // https://github.com/sweetalert2/sweetalert2/issues/1699
7430 if ('MutationObserver' in window) {
7431 const popup = getPopup();
7432 if (!popup) {
7433 return;
7434 }
7435 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
7436 const textareaResizeHandler = () => {
7437 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7438 if (!document.body.contains(textareaElement)) {
7439 return;
7440 }
7441 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
7442 const popupElement = getPopup();
7443 if (popupElement) {
7444 if (textareaWidth > initialPopupWidth) {
7445 popupElement.style.width = `${textareaWidth}px`;
7446 } else {
7447 applyNumericalStyle(popupElement, 'width', params.width);
7448 }
7449 }
7450 };
7451 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
7452 attributes: true,
7453 attributeFilter: ['style']
7454 });
7455 }
7456 });
7457 return textareaElement;
7458 };
7459
7460 /**
7461 * @param {SweetAlert} instance
7462 * @param {SweetAlertOptions} params
7463 */
7464 const renderContent = (instance, params) => {
7465 const htmlContainer = getHtmlContainer();
7466 if (!htmlContainer) {
7467 return;
7468 }
7469 showWhenInnerHtmlPresent(htmlContainer);
7470 applyCustomClass(htmlContainer, params, 'htmlContainer');
7471
7472 // Content as HTML
7473 if (params.html) {
7474 parseHtmlToContainer(params.html, htmlContainer);
7475 show(htmlContainer, 'block');
7476 }
7477
7478 // Content as plain text
7479 else if (params.text) {
7480 htmlContainer.textContent = params.text;
7481 show(htmlContainer, 'block');
7482 }
7483
7484 // No content
7485 else {
7486 hide(htmlContainer);
7487 }
7488 renderInput(instance, params);
7489 };
7490
7491 /**
7492 * @param {SweetAlert} instance
7493 * @param {SweetAlertOptions} params
7494 */
7495 const renderFooter = (instance, params) => {
7496 const footer = getFooter();
7497 if (!footer) {
7498 return;
7499 }
7500 showWhenInnerHtmlPresent(footer);
7501 toggle(footer, Boolean(params.footer), 'block');
7502 if (params.footer) {
7503 parseHtmlToContainer(params.footer, footer);
7504 }
7505
7506 // Custom class
7507 applyCustomClass(footer, params, 'footer');
7508 };
7509
7510 /**
7511 * @param {SweetAlert} instance
7512 * @param {SweetAlertOptions} params
7513 */
7514 const renderIcon = (instance, params) => {
7515 const innerParams = privateProps.innerParams.get(instance);
7516 const icon = getIcon();
7517 if (!icon) {
7518 return;
7519 }
7520
7521 // if the given icon already rendered, apply the styling without re-rendering the icon
7522 if (innerParams && params.icon === innerParams.icon) {
7523 // Custom or default content
7524 setContent(icon, params);
7525 applyStyles(icon, params);
7526 return;
7527 }
7528 if (!params.icon && !params.iconHtml) {
7529 hide(icon);
7530 return;
7531 }
7532 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7533 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7534 hide(icon);
7535 return;
7536 }
7537 show(icon);
7538
7539 // Custom or default content
7540 setContent(icon, params);
7541 applyStyles(icon, params);
7542
7543 // Animate icon
7544 addClass(icon, params.showClass && params.showClass.icon);
7545
7546 // Re-adjust the success icon on system theme change
7547 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7548 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7549 };
7550
7551 /**
7552 * @param {HTMLElement} icon
7553 * @param {SweetAlertOptions} params
7554 */
7555 const applyStyles = (icon, params) => {
7556 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7557 if (params.icon !== iconType) {
7558 removeClass(icon, iconClassName);
7559 }
7560 }
7561 addClass(icon, params.icon && iconTypes[params.icon]);
7562
7563 // Icon color
7564 setColor(icon, params);
7565
7566 // Success icon background color
7567 adjustSuccessIconBackgroundColor();
7568
7569 // Custom class
7570 applyCustomClass(icon, params, 'icon');
7571 };
7572
7573 // Adjust success icon background color to match the popup background color
7574 const adjustSuccessIconBackgroundColor = () => {
7575 const popup = getPopup();
7576 if (!popup) {
7577 return;
7578 }
7579 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7580 /** @type {NodeListOf<HTMLElement>} */
7581 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7582 for (let i = 0; i < successIconParts.length; i++) {
7583 successIconParts[i].style.backgroundColor = popupBackgroundColor;
7584 }
7585 };
7586
7587 /**
7588 *
7589 * @param {SweetAlertOptions} params
7590 * @returns {string}
7591 */
7592 const successIconHtml = params => `
7593 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7594 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7595 <div class="swal2-success-ring"></div>
7596 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7597 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7598 `;
7599 const errorIconHtml = `
7600 <span class="swal2-x-mark">
7601 <span class="swal2-x-mark-line-left"></span>
7602 <span class="swal2-x-mark-line-right"></span>
7603 </span>
7604 `;
7605
7606 /**
7607 * @param {HTMLElement} icon
7608 * @param {SweetAlertOptions} params
7609 */
7610 const setContent = (icon, params) => {
7611 if (!params.icon && !params.iconHtml) {
7612 return;
7613 }
7614 let oldContent = icon.innerHTML;
7615 let newContent = '';
7616 if (params.iconHtml) {
7617 newContent = iconContent(params.iconHtml);
7618 } else if (params.icon === 'success') {
7619 newContent = successIconHtml(params);
7620 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7621 } else if (params.icon === 'error') {
7622 newContent = errorIconHtml;
7623 } else if (params.icon) {
7624 const defaultIconHtml = {
7625 question: '?',
7626 warning: '!',
7627 info: 'i'
7628 };
7629 newContent = iconContent(defaultIconHtml[params.icon]);
7630 }
7631 if (oldContent.trim() !== newContent.trim()) {
7632 setInnerHtml(icon, newContent);
7633 }
7634 };
7635
7636 /**
7637 * @param {HTMLElement} icon
7638 * @param {SweetAlertOptions} params
7639 */
7640 const setColor = (icon, params) => {
7641 if (!params.iconColor) {
7642 return;
7643 }
7644 icon.style.color = params.iconColor;
7645 icon.style.borderColor = params.iconColor;
7646 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7647 setStyle(icon, sel, 'background-color', params.iconColor);
7648 }
7649 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7650 };
7651
7652 /**
7653 * @param {string} content
7654 * @returns {string}
7655 */
7656 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7657
7658 /**
7659 * @param {SweetAlert} instance
7660 * @param {SweetAlertOptions} params
7661 */
7662 const renderImage = (instance, params) => {
7663 const image = getImage();
7664 if (!image) {
7665 return;
7666 }
7667 if (!params.imageUrl) {
7668 hide(image);
7669 return;
7670 }
7671 show(image, '');
7672
7673 // Src, alt
7674 image.setAttribute('src', params.imageUrl);
7675 image.setAttribute('alt', params.imageAlt || '');
7676
7677 // Width, height
7678 applyNumericalStyle(image, 'width', params.imageWidth);
7679 applyNumericalStyle(image, 'height', params.imageHeight);
7680
7681 // Class
7682 image.className = swalClasses.image;
7683 applyCustomClass(image, params, 'image');
7684 };
7685
7686 let dragging = false;
7687 let mousedownX = 0;
7688 let mousedownY = 0;
7689 let initialX = 0;
7690 let initialY = 0;
7691
7692 /**
7693 * @param {HTMLElement} popup
7694 */
7695 const addDraggableListeners = popup => {
7696 popup.addEventListener('mousedown', down);
7697 document.body.addEventListener('mousemove', move);
7698 popup.addEventListener('mouseup', up);
7699 popup.addEventListener('touchstart', down);
7700 document.body.addEventListener('touchmove', move);
7701 popup.addEventListener('touchend', up);
7702 };
7703
7704 /**
7705 * @param {HTMLElement} popup
7706 */
7707 const removeDraggableListeners = popup => {
7708 popup.removeEventListener('mousedown', down);
7709 document.body.removeEventListener('mousemove', move);
7710 popup.removeEventListener('mouseup', up);
7711 popup.removeEventListener('touchstart', down);
7712 document.body.removeEventListener('touchmove', move);
7713 popup.removeEventListener('touchend', up);
7714 };
7715
7716 /**
7717 * @param {MouseEvent | TouchEvent} event
7718 */
7719 const down = event => {
7720 const popup = getPopup();
7721 if (!popup) {
7722 return;
7723 }
7724 const icon = getIcon();
7725 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
7726 dragging = true;
7727 const clientXY = getClientXY(event);
7728 mousedownX = clientXY.clientX;
7729 mousedownY = clientXY.clientY;
7730 initialX = parseInt(popup.style.insetInlineStart) || 0;
7731 initialY = parseInt(popup.style.insetBlockStart) || 0;
7732 addClass(popup, 'swal2-dragging');
7733 }
7734 };
7735
7736 /**
7737 * @param {MouseEvent | TouchEvent} event
7738 */
7739 const move = event => {
7740 const popup = getPopup();
7741 if (!popup) {
7742 return;
7743 }
7744 if (dragging) {
7745 let {
7746 clientX,
7747 clientY
7748 } = getClientXY(event);
7749 const deltaX = clientX - mousedownX;
7750 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
7751 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
7752 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7753 }
7754 };
7755 const up = () => {
7756 const popup = getPopup();
7757 dragging = false;
7758 removeClass(popup, 'swal2-dragging');
7759 };
7760
7761 /**
7762 * @param {MouseEvent | TouchEvent} event
7763 * @returns {{ clientX: number, clientY: number }}
7764 */
7765 const getClientXY = event => {
7766 let clientX = 0,
7767 clientY = 0;
7768 if (event.type.startsWith('mouse')) {
7769 clientX = /** @type {MouseEvent} */event.clientX;
7770 clientY = /** @type {MouseEvent} */event.clientY;
7771 } else if (event.type.startsWith('touch')) {
7772 clientX = /** @type {TouchEvent} */event.touches[0].clientX;
7773 clientY = /** @type {TouchEvent} */event.touches[0].clientY;
7774 }
7775 return {
7776 clientX,
7777 clientY
7778 };
7779 };
7780
7781 /**
7782 * @param {SweetAlert} instance
7783 * @param {SweetAlertOptions} params
7784 */
7785 const renderPopup = (instance, params) => {
7786 const container = getContainer();
7787 const popup = getPopup();
7788 if (!container || !popup) {
7789 return;
7790 }
7791
7792 // Width
7793 // https://github.com/sweetalert2/sweetalert2/issues/2170
7794 if (params.toast) {
7795 applyNumericalStyle(container, 'width', params.width);
7796 popup.style.width = '100%';
7797 const loader = getLoader();
7798 if (loader) {
7799 popup.insertBefore(loader, getIcon());
7800 }
7801 } else {
7802 applyNumericalStyle(popup, 'width', params.width);
7803 }
7804
7805 // Padding
7806 applyNumericalStyle(popup, 'padding', params.padding);
7807
7808 // Color
7809 if (params.color) {
7810 popup.style.color = params.color;
7811 }
7812
7813 // Background
7814 if (params.background) {
7815 popup.style.background = params.background;
7816 }
7817 hide(getValidationMessage());
7818
7819 // Classes
7820 addClasses$1(popup, params);
7821 if (params.draggable && !params.toast) {
7822 addClass(popup, swalClasses.draggable);
7823 addDraggableListeners(popup);
7824 } else {
7825 removeClass(popup, swalClasses.draggable);
7826 removeDraggableListeners(popup);
7827 }
7828 };
7829
7830 /**
7831 * @param {HTMLElement} popup
7832 * @param {SweetAlertOptions} params
7833 */
7834 const addClasses$1 = (popup, params) => {
7835 const showClass = params.showClass || {};
7836 // Default Class + showClass when updating Swal.update({})
7837 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7838 if (params.toast) {
7839 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7840 addClass(popup, swalClasses.toast);
7841 } else {
7842 addClass(popup, swalClasses.modal);
7843 }
7844
7845 // Custom class
7846 applyCustomClass(popup, params, 'popup');
7847 // TODO: remove in the next major
7848 if (typeof params.customClass === 'string') {
7849 addClass(popup, params.customClass);
7850 }
7851
7852 // Icon class (#1842)
7853 if (params.icon) {
7854 addClass(popup, swalClasses[`icon-${params.icon}`]);
7855 }
7856 };
7857
7858 /**
7859 * @param {SweetAlert} instance
7860 * @param {SweetAlertOptions} params
7861 */
7862 const renderProgressSteps = (instance, params) => {
7863 const progressStepsContainer = getProgressSteps();
7864 if (!progressStepsContainer) {
7865 return;
7866 }
7867 const {
7868 progressSteps,
7869 currentProgressStep
7870 } = params;
7871 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
7872 hide(progressStepsContainer);
7873 return;
7874 }
7875 show(progressStepsContainer);
7876 progressStepsContainer.textContent = '';
7877 if (currentProgressStep >= progressSteps.length) {
7878 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
7879 }
7880 progressSteps.forEach((step, index) => {
7881 const stepEl = createStepElement(step);
7882 progressStepsContainer.appendChild(stepEl);
7883 if (index === currentProgressStep) {
7884 addClass(stepEl, swalClasses['active-progress-step']);
7885 }
7886 if (index !== progressSteps.length - 1) {
7887 const lineEl = createLineElement(params);
7888 progressStepsContainer.appendChild(lineEl);
7889 }
7890 });
7891 };
7892
7893 /**
7894 * @param {string} step
7895 * @returns {HTMLLIElement}
7896 */
7897 const createStepElement = step => {
7898 const stepEl = document.createElement('li');
7899 addClass(stepEl, swalClasses['progress-step']);
7900 setInnerHtml(stepEl, step);
7901 return stepEl;
7902 };
7903
7904 /**
7905 * @param {SweetAlertOptions} params
7906 * @returns {HTMLLIElement}
7907 */
7908 const createLineElement = params => {
7909 const lineEl = document.createElement('li');
7910 addClass(lineEl, swalClasses['progress-step-line']);
7911 if (params.progressStepsDistance) {
7912 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
7913 }
7914 return lineEl;
7915 };
7916
7917 /**
7918 * @param {SweetAlert} instance
7919 * @param {SweetAlertOptions} params
7920 */
7921 const renderTitle = (instance, params) => {
7922 const title = getTitle();
7923 if (!title) {
7924 return;
7925 }
7926 showWhenInnerHtmlPresent(title);
7927 toggle(title, Boolean(params.title || params.titleText), 'block');
7928 if (params.title) {
7929 parseHtmlToContainer(params.title, title);
7930 }
7931 if (params.titleText) {
7932 title.innerText = params.titleText;
7933 }
7934
7935 // Custom class
7936 applyCustomClass(title, params, 'title');
7937 };
7938
7939 /**
7940 * @param {SweetAlert} instance
7941 * @param {SweetAlertOptions} params
7942 */
7943 const render = (instance, params) => {
7944 var _globalState$eventEmi;
7945 renderPopup(instance, params);
7946 renderContainer(instance, params);
7947 renderProgressSteps(instance, params);
7948 renderIcon(instance, params);
7949 renderImage(instance, params);
7950 renderTitle(instance, params);
7951 renderCloseButton(instance, params);
7952 renderContent(instance, params);
7953 renderActions(instance, params);
7954 renderFooter(instance, params);
7955 const popup = getPopup();
7956 if (typeof params.didRender === 'function' && popup) {
7957 params.didRender(popup);
7958 }
7959 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
7960 };
7961
7962 /*
7963 * Global function to determine if SweetAlert2 popup is shown
7964 */
7965 const isVisible = () => {
7966 return isVisible$1(getPopup());
7967 };
7968
7969 /*
7970 * Global function to click 'Confirm' button
7971 */
7972 const clickConfirm = () => {
7973 var _dom$getConfirmButton;
7974 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
7975 };
7976
7977 /*
7978 * Global function to click 'Deny' button
7979 */
7980 const clickDeny = () => {
7981 var _dom$getDenyButton;
7982 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
7983 };
7984
7985 /*
7986 * Global function to click 'Cancel' button
7987 */
7988 const clickCancel = () => {
7989 var _dom$getCancelButton;
7990 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
7991 };
7992
7993 /** @type {Record<DismissReason, DismissReason>} */
7994 const DismissReason = Object.freeze({
7995 cancel: 'cancel',
7996 backdrop: 'backdrop',
7997 close: 'close',
7998 esc: 'esc',
7999 timer: 'timer'
8000 });
8001
8002 /**
8003 * @param {GlobalState} globalState
8004 */
8005 const removeKeydownHandler = globalState => {
8006 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
8007 const handler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */globalState.keydownHandler;
8008 globalState.keydownTarget.removeEventListener('keydown', handler, {
8009 capture: globalState.keydownListenerCapture
8010 });
8011 globalState.keydownHandlerAdded = false;
8012 }
8013 };
8014
8015 /**
8016 * @param {GlobalState} globalState
8017 * @param {SweetAlertOptions} innerParams
8018 * @param {(dismiss: DismissReason) => void} dismissWith
8019 */
8020 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
8021 removeKeydownHandler(globalState);
8022 if (!innerParams.toast) {
8023 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
8024 const handler = e => keydownHandler(innerParams, e, dismissWith);
8025 globalState.keydownHandler = handler;
8026 const target = innerParams.keydownListenerCapture ? window : getPopup();
8027 if (target) {
8028 globalState.keydownTarget = target;
8029 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
8030 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
8031 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
8032 capture: globalState.keydownListenerCapture
8033 });
8034 globalState.keydownHandlerAdded = true;
8035 }
8036 }
8037 };
8038
8039 /**
8040 * @param {number} index
8041 * @param {number} increment
8042 */
8043 const setFocus = (index, increment) => {
8044 var _dom$getPopup;
8045 const focusableElements = getFocusableElements();
8046 // search for visible elements and select the next possible match
8047 if (focusableElements.length) {
8048 index = index + increment;
8049
8050 // shift + tab when .swal2-popup is focused
8051 if (index === -2) {
8052 index = focusableElements.length - 1;
8053 }
8054
8055 // rollover to first item
8056 if (index === focusableElements.length) {
8057 index = 0;
8058
8059 // go to last item
8060 } else if (index === -1) {
8061 index = focusableElements.length - 1;
8062 }
8063 focusableElements[index].focus();
8064 return;
8065 }
8066 // no visible focusable elements, focus the popup
8067 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
8068 };
8069 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
8070 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
8071
8072 /**
8073 * @param {SweetAlertOptions} innerParams
8074 * @param {KeyboardEvent} event
8075 * @param {(dismiss: DismissReason) => void} dismissWith
8076 */
8077 const keydownHandler = (innerParams, event, dismissWith) => {
8078 if (!innerParams) {
8079 return; // This instance has already been destroyed
8080 }
8081
8082 // Ignore keydown during IME composition
8083 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
8084 // https://github.com/sweetalert2/sweetalert2/issues/720
8085 // https://github.com/sweetalert2/sweetalert2/issues/2406
8086 if (event.isComposing || event.keyCode === 229) {
8087 return;
8088 }
8089 if (innerParams.stopKeydownPropagation) {
8090 event.stopPropagation();
8091 }
8092
8093 // ENTER
8094 if (event.key === 'Enter') {
8095 handleEnter(event, innerParams);
8096 }
8097
8098 // TAB
8099 else if (event.key === 'Tab') {
8100 handleTab(event);
8101 }
8102
8103 // ARROWS - switch focus between buttons
8104 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
8105 handleArrows(event.key);
8106 }
8107
8108 // ESC
8109 else if (event.key === 'Escape') {
8110 handleEsc(event, innerParams, dismissWith);
8111 }
8112 };
8113
8114 /**
8115 * @param {KeyboardEvent} event
8116 * @param {SweetAlertOptions} innerParams
8117 */
8118 const handleEnter = (event, innerParams) => {
8119 // https://github.com/sweetalert2/sweetalert2/issues/2386
8120 if (!callIfFunction(innerParams.allowEnterKey)) {
8121 return;
8122 }
8123 const popup = getPopup();
8124 if (!popup || !innerParams.input) {
8125 return;
8126 }
8127 const input = getInput$1(popup, innerParams.input);
8128 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
8129 if (['textarea', 'file'].includes(innerParams.input)) {
8130 return; // do not submit
8131 }
8132 clickConfirm();
8133 event.preventDefault();
8134 }
8135 };
8136
8137 /**
8138 * @param {KeyboardEvent} event
8139 */
8140 const handleTab = event => {
8141 const targetElement = event.target;
8142 const focusableElements = getFocusableElements();
8143 let btnIndex = -1;
8144 for (let i = 0; i < focusableElements.length; i++) {
8145 if (targetElement === focusableElements[i]) {
8146 btnIndex = i;
8147 break;
8148 }
8149 }
8150
8151 // Cycle to the next button
8152 if (!event.shiftKey) {
8153 setFocus(btnIndex, 1);
8154 }
8155
8156 // Cycle to the prev button
8157 else {
8158 setFocus(btnIndex, -1);
8159 }
8160 event.stopPropagation();
8161 event.preventDefault();
8162 };
8163
8164 /**
8165 * @param {string} key
8166 */
8167 const handleArrows = key => {
8168 const actions = getActions();
8169 const confirmButton = getConfirmButton();
8170 const denyButton = getDenyButton();
8171 const cancelButton = getCancelButton();
8172 if (!actions || !confirmButton || !denyButton || !cancelButton) {
8173 return;
8174 }
8175 /** @type HTMLElement[] */
8176 const buttons = [confirmButton, denyButton, cancelButton];
8177 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
8178 return;
8179 }
8180 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
8181 let buttonToFocus = document.activeElement;
8182 if (!buttonToFocus) {
8183 return;
8184 }
8185 for (let i = 0; i < actions.children.length; i++) {
8186 buttonToFocus = buttonToFocus[sibling];
8187 if (!buttonToFocus) {
8188 return;
8189 }
8190 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
8191 break;
8192 }
8193 }
8194 if (buttonToFocus instanceof HTMLButtonElement) {
8195 buttonToFocus.focus();
8196 }
8197 };
8198
8199 /**
8200 * @param {KeyboardEvent} event
8201 * @param {SweetAlertOptions} innerParams
8202 * @param {(dismiss: DismissReason) => void} dismissWith
8203 */
8204 const handleEsc = (event, innerParams, dismissWith) => {
8205 event.preventDefault();
8206 if (callIfFunction(innerParams.allowEscapeKey)) {
8207 dismissWith(DismissReason.esc);
8208 }
8209 };
8210
8211 /**
8212 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8213 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8214 * This is the approach that Babel will probably take to implement private methods/fields
8215 * https://github.com/tc39/proposal-private-methods
8216 * https://github.com/babel/babel/pull/7555
8217 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8218 * then we can use that language feature.
8219 */
8220
8221 var privateMethods = {
8222 swalPromiseResolve: new WeakMap(),
8223 swalPromiseReject: new WeakMap()
8224 };
8225
8226 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
8227 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
8228 // elements not within the active modal dialog will not be surfaced if a user opens a screen
8229 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
8230
8231 const setAriaHidden = () => {
8232 const container = getContainer();
8233 const bodyChildren = Array.from(document.body.children);
8234 bodyChildren.forEach(el => {
8235 if (el.contains(container)) {
8236 return;
8237 }
8238 if (el.hasAttribute('aria-hidden')) {
8239 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
8240 }
8241 el.setAttribute('aria-hidden', 'true');
8242 });
8243 };
8244 const unsetAriaHidden = () => {
8245 const bodyChildren = Array.from(document.body.children);
8246 bodyChildren.forEach(el => {
8247 if (el.hasAttribute('data-previous-aria-hidden')) {
8248 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
8249 el.removeAttribute('data-previous-aria-hidden');
8250 } else {
8251 el.removeAttribute('aria-hidden');
8252 }
8253 });
8254 };
8255
8256 // @ts-ignore
8257 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
8258
8259 /**
8260 * Fix iOS scrolling
8261 * http://stackoverflow.com/q/39626302
8262 */
8263 const iOSfix = () => {
8264 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
8265 const offset = document.body.scrollTop;
8266 document.body.style.top = `${offset * -1}px`;
8267 addClass(document.body, swalClasses.iosfix);
8268 lockBodyScroll();
8269 }
8270 };
8271
8272 /**
8273 * https://github.com/sweetalert2/sweetalert2/issues/1246
8274 */
8275 const lockBodyScroll = () => {
8276 const container = getContainer();
8277 if (!container) {
8278 return;
8279 }
8280 /** @type {boolean} */
8281 let preventTouchMove;
8282 /**
8283 * @param {TouchEvent} event
8284 */
8285 container.ontouchstart = event => {
8286 preventTouchMove = shouldPreventTouchMove(event);
8287 };
8288 /**
8289 * @param {TouchEvent} event
8290 */
8291 container.ontouchmove = event => {
8292 if (preventTouchMove) {
8293 event.preventDefault();
8294 event.stopPropagation();
8295 }
8296 };
8297 };
8298
8299 /**
8300 * @param {TouchEvent} event
8301 * @returns {boolean}
8302 */
8303 const shouldPreventTouchMove = event => {
8304 const target = event.target;
8305 const container = getContainer();
8306 const htmlContainer = getHtmlContainer();
8307 if (!container || !htmlContainer) {
8308 return false;
8309 }
8310 if (isStylus(event) || isZoom(event)) {
8311 return false;
8312 }
8313 if (target === container) {
8314 return true;
8315 }
8316 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8317 // #2823
8318 target.tagName !== 'INPUT' &&
8319 // #1603
8320 target.tagName !== 'TEXTAREA' &&
8321 // #2266
8322 !(isScrollable(htmlContainer) &&
8323 // #1944
8324 htmlContainer.contains(target))) {
8325 return true;
8326 }
8327 return false;
8328 };
8329
8330 /**
8331 * https://github.com/sweetalert2/sweetalert2/issues/1786
8332 *
8333 * @param {TouchEvent} event
8334 * @returns {boolean}
8335 */
8336 const isStylus = event => {
8337 return Boolean(event.touches && event.touches.length &&
8338 // @ts-ignore - touchType is not a standard property
8339 event.touches[0].touchType === 'stylus');
8340 };
8341
8342 /**
8343 * https://github.com/sweetalert2/sweetalert2/issues/1891
8344 *
8345 * @param {TouchEvent} event
8346 * @returns {boolean}
8347 */
8348 const isZoom = event => {
8349 return event.touches && event.touches.length > 1;
8350 };
8351 const undoIOSfix = () => {
8352 if (hasClass(document.body, swalClasses.iosfix)) {
8353 const offset = parseInt(document.body.style.top, 10);
8354 removeClass(document.body, swalClasses.iosfix);
8355 document.body.style.top = '';
8356 document.body.scrollTop = offset * -1;
8357 }
8358 };
8359
8360 /**
8361 * Measure scrollbar width for padding body during modal show/hide
8362 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8363 *
8364 * @returns {number}
8365 */
8366 const measureScrollbar = () => {
8367 const scrollDiv = document.createElement('div');
8368 scrollDiv.className = swalClasses['scrollbar-measure'];
8369 document.body.appendChild(scrollDiv);
8370 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8371 document.body.removeChild(scrollDiv);
8372 return scrollbarWidth;
8373 };
8374
8375 /**
8376 * Remember state in cases where opening and handling a modal will fiddle with it.
8377 * @type {number | null}
8378 */
8379 let previousBodyPadding = null;
8380
8381 /**
8382 * @param {string} initialBodyOverflow
8383 */
8384 const replaceScrollbarWithPadding = initialBodyOverflow => {
8385 // for queues, do not do this more than once
8386 if (previousBodyPadding !== null) {
8387 return;
8388 }
8389 // if the body has overflow
8390 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8391 ) {
8392 // add padding so the content doesn't shift after removal of scrollbar
8393 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8394 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8395 }
8396 };
8397 const undoReplaceScrollbarWithPadding = () => {
8398 if (previousBodyPadding !== null) {
8399 document.body.style.paddingRight = `${previousBodyPadding}px`;
8400 previousBodyPadding = null;
8401 }
8402 };
8403
8404 /**
8405 * @param {SweetAlert} instance
8406 * @param {HTMLElement} container
8407 * @param {boolean} returnFocus
8408 * @param {(() => void) | undefined} didClose
8409 */
8410 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8411 if (isToast()) {
8412 triggerDidCloseAndDispose(instance, didClose);
8413 } else {
8414 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8415 removeKeydownHandler(globalState);
8416 }
8417
8418 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8419 // for some reason removing the container in Safari will scroll the document to bottom
8420 if (isSafariOrIOS) {
8421 container.setAttribute('style', 'display:none !important');
8422 container.removeAttribute('class');
8423 container.innerHTML = '';
8424 } else {
8425 container.remove();
8426 }
8427 if (isModal()) {
8428 undoReplaceScrollbarWithPadding();
8429 undoIOSfix();
8430 unsetAriaHidden();
8431 }
8432 removeBodyClasses();
8433 }
8434
8435 /**
8436 * Remove SweetAlert2 classes from body
8437 */
8438 function removeBodyClasses() {
8439 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8440 }
8441
8442 /**
8443 * Instance method to close sweetAlert
8444 *
8445 * @param {SweetAlertResult | undefined} resolveValue
8446 * @this {SweetAlert}
8447 */
8448 function close(resolveValue) {
8449 resolveValue = prepareResolveValue(resolveValue);
8450 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8451 const didClose = triggerClosePopup(this);
8452 if (this.isAwaitingPromise) {
8453 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8454 if (!resolveValue.isDismissed) {
8455 handleAwaitingPromise(this);
8456 swalPromiseResolve(resolveValue);
8457 }
8458 } else if (didClose) {
8459 // Resolve Swal promise
8460 swalPromiseResolve(resolveValue);
8461 }
8462 }
8463
8464 /**
8465 * @param {SweetAlert} instance
8466 * @returns {boolean}
8467 */
8468 const triggerClosePopup = instance => {
8469 const popup = getPopup();
8470 if (!popup) {
8471 return false;
8472 }
8473 const innerParams = privateProps.innerParams.get(instance);
8474 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8475 return false;
8476 }
8477 removeClass(popup, innerParams.showClass.popup);
8478 addClass(popup, innerParams.hideClass.popup);
8479 const backdrop = getContainer();
8480 removeClass(backdrop, innerParams.showClass.backdrop);
8481 addClass(backdrop, innerParams.hideClass.backdrop);
8482 handlePopupAnimation(instance, popup, innerParams);
8483 return true;
8484 };
8485
8486 /**
8487 * @param {Error | string} error
8488 * @this {SweetAlert}
8489 */
8490 function rejectPromise(error) {
8491 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8492 handleAwaitingPromise(this);
8493 if (rejectPromise) {
8494 // Reject Swal promise
8495 rejectPromise(error);
8496 }
8497 }
8498
8499 /**
8500 * @param {SweetAlert} instance
8501 */
8502 const handleAwaitingPromise = instance => {
8503 if (instance.isAwaitingPromise) {
8504 // @ts-ignore
8505 delete instance.isAwaitingPromise;
8506 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8507 if (!privateProps.innerParams.get(instance)) {
8508 instance._destroy();
8509 }
8510 }
8511 };
8512
8513 /**
8514 * @param {SweetAlertResult | undefined} resolveValue
8515 * @returns {SweetAlertResult}
8516 */
8517 const prepareResolveValue = resolveValue => {
8518 // When user calls Swal.close()
8519 if (typeof resolveValue === 'undefined') {
8520 return {
8521 isConfirmed: false,
8522 isDenied: false,
8523 isDismissed: true
8524 };
8525 }
8526 return Object.assign({
8527 isConfirmed: false,
8528 isDenied: false,
8529 isDismissed: false
8530 }, resolveValue);
8531 };
8532
8533 /**
8534 * @param {SweetAlert} instance
8535 * @param {HTMLElement} popup
8536 * @param {SweetAlertOptions} innerParams
8537 */
8538 const handlePopupAnimation = (instance, popup, innerParams) => {
8539 var _globalState$eventEmi;
8540 const container = getContainer();
8541 // If animation is supported, animate
8542 const animationIsSupported = hasCssAnimation(popup);
8543 if (typeof innerParams.willClose === 'function') {
8544 innerParams.willClose(popup);
8545 }
8546 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8547 if (animationIsSupported && container) {
8548 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8549 } else if (container) {
8550 // Otherwise, remove immediately
8551 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8552 }
8553 };
8554
8555 /**
8556 * @param {SweetAlert} instance
8557 * @param {HTMLElement} popup
8558 * @param {HTMLElement} container
8559 * @param {boolean} returnFocus
8560 * @param {(() => void) | undefined} didClose
8561 */
8562 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8563 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8564 /**
8565 * @param {AnimationEvent | TransitionEvent} e
8566 */
8567 const swalCloseAnimationFinished = function (e) {
8568 if (e.target === popup) {
8569 var _globalState$swalClos;
8570 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8571 delete globalState.swalCloseEventFinishedCallback;
8572 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8573 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8574 }
8575 };
8576 popup.addEventListener('animationend', swalCloseAnimationFinished);
8577 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8578 };
8579
8580 /**
8581 * @param {SweetAlert} instance
8582 * @param {(() => void) | undefined} didClose
8583 */
8584 const triggerDidCloseAndDispose = (instance, didClose) => {
8585 setTimeout(() => {
8586 var _globalState$eventEmi2;
8587 if (typeof didClose === 'function') {
8588 didClose.bind(instance.params)();
8589 }
8590 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8591 // instance might have been destroyed already
8592 if (instance._destroy) {
8593 instance._destroy();
8594 }
8595 });
8596 };
8597
8598 /**
8599 * Shows loader (spinner), this is useful with AJAX requests.
8600 * By default the loader be shown instead of the "Confirm" button.
8601 *
8602 * @param {HTMLButtonElement | null} [buttonToReplace]
8603 */
8604 const showLoading = buttonToReplace => {
8605 let popup = getPopup();
8606 if (!popup) {
8607 new Swal();
8608 }
8609 popup = getPopup();
8610 if (!popup) {
8611 return;
8612 }
8613 const loader = getLoader();
8614 if (isToast()) {
8615 hide(getIcon());
8616 } else {
8617 replaceButton(popup, buttonToReplace);
8618 }
8619 show(loader);
8620 popup.setAttribute('data-loading', 'true');
8621 popup.setAttribute('aria-busy', 'true');
8622 popup.focus();
8623 };
8624
8625 /**
8626 * @param {HTMLElement} popup
8627 * @param {HTMLButtonElement | null} [buttonToReplace]
8628 */
8629 const replaceButton = (popup, buttonToReplace) => {
8630 const actions = getActions();
8631 const loader = getLoader();
8632 if (!actions || !loader) {
8633 return;
8634 }
8635 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8636 buttonToReplace = getConfirmButton();
8637 }
8638 show(actions);
8639 if (buttonToReplace) {
8640 hide(buttonToReplace);
8641 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8642 actions.insertBefore(loader, buttonToReplace);
8643 }
8644 addClass([popup, actions], swalClasses.loading);
8645 };
8646
8647 /**
8648 * @param {SweetAlert} instance
8649 * @param {SweetAlertOptions} params
8650 */
8651 const handleInputOptionsAndValue = (instance, params) => {
8652 if (params.input === 'select' || params.input === 'radio') {
8653 handleInputOptions(instance, params);
8654 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8655 showLoading(getConfirmButton());
8656 handleInputValue(instance, params);
8657 }
8658 };
8659
8660 /**
8661 * @param {SweetAlert} instance
8662 * @param {SweetAlertOptions} innerParams
8663 * @returns {SweetAlertInputValue}
8664 */
8665 const getInputValue = (instance, innerParams) => {
8666 const input = instance.getInput();
8667 if (!input) {
8668 return null;
8669 }
8670 switch (innerParams.input) {
8671 case 'checkbox':
8672 return getCheckboxValue(input);
8673 case 'radio':
8674 return getRadioValue(input);
8675 case 'file':
8676 return getFileValue(input);
8677 default:
8678 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8679 }
8680 };
8681
8682 /**
8683 * @param {HTMLInputElement} input
8684 * @returns {number}
8685 */
8686 const getCheckboxValue = input => input.checked ? 1 : 0;
8687
8688 /**
8689 * @param {HTMLInputElement} input
8690 * @returns {string | null}
8691 */
8692 const getRadioValue = input => input.checked ? input.value : null;
8693
8694 /**
8695 * @param {HTMLInputElement} input
8696 * @returns {FileList | File | null}
8697 */
8698 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8699
8700 /**
8701 * @param {SweetAlert} instance
8702 * @param {SweetAlertOptions} params
8703 */
8704 const handleInputOptions = (instance, params) => {
8705 const popup = getPopup();
8706 if (!popup) {
8707 return;
8708 }
8709 /**
8710 * @param {*} inputOptions
8711 */
8712 const processInputOptions = inputOptions => {
8713 if (params.input === 'select') {
8714 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8715 } else if (params.input === 'radio') {
8716 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8717 }
8718 };
8719 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8720 showLoading(getConfirmButton());
8721 asPromise(params.inputOptions).then(inputOptions => {
8722 instance.hideLoading();
8723 processInputOptions(inputOptions);
8724 });
8725 } else if (typeof params.inputOptions === 'object') {
8726 processInputOptions(params.inputOptions);
8727 } else {
8728 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8729 }
8730 };
8731
8732 /**
8733 * @param {SweetAlert} instance
8734 * @param {SweetAlertOptions} params
8735 */
8736 const handleInputValue = (instance, params) => {
8737 const input = instance.getInput();
8738 if (!input) {
8739 return;
8740 }
8741 hide(input);
8742 asPromise(params.inputValue).then(inputValue => {
8743 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8744 show(input);
8745 input.focus();
8746 instance.hideLoading();
8747 }).catch(err => {
8748 error(`Error in inputValue promise: ${err}`);
8749 input.value = '';
8750 show(input);
8751 input.focus();
8752 instance.hideLoading();
8753 });
8754 };
8755
8756 /**
8757 * @param {HTMLElement} popup
8758 * @param {InputOptionFlattened[]} inputOptions
8759 * @param {SweetAlertOptions} params
8760 */
8761 function populateSelectOptions(popup, inputOptions, params) {
8762 const select = getDirectChildByClass(popup, swalClasses.select);
8763 if (!select) {
8764 return;
8765 }
8766 /**
8767 * @param {HTMLElement} parent
8768 * @param {string} optionLabel
8769 * @param {string} optionValue
8770 */
8771 const renderOption = (parent, optionLabel, optionValue) => {
8772 const option = document.createElement('option');
8773 option.value = optionValue;
8774 setInnerHtml(option, optionLabel);
8775 option.selected = isSelected(optionValue, params.inputValue);
8776 parent.appendChild(option);
8777 };
8778 inputOptions.forEach(inputOption => {
8779 const optionValue = inputOption[0];
8780 const optionLabel = inputOption[1];
8781 // <optgroup> spec:
8782 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8783 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8784 // check whether this is a <optgroup>
8785 if (Array.isArray(optionLabel)) {
8786 // if it is an array, then it is an <optgroup>
8787 const optgroup = document.createElement('optgroup');
8788 optgroup.label = optionValue;
8789 optgroup.disabled = false; // not configurable for now
8790 select.appendChild(optgroup);
8791 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8792 } else {
8793 // case of <option>
8794 renderOption(select, optionLabel, optionValue);
8795 }
8796 });
8797 select.focus();
8798 }
8799
8800 /**
8801 * @param {HTMLElement} popup
8802 * @param {InputOptionFlattened[]} inputOptions
8803 * @param {SweetAlertOptions} params
8804 */
8805 function populateRadioOptions(popup, inputOptions, params) {
8806 const radio = getDirectChildByClass(popup, swalClasses.radio);
8807 if (!radio) {
8808 return;
8809 }
8810 inputOptions.forEach(inputOption => {
8811 const radioValue = inputOption[0];
8812 const radioLabel = inputOption[1];
8813 const radioInput = document.createElement('input');
8814 const radioLabelElement = document.createElement('label');
8815 radioInput.type = 'radio';
8816 radioInput.name = swalClasses.radio;
8817 radioInput.value = radioValue;
8818 if (isSelected(radioValue, params.inputValue)) {
8819 radioInput.checked = true;
8820 }
8821 const label = document.createElement('span');
8822 setInnerHtml(label, radioLabel);
8823 label.className = swalClasses.label;
8824 radioLabelElement.appendChild(radioInput);
8825 radioLabelElement.appendChild(label);
8826 radio.appendChild(radioLabelElement);
8827 });
8828 const radios = radio.querySelectorAll('input');
8829 if (radios.length) {
8830 radios[0].focus();
8831 }
8832 }
8833
8834 /**
8835 * Converts `inputOptions` into an array of `[value, label]`s
8836 *
8837 * @param {*} inputOptions
8838 * @typedef {string[]} InputOptionFlattened
8839 * @returns {InputOptionFlattened[]}
8840 */
8841 const formatInputOptions = inputOptions => {
8842 /** @type {InputOptionFlattened[]} */
8843 const result = [];
8844 if (inputOptions instanceof Map) {
8845 inputOptions.forEach((value, key) => {
8846 let valueFormatted = value;
8847 if (typeof valueFormatted === 'object') {
8848 // case of <optgroup>
8849 valueFormatted = formatInputOptions(valueFormatted);
8850 }
8851 result.push([key, valueFormatted]);
8852 });
8853 } else {
8854 Object.keys(inputOptions).forEach(key => {
8855 let valueFormatted = inputOptions[key];
8856 if (typeof valueFormatted === 'object') {
8857 // case of <optgroup>
8858 valueFormatted = formatInputOptions(valueFormatted);
8859 }
8860 result.push([key, valueFormatted]);
8861 });
8862 }
8863 return result;
8864 };
8865
8866 /**
8867 * @param {string} optionValue
8868 * @param {SweetAlertInputValue} inputValue
8869 * @returns {boolean}
8870 */
8871 const isSelected = (optionValue, inputValue) => {
8872 return Boolean(inputValue) && inputValue !== null && inputValue !== undefined && inputValue.toString() === optionValue.toString();
8873 };
8874
8875 /**
8876 * @param {SweetAlert} instance
8877 */
8878 const handleConfirmButtonClick = instance => {
8879 const innerParams = privateProps.innerParams.get(instance);
8880 instance.disableButtons();
8881 if (innerParams.input) {
8882 handleConfirmOrDenyWithInput(instance, 'confirm');
8883 } else {
8884 confirm(instance, true);
8885 }
8886 };
8887
8888 /**
8889 * @param {SweetAlert} instance
8890 */
8891 const handleDenyButtonClick = instance => {
8892 const innerParams = privateProps.innerParams.get(instance);
8893 instance.disableButtons();
8894 if (innerParams.returnInputValueOnDeny) {
8895 handleConfirmOrDenyWithInput(instance, 'deny');
8896 } else {
8897 deny(instance, false);
8898 }
8899 };
8900
8901 /**
8902 * @param {SweetAlert} instance
8903 * @param {(dismiss: DismissReason) => void} dismissWith
8904 */
8905 const handleCancelButtonClick = (instance, dismissWith) => {
8906 instance.disableButtons();
8907 dismissWith(DismissReason.cancel);
8908 };
8909
8910 /**
8911 * @param {SweetAlert} instance
8912 * @param {'confirm' | 'deny'} type
8913 */
8914 const handleConfirmOrDenyWithInput = (instance, type) => {
8915 const innerParams = privateProps.innerParams.get(instance);
8916 if (!innerParams.input) {
8917 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
8918 return;
8919 }
8920 const input = instance.getInput();
8921 const inputValue = getInputValue(instance, innerParams);
8922 if (innerParams.inputValidator) {
8923 handleInputValidator(instance, inputValue, type);
8924 } else if (input && !input.checkValidity()) {
8925 instance.enableButtons();
8926 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
8927 } else if (type === 'deny') {
8928 deny(instance, inputValue);
8929 } else {
8930 confirm(instance, inputValue);
8931 }
8932 };
8933
8934 /**
8935 * @param {SweetAlert} instance
8936 * @param {SweetAlertInputValue} inputValue
8937 * @param {'confirm' | 'deny'} type
8938 */
8939 const handleInputValidator = (instance, inputValue, type) => {
8940 const innerParams = privateProps.innerParams.get(instance);
8941 instance.disableInput();
8942 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
8943 validationPromise.then(validationMessage => {
8944 instance.enableButtons();
8945 instance.enableInput();
8946 if (validationMessage) {
8947 instance.showValidationMessage(validationMessage);
8948 } else if (type === 'deny') {
8949 deny(instance, inputValue);
8950 } else {
8951 confirm(instance, inputValue);
8952 }
8953 });
8954 };
8955
8956 /**
8957 * @param {SweetAlert} instance
8958 * @param {*} value
8959 */
8960 const deny = (instance, value) => {
8961 const innerParams = privateProps.innerParams.get(instance);
8962 if (innerParams.showLoaderOnDeny) {
8963 showLoading(getDenyButton());
8964 }
8965 if (innerParams.preDeny) {
8966 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
8967 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
8968 preDenyPromise.then(preDenyValue => {
8969 if (preDenyValue === false) {
8970 instance.hideLoading();
8971 handleAwaitingPromise(instance);
8972 } else {
8973 instance.close(/** @type SweetAlertResult */{
8974 isDenied: true,
8975 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
8976 });
8977 }
8978 }).catch(error => rejectWith(instance, error));
8979 } else {
8980 instance.close(/** @type SweetAlertResult */{
8981 isDenied: true,
8982 value
8983 });
8984 }
8985 };
8986
8987 /**
8988 * @param {SweetAlert} instance
8989 * @param {*} value
8990 */
8991 const succeedWith = (instance, value) => {
8992 instance.close(/** @type SweetAlertResult */{
8993 isConfirmed: true,
8994 value
8995 });
8996 };
8997
8998 /**
8999 *
9000 * @param {SweetAlert} instance
9001 * @param {string} error
9002 */
9003 const rejectWith = (instance, error) => {
9004 instance.rejectPromise(error);
9005 };
9006
9007 /**
9008 *
9009 * @param {SweetAlert} instance
9010 * @param {*} value
9011 */
9012 const confirm = (instance, value) => {
9013 const innerParams = privateProps.innerParams.get(instance);
9014 if (innerParams.showLoaderOnConfirm) {
9015 showLoading();
9016 }
9017 if (innerParams.preConfirm) {
9018 instance.resetValidationMessage();
9019 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
9020 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
9021 preConfirmPromise.then(preConfirmValue => {
9022 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
9023 instance.hideLoading();
9024 handleAwaitingPromise(instance);
9025 } else {
9026 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
9027 }
9028 }).catch(error => rejectWith(instance, error));
9029 } else {
9030 succeedWith(instance, value);
9031 }
9032 };
9033
9034 /**
9035 * Hides loader and shows back the button which was hidden by .showLoading()
9036 * @this {SweetAlert}
9037 */
9038 function hideLoading() {
9039 // do nothing if popup is closed
9040 const innerParams = privateProps.innerParams.get(this);
9041 if (!innerParams) {
9042 return;
9043 }
9044 const domCache = privateProps.domCache.get(this);
9045 hide(domCache.loader);
9046 if (isToast()) {
9047 if (innerParams.icon) {
9048 show(getIcon());
9049 }
9050 } else {
9051 showRelatedButton(domCache);
9052 }
9053 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
9054 domCache.popup.removeAttribute('aria-busy');
9055 domCache.popup.removeAttribute('data-loading');
9056 domCache.confirmButton.disabled = false;
9057 domCache.denyButton.disabled = false;
9058 domCache.cancelButton.disabled = false;
9059 }
9060
9061 /**
9062 * @param {DomCache} domCache
9063 */
9064 const showRelatedButton = domCache => {
9065 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
9066 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
9067 if (buttonToReplace.length) {
9068 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
9069 } else if (allButtonsAreHidden()) {
9070 hide(domCache.actions);
9071 }
9072 };
9073
9074 /**
9075 * Gets the input DOM node, this method works with input parameter.
9076 *
9077 * @returns {HTMLInputElement | null}
9078 * @this {SweetAlert}
9079 */
9080 function getInput() {
9081 const innerParams = privateProps.innerParams.get(this);
9082 const domCache = privateProps.domCache.get(this);
9083 if (!domCache) {
9084 return null;
9085 }
9086 return getInput$1(domCache.popup, innerParams.input);
9087 }
9088
9089 /**
9090 * @param {SweetAlert} instance
9091 * @param {string[]} buttons
9092 * @param {boolean} disabled
9093 */
9094 function setButtonsDisabled(instance, buttons, disabled) {
9095 const domCache = privateProps.domCache.get(instance);
9096 buttons.forEach(button => {
9097 domCache[button].disabled = disabled;
9098 });
9099 }
9100
9101 /**
9102 * @param {HTMLInputElement | null} input
9103 * @param {boolean} disabled
9104 */
9105 function setInputDisabled(input, disabled) {
9106 const popup = getPopup();
9107 if (!popup || !input) {
9108 return;
9109 }
9110 if (input.type === 'radio') {
9111 /** @type {NodeListOf<HTMLInputElement>} */
9112 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
9113 for (let i = 0; i < radios.length; i++) {
9114 radios[i].disabled = disabled;
9115 }
9116 } else {
9117 input.disabled = disabled;
9118 }
9119 }
9120
9121 /**
9122 * Enable all the buttons
9123 * @this {SweetAlert}
9124 */
9125 function enableButtons() {
9126 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
9127 }
9128
9129 /**
9130 * Disable all the buttons
9131 * @this {SweetAlert}
9132 */
9133 function disableButtons() {
9134 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
9135 }
9136
9137 /**
9138 * Enable the input field
9139 * @this {SweetAlert}
9140 */
9141 function enableInput() {
9142 setInputDisabled(this.getInput(), false);
9143 }
9144
9145 /**
9146 * Disable the input field
9147 * @this {SweetAlert}
9148 */
9149 function disableInput() {
9150 setInputDisabled(this.getInput(), true);
9151 }
9152
9153 /**
9154 * Show block with validation message
9155 *
9156 * @param {string} error
9157 * @this {SweetAlert}
9158 */
9159 function showValidationMessage(error) {
9160 const domCache = privateProps.domCache.get(this);
9161 const params = privateProps.innerParams.get(this);
9162 setInnerHtml(domCache.validationMessage, error);
9163 domCache.validationMessage.className = swalClasses['validation-message'];
9164 if (params.customClass && params.customClass.validationMessage) {
9165 addClass(domCache.validationMessage, params.customClass.validationMessage);
9166 }
9167 show(domCache.validationMessage);
9168 const input = this.getInput();
9169 if (input) {
9170 input.setAttribute('aria-invalid', 'true');
9171 input.setAttribute('aria-describedby', swalClasses['validation-message']);
9172 focusInput(input);
9173 addClass(input, swalClasses.inputerror);
9174 }
9175 }
9176
9177 /**
9178 * Hide block with validation message
9179 *
9180 * @this {SweetAlert}
9181 */
9182 function resetValidationMessage() {
9183 const domCache = privateProps.domCache.get(this);
9184 if (domCache.validationMessage) {
9185 hide(domCache.validationMessage);
9186 }
9187 const input = this.getInput();
9188 if (input) {
9189 input.removeAttribute('aria-invalid');
9190 input.removeAttribute('aria-describedby');
9191 removeClass(input, swalClasses.inputerror);
9192 }
9193 }
9194
9195 const defaultParams = {
9196 title: '',
9197 titleText: '',
9198 text: '',
9199 html: '',
9200 footer: '',
9201 icon: undefined,
9202 iconColor: undefined,
9203 iconHtml: undefined,
9204 template: undefined,
9205 toast: false,
9206 draggable: false,
9207 animation: true,
9208 theme: 'light',
9209 showClass: {
9210 popup: 'swal2-show',
9211 backdrop: 'swal2-backdrop-show',
9212 icon: 'swal2-icon-show'
9213 },
9214 hideClass: {
9215 popup: 'swal2-hide',
9216 backdrop: 'swal2-backdrop-hide',
9217 icon: 'swal2-icon-hide'
9218 },
9219 customClass: {},
9220 target: 'body',
9221 color: undefined,
9222 backdrop: true,
9223 heightAuto: true,
9224 allowOutsideClick: true,
9225 allowEscapeKey: true,
9226 allowEnterKey: true,
9227 stopKeydownPropagation: true,
9228 keydownListenerCapture: false,
9229 showConfirmButton: true,
9230 showDenyButton: false,
9231 showCancelButton: false,
9232 preConfirm: undefined,
9233 preDeny: undefined,
9234 confirmButtonText: 'OK',
9235 confirmButtonAriaLabel: '',
9236 confirmButtonColor: undefined,
9237 denyButtonText: 'No',
9238 denyButtonAriaLabel: '',
9239 denyButtonColor: undefined,
9240 cancelButtonText: 'Cancel',
9241 cancelButtonAriaLabel: '',
9242 cancelButtonColor: undefined,
9243 buttonsStyling: true,
9244 reverseButtons: false,
9245 focusConfirm: true,
9246 focusDeny: false,
9247 focusCancel: false,
9248 returnFocus: true,
9249 showCloseButton: false,
9250 closeButtonHtml: '&times;',
9251 closeButtonAriaLabel: 'Close this dialog',
9252 loaderHtml: '',
9253 showLoaderOnConfirm: false,
9254 showLoaderOnDeny: false,
9255 imageUrl: undefined,
9256 imageWidth: undefined,
9257 imageHeight: undefined,
9258 imageAlt: '',
9259 timer: undefined,
9260 timerProgressBar: false,
9261 width: undefined,
9262 padding: undefined,
9263 background: undefined,
9264 input: undefined,
9265 inputPlaceholder: '',
9266 inputLabel: '',
9267 inputValue: '',
9268 inputOptions: {},
9269 inputAutoFocus: true,
9270 inputAutoTrim: true,
9271 inputAttributes: {},
9272 inputValidator: undefined,
9273 returnInputValueOnDeny: false,
9274 validationMessage: undefined,
9275 grow: false,
9276 position: 'center',
9277 progressSteps: [],
9278 currentProgressStep: undefined,
9279 progressStepsDistance: undefined,
9280 willOpen: undefined,
9281 didOpen: undefined,
9282 didRender: undefined,
9283 willClose: undefined,
9284 didClose: undefined,
9285 didDestroy: undefined,
9286 scrollbarPadding: true,
9287 topLayer: false
9288 };
9289 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'];
9290
9291 /** @type {Record<string, string | undefined>} */
9292 const deprecatedParams = {
9293 allowEnterKey: undefined
9294 };
9295 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9296
9297 /**
9298 * Is valid parameter
9299 *
9300 * @param {string} paramName
9301 * @returns {boolean}
9302 */
9303 const isValidParameter = paramName => {
9304 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9305 };
9306
9307 /**
9308 * Is valid parameter for Swal.update() method
9309 *
9310 * @param {string} paramName
9311 * @returns {boolean}
9312 */
9313 const isUpdatableParameter = paramName => {
9314 return updatableParams.indexOf(paramName) !== -1;
9315 };
9316
9317 /**
9318 * Is deprecated parameter
9319 *
9320 * @param {string} paramName
9321 * @returns {string | undefined}
9322 */
9323 const isDeprecatedParameter = paramName => {
9324 return deprecatedParams[paramName];
9325 };
9326
9327 /**
9328 * @param {string} param
9329 */
9330 const checkIfParamIsValid = param => {
9331 if (!isValidParameter(param)) {
9332 warn(`Unknown parameter "${param}"`);
9333 }
9334 };
9335
9336 /**
9337 * @param {string} param
9338 */
9339 const checkIfToastParamIsValid = param => {
9340 if (toastIncompatibleParams.includes(param)) {
9341 warn(`The parameter "${param}" is incompatible with toasts`);
9342 }
9343 };
9344
9345 /**
9346 * @param {string} param
9347 */
9348 const checkIfParamIsDeprecated = param => {
9349 const isDeprecated = isDeprecatedParameter(param);
9350 if (isDeprecated) {
9351 warnAboutDeprecation(param, isDeprecated);
9352 }
9353 };
9354
9355 /**
9356 * Show relevant warnings for given params
9357 *
9358 * @param {SweetAlertOptions} params
9359 */
9360 const showWarningsForParams = params => {
9361 if (params.backdrop === false && params.allowOutsideClick) {
9362 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9363 }
9364 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)) {
9365 warn(`Invalid theme "${params.theme}"`);
9366 }
9367 for (const param in params) {
9368 checkIfParamIsValid(param);
9369 if (params.toast) {
9370 checkIfToastParamIsValid(param);
9371 }
9372 checkIfParamIsDeprecated(param);
9373 }
9374 };
9375
9376 /**
9377 * Updates popup parameters.
9378 *
9379 * @this {any}
9380 * @param {SweetAlertOptions} params
9381 */
9382 function update(params) {
9383 const container = getContainer();
9384 const popup = getPopup();
9385 const innerParams = privateProps.innerParams.get(this);
9386 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9387 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.`);
9388 return;
9389 }
9390 const validUpdatableParams = filterValidParams(params);
9391 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9392 showWarningsForParams(updatedParams);
9393 if (container) {
9394 container.dataset['swal2Theme'] = updatedParams.theme;
9395 }
9396 render(this, updatedParams);
9397 privateProps.innerParams.set(this, updatedParams);
9398 Object.defineProperties(this, {
9399 params: {
9400 value: Object.assign({}, this.params, params),
9401 writable: false,
9402 enumerable: true
9403 }
9404 });
9405 }
9406
9407 /**
9408 * @param {SweetAlertOptions} params
9409 * @returns {SweetAlertOptions}
9410 */
9411 const filterValidParams = params => {
9412 /** @type {Record<string, any>} */
9413 const validUpdatableParams = {};
9414 Object.keys(params).forEach(param => {
9415 if (isUpdatableParameter(param)) {
9416 const typedParams = /** @type {Record<string, any>} */params;
9417 validUpdatableParams[param] = typedParams[param];
9418 } else {
9419 warn(`Invalid parameter to update: ${param}`);
9420 }
9421 });
9422 return validUpdatableParams;
9423 };
9424
9425 /**
9426 * Dispose the current SweetAlert2 instance
9427 * @this {SweetAlert}
9428 */
9429 function _destroy() {
9430 var _globalState$eventEmi;
9431 const domCache = privateProps.domCache.get(this);
9432 const innerParams = privateProps.innerParams.get(this);
9433 if (!innerParams) {
9434 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9435 return; // This instance has already been destroyed
9436 }
9437
9438 // Check if there is another Swal closing
9439 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9440 globalState.swalCloseEventFinishedCallback();
9441 delete globalState.swalCloseEventFinishedCallback;
9442 }
9443 if (typeof innerParams.didDestroy === 'function') {
9444 innerParams.didDestroy();
9445 }
9446 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
9447 disposeSwal(this);
9448 }
9449
9450 /**
9451 * @param {SweetAlert} instance
9452 */
9453 const disposeSwal = instance => {
9454 disposeWeakMaps(instance);
9455 // Unset this.params so GC will dispose it (#1569)
9456 // @ts-ignore
9457 delete instance.params;
9458 // Unset globalState props so GC will dispose globalState (#1569)
9459 delete globalState.keydownHandler;
9460 delete globalState.keydownTarget;
9461 // Unset currentInstance
9462 delete globalState.currentInstance;
9463 };
9464
9465 /**
9466 * @param {SweetAlert} instance
9467 */
9468 const disposeWeakMaps = instance => {
9469 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9470 if (instance.isAwaitingPromise) {
9471 unsetWeakMaps(privateProps, instance);
9472 instance.isAwaitingPromise = true;
9473 } else {
9474 unsetWeakMaps(privateMethods, instance);
9475 unsetWeakMaps(privateProps, instance);
9476
9477 // @ts-ignore
9478 delete instance.isAwaitingPromise;
9479 // Unset instance methods
9480 // @ts-ignore
9481 delete instance.disableButtons;
9482 // @ts-ignore
9483 delete instance.enableButtons;
9484 // @ts-ignore
9485 delete instance.getInput;
9486 // @ts-ignore
9487 delete instance.disableInput;
9488 // @ts-ignore
9489 delete instance.enableInput;
9490 // @ts-ignore
9491 delete instance.hideLoading;
9492 // @ts-ignore
9493 delete instance.disableLoading;
9494 // @ts-ignore
9495 delete instance.showValidationMessage;
9496 // @ts-ignore
9497 delete instance.resetValidationMessage;
9498 // @ts-ignore
9499 delete instance.close;
9500 // @ts-ignore
9501 delete instance.closePopup;
9502 // @ts-ignore
9503 delete instance.closeModal;
9504 // @ts-ignore
9505 delete instance.closeToast;
9506 // @ts-ignore
9507 delete instance.rejectPromise;
9508 // @ts-ignore
9509 delete instance.update;
9510 // @ts-ignore
9511 delete instance._destroy;
9512 }
9513 };
9514
9515 /**
9516 * @param {Record<string, WeakMap<any, any>>} obj
9517 * @param {SweetAlert} instance
9518 */
9519 const unsetWeakMaps = (obj, instance) => {
9520 for (const i in obj) {
9521 obj[i].delete(instance);
9522 }
9523 };
9524
9525 var instanceMethods = /*#__PURE__*/Object.freeze({
9526 __proto__: null,
9527 _destroy: _destroy,
9528 close: close,
9529 closeModal: close,
9530 closePopup: close,
9531 closeToast: close,
9532 disableButtons: disableButtons,
9533 disableInput: disableInput,
9534 disableLoading: hideLoading,
9535 enableButtons: enableButtons,
9536 enableInput: enableInput,
9537 getInput: getInput,
9538 handleAwaitingPromise: handleAwaitingPromise,
9539 hideLoading: hideLoading,
9540 rejectPromise: rejectPromise,
9541 resetValidationMessage: resetValidationMessage,
9542 showValidationMessage: showValidationMessage,
9543 update: update
9544 });
9545
9546 /**
9547 * @param {SweetAlertOptions} innerParams
9548 * @param {DomCache} domCache
9549 * @param {(dismiss: DismissReason) => void} dismissWith
9550 */
9551 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9552 if (innerParams.toast) {
9553 handleToastClick(innerParams, domCache, dismissWith);
9554 } else {
9555 // Ignore click events that had mousedown on the popup but mouseup on the container
9556 // This can happen when the user drags a slider
9557 handleModalMousedown(domCache);
9558
9559 // Ignore click events that had mousedown on the container but mouseup on the popup
9560 handleContainerMousedown(domCache);
9561 handleModalClick(innerParams, domCache, dismissWith);
9562 }
9563 };
9564
9565 /**
9566 * @param {SweetAlertOptions} innerParams
9567 * @param {DomCache} domCache
9568 * @param {(dismiss: DismissReason) => void} dismissWith
9569 */
9570 const handleToastClick = (innerParams, domCache, dismissWith) => {
9571 // Closing toast by internal click
9572 domCache.popup.onclick = () => {
9573 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9574 return;
9575 }
9576 dismissWith(DismissReason.close);
9577 };
9578 };
9579
9580 /**
9581 * @param {SweetAlertOptions} innerParams
9582 * @returns {boolean}
9583 */
9584 const isAnyButtonShown = innerParams => {
9585 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9586 };
9587 let ignoreOutsideClick = false;
9588
9589 /**
9590 * @param {DomCache} domCache
9591 */
9592 const handleModalMousedown = domCache => {
9593 domCache.popup.onmousedown = () => {
9594 domCache.container.onmouseup = function (e) {
9595 domCache.container.onmouseup = () => {};
9596 // We only check if the mouseup target is the container because usually it doesn't
9597 // have any other direct children aside of the popup
9598 if (e.target === domCache.container) {
9599 ignoreOutsideClick = true;
9600 }
9601 };
9602 };
9603 };
9604
9605 /**
9606 * @param {DomCache} domCache
9607 */
9608 const handleContainerMousedown = domCache => {
9609 domCache.container.onmousedown = e => {
9610 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9611 if (e.target === domCache.container) {
9612 e.preventDefault();
9613 }
9614 domCache.popup.onmouseup = function (e) {
9615 domCache.popup.onmouseup = () => {};
9616 // We also need to check if the mouseup target is a child of the popup
9617 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9618 ignoreOutsideClick = true;
9619 }
9620 };
9621 };
9622 };
9623
9624 /**
9625 * @param {SweetAlertOptions} innerParams
9626 * @param {DomCache} domCache
9627 * @param {(dismiss: DismissReason) => void} dismissWith
9628 */
9629 const handleModalClick = (innerParams, domCache, dismissWith) => {
9630 domCache.container.onclick = e => {
9631 if (ignoreOutsideClick) {
9632 ignoreOutsideClick = false;
9633 return;
9634 }
9635 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9636 dismissWith(DismissReason.backdrop);
9637 }
9638 };
9639 };
9640
9641 /**
9642 * @param {any} elem
9643 * @returns {boolean}
9644 */
9645 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
9646
9647 /**
9648 * @param {any} elem
9649 * @returns {boolean}
9650 */
9651 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9652
9653 /**
9654 * @param {any[]} args
9655 * @returns {SweetAlertOptions}
9656 */
9657 const argsToParams = args => {
9658 /** @type {Record<string, any>} */
9659 const params = {};
9660 if (typeof args[0] === 'object' && !isElement(args[0])) {
9661 Object.assign(params, args[0]);
9662 } else {
9663 ['title', 'html', 'icon'].forEach((name, index) => {
9664 const arg = args[index];
9665 if (typeof arg === 'string' || isElement(arg)) {
9666 params[name] = arg;
9667 } else if (arg !== undefined) {
9668 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9669 }
9670 });
9671 }
9672 return params;
9673 };
9674
9675 /**
9676 * Main method to create a new SweetAlert2 popup
9677 *
9678 * @this {new (...args: any[]) => any}
9679 * @param {...SweetAlertOptions} args
9680 * @returns {Promise<SweetAlertResult>}
9681 */
9682 function fire(...args) {
9683 return new this(...args);
9684 }
9685
9686 /**
9687 * Returns an extended version of `Swal` containing `params` as defaults.
9688 * Useful for reusing Swal configuration.
9689 *
9690 * For example:
9691 *
9692 * Before:
9693 * const textPromptOptions = { input: 'text', showCancelButton: true }
9694 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9695 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9696 *
9697 * After:
9698 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9699 * const {value: firstName} = await TextPrompt('What is your first name?')
9700 * const {value: lastName} = await TextPrompt('What is your last name?')
9701 *
9702 * @param {SweetAlertOptions} mixinParams
9703 * @returns {SweetAlert}
9704 * @this {typeof import('../SweetAlert.js').SweetAlert}
9705 */
9706 function mixin(mixinParams) {
9707 // @ts-ignore: 'this' refers to the SweetAlert constructor
9708 class MixinSwal extends this {
9709 /**
9710 * @param {any} params
9711 * @param {any} priorityMixinParams
9712 */
9713 _main(params, priorityMixinParams) {
9714 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9715 }
9716 }
9717 // @ts-ignore
9718 return MixinSwal;
9719 }
9720
9721 /**
9722 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9723 * Otherwise, returns undefined.
9724 *
9725 * @returns {number | undefined}
9726 */
9727 const getTimerLeft = () => {
9728 return globalState.timeout && globalState.timeout.getTimerLeft();
9729 };
9730
9731 /**
9732 * Stop timer. Returns number of milliseconds of timer remained.
9733 * If `timer` parameter isn't set, returns undefined.
9734 *
9735 * @returns {number | undefined}
9736 */
9737 const stopTimer = () => {
9738 if (globalState.timeout) {
9739 stopTimerProgressBar();
9740 return globalState.timeout.stop();
9741 }
9742 };
9743
9744 /**
9745 * Resume timer. Returns number of milliseconds of timer remained.
9746 * If `timer` parameter isn't set, returns undefined.
9747 *
9748 * @returns {number | undefined}
9749 */
9750 const resumeTimer = () => {
9751 if (globalState.timeout) {
9752 const remaining = globalState.timeout.start();
9753 animateTimerProgressBar(remaining);
9754 return remaining;
9755 }
9756 };
9757
9758 /**
9759 * Resume timer. Returns number of milliseconds of timer remained.
9760 * If `timer` parameter isn't set, returns undefined.
9761 *
9762 * @returns {number | undefined}
9763 */
9764 const toggleTimer = () => {
9765 const timer = globalState.timeout;
9766 return timer && (timer.running ? stopTimer() : resumeTimer());
9767 };
9768
9769 /**
9770 * Increase timer. Returns number of milliseconds of an updated timer.
9771 * If `timer` parameter isn't set, returns undefined.
9772 *
9773 * @param {number} ms
9774 * @returns {number | undefined}
9775 */
9776 const increaseTimer = ms => {
9777 if (globalState.timeout) {
9778 const remaining = globalState.timeout.increase(ms);
9779 animateTimerProgressBar(remaining, true);
9780 return remaining;
9781 }
9782 };
9783
9784 /**
9785 * Check if timer is running. Returns true if timer is running
9786 * or false if timer is paused or stopped.
9787 * If `timer` parameter isn't set, returns undefined
9788 *
9789 * @returns {boolean}
9790 */
9791 const isTimerRunning = () => {
9792 return Boolean(globalState.timeout && globalState.timeout.isRunning());
9793 };
9794
9795 let bodyClickListenerAdded = false;
9796 /** @type {Record<string, any>} */
9797 const clickHandlers = {};
9798
9799 /**
9800 * @this {any}
9801 * @param {string} attr
9802 */
9803 function bindClickHandler(attr = 'data-swal-template') {
9804 clickHandlers[attr] = this;
9805 if (!bodyClickListenerAdded) {
9806 document.body.addEventListener('click', bodyClickListener);
9807 bodyClickListenerAdded = true;
9808 }
9809 }
9810
9811 /**
9812 * @param {MouseEvent} event
9813 */
9814 const bodyClickListener = event => {
9815 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
9816 for (const attr in clickHandlers) {
9817 const template = el.getAttribute && el.getAttribute(attr);
9818 if (template) {
9819 clickHandlers[attr].fire({
9820 template
9821 });
9822 return;
9823 }
9824 }
9825 }
9826 };
9827
9828 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9829
9830 class EventEmitter {
9831 constructor() {
9832 /** @type {Events} */
9833 this.events = {};
9834 }
9835
9836 /**
9837 * @param {string} eventName
9838 * @returns {EventHandlers}
9839 */
9840 _getHandlersByEventName(eventName) {
9841 if (typeof this.events[eventName] === 'undefined') {
9842 // not Set because we need to keep the FIFO order
9843 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
9844 this.events[eventName] = [];
9845 }
9846 return this.events[eventName];
9847 }
9848
9849 /**
9850 * @param {string} eventName
9851 * @param {EventHandler} eventHandler
9852 */
9853 on(eventName, eventHandler) {
9854 const currentHandlers = this._getHandlersByEventName(eventName);
9855 if (!currentHandlers.includes(eventHandler)) {
9856 currentHandlers.push(eventHandler);
9857 }
9858 }
9859
9860 /**
9861 * @param {string} eventName
9862 * @param {EventHandler} eventHandler
9863 */
9864 once(eventName, eventHandler) {
9865 /**
9866 * @param {...any} args
9867 */
9868 const onceFn = (...args) => {
9869 this.removeListener(eventName, onceFn);
9870 // @ts-ignore
9871 eventHandler.apply(this, args);
9872 };
9873 this.on(eventName, onceFn);
9874 }
9875
9876 /**
9877 * @param {string} eventName
9878 * @param {...any} args
9879 */
9880 emit(eventName, ...args) {
9881 this._getHandlersByEventName(eventName).forEach(
9882 /**
9883 * @param {EventHandler} eventHandler
9884 */
9885 eventHandler => {
9886 try {
9887 // @ts-ignore
9888 eventHandler.apply(this, args);
9889 } catch (error) {
9890 console.error(error);
9891 }
9892 });
9893 }
9894
9895 /**
9896 * @param {string} eventName
9897 * @param {EventHandler} eventHandler
9898 */
9899 removeListener(eventName, eventHandler) {
9900 const currentHandlers = this._getHandlersByEventName(eventName);
9901 const index = currentHandlers.indexOf(eventHandler);
9902 if (index > -1) {
9903 currentHandlers.splice(index, 1);
9904 }
9905 }
9906
9907 /**
9908 * @param {string} eventName
9909 */
9910 removeAllListeners(eventName) {
9911 if (this.events[eventName] !== undefined) {
9912 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
9913 this.events[eventName].length = 0;
9914 }
9915 }
9916 reset() {
9917 this.events = {};
9918 }
9919 }
9920
9921 globalState.eventEmitter = new EventEmitter();
9922
9923 /**
9924 * @param {string} eventName
9925 * @param {EventHandler} eventHandler
9926 */
9927 const on = (eventName, eventHandler) => {
9928 if (globalState.eventEmitter) {
9929 globalState.eventEmitter.on(eventName, eventHandler);
9930 }
9931 };
9932
9933 /**
9934 * @param {string} eventName
9935 * @param {EventHandler} eventHandler
9936 */
9937 const once = (eventName, eventHandler) => {
9938 if (globalState.eventEmitter) {
9939 globalState.eventEmitter.once(eventName, eventHandler);
9940 }
9941 };
9942
9943 /**
9944 * @param {string} [eventName]
9945 * @param {EventHandler} [eventHandler]
9946 */
9947 const off = (eventName, eventHandler) => {
9948 if (!globalState.eventEmitter) {
9949 return;
9950 }
9951
9952 // Remove all handlers for all events
9953 if (!eventName) {
9954 globalState.eventEmitter.reset();
9955 return;
9956 }
9957 if (eventHandler) {
9958 // Remove a specific handler
9959 globalState.eventEmitter.removeListener(eventName, eventHandler);
9960 } else {
9961 // Remove all handlers for a specific event
9962 globalState.eventEmitter.removeAllListeners(eventName);
9963 }
9964 };
9965
9966 var staticMethods = /*#__PURE__*/Object.freeze({
9967 __proto__: null,
9968 argsToParams: argsToParams,
9969 bindClickHandler: bindClickHandler,
9970 clickCancel: clickCancel,
9971 clickConfirm: clickConfirm,
9972 clickDeny: clickDeny,
9973 enableLoading: showLoading,
9974 fire: fire,
9975 getActions: getActions,
9976 getCancelButton: getCancelButton,
9977 getCloseButton: getCloseButton,
9978 getConfirmButton: getConfirmButton,
9979 getContainer: getContainer,
9980 getDenyButton: getDenyButton,
9981 getFocusableElements: getFocusableElements,
9982 getFooter: getFooter,
9983 getHtmlContainer: getHtmlContainer,
9984 getIcon: getIcon,
9985 getIconContent: getIconContent,
9986 getImage: getImage,
9987 getInputLabel: getInputLabel,
9988 getLoader: getLoader,
9989 getPopup: getPopup,
9990 getProgressSteps: getProgressSteps,
9991 getTimerLeft: getTimerLeft,
9992 getTimerProgressBar: getTimerProgressBar,
9993 getTitle: getTitle,
9994 getValidationMessage: getValidationMessage,
9995 increaseTimer: increaseTimer,
9996 isDeprecatedParameter: isDeprecatedParameter,
9997 isLoading: isLoading,
9998 isTimerRunning: isTimerRunning,
9999 isUpdatableParameter: isUpdatableParameter,
10000 isValidParameter: isValidParameter,
10001 isVisible: isVisible,
10002 mixin: mixin,
10003 off: off,
10004 on: on,
10005 once: once,
10006 resumeTimer: resumeTimer,
10007 showLoading: showLoading,
10008 stopTimer: stopTimer,
10009 toggleTimer: toggleTimer
10010 });
10011
10012 class Timer {
10013 /**
10014 * @param {() => void} callback
10015 * @param {number} delay
10016 */
10017 constructor(callback, delay) {
10018 this.callback = callback;
10019 this.remaining = delay;
10020 this.running = false;
10021 this.start();
10022 }
10023
10024 /**
10025 * @returns {number}
10026 */
10027 start() {
10028 if (!this.running) {
10029 this.running = true;
10030 this.started = new Date();
10031 this.id = setTimeout(this.callback, this.remaining);
10032 }
10033 return this.remaining;
10034 }
10035
10036 /**
10037 * @returns {number}
10038 */
10039 stop() {
10040 if (this.started && this.running) {
10041 this.running = false;
10042 clearTimeout(this.id);
10043 this.remaining -= new Date().getTime() - this.started.getTime();
10044 }
10045 return this.remaining;
10046 }
10047
10048 /**
10049 * @param {number} n
10050 * @returns {number}
10051 */
10052 increase(n) {
10053 const running = this.running;
10054 if (running) {
10055 this.stop();
10056 }
10057 this.remaining += n;
10058 if (running) {
10059 this.start();
10060 }
10061 return this.remaining;
10062 }
10063
10064 /**
10065 * @returns {number}
10066 */
10067 getTimerLeft() {
10068 if (this.running) {
10069 this.stop();
10070 this.start();
10071 }
10072 return this.remaining;
10073 }
10074
10075 /**
10076 * @returns {boolean}
10077 */
10078 isRunning() {
10079 return this.running;
10080 }
10081 }
10082
10083 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
10084
10085 /**
10086 * @param {SweetAlertOptions} params
10087 * @returns {SweetAlertOptions}
10088 */
10089 const getTemplateParams = params => {
10090 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
10091 if (!template) {
10092 return {};
10093 }
10094 /** @type {DocumentFragment} */
10095 const templateContent = template.content;
10096 showWarningsForElements(templateContent);
10097 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
10098 return result;
10099 };
10100
10101 /**
10102 * @param {DocumentFragment} templateContent
10103 * @returns {Record<string, string | boolean | number>}
10104 */
10105 const getSwalParams = templateContent => {
10106 /** @type {Record<string, string | boolean | number>} */
10107 const result = {};
10108 /** @type {HTMLElement[]} */
10109 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
10110 swalParams.forEach(param => {
10111 showWarningsForAttributes(param, ['name', 'value']);
10112 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10113 const value = param.getAttribute('value');
10114 if (!paramName || !value) {
10115 return;
10116 }
10117 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
10118 result[paramName] = value !== 'false';
10119 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
10120 result[paramName] = JSON.parse(value);
10121 } else {
10122 result[paramName] = value;
10123 }
10124 });
10125 return result;
10126 };
10127
10128 /**
10129 * @param {DocumentFragment} templateContent
10130 * @returns {Record<string, () => void>}
10131 */
10132 const getSwalFunctionParams = templateContent => {
10133 /** @type {Record<string, () => void>} */
10134 const result = {};
10135 /** @type {HTMLElement[]} */
10136 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
10137 swalFunctions.forEach(param => {
10138 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10139 const value = param.getAttribute('value');
10140 if (!paramName || !value) {
10141 return;
10142 }
10143 result[paramName] = new Function(`return ${value}`)();
10144 });
10145 return result;
10146 };
10147
10148 /**
10149 * @param {DocumentFragment} templateContent
10150 * @returns {Record<string, string | boolean>}
10151 */
10152 const getSwalButtons = templateContent => {
10153 /** @type {Record<string, string | boolean>} */
10154 const result = {};
10155 /** @type {HTMLElement[]} */
10156 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
10157 swalButtons.forEach(button => {
10158 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
10159 const type = button.getAttribute('type');
10160 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
10161 return;
10162 }
10163 result[`${type}ButtonText`] = button.innerHTML;
10164 result[`show${capitalizeFirstLetter(type)}Button`] = true;
10165 if (button.hasAttribute('color')) {
10166 const color = button.getAttribute('color');
10167 if (color !== null) {
10168 result[`${type}ButtonColor`] = color;
10169 }
10170 }
10171 if (button.hasAttribute('aria-label')) {
10172 const ariaLabel = button.getAttribute('aria-label');
10173 if (ariaLabel !== null) {
10174 result[`${type}ButtonAriaLabel`] = ariaLabel;
10175 }
10176 }
10177 });
10178 return result;
10179 };
10180
10181 /**
10182 * @param {DocumentFragment} templateContent
10183 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
10184 */
10185 const getSwalImage = templateContent => {
10186 const result = {};
10187 /** @type {HTMLElement | null} */
10188 const image = templateContent.querySelector('swal-image');
10189 if (image) {
10190 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
10191 if (image.hasAttribute('src')) {
10192 result.imageUrl = image.getAttribute('src') || undefined;
10193 }
10194 if (image.hasAttribute('width')) {
10195 result.imageWidth = image.getAttribute('width') || undefined;
10196 }
10197 if (image.hasAttribute('height')) {
10198 result.imageHeight = image.getAttribute('height') || undefined;
10199 }
10200 if (image.hasAttribute('alt')) {
10201 result.imageAlt = image.getAttribute('alt') || undefined;
10202 }
10203 }
10204 return result;
10205 };
10206
10207 /**
10208 * @param {DocumentFragment} templateContent
10209 * @returns {object}
10210 */
10211 const getSwalIcon = templateContent => {
10212 const result = {};
10213 /** @type {HTMLElement | null} */
10214 const icon = templateContent.querySelector('swal-icon');
10215 if (icon) {
10216 showWarningsForAttributes(icon, ['type', 'color']);
10217 if (icon.hasAttribute('type')) {
10218 result.icon = icon.getAttribute('type');
10219 }
10220 if (icon.hasAttribute('color')) {
10221 result.iconColor = icon.getAttribute('color');
10222 }
10223 result.iconHtml = icon.innerHTML;
10224 }
10225 return result;
10226 };
10227
10228 /**
10229 * @param {DocumentFragment} templateContent
10230 * @returns {object}
10231 */
10232 const getSwalInput = templateContent => {
10233 /** @type {Record<string, any>} */
10234 const result = {};
10235 /** @type {HTMLElement | null} */
10236 const input = templateContent.querySelector('swal-input');
10237 if (input) {
10238 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
10239 result.input = input.getAttribute('type') || 'text';
10240 if (input.hasAttribute('label')) {
10241 result.inputLabel = input.getAttribute('label');
10242 }
10243 if (input.hasAttribute('placeholder')) {
10244 result.inputPlaceholder = input.getAttribute('placeholder');
10245 }
10246 if (input.hasAttribute('value')) {
10247 result.inputValue = input.getAttribute('value');
10248 }
10249 }
10250 /** @type {HTMLElement[]} */
10251 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
10252 if (inputOptions.length) {
10253 result.inputOptions = {};
10254 inputOptions.forEach(option => {
10255 showWarningsForAttributes(option, ['value']);
10256 const optionValue = option.getAttribute('value');
10257 if (!optionValue) {
10258 return;
10259 }
10260 const optionName = option.innerHTML;
10261 result.inputOptions[optionValue] = optionName;
10262 });
10263 }
10264 return result;
10265 };
10266
10267 /**
10268 * @param {DocumentFragment} templateContent
10269 * @param {string[]} paramNames
10270 * @returns {Record<string, string>}
10271 */
10272 const getSwalStringParams = (templateContent, paramNames) => {
10273 /** @type {Record<string, string>} */
10274 const result = {};
10275 for (const i in paramNames) {
10276 const paramName = paramNames[i];
10277 /** @type {HTMLElement | null} */
10278 const tag = templateContent.querySelector(paramName);
10279 if (tag) {
10280 showWarningsForAttributes(tag, []);
10281 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
10282 }
10283 }
10284 return result;
10285 };
10286
10287 /**
10288 * @param {DocumentFragment} templateContent
10289 */
10290 const showWarningsForElements = templateContent => {
10291 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
10292 Array.from(templateContent.children).forEach(el => {
10293 const tagName = el.tagName.toLowerCase();
10294 if (!allowedElements.includes(tagName)) {
10295 warn(`Unrecognized element <${tagName}>`);
10296 }
10297 });
10298 };
10299
10300 /**
10301 * @param {HTMLElement} el
10302 * @param {string[]} allowedAttributes
10303 */
10304 const showWarningsForAttributes = (el, allowedAttributes) => {
10305 Array.from(el.attributes).forEach(attribute => {
10306 if (allowedAttributes.indexOf(attribute.name) === -1) {
10307 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.'}`]);
10308 }
10309 });
10310 };
10311
10312 const SHOW_CLASS_TIMEOUT = 10;
10313
10314 /**
10315 * Open popup, add necessary classes and styles, fix scrollbar
10316 *
10317 * @param {SweetAlertOptions} params
10318 */
10319 const openPopup = params => {
10320 var _globalState$eventEmi, _globalState$eventEmi2;
10321 const container = getContainer();
10322 const popup = getPopup();
10323 if (!container || !popup) {
10324 return;
10325 }
10326 if (typeof params.willOpen === 'function') {
10327 params.willOpen(popup);
10328 }
10329 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
10330 const bodyStyles = window.getComputedStyle(document.body);
10331 const initialBodyOverflow = bodyStyles.overflowY;
10332 addClasses(container, popup, params);
10333
10334 // scrolling is 'hidden' until animation is done, after that 'auto'
10335 setTimeout(() => {
10336 setScrollingVisibility(container, popup);
10337 }, SHOW_CLASS_TIMEOUT);
10338 if (isModal()) {
10339 // Using ternary instead of ?? operator for Webpack 4 compatibility
10340 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
10341 setAriaHidden();
10342 }
10343 if (!isToast() && !globalState.previousActiveElement) {
10344 globalState.previousActiveElement = document.activeElement;
10345 }
10346 if (typeof params.didOpen === 'function') {
10347 const didOpen = params.didOpen;
10348 setTimeout(() => didOpen(popup));
10349 }
10350 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
10351 };
10352
10353 /**
10354 * @param {Event} event
10355 */
10356 const swalOpenAnimationFinished = event => {
10357 const popup = getPopup();
10358 if (!popup || event.target !== popup) {
10359 return;
10360 }
10361 const container = getContainer();
10362 if (!container) {
10363 return;
10364 }
10365 popup.removeEventListener('animationend', swalOpenAnimationFinished);
10366 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
10367 container.style.overflowY = 'auto';
10368
10369 // no-transition is added in init() in case one swal is opened right after another
10370 removeClass(container, swalClasses['no-transition']);
10371 };
10372
10373 /**
10374 * @param {HTMLElement} container
10375 * @param {HTMLElement} popup
10376 */
10377 const setScrollingVisibility = (container, popup) => {
10378 if (hasCssAnimation(popup)) {
10379 container.style.overflowY = 'hidden';
10380 popup.addEventListener('animationend', swalOpenAnimationFinished);
10381 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10382 } else {
10383 container.style.overflowY = 'auto';
10384 }
10385 };
10386
10387 /**
10388 * @param {HTMLElement} container
10389 * @param {boolean} scrollbarPadding
10390 * @param {string} initialBodyOverflow
10391 */
10392 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10393 iOSfix();
10394 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10395 replaceScrollbarWithPadding(initialBodyOverflow);
10396 }
10397
10398 // sweetalert2/issues/1247
10399 setTimeout(() => {
10400 container.scrollTop = 0;
10401 });
10402 };
10403
10404 /**
10405 * @param {HTMLElement} container
10406 * @param {HTMLElement} popup
10407 * @param {SweetAlertOptions} params
10408 */
10409 const addClasses = (container, popup, params) => {
10410 var _params$showClass;
10411 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
10412 addClass(container, params.showClass.backdrop);
10413 }
10414 if (params.animation) {
10415 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10416 popup.style.setProperty('opacity', '0', 'important');
10417 show(popup, 'grid');
10418 setTimeout(() => {
10419 var _params$showClass2;
10420 // Animate popup right after showing it
10421 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
10422 addClass(popup, params.showClass.popup);
10423 }
10424 // and remove the opacity workaround
10425 popup.style.removeProperty('opacity');
10426 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10427 } else {
10428 show(popup, 'grid');
10429 }
10430 addClass([document.documentElement, document.body], swalClasses.shown);
10431 if (params.heightAuto && params.backdrop && !params.toast) {
10432 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10433 }
10434 };
10435
10436 var defaultInputValidators = {
10437 /**
10438 * @param {string} string
10439 * @param {string} [validationMessage]
10440 * @returns {Promise<string | void>}
10441 */
10442 email: (string, validationMessage) => {
10443 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10444 },
10445 /**
10446 * @param {string} string
10447 * @param {string} [validationMessage]
10448 * @returns {Promise<string | void>}
10449 */
10450 url: (string, validationMessage) => {
10451 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10452 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');
10453 }
10454 };
10455
10456 /**
10457 * @param {SweetAlertOptions} params
10458 */
10459 function setDefaultInputValidators(params) {
10460 // Use default `inputValidator` for supported input types if not provided
10461 if (params.inputValidator) {
10462 return;
10463 }
10464 if (params.input === 'email') {
10465 params.inputValidator = defaultInputValidators['email'];
10466 }
10467 if (params.input === 'url') {
10468 params.inputValidator = defaultInputValidators['url'];
10469 }
10470 }
10471
10472 /**
10473 * @param {SweetAlertOptions} params
10474 */
10475 function validateCustomTargetElement(params) {
10476 // Determine if the custom target element is valid
10477 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10478 warn('Target parameter is not valid, defaulting to "body"');
10479 params.target = 'body';
10480 }
10481 }
10482
10483 /**
10484 * Set type, text and actions on popup
10485 *
10486 * @param {SweetAlertOptions} params
10487 */
10488 function setParameters(params) {
10489 setDefaultInputValidators(params);
10490
10491 // showLoaderOnConfirm && preConfirm
10492 if (params.showLoaderOnConfirm && !params.preConfirm) {
10493 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');
10494 }
10495 validateCustomTargetElement(params);
10496
10497 // Replace newlines with <br> in title
10498 if (typeof params.title === 'string') {
10499 params.title = params.title.split('\n').join('<br />');
10500 }
10501 init(params);
10502 }
10503
10504 /** @type {SweetAlert} */
10505 let currentInstance;
10506 var _promise = /*#__PURE__*/new WeakMap();
10507 class SweetAlert {
10508 /**
10509 * @param {...(SweetAlertOptions | string)} args
10510 * @this {SweetAlert}
10511 */
10512 constructor(...args) {
10513 /**
10514 * @type {Promise<SweetAlertResult>}
10515 */
10516 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */Promise.resolve({
10517 isConfirmed: false,
10518 isDenied: false,
10519 isDismissed: true
10520 }));
10521 // Prevent run in Node env
10522 if (typeof window === 'undefined') {
10523 return;
10524 }
10525 currentInstance = this;
10526
10527 // @ts-ignore
10528 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10529
10530 /** @type {Readonly<SweetAlertOptions>} */
10531 this.params = outerParams;
10532
10533 /** @type {boolean} */
10534 this.isAwaitingPromise = false;
10535 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10536 }
10537
10538 /**
10539 * @param {any} userParams
10540 * @param {any} mixinParams
10541 */
10542 _main(userParams, mixinParams = {}) {
10543 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10544 if (globalState.currentInstance) {
10545 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10546 const {
10547 isAwaitingPromise
10548 } = globalState.currentInstance;
10549 globalState.currentInstance._destroy();
10550 if (!isAwaitingPromise) {
10551 swalPromiseResolve({
10552 isDismissed: true
10553 });
10554 }
10555 if (isModal()) {
10556 unsetAriaHidden();
10557 }
10558 }
10559 globalState.currentInstance = currentInstance;
10560 const innerParams = prepareParams(userParams, mixinParams);
10561 setParameters(innerParams);
10562 Object.freeze(innerParams);
10563
10564 // clear the previous timer
10565 if (globalState.timeout) {
10566 globalState.timeout.stop();
10567 delete globalState.timeout;
10568 }
10569
10570 // clear the restore focus timeout
10571 clearTimeout(globalState.restoreFocusTimeout);
10572 const domCache = populateDomCache(currentInstance);
10573 render(currentInstance, innerParams);
10574 privateProps.innerParams.set(currentInstance, innerParams);
10575 return swalPromise(currentInstance, domCache, innerParams);
10576 }
10577
10578 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10579 /**
10580 * @param {any} onFulfilled
10581 */
10582 then(onFulfilled) {
10583 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10584 }
10585
10586 /**
10587 * @param {any} onFinally
10588 */
10589 finally(onFinally) {
10590 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10591 }
10592 }
10593
10594 /**
10595 * @param {SweetAlert} instance
10596 * @param {DomCache} domCache
10597 * @param {SweetAlertOptions} innerParams
10598 * @returns {Promise<SweetAlertResult>}
10599 */
10600 const swalPromise = (instance, domCache, innerParams) => {
10601 return new Promise((resolve, reject) => {
10602 // functions to handle all closings/dismissals
10603 /**
10604 * @param {DismissReason} dismiss
10605 */
10606 const dismissWith = dismiss => {
10607 instance.close({
10608 isDismissed: true,
10609 dismiss,
10610 isConfirmed: false,
10611 isDenied: false
10612 });
10613 };
10614 privateMethods.swalPromiseResolve.set(instance, resolve);
10615 privateMethods.swalPromiseReject.set(instance, reject);
10616 domCache.confirmButton.onclick = () => {
10617 handleConfirmButtonClick(instance);
10618 };
10619 domCache.denyButton.onclick = () => {
10620 handleDenyButtonClick(instance);
10621 };
10622 domCache.cancelButton.onclick = () => {
10623 handleCancelButtonClick(instance, dismissWith);
10624 };
10625 domCache.closeButton.onclick = () => {
10626 dismissWith(DismissReason.close);
10627 };
10628 handlePopupClick(innerParams, domCache, dismissWith);
10629 addKeydownHandler(globalState, innerParams, dismissWith);
10630 handleInputOptionsAndValue(instance, innerParams);
10631 openPopup(innerParams);
10632 setupTimer(globalState, innerParams, dismissWith);
10633 initFocus(domCache, innerParams);
10634
10635 // Scroll container to top on open (#1247, #1946)
10636 setTimeout(() => {
10637 domCache.container.scrollTop = 0;
10638 });
10639 });
10640 };
10641
10642 /**
10643 * @param {SweetAlertOptions} userParams
10644 * @param {SweetAlertOptions} mixinParams
10645 * @returns {SweetAlertOptions}
10646 */
10647 const prepareParams = (userParams, mixinParams) => {
10648 const templateParams = getTemplateParams(userParams);
10649 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10650 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10651 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10652 if (params.animation === false) {
10653 params.showClass = {
10654 backdrop: 'swal2-noanimation'
10655 };
10656 params.hideClass = {};
10657 }
10658 return params;
10659 };
10660
10661 /**
10662 * @param {SweetAlert} instance
10663 * @returns {DomCache}
10664 */
10665 const populateDomCache = instance => {
10666 const domCache = /** @type {DomCache} */{
10667 popup: (/** @type {HTMLElement} */getPopup()),
10668 container: (/** @type {HTMLElement} */getContainer()),
10669 actions: (/** @type {HTMLElement} */getActions()),
10670 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
10671 denyButton: (/** @type {HTMLElement} */getDenyButton()),
10672 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
10673 loader: (/** @type {HTMLElement} */getLoader()),
10674 closeButton: (/** @type {HTMLElement} */getCloseButton()),
10675 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
10676 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
10677 };
10678 privateProps.domCache.set(instance, domCache);
10679 return domCache;
10680 };
10681
10682 /**
10683 * @param {GlobalState} globalState
10684 * @param {SweetAlertOptions} innerParams
10685 * @param {(dismiss: DismissReason) => void} dismissWith
10686 */
10687 const setupTimer = (globalState, innerParams, dismissWith) => {
10688 const timerProgressBar = getTimerProgressBar();
10689 hide(timerProgressBar);
10690 if (innerParams.timer) {
10691 globalState.timeout = new Timer(() => {
10692 dismissWith('timer');
10693 delete globalState.timeout;
10694 }, innerParams.timer);
10695 if (innerParams.timerProgressBar && timerProgressBar) {
10696 show(timerProgressBar);
10697 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10698 setTimeout(() => {
10699 if (globalState.timeout && globalState.timeout.running) {
10700 // timer can be already stopped or unset at this point
10701 animateTimerProgressBar(/** @type {number} */innerParams.timer);
10702 }
10703 });
10704 }
10705 }
10706 };
10707
10708 /**
10709 * Initialize focus in the popup:
10710 *
10711 * 1. If `toast` is `true`, don't steal focus from the document.
10712 * 2. Else if there is an [autofocus] element, focus it.
10713 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10714 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10715 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10716 * 6. Else focus the first focusable element in a popup (if any).
10717 *
10718 * @param {DomCache} domCache
10719 * @param {SweetAlertOptions} innerParams
10720 */
10721 const initFocus = (domCache, innerParams) => {
10722 if (innerParams.toast) {
10723 return;
10724 }
10725 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10726 if (!callIfFunction(innerParams.allowEnterKey)) {
10727 warnAboutDeprecation('allowEnterKey');
10728 blurActiveElement();
10729 return;
10730 }
10731 if (focusAutofocus(domCache)) {
10732 return;
10733 }
10734 if (focusButton(domCache, innerParams)) {
10735 return;
10736 }
10737 setFocus(-1, 1);
10738 };
10739
10740 /**
10741 * @param {DomCache} domCache
10742 * @returns {boolean}
10743 */
10744 const focusAutofocus = domCache => {
10745 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10746 for (const autofocusElement of autofocusElements) {
10747 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10748 autofocusElement.focus();
10749 return true;
10750 }
10751 }
10752 return false;
10753 };
10754
10755 /**
10756 * @param {DomCache} domCache
10757 * @param {SweetAlertOptions} innerParams
10758 * @returns {boolean}
10759 */
10760 const focusButton = (domCache, innerParams) => {
10761 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10762 domCache.denyButton.focus();
10763 return true;
10764 }
10765 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10766 domCache.cancelButton.focus();
10767 return true;
10768 }
10769 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10770 domCache.confirmButton.focus();
10771 return true;
10772 }
10773 return false;
10774 };
10775 const blurActiveElement = () => {
10776 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
10777 document.activeElement.blur();
10778 }
10779 };
10780
10781 // Assign instance methods from src/instanceMethods/*.js to prototype
10782 SweetAlert.prototype.disableButtons = disableButtons;
10783 SweetAlert.prototype.enableButtons = enableButtons;
10784 SweetAlert.prototype.getInput = getInput;
10785 SweetAlert.prototype.disableInput = disableInput;
10786 SweetAlert.prototype.enableInput = enableInput;
10787 SweetAlert.prototype.hideLoading = hideLoading;
10788 SweetAlert.prototype.disableLoading = hideLoading;
10789 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10790 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10791 SweetAlert.prototype.close = close;
10792 SweetAlert.prototype.closePopup = close;
10793 SweetAlert.prototype.closeModal = close;
10794 SweetAlert.prototype.closeToast = close;
10795 SweetAlert.prototype.rejectPromise = rejectPromise;
10796 SweetAlert.prototype.update = update;
10797 SweetAlert.prototype._destroy = _destroy;
10798
10799 // Assign static methods from src/staticMethods/*.js to constructor
10800 Object.assign(SweetAlert, staticMethods);
10801
10802 // Proxy to instance methods to constructor, for now, for backwards compatibility
10803 Object.keys(instanceMethods).forEach(key => {
10804 /**
10805 * @param {...(SweetAlertOptions | string | undefined)} args
10806 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
10807 */
10808 // @ts-ignore: Dynamic property assignment for backwards compatibility
10809 SweetAlert[key] = function (...args) {
10810 // @ts-ignore
10811 if (currentInstance && currentInstance[key]) {
10812 // @ts-ignore
10813 return currentInstance[key](...args);
10814 }
10815 return undefined;
10816 };
10817 });
10818 SweetAlert.DismissReason = DismissReason;
10819 SweetAlert.version = '11.26.17';
10820
10821 const Swal = SweetAlert;
10822 // @ts-ignore
10823 Swal.default = Swal;
10824
10825 return Swal;
10826
10827 }));
10828 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10829 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-icon-animations: true;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem;container-name:swal2-popup}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}@container swal2-popup style(--swal2-icon-animations:true){.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
10830
10831 /***/ },
10832
10833 /***/ "./node_modules/toastify-js/src/toastify.js"
10834 /*!**************************************************!*\
10835 !*** ./node_modules/toastify-js/src/toastify.js ***!
10836 \**************************************************/
10837 (module) {
10838
10839 /*!
10840 * Toastify js 1.12.0
10841 * https://github.com/apvarun/toastify-js
10842 * @license MIT licensed
10843 *
10844 * Copyright (C) 2018 Varun A P
10845 */
10846 (function(root, factory) {
10847 if ( true && module.exports) {
10848 module.exports = factory();
10849 } else {
10850 root.Toastify = factory();
10851 }
10852 })(this, function(global) {
10853 // Object initialization
10854 var Toastify = function(options) {
10855 // Returning a new init object
10856 return new Toastify.lib.init(options);
10857 },
10858 // Library version
10859 version = "1.12.0";
10860
10861 // Set the default global options
10862 Toastify.defaults = {
10863 oldestFirst: true,
10864 text: "Toastify is awesome!",
10865 node: undefined,
10866 duration: 3000,
10867 selector: undefined,
10868 callback: function () {
10869 },
10870 destination: undefined,
10871 newWindow: false,
10872 close: false,
10873 gravity: "toastify-top",
10874 positionLeft: false,
10875 position: '',
10876 backgroundColor: '',
10877 avatar: "",
10878 className: "",
10879 stopOnFocus: true,
10880 onClick: function () {
10881 },
10882 offset: {x: 0, y: 0},
10883 escapeMarkup: true,
10884 ariaLive: 'polite',
10885 style: {background: ''}
10886 };
10887
10888 // Defining the prototype of the object
10889 Toastify.lib = Toastify.prototype = {
10890 toastify: version,
10891
10892 constructor: Toastify,
10893
10894 // Initializing the object with required parameters
10895 init: function(options) {
10896 // Verifying and validating the input object
10897 if (!options) {
10898 options = {};
10899 }
10900
10901 // Creating the options object
10902 this.options = {};
10903
10904 this.toastElement = null;
10905
10906 // Validating the options
10907 this.options.text = options.text || Toastify.defaults.text; // Display message
10908 this.options.node = options.node || Toastify.defaults.node; // Display content as node
10909 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
10910 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
10911 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
10912 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
10913 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
10914 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
10915 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
10916 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
10917 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
10918 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
10919 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
10920 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
10921 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
10922 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
10923 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
10924 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
10925 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
10926 this.options.style = options.style || Toastify.defaults.style;
10927 if(options.backgroundColor) {
10928 this.options.style.background = options.backgroundColor;
10929 }
10930
10931 // Returning the current object for chaining functions
10932 return this;
10933 },
10934
10935 // Building the DOM element
10936 buildToast: function() {
10937 // Validating if the options are defined
10938 if (!this.options) {
10939 throw "Toastify is not initialized";
10940 }
10941
10942 // Creating the DOM object
10943 var divElement = document.createElement("div");
10944 divElement.className = "toastify on " + this.options.className;
10945
10946 // Positioning toast to left or right or center
10947 if (!!this.options.position) {
10948 divElement.className += " toastify-" + this.options.position;
10949 } else {
10950 // To be depreciated in further versions
10951 if (this.options.positionLeft === true) {
10952 divElement.className += " toastify-left";
10953 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
10954 } else {
10955 // Default position
10956 divElement.className += " toastify-right";
10957 }
10958 }
10959
10960 // Assigning gravity of element
10961 divElement.className += " " + this.options.gravity;
10962
10963 if (this.options.backgroundColor) {
10964 // This is being deprecated in favor of using the style HTML DOM property
10965 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
10966 }
10967
10968 // Loop through our style object and apply styles to divElement
10969 for (var property in this.options.style) {
10970 divElement.style[property] = this.options.style[property];
10971 }
10972
10973 // Announce the toast to screen readers
10974 if (this.options.ariaLive) {
10975 divElement.setAttribute('aria-live', this.options.ariaLive)
10976 }
10977
10978 // Adding the toast message/node
10979 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
10980 // If we have a valid node, we insert it
10981 divElement.appendChild(this.options.node)
10982 } else {
10983 if (this.options.escapeMarkup) {
10984 divElement.innerText = this.options.text;
10985 } else {
10986 divElement.innerHTML = this.options.text;
10987 }
10988
10989 if (this.options.avatar !== "") {
10990 var avatarElement = document.createElement("img");
10991 avatarElement.src = this.options.avatar;
10992
10993 avatarElement.className = "toastify-avatar";
10994
10995 if (this.options.position == "left" || this.options.positionLeft === true) {
10996 // Adding close icon on the left of content
10997 divElement.appendChild(avatarElement);
10998 } else {
10999 // Adding close icon on the right of content
11000 divElement.insertAdjacentElement("afterbegin", avatarElement);
11001 }
11002 }
11003 }
11004
11005 // Adding a close icon to the toast
11006 if (this.options.close === true) {
11007 // Create a span for close element
11008 var closeElement = document.createElement("button");
11009 closeElement.type = "button";
11010 closeElement.setAttribute("aria-label", "Close");
11011 closeElement.className = "toast-close";
11012 closeElement.innerHTML = "&#10006;";
11013
11014 // Triggering the removal of toast from DOM on close click
11015 closeElement.addEventListener(
11016 "click",
11017 function(event) {
11018 event.stopPropagation();
11019 this.removeElement(this.toastElement);
11020 window.clearTimeout(this.toastElement.timeOutValue);
11021 }.bind(this)
11022 );
11023
11024 //Calculating screen width
11025 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11026
11027 // Adding the close icon to the toast element
11028 // Display on the right if screen width is less than or equal to 360px
11029 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
11030 // Adding close icon on the left of content
11031 divElement.insertAdjacentElement("afterbegin", closeElement);
11032 } else {
11033 // Adding close icon on the right of content
11034 divElement.appendChild(closeElement);
11035 }
11036 }
11037
11038 // Clear timeout while toast is focused
11039 if (this.options.stopOnFocus && this.options.duration > 0) {
11040 var self = this;
11041 // stop countdown
11042 divElement.addEventListener(
11043 "mouseover",
11044 function(event) {
11045 window.clearTimeout(divElement.timeOutValue);
11046 }
11047 )
11048 // add back the timeout
11049 divElement.addEventListener(
11050 "mouseleave",
11051 function() {
11052 divElement.timeOutValue = window.setTimeout(
11053 function() {
11054 // Remove the toast from DOM
11055 self.removeElement(divElement);
11056 },
11057 self.options.duration
11058 )
11059 }
11060 )
11061 }
11062
11063 // Adding an on-click destination path
11064 if (typeof this.options.destination !== "undefined") {
11065 divElement.addEventListener(
11066 "click",
11067 function(event) {
11068 event.stopPropagation();
11069 if (this.options.newWindow === true) {
11070 window.open(this.options.destination, "_blank");
11071 } else {
11072 window.location = this.options.destination;
11073 }
11074 }.bind(this)
11075 );
11076 }
11077
11078 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
11079 divElement.addEventListener(
11080 "click",
11081 function(event) {
11082 event.stopPropagation();
11083 this.options.onClick();
11084 }.bind(this)
11085 );
11086 }
11087
11088 // Adding offset
11089 if(typeof this.options.offset === "object") {
11090
11091 var x = getAxisOffsetAValue("x", this.options);
11092 var y = getAxisOffsetAValue("y", this.options);
11093
11094 var xOffset = this.options.position == "left" ? x : "-" + x;
11095 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
11096
11097 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
11098
11099 }
11100
11101 // Returning the generated element
11102 return divElement;
11103 },
11104
11105 // Displaying the toast
11106 showToast: function() {
11107 // Creating the DOM object for the toast
11108 this.toastElement = this.buildToast();
11109
11110 // Getting the root element to with the toast needs to be added
11111 var rootElement;
11112 if (typeof this.options.selector === "string") {
11113 rootElement = document.getElementById(this.options.selector);
11114 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
11115 rootElement = this.options.selector;
11116 } else {
11117 rootElement = document.body;
11118 }
11119
11120 // Validating if root element is present in DOM
11121 if (!rootElement) {
11122 throw "Root element is not defined";
11123 }
11124
11125 // Adding the DOM element
11126 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
11127 rootElement.insertBefore(this.toastElement, elementToInsert);
11128
11129 // Repositioning the toasts in case multiple toasts are present
11130 Toastify.reposition();
11131
11132 if (this.options.duration > 0) {
11133 this.toastElement.timeOutValue = window.setTimeout(
11134 function() {
11135 // Remove the toast from DOM
11136 this.removeElement(this.toastElement);
11137 }.bind(this),
11138 this.options.duration
11139 ); // Binding `this` for function invocation
11140 }
11141
11142 // Supporting function chaining
11143 return this;
11144 },
11145
11146 hideToast: function() {
11147 if (this.toastElement.timeOutValue) {
11148 clearTimeout(this.toastElement.timeOutValue);
11149 }
11150 this.removeElement(this.toastElement);
11151 },
11152
11153 // Removing the element from the DOM
11154 removeElement: function(toastElement) {
11155 // Hiding the element
11156 // toastElement.classList.remove("on");
11157 toastElement.className = toastElement.className.replace(" on", "");
11158
11159 // Removing the element from DOM after transition end
11160 window.setTimeout(
11161 function() {
11162 // remove options node if any
11163 if (this.options.node && this.options.node.parentNode) {
11164 this.options.node.parentNode.removeChild(this.options.node);
11165 }
11166
11167 // Remove the element from the DOM, only when the parent node was not removed before.
11168 if (toastElement.parentNode) {
11169 toastElement.parentNode.removeChild(toastElement);
11170 }
11171
11172 // Calling the callback function
11173 this.options.callback.call(toastElement);
11174
11175 // Repositioning the toasts again
11176 Toastify.reposition();
11177 }.bind(this),
11178 400
11179 ); // Binding `this` for function invocation
11180 },
11181 };
11182
11183 // Positioning the toasts on the DOM
11184 Toastify.reposition = function() {
11185
11186 // Top margins with gravity
11187 var topLeftOffsetSize = {
11188 top: 15,
11189 bottom: 15,
11190 };
11191 var topRightOffsetSize = {
11192 top: 15,
11193 bottom: 15,
11194 };
11195 var offsetSize = {
11196 top: 15,
11197 bottom: 15,
11198 };
11199
11200 // Get all toast messages on the DOM
11201 var allToasts = document.getElementsByClassName("toastify");
11202
11203 var classUsed;
11204
11205 // Modifying the position of each toast element
11206 for (var i = 0; i < allToasts.length; i++) {
11207 // Getting the applied gravity
11208 if (containsClass(allToasts[i], "toastify-top") === true) {
11209 classUsed = "toastify-top";
11210 } else {
11211 classUsed = "toastify-bottom";
11212 }
11213
11214 var height = allToasts[i].offsetHeight;
11215 classUsed = classUsed.substr(9, classUsed.length-1)
11216 // Spacing between toasts
11217 var offset = 15;
11218
11219 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11220
11221 // Show toast in center if screen with less than or equal to 360px
11222 if (width <= 360) {
11223 // Setting the position
11224 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
11225
11226 offsetSize[classUsed] += height + offset;
11227 } else {
11228 if (containsClass(allToasts[i], "toastify-left") === true) {
11229 // Setting the position
11230 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
11231
11232 topLeftOffsetSize[classUsed] += height + offset;
11233 } else {
11234 // Setting the position
11235 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
11236
11237 topRightOffsetSize[classUsed] += height + offset;
11238 }
11239 }
11240 }
11241
11242 // Supporting function chaining
11243 return this;
11244 };
11245
11246 // Helper function to get offset.
11247 function getAxisOffsetAValue(axis, options) {
11248
11249 if(options.offset[axis]) {
11250 if(isNaN(options.offset[axis])) {
11251 return options.offset[axis];
11252 }
11253 else {
11254 return options.offset[axis] + 'px';
11255 }
11256 }
11257
11258 return '0px';
11259
11260 }
11261
11262 function containsClass(elem, yourClass) {
11263 if (!elem || typeof yourClass !== "string") {
11264 return false;
11265 } else if (
11266 elem.className &&
11267 elem.className
11268 .trim()
11269 .split(/\s+/gi)
11270 .indexOf(yourClass) > -1
11271 ) {
11272 return true;
11273 } else {
11274 return false;
11275 }
11276 }
11277
11278 // Setting up the prototype for the init object
11279 Toastify.lib.init.prototype = Toastify.lib;
11280
11281 // Returning the Toastify function to be assigned to the window object/module
11282 return Toastify;
11283 });
11284
11285
11286 /***/ }
11287
11288 /******/ });
11289 /************************************************************************/
11290 /******/ // The module cache
11291 /******/ var __webpack_module_cache__ = {};
11292 /******/
11293 /******/ // The require function
11294 /******/ function __webpack_require__(moduleId) {
11295 /******/ // Check if module is in cache
11296 /******/ var cachedModule = __webpack_module_cache__[moduleId];
11297 /******/ if (cachedModule !== undefined) {
11298 /******/ return cachedModule.exports;
11299 /******/ }
11300 /******/ // Create a new module (and put it into the cache)
11301 /******/ var module = __webpack_module_cache__[moduleId] = {
11302 /******/ id: moduleId,
11303 /******/ // no module.loaded needed
11304 /******/ exports: {}
11305 /******/ };
11306 /******/
11307 /******/ // Execute the module function
11308 /******/ if (!(moduleId in __webpack_modules__)) {
11309 /******/ delete __webpack_module_cache__[moduleId];
11310 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
11311 /******/ e.code = 'MODULE_NOT_FOUND';
11312 /******/ throw e;
11313 /******/ }
11314 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11315 /******/
11316 /******/ // Return the exports of the module
11317 /******/ return module.exports;
11318 /******/ }
11319 /******/
11320 /************************************************************************/
11321 /******/ /* webpack/runtime/compat get default export */
11322 /******/ (() => {
11323 /******/ // getDefaultExport function for compatibility with non-harmony modules
11324 /******/ __webpack_require__.n = (module) => {
11325 /******/ var getter = module && module.__esModule ?
11326 /******/ () => (module['default']) :
11327 /******/ () => (module);
11328 /******/ __webpack_require__.d(getter, { a: getter });
11329 /******/ return getter;
11330 /******/ };
11331 /******/ })();
11332 /******/
11333 /******/ /* webpack/runtime/define property getters */
11334 /******/ (() => {
11335 /******/ // define getter functions for harmony exports
11336 /******/ __webpack_require__.d = (exports, definition) => {
11337 /******/ for(var key in definition) {
11338 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11339 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11340 /******/ }
11341 /******/ }
11342 /******/ };
11343 /******/ })();
11344 /******/
11345 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11346 /******/ (() => {
11347 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
11348 /******/ })();
11349 /******/
11350 /******/ /* webpack/runtime/make namespace object */
11351 /******/ (() => {
11352 /******/ // define __esModule on exports
11353 /******/ __webpack_require__.r = (exports) => {
11354 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
11355 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11356 /******/ }
11357 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11358 /******/ };
11359 /******/ })();
11360 /******/
11361 /******/ /* webpack/runtime/nonce */
11362 /******/ (() => {
11363 /******/ __webpack_require__.nc = undefined;
11364 /******/ })();
11365 /******/
11366 /************************************************************************/
11367 var __webpack_exports__ = {};
11368 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11369 (() => {
11370 "use strict";
11371 /*!******************************************!*\
11372 !*** ./assets/src/js/admin/edit-quiz.js ***!
11373 \******************************************/
11374 __webpack_require__.r(__webpack_exports__);
11375 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ "./assets/src/js/utils.js");
11376 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
11377 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_1__);
11378 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
11379 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
11380 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
11381 /* harmony import */ var _edit_question_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./edit-question.js */ "./assets/src/js/admin/edit-question.js");
11382 /* harmony import */ var lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lpAssetsJsPath/lpPopupSelectItemToAdd.js */ "./assets/src/js/lpPopupSelectItemToAdd.js");
11383 /**
11384 * Edit Quiz JS handler as a class.
11385 *
11386 * @since 4.2.8.6
11387 * @version 1.0.3
11388 */
11389
11390
11391
11392
11393
11394
11395
11396 let editQuestion;
11397 const lpPopupSelectItemToAdd = new lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd();
11398 lpPopupSelectItemToAdd.init();
11399 class EditQuiz {
11400 constructor() {
11401 this.idUrlHandle = 'edit-quiz-questions';
11402 this.elEditQuizWrap = null;
11403 this.elEditListQuestions = null;
11404 this.quizID = null;
11405 }
11406 static selectors = {
11407 elEditQuizWrap: '.lp-edit-quiz-wrap',
11408 elQuestionEditMain: '.lp-question-edit-main',
11409 elQuestionToggleAll: '.lp-question-toggle-all',
11410 elEditListQuestions: '.lp-edit-list-questions',
11411 elQuestionItem: '.lp-question-item',
11412 elQuestionToggle: '.lp-question-toggle',
11413 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
11414 elBtnAddQuestion: '.lp-btn-add-question',
11415 elBtnRemoveQuestion: '.lp-btn-remove-question',
11416 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
11417 elBtnCancelUpdateQuestionTitle: '.lp-btn-cancel-update-question-title',
11418 elQuestionTitleNewInput: '.lp-question-title-new-input',
11419 elQuestionTitleInput: '.lp-question-title-input',
11420 elQuestionTypeLabel: '.lp-question-type-label',
11421 elQuestionTypeNew: '.lp-question-type-new',
11422 elAddNewQuestion: 'add-new-question',
11423 elQuestionClone: '.lp-question-item.clone',
11424 LPTarget: '.lp-target',
11425 elCollapse: 'lp-collapse'
11426 };
11427 init() {
11428 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuiz.selectors.elEditQuizWrap, elEditQuizWrapFound => {
11429 this.elEditQuizWrap = elEditQuizWrapFound;
11430 this.elEditListQuestions = this.elEditQuizWrap.querySelector(EditQuiz.selectors.elEditListQuestions);
11431 const elLPTarget = this.elEditQuizWrap.closest(EditQuiz.selectors.LPTarget);
11432 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
11433 this.quizID = dataSend.args.quiz_id;
11434 this.sortAbleQuestion();
11435 editQuestion = new _edit_question_js__WEBPACK_IMPORTED_MODULE_5__.EditQuestion();
11436 editQuestion.init();
11437 const elQuestionEditMains = elEditQuizWrapFound.querySelectorAll(`${EditQuiz.selectors.elQuestionEditMain}`);
11438 elQuestionEditMains.forEach(elQuestionEditMain => {
11439 editQuestion.sortAbleQuestionAnswer(elQuestionEditMain);
11440 });
11441 this.events();
11442 });
11443 }
11444 events() {
11445 if (EditQuiz._loadedEvents) {
11446 return;
11447 }
11448 EditQuiz._loadedEvents = true;
11449 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
11450 selector: EditQuiz.selectors.elQuestionToggleAll,
11451 class: this,
11452 callBack: this.toggleQuestionAll.name
11453 }, {
11454 selector: EditQuiz.selectors.elBtnAddQuestion,
11455 class: this,
11456 callBack: this.addQuestion.name
11457 }, {
11458 selector: EditQuiz.selectors.elBtnRemoveQuestion,
11459 class: this,
11460 callBack: this.removeQuestion.name
11461 }, {
11462 selector: EditQuiz.selectors.elBtnUpdateQuestionTitle,
11463 class: this,
11464 callBack: this.updateQuestionTitle.name
11465 }, {
11466 selector: EditQuiz.selectors.elBtnCancelUpdateQuestionTitle,
11467 class: this,
11468 callBack: this.cancelChangeTitleQuestion.name
11469 }, {
11470 selector: lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected,
11471 class: lpPopupSelectItemToAdd,
11472 callBack: lpPopupSelectItemToAdd.addItemsSelectedToSection.name,
11473 callBackHandle: this.addQuestionsSelectedToQuiz.bind(this)
11474 }]);
11475
11476 // Keydown
11477 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
11478 selector: EditQuiz.selectors.elQuestionTitleInput,
11479 class: this,
11480 callBack: this.updateQuestionTitle.name,
11481 checkIsEventEnter: true
11482 }, {
11483 selector: EditQuiz.selectors.elQuestionTitleNewInput,
11484 class: this,
11485 callBack: this.addQuestion.name,
11486 checkIsEventEnter: true
11487 }]);
11488
11489 // Keyup
11490 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
11491 selector: EditQuiz.selectors.elQuestionTitleInput,
11492 class: this,
11493 callBack: this.changeTitleQuestion.name
11494 }, {
11495 selector: `${EditQuiz.selectors.elQuestionTitleNewInput}, ${EditQuiz.selectors.elQuestionTypeNew}`,
11496 class: this,
11497 callBack: this.checkCanAddQuestion.name
11498 }]);
11499
11500 // Change
11501 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
11502 selector: EditQuiz.selectors.elQuestionTypeNew,
11503 class: this,
11504 callBack: this.checkCanAddQuestion.name
11505 }]);
11506
11507 // Click
11508 document.addEventListener('click', e => {
11509 const target = e.target;
11510 _utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuiz.selectors.elQuestionToggle, [], () => this.checkAllQuestionsCollapsed());
11511 });
11512 }
11513
11514 // Toggle all questions
11515 toggleQuestionAll(args) {
11516 const {
11517 e,
11518 target
11519 } = args;
11520 const elQuestionToggleAll = target.closest(`${EditQuiz.selectors.elQuestionToggleAll}`);
11521 if (!elQuestionToggleAll) {
11522 return;
11523 }
11524 const elQuestionItems = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11525 elQuestionToggleAll.classList.toggle(`${EditQuiz.selectors.elCollapse}`);
11526 elQuestionItems.forEach(el => {
11527 const shouldCollapse = elQuestionToggleAll.classList.contains(`${EditQuiz.selectors.elCollapse}`);
11528 el.classList.toggle(`${EditQuiz.selectors.elCollapse}`, shouldCollapse);
11529 });
11530 }
11531 checkAllQuestionsCollapsed() {
11532 const elQuestionItems = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11533 const elQuestionToggleAll = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionToggleAll}`);
11534 let isAllExpand = true;
11535 elQuestionItems.forEach(el => {
11536 if (el.classList.contains(`${EditQuiz.selectors.elCollapse}`)) {
11537 isAllExpand = false;
11538 return false; // Break
11539 }
11540 });
11541 if (isAllExpand) {
11542 elQuestionToggleAll.classList.remove(`${EditQuiz.selectors.elCollapse}`);
11543 } else {
11544 elQuestionToggleAll.classList.add(`${EditQuiz.selectors.elCollapse}`);
11545 }
11546 }
11547 updateCountItems() {
11548 const elCountItemsAll = this.elEditQuizWrap.querySelector('.total-items');
11549 const elItemsAll = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11550 const itemsAllCount = elItemsAll.length;
11551 elCountItemsAll.dataset.count = itemsAllCount;
11552 elCountItemsAll.querySelector('.count').textContent = itemsAllCount;
11553 }
11554
11555 // Add question to quiz
11556 addQuestion(args) {
11557 const {
11558 e,
11559 target,
11560 callBackNest
11561 } = args;
11562 e.preventDefault();
11563 const elAddNewQuestion = target.closest(`.${EditQuiz.selectors.elAddNewQuestion}`);
11564 if (!elAddNewQuestion) {
11565 return;
11566 }
11567 const elQuestionTitleNewInput = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTitleNewInput}`);
11568 const questionTitle = elQuestionTitleNewInput.value.trim();
11569 if (!questionTitle) {
11570 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(elQuestionTitleNewInput.dataset.messEmptyTitle, 'error');
11571 return;
11572 }
11573 const elQuestionType = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTypeNew}`);
11574 const questionType = elQuestionType.value;
11575 if (!questionType) {
11576 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(elQuestionType.dataset.messEmptyType, 'error');
11577 return;
11578 }
11579 const elQuestionClone = this.elEditListQuestions.querySelector(`${EditQuiz.selectors.elQuestionItem}.clone`);
11580 const newQuestionItem = elQuestionClone.cloneNode(true);
11581 const elQuestionTitleInput = newQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11582 elQuestionTitleInput.value = questionTitle;
11583 elQuestionTitleNewInput.value = '';
11584 newQuestionItem.classList.remove('clone');
11585 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(newQuestionItem, 1);
11586 elQuestionClone.insertAdjacentElement('beforebegin', newQuestionItem);
11587 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(newQuestionItem, 1);
11588 const callBack = {
11589 success: response => {
11590 const {
11591 message,
11592 status,
11593 data
11594 } = response;
11595 const {
11596 question,
11597 html_edit_question
11598 } = data;
11599 if (status === 'error') {
11600 throw `Error: ${message}`;
11601 } else if (status === 'success') {
11602 newQuestionItem.dataset.questionId = question.ID;
11603 newQuestionItem.dataset.questionType = question.meta_data._lp_type;
11604 newQuestionItem.outerHTML = html_edit_question;
11605 const elQuestionItemCreated = this.elEditListQuestions.querySelector(`${EditQuiz.selectors.elQuestionItem}[data-question-id="${question.ID}"]`);
11606 elQuestionItemCreated.classList.remove(EditQuiz.selectors.elCollapse);
11607 this.updateCountItems();
11608 editQuestion.initTinyMCE();
11609 const elQuestionEditMain = elQuestionItemCreated.querySelector(`${EditQuiz.selectors.elQuestionEditMain}`);
11610 editQuestion.sortAbleQuestionAnswer(elQuestionEditMain);
11611
11612 // Callback nest
11613 if (callBackNest && typeof callBackNest.success === 'function') {
11614 callBackNest.success({
11615 response,
11616 elQuestionItemCreated
11617 });
11618 }
11619 }
11620 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11621 },
11622 error: error => {
11623 newQuestionItem.remove();
11624 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11625 if (callBackNest && typeof callBackNest.error === 'function') {
11626 callBackNest.error({
11627 error,
11628 newQuestionItem
11629 });
11630 }
11631 },
11632 completed: () => {
11633 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(newQuestionItem, 0);
11634 this.checkCanAddQuestion({
11635 e,
11636 target: elQuestionTitleNewInput
11637 });
11638 if (callBackNest && typeof callBackNest.completed === 'function') {
11639 callBackNest.completed({
11640 newQuestionItem
11641 });
11642 }
11643 }
11644 };
11645 let dataSend = JSON.parse(elQuestionTitleNewInput.dataset.send);
11646 dataSend = {
11647 ...dataSend,
11648 question_title: questionTitle,
11649 question_type: questionType
11650 };
11651 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11652 }
11653
11654 // Add questions selected from popup to quiz
11655 addQuestionsSelectedToQuiz(itemsSelected) {
11656 const questionIds = [];
11657 itemsSelected.forEach(item => {
11658 const elQuestionItemClone = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionItem}.clone`);
11659 if (!elQuestionItemClone) {
11660 return;
11661 }
11662 questionIds.push(item.id);
11663 const elQuestionItemNew = elQuestionItemClone.cloneNode(true);
11664 const elQuestionItemTitleInput = elQuestionItemNew.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11665 elQuestionItemNew.classList.remove('clone');
11666 elQuestionItemNew.dataset.questionId = item.id;
11667 elQuestionItemTitleInput.value = item.titleSelected;
11668 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItemNew, 1);
11669 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionItemNew, 1);
11670 elQuestionItemClone.insertAdjacentElement('beforebegin', elQuestionItemNew);
11671 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItemNew, 1);
11672 });
11673 const callBack = {
11674 success: response => {
11675 const {
11676 message,
11677 status,
11678 data
11679 } = response;
11680 if (status === 'success') {
11681 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11682 const {
11683 html_edit_question
11684 } = data;
11685 if (html_edit_question) {
11686 Object.entries(html_edit_question).forEach(([question_id, item_html]) => {
11687 const elQuestionItemNew = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionItem}[data-question-id="${question_id}"]`);
11688 elQuestionItemNew.outerHTML = item_html;
11689 });
11690 }
11691 this.updateCountItems();
11692 editQuestion.initTinyMCE();
11693 } else {
11694 throw `Error: ${message}`;
11695 }
11696 },
11697 error: error => {
11698 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11699 },
11700 completed: () => {
11701 // completed handler intentionally empty
11702 }
11703 };
11704 const dataSend = {
11705 action: 'add_questions_to_quiz',
11706 quiz_id: this.quizID,
11707 question_ids: questionIds,
11708 args: {
11709 id_url: this.idUrlHandle
11710 }
11711 };
11712 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11713 }
11714 checkCanAddQuestion(args) {
11715 const {
11716 e,
11717 target
11718 } = args;
11719 const elTrigger = target.closest(EditQuiz.selectors.elQuestionTitleNewInput) || target.closest(EditQuiz.selectors.elQuestionTypeNew);
11720 if (!elTrigger) {
11721 return;
11722 }
11723 const elAddNewQuestion = elTrigger.closest(`.${EditQuiz.selectors.elAddNewQuestion}`);
11724 if (!elAddNewQuestion) {
11725 return;
11726 }
11727 const elBtnAddQuestion = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elBtnAddQuestion}`);
11728 if (!elBtnAddQuestion) {
11729 return;
11730 }
11731 const elQuestionTitleInput = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTitleNewInput}`);
11732 const elQuestionTypeNew = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTypeNew}`);
11733 const questionTitle = elQuestionTitleInput.value.trim();
11734 const questionType = elQuestionTypeNew.value;
11735 if (questionTitle && questionType) {
11736 elBtnAddQuestion.classList.add('active');
11737 } else {
11738 elBtnAddQuestion.classList.remove('active');
11739 }
11740 }
11741 removeQuestion(args) {
11742 const {
11743 e,
11744 target
11745 } = args;
11746 const elBtnRemoveQuestion = target.closest(`${EditQuiz.selectors.elBtnRemoveQuestion}`);
11747 if (!elBtnRemoveQuestion) {
11748 return;
11749 }
11750 const elQuestionItem = elBtnRemoveQuestion.closest(`${EditQuiz.selectors.elQuestionItem}`);
11751 if (!elQuestionItem) {
11752 return;
11753 }
11754 const questionId = elQuestionItem.dataset.questionId;
11755 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
11756 title: elBtnRemoveQuestion.dataset.title,
11757 text: elBtnRemoveQuestion.dataset.content,
11758 icon: 'warning',
11759 showCloseButton: true,
11760 showCancelButton: true,
11761 cancelButtonText: lpDataAdmin.i18n.cancel,
11762 confirmButtonText: lpDataAdmin.i18n.yes,
11763 reverseButtons: true
11764 }).then(result => {
11765 if (result.isConfirmed) {
11766 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11767 const callBack = {
11768 success: response => {
11769 const {
11770 message,
11771 status
11772 } = response;
11773 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11774 if (status === 'success') {
11775 elQuestionItem.remove();
11776 this.updateCountItems();
11777 }
11778 },
11779 error: error => {
11780 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11781 },
11782 completed: () => {
11783 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11784 }
11785 };
11786 const dataSend = {
11787 quiz_id: this.quizID,
11788 action: 'remove_question_from_quiz',
11789 question_id: questionId,
11790 args: {
11791 id_url: this.idUrlHandle
11792 }
11793 };
11794 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11795 }
11796 });
11797 }
11798 updateQuestionTitle(args) {
11799 const {
11800 e,
11801 target
11802 } = args;
11803 let canHandle = false;
11804 if (target.closest(`${EditQuiz.selectors.elBtnUpdateQuestionTitle}`)) {
11805 canHandle = true;
11806 } else if (target.closest(`${EditQuiz.selectors.elQuestionTitleInput}`) && e.key === 'Enter') {
11807 canHandle = true;
11808 }
11809 if (!canHandle) {
11810 return;
11811 }
11812 e.preventDefault();
11813 const elQuestionItem = target.closest(`${EditQuiz.selectors.elQuestionItem}`);
11814 if (!elQuestionItem) {
11815 return;
11816 }
11817 const elQuestionTitleInput = elQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11818 if (!elQuestionTitleInput) {
11819 return;
11820 }
11821 const questionId = elQuestionItem.dataset.questionId;
11822 const questionTitleValue = elQuestionTitleInput.value.trim();
11823 const titleOld = elQuestionTitleInput.dataset.old;
11824 const message = elQuestionTitleInput.dataset.messEmptyTitle;
11825 if (questionTitleValue.length === 0) {
11826 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, 'error');
11827 return;
11828 }
11829 if (questionTitleValue === titleOld) {
11830 return;
11831 }
11832 elQuestionTitleInput.blur();
11833 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11834 const callBack = {
11835 success: response => {
11836 const {
11837 message,
11838 status
11839 } = response;
11840 if (status === 'success') {
11841 elQuestionTitleInput.dataset.old = questionTitleValue;
11842 } else {
11843 elQuestionTitleInput.value = titleOld;
11844 }
11845 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11846 },
11847 error: error => {
11848 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11849 },
11850 completed: () => {
11851 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11852 elQuestionItem.classList.remove('editing');
11853 }
11854 };
11855 const dataSend = {
11856 quiz_id: this.quizID,
11857 action: 'update_question',
11858 question_id: questionId,
11859 question_title: questionTitleValue,
11860 args: {
11861 id_url: this.idUrlHandle
11862 }
11863 };
11864 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11865 }
11866 changeTitleQuestion(args) {
11867 const {
11868 e,
11869 target
11870 } = args;
11871 const elQuestionTitleInput = target.closest(`${EditQuiz.selectors.elQuestionTitleInput}`);
11872 if (!elQuestionTitleInput) {
11873 return;
11874 }
11875 const elQuestionItem = elQuestionTitleInput.closest(`${EditQuiz.selectors.elQuestionItem}`);
11876 const titleValue = elQuestionTitleInput.value.trim();
11877 const titleValueOld = elQuestionTitleInput.dataset.old || '';
11878 if (titleValue === titleValueOld) {
11879 elQuestionItem.classList.remove('editing');
11880 } else {
11881 elQuestionItem.classList.add('editing');
11882 }
11883 }
11884 cancelChangeTitleQuestion(args) {
11885 const {
11886 e,
11887 target
11888 } = args;
11889 const elBtnCancelUpdateQuestionTitle = target.closest(`${EditQuiz.selectors.elBtnCancelUpdateQuestionTitle}`);
11890 if (!elBtnCancelUpdateQuestionTitle) {
11891 return;
11892 }
11893 const elQuestionItem = elBtnCancelUpdateQuestionTitle.closest(`${EditQuiz.selectors.elQuestionItem}`);
11894 const elQuestionTitleInput = elQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11895 elQuestionTitleInput.value = elQuestionTitleInput.dataset.old || '';
11896 elQuestionItem.classList.remove('editing');
11897 }
11898 sortAbleQuestion() {
11899 let isUpdateSectionPosition = 0;
11900 let timeout;
11901 new sortablejs__WEBPACK_IMPORTED_MODULE_2__["default"](this.elEditListQuestions, {
11902 handle: '.drag',
11903 animation: 150,
11904 onEnd: evt => {
11905 const elQuestionItem = evt.item;
11906 if (!isUpdateSectionPosition) {
11907 return;
11908 }
11909 clearTimeout(timeout);
11910 timeout = setTimeout(() => {
11911 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11912 const questionIds = [];
11913 const elQuestionItems = this.elEditListQuestions.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11914 elQuestionItems.forEach(elItem => {
11915 const questionId = elItem.dataset.questionId;
11916 if (questionId) {
11917 questionIds.push(questionId);
11918 }
11919 });
11920 const callBack = {
11921 success: response => {
11922 const {
11923 message,
11924 status
11925 } = response;
11926 if (status === 'success') {
11927 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11928 editQuestion.initTinyMCE();
11929 } else {
11930 throw `Error: ${message}`;
11931 }
11932 },
11933 error: error => {
11934 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11935 },
11936 completed: () => {
11937 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11938 isUpdateSectionPosition = 0;
11939 }
11940 };
11941 const dataSend = {
11942 quiz_id: this.quizID,
11943 action: 'update_questions_position',
11944 question_ids: questionIds,
11945 args: {
11946 id_url: this.idUrlHandle
11947 }
11948 };
11949 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11950 }, 1000);
11951 },
11952 onMove: () => {
11953 clearTimeout(timeout);
11954 },
11955 onUpdate: () => {
11956 isUpdateSectionPosition = 1;
11957 }
11958 });
11959 }
11960 }
11961 const editQuiz = new EditQuiz();
11962 editQuiz.init();
11963 })();
11964
11965 /******/ })()
11966 ;
11967 //# sourceMappingURL=edit-quiz.js.map