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

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

12,106 lines 434.1 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 window.tinymce.execCommand('mceRemoveEditor', true, id);
209 window.tinymce.execCommand('mceAddEditor', true, id);
210 }
211 reInitQuickTags(id) {
212 const toolbar = document.getElementById(`qt_${id}_toolbar`);
213 if (!toolbar || toolbar.children.length || !window.quicktags) {
214 return;
215 }
216 const settings = window.tinyMCEPreInit?.qtInit?.[id] || {
217 id
218 };
219 window.quicktags(settings);
220 if (window.QTags?._buttonsInit) {
221 window.QTags._buttonsInit();
222 }
223 }
224 setDefaultEditorTab(id) {
225 const wrapEditor = document.getElementById(`wp-${id}-wrap`);
226 if (!wrapEditor) {
227 return;
228 }
229 if (wrapEditor.classList.contains('html-active') && window.switchEditors?.go) {
230 window.switchEditors.go(id, 'tmce');
231 const elTextarea = document.getElementById(id);
232 if (elTextarea) {
233 elTextarea.style.visibility = '';
234 }
235 }
236 wrapEditor.classList.add('tmce-active');
237 wrapEditor.classList.remove('html-active');
238 const visualTab = document.getElementById(`${id}-tmce`);
239 const codeTab = document.getElementById(`${id}-html`);
240 visualTab?.setAttribute('aria-pressed', 'true');
241 codeTab?.setAttribute('aria-pressed', 'false');
242 }
243
244 // Events for TinyMCE editor
245 eventEditorTinymce() {
246 window.tinymce.on('AddEditor', eEditor => {
247 const id = eEditor.editor.id;
248 const editor = window.tinymce.get(id);
249 if (!editor) {
250 return;
251 }
252 if (id === 'content') {
253 return;
254 }
255 const elTextarea = document.getElementById(id);
256 if (!elTextarea) {
257 return;
258 }
259 const elQuestionEditMain = elTextarea.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
260
261 // Skip if not in question edit context
262 if (!elQuestionEditMain) {
263 return;
264 }
265 const questionId = elQuestionEditMain.dataset.questionId;
266 editor.settings.force_p_newlines = false;
267 editor.settings.forced_root_block = '';
268 editor.settings.force_br_newlines = true;
269
270 // Config use absolute url
271 editor.settings.relative_urls = false;
272 editor.settings.remove_script_host = false;
273 editor.settings.convert_urls = true;
274 editor.settings.document_base_url = lpData.site_url;
275 // End config use absolute url
276
277 // Add quick tags
278 this.reInitQuickTags(id);
279
280 // Events focus in TinyMCE editor
281 editor.on('change keyup', e => {
282 // Auto save if it has class lp-auto-save
283 elTextarea.value = editor.getContent();
284 this.autoUpdateQuestion({
285 e,
286 target: elTextarea
287 });
288 });
289 editor.on('blur', e => {
290 //console.log( 'Editor blurred:', e.target.id );
291 });
292 editor.on('focusin', e => {});
293 editor.on('init', () => {
294 // Add style
295 editor.dom.addStyle(`
296 body {
297 line-height: 2.2 !important;
298 }
299 .${EditQuestion.selectors.elQuestionFibInput} {
300 border: 1px dashed rebeccapurple;
301 padding: 5px;
302 }
303 `);
304
305 // Set default tab visual
306 this.setDefaultEditorTab(id);
307 });
308 editor.on('setcontent', e => {
309 const uniquid = this.randomString();
310 const elementg = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${uniquid}"]`);
311 if (elementg[0]) {
312 elementg[0].focus();
313 }
314 editor.dom.bind(elementg[0], 'input', e => {
315 //console.log( 'Input changed:', e.target.value );
316 });
317 });
318 editor.on('selectionchange', e => {
319 fibSelection = editor.selection;
320
321 // Check selection is blank, check empty blank content
322 if (fibSelection.getNode().classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
323 const blankId = fibSelection.getNode().dataset.id;
324 const textBlank = fibSelection.getNode().textContent.trim();
325 if (textBlank.length === 0) {
326 const editorId = editor.id;
327 const questionId = editorId.replace(`${EditQuestion.selectors.elQuestionFibInput}-`, '');
328 const elQuestionEditMain = document.querySelector(`${EditQuestion.selectors.elQuestionEditMain}[data-question-id="${questionId}"]`);
329 const elQuestionBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
330 const elFibBlankOptionItem = elQuestionBlankOptions.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
331 if (elFibBlankOptionItem) {
332 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 0);
333 }
334 } else {
335 const elTextarea = document.getElementById(id);
336 const elAnswersConfig = elTextarea.closest(`${EditQuestion.selectors.elAnswersConfig}`);
337 const elFibBlankOptionItem = elAnswersConfig.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
338 if (elFibBlankOptionItem) {
339 const elFibOptionTitleInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
340 if (elFibOptionTitleInput) {
341 elFibOptionTitleInput.value = textBlank;
342 }
343 }
344 }
345 }
346 });
347 editor.on('Undo', e => {
348 const contentUndo = editor.getContent();
349 const selection = editor.selection;
350 const nodeUndo = selection.getNode();
351 if (nodeUndo.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
352 const blankId = nodeUndo.dataset.id;
353 const elFibBlankOptionItem = document.querySelector(`${EditQuestion.selectors.elFibBlankOptionItem}[data-id="${blankId}"]`);
354 if (elFibBlankOptionItem) {
355 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItem, 1);
356 }
357 }
358 });
359 editor.on('Redo', e => {});
360 });
361 }
362 autoUpdateQuestion(args) {
363 let {
364 e,
365 target,
366 key,
367 value
368 } = args;
369 const elAutoSave = target.closest(`${EditQuestion.selectors.elAutoSaveQuestion}`);
370 if (!elAutoSave) {
371 return;
372 }
373 const elQuestionEditMain = elAutoSave.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
374 const questionId = elQuestionEditMain.dataset.questionId;
375 clearTimeout(timeoutAutoUpdateQuestion);
376 timeoutAutoUpdateQuestion = setTimeout(() => {
377 // Call ajax to update question description
378 const callBack = {
379 success: response => {
380 const {
381 message,
382 status
383 } = response;
384 if (status === 'success') {
385 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
386 } else {
387 throw `Error: ${message}`;
388 }
389 },
390 error: error => {
391 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
392 },
393 completed: () => {}
394 };
395 const dataSend = {
396 action: 'update_question',
397 question_id: questionId,
398 args: {
399 id_url: idUrlHandle
400 }
401 };
402 if (undefined === key) {
403 key = elAutoSave.dataset.keyAutoSave;
404 if (!key) {
405 if (!elAutoSave.classList.contains('lp-editor-tinymce')) {
406 return;
407 }
408 const textAreaId = elAutoSave.id;
409 key = textAreaId.replace(/lp-/g, '').replace(`-${questionId}`, '').replace(/-/g, '_');
410 if (!key) {
411 return;
412 }
413 }
414 value = elAutoSave.value;
415 }
416 dataSend[key] = value;
417 window.lpAJAXG.fetchAJAX(dataSend, callBack);
418 }, 700);
419 }
420 // Create question type
421 createQuestionType(args) {
422 const {
423 e,
424 target
425 } = args;
426 const elBtnQuestionCreateType = target.closest(`${EditQuestion.selectors.elBtnQuestionCreateType}`);
427 if (!elBtnQuestionCreateType) {
428 return;
429 }
430 const elQuestionEditMain = elBtnQuestionCreateType.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
431 if (!elQuestionEditMain) {
432 return;
433 }
434 const questionId = elQuestionEditMain.dataset.questionId;
435 const elQuestionTypeNew = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionTypeNew}`);
436 if (!elQuestionTypeNew) {
437 return;
438 }
439 const questionType = elQuestionTypeNew.value.trim();
440 if (!questionType) {
441 const message = elQuestionTypeNew.dataset.messEmptyType;
442 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
443 return;
444 }
445
446 // Call ajax to create new question type
447 const callBack = {
448 success: response => {
449 const {
450 message,
451 status,
452 data
453 } = response;
454 if (status === 'success') {
455 const {
456 html_option_answers
457 } = data;
458 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
459 elAnswersConfig.outerHTML = html_option_answers;
460 this.initTinyMCE();
461 this.sortAbleQuestionAnswer(elQuestionEditMain);
462 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
463 } else {
464 throw `Error: ${message}`;
465 }
466 },
467 error: error => {
468 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
469 },
470 completed: () => {}
471 };
472 const dataSend = {
473 action: 'update_question',
474 question_id: questionId,
475 question_type: questionType,
476 args: {
477 id_url: idUrlHandle
478 }
479 };
480 window.lpAJAXG.fetchAJAX(dataSend, callBack);
481 }
482 addQuestionAnswer(args) {
483 const {
484 e,
485 target
486 } = args;
487 const elQuestionAnswerItemAddNew = target.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
488 if (!elQuestionAnswerItemAddNew) {
489 return;
490 }
491 e.preventDefault();
492 const elQuestionAnswerTitleNewInput = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleNewInput}`);
493 if (!elQuestionAnswerTitleNewInput.value.trim()) {
494 const message = elQuestionAnswerTitleNewInput.dataset.messEmptyTitle;
495 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
496 return;
497 }
498 const elQuestionEditMain = target.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
499 const elQuestionAnswerClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}.clone`);
500 const elQuestionAnswerNew = elQuestionAnswerClone.cloneNode(true);
501 const elQuestionAnswerTitleInputNew = elQuestionAnswerNew.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
502 elQuestionAnswerNew.classList.remove('clone');
503 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionAnswerNew, 1);
504 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 1);
505 elQuestionAnswerClone.insertAdjacentElement('beforebegin', elQuestionAnswerNew);
506 const answerTitle = elQuestionAnswerTitleNewInput.value.trim();
507 elQuestionAnswerTitleInputNew.value = answerTitle;
508 elQuestionAnswerTitleNewInput.value = '';
509 const questionId = elQuestionEditMain.dataset.questionId;
510
511 // Call ajax to add new question answer
512 const callBack = {
513 success: response => {
514 const {
515 message,
516 status,
517 data
518 } = response;
519 if (status === 'success') {
520 const {
521 question_answer
522 } = data;
523 elQuestionAnswerNew.dataset.answerId = question_answer.question_answer_id;
524 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerNew, 0);
525
526 // Set data lp-answers-config
527 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
528 dataAnswers.push(question_answer);
529 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
530 } else {
531 throw `Error: ${message}`;
532 }
533 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
534 },
535 error: error => {
536 elQuestionAnswerNew.remove();
537 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
538 },
539 completed: () => {}
540 };
541 const dataSend = {
542 action: 'add_question_answer',
543 question_id: questionId,
544 answer_title: answerTitle,
545 args: {
546 id_url: idUrlHandle
547 }
548 };
549 window.lpAJAXG.fetchAJAX(dataSend, callBack);
550 }
551
552 // Check to enable or disable add new question button
553 checkCanAddAnswer(args) {
554 const {
555 e,
556 target
557 } = args;
558 const elTrigger = target.closest(EditQuestion.selectors.elQuestionAnswerTitleNewInput);
559 if (!elTrigger) {
560 return;
561 }
562 const elQuestionAnswerItemAddNew = elTrigger.closest(`${EditQuestion.selectors.elQuestionAnswerItemAddNew}`);
563 if (!elQuestionAnswerItemAddNew) {
564 return;
565 }
566 const elBtnAddAnswer = elQuestionAnswerItemAddNew.querySelector(`${EditQuestion.selectors.elBtnAddAnswer}`);
567 if (!elBtnAddAnswer) {
568 return;
569 }
570 const titleValue = elTrigger.value.trim();
571 if (titleValue) {
572 elBtnAddAnswer.classList.add('active');
573 } else {
574 elBtnAddAnswer.classList.remove('active');
575 }
576 }
577
578 // Auto update question answer
579 autoUpdateAnswer(args) {
580 const {
581 e,
582 target
583 } = args;
584 const elAutoSaveAnswer = target.closest(`${EditQuestion.selectors.elAutoSaveAnswer}`);
585 if (!elAutoSaveAnswer) {
586 return;
587 }
588 const elQuestionAnswerItem = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
589 clearTimeout(timeoutAutoUpdateAnswer);
590 timeoutAutoUpdateAnswer = setTimeout(() => {
591 const elQuestionEditMain = elAutoSaveAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
592 const questionId = elQuestionEditMain.dataset.questionId;
593 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
594 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
595
596 // For both radio and checkbox.
597 const dataAnswersOld = structuredClone(dataAnswers);
598
599 // Get position of answers
600 const elQuestionAnswerItems = elAnswersConfig.querySelectorAll(`${EditQuestion.selectors.elQuestionAnswerItem}:not(.clone)`);
601 const answersPosition = {};
602 elQuestionAnswerItems.forEach((elQuestionAnswerItem, index) => {
603 answersPosition[elQuestionAnswerItem.dataset.answerId] = index + 1; // Start from 1
604 });
605
606 //console.log( 'answersPosition', answersPosition );
607
608 dataAnswers.map((answer, k) => {
609 const elQuestionAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
610 const elInputAnswerSetTrue = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
611 const elInputAnswerTitle = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elQuestionAnswerTitleInput}`);
612
613 // Set title
614 if (elInputAnswerTitle) {
615 answer.title = elInputAnswerTitle.value.trim();
616 }
617
618 // Set true answer
619 if (elInputAnswerSetTrue) {
620 if (elInputAnswerSetTrue.checked) {
621 answer.is_true = 'yes';
622 } else {
623 answer.is_true = '';
624 }
625 }
626
627 // Set position
628 if (answersPosition[answer.question_answer_id]) {
629 answer.order = answersPosition[answer.question_answer_id];
630 }
631 return answer;
632 });
633
634 //console.log( dataAnswers );
635
636 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
637
638 // Call ajax to update answers config
639 const callBack = {
640 success: response => {
641 const {
642 message,
643 status
644 } = response;
645 if (status === 'success') {} else {
646 throw `Error: ${message}`;
647 }
648 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
649 },
650 error: error => {
651 // rollback changes to old data
652 dataAnswersOld.forEach(answer => {
653 const elAnswerItem = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elQuestionAnswerItem}[data-answer-id="${answer.question_answer_id}"]`);
654 const inputAnswerSetTrue = elAnswerItem.querySelector(`${EditQuestion.selectors.elInputAnswerSetTrue}`);
655 if (answer.is_true === 'yes') {
656 inputAnswerSetTrue.checked = true;
657 }
658 return answer;
659 });
660 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
661 },
662 completed: () => {
663 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
664 }
665 };
666 const dataSend = {
667 action: 'update_question_answers_config',
668 question_id: questionId,
669 answers: dataAnswers,
670 args: {
671 id_url: idUrlHandle
672 }
673 };
674 window.lpAJAXG.fetchAJAX(dataSend, callBack);
675 }, 700);
676 }
677
678 // Sortable answers's question
679 sortAbleQuestionAnswer(elQuestionEditMain) {
680 let isUpdateSectionPosition = 0;
681 let timeout;
682 const elQuestionAnswers = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elAnswersConfig}`);
683 elQuestionAnswers.forEach(elAnswersConfig => {
684 new sortablejs__WEBPACK_IMPORTED_MODULE_3__["default"](elAnswersConfig, {
685 handle: '.drag',
686 animation: 150,
687 onEnd: evt => {
688 const elQuestionAnswerItem = evt.item;
689 if (!isUpdateSectionPosition) {
690 // No change in section position, do nothing
691 return;
692 }
693 clearTimeout(timeout);
694 timeout = setTimeout(() => {
695 const elAutoSaveAnswer = elQuestionAnswerItem.querySelector(`${EditQuestion.selectors.elAutoSaveAnswer}`);
696 this.autoUpdateAnswer({
697 e: null,
698 target: elAutoSaveAnswer
699 });
700 }, 1000);
701 },
702 onMove: evt => {
703 clearTimeout(timeout);
704 },
705 onUpdate: evt => {
706 isUpdateSectionPosition = 1;
707 }
708 });
709 });
710 }
711
712 // Delete question answer
713 deleteQuestionAnswer(args) {
714 const {
715 e,
716 target
717 } = args;
718 const elBtnDeleteAnswer = target.closest(`${EditQuestion.selectors.elBtnDeleteAnswer}`);
719 if (!elBtnDeleteAnswer) {
720 return;
721 }
722 const elQuestionAnswerItem = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionAnswerItem}`);
723 if (!elQuestionAnswerItem) {
724 return;
725 }
726 const elQuestionEditMain = elBtnDeleteAnswer.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
727 const questionId = elQuestionEditMain.dataset.questionId;
728 const questionAnswerId = elQuestionAnswerItem.dataset.answerId;
729 if (!questionId || !questionAnswerId) {
730 return;
731 }
732 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
733 title: elBtnDeleteAnswer.dataset.title || 'Are you sure?',
734 text: elBtnDeleteAnswer.dataset.content || 'Do you want to delete this answer?',
735 icon: 'warning',
736 showCloseButton: true,
737 showCancelButton: true,
738 cancelButtonText: lpData.i18n.cancel,
739 confirmButtonText: lpData.i18n.yes,
740 reverseButtons: true
741 }).then(result => {
742 if (result.isConfirmed) {
743 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 1);
744
745 // Call ajax to delete item from section
746 const callBack = {
747 success: response => {
748 const {
749 message,
750 status
751 } = response;
752 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
753 if (status === 'success') {
754 const elQuestionAnswerId = parseInt(elQuestionAnswerItem.dataset.answerId);
755 elQuestionAnswerItem.remove();
756 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
757 if (dataAnswers) {
758 const updatedAnswers = dataAnswers.filter(answer => parseInt(answer.question_answer_id) !== elQuestionAnswerId);
759 this.setDataAnswersConfig(elQuestionEditMain, updatedAnswers);
760 }
761 }
762 },
763 error: error => {
764 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
765 },
766 completed: () => {
767 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionAnswerItem, 0);
768 }
769 };
770 const dataSend = {
771 action: 'delete_question_answer',
772 question_id: questionId,
773 question_answer_id: questionAnswerId,
774 args: {
775 id_url: idUrlHandle
776 }
777 };
778 window.lpAJAXG.fetchAJAX(dataSend, callBack);
779 }
780 });
781 }
782
783 // Get data answers config
784 getDataAnswersConfig(elQuestionEditMain) {
785 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
786 if (!elAnswersConfig) {
787 return null;
788 }
789 let dataAnswers = elAnswersConfig.dataset.answers || '[]';
790 try {
791 dataAnswers = JSON.parse(dataAnswers);
792 } catch (e) {
793 dataAnswers = [];
794 }
795 if (!dataAnswers.meta_data) {
796 dataAnswers.meta_data = {};
797 }
798 return dataAnswers;
799 }
800
801 // Set data answers config
802 setDataAnswersConfig(elQuestionEditMain, dataAnswers) {
803 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
804 if (!elAnswersConfig) {
805 return;
806 }
807 if (!dataAnswers || typeof dataAnswers !== 'object') {
808 dataAnswers = {};
809 }
810 elAnswersConfig.dataset.answers = JSON.stringify(dataAnswers);
811 }
812
813 /***** Fill in the blank question type *****/
814 // For FIB question type
815 fibInsertBlank = args => {
816 const {
817 e,
818 target
819 } = args;
820 const elBtnFibInsertBlank = target.closest(EditQuestion.selectors.elBtnFibInsertBlank);
821 if (!elBtnFibInsertBlank) {
822 return;
823 }
824 const textPlaceholder = elBtnFibInsertBlank.dataset.defaultText;
825 const elQuestionEditMain = elBtnFibInsertBlank.closest(EditQuestion.selectors.elQuestionEditMain);
826 const questionId = elQuestionEditMain.dataset.questionId;
827 const messErrInserted = elBtnFibInsertBlank.dataset.messInserted;
828 const messErrRequireSelectText = elBtnFibInsertBlank.dataset.messRequireSelectText;
829 const idEditor = `${EditQuestion.selectors.elQuestionFibInput}-${questionId}`;
830 const uniquid = this.randomString();
831 let selectedText;
832 if (fibSelection) {
833 const elNode = fibSelection.getNode();
834 if (!elNode) {
835 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Event insert blank has error, please try again', 'error');
836 return;
837 }
838 const findParent = elNode.closest(`body[data-id="${idEditor}"]`);
839 if (!findParent) {
840 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
841 return;
842 }
843 if (elNode.classList.contains(`${EditQuestion.selectors.elQuestionFibInput}`)) {
844 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrInserted, 'error');
845 return;
846 }
847 selectedText = fibSelection.getContent();
848 if (selectedText.length === 0) {
849 selectedText = textPlaceholder;
850 }
851 const elInputNew = `<span class="${EditQuestion.selectors.elQuestionFibInput}" data-id="${uniquid}">${selectedText}</span>`;
852 fibSelection.setContent(elInputNew);
853 } else {
854 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(messErrRequireSelectText, 'error');
855 return;
856 }
857 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
858 dataAnswers.meta_data = dataAnswers.meta_data || {};
859 // Convert array to object
860 if (Object.keys(dataAnswers.meta_data).length === 0) {
861 dataAnswers.meta_data = {};
862 }
863 dataAnswers.meta_data[uniquid] = {
864 id: uniquid,
865 match_case: 0,
866 comparison: 'equal',
867 fill: selectedText,
868 index: 1,
869 open: false
870 };
871 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
872
873 // Clone blank options
874 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
875 const elFibBlankOptionItemClone = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptionItemClone}`);
876 const elFibBlankOptionItemNew = elFibBlankOptionItemClone.cloneNode(true);
877 const countOptions = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`).length;
878 const elFibBlankOptionIndex = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibBlankOptionIndex}`);
879 const elFibOptionTitleInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionTitleInput}`);
880 const elFibOptionMatchCaseInput = elFibBlankOptionItemNew.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
881 const elFibOptionComparisonInput = elFibBlankOptionItemNew.querySelectorAll(`${EditQuestion.selectors.elFibOptionComparisonInput}`);
882 elFibBlankOptionItemNew.dataset.id = uniquid;
883 elFibOptionTitleInput.name = `${EditQuestion.selectors.elFibOptionTitleInput}-${uniquid}`;
884 elFibOptionTitleInput.value = this.decodeHtml(selectedText);
885 elFibBlankOptionIndex.textContent = countOptions + 1 + '.';
886 elFibOptionMatchCaseInput.name = `${EditQuestion.selectors.elFibOptionMatchCaseInput}-${uniquid}`.replace(/\./g, '');
887 elFibOptionComparisonInput.forEach(elInput => {
888 elInput.name = `${EditQuestion.selectors.elFibOptionComparisonInput}-${uniquid}`.replace(/\./g, '');
889 if (elInput.value === 'equal') {
890 elInput.checked = true;
891 }
892 });
893 elFibBlankOptionItemClone.insertAdjacentElement('beforebegin', elFibBlankOptionItemNew);
894 elFibBlankOptionItemNew.classList.remove('clone');
895 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibBlankOptionItemNew, 1);
896 // End clone blank options
897
898 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
899 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 1);
900 this.fibSaveContent({
901 e: null,
902 target: elBtnFibSaveContent,
903 callBackCompleted: () => {
904 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibInsertBlank, 0);
905 }
906 });
907 };
908
909 // Delete all blanks
910 fibDeleteAllBlanks(args) {
911 const {
912 e,
913 target
914 } = args;
915 const elBtnFibDeleteAllBlanks = target.closest(`${EditQuestion.selectors.elBtnFibDeleteAllBlanks}`);
916 if (!elBtnFibDeleteAllBlanks) {
917 return;
918 }
919 const elQuestionEditMain = elBtnFibDeleteAllBlanks.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
920 if (!elQuestionEditMain) {
921 return;
922 }
923 const questionId = elQuestionEditMain.dataset.questionId;
924 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
925 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
926 title: elBtnFibDeleteAllBlanks.dataset.title,
927 text: elBtnFibDeleteAllBlanks.dataset.content,
928 icon: 'warning',
929 showCloseButton: true,
930 showCancelButton: true,
931 cancelButtonText: lpData.i18n.cancel,
932 confirmButtonText: lpData.i18n.yes,
933 reverseButtons: true
934 }).then(result => {
935 if (result.isConfirmed) {
936 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
937 const elBlanks = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}`);
938 elBlanks.forEach(elBlank => {
939 editor.dom.remove(elBlank, true);
940 });
941 dataAnswers.meta_data = {};
942 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
943 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
944 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
945 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
946 elFibBlankOptionItem.remove();
947 });
948 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
949 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 1);
950 this.fibSaveContent({
951 e: null,
952 target: elBtnFibSaveContent,
953 callBackCompleted: () => {
954 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibDeleteAllBlanks, 0);
955 }
956 });
957 }
958 });
959 }
960 // Clear content FIB question
961 fibClearContent(args) {
962 const {
963 e,
964 target
965 } = args;
966 const elBtnFibClearAllContent = target.closest(`${EditQuestion.selectors.elBtnFibClearAllContent}`);
967 if (!elBtnFibClearAllContent) {
968 return;
969 }
970 const elQuestionEditMain = elBtnFibClearAllContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
971 if (!elQuestionEditMain) {
972 return;
973 }
974 const questionId = elQuestionEditMain.dataset.questionId;
975 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
976 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
977 title: elBtnFibClearAllContent.dataset.title,
978 text: elBtnFibClearAllContent.dataset.content,
979 icon: 'warning',
980 showCloseButton: true,
981 showCancelButton: true,
982 cancelButtonText: lpData.i18n.cancel,
983 confirmButtonText: lpData.i18n.yes,
984 reverseButtons: true
985 }).then(result => {
986 if (result.isConfirmed) {
987 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
988 editor.setContent('');
989 dataAnswers.meta_data = {};
990 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
991 const elFibBlankOptions = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elFibBlankOptions}`);
992 const elFibBlankOptionItems = elFibBlankOptions.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
993 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
994 elFibBlankOptionItem.remove();
995 });
996 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
997 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 1);
998 this.fibSaveContent({
999 e: null,
1000 target: elBtnFibSaveContent,
1001 callBackCompleted: () => {
1002 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibClearAllContent, 0);
1003 }
1004 });
1005 }
1006 });
1007 }
1008
1009 // Remove blank
1010 fibDeleteBlank(args) {
1011 const {
1012 e,
1013 target
1014 } = args;
1015 const elBtnFibOptionDelete = target.closest(`${EditQuestion.selectors.elBtnFibOptionDelete}`);
1016 if (!elBtnFibOptionDelete) {
1017 return;
1018 }
1019 const elQuestionEditMain = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1020 if (!elQuestionEditMain) {
1021 return;
1022 }
1023 const questionId = elQuestionEditMain.dataset.questionId;
1024 const elAnswersConfig = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elAnswersConfig}`);
1025 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
1026 const elFibBlankOptionItem = elBtnFibOptionDelete.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
1027 const blankId = elFibBlankOptionItem.dataset.id;
1028 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
1029 title: elBtnFibOptionDelete.dataset.title,
1030 text: elBtnFibOptionDelete.dataset.content,
1031 icon: 'warning',
1032 showCloseButton: true,
1033 showCancelButton: true,
1034 cancelButtonText: lpData.i18n.cancel,
1035 confirmButtonText: lpData.i18n.yes,
1036 reverseButtons: true
1037 }).then(result => {
1038 if (result.isConfirmed) {
1039 // Find span with id on editor and remove it
1040 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
1041 const elBlank = editor.dom.select(`.${EditQuestion.selectors.elQuestionFibInput}[data-id="${blankId}"]`);
1042 if (elBlank[0]) {
1043 // Remove tag html but keep content
1044 editor.dom.remove(elBlank[0], true);
1045 }
1046 elFibBlankOptionItem.remove();
1047 dataAnswers.meta_data = dataAnswers.meta_data || {};
1048 if (dataAnswers.meta_data[blankId]) {
1049 delete dataAnswers.meta_data[blankId];
1050 }
1051 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
1052 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1053 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 1);
1054 this.fibSaveContent({
1055 e: null,
1056 target: elBtnFibSaveContent,
1057 callBackCompleted: () => {
1058 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elFibBlankOptionItem, 0);
1059 }
1060 });
1061 }
1062 });
1063 }
1064
1065 // Change title of blank option
1066 fibOptionTitleInputChange(args) {
1067 const {
1068 e,
1069 target
1070 } = args;
1071 const elFibOptionTitleInput = target.closest(`${EditQuestion.selectors.elFibOptionTitleInput}`);
1072 if (!elFibOptionTitleInput) {
1073 return;
1074 }
1075 const elQuestionFibOptionItem = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elFibBlankOptionItem}`);
1076 if (!elQuestionFibOptionItem) {
1077 return;
1078 }
1079 const elQuestionEditMain = elFibOptionTitleInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1080 if (!elQuestionEditMain) {
1081 return;
1082 }
1083 const value = elFibOptionTitleInput.value.trim();
1084 const blankId = elQuestionFibOptionItem.dataset.id;
1085 const questionId = elQuestionEditMain.dataset.questionId;
1086 const editor = window.tinymce.get(`lp-question-fib-input-${questionId}`);
1087 const elBlank = editor.dom.select(`.lp-question-fib-input[data-id="${blankId}"]`);
1088 if (elBlank[0]) {
1089 // Update content of blank
1090 elBlank[0].textContent = value;
1091 }
1092 clearTimeout(timeoutAutoUpdateFib);
1093 timeoutAutoUpdateFib = setTimeout(() => {
1094 // Call ajax to update question description
1095 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1096 this.fibSaveContent({
1097 e: null,
1098 target: elBtnFibSaveContent
1099 });
1100 }, 700);
1101 }
1102
1103 // Save content FIB question
1104 fibSaveContent(args) {
1105 const {
1106 e,
1107 target,
1108 callBackCompleted = null
1109 } = args;
1110 const elBtnFibSaveContent = target.closest(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1111 if (!elBtnFibSaveContent) {
1112 return;
1113 }
1114 const elQuestionEditMain = elBtnFibSaveContent.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1115 const questionId = elQuestionEditMain.dataset.questionId;
1116 const dataAnswers = this.getDataAnswersConfig(elQuestionEditMain);
1117 if (!dataAnswers) {
1118 return;
1119 }
1120 const editor = window.tinymce.get(`${EditQuestion.selectors.elQuestionFibInput}-${questionId}`);
1121 dataAnswers.title = editor.getContent();
1122 const elFibBlankOptionItems = elQuestionEditMain.querySelectorAll(`${EditQuestion.selectors.elFibBlankOptionItem}:not(.clone)`);
1123 if (elFibBlankOptionItems) {
1124 elFibBlankOptionItems.forEach(elFibBlankOptionItem => {
1125 const blankId = elFibBlankOptionItem.dataset.id;
1126 const elFibOptionMatchCaseInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
1127 const elFibOptionComparisonInput = elFibBlankOptionItem.querySelector(`${EditQuestion.selectors.elFibOptionComparisonInput}:checked`);
1128 dataAnswers.meta_data[blankId].match_case = elFibOptionMatchCaseInput.checked ? 1 : 0;
1129 dataAnswers.meta_data[blankId].comparison = elFibOptionComparisonInput.value;
1130 });
1131 }
1132
1133 //console.log( 'dataAnswers', dataAnswers );
1134
1135 if (!callBackCompleted) {
1136 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 1);
1137 }
1138
1139 // Call ajax to update answers config
1140 const callBack = {
1141 success: response => {
1142 const {
1143 message,
1144 status
1145 } = response;
1146 if (status === 'success') {
1147 this.setDataAnswersConfig(elQuestionEditMain, dataAnswers);
1148 } else {
1149 throw `Error: ${message}`;
1150 }
1151 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, status);
1152 },
1153 error: error => {
1154 lpAssetsJsPath_lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1155 },
1156 completed: () => {
1157 if (callBackCompleted && typeof callBackCompleted === 'function') {
1158 callBackCompleted();
1159 } else {
1160 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elBtnFibSaveContent, 0);
1161 }
1162 }
1163 };
1164
1165 //console.log( 'dataAnswers', dataAnswers );
1166
1167 const dataSend = {
1168 action: 'update_question_answers_config',
1169 question_id: questionId,
1170 answers: dataAnswers,
1171 args: {
1172 id_url: idUrlHandle
1173 }
1174 };
1175 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1176 }
1177 // Show/hide match case option
1178 fibShowHideMatchCaseOption(args) {
1179 const {
1180 e,
1181 target
1182 } = args;
1183 const elFibOptionMatchCaseInput = target.closest(`${EditQuestion.selectors.elFibOptionMatchCaseInput}`);
1184 if (!elFibOptionMatchCaseInput) {
1185 return;
1186 }
1187 const elQuestionFibOptionDetail = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionFibOptionDetail}`);
1188 const elFibOptionMatchCaseWrap = elQuestionFibOptionDetail.querySelector(`${EditQuestion.selectors.elFibOptionMatchCaseWrap}`);
1189 if (!elQuestionFibOptionDetail || !elFibOptionMatchCaseWrap) {
1190 return;
1191 }
1192 if (elFibOptionMatchCaseInput.checked) {
1193 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 1);
1194 } else {
1195 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elFibOptionMatchCaseWrap, 0);
1196 }
1197 const elQuestionEditMain = elFibOptionMatchCaseInput.closest(`${EditQuestion.selectors.elQuestionEditMain}`);
1198 const elBtnFibSaveContent = elQuestionEditMain.querySelector(`${EditQuestion.selectors.elBtnFibSaveContent}`);
1199 elBtnFibSaveContent.click();
1200 }
1201 /***** End Fill in the blank question type *****/
1202
1203 // Generate a random string of specified length, for set unique id
1204 randomString(length = 10) {
1205 const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
1206 let result = '';
1207 for (let i = 0; i < length; i++) {
1208 result += chars.charAt(Math.floor(Math.random() * chars.length));
1209 }
1210 return result;
1211 }
1212 // Decode HTML entities
1213 decodeHtml(html) {
1214 const txt = document.createElement('textarea');
1215 txt.innerHTML = html;
1216 return txt.value;
1217 }
1218 }
1219 const editQuestion = new EditQuestion();
1220 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuestion.selectors.elEditQuestionWrap, elEditQuestionWrap => {
1221 const findClass = EditQuestion.selectors.elQuestionEditMain.replace('.', '');
1222 if (!elEditQuestionWrap.classList.contains(findClass)) {
1223 return;
1224 }
1225 editQuestion.init();
1226 });
1227
1228 /***/ },
1229
1230 /***/ "./assets/src/js/lpPopupSelectItemToAdd.js"
1231 /*!*************************************************!*\
1232 !*** ./assets/src/js/lpPopupSelectItemToAdd.js ***!
1233 \*************************************************/
1234 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1235
1236 "use strict";
1237 __webpack_require__.r(__webpack_exports__);
1238 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1239 /* harmony export */ LpPopupSelectItemToAdd: () => (/* binding */ LpPopupSelectItemToAdd)
1240 /* harmony export */ });
1241 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
1242 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
1243 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1244 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
1245 /**
1246 * LearnPress Popup Select Item
1247 *
1248 * Handles load(search) item from API, show in popup and select item.
1249 */
1250
1251
1252
1253
1254 let itemsSelectedData = [];
1255 let elPopup;
1256 let timeSearchTitleItem;
1257 class LpPopupSelectItemToAdd {
1258 constructor() {
1259 this.init();
1260 }
1261 static selectors = {
1262 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
1263 elBtnAddItemsSelected: '.lp-btn-add-items-selected',
1264 elBtnCountItemsSelected: '.lp-btn-count-items-selected',
1265 elHeaderCountItemSelected: '.header-count-items-selected',
1266 elSelectItem: '.lp-select-item',
1267 elListItems: '.list-items',
1268 elPopupItemsToSelect: '.lp-popup-items-to-select',
1269 elSearchTitleItem: '.lp-search-title-item',
1270 elBtnBackListItems: '.lp-btn-back-to-select-items',
1271 elListItemsWrap: '.list-items-wrap',
1272 elListItemsSelected: '.list-items-selected',
1273 elItemSelectedClone: '.li-item-selected.clone',
1274 elItemSelected: '.li-item-selected',
1275 LPTarget: '.lp-target'
1276 };
1277 init() {
1278 this.events();
1279 }
1280 events = () => {
1281 if (LpPopupSelectItemToAdd._loadedEvents) {
1282 return;
1283 }
1284 LpPopupSelectItemToAdd._loadedEvents = true;
1285 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
1286 selector: LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect,
1287 callBack: this.showPopupItemsToSelect.name,
1288 class: this
1289 }, {
1290 selector: LpPopupSelectItemToAdd.selectors.elSelectItem,
1291 callBack: this.selectItemsFromList.name,
1292 class: this
1293 }, {
1294 selector: LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected,
1295 callBack: this.showItemsSelected.name,
1296 class: this
1297 }, {
1298 selector: LpPopupSelectItemToAdd.selectors.elBtnBackListItems,
1299 callBack: this.backToSelectItems.name,
1300 class: this
1301 }, {
1302 selector: LpPopupSelectItemToAdd.selectors.elItemSelected,
1303 callBack: this.removeItemSelected.name,
1304 class: this
1305 }, {
1306 selector: '.tabs .tab',
1307 callBack: this.chooseTabItemsType.name,
1308 class: this
1309 }]);
1310 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
1311 selector: LpPopupSelectItemToAdd.selectors.elSearchTitleItem,
1312 callBack: this.searchTitleItemToSelect.name,
1313 class: this
1314 }]);
1315 };
1316
1317 // Show popup items to select
1318 showPopupItemsToSelect = args => {
1319 const {
1320 e,
1321 target = false,
1322 callBack
1323 } = args;
1324 const elBtnShowPopupItemsToSelect = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect}`);
1325 if (!elBtnShowPopupItemsToSelect) {
1326 return;
1327 }
1328
1329 // Reset items selected data when opening popup
1330 itemsSelectedData = [];
1331 const templateId = target.dataset.template || '';
1332 const modalTemplate = document.querySelector(templateId);
1333 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
1334 html: modalTemplate.innerHTML,
1335 showConfirmButton: false,
1336 showCloseButton: true,
1337 width: 'max(350px, 65vw)',
1338 customClass: {
1339 popup: 'lp-select-items-popup',
1340 htmlContainer: 'lp-select-items-html-container',
1341 container: 'lp-select-items-container'
1342 },
1343 willOpen: () => {
1344 elPopup = sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().getPopup();
1345 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1346
1347 // Avoid duplicate AJAX: loadAJAX.js handles fresh elements; skip if already loaded. Set timeout to ensure DOM is ready handle.
1348 setTimeout(() => {
1349 const elLoadAjaxElement = elLPTarget.closest('.lp-load-ajax-element:not(.loaded)');
1350 if (!elLoadAjaxElement) {
1351 return;
1352 }
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 }, 1);
1371 }
1372 }).then(result => {
1373 if (result.isDismissed) {}
1374 });
1375 };
1376
1377 // Choose tab items type
1378 chooseTabItemsType = args => {
1379 const {
1380 e,
1381 target,
1382 callBack
1383 } = args;
1384 const elTabType = target.closest('.tab');
1385 if (!elTabType) {
1386 return;
1387 }
1388 e.preventDefault();
1389 const elTabs = elTabType.closest('.tabs');
1390 if (!elTabs) {
1391 return;
1392 }
1393 const elSelectItemsToAdd = elTabs.closest(`${LpPopupSelectItemToAdd.selectors.elPopupItemsToSelect}`);
1394 const elInputSearch = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.elSearchTitleItem}`);
1395 const itemType = elTabType.dataset.type;
1396 const elTabLis = elTabs.querySelectorAll('.tab');
1397 elTabLis.forEach(elTabLi => {
1398 if (elTabLi.classList.contains('active')) {
1399 elTabLi.classList.remove('active');
1400 }
1401 });
1402 elTabType.classList.add('active');
1403 // Reset search input
1404 elInputSearch.value = '';
1405 const elLPTarget = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1406 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1407 dataSend.args.item_type = itemType;
1408 dataSend.args.paged = 1;
1409 dataSend.args.item_selecting = itemsSelectedData || [];
1410 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
1411 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1412 window.lpAJAXG.fetchAJAX(dataSend, {
1413 success: response => {
1414 const {
1415 data
1416 } = response;
1417 elLPTarget.innerHTML = data.content || '';
1418 },
1419 error: error => {
1420 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1421 },
1422 completed: () => {
1423 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1424 this.watchItemsSelectedDataChange();
1425 }
1426 });
1427 };
1428
1429 // Choice items to add list items selected before adding to section
1430 selectItemsFromList = args => {
1431 const {
1432 e,
1433 target
1434 } = args;
1435 const elItemAttend = target.closest(`${LpPopupSelectItemToAdd.selectors.elSelectItem}`);
1436 if (!elItemAttend) {
1437 return;
1438 }
1439 const elInput = elItemAttend.querySelector('input[type="checkbox"]');
1440 if (target.tagName !== 'INPUT') {
1441 elInput.click();
1442 return;
1443 }
1444 const elUl = elItemAttend.closest(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
1445 if (!elUl) {
1446 return;
1447 }
1448 const itemSelected = {
1449 ...elInput.dataset
1450 };
1451 //console.log( 'itemSelected', itemSelected );
1452
1453 if (elInput.checked) {
1454 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
1455 if (!exists) {
1456 itemsSelectedData.push(itemSelected);
1457 }
1458 } else {
1459 const index = itemsSelectedData.findIndex(item => item.id === itemSelected.id);
1460 if (index !== -1) {
1461 itemsSelectedData.splice(index, 1);
1462 }
1463 }
1464 this.watchItemsSelectedDataChange();
1465 };
1466
1467 // Search title item
1468 searchTitleItemToSelect = args => {
1469 const {
1470 e,
1471 target
1472 } = args;
1473 const elInputSearch = target.closest(LpPopupSelectItemToAdd.selectors.elSearchTitleItem);
1474 if (!elInputSearch) {
1475 return;
1476 }
1477 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1478 clearTimeout(timeSearchTitleItem);
1479 timeSearchTitleItem = setTimeout(() => {
1480 const dataSet = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1481 dataSet.args.search_title = elInputSearch.value.trim();
1482 dataSet.args.item_selecting = itemsSelectedData;
1483 dataSet.args.paged = 1;
1484 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSet);
1485
1486 // Show loading
1487 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1488 window.lpAJAXG.fetchAJAX(dataSet, {
1489 success: response => {
1490 const {
1491 data
1492 } = response;
1493 elLPTarget.innerHTML = data.content || '';
1494 },
1495 error: error => {
1496 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
1497 },
1498 completed: () => {
1499 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1500 }
1501 });
1502 }, 800);
1503 };
1504
1505 // Show list of items, to choose items to add to section
1506 showItemsSelected = args => {
1507 const {
1508 e,
1509 target
1510 } = args;
1511 const elBtnCountItemsSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1512 if (!elBtnCountItemsSelected) {
1513 return;
1514 }
1515 const elBtnBack = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
1516 const elTabs = elPopup.querySelector('.tabs');
1517 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
1518 const elHeaderItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1519 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
1520 const elItemClone = elListItemsSelected.querySelector(`${LpPopupSelectItemToAdd.selectors.elItemSelectedClone}`);
1521 elHeaderItemsSelected.innerHTML = elBtnCountItemsSelected.innerHTML;
1522 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 0);
1523 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 0);
1524 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 0);
1525 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 1);
1526 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderItemsSelected, 1);
1527 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 1);
1528 elListItemsSelected.querySelectorAll(`${LpPopupSelectItemToAdd.selectors.elItemSelected}:not(.clone)`).forEach(elItem => {
1529 elItem.remove();
1530 });
1531 itemsSelectedData.forEach(item => {
1532 const elItemSelected = elItemClone.cloneNode(true);
1533 elItemSelected.classList.remove('clone');
1534 Object.entries(item).forEach(([key, value]) => {
1535 elItemSelected.dataset[key] = value;
1536 });
1537 const elTitleDisplay = elItemSelected.querySelector('.title-display');
1538 elTitleDisplay.innerHTML = item.title;
1539 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elItemSelected, 1);
1540 elItemClone.insertAdjacentElement('beforebegin', elItemSelected);
1541 });
1542 };
1543
1544 // Back to list of items
1545 backToSelectItems = args => {
1546 const {
1547 e,
1548 target
1549 } = args;
1550 const elBtnBack = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
1551 if (!elBtnBack) {
1552 return;
1553 }
1554 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1555 const elTabs = elPopup.querySelector('.tabs');
1556 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
1557 const elHeaderCountItemSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1558 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
1559 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 1);
1560 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 1);
1561 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 1);
1562 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 0);
1563 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderCountItemSelected, 0);
1564 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 0);
1565 };
1566
1567 // Remove item selected from list items selected
1568 removeItemSelected = args => {
1569 const {
1570 e,
1571 target
1572 } = args;
1573 const elRemoveItemSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elItemSelected}`);
1574 if (!elRemoveItemSelected) {
1575 return;
1576 }
1577 const itemRemove = elRemoveItemSelected.dataset;
1578 const index = itemsSelectedData.findIndex(item => item.id === itemRemove.id);
1579 if (index !== -1) {
1580 itemsSelectedData.splice(index, 1);
1581 }
1582 elRemoveItemSelected.remove();
1583 this.watchItemsSelectedDataChange();
1584 };
1585
1586 // Watch items selected when data change
1587 watchItemsSelectedDataChange = () => {
1588 // Update count items selected, disable/enable buttons
1589 const elBtnAddItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected}`);
1590 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
1591 const elSpanCount = elBtnCountItemsSelected.querySelector('span');
1592 const elHeaderCount = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
1593 const elTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
1594 if (itemsSelectedData.length !== 0) {
1595 elBtnCountItemsSelected.disabled = false;
1596 elBtnAddItemsSelected.disabled = false;
1597 elBtnAddItemsSelected.classList.add('active');
1598 elSpanCount.textContent = `(${itemsSelectedData.length})`;
1599 elHeaderCount.innerHTML = elBtnCountItemsSelected.innerHTML;
1600 } else {
1601 elBtnCountItemsSelected.disabled = true;
1602 elBtnAddItemsSelected.disabled = true;
1603 elBtnAddItemsSelected.classList.remove('active');
1604 elSpanCount.textContent = '';
1605 elHeaderCount.textContent = '';
1606 }
1607
1608 // Update list input checked, when items removed, or change tab type
1609 const elListItems = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
1610 const elInputs = elListItems.querySelectorAll('input[type="checkbox"]');
1611 elInputs.forEach(elInputItem => {
1612 const itemSelected = elInputItem.dataset;
1613 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
1614 elInputItem.checked = exists;
1615 });
1616
1617 // Set item selecting data to dataset for query.
1618 const dataSet = window.lpAJAXG.getDataSetCurrent(elTarget);
1619 dataSet.args.item_selecting = itemsSelectedData;
1620 window.lpAJAXG.setDataSetCurrent(elTarget, dataSet);
1621 };
1622
1623 // Add items selected to section
1624 addItemsSelectedToSection = args => {
1625 const {
1626 e,
1627 target,
1628 callBackHandle
1629 } = args;
1630 if (!elPopup) {
1631 return;
1632 }
1633 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().close();
1634 if (typeof callBackHandle === 'function') {
1635 callBackHandle(itemsSelectedData);
1636 itemsSelectedData = [];
1637 }
1638 };
1639 }
1640
1641 /***/ },
1642
1643 /***/ "./assets/src/js/lpToastify.js"
1644 /*!*************************************!*\
1645 !*** ./assets/src/js/lpToastify.js ***!
1646 \*************************************/
1647 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1648
1649 "use strict";
1650 __webpack_require__.r(__webpack_exports__);
1651 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1652 /* harmony export */ show: () => (/* binding */ show)
1653 /* harmony export */ });
1654 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
1655 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
1656 /* 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");
1657 /**
1658 * Utils functions
1659 *
1660 * @param url
1661 * @param data
1662 * @param functions
1663 * @since 4.3.0
1664 * @version 1.0.0
1665 */
1666
1667
1668 const argsToastify = {
1669 text: '',
1670 gravity: lpData.toast.gravity,
1671 // `top` or `bottom`
1672 position: lpData.toast.position,
1673 // `left`, `center` or `right`
1674 className: `${lpData.toast.classPrefix}`,
1675 close: lpData.toast.close == 1,
1676 stopOnFocus: lpData.toast.stopOnFocus == 1,
1677 duration: lpData.toast.duration
1678 };
1679 const show = (message, status = 'success', argsCustom) => {
1680 let args = argsToastify;
1681 if (argsCustom) {
1682 args = {
1683 ...args,
1684 ...argsCustom
1685 };
1686 }
1687 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
1688 ...args,
1689 text: message,
1690 className: `${lpData.toast.classPrefix} ${status}`
1691 });
1692 toastify.showToast();
1693 };
1694
1695 /***/ },
1696
1697 /***/ "./assets/src/js/utils.js"
1698 /*!********************************!*\
1699 !*** ./assets/src/js/utils.js ***!
1700 \********************************/
1701 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1702
1703 "use strict";
1704 __webpack_require__.r(__webpack_exports__);
1705 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1706 /* harmony export */ debounce: () => (/* binding */ debounce),
1707 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
1708 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
1709 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
1710 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
1711 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
1712 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
1713 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
1714 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
1715 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
1716 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
1717 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
1718 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
1719 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
1720 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
1721 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
1722 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
1723 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
1724 /* harmony export */ });
1725 /**
1726 * Utils functions
1727 *
1728 * @param url
1729 * @param data
1730 * @param functions
1731 * @since 4.2.5.1
1732 * @version 1.0.7
1733 */
1734 const lpClassName = {
1735 hidden: 'lp-hidden',
1736 loading: 'loading',
1737 elCollapse: 'lp-collapse',
1738 elSectionToggle: '.lp-section-toggle',
1739 elTriggerToggle: '.lp-trigger-toggle',
1740 elBtnFullScreen: '.lp-btn-full-screen-view',
1741 elFullScreen: 'lp-full-screen-view',
1742 elBtnFullScreenClose: 'lp-full-screen-view__close'
1743 };
1744 const lpFetchAPI = (url, data = {}, functions = {}) => {
1745 if ('function' === typeof functions.before) {
1746 functions.before();
1747 }
1748 fetch(url, {
1749 method: 'GET',
1750 ...data
1751 }).then(response => response.json()).then(response => {
1752 if ('function' === typeof functions.success) {
1753 functions.success(response);
1754 }
1755 }).catch(err => {
1756 if ('function' === typeof functions.error) {
1757 functions.error(err);
1758 }
1759 }).finally(() => {
1760 if ('function' === typeof functions.completed) {
1761 functions.completed();
1762 }
1763 });
1764 };
1765
1766 /**
1767 * Get current URL without params.
1768 *
1769 * @since 4.2.5.1
1770 */
1771 const lpGetCurrentURLNoParam = () => {
1772 let currentUrl = window.location.href;
1773 const hasParams = currentUrl.includes('?');
1774 if (hasParams) {
1775 currentUrl = currentUrl.split('?')[0];
1776 }
1777 return currentUrl;
1778 };
1779 const lpAddQueryArgs = (endpoint, args) => {
1780 const url = new URL(endpoint);
1781 Object.keys(args).forEach(arg => {
1782 url.searchParams.set(arg, args[arg]);
1783 });
1784 return url;
1785 };
1786
1787 /**
1788 * Listen element viewed.
1789 *
1790 * @param el
1791 * @param callback
1792 * @since 4.2.5.8
1793 */
1794 const listenElementViewed = (el, callback) => {
1795 const observerSeeItem = new IntersectionObserver(function (entries) {
1796 for (const entry of entries) {
1797 if (entry.isIntersecting) {
1798 callback(entry);
1799 }
1800 }
1801 });
1802 observerSeeItem.observe(el);
1803 };
1804
1805 /**
1806 * Listen element created.
1807 *
1808 * @param callback
1809 * @since 4.2.5.8
1810 */
1811 const listenElementCreated = callback => {
1812 const observerCreateItem = new MutationObserver(function (mutations) {
1813 mutations.forEach(function (mutation) {
1814 if (mutation.addedNodes) {
1815 mutation.addedNodes.forEach(function (node) {
1816 if (node.nodeType === 1) {
1817 callback(node);
1818 }
1819 });
1820 }
1821 });
1822 });
1823 observerCreateItem.observe(document, {
1824 childList: true,
1825 subtree: true
1826 });
1827 // End.
1828 };
1829
1830 /**
1831 * Listen element created.
1832 *
1833 * @param selector
1834 * @param callback
1835 * @since 4.2.7.1
1836 */
1837 const lpOnElementReady = (selector, callback) => {
1838 const element = document.querySelector(selector);
1839 if (element) {
1840 callback(element);
1841 return;
1842 }
1843 const observer = new MutationObserver((mutations, obs) => {
1844 const element = document.querySelector(selector);
1845 if (element) {
1846 obs.disconnect();
1847 callback(element);
1848 }
1849 });
1850 observer.observe(document.documentElement, {
1851 childList: true,
1852 subtree: true
1853 });
1854 };
1855
1856 // Parse JSON from string with content include LP_AJAX_START.
1857 const lpAjaxParseJsonOld = data => {
1858 if (typeof data !== 'string') {
1859 return data;
1860 }
1861 const m = String.raw({
1862 raw: data
1863 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
1864 try {
1865 if (m) {
1866 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
1867 } else {
1868 data = JSON.parse(data);
1869 }
1870 } catch (e) {
1871 data = {};
1872 }
1873 return data;
1874 };
1875
1876 // status 0: hide, 1: show
1877 const lpShowHideEl = (el, status = 0) => {
1878 if (!el) {
1879 return;
1880 }
1881 if (!status) {
1882 el.classList.add(lpClassName.hidden);
1883 } else {
1884 el.classList.remove(lpClassName.hidden);
1885 }
1886 };
1887
1888 // status 0: hide, 1: show
1889 const lpSetLoadingEl = (el, status) => {
1890 if (!el) {
1891 return;
1892 }
1893 if (!status) {
1894 el.classList.remove(lpClassName.loading);
1895 } else {
1896 el.classList.add(lpClassName.loading);
1897 }
1898 };
1899
1900 // Toggle collapse section
1901 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
1902 if (!elTriggerClassName) {
1903 elTriggerClassName = lpClassName.elTriggerToggle;
1904 }
1905
1906 // Exclude elements, which should not trigger the collapse toggle
1907 if (elsExclude && elsExclude.length > 0) {
1908 for (const elExclude of elsExclude) {
1909 if (target.closest(elExclude)) {
1910 return;
1911 }
1912 }
1913 }
1914 const elTrigger = target.closest(elTriggerClassName);
1915 if (!elTrigger) {
1916 return;
1917 }
1918
1919 //console.log( 'elTrigger', elTrigger );
1920
1921 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
1922 if (!elSectionToggle) {
1923 return;
1924 }
1925 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
1926 if ('function' === typeof callback) {
1927 callback(elSectionToggle);
1928 }
1929 };
1930
1931 // Get data of form
1932 const getDataOfForm = form => {
1933 const dataSend = {};
1934 const formData = new FormData(form);
1935 for (const pair of formData.entries()) {
1936 const key = pair[0];
1937 const value = formData.getAll(key);
1938 if (!dataSend.hasOwnProperty(key)) {
1939 // Convert value array to string.
1940 dataSend[key] = value.join(',');
1941 }
1942 }
1943 return dataSend;
1944 };
1945
1946 // Get field keys of form
1947 const getFieldKeysOfForm = form => {
1948 const keys = [];
1949 const elements = form.elements;
1950 for (let i = 0; i < elements.length; i++) {
1951 const name = elements[i].name;
1952 if (name && !keys.includes(name)) {
1953 keys.push(name);
1954 }
1955 }
1956 return keys;
1957 };
1958
1959 // Merge data handle with data form.
1960 const mergeDataWithDatForm = (elForm, dataHandle) => {
1961 const dataForm = getDataOfForm(elForm);
1962 const keys = getFieldKeysOfForm(elForm);
1963 keys.forEach(key => {
1964 if (!dataForm.hasOwnProperty(key)) {
1965 delete dataHandle[key];
1966 } else if (dataForm[key][0] === '') {
1967 delete dataForm[key];
1968 delete dataHandle[key];
1969 }
1970 });
1971 dataHandle = {
1972 ...dataHandle,
1973 ...dataForm
1974 };
1975 return dataHandle;
1976 };
1977
1978 /**
1979 * Event trigger
1980 * For each list of event handlers, listen event on document.
1981 *
1982 * eventName: 'click', 'change', ...
1983 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
1984 *
1985 * @param eventName
1986 * @param eventHandlers
1987 */
1988 const eventHandlers = (eventName, eventHandlers) => {
1989 document.addEventListener(eventName, e => {
1990 const target = e.target;
1991 let args = {
1992 e,
1993 target
1994 };
1995 eventHandlers.forEach(eventHandler => {
1996 args = {
1997 ...args,
1998 ...eventHandler
1999 };
2000
2001 //console.log( args );
2002
2003 // Check condition before call back
2004 if (eventHandler.conditionBeforeCallBack) {
2005 if (eventHandler.conditionBeforeCallBack(args) !== true) {
2006 return;
2007 }
2008 }
2009
2010 // Special check for keydown event with checkIsEventEnter = true
2011 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
2012 if (e.key !== 'Enter') {
2013 return;
2014 }
2015 }
2016 if (target.closest(eventHandler.selector)) {
2017 if (eventHandler.class) {
2018 // Call method of class, function callBack will understand exactly {this} is class object.
2019 eventHandler.class[eventHandler.callBack](args);
2020 } else {
2021 // For send args is objected, {this} is eventHandler object, not class object.
2022 eventHandler.callBack(args);
2023 }
2024 }
2025 });
2026 });
2027 };
2028
2029 /**
2030 * Debounce - delays function execution until after `wait` ms of inactivity.
2031 *
2032 * Each call resets the timer. Only the last call in a burst executes.
2033 *
2034 * USE CASES:
2035 * - Search inputs, form validation, window resize
2036 * - Multiple elements need independent timers
2037 * - When you need to call with different arguments
2038 *
2039 * EXAMPLES:
2040 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
2041 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
2042 *
2043 * const debouncedResize = debounce( recalculateLayout, 250 );
2044 * window.addEventListener('resize', debouncedResize);
2045 *
2046 * ⚠️ Create ONCE outside event handlers, not inside.
2047 *
2048 * @param {Function} func - Function to debounce (can be anonymous)
2049 * @param {number} wait - Milliseconds to wait (default: 500)
2050 * @return {Function} Debounced wrapper function
2051 * @since 4.3.7
2052 * @version 1.0.0
2053 */
2054 const debounce = (func, wait = 500) => {
2055 let timer;
2056 return args => {
2057 clearTimeout(timer);
2058 timer = setTimeout(() => func(args), wait);
2059 };
2060 };
2061
2062 /**
2063 * Initialize lp-toggle-enable components.
2064 *
2065 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
2066 * Reads initial state from `data-enabled` attribute ("true"/"false").
2067 * Calls `data-on-toggle` callback (if provided via options) on state change.
2068 *
2069 * HTML structure:
2070 * <label class="lp-toggle-enable" data-enabled="true">
2071 * <input type="checkbox" class="lp-toggle-enable__input" />
2072 * <span class="lp-toggle-enable__track"></span>
2073 * </label>
2074 *
2075 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
2076 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
2077 * @since 4.4.5
2078 * @version 1.0.0
2079 */
2080 window.lpToggleEnableInit = 0;
2081 const toggleEnable = (onToggle = null) => {
2082 if (window.lpToggleEnableInit) {
2083 return;
2084 }
2085 window.lpToggleEnableInit = 1;
2086 const selector = '.lp-toggle-enable';
2087 const updateUI = (toggle, isEnabled) => {
2088 toggle.classList.toggle('is-enabled', isEnabled);
2089 const input = toggle.querySelector('.lp-toggle-enable__input');
2090 if (input) {
2091 input.checked = isEnabled;
2092 input.value = isEnabled ? '1' : '0';
2093 }
2094 };
2095
2096 // Delegate click handling via eventHandlers.
2097 eventHandlers('click', [{
2098 selector,
2099 callBack: args => {
2100 const {
2101 e,
2102 target
2103 } = args;
2104 const toggle = target.closest(selector);
2105 if (!toggle || toggle.classList.contains('is-disabled')) {
2106 return;
2107 }
2108 e.preventDefault();
2109 const isEnabled = !toggle.classList.contains('is-enabled');
2110 updateUI(toggle, isEnabled);
2111 if ('function' === typeof onToggle) {
2112 onToggle(toggle, isEnabled);
2113 }
2114 }
2115 }]);
2116 };
2117
2118 /**
2119 * Initialize custom fullscreen view buttons.
2120 *
2121 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
2122 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
2123 * target element. Falls back to the button's parent element when
2124 * `data-target` is not provided.
2125 *
2126 * @since 4.4.5
2127 * @version 1.0.0
2128 */
2129 window.lpFullScreenViewInit = 0;
2130 const fullScreenView = () => {
2131 if (window.lpFullScreenViewInit) {
2132 return;
2133 }
2134 window.lpFullScreenViewInit = 1;
2135 let lastScrollY = 0;
2136 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
2137 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
2138 if (isFullscreen) {
2139 elTarget.classList.remove(lpClassName.elFullScreen);
2140 document.documentElement.classList.remove('lp-full-screen-active');
2141 window.scrollTo(0, lastScrollY);
2142 } else {
2143 lastScrollY = window.scrollY;
2144 elTarget.classList.add(lpClassName.elFullScreen);
2145 document.documentElement.classList.add('lp-full-screen-active');
2146 }
2147 if (!isFullscreen) {
2148 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
2149 const closeButton = document.createElement('button');
2150 closeButton.type = 'button';
2151 closeButton.className = lpClassName.elBtnFullScreenClose;
2152 closeButton.setAttribute('aria-label', 'Close');
2153 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
2154 closeButton.addEventListener('click', e => {
2155 e.preventDefault();
2156 lpToggleFullscreenView(elTarget);
2157 });
2158 elTarget.appendChild(closeButton);
2159 }
2160 } else {
2161 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
2162 if (closeButton) {
2163 closeButton.remove();
2164 }
2165 }
2166 };
2167 eventHandlers('click', [{
2168 selector: lpClassName.elBtnFullScreen,
2169 callBack: args => {
2170 const {
2171 e,
2172 target
2173 } = args;
2174 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
2175 if (!elBtnFullScreen) {
2176 console.log('No full screen button found');
2177 return;
2178 }
2179 e.preventDefault();
2180 let elTarget = null;
2181 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
2182 console.log(targetSelector);
2183 if (targetSelector) {
2184 elTarget = document.querySelector(targetSelector);
2185 }
2186 if (!elTarget) {
2187 console.log('No target element found');
2188 return;
2189 }
2190 lpToggleFullscreenView(elTarget, elBtnFullScreen);
2191 }
2192 }]);
2193 };
2194
2195 /***/ },
2196
2197 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
2198 /*!*****************************************************************************************!*\
2199 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
2200 \*****************************************************************************************/
2201 (module, __webpack_exports__, __webpack_require__) {
2202
2203 "use strict";
2204 __webpack_require__.r(__webpack_exports__);
2205 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2206 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2207 /* harmony export */ });
2208 /* 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");
2209 /* 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__);
2210 /* 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");
2211 /* 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__);
2212 // Imports
2213
2214
2215 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()));
2216 // Module
2217 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
2218 * Toastify js 1.12.0
2219 * https://github.com/apvarun/toastify-js
2220 * @license MIT licensed
2221 *
2222 * Copyright (C) 2018 Varun A P
2223 */
2224
2225 .toastify {
2226 padding: 12px 20px;
2227 color: #ffffff;
2228 display: inline-block;
2229 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
2230 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
2231 background: linear-gradient(135deg, #73a5ff, #5477f5);
2232 position: fixed;
2233 opacity: 0;
2234 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
2235 border-radius: 2px;
2236 cursor: pointer;
2237 text-decoration: none;
2238 max-width: calc(50% - 20px);
2239 z-index: 2147483647;
2240 }
2241
2242 .toastify.on {
2243 opacity: 1;
2244 }
2245
2246 .toast-close {
2247 background: transparent;
2248 border: 0;
2249 color: white;
2250 cursor: pointer;
2251 font-family: inherit;
2252 font-size: 1em;
2253 opacity: 0.4;
2254 padding: 0 5px;
2255 }
2256
2257 .toastify-right {
2258 right: 15px;
2259 }
2260
2261 .toastify-left {
2262 left: 15px;
2263 }
2264
2265 .toastify-top {
2266 top: -150px;
2267 }
2268
2269 .toastify-bottom {
2270 bottom: -150px;
2271 }
2272
2273 .toastify-rounded {
2274 border-radius: 25px;
2275 }
2276
2277 .toastify-avatar {
2278 width: 1.5em;
2279 height: 1.5em;
2280 margin: -7px 5px;
2281 border-radius: 2px;
2282 }
2283
2284 .toastify-center {
2285 margin-left: auto;
2286 margin-right: auto;
2287 left: 0;
2288 right: 0;
2289 max-width: fit-content;
2290 max-width: -moz-fit-content;
2291 }
2292
2293 @media only screen and (max-width: 360px) {
2294 .toastify-right, .toastify-left {
2295 margin-left: auto;
2296 margin-right: auto;
2297 left: 0;
2298 right: 0;
2299 max-width: fit-content;
2300 }
2301 }
2302 `, "",{"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":""}]);
2303 // Exports
2304 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
2305
2306
2307 /***/ },
2308
2309 /***/ "./node_modules/css-loader/dist/runtime/api.js"
2310 /*!*****************************************************!*\
2311 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
2312 \*****************************************************/
2313 (module) {
2314
2315 "use strict";
2316
2317
2318 /*
2319 MIT License http://www.opensource.org/licenses/mit-license.php
2320 Author Tobias Koppers @sokra
2321 */
2322 module.exports = function (cssWithMappingToString) {
2323 var list = [];
2324
2325 // return the list of modules as css string
2326 list.toString = function toString() {
2327 return this.map(function (item) {
2328 var content = "";
2329 var needLayer = typeof item[5] !== "undefined";
2330 if (item[4]) {
2331 content += "@supports (".concat(item[4], ") {");
2332 }
2333 if (item[2]) {
2334 content += "@media ".concat(item[2], " {");
2335 }
2336 if (needLayer) {
2337 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
2338 }
2339 content += cssWithMappingToString(item);
2340 if (needLayer) {
2341 content += "}";
2342 }
2343 if (item[2]) {
2344 content += "}";
2345 }
2346 if (item[4]) {
2347 content += "}";
2348 }
2349 return content;
2350 }).join("");
2351 };
2352
2353 // import a list of modules into the list
2354 list.i = function i(modules, media, dedupe, supports, layer) {
2355 if (typeof modules === "string") {
2356 modules = [[null, modules, undefined]];
2357 }
2358 var alreadyImportedModules = {};
2359 if (dedupe) {
2360 for (var k = 0; k < this.length; k++) {
2361 var id = this[k][0];
2362 if (id != null) {
2363 alreadyImportedModules[id] = true;
2364 }
2365 }
2366 }
2367 for (var _k = 0; _k < modules.length; _k++) {
2368 var item = [].concat(modules[_k]);
2369 if (dedupe && alreadyImportedModules[item[0]]) {
2370 continue;
2371 }
2372 if (typeof layer !== "undefined") {
2373 if (typeof item[5] === "undefined") {
2374 item[5] = layer;
2375 } else {
2376 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
2377 item[5] = layer;
2378 }
2379 }
2380 if (media) {
2381 if (!item[2]) {
2382 item[2] = media;
2383 } else {
2384 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
2385 item[2] = media;
2386 }
2387 }
2388 if (supports) {
2389 if (!item[4]) {
2390 item[4] = "".concat(supports);
2391 } else {
2392 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
2393 item[4] = supports;
2394 }
2395 }
2396 list.push(item);
2397 }
2398 };
2399 return list;
2400 };
2401
2402 /***/ },
2403
2404 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
2405 /*!************************************************************!*\
2406 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
2407 \************************************************************/
2408 (module) {
2409
2410 "use strict";
2411
2412
2413 module.exports = function (item) {
2414 var content = item[1];
2415 var cssMapping = item[3];
2416 if (!cssMapping) {
2417 return content;
2418 }
2419 if (typeof btoa === "function") {
2420 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
2421 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
2422 var sourceMapping = "/*# ".concat(data, " */");
2423 return [content].concat([sourceMapping]).join("\n");
2424 }
2425 return [content].join("\n");
2426 };
2427
2428 /***/ },
2429
2430 /***/ "./node_modules/sortablejs/modular/sortable.esm.js"
2431 /*!*********************************************************!*\
2432 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
2433 \*********************************************************/
2434 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2435
2436 "use strict";
2437 __webpack_require__.r(__webpack_exports__);
2438 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2439 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
2440 /* harmony export */ Sortable: () => (/* binding */ Sortable),
2441 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
2442 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
2443 /* harmony export */ });
2444 /**!
2445 * Sortable 1.15.7
2446 * @author RubaXa <trash@rubaxa.org>
2447 * @author owenm <owen23355@gmail.com>
2448 * @license MIT
2449 */
2450 function _arrayLikeToArray(r, a) {
2451 (null == a || a > r.length) && (a = r.length);
2452 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
2453 return n;
2454 }
2455 function _arrayWithoutHoles(r) {
2456 if (Array.isArray(r)) return _arrayLikeToArray(r);
2457 }
2458 function _defineProperty(e, r, t) {
2459 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
2460 value: t,
2461 enumerable: !0,
2462 configurable: !0,
2463 writable: !0
2464 }) : e[r] = t, e;
2465 }
2466 function _extends() {
2467 return _extends = Object.assign ? Object.assign.bind() : function (n) {
2468 for (var e = 1; e < arguments.length; e++) {
2469 var t = arguments[e];
2470 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
2471 }
2472 return n;
2473 }, _extends.apply(null, arguments);
2474 }
2475 function _iterableToArray(r) {
2476 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
2477 }
2478 function _nonIterableSpread() {
2479 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2480 }
2481 function ownKeys(e, r) {
2482 var t = Object.keys(e);
2483 if (Object.getOwnPropertySymbols) {
2484 var o = Object.getOwnPropertySymbols(e);
2485 r && (o = o.filter(function (r) {
2486 return Object.getOwnPropertyDescriptor(e, r).enumerable;
2487 })), t.push.apply(t, o);
2488 }
2489 return t;
2490 }
2491 function _objectSpread2(e) {
2492 for (var r = 1; r < arguments.length; r++) {
2493 var t = null != arguments[r] ? arguments[r] : {};
2494 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
2495 _defineProperty(e, r, t[r]);
2496 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
2497 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
2498 });
2499 }
2500 return e;
2501 }
2502 function _objectWithoutProperties(e, t) {
2503 if (null == e) return {};
2504 var o,
2505 r,
2506 i = _objectWithoutPropertiesLoose(e, t);
2507 if (Object.getOwnPropertySymbols) {
2508 var n = Object.getOwnPropertySymbols(e);
2509 for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
2510 }
2511 return i;
2512 }
2513 function _objectWithoutPropertiesLoose(r, e) {
2514 if (null == r) return {};
2515 var t = {};
2516 for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
2517 if (-1 !== e.indexOf(n)) continue;
2518 t[n] = r[n];
2519 }
2520 return t;
2521 }
2522 function _toConsumableArray(r) {
2523 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
2524 }
2525 function _toPrimitive(t, r) {
2526 if ("object" != typeof t || !t) return t;
2527 var e = t[Symbol.toPrimitive];
2528 if (void 0 !== e) {
2529 var i = e.call(t, r || "default");
2530 if ("object" != typeof i) return i;
2531 throw new TypeError("@@toPrimitive must return a primitive value.");
2532 }
2533 return ("string" === r ? String : Number)(t);
2534 }
2535 function _toPropertyKey(t) {
2536 var i = _toPrimitive(t, "string");
2537 return "symbol" == typeof i ? i : i + "";
2538 }
2539 function _typeof(o) {
2540 "@babel/helpers - typeof";
2541
2542 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
2543 return typeof o;
2544 } : function (o) {
2545 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
2546 }, _typeof(o);
2547 }
2548 function _unsupportedIterableToArray(r, a) {
2549 if (r) {
2550 if ("string" == typeof r) return _arrayLikeToArray(r, a);
2551 var t = {}.toString.call(r).slice(8, -1);
2552 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;
2553 }
2554 }
2555
2556 var version = "1.15.7";
2557
2558 function userAgent(pattern) {
2559 if (typeof window !== 'undefined' && window.navigator) {
2560 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
2561 }
2562 }
2563 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
2564 var Edge = userAgent(/Edge/i);
2565 var FireFox = userAgent(/firefox/i);
2566 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
2567 var IOS = userAgent(/iP(ad|od|hone)/i);
2568 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
2569
2570 var captureMode = {
2571 capture: false,
2572 passive: false
2573 };
2574 function on(el, event, fn) {
2575 el.addEventListener(event, fn, !IE11OrLess && captureMode);
2576 }
2577 function off(el, event, fn) {
2578 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
2579 }
2580 function matches( /**HTMLElement*/el, /**String*/selector) {
2581 if (!selector) return;
2582 selector[0] === '>' && (selector = selector.substring(1));
2583 if (el) {
2584 try {
2585 if (el.matches) {
2586 return el.matches(selector);
2587 } else if (el.msMatchesSelector) {
2588 return el.msMatchesSelector(selector);
2589 } else if (el.webkitMatchesSelector) {
2590 return el.webkitMatchesSelector(selector);
2591 }
2592 } catch (_) {
2593 return false;
2594 }
2595 }
2596 return false;
2597 }
2598 function getParentOrHost(el) {
2599 return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
2600 }
2601 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
2602 if (el) {
2603 ctx = ctx || document;
2604 do {
2605 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
2606 return el;
2607 }
2608 if (el === ctx) break;
2609 /* jshint boss:true */
2610 } while (el = getParentOrHost(el));
2611 }
2612 return null;
2613 }
2614 var R_SPACE = /\s+/g;
2615 function toggleClass(el, name, state) {
2616 if (el && name) {
2617 if (el.classList) {
2618 el.classList[state ? 'add' : 'remove'](name);
2619 } else {
2620 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
2621 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
2622 }
2623 }
2624 }
2625 function css(el, prop, val) {
2626 var style = el && el.style;
2627 if (style) {
2628 if (val === void 0) {
2629 if (document.defaultView && document.defaultView.getComputedStyle) {
2630 val = document.defaultView.getComputedStyle(el, '');
2631 } else if (el.currentStyle) {
2632 val = el.currentStyle;
2633 }
2634 return prop === void 0 ? val : val[prop];
2635 } else {
2636 if (!(prop in style) && prop.indexOf('webkit') === -1) {
2637 prop = '-webkit-' + prop;
2638 }
2639 style[prop] = val + (typeof val === 'string' ? '' : 'px');
2640 }
2641 }
2642 }
2643 function matrix(el, selfOnly) {
2644 var appliedTransforms = '';
2645 if (typeof el === 'string') {
2646 appliedTransforms = el;
2647 } else {
2648 do {
2649 var transform = css(el, 'transform');
2650 if (transform && transform !== 'none') {
2651 appliedTransforms = transform + ' ' + appliedTransforms;
2652 }
2653 /* jshint boss:true */
2654 } while (!selfOnly && (el = el.parentNode));
2655 }
2656 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
2657 /*jshint -W056 */
2658 return matrixFn && new matrixFn(appliedTransforms);
2659 }
2660 function find(ctx, tagName, iterator) {
2661 if (ctx) {
2662 var list = ctx.getElementsByTagName(tagName),
2663 i = 0,
2664 n = list.length;
2665 if (iterator) {
2666 for (; i < n; i++) {
2667 iterator(list[i], i);
2668 }
2669 }
2670 return list;
2671 }
2672 return [];
2673 }
2674 function getWindowScrollingElement() {
2675 var scrollingElement = document.scrollingElement;
2676 if (scrollingElement) {
2677 return scrollingElement;
2678 } else {
2679 return document.documentElement;
2680 }
2681 }
2682
2683 /**
2684 * Returns the "bounding client rect" of given element
2685 * @param {HTMLElement} el The element whose boundingClientRect is wanted
2686 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
2687 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
2688 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
2689 * @param {[HTMLElement]} container The parent the element will be placed in
2690 * @return {Object} The boundingClientRect of el, with specified adjustments
2691 */
2692 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
2693 if (!el.getBoundingClientRect && el !== window) return;
2694 var elRect, top, left, bottom, right, height, width;
2695 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
2696 elRect = el.getBoundingClientRect();
2697 top = elRect.top;
2698 left = elRect.left;
2699 bottom = elRect.bottom;
2700 right = elRect.right;
2701 height = elRect.height;
2702 width = elRect.width;
2703 } else {
2704 top = 0;
2705 left = 0;
2706 bottom = window.innerHeight;
2707 right = window.innerWidth;
2708 height = window.innerHeight;
2709 width = window.innerWidth;
2710 }
2711 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
2712 // Adjust for translate()
2713 container = container || el.parentNode;
2714
2715 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
2716 // Not needed on <= IE11
2717 if (!IE11OrLess) {
2718 do {
2719 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
2720 var containerRect = container.getBoundingClientRect();
2721
2722 // Set relative to edges of padding box of container
2723 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
2724 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
2725 bottom = top + elRect.height;
2726 right = left + elRect.width;
2727 break;
2728 }
2729 /* jshint boss:true */
2730 } while (container = container.parentNode);
2731 }
2732 }
2733 if (undoScale && el !== window) {
2734 // Adjust for scale()
2735 var elMatrix = matrix(container || el),
2736 scaleX = elMatrix && elMatrix.a,
2737 scaleY = elMatrix && elMatrix.d;
2738 if (elMatrix) {
2739 top /= scaleY;
2740 left /= scaleX;
2741 width /= scaleX;
2742 height /= scaleY;
2743 bottom = top + height;
2744 right = left + width;
2745 }
2746 }
2747 return {
2748 top: top,
2749 left: left,
2750 bottom: bottom,
2751 right: right,
2752 width: width,
2753 height: height
2754 };
2755 }
2756
2757 /**
2758 * Checks if a side of an element is scrolled past a side of its parents
2759 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
2760 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
2761 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
2762 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
2763 */
2764 function isScrolledPast(el, elSide, parentSide) {
2765 var parent = getParentAutoScrollElement(el, true),
2766 elSideVal = getRect(el)[elSide];
2767
2768 /* jshint boss:true */
2769 while (parent) {
2770 var parentSideVal = getRect(parent)[parentSide],
2771 visible = void 0;
2772 if (parentSide === 'top' || parentSide === 'left') {
2773 visible = elSideVal >= parentSideVal;
2774 } else {
2775 visible = elSideVal <= parentSideVal;
2776 }
2777 if (!visible) return parent;
2778 if (parent === getWindowScrollingElement()) break;
2779 parent = getParentAutoScrollElement(parent, false);
2780 }
2781 return false;
2782 }
2783
2784 /**
2785 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
2786 * and non-draggable elements
2787 * @param {HTMLElement} el The parent element
2788 * @param {Number} childNum The index of the child
2789 * @param {Object} options Parent Sortable's options
2790 * @return {HTMLElement} The child at index childNum, or null if not found
2791 */
2792 function getChild(el, childNum, options, includeDragEl) {
2793 var currentChild = 0,
2794 i = 0,
2795 children = el.children;
2796 while (i < children.length) {
2797 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
2798 if (currentChild === childNum) {
2799 return children[i];
2800 }
2801 currentChild++;
2802 }
2803 i++;
2804 }
2805 return null;
2806 }
2807
2808 /**
2809 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
2810 * @param {HTMLElement} el Parent element
2811 * @param {selector} selector Any other elements that should be ignored
2812 * @return {HTMLElement} The last child, ignoring ghostEl
2813 */
2814 function lastChild(el, selector) {
2815 var last = el.lastElementChild;
2816 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
2817 last = last.previousElementSibling;
2818 }
2819 return last || null;
2820 }
2821
2822 /**
2823 * Returns the index of an element within its parent for a selected set of
2824 * elements
2825 * @param {HTMLElement} el
2826 * @param {selector} selector
2827 * @return {number}
2828 */
2829 function index(el, selector) {
2830 var index = 0;
2831 if (!el || !el.parentNode) {
2832 return -1;
2833 }
2834
2835 /* jshint boss:true */
2836 while (el = el.previousElementSibling) {
2837 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
2838 index++;
2839 }
2840 }
2841 return index;
2842 }
2843
2844 /**
2845 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
2846 * The value is returned in real pixels.
2847 * @param {HTMLElement} el
2848 * @return {Array} Offsets in the format of [left, top]
2849 */
2850 function getRelativeScrollOffset(el) {
2851 var offsetLeft = 0,
2852 offsetTop = 0,
2853 winScroller = getWindowScrollingElement();
2854 if (el) {
2855 do {
2856 var elMatrix = matrix(el),
2857 scaleX = elMatrix.a,
2858 scaleY = elMatrix.d;
2859 offsetLeft += el.scrollLeft * scaleX;
2860 offsetTop += el.scrollTop * scaleY;
2861 } while (el !== winScroller && (el = el.parentNode));
2862 }
2863 return [offsetLeft, offsetTop];
2864 }
2865
2866 /**
2867 * Returns the index of the object within the given array
2868 * @param {Array} arr Array that may or may not hold the object
2869 * @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
2870 * @return {Number} The index of the object in the array, or -1
2871 */
2872 function indexOfObject(arr, obj) {
2873 for (var i in arr) {
2874 if (!arr.hasOwnProperty(i)) continue;
2875 for (var key in obj) {
2876 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
2877 }
2878 }
2879 return -1;
2880 }
2881 function getParentAutoScrollElement(el, includeSelf) {
2882 // skip to window
2883 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
2884 var elem = el;
2885 var gotSelf = false;
2886 do {
2887 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
2888 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
2889 var elemCSS = css(elem);
2890 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
2891 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
2892 if (gotSelf || includeSelf) return elem;
2893 gotSelf = true;
2894 }
2895 }
2896 /* jshint boss:true */
2897 } while (elem = elem.parentNode);
2898 return getWindowScrollingElement();
2899 }
2900 function extend(dst, src) {
2901 if (dst && src) {
2902 for (var key in src) {
2903 if (src.hasOwnProperty(key)) {
2904 dst[key] = src[key];
2905 }
2906 }
2907 }
2908 return dst;
2909 }
2910 function isRectEqual(rect1, rect2) {
2911 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);
2912 }
2913 var _throttleTimeout;
2914 function throttle(callback, ms) {
2915 return function () {
2916 if (!_throttleTimeout) {
2917 var args = arguments,
2918 _this = this;
2919 if (args.length === 1) {
2920 callback.call(_this, args[0]);
2921 } else {
2922 callback.apply(_this, args);
2923 }
2924 _throttleTimeout = setTimeout(function () {
2925 _throttleTimeout = void 0;
2926 }, ms);
2927 }
2928 };
2929 }
2930 function cancelThrottle() {
2931 clearTimeout(_throttleTimeout);
2932 _throttleTimeout = void 0;
2933 }
2934 function scrollBy(el, x, y) {
2935 el.scrollLeft += x;
2936 el.scrollTop += y;
2937 }
2938 function clone(el) {
2939 var Polymer = window.Polymer;
2940 var $ = window.jQuery || window.Zepto;
2941 if (Polymer && Polymer.dom) {
2942 return Polymer.dom(el).cloneNode(true);
2943 } else if ($) {
2944 return $(el).clone(true)[0];
2945 } else {
2946 return el.cloneNode(true);
2947 }
2948 }
2949 function setRect(el, rect) {
2950 css(el, 'position', 'absolute');
2951 css(el, 'top', rect.top);
2952 css(el, 'left', rect.left);
2953 css(el, 'width', rect.width);
2954 css(el, 'height', rect.height);
2955 }
2956 function unsetRect(el) {
2957 css(el, 'position', '');
2958 css(el, 'top', '');
2959 css(el, 'left', '');
2960 css(el, 'width', '');
2961 css(el, 'height', '');
2962 }
2963 function getChildContainingRectFromElement(container, options, ghostEl) {
2964 var rect = {};
2965 Array.from(container.children).forEach(function (child) {
2966 var _rect$left, _rect$top, _rect$right, _rect$bottom;
2967 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
2968 var childRect = getRect(child);
2969 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
2970 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
2971 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
2972 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
2973 });
2974 rect.width = rect.right - rect.left;
2975 rect.height = rect.bottom - rect.top;
2976 rect.x = rect.left;
2977 rect.y = rect.top;
2978 return rect;
2979 }
2980 var expando = 'Sortable' + new Date().getTime();
2981
2982 function AnimationStateManager() {
2983 var animationStates = [],
2984 animationCallbackId;
2985 return {
2986 captureAnimationState: function captureAnimationState() {
2987 animationStates = [];
2988 if (!this.options.animation) return;
2989 var children = [].slice.call(this.el.children);
2990 children.forEach(function (child) {
2991 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
2992 animationStates.push({
2993 target: child,
2994 rect: getRect(child)
2995 });
2996 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
2997
2998 // If animating: compensate for current animation
2999 if (child.thisAnimationDuration) {
3000 var childMatrix = matrix(child, true);
3001 if (childMatrix) {
3002 fromRect.top -= childMatrix.f;
3003 fromRect.left -= childMatrix.e;
3004 }
3005 }
3006 child.fromRect = fromRect;
3007 });
3008 },
3009 addAnimationState: function addAnimationState(state) {
3010 animationStates.push(state);
3011 },
3012 removeAnimationState: function removeAnimationState(target) {
3013 animationStates.splice(indexOfObject(animationStates, {
3014 target: target
3015 }), 1);
3016 },
3017 animateAll: function animateAll(callback) {
3018 var _this = this;
3019 if (!this.options.animation) {
3020 clearTimeout(animationCallbackId);
3021 if (typeof callback === 'function') callback();
3022 return;
3023 }
3024 var animating = false,
3025 animationTime = 0;
3026 animationStates.forEach(function (state) {
3027 var time = 0,
3028 target = state.target,
3029 fromRect = target.fromRect,
3030 toRect = getRect(target),
3031 prevFromRect = target.prevFromRect,
3032 prevToRect = target.prevToRect,
3033 animatingRect = state.rect,
3034 targetMatrix = matrix(target, true);
3035 if (targetMatrix) {
3036 // Compensate for current animation
3037 toRect.top -= targetMatrix.f;
3038 toRect.left -= targetMatrix.e;
3039 }
3040 target.toRect = toRect;
3041 if (target.thisAnimationDuration) {
3042 // Could also check if animatingRect is between fromRect and toRect
3043 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
3044 // Make sure animatingRect is on line between toRect & fromRect
3045 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
3046 // If returning to same place as started from animation and on same axis
3047 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
3048 }
3049 }
3050
3051 // if fromRect != toRect: animate
3052 if (!isRectEqual(toRect, fromRect)) {
3053 target.prevFromRect = fromRect;
3054 target.prevToRect = toRect;
3055 if (!time) {
3056 time = _this.options.animation;
3057 }
3058 _this.animate(target, animatingRect, toRect, time);
3059 }
3060 if (time) {
3061 animating = true;
3062 animationTime = Math.max(animationTime, time);
3063 clearTimeout(target.animationResetTimer);
3064 target.animationResetTimer = setTimeout(function () {
3065 target.animationTime = 0;
3066 target.prevFromRect = null;
3067 target.fromRect = null;
3068 target.prevToRect = null;
3069 target.thisAnimationDuration = null;
3070 }, time);
3071 target.thisAnimationDuration = time;
3072 }
3073 });
3074 clearTimeout(animationCallbackId);
3075 if (!animating) {
3076 if (typeof callback === 'function') callback();
3077 } else {
3078 animationCallbackId = setTimeout(function () {
3079 if (typeof callback === 'function') callback();
3080 }, animationTime);
3081 }
3082 animationStates = [];
3083 },
3084 animate: function animate(target, currentRect, toRect, duration) {
3085 if (duration) {
3086 css(target, 'transition', '');
3087 css(target, 'transform', '');
3088 var elMatrix = matrix(this.el),
3089 scaleX = elMatrix && elMatrix.a,
3090 scaleY = elMatrix && elMatrix.d,
3091 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
3092 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
3093 target.animatingX = !!translateX;
3094 target.animatingY = !!translateY;
3095 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
3096 this.forRepaintDummy = repaint(target); // repaint
3097
3098 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
3099 css(target, 'transform', 'translate3d(0,0,0)');
3100 typeof target.animated === 'number' && clearTimeout(target.animated);
3101 target.animated = setTimeout(function () {
3102 css(target, 'transition', '');
3103 css(target, 'transform', '');
3104 target.animated = false;
3105 target.animatingX = false;
3106 target.animatingY = false;
3107 }, duration);
3108 }
3109 }
3110 };
3111 }
3112 function repaint(target) {
3113 return target.offsetWidth;
3114 }
3115 function calculateRealTime(animatingRect, fromRect, toRect, options) {
3116 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;
3117 }
3118
3119 var plugins = [];
3120 var defaults = {
3121 initializeByDefault: true
3122 };
3123 var PluginManager = {
3124 mount: function mount(plugin) {
3125 // Set default static properties
3126 for (var option in defaults) {
3127 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
3128 plugin[option] = defaults[option];
3129 }
3130 }
3131 plugins.forEach(function (p) {
3132 if (p.pluginName === plugin.pluginName) {
3133 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
3134 }
3135 });
3136 plugins.push(plugin);
3137 },
3138 pluginEvent: function pluginEvent(eventName, sortable, evt) {
3139 var _this = this;
3140 this.eventCanceled = false;
3141 evt.cancel = function () {
3142 _this.eventCanceled = true;
3143 };
3144 var eventNameGlobal = eventName + 'Global';
3145 plugins.forEach(function (plugin) {
3146 if (!sortable[plugin.pluginName]) return;
3147 // Fire global events if it exists in this sortable
3148 if (sortable[plugin.pluginName][eventNameGlobal]) {
3149 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
3150 sortable: sortable
3151 }, evt));
3152 }
3153
3154 // Only fire plugin event if plugin is enabled in this sortable,
3155 // and plugin has event defined
3156 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
3157 sortable[plugin.pluginName][eventName](_objectSpread2({
3158 sortable: sortable
3159 }, evt));
3160 }
3161 });
3162 },
3163 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
3164 plugins.forEach(function (plugin) {
3165 var pluginName = plugin.pluginName;
3166 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
3167 var initialized = new plugin(sortable, el, sortable.options);
3168 initialized.sortable = sortable;
3169 initialized.options = sortable.options;
3170 sortable[pluginName] = initialized;
3171
3172 // Add default options from plugin
3173 _extends(defaults, initialized.defaults);
3174 });
3175 for (var option in sortable.options) {
3176 if (!sortable.options.hasOwnProperty(option)) continue;
3177 var modified = this.modifyOption(sortable, option, sortable.options[option]);
3178 if (typeof modified !== 'undefined') {
3179 sortable.options[option] = modified;
3180 }
3181 }
3182 },
3183 getEventProperties: function getEventProperties(name, sortable) {
3184 var eventProperties = {};
3185 plugins.forEach(function (plugin) {
3186 if (typeof plugin.eventProperties !== 'function') return;
3187 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
3188 });
3189 return eventProperties;
3190 },
3191 modifyOption: function modifyOption(sortable, name, value) {
3192 var modifiedValue;
3193 plugins.forEach(function (plugin) {
3194 // Plugin must exist on the Sortable
3195 if (!sortable[plugin.pluginName]) return;
3196
3197 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
3198 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
3199 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
3200 }
3201 });
3202 return modifiedValue;
3203 }
3204 };
3205
3206 function dispatchEvent(_ref) {
3207 var sortable = _ref.sortable,
3208 rootEl = _ref.rootEl,
3209 name = _ref.name,
3210 targetEl = _ref.targetEl,
3211 cloneEl = _ref.cloneEl,
3212 toEl = _ref.toEl,
3213 fromEl = _ref.fromEl,
3214 oldIndex = _ref.oldIndex,
3215 newIndex = _ref.newIndex,
3216 oldDraggableIndex = _ref.oldDraggableIndex,
3217 newDraggableIndex = _ref.newDraggableIndex,
3218 originalEvent = _ref.originalEvent,
3219 putSortable = _ref.putSortable,
3220 extraEventProperties = _ref.extraEventProperties;
3221 sortable = sortable || rootEl && rootEl[expando];
3222 if (!sortable) return;
3223 var evt,
3224 options = sortable.options,
3225 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
3226 // Support for new CustomEvent feature
3227 if (window.CustomEvent && !IE11OrLess && !Edge) {
3228 evt = new CustomEvent(name, {
3229 bubbles: true,
3230 cancelable: true
3231 });
3232 } else {
3233 evt = document.createEvent('Event');
3234 evt.initEvent(name, true, true);
3235 }
3236 evt.to = toEl || rootEl;
3237 evt.from = fromEl || rootEl;
3238 evt.item = targetEl || rootEl;
3239 evt.clone = cloneEl;
3240 evt.oldIndex = oldIndex;
3241 evt.newIndex = newIndex;
3242 evt.oldDraggableIndex = oldDraggableIndex;
3243 evt.newDraggableIndex = newDraggableIndex;
3244 evt.originalEvent = originalEvent;
3245 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
3246 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
3247 for (var option in allEventProperties) {
3248 evt[option] = allEventProperties[option];
3249 }
3250 if (rootEl) {
3251 rootEl.dispatchEvent(evt);
3252 }
3253 if (options[onName]) {
3254 options[onName].call(sortable, evt);
3255 }
3256 }
3257
3258 var _excluded = ["evt"];
3259 var pluginEvent = function pluginEvent(eventName, sortable) {
3260 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
3261 originalEvent = _ref.evt,
3262 data = _objectWithoutProperties(_ref, _excluded);
3263 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
3264 dragEl: dragEl,
3265 parentEl: parentEl,
3266 ghostEl: ghostEl,
3267 rootEl: rootEl,
3268 nextEl: nextEl,
3269 lastDownEl: lastDownEl,
3270 cloneEl: cloneEl,
3271 cloneHidden: cloneHidden,
3272 dragStarted: moved,
3273 putSortable: putSortable,
3274 activeSortable: Sortable.active,
3275 originalEvent: originalEvent,
3276 oldIndex: oldIndex,
3277 oldDraggableIndex: oldDraggableIndex,
3278 newIndex: newIndex,
3279 newDraggableIndex: newDraggableIndex,
3280 hideGhostForTarget: _hideGhostForTarget,
3281 unhideGhostForTarget: _unhideGhostForTarget,
3282 cloneNowHidden: function cloneNowHidden() {
3283 cloneHidden = true;
3284 },
3285 cloneNowShown: function cloneNowShown() {
3286 cloneHidden = false;
3287 },
3288 dispatchSortableEvent: function dispatchSortableEvent(name) {
3289 _dispatchEvent({
3290 sortable: sortable,
3291 name: name,
3292 originalEvent: originalEvent
3293 });
3294 }
3295 }, data));
3296 };
3297 function _dispatchEvent(info) {
3298 dispatchEvent(_objectSpread2({
3299 putSortable: putSortable,
3300 cloneEl: cloneEl,
3301 targetEl: dragEl,
3302 rootEl: rootEl,
3303 oldIndex: oldIndex,
3304 oldDraggableIndex: oldDraggableIndex,
3305 newIndex: newIndex,
3306 newDraggableIndex: newDraggableIndex
3307 }, info));
3308 }
3309 var dragEl,
3310 parentEl,
3311 ghostEl,
3312 rootEl,
3313 nextEl,
3314 lastDownEl,
3315 cloneEl,
3316 cloneHidden,
3317 oldIndex,
3318 newIndex,
3319 oldDraggableIndex,
3320 newDraggableIndex,
3321 activeGroup,
3322 putSortable,
3323 awaitingDragStarted = false,
3324 ignoreNextClick = false,
3325 sortables = [],
3326 tapEvt,
3327 touchEvt,
3328 lastDx,
3329 lastDy,
3330 tapDistanceLeft,
3331 tapDistanceTop,
3332 moved,
3333 lastTarget,
3334 lastDirection,
3335 pastFirstInvertThresh = false,
3336 isCircumstantialInvert = false,
3337 targetMoveDistance,
3338 // For positioning ghost absolutely
3339 ghostRelativeParent,
3340 ghostRelativeParentInitialScroll = [],
3341 // (left, top)
3342
3343 _silent = false,
3344 savedInputChecked = [];
3345
3346 /** @const */
3347 var documentExists = typeof document !== 'undefined',
3348 PositionGhostAbsolutely = IOS,
3349 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
3350 // This will not pass for IE9, because IE9 DnD only works on anchors
3351 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
3352 supportCssPointerEvents = function () {
3353 if (!documentExists) return;
3354 // false when <= IE11
3355 if (IE11OrLess) {
3356 return false;
3357 }
3358 var el = document.createElement('x');
3359 el.style.cssText = 'pointer-events:auto';
3360 return el.style.pointerEvents === 'auto';
3361 }(),
3362 _detectDirection = function _detectDirection(el, options) {
3363 var elCSS = css(el),
3364 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
3365 child1 = getChild(el, 0, options),
3366 child2 = getChild(el, 1, options),
3367 firstChildCSS = child1 && css(child1),
3368 secondChildCSS = child2 && css(child2),
3369 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
3370 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
3371 if (elCSS.display === 'flex') {
3372 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
3373 }
3374 if (elCSS.display === 'grid') {
3375 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
3376 }
3377 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
3378 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
3379 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
3380 }
3381 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';
3382 },
3383 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
3384 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
3385 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
3386 dragElOppLength = vertical ? dragRect.width : dragRect.height,
3387 targetS1Opp = vertical ? targetRect.left : targetRect.top,
3388 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
3389 targetOppLength = vertical ? targetRect.width : targetRect.height;
3390 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
3391 },
3392 /**
3393 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
3394 * @param {Number} x X position
3395 * @param {Number} y Y position
3396 * @return {HTMLElement} Element of the first found nearest Sortable
3397 */
3398 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
3399 var ret;
3400 sortables.some(function (sortable) {
3401 var threshold = sortable[expando].options.emptyInsertThreshold;
3402 if (!threshold || lastChild(sortable)) return;
3403 var rect = getRect(sortable),
3404 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
3405 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
3406 if (insideHorizontally && insideVertically) {
3407 return ret = sortable;
3408 }
3409 });
3410 return ret;
3411 },
3412 _prepareGroup = function _prepareGroup(options) {
3413 function toFn(value, pull) {
3414 return function (to, from, dragEl, evt) {
3415 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
3416 if (value == null && (pull || sameGroup)) {
3417 // Default pull value
3418 // Default pull and put value if same group
3419 return true;
3420 } else if (value == null || value === false) {
3421 return false;
3422 } else if (pull && value === 'clone') {
3423 return value;
3424 } else if (typeof value === 'function') {
3425 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
3426 } else {
3427 var otherGroup = (pull ? to : from).options.group.name;
3428 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
3429 }
3430 };
3431 }
3432 var group = {};
3433 var originalGroup = options.group;
3434 if (!originalGroup || _typeof(originalGroup) != 'object') {
3435 originalGroup = {
3436 name: originalGroup
3437 };
3438 }
3439 group.name = originalGroup.name;
3440 group.checkPull = toFn(originalGroup.pull, true);
3441 group.checkPut = toFn(originalGroup.put);
3442 group.revertClone = originalGroup.revertClone;
3443 options.group = group;
3444 },
3445 _hideGhostForTarget = function _hideGhostForTarget() {
3446 if (!supportCssPointerEvents && ghostEl) {
3447 css(ghostEl, 'display', 'none');
3448 }
3449 },
3450 _unhideGhostForTarget = function _unhideGhostForTarget() {
3451 if (!supportCssPointerEvents && ghostEl) {
3452 css(ghostEl, 'display', '');
3453 }
3454 };
3455
3456 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
3457 if (documentExists && !ChromeForAndroid) {
3458 document.addEventListener('click', function (evt) {
3459 if (ignoreNextClick) {
3460 evt.preventDefault();
3461 evt.stopPropagation && evt.stopPropagation();
3462 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
3463 ignoreNextClick = false;
3464 return false;
3465 }
3466 }, true);
3467 }
3468 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
3469 if (dragEl) {
3470 evt = evt.touches ? evt.touches[0] : evt;
3471 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
3472 if (nearest) {
3473 // Create imitation event
3474 var event = {};
3475 for (var i in evt) {
3476 if (evt.hasOwnProperty(i)) {
3477 event[i] = evt[i];
3478 }
3479 }
3480 event.target = event.rootEl = nearest;
3481 event.preventDefault = void 0;
3482 event.stopPropagation = void 0;
3483 nearest[expando]._onDragOver(event);
3484 }
3485 }
3486 };
3487 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
3488 if (dragEl) {
3489 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
3490 }
3491 };
3492
3493 /**
3494 * @class Sortable
3495 * @param {HTMLElement} el
3496 * @param {Object} [options]
3497 */
3498 function Sortable(el, options) {
3499 if (!(el && el.nodeType && el.nodeType === 1)) {
3500 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
3501 }
3502 this.el = el; // root element
3503 this.options = options = _extends({}, options);
3504
3505 // Export instance
3506 el[expando] = this;
3507 var defaults = {
3508 group: null,
3509 sort: true,
3510 disabled: false,
3511 store: null,
3512 handle: null,
3513 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
3514 swapThreshold: 1,
3515 // percentage; 0 <= x <= 1
3516 invertSwap: false,
3517 // invert always
3518 invertedSwapThreshold: null,
3519 // will be set to same as swapThreshold if default
3520 removeCloneOnHide: true,
3521 direction: function direction() {
3522 return _detectDirection(el, this.options);
3523 },
3524 ghostClass: 'sortable-ghost',
3525 chosenClass: 'sortable-chosen',
3526 dragClass: 'sortable-drag',
3527 ignore: 'a, img',
3528 filter: null,
3529 preventOnFilter: true,
3530 animation: 0,
3531 easing: null,
3532 setData: function setData(dataTransfer, dragEl) {
3533 dataTransfer.setData('Text', dragEl.textContent);
3534 },
3535 dropBubble: false,
3536 dragoverBubble: false,
3537 dataIdAttr: 'data-id',
3538 delay: 0,
3539 delayOnTouchOnly: false,
3540 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
3541 forceFallback: false,
3542 fallbackClass: 'sortable-fallback',
3543 fallbackOnBody: false,
3544 fallbackTolerance: 0,
3545 fallbackOffset: {
3546 x: 0,
3547 y: 0
3548 },
3549 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
3550 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
3551 emptyInsertThreshold: 5
3552 };
3553 PluginManager.initializePlugins(this, el, defaults);
3554
3555 // Set default options
3556 for (var name in defaults) {
3557 !(name in options) && (options[name] = defaults[name]);
3558 }
3559 _prepareGroup(options);
3560
3561 // Bind all private methods
3562 for (var fn in this) {
3563 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
3564 this[fn] = this[fn].bind(this);
3565 }
3566 }
3567
3568 // Setup drag mode
3569 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
3570 if (this.nativeDraggable) {
3571 // Touch start threshold cannot be greater than the native dragstart threshold
3572 this.options.touchStartThreshold = 1;
3573 }
3574
3575 // Bind events
3576 if (options.supportPointer) {
3577 on(el, 'pointerdown', this._onTapStart);
3578 } else {
3579 on(el, 'mousedown', this._onTapStart);
3580 on(el, 'touchstart', this._onTapStart);
3581 }
3582 if (this.nativeDraggable) {
3583 on(el, 'dragover', this);
3584 on(el, 'dragenter', this);
3585 }
3586 sortables.push(this.el);
3587
3588 // Restore sorting
3589 options.store && options.store.get && this.sort(options.store.get(this) || []);
3590
3591 // Add animation state manager
3592 _extends(this, AnimationStateManager());
3593 }
3594 Sortable.prototype = /** @lends Sortable.prototype */{
3595 constructor: Sortable,
3596 _isOutsideThisEl: function _isOutsideThisEl(target) {
3597 if (!this.el.contains(target) && target !== this.el) {
3598 lastTarget = null;
3599 }
3600 },
3601 _getDirection: function _getDirection(evt, target) {
3602 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
3603 },
3604 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
3605 if (!evt.cancelable) return;
3606 var _this = this,
3607 el = this.el,
3608 options = this.options,
3609 preventOnFilter = options.preventOnFilter,
3610 type = evt.type,
3611 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
3612 target = (touch || evt).target,
3613 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
3614 filter = options.filter;
3615 _saveInputCheckedState(el);
3616
3617 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
3618 if (dragEl) {
3619 return;
3620 }
3621 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
3622 return; // only left button and enabled
3623 }
3624
3625 // cancel dnd if original target is content editable
3626 if (originalTarget.isContentEditable) {
3627 return;
3628 }
3629
3630 // Safari ignores further event handling after mousedown
3631 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
3632 return;
3633 }
3634 target = closest(target, options.draggable, el, false);
3635 if (target && target.animated) {
3636 return;
3637 }
3638 if (lastDownEl === target) {
3639 // Ignoring duplicate `down`
3640 return;
3641 }
3642
3643 // Get the index of the dragged element within its parent
3644 oldIndex = index(target);
3645 oldDraggableIndex = index(target, options.draggable);
3646
3647 // Check filter
3648 if (typeof filter === 'function') {
3649 if (filter.call(this, evt, target, this)) {
3650 _dispatchEvent({
3651 sortable: _this,
3652 rootEl: originalTarget,
3653 name: 'filter',
3654 targetEl: target,
3655 toEl: el,
3656 fromEl: el
3657 });
3658 pluginEvent('filter', _this, {
3659 evt: evt
3660 });
3661 preventOnFilter && evt.preventDefault();
3662 return; // cancel dnd
3663 }
3664 } else if (filter) {
3665 filter = filter.split(',').some(function (criteria) {
3666 criteria = closest(originalTarget, criteria.trim(), el, false);
3667 if (criteria) {
3668 _dispatchEvent({
3669 sortable: _this,
3670 rootEl: criteria,
3671 name: 'filter',
3672 targetEl: target,
3673 fromEl: el,
3674 toEl: el
3675 });
3676 pluginEvent('filter', _this, {
3677 evt: evt
3678 });
3679 return true;
3680 }
3681 });
3682 if (filter) {
3683 preventOnFilter && evt.preventDefault();
3684 return; // cancel dnd
3685 }
3686 }
3687 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
3688 return;
3689 }
3690
3691 // Prepare `dragstart`
3692 this._prepareDragStart(evt, touch, target);
3693 },
3694 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
3695 var _this = this,
3696 el = _this.el,
3697 options = _this.options,
3698 ownerDocument = el.ownerDocument,
3699 dragStartFn;
3700 if (target && !dragEl && target.parentNode === el) {
3701 var dragRect = getRect(target);
3702 rootEl = el;
3703 dragEl = target;
3704 parentEl = dragEl.parentNode;
3705 nextEl = dragEl.nextSibling;
3706 lastDownEl = target;
3707 activeGroup = options.group;
3708 Sortable.dragged = dragEl;
3709 tapEvt = {
3710 target: dragEl,
3711 clientX: (touch || evt).clientX,
3712 clientY: (touch || evt).clientY
3713 };
3714 tapDistanceLeft = tapEvt.clientX - dragRect.left;
3715 tapDistanceTop = tapEvt.clientY - dragRect.top;
3716 this._lastX = (touch || evt).clientX;
3717 this._lastY = (touch || evt).clientY;
3718 dragEl.style['will-change'] = 'all';
3719 dragStartFn = function dragStartFn() {
3720 pluginEvent('delayEnded', _this, {
3721 evt: evt
3722 });
3723 if (Sortable.eventCanceled) {
3724 _this._onDrop();
3725 return;
3726 }
3727 // Delayed drag has been triggered
3728 // we can re-enable the events: touchmove/mousemove
3729 _this._disableDelayedDragEvents();
3730 if (!FireFox && _this.nativeDraggable) {
3731 dragEl.draggable = true;
3732 }
3733
3734 // Bind the events: dragstart/dragend
3735 _this._triggerDragStart(evt, touch);
3736
3737 // Drag start event
3738 _dispatchEvent({
3739 sortable: _this,
3740 name: 'choose',
3741 originalEvent: evt
3742 });
3743
3744 // Chosen item
3745 toggleClass(dragEl, options.chosenClass, true);
3746 };
3747
3748 // Disable "draggable"
3749 options.ignore.split(',').forEach(function (criteria) {
3750 find(dragEl, criteria.trim(), _disableDraggable);
3751 });
3752 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
3753 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
3754 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
3755 if (options.supportPointer) {
3756 on(ownerDocument, 'pointerup', _this._onDrop);
3757 // Native D&D triggers pointercancel
3758 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
3759 } else {
3760 on(ownerDocument, 'mouseup', _this._onDrop);
3761 on(ownerDocument, 'touchend', _this._onDrop);
3762 on(ownerDocument, 'touchcancel', _this._onDrop);
3763 }
3764
3765 // Make dragEl draggable (must be before delay for FireFox)
3766 if (FireFox && this.nativeDraggable) {
3767 this.options.touchStartThreshold = 4;
3768 dragEl.draggable = true;
3769 }
3770 pluginEvent('delayStart', this, {
3771 evt: evt
3772 });
3773
3774 // Delay is impossible for native DnD in Edge or IE
3775 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
3776 if (Sortable.eventCanceled) {
3777 this._onDrop();
3778 return;
3779 }
3780 // If the user moves the pointer or let go the click or touch
3781 // before the delay has been reached:
3782 // disable the delayed drag
3783 if (options.supportPointer) {
3784 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
3785 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
3786 } else {
3787 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
3788 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
3789 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
3790 }
3791 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
3792 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
3793 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
3794 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
3795 } else {
3796 dragStartFn();
3797 }
3798 }
3799 },
3800 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
3801 var touch = e.touches ? e.touches[0] : e;
3802 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))) {
3803 this._disableDelayedDrag();
3804 }
3805 },
3806 _disableDelayedDrag: function _disableDelayedDrag() {
3807 dragEl && _disableDraggable(dragEl);
3808 clearTimeout(this._dragStartTimer);
3809 this._disableDelayedDragEvents();
3810 },
3811 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
3812 var ownerDocument = this.el.ownerDocument;
3813 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
3814 off(ownerDocument, 'touchend', this._disableDelayedDrag);
3815 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
3816 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
3817 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
3818 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
3819 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
3820 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
3821 },
3822 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
3823 touch = touch || evt.pointerType == 'touch' && evt;
3824 if (!this.nativeDraggable || touch) {
3825 if (this.options.supportPointer) {
3826 on(document, 'pointermove', this._onTouchMove);
3827 } else if (touch) {
3828 on(document, 'touchmove', this._onTouchMove);
3829 } else {
3830 on(document, 'mousemove', this._onTouchMove);
3831 }
3832 } else {
3833 on(dragEl, 'dragend', this);
3834 on(rootEl, 'dragstart', this._onDragStart);
3835 }
3836 try {
3837 if (document.selection) {
3838 _nextTick(function () {
3839 document.selection.empty();
3840 });
3841 } else {
3842 window.getSelection().removeAllRanges();
3843 }
3844 } catch (err) {}
3845 },
3846 _dragStarted: function _dragStarted(fallback, evt) {
3847 awaitingDragStarted = false;
3848 if (rootEl && dragEl) {
3849 pluginEvent('dragStarted', this, {
3850 evt: evt
3851 });
3852 if (this.nativeDraggable) {
3853 on(document, 'dragover', _checkOutsideTargetEl);
3854 }
3855 var options = this.options;
3856
3857 // Apply effect
3858 !fallback && toggleClass(dragEl, options.dragClass, false);
3859 toggleClass(dragEl, options.ghostClass, true);
3860 Sortable.active = this;
3861 fallback && this._appendGhost();
3862
3863 // Drag start event
3864 _dispatchEvent({
3865 sortable: this,
3866 name: 'start',
3867 originalEvent: evt
3868 });
3869 } else {
3870 this._nulling();
3871 }
3872 },
3873 _emulateDragOver: function _emulateDragOver() {
3874 if (touchEvt) {
3875 this._lastX = touchEvt.clientX;
3876 this._lastY = touchEvt.clientY;
3877 _hideGhostForTarget();
3878 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3879 var parent = target;
3880 while (target && target.shadowRoot) {
3881 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
3882 if (target === parent) break;
3883 parent = target;
3884 }
3885 dragEl.parentNode[expando]._isOutsideThisEl(target);
3886 if (parent) {
3887 do {
3888 if (parent[expando]) {
3889 var inserted = void 0;
3890 inserted = parent[expando]._onDragOver({
3891 clientX: touchEvt.clientX,
3892 clientY: touchEvt.clientY,
3893 target: target,
3894 rootEl: parent
3895 });
3896 if (inserted && !this.options.dragoverBubble) {
3897 break;
3898 }
3899 }
3900 target = parent; // store last element
3901 }
3902 /* jshint boss:true */ while (parent = getParentOrHost(parent));
3903 }
3904 _unhideGhostForTarget();
3905 }
3906 },
3907 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
3908 if (tapEvt) {
3909 var options = this.options,
3910 fallbackTolerance = options.fallbackTolerance,
3911 fallbackOffset = options.fallbackOffset,
3912 touch = evt.touches ? evt.touches[0] : evt,
3913 ghostMatrix = ghostEl && matrix(ghostEl, true),
3914 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
3915 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
3916 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
3917 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
3918 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
3919
3920 // only set the status to dragging, when we are actually dragging
3921 if (!Sortable.active && !awaitingDragStarted) {
3922 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
3923 return;
3924 }
3925 this._onDragStart(evt, true);
3926 }
3927 if (ghostEl) {
3928 if (ghostMatrix) {
3929 ghostMatrix.e += dx - (lastDx || 0);
3930 ghostMatrix.f += dy - (lastDy || 0);
3931 } else {
3932 ghostMatrix = {
3933 a: 1,
3934 b: 0,
3935 c: 0,
3936 d: 1,
3937 e: dx,
3938 f: dy
3939 };
3940 }
3941 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
3942 css(ghostEl, 'webkitTransform', cssMatrix);
3943 css(ghostEl, 'mozTransform', cssMatrix);
3944 css(ghostEl, 'msTransform', cssMatrix);
3945 css(ghostEl, 'transform', cssMatrix);
3946 lastDx = dx;
3947 lastDy = dy;
3948 touchEvt = touch;
3949 }
3950 evt.cancelable && evt.preventDefault();
3951 }
3952 },
3953 _appendGhost: function _appendGhost() {
3954 // Bug if using scale(): https://stackoverflow.com/questions/2637058
3955 // Not being adjusted for
3956 if (!ghostEl) {
3957 var container = this.options.fallbackOnBody ? document.body : rootEl,
3958 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
3959 options = this.options;
3960
3961 // Position absolutely
3962 if (PositionGhostAbsolutely) {
3963 // Get relatively positioned parent
3964 ghostRelativeParent = container;
3965 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
3966 ghostRelativeParent = ghostRelativeParent.parentNode;
3967 }
3968 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
3969 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
3970 rect.top += ghostRelativeParent.scrollTop;
3971 rect.left += ghostRelativeParent.scrollLeft;
3972 } else {
3973 ghostRelativeParent = getWindowScrollingElement();
3974 }
3975 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
3976 }
3977 ghostEl = dragEl.cloneNode(true);
3978 toggleClass(ghostEl, options.ghostClass, false);
3979 toggleClass(ghostEl, options.fallbackClass, true);
3980 toggleClass(ghostEl, options.dragClass, true);
3981 css(ghostEl, 'transition', '');
3982 css(ghostEl, 'transform', '');
3983 css(ghostEl, 'box-sizing', 'border-box');
3984 css(ghostEl, 'margin', 0);
3985 css(ghostEl, 'top', rect.top);
3986 css(ghostEl, 'left', rect.left);
3987 css(ghostEl, 'width', rect.width);
3988 css(ghostEl, 'height', rect.height);
3989 css(ghostEl, 'opacity', '0.8');
3990 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
3991 css(ghostEl, 'zIndex', '100000');
3992 css(ghostEl, 'pointerEvents', 'none');
3993 Sortable.ghost = ghostEl;
3994 container.appendChild(ghostEl);
3995
3996 // Set transform-origin
3997 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
3998 }
3999 },
4000 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
4001 var _this = this;
4002 var dataTransfer = evt.dataTransfer;
4003 var options = _this.options;
4004 pluginEvent('dragStart', this, {
4005 evt: evt
4006 });
4007 if (Sortable.eventCanceled) {
4008 this._onDrop();
4009 return;
4010 }
4011 pluginEvent('setupClone', this);
4012 if (!Sortable.eventCanceled) {
4013 cloneEl = clone(dragEl);
4014 cloneEl.removeAttribute("id");
4015 cloneEl.draggable = false;
4016 cloneEl.style['will-change'] = '';
4017 this._hideClone();
4018 toggleClass(cloneEl, this.options.chosenClass, false);
4019 Sortable.clone = cloneEl;
4020 }
4021
4022 // #1143: IFrame support workaround
4023 _this.cloneId = _nextTick(function () {
4024 pluginEvent('clone', _this);
4025 if (Sortable.eventCanceled) return;
4026 if (!_this.options.removeCloneOnHide) {
4027 rootEl.insertBefore(cloneEl, dragEl);
4028 }
4029 _this._hideClone();
4030 _dispatchEvent({
4031 sortable: _this,
4032 name: 'clone'
4033 });
4034 });
4035 !fallback && toggleClass(dragEl, options.dragClass, true);
4036
4037 // Set proper drop events
4038 if (fallback) {
4039 ignoreNextClick = true;
4040 _this._loopId = setInterval(_this._emulateDragOver, 50);
4041 } else {
4042 // Undo what was set in _prepareDragStart before drag started
4043 off(document, 'mouseup', _this._onDrop);
4044 off(document, 'touchend', _this._onDrop);
4045 off(document, 'touchcancel', _this._onDrop);
4046 if (dataTransfer) {
4047 dataTransfer.effectAllowed = 'move';
4048 options.setData && options.setData.call(_this, dataTransfer, dragEl);
4049 }
4050 on(document, 'drop', _this);
4051
4052 // #1276 fix:
4053 css(dragEl, 'transform', 'translateZ(0)');
4054 }
4055 awaitingDragStarted = true;
4056 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
4057 on(document, 'selectstart', _this);
4058 moved = true;
4059 window.getSelection().removeAllRanges();
4060 if (Safari) {
4061 css(document.body, 'user-select', 'none');
4062 }
4063 },
4064 // Returns true - if no further action is needed (either inserted or another condition)
4065 _onDragOver: function _onDragOver( /**Event*/evt) {
4066 var el = this.el,
4067 target = evt.target,
4068 dragRect,
4069 targetRect,
4070 revert,
4071 options = this.options,
4072 group = options.group,
4073 activeSortable = Sortable.active,
4074 isOwner = activeGroup === group,
4075 canSort = options.sort,
4076 fromSortable = putSortable || activeSortable,
4077 vertical,
4078 _this = this,
4079 completedFired = false;
4080 if (_silent) return;
4081 function dragOverEvent(name, extra) {
4082 pluginEvent(name, _this, _objectSpread2({
4083 evt: evt,
4084 isOwner: isOwner,
4085 axis: vertical ? 'vertical' : 'horizontal',
4086 revert: revert,
4087 dragRect: dragRect,
4088 targetRect: targetRect,
4089 canSort: canSort,
4090 fromSortable: fromSortable,
4091 target: target,
4092 completed: completed,
4093 onMove: function onMove(target, after) {
4094 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
4095 },
4096 changed: changed
4097 }, extra));
4098 }
4099
4100 // Capture animation state
4101 function capture() {
4102 dragOverEvent('dragOverAnimationCapture');
4103 _this.captureAnimationState();
4104 if (_this !== fromSortable) {
4105 fromSortable.captureAnimationState();
4106 }
4107 }
4108
4109 // Return invocation when dragEl is inserted (or completed)
4110 function completed(insertion) {
4111 dragOverEvent('dragOverCompleted', {
4112 insertion: insertion
4113 });
4114 if (insertion) {
4115 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
4116 if (isOwner) {
4117 activeSortable._hideClone();
4118 } else {
4119 activeSortable._showClone(_this);
4120 }
4121 if (_this !== fromSortable) {
4122 // Set ghost class to new sortable's ghost class
4123 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
4124 toggleClass(dragEl, options.ghostClass, true);
4125 }
4126 if (putSortable !== _this && _this !== Sortable.active) {
4127 putSortable = _this;
4128 } else if (_this === Sortable.active && putSortable) {
4129 putSortable = null;
4130 }
4131
4132 // Animation
4133 if (fromSortable === _this) {
4134 _this._ignoreWhileAnimating = target;
4135 }
4136 _this.animateAll(function () {
4137 dragOverEvent('dragOverAnimationComplete');
4138 _this._ignoreWhileAnimating = null;
4139 });
4140 if (_this !== fromSortable) {
4141 fromSortable.animateAll();
4142 fromSortable._ignoreWhileAnimating = null;
4143 }
4144 }
4145
4146 // Null lastTarget if it is not inside a previously swapped element
4147 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
4148 lastTarget = null;
4149 }
4150
4151 // no bubbling and not fallback
4152 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
4153 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
4154
4155 // Do not detect for empty insert if already inserted
4156 !insertion && nearestEmptyInsertDetectEvent(evt);
4157 }
4158 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
4159 return completedFired = true;
4160 }
4161
4162 // Call when dragEl has been inserted
4163 function changed() {
4164 newIndex = index(dragEl);
4165 newDraggableIndex = index(dragEl, options.draggable);
4166 _dispatchEvent({
4167 sortable: _this,
4168 name: 'change',
4169 toEl: el,
4170 newIndex: newIndex,
4171 newDraggableIndex: newDraggableIndex,
4172 originalEvent: evt
4173 });
4174 }
4175 if (evt.preventDefault !== void 0) {
4176 evt.cancelable && evt.preventDefault();
4177 }
4178 target = closest(target, options.draggable, el, true);
4179 dragOverEvent('dragOver');
4180 if (Sortable.eventCanceled) return completedFired;
4181 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
4182 return completed(false);
4183 }
4184 ignoreNextClick = false;
4185 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
4186 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
4187 vertical = this._getDirection(evt, target) === 'vertical';
4188 dragRect = getRect(dragEl);
4189 dragOverEvent('dragOverValid');
4190 if (Sortable.eventCanceled) return completedFired;
4191 if (revert) {
4192 parentEl = rootEl; // actualization
4193 capture();
4194 this._hideClone();
4195 dragOverEvent('revert');
4196 if (!Sortable.eventCanceled) {
4197 if (nextEl) {
4198 rootEl.insertBefore(dragEl, nextEl);
4199 } else {
4200 rootEl.appendChild(dragEl);
4201 }
4202 }
4203 return completed(true);
4204 }
4205 var elLastChild = lastChild(el, options.draggable);
4206 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
4207 // Insert to end of list
4208
4209 // If already at end of list: Do not insert
4210 if (elLastChild === dragEl) {
4211 return completed(false);
4212 }
4213
4214 // if there is a last element, it is the target
4215 if (elLastChild && el === evt.target) {
4216 target = elLastChild;
4217 }
4218 if (target) {
4219 targetRect = getRect(target);
4220 }
4221 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
4222 capture();
4223 if (elLastChild && elLastChild.nextSibling) {
4224 // the last draggable element is not the last node
4225 el.insertBefore(dragEl, elLastChild.nextSibling);
4226 } else {
4227 el.appendChild(dragEl);
4228 }
4229 parentEl = el; // actualization
4230
4231 changed();
4232 return completed(true);
4233 }
4234 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
4235 // Insert to start of list
4236 var firstChild = getChild(el, 0, options, true);
4237 if (firstChild === dragEl) {
4238 return completed(false);
4239 }
4240 target = firstChild;
4241 targetRect = getRect(target);
4242 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
4243 capture();
4244 el.insertBefore(dragEl, firstChild);
4245 parentEl = el; // actualization
4246
4247 changed();
4248 return completed(true);
4249 }
4250 } else if (target.parentNode === el) {
4251 targetRect = getRect(target);
4252 var direction = 0,
4253 targetBeforeFirstSwap,
4254 differentLevel = dragEl.parentNode !== el,
4255 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
4256 side1 = vertical ? 'top' : 'left',
4257 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
4258 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
4259 if (lastTarget !== target) {
4260 targetBeforeFirstSwap = targetRect[side1];
4261 pastFirstInvertThresh = false;
4262 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
4263 }
4264 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
4265 var sibling;
4266 if (direction !== 0) {
4267 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
4268 var dragIndex = index(dragEl);
4269 do {
4270 dragIndex -= direction;
4271 sibling = parentEl.children[dragIndex];
4272 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
4273 }
4274 // If dragEl is already beside target: Do not insert
4275 if (direction === 0 || sibling === target) {
4276 return completed(false);
4277 }
4278 lastTarget = target;
4279 lastDirection = direction;
4280 var nextSibling = target.nextElementSibling,
4281 after = false;
4282 after = direction === 1;
4283 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
4284 if (moveVector !== false) {
4285 if (moveVector === 1 || moveVector === -1) {
4286 after = moveVector === 1;
4287 }
4288 _silent = true;
4289 setTimeout(_unsilent, 30);
4290 capture();
4291 if (after && !nextSibling) {
4292 el.appendChild(dragEl);
4293 } else {
4294 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
4295 }
4296
4297 // Undo chrome's scroll adjustment (has no effect on other browsers)
4298 if (scrolledPastTop) {
4299 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
4300 }
4301 parentEl = dragEl.parentNode; // actualization
4302
4303 // must be done before animation
4304 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
4305 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
4306 }
4307 changed();
4308 return completed(true);
4309 }
4310 }
4311 if (el.contains(dragEl)) {
4312 return completed(false);
4313 }
4314 }
4315 return false;
4316 },
4317 _ignoreWhileAnimating: null,
4318 _offMoveEvents: function _offMoveEvents() {
4319 off(document, 'mousemove', this._onTouchMove);
4320 off(document, 'touchmove', this._onTouchMove);
4321 off(document, 'pointermove', this._onTouchMove);
4322 off(document, 'dragover', nearestEmptyInsertDetectEvent);
4323 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
4324 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
4325 },
4326 _offUpEvents: function _offUpEvents() {
4327 var ownerDocument = this.el.ownerDocument;
4328 off(ownerDocument, 'mouseup', this._onDrop);
4329 off(ownerDocument, 'touchend', this._onDrop);
4330 off(ownerDocument, 'pointerup', this._onDrop);
4331 off(ownerDocument, 'pointercancel', this._onDrop);
4332 off(ownerDocument, 'touchcancel', this._onDrop);
4333 off(document, 'selectstart', this);
4334 },
4335 _onDrop: function _onDrop( /**Event*/evt) {
4336 var el = this.el,
4337 options = this.options;
4338
4339 // Get the index of the dragged element within its parent
4340 newIndex = index(dragEl);
4341 newDraggableIndex = index(dragEl, options.draggable);
4342 pluginEvent('drop', this, {
4343 evt: evt
4344 });
4345 parentEl = dragEl && dragEl.parentNode;
4346
4347 // Get again after plugin event
4348 newIndex = index(dragEl);
4349 newDraggableIndex = index(dragEl, options.draggable);
4350 if (Sortable.eventCanceled) {
4351 this._nulling();
4352 return;
4353 }
4354 awaitingDragStarted = false;
4355 isCircumstantialInvert = false;
4356 pastFirstInvertThresh = false;
4357 clearInterval(this._loopId);
4358 clearTimeout(this._dragStartTimer);
4359 _cancelNextTick(this.cloneId);
4360 _cancelNextTick(this._dragStartId);
4361
4362 // Unbind events
4363 if (this.nativeDraggable) {
4364 off(document, 'drop', this);
4365 off(el, 'dragstart', this._onDragStart);
4366 }
4367 this._offMoveEvents();
4368 this._offUpEvents();
4369 if (Safari) {
4370 css(document.body, 'user-select', '');
4371 }
4372 css(dragEl, 'transform', '');
4373 if (evt) {
4374 if (moved) {
4375 evt.cancelable && evt.preventDefault();
4376 !options.dropBubble && evt.stopPropagation();
4377 }
4378 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
4379 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
4380 // Remove clone(s)
4381 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
4382 }
4383 if (dragEl) {
4384 if (this.nativeDraggable) {
4385 off(dragEl, 'dragend', this);
4386 }
4387 _disableDraggable(dragEl);
4388 dragEl.style['will-change'] = '';
4389
4390 // Remove classes
4391 // ghostClass is added in dragStarted
4392 if (moved && !awaitingDragStarted) {
4393 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
4394 }
4395 toggleClass(dragEl, this.options.chosenClass, false);
4396
4397 // Drag stop event
4398 _dispatchEvent({
4399 sortable: this,
4400 name: 'unchoose',
4401 toEl: parentEl,
4402 newIndex: null,
4403 newDraggableIndex: null,
4404 originalEvent: evt
4405 });
4406 if (rootEl !== parentEl) {
4407 if (newIndex >= 0) {
4408 // Add event
4409 _dispatchEvent({
4410 rootEl: parentEl,
4411 name: 'add',
4412 toEl: parentEl,
4413 fromEl: rootEl,
4414 originalEvent: evt
4415 });
4416
4417 // Remove event
4418 _dispatchEvent({
4419 sortable: this,
4420 name: 'remove',
4421 toEl: parentEl,
4422 originalEvent: evt
4423 });
4424
4425 // drag from one list and drop into another
4426 _dispatchEvent({
4427 rootEl: parentEl,
4428 name: 'sort',
4429 toEl: parentEl,
4430 fromEl: rootEl,
4431 originalEvent: evt
4432 });
4433 _dispatchEvent({
4434 sortable: this,
4435 name: 'sort',
4436 toEl: parentEl,
4437 originalEvent: evt
4438 });
4439 }
4440 putSortable && putSortable.save();
4441 } else {
4442 if (newIndex !== oldIndex) {
4443 if (newIndex >= 0) {
4444 // drag & drop within the same list
4445 _dispatchEvent({
4446 sortable: this,
4447 name: 'update',
4448 toEl: parentEl,
4449 originalEvent: evt
4450 });
4451 _dispatchEvent({
4452 sortable: this,
4453 name: 'sort',
4454 toEl: parentEl,
4455 originalEvent: evt
4456 });
4457 }
4458 }
4459 }
4460 if (Sortable.active) {
4461 /* jshint eqnull:true */
4462 if (newIndex == null || newIndex === -1) {
4463 newIndex = oldIndex;
4464 newDraggableIndex = oldDraggableIndex;
4465 }
4466 _dispatchEvent({
4467 sortable: this,
4468 name: 'end',
4469 toEl: parentEl,
4470 originalEvent: evt
4471 });
4472
4473 // Save sorting
4474 this.save();
4475 }
4476 }
4477 }
4478 this._nulling();
4479 },
4480 _nulling: function _nulling() {
4481 pluginEvent('nulling', this);
4482 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;
4483 var el = this.el;
4484 savedInputChecked.forEach(function (checkEl) {
4485 if (el.contains(checkEl)) {
4486 checkEl.checked = true;
4487 }
4488 });
4489 savedInputChecked.length = lastDx = lastDy = 0;
4490 },
4491 handleEvent: function handleEvent( /**Event*/evt) {
4492 switch (evt.type) {
4493 case 'drop':
4494 case 'dragend':
4495 this._onDrop(evt);
4496 break;
4497 case 'dragenter':
4498 case 'dragover':
4499 if (dragEl) {
4500 this._onDragOver(evt);
4501 _globalDragOver(evt);
4502 }
4503 break;
4504 case 'selectstart':
4505 evt.preventDefault();
4506 break;
4507 }
4508 },
4509 /**
4510 * Serializes the item into an array of string.
4511 * @returns {String[]}
4512 */
4513 toArray: function toArray() {
4514 var order = [],
4515 el,
4516 children = this.el.children,
4517 i = 0,
4518 n = children.length,
4519 options = this.options;
4520 for (; i < n; i++) {
4521 el = children[i];
4522 if (closest(el, options.draggable, this.el, false)) {
4523 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
4524 }
4525 }
4526 return order;
4527 },
4528 /**
4529 * Sorts the elements according to the array.
4530 * @param {String[]} order order of the items
4531 */
4532 sort: function sort(order, useAnimation) {
4533 var items = {},
4534 rootEl = this.el;
4535 this.toArray().forEach(function (id, i) {
4536 var el = rootEl.children[i];
4537 if (closest(el, this.options.draggable, rootEl, false)) {
4538 items[id] = el;
4539 }
4540 }, this);
4541 useAnimation && this.captureAnimationState();
4542 order.forEach(function (id) {
4543 if (items[id]) {
4544 rootEl.removeChild(items[id]);
4545 rootEl.appendChild(items[id]);
4546 }
4547 });
4548 useAnimation && this.animateAll();
4549 },
4550 /**
4551 * Save the current sorting
4552 */
4553 save: function save() {
4554 var store = this.options.store;
4555 store && store.set && store.set(this);
4556 },
4557 /**
4558 * 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.
4559 * @param {HTMLElement} el
4560 * @param {String} [selector] default: `options.draggable`
4561 * @returns {HTMLElement|null}
4562 */
4563 closest: function closest$1(el, selector) {
4564 return closest(el, selector || this.options.draggable, this.el, false);
4565 },
4566 /**
4567 * Set/get option
4568 * @param {string} name
4569 * @param {*} [value]
4570 * @returns {*}
4571 */
4572 option: function option(name, value) {
4573 var options = this.options;
4574 if (value === void 0) {
4575 return options[name];
4576 } else {
4577 var modifiedValue = PluginManager.modifyOption(this, name, value);
4578 if (typeof modifiedValue !== 'undefined') {
4579 options[name] = modifiedValue;
4580 } else {
4581 options[name] = value;
4582 }
4583 if (name === 'group') {
4584 _prepareGroup(options);
4585 }
4586 }
4587 },
4588 /**
4589 * Destroy
4590 */
4591 destroy: function destroy() {
4592 pluginEvent('destroy', this);
4593 var el = this.el;
4594 el[expando] = null;
4595 off(el, 'mousedown', this._onTapStart);
4596 off(el, 'touchstart', this._onTapStart);
4597 off(el, 'pointerdown', this._onTapStart);
4598 if (this.nativeDraggable) {
4599 off(el, 'dragover', this);
4600 off(el, 'dragenter', this);
4601 }
4602 // Remove draggable attributes
4603 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
4604 el.removeAttribute('draggable');
4605 });
4606 this._onDrop();
4607 this._disableDelayedDragEvents();
4608 sortables.splice(sortables.indexOf(this.el), 1);
4609 this.el = el = null;
4610 },
4611 _hideClone: function _hideClone() {
4612 if (!cloneHidden) {
4613 pluginEvent('hideClone', this);
4614 if (Sortable.eventCanceled) return;
4615 css(cloneEl, 'display', 'none');
4616 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
4617 cloneEl.parentNode.removeChild(cloneEl);
4618 }
4619 cloneHidden = true;
4620 }
4621 },
4622 _showClone: function _showClone(putSortable) {
4623 if (putSortable.lastPutMode !== 'clone') {
4624 this._hideClone();
4625 return;
4626 }
4627 if (cloneHidden) {
4628 pluginEvent('showClone', this);
4629 if (Sortable.eventCanceled) return;
4630
4631 // show clone at dragEl or original position
4632 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
4633 rootEl.insertBefore(cloneEl, dragEl);
4634 } else if (nextEl) {
4635 rootEl.insertBefore(cloneEl, nextEl);
4636 } else {
4637 rootEl.appendChild(cloneEl);
4638 }
4639 if (this.options.group.revertClone) {
4640 this.animate(dragEl, cloneEl);
4641 }
4642 css(cloneEl, 'display', '');
4643 cloneHidden = false;
4644 }
4645 }
4646 };
4647 function _globalDragOver( /**Event*/evt) {
4648 if (evt.dataTransfer) {
4649 evt.dataTransfer.dropEffect = 'move';
4650 }
4651 evt.cancelable && evt.preventDefault();
4652 }
4653 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
4654 var evt,
4655 sortable = fromEl[expando],
4656 onMoveFn = sortable.options.onMove,
4657 retVal;
4658 // Support for new CustomEvent feature
4659 if (window.CustomEvent && !IE11OrLess && !Edge) {
4660 evt = new CustomEvent('move', {
4661 bubbles: true,
4662 cancelable: true
4663 });
4664 } else {
4665 evt = document.createEvent('Event');
4666 evt.initEvent('move', true, true);
4667 }
4668 evt.to = toEl;
4669 evt.from = fromEl;
4670 evt.dragged = dragEl;
4671 evt.draggedRect = dragRect;
4672 evt.related = targetEl || toEl;
4673 evt.relatedRect = targetRect || getRect(toEl);
4674 evt.willInsertAfter = willInsertAfter;
4675 evt.originalEvent = originalEvent;
4676 fromEl.dispatchEvent(evt);
4677 if (onMoveFn) {
4678 retVal = onMoveFn.call(sortable, evt, originalEvent);
4679 }
4680 return retVal;
4681 }
4682 function _disableDraggable(el) {
4683 el.draggable = false;
4684 }
4685 function _unsilent() {
4686 _silent = false;
4687 }
4688 function _ghostIsFirst(evt, vertical, sortable) {
4689 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
4690 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4691 var spacer = 10;
4692 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;
4693 }
4694 function _ghostIsLast(evt, vertical, sortable) {
4695 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
4696 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
4697 var spacer = 10;
4698 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;
4699 }
4700 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
4701 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
4702 targetLength = vertical ? targetRect.height : targetRect.width,
4703 targetS1 = vertical ? targetRect.top : targetRect.left,
4704 targetS2 = vertical ? targetRect.bottom : targetRect.right,
4705 invert = false;
4706 if (!invertSwap) {
4707 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
4708 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
4709 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
4710 // check if past first invert threshold on side opposite of lastDirection
4711 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
4712 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
4713 pastFirstInvertThresh = true;
4714 }
4715 if (!pastFirstInvertThresh) {
4716 // dragEl shadow (target move distance shadow)
4717 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
4718 : mouseOnAxis > targetS2 - targetMoveDistance) {
4719 return -lastDirection;
4720 }
4721 } else {
4722 invert = true;
4723 }
4724 } else {
4725 // Regular
4726 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
4727 return _getInsertDirection(target);
4728 }
4729 }
4730 }
4731 invert = invert || invertSwap;
4732 if (invert) {
4733 // Invert of regular
4734 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
4735 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
4736 }
4737 }
4738 return 0;
4739 }
4740
4741 /**
4742 * Gets the direction dragEl must be swapped relative to target in order to make it
4743 * seem that dragEl has been "inserted" into that element's position
4744 * @param {HTMLElement} target The target whose position dragEl is being inserted at
4745 * @return {Number} Direction dragEl must be swapped
4746 */
4747 function _getInsertDirection(target) {
4748 if (index(dragEl) < index(target)) {
4749 return 1;
4750 } else {
4751 return -1;
4752 }
4753 }
4754
4755 /**
4756 * Generate id
4757 * @param {HTMLElement} el
4758 * @returns {String}
4759 * @private
4760 */
4761 function _generateId(el) {
4762 var str = el.tagName + el.className + el.src + el.href + el.textContent,
4763 i = str.length,
4764 sum = 0;
4765 while (i--) {
4766 sum += str.charCodeAt(i);
4767 }
4768 return sum.toString(36);
4769 }
4770 function _saveInputCheckedState(root) {
4771 savedInputChecked.length = 0;
4772 var inputs = root.getElementsByTagName('input');
4773 var idx = inputs.length;
4774 while (idx--) {
4775 var el = inputs[idx];
4776 el.checked && savedInputChecked.push(el);
4777 }
4778 }
4779 function _nextTick(fn) {
4780 return setTimeout(fn, 0);
4781 }
4782 function _cancelNextTick(id) {
4783 return clearTimeout(id);
4784 }
4785
4786 // Fixed #973:
4787 if (documentExists) {
4788 on(document, 'touchmove', function (evt) {
4789 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
4790 evt.preventDefault();
4791 }
4792 });
4793 }
4794
4795 // Export utils
4796 Sortable.utils = {
4797 on: on,
4798 off: off,
4799 css: css,
4800 find: find,
4801 is: function is(el, selector) {
4802 return !!closest(el, selector, el, false);
4803 },
4804 extend: extend,
4805 throttle: throttle,
4806 closest: closest,
4807 toggleClass: toggleClass,
4808 clone: clone,
4809 index: index,
4810 nextTick: _nextTick,
4811 cancelNextTick: _cancelNextTick,
4812 detectDirection: _detectDirection,
4813 getChild: getChild,
4814 expando: expando
4815 };
4816
4817 /**
4818 * Get the Sortable instance of an element
4819 * @param {HTMLElement} element The element
4820 * @return {Sortable|undefined} The instance of Sortable
4821 */
4822 Sortable.get = function (element) {
4823 return element[expando];
4824 };
4825
4826 /**
4827 * Mount a plugin to Sortable
4828 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
4829 */
4830 Sortable.mount = function () {
4831 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
4832 plugins[_key] = arguments[_key];
4833 }
4834 if (plugins[0].constructor === Array) plugins = plugins[0];
4835 plugins.forEach(function (plugin) {
4836 if (!plugin.prototype || !plugin.prototype.constructor) {
4837 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
4838 }
4839 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
4840 PluginManager.mount(plugin);
4841 });
4842 };
4843
4844 /**
4845 * Create sortable instance
4846 * @param {HTMLElement} el
4847 * @param {Object} [options]
4848 */
4849 Sortable.create = function (el, options) {
4850 return new Sortable(el, options);
4851 };
4852
4853 // Export
4854 Sortable.version = version;
4855
4856 var autoScrolls = [],
4857 scrollEl,
4858 scrollRootEl,
4859 scrolling = false,
4860 lastAutoScrollX,
4861 lastAutoScrollY,
4862 touchEvt$1,
4863 pointerElemChangedInterval;
4864 function AutoScrollPlugin() {
4865 function AutoScroll() {
4866 this.defaults = {
4867 scroll: true,
4868 forceAutoScrollFallback: false,
4869 scrollSensitivity: 30,
4870 scrollSpeed: 10,
4871 bubbleScroll: true
4872 };
4873
4874 // Bind all private methods
4875 for (var fn in this) {
4876 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
4877 this[fn] = this[fn].bind(this);
4878 }
4879 }
4880 }
4881 AutoScroll.prototype = {
4882 dragStarted: function dragStarted(_ref) {
4883 var originalEvent = _ref.originalEvent;
4884 if (this.sortable.nativeDraggable) {
4885 on(document, 'dragover', this._handleAutoScroll);
4886 } else {
4887 if (this.options.supportPointer) {
4888 on(document, 'pointermove', this._handleFallbackAutoScroll);
4889 } else if (originalEvent.touches) {
4890 on(document, 'touchmove', this._handleFallbackAutoScroll);
4891 } else {
4892 on(document, 'mousemove', this._handleFallbackAutoScroll);
4893 }
4894 }
4895 },
4896 dragOverCompleted: function dragOverCompleted(_ref2) {
4897 var originalEvent = _ref2.originalEvent;
4898 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
4899 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
4900 this._handleAutoScroll(originalEvent);
4901 }
4902 },
4903 drop: function drop() {
4904 if (this.sortable.nativeDraggable) {
4905 off(document, 'dragover', this._handleAutoScroll);
4906 } else {
4907 off(document, 'pointermove', this._handleFallbackAutoScroll);
4908 off(document, 'touchmove', this._handleFallbackAutoScroll);
4909 off(document, 'mousemove', this._handleFallbackAutoScroll);
4910 }
4911 clearPointerElemChangedInterval();
4912 clearAutoScrolls();
4913 cancelThrottle();
4914 },
4915 nulling: function nulling() {
4916 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
4917 autoScrolls.length = 0;
4918 },
4919 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
4920 this._handleAutoScroll(evt, true);
4921 },
4922 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
4923 var _this = this;
4924 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4925 y = (evt.touches ? evt.touches[0] : evt).clientY,
4926 elem = document.elementFromPoint(x, y);
4927 touchEvt$1 = evt;
4928
4929 // IE does not seem to have native autoscroll,
4930 // Edge's autoscroll seems too conditional,
4931 // MACOS Safari does not have autoscroll,
4932 // Firefox and Chrome are good
4933 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
4934 autoScroll(evt, this.options, elem, fallback);
4935
4936 // Listener for pointer element change
4937 var ogElemScroller = getParentAutoScrollElement(elem, true);
4938 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
4939 pointerElemChangedInterval && clearPointerElemChangedInterval();
4940 // Detect for pointer elem change, emulating native DnD behaviour
4941 pointerElemChangedInterval = setInterval(function () {
4942 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
4943 if (newElem !== ogElemScroller) {
4944 ogElemScroller = newElem;
4945 clearAutoScrolls();
4946 }
4947 autoScroll(evt, _this.options, newElem, fallback);
4948 }, 10);
4949 lastAutoScrollX = x;
4950 lastAutoScrollY = y;
4951 }
4952 } else {
4953 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
4954 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
4955 clearAutoScrolls();
4956 return;
4957 }
4958 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
4959 }
4960 }
4961 };
4962 return _extends(AutoScroll, {
4963 pluginName: 'scroll',
4964 initializeByDefault: true
4965 });
4966 }
4967 function clearAutoScrolls() {
4968 autoScrolls.forEach(function (autoScroll) {
4969 clearInterval(autoScroll.pid);
4970 });
4971 autoScrolls = [];
4972 }
4973 function clearPointerElemChangedInterval() {
4974 clearInterval(pointerElemChangedInterval);
4975 }
4976 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
4977 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
4978 if (!options.scroll) return;
4979 var x = (evt.touches ? evt.touches[0] : evt).clientX,
4980 y = (evt.touches ? evt.touches[0] : evt).clientY,
4981 sens = options.scrollSensitivity,
4982 speed = options.scrollSpeed,
4983 winScroller = getWindowScrollingElement();
4984 var scrollThisInstance = false,
4985 scrollCustomFn;
4986
4987 // New scroll root, set scrollEl
4988 if (scrollRootEl !== rootEl) {
4989 scrollRootEl = rootEl;
4990 clearAutoScrolls();
4991 scrollEl = options.scroll;
4992 scrollCustomFn = options.scrollFn;
4993 if (scrollEl === true) {
4994 scrollEl = getParentAutoScrollElement(rootEl, true);
4995 }
4996 }
4997 var layersOut = 0;
4998 var currentParent = scrollEl;
4999 do {
5000 var el = currentParent,
5001 rect = getRect(el),
5002 top = rect.top,
5003 bottom = rect.bottom,
5004 left = rect.left,
5005 right = rect.right,
5006 width = rect.width,
5007 height = rect.height,
5008 canScrollX = void 0,
5009 canScrollY = void 0,
5010 scrollWidth = el.scrollWidth,
5011 scrollHeight = el.scrollHeight,
5012 elCSS = css(el),
5013 scrollPosX = el.scrollLeft,
5014 scrollPosY = el.scrollTop;
5015 if (el === winScroller) {
5016 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
5017 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
5018 } else {
5019 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
5020 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
5021 }
5022 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
5023 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
5024 if (!autoScrolls[layersOut]) {
5025 for (var i = 0; i <= layersOut; i++) {
5026 if (!autoScrolls[i]) {
5027 autoScrolls[i] = {};
5028 }
5029 }
5030 }
5031 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
5032 autoScrolls[layersOut].el = el;
5033 autoScrolls[layersOut].vx = vx;
5034 autoScrolls[layersOut].vy = vy;
5035 clearInterval(autoScrolls[layersOut].pid);
5036 if (vx != 0 || vy != 0) {
5037 scrollThisInstance = true;
5038 /* jshint loopfunc:true */
5039 autoScrolls[layersOut].pid = setInterval(function () {
5040 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
5041 if (isFallback && this.layer === 0) {
5042 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
5043 }
5044 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
5045 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
5046 if (typeof scrollCustomFn === 'function') {
5047 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
5048 return;
5049 }
5050 }
5051 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
5052 }.bind({
5053 layer: layersOut
5054 }), 24);
5055 }
5056 }
5057 layersOut++;
5058 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
5059 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
5060 }, 30);
5061
5062 var drop = function drop(_ref) {
5063 var originalEvent = _ref.originalEvent,
5064 putSortable = _ref.putSortable,
5065 dragEl = _ref.dragEl,
5066 activeSortable = _ref.activeSortable,
5067 dispatchSortableEvent = _ref.dispatchSortableEvent,
5068 hideGhostForTarget = _ref.hideGhostForTarget,
5069 unhideGhostForTarget = _ref.unhideGhostForTarget;
5070 if (!originalEvent) return;
5071 var toSortable = putSortable || activeSortable;
5072 hideGhostForTarget();
5073 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
5074 var target = document.elementFromPoint(touch.clientX, touch.clientY);
5075 unhideGhostForTarget();
5076 if (toSortable && !toSortable.el.contains(target)) {
5077 dispatchSortableEvent('spill');
5078 this.onSpill({
5079 dragEl: dragEl,
5080 putSortable: putSortable
5081 });
5082 }
5083 };
5084 function Revert() {}
5085 Revert.prototype = {
5086 startIndex: null,
5087 dragStart: function dragStart(_ref2) {
5088 var oldDraggableIndex = _ref2.oldDraggableIndex;
5089 this.startIndex = oldDraggableIndex;
5090 },
5091 onSpill: function onSpill(_ref3) {
5092 var dragEl = _ref3.dragEl,
5093 putSortable = _ref3.putSortable;
5094 this.sortable.captureAnimationState();
5095 if (putSortable) {
5096 putSortable.captureAnimationState();
5097 }
5098 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
5099 if (nextSibling) {
5100 this.sortable.el.insertBefore(dragEl, nextSibling);
5101 } else {
5102 this.sortable.el.appendChild(dragEl);
5103 }
5104 this.sortable.animateAll();
5105 if (putSortable) {
5106 putSortable.animateAll();
5107 }
5108 },
5109 drop: drop
5110 };
5111 _extends(Revert, {
5112 pluginName: 'revertOnSpill'
5113 });
5114 function Remove() {}
5115 Remove.prototype = {
5116 onSpill: function onSpill(_ref4) {
5117 var dragEl = _ref4.dragEl,
5118 putSortable = _ref4.putSortable;
5119 var parentSortable = putSortable || this.sortable;
5120 parentSortable.captureAnimationState();
5121 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
5122 parentSortable.animateAll();
5123 },
5124 drop: drop
5125 };
5126 _extends(Remove, {
5127 pluginName: 'removeOnSpill'
5128 });
5129
5130 var lastSwapEl;
5131 function SwapPlugin() {
5132 function Swap() {
5133 this.defaults = {
5134 swapClass: 'sortable-swap-highlight'
5135 };
5136 }
5137 Swap.prototype = {
5138 dragStart: function dragStart(_ref) {
5139 var dragEl = _ref.dragEl;
5140 lastSwapEl = dragEl;
5141 },
5142 dragOverValid: function dragOverValid(_ref2) {
5143 var completed = _ref2.completed,
5144 target = _ref2.target,
5145 onMove = _ref2.onMove,
5146 activeSortable = _ref2.activeSortable,
5147 changed = _ref2.changed,
5148 cancel = _ref2.cancel;
5149 if (!activeSortable.options.swap) return;
5150 var el = this.sortable.el,
5151 options = this.options;
5152 if (target && target !== el) {
5153 var prevSwapEl = lastSwapEl;
5154 if (onMove(target) !== false) {
5155 toggleClass(target, options.swapClass, true);
5156 lastSwapEl = target;
5157 } else {
5158 lastSwapEl = null;
5159 }
5160 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
5161 toggleClass(prevSwapEl, options.swapClass, false);
5162 }
5163 }
5164 changed();
5165 completed(true);
5166 cancel();
5167 },
5168 drop: function drop(_ref3) {
5169 var activeSortable = _ref3.activeSortable,
5170 putSortable = _ref3.putSortable,
5171 dragEl = _ref3.dragEl;
5172 var toSortable = putSortable || this.sortable;
5173 var options = this.options;
5174 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
5175 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
5176 if (dragEl !== lastSwapEl) {
5177 toSortable.captureAnimationState();
5178 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
5179 swapNodes(dragEl, lastSwapEl);
5180 toSortable.animateAll();
5181 if (toSortable !== activeSortable) activeSortable.animateAll();
5182 }
5183 }
5184 },
5185 nulling: function nulling() {
5186 lastSwapEl = null;
5187 }
5188 };
5189 return _extends(Swap, {
5190 pluginName: 'swap',
5191 eventProperties: function eventProperties() {
5192 return {
5193 swapItem: lastSwapEl
5194 };
5195 }
5196 });
5197 }
5198 function swapNodes(n1, n2) {
5199 var p1 = n1.parentNode,
5200 p2 = n2.parentNode,
5201 i1,
5202 i2;
5203 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
5204 i1 = index(n1);
5205 i2 = index(n2);
5206 if (p1.isEqualNode(p2) && i1 < i2) {
5207 i2++;
5208 }
5209 p1.insertBefore(n2, p1.children[i1]);
5210 p2.insertBefore(n1, p2.children[i2]);
5211 }
5212
5213 var multiDragElements = [],
5214 multiDragClones = [],
5215 lastMultiDragSelect,
5216 // for selection with modifier key down (SHIFT)
5217 multiDragSortable,
5218 initialFolding = false,
5219 // Initial multi-drag fold when drag started
5220 folding = false,
5221 // Folding any other time
5222 dragStarted = false,
5223 dragEl$1,
5224 clonesFromRect,
5225 clonesHidden;
5226 function MultiDragPlugin() {
5227 function MultiDrag(sortable) {
5228 // Bind all private methods
5229 for (var fn in this) {
5230 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
5231 this[fn] = this[fn].bind(this);
5232 }
5233 }
5234 if (!sortable.options.avoidImplicitDeselect) {
5235 if (sortable.options.supportPointer) {
5236 on(document, 'pointerup', this._deselectMultiDrag);
5237 } else {
5238 on(document, 'mouseup', this._deselectMultiDrag);
5239 on(document, 'touchend', this._deselectMultiDrag);
5240 }
5241 }
5242 on(document, 'keydown', this._checkKeyDown);
5243 on(document, 'keyup', this._checkKeyUp);
5244 this.defaults = {
5245 selectedClass: 'sortable-selected',
5246 multiDragKey: null,
5247 avoidImplicitDeselect: false,
5248 setData: function setData(dataTransfer, dragEl) {
5249 var data = '';
5250 if (multiDragElements.length && multiDragSortable === sortable) {
5251 multiDragElements.forEach(function (multiDragElement, i) {
5252 data += (!i ? '' : ', ') + multiDragElement.textContent;
5253 });
5254 } else {
5255 data = dragEl.textContent;
5256 }
5257 dataTransfer.setData('Text', data);
5258 }
5259 };
5260 }
5261 MultiDrag.prototype = {
5262 multiDragKeyDown: false,
5263 isMultiDrag: false,
5264 delayStartGlobal: function delayStartGlobal(_ref) {
5265 var dragged = _ref.dragEl;
5266 dragEl$1 = dragged;
5267 },
5268 delayEnded: function delayEnded() {
5269 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
5270 },
5271 setupClone: function setupClone(_ref2) {
5272 var sortable = _ref2.sortable,
5273 cancel = _ref2.cancel;
5274 if (!this.isMultiDrag) return;
5275 for (var i = 0; i < multiDragElements.length; i++) {
5276 multiDragClones.push(clone(multiDragElements[i]));
5277 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
5278 multiDragClones[i].draggable = false;
5279 multiDragClones[i].style['will-change'] = '';
5280 toggleClass(multiDragClones[i], this.options.selectedClass, false);
5281 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
5282 }
5283 sortable._hideClone();
5284 cancel();
5285 },
5286 clone: function clone(_ref3) {
5287 var sortable = _ref3.sortable,
5288 rootEl = _ref3.rootEl,
5289 dispatchSortableEvent = _ref3.dispatchSortableEvent,
5290 cancel = _ref3.cancel;
5291 if (!this.isMultiDrag) return;
5292 if (!this.options.removeCloneOnHide) {
5293 if (multiDragElements.length && multiDragSortable === sortable) {
5294 insertMultiDragClones(true, rootEl);
5295 dispatchSortableEvent('clone');
5296 cancel();
5297 }
5298 }
5299 },
5300 showClone: function showClone(_ref4) {
5301 var cloneNowShown = _ref4.cloneNowShown,
5302 rootEl = _ref4.rootEl,
5303 cancel = _ref4.cancel;
5304 if (!this.isMultiDrag) return;
5305 insertMultiDragClones(false, rootEl);
5306 multiDragClones.forEach(function (clone) {
5307 css(clone, 'display', '');
5308 });
5309 cloneNowShown();
5310 clonesHidden = false;
5311 cancel();
5312 },
5313 hideClone: function hideClone(_ref5) {
5314 var _this = this;
5315 var sortable = _ref5.sortable,
5316 cloneNowHidden = _ref5.cloneNowHidden,
5317 cancel = _ref5.cancel;
5318 if (!this.isMultiDrag) return;
5319 multiDragClones.forEach(function (clone) {
5320 css(clone, 'display', 'none');
5321 if (_this.options.removeCloneOnHide && clone.parentNode) {
5322 clone.parentNode.removeChild(clone);
5323 }
5324 });
5325 cloneNowHidden();
5326 clonesHidden = true;
5327 cancel();
5328 },
5329 dragStartGlobal: function dragStartGlobal(_ref6) {
5330 var sortable = _ref6.sortable;
5331 if (!this.isMultiDrag && multiDragSortable) {
5332 multiDragSortable.multiDrag._deselectMultiDrag();
5333 }
5334 multiDragElements.forEach(function (multiDragElement) {
5335 multiDragElement.sortableIndex = index(multiDragElement);
5336 });
5337
5338 // Sort multi-drag elements
5339 multiDragElements = multiDragElements.sort(function (a, b) {
5340 return a.sortableIndex - b.sortableIndex;
5341 });
5342 dragStarted = true;
5343 },
5344 dragStarted: function dragStarted(_ref7) {
5345 var _this2 = this;
5346 var sortable = _ref7.sortable;
5347 if (!this.isMultiDrag) return;
5348 if (this.options.sort) {
5349 // Capture rects,
5350 // hide multi drag elements (by positioning them absolute),
5351 // set multi drag elements rects to dragRect,
5352 // show multi drag elements,
5353 // animate to rects,
5354 // unset rects & remove from DOM
5355
5356 sortable.captureAnimationState();
5357 if (this.options.animation) {
5358 multiDragElements.forEach(function (multiDragElement) {
5359 if (multiDragElement === dragEl$1) return;
5360 css(multiDragElement, 'position', 'absolute');
5361 });
5362 var dragRect = getRect(dragEl$1, false, true, true);
5363 multiDragElements.forEach(function (multiDragElement) {
5364 if (multiDragElement === dragEl$1) return;
5365 setRect(multiDragElement, dragRect);
5366 });
5367 folding = true;
5368 initialFolding = true;
5369 }
5370 }
5371 sortable.animateAll(function () {
5372 folding = false;
5373 initialFolding = false;
5374 if (_this2.options.animation) {
5375 multiDragElements.forEach(function (multiDragElement) {
5376 unsetRect(multiDragElement);
5377 });
5378 }
5379
5380 // Remove all auxiliary multidrag items from el, if sorting enabled
5381 if (_this2.options.sort) {
5382 removeMultiDragElements();
5383 }
5384 });
5385 },
5386 dragOver: function dragOver(_ref8) {
5387 var target = _ref8.target,
5388 completed = _ref8.completed,
5389 cancel = _ref8.cancel;
5390 if (folding && ~multiDragElements.indexOf(target)) {
5391 completed(false);
5392 cancel();
5393 }
5394 },
5395 revert: function revert(_ref9) {
5396 var fromSortable = _ref9.fromSortable,
5397 rootEl = _ref9.rootEl,
5398 sortable = _ref9.sortable,
5399 dragRect = _ref9.dragRect;
5400 if (multiDragElements.length > 1) {
5401 // Setup unfold animation
5402 multiDragElements.forEach(function (multiDragElement) {
5403 sortable.addAnimationState({
5404 target: multiDragElement,
5405 rect: folding ? getRect(multiDragElement) : dragRect
5406 });
5407 unsetRect(multiDragElement);
5408 multiDragElement.fromRect = dragRect;
5409 fromSortable.removeAnimationState(multiDragElement);
5410 });
5411 folding = false;
5412 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
5413 }
5414 },
5415 dragOverCompleted: function dragOverCompleted(_ref10) {
5416 var sortable = _ref10.sortable,
5417 isOwner = _ref10.isOwner,
5418 insertion = _ref10.insertion,
5419 activeSortable = _ref10.activeSortable,
5420 parentEl = _ref10.parentEl,
5421 putSortable = _ref10.putSortable;
5422 var options = this.options;
5423 if (insertion) {
5424 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
5425 if (isOwner) {
5426 activeSortable._hideClone();
5427 }
5428 initialFolding = false;
5429 // If leaving sort:false root, or already folding - Fold to new location
5430 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
5431 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
5432 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
5433 multiDragElements.forEach(function (multiDragElement) {
5434 if (multiDragElement === dragEl$1) return;
5435 setRect(multiDragElement, dragRectAbsolute);
5436
5437 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
5438 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
5439 parentEl.appendChild(multiDragElement);
5440 });
5441 folding = true;
5442 }
5443
5444 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
5445 if (!isOwner) {
5446 // Only remove if not folding (folding will remove them anyways)
5447 if (!folding) {
5448 removeMultiDragElements();
5449 }
5450 if (multiDragElements.length > 1) {
5451 var clonesHiddenBefore = clonesHidden;
5452 activeSortable._showClone(sortable);
5453
5454 // Unfold animation for clones if showing from hidden
5455 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
5456 multiDragClones.forEach(function (clone) {
5457 activeSortable.addAnimationState({
5458 target: clone,
5459 rect: clonesFromRect
5460 });
5461 clone.fromRect = clonesFromRect;
5462 clone.thisAnimationDuration = null;
5463 });
5464 }
5465 } else {
5466 activeSortable._showClone(sortable);
5467 }
5468 }
5469 }
5470 },
5471 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
5472 var dragRect = _ref11.dragRect,
5473 isOwner = _ref11.isOwner,
5474 activeSortable = _ref11.activeSortable;
5475 multiDragElements.forEach(function (multiDragElement) {
5476 multiDragElement.thisAnimationDuration = null;
5477 });
5478 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
5479 clonesFromRect = _extends({}, dragRect);
5480 var dragMatrix = matrix(dragEl$1, true);
5481 clonesFromRect.top -= dragMatrix.f;
5482 clonesFromRect.left -= dragMatrix.e;
5483 }
5484 },
5485 dragOverAnimationComplete: function dragOverAnimationComplete() {
5486 if (folding) {
5487 folding = false;
5488 removeMultiDragElements();
5489 }
5490 },
5491 drop: function drop(_ref12) {
5492 var evt = _ref12.originalEvent,
5493 rootEl = _ref12.rootEl,
5494 parentEl = _ref12.parentEl,
5495 sortable = _ref12.sortable,
5496 dispatchSortableEvent = _ref12.dispatchSortableEvent,
5497 oldIndex = _ref12.oldIndex,
5498 putSortable = _ref12.putSortable;
5499 var toSortable = putSortable || this.sortable;
5500 if (!evt) return;
5501 var options = this.options,
5502 children = parentEl.children;
5503
5504 // Multi-drag selection
5505 if (!dragStarted) {
5506 if (options.multiDragKey && !this.multiDragKeyDown) {
5507 this._deselectMultiDrag();
5508 }
5509 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
5510 if (!~multiDragElements.indexOf(dragEl$1)) {
5511 multiDragElements.push(dragEl$1);
5512 dispatchEvent({
5513 sortable: sortable,
5514 rootEl: rootEl,
5515 name: 'select',
5516 targetEl: dragEl$1,
5517 originalEvent: evt
5518 });
5519
5520 // Modifier activated, select from last to dragEl
5521 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
5522 var lastIndex = index(lastMultiDragSelect),
5523 currentIndex = index(dragEl$1);
5524 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
5525 (function () {
5526 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
5527 // (but previous selection existed)
5528 var n, i;
5529 if (currentIndex > lastIndex) {
5530 i = lastIndex;
5531 n = currentIndex;
5532 } else {
5533 i = currentIndex;
5534 n = lastIndex + 1;
5535 }
5536 var filter = options.filter;
5537 for (; i < n; i++) {
5538 if (~multiDragElements.indexOf(children[i])) continue;
5539 // Check if element is draggable
5540 if (!closest(children[i], options.draggable, parentEl, false)) continue;
5541 // Check if element is filtered
5542 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
5543 return closest(children[i], criteria.trim(), parentEl, false);
5544 }));
5545 if (filtered) continue;
5546 toggleClass(children[i], options.selectedClass, true);
5547 multiDragElements.push(children[i]);
5548 dispatchEvent({
5549 sortable: sortable,
5550 rootEl: rootEl,
5551 name: 'select',
5552 targetEl: children[i],
5553 originalEvent: evt
5554 });
5555 }
5556 })();
5557 }
5558 } else {
5559 lastMultiDragSelect = dragEl$1;
5560 }
5561 multiDragSortable = toSortable;
5562 } else {
5563 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
5564 lastMultiDragSelect = null;
5565 dispatchEvent({
5566 sortable: sortable,
5567 rootEl: rootEl,
5568 name: 'deselect',
5569 targetEl: dragEl$1,
5570 originalEvent: evt
5571 });
5572 }
5573 }
5574
5575 // Multi-drag drop
5576 if (dragStarted && this.isMultiDrag) {
5577 folding = false;
5578 // Do not "unfold" after around dragEl if reverted
5579 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
5580 var dragRect = getRect(dragEl$1),
5581 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
5582 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
5583 toSortable.captureAnimationState();
5584 if (!initialFolding) {
5585 if (options.animation) {
5586 dragEl$1.fromRect = dragRect;
5587 multiDragElements.forEach(function (multiDragElement) {
5588 multiDragElement.thisAnimationDuration = null;
5589 if (multiDragElement !== dragEl$1) {
5590 var rect = folding ? getRect(multiDragElement) : dragRect;
5591 multiDragElement.fromRect = rect;
5592
5593 // Prepare unfold animation
5594 toSortable.addAnimationState({
5595 target: multiDragElement,
5596 rect: rect
5597 });
5598 }
5599 });
5600 }
5601
5602 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
5603 // properly they must all be removed
5604 removeMultiDragElements();
5605 multiDragElements.forEach(function (multiDragElement) {
5606 if (children[multiDragIndex]) {
5607 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
5608 } else {
5609 parentEl.appendChild(multiDragElement);
5610 }
5611 multiDragIndex++;
5612 });
5613
5614 // If initial folding is done, the elements may have changed position because they are now
5615 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
5616 // must be fired here as Sortable will not.
5617 if (oldIndex === index(dragEl$1)) {
5618 var update = false;
5619 multiDragElements.forEach(function (multiDragElement) {
5620 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
5621 update = true;
5622 return;
5623 }
5624 });
5625 if (update) {
5626 dispatchSortableEvent('update');
5627 dispatchSortableEvent('sort');
5628 }
5629 }
5630 }
5631
5632 // Must be done after capturing individual rects (scroll bar)
5633 multiDragElements.forEach(function (multiDragElement) {
5634 unsetRect(multiDragElement);
5635 });
5636 toSortable.animateAll();
5637 }
5638 multiDragSortable = toSortable;
5639 }
5640
5641 // Remove clones if necessary
5642 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
5643 multiDragClones.forEach(function (clone) {
5644 clone.parentNode && clone.parentNode.removeChild(clone);
5645 });
5646 }
5647 },
5648 nullingGlobal: function nullingGlobal() {
5649 this.isMultiDrag = dragStarted = false;
5650 multiDragClones.length = 0;
5651 },
5652 destroyGlobal: function destroyGlobal() {
5653 this._deselectMultiDrag();
5654 off(document, 'pointerup', this._deselectMultiDrag);
5655 off(document, 'mouseup', this._deselectMultiDrag);
5656 off(document, 'touchend', this._deselectMultiDrag);
5657 off(document, 'keydown', this._checkKeyDown);
5658 off(document, 'keyup', this._checkKeyUp);
5659 },
5660 _deselectMultiDrag: function _deselectMultiDrag(evt) {
5661 if (typeof dragStarted !== "undefined" && dragStarted) return;
5662
5663 // Only deselect if selection is in this sortable
5664 if (multiDragSortable !== this.sortable) return;
5665
5666 // Only deselect if target is not item in this sortable
5667 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
5668
5669 // Only deselect if left click
5670 if (evt && evt.button !== 0) return;
5671 while (multiDragElements.length) {
5672 var el = multiDragElements[0];
5673 toggleClass(el, this.options.selectedClass, false);
5674 multiDragElements.shift();
5675 dispatchEvent({
5676 sortable: this.sortable,
5677 rootEl: this.sortable.el,
5678 name: 'deselect',
5679 targetEl: el,
5680 originalEvent: evt
5681 });
5682 }
5683 },
5684 _checkKeyDown: function _checkKeyDown(evt) {
5685 if (evt.key === this.options.multiDragKey) {
5686 this.multiDragKeyDown = true;
5687 }
5688 },
5689 _checkKeyUp: function _checkKeyUp(evt) {
5690 if (evt.key === this.options.multiDragKey) {
5691 this.multiDragKeyDown = false;
5692 }
5693 }
5694 };
5695 return _extends(MultiDrag, {
5696 // Static methods & properties
5697 pluginName: 'multiDrag',
5698 utils: {
5699 /**
5700 * Selects the provided multi-drag item
5701 * @param {HTMLElement} el The element to be selected
5702 */
5703 select: function select(el) {
5704 var sortable = el.parentNode[expando];
5705 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
5706 if (multiDragSortable && multiDragSortable !== sortable) {
5707 multiDragSortable.multiDrag._deselectMultiDrag();
5708 multiDragSortable = sortable;
5709 }
5710 toggleClass(el, sortable.options.selectedClass, true);
5711 multiDragElements.push(el);
5712 },
5713 /**
5714 * Deselects the provided multi-drag item
5715 * @param {HTMLElement} el The element to be deselected
5716 */
5717 deselect: function deselect(el) {
5718 var sortable = el.parentNode[expando],
5719 index = multiDragElements.indexOf(el);
5720 if (!sortable || !sortable.options.multiDrag || !~index) return;
5721 toggleClass(el, sortable.options.selectedClass, false);
5722 multiDragElements.splice(index, 1);
5723 }
5724 },
5725 eventProperties: function eventProperties() {
5726 var _this3 = this;
5727 var oldIndicies = [],
5728 newIndicies = [];
5729 multiDragElements.forEach(function (multiDragElement) {
5730 oldIndicies.push({
5731 multiDragElement: multiDragElement,
5732 index: multiDragElement.sortableIndex
5733 });
5734
5735 // multiDragElements will already be sorted if folding
5736 var newIndex;
5737 if (folding && multiDragElement !== dragEl$1) {
5738 newIndex = -1;
5739 } else if (folding) {
5740 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
5741 } else {
5742 newIndex = index(multiDragElement);
5743 }
5744 newIndicies.push({
5745 multiDragElement: multiDragElement,
5746 index: newIndex
5747 });
5748 });
5749 return {
5750 items: _toConsumableArray(multiDragElements),
5751 clones: [].concat(multiDragClones),
5752 oldIndicies: oldIndicies,
5753 newIndicies: newIndicies
5754 };
5755 },
5756 optionListeners: {
5757 multiDragKey: function multiDragKey(key) {
5758 key = key.toLowerCase();
5759 if (key === 'ctrl') {
5760 key = 'Control';
5761 } else if (key.length > 1) {
5762 key = key.charAt(0).toUpperCase() + key.substr(1);
5763 }
5764 return key;
5765 }
5766 }
5767 });
5768 }
5769 function insertMultiDragElements(clonesInserted, rootEl) {
5770 multiDragElements.forEach(function (multiDragElement, i) {
5771 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
5772 if (target) {
5773 rootEl.insertBefore(multiDragElement, target);
5774 } else {
5775 rootEl.appendChild(multiDragElement);
5776 }
5777 });
5778 }
5779
5780 /**
5781 * Insert multi-drag clones
5782 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
5783 * @param {HTMLElement} rootEl
5784 */
5785 function insertMultiDragClones(elementsInserted, rootEl) {
5786 multiDragClones.forEach(function (clone, i) {
5787 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
5788 if (target) {
5789 rootEl.insertBefore(clone, target);
5790 } else {
5791 rootEl.appendChild(clone);
5792 }
5793 });
5794 }
5795 function removeMultiDragElements() {
5796 multiDragElements.forEach(function (multiDragElement) {
5797 if (multiDragElement === dragEl$1) return;
5798 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
5799 });
5800 }
5801
5802 Sortable.mount(new AutoScrollPlugin());
5803 Sortable.mount(Remove, Revert);
5804
5805 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
5806
5807
5808
5809 /***/ },
5810
5811 /***/ "./node_modules/toastify-js/src/toastify.css"
5812 /*!***************************************************!*\
5813 !*** ./node_modules/toastify-js/src/toastify.css ***!
5814 \***************************************************/
5815 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5816
5817 "use strict";
5818 __webpack_require__.r(__webpack_exports__);
5819 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5820 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5821 /* harmony export */ });
5822 /* 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");
5823 /* 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__);
5824 /* 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");
5825 /* 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__);
5826 /* 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");
5827 /* 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__);
5828 /* 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");
5829 /* 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__);
5830 /* 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");
5831 /* 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__);
5832 /* 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");
5833 /* 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__);
5834 /* 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");
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846 var options = {};
5847
5848 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5849 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5850
5851 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5852
5853 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5854 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5855
5856 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);
5857
5858
5859
5860
5861 /* 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);
5862
5863
5864 /***/ },
5865
5866 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
5867 /*!****************************************************************************!*\
5868 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
5869 \****************************************************************************/
5870 (module) {
5871
5872 "use strict";
5873
5874
5875 var stylesInDOM = [];
5876 function getIndexByIdentifier(identifier) {
5877 var result = -1;
5878 for (var i = 0; i < stylesInDOM.length; i++) {
5879 if (stylesInDOM[i].identifier === identifier) {
5880 result = i;
5881 break;
5882 }
5883 }
5884 return result;
5885 }
5886 function modulesToDom(list, options) {
5887 var idCountMap = {};
5888 var identifiers = [];
5889 for (var i = 0; i < list.length; i++) {
5890 var item = list[i];
5891 var id = options.base ? item[0] + options.base : item[0];
5892 var count = idCountMap[id] || 0;
5893 var identifier = "".concat(id, " ").concat(count);
5894 idCountMap[id] = count + 1;
5895 var indexByIdentifier = getIndexByIdentifier(identifier);
5896 var obj = {
5897 css: item[1],
5898 media: item[2],
5899 sourceMap: item[3],
5900 supports: item[4],
5901 layer: item[5]
5902 };
5903 if (indexByIdentifier !== -1) {
5904 stylesInDOM[indexByIdentifier].references++;
5905 stylesInDOM[indexByIdentifier].updater(obj);
5906 } else {
5907 var updater = addElementStyle(obj, options);
5908 options.byIndex = i;
5909 stylesInDOM.splice(i, 0, {
5910 identifier: identifier,
5911 updater: updater,
5912 references: 1
5913 });
5914 }
5915 identifiers.push(identifier);
5916 }
5917 return identifiers;
5918 }
5919 function addElementStyle(obj, options) {
5920 var api = options.domAPI(options);
5921 api.update(obj);
5922 var updater = function updater(newObj) {
5923 if (newObj) {
5924 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
5925 return;
5926 }
5927 api.update(obj = newObj);
5928 } else {
5929 api.remove();
5930 }
5931 };
5932 return updater;
5933 }
5934 module.exports = function (list, options) {
5935 options = options || {};
5936 list = list || [];
5937 var lastIdentifiers = modulesToDom(list, options);
5938 return function update(newList) {
5939 newList = newList || [];
5940 for (var i = 0; i < lastIdentifiers.length; i++) {
5941 var identifier = lastIdentifiers[i];
5942 var index = getIndexByIdentifier(identifier);
5943 stylesInDOM[index].references--;
5944 }
5945 var newLastIdentifiers = modulesToDom(newList, options);
5946 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
5947 var _identifier = lastIdentifiers[_i];
5948 var _index = getIndexByIdentifier(_identifier);
5949 if (stylesInDOM[_index].references === 0) {
5950 stylesInDOM[_index].updater();
5951 stylesInDOM.splice(_index, 1);
5952 }
5953 }
5954 lastIdentifiers = newLastIdentifiers;
5955 };
5956 };
5957
5958 /***/ },
5959
5960 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
5961 /*!********************************************************************!*\
5962 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
5963 \********************************************************************/
5964 (module) {
5965
5966 "use strict";
5967
5968
5969 var memo = {};
5970
5971 /* istanbul ignore next */
5972 function getTarget(target) {
5973 if (typeof memo[target] === "undefined") {
5974 var styleTarget = document.querySelector(target);
5975
5976 // Special case to return head of iframe instead of iframe itself
5977 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
5978 try {
5979 // This will throw an exception if access to iframe is blocked
5980 // due to cross-origin restrictions
5981 styleTarget = styleTarget.contentDocument.head;
5982 } catch (e) {
5983 // istanbul ignore next
5984 styleTarget = null;
5985 }
5986 }
5987 memo[target] = styleTarget;
5988 }
5989 return memo[target];
5990 }
5991
5992 /* istanbul ignore next */
5993 function insertBySelector(insert, style) {
5994 var target = getTarget(insert);
5995 if (!target) {
5996 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
5997 }
5998 target.appendChild(style);
5999 }
6000 module.exports = insertBySelector;
6001
6002 /***/ },
6003
6004 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
6005 /*!**********************************************************************!*\
6006 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
6007 \**********************************************************************/
6008 (module) {
6009
6010 "use strict";
6011
6012
6013 /* istanbul ignore next */
6014 function insertStyleElement(options) {
6015 var element = document.createElement("style");
6016 options.setAttributes(element, options.attributes);
6017 options.insert(element, options.options);
6018 return element;
6019 }
6020 module.exports = insertStyleElement;
6021
6022 /***/ },
6023
6024 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
6025 /*!**********************************************************************************!*\
6026 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
6027 \**********************************************************************************/
6028 (module, __unused_webpack_exports, __webpack_require__) {
6029
6030 "use strict";
6031
6032
6033 /* istanbul ignore next */
6034 function setAttributesWithoutAttributes(styleElement) {
6035 var nonce = true ? __webpack_require__.nc : 0;
6036 if (nonce) {
6037 styleElement.setAttribute("nonce", nonce);
6038 }
6039 }
6040 module.exports = setAttributesWithoutAttributes;
6041
6042 /***/ },
6043
6044 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
6045 /*!***************************************************************!*\
6046 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
6047 \***************************************************************/
6048 (module) {
6049
6050 "use strict";
6051
6052
6053 /* istanbul ignore next */
6054 function apply(styleElement, options, obj) {
6055 var css = "";
6056 if (obj.supports) {
6057 css += "@supports (".concat(obj.supports, ") {");
6058 }
6059 if (obj.media) {
6060 css += "@media ".concat(obj.media, " {");
6061 }
6062 var needLayer = typeof obj.layer !== "undefined";
6063 if (needLayer) {
6064 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
6065 }
6066 css += obj.css;
6067 if (needLayer) {
6068 css += "}";
6069 }
6070 if (obj.media) {
6071 css += "}";
6072 }
6073 if (obj.supports) {
6074 css += "}";
6075 }
6076 var sourceMap = obj.sourceMap;
6077 if (sourceMap && typeof btoa !== "undefined") {
6078 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
6079 }
6080
6081 // For old IE
6082 /* istanbul ignore if */
6083 options.styleTagTransform(css, styleElement, options.options);
6084 }
6085 function removeStyleElement(styleElement) {
6086 // istanbul ignore if
6087 if (styleElement.parentNode === null) {
6088 return false;
6089 }
6090 styleElement.parentNode.removeChild(styleElement);
6091 }
6092
6093 /* istanbul ignore next */
6094 function domAPI(options) {
6095 if (typeof document === "undefined") {
6096 return {
6097 update: function update() {},
6098 remove: function remove() {}
6099 };
6100 }
6101 var styleElement = options.insertStyleElement(options);
6102 return {
6103 update: function update(obj) {
6104 apply(styleElement, options, obj);
6105 },
6106 remove: function remove() {
6107 removeStyleElement(styleElement);
6108 }
6109 };
6110 }
6111 module.exports = domAPI;
6112
6113 /***/ },
6114
6115 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
6116 /*!*********************************************************************!*\
6117 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
6118 \*********************************************************************/
6119 (module) {
6120
6121 "use strict";
6122
6123
6124 /* istanbul ignore next */
6125 function styleTagTransform(css, styleElement) {
6126 if (styleElement.styleSheet) {
6127 styleElement.styleSheet.cssText = css;
6128 } else {
6129 while (styleElement.firstChild) {
6130 styleElement.removeChild(styleElement.firstChild);
6131 }
6132 styleElement.appendChild(document.createTextNode(css));
6133 }
6134 }
6135 module.exports = styleTagTransform;
6136
6137 /***/ },
6138
6139 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
6140 /*!**********************************************************!*\
6141 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
6142 \**********************************************************/
6143 (module) {
6144
6145 /*!
6146 * sweetalert2 v11.26.17
6147 * Released under the MIT License.
6148 */
6149 (function (global, factory) {
6150 true ? module.exports = factory() :
6151 0;
6152 })(this, (function () { 'use strict';
6153
6154 function _assertClassBrand(e, t, n) {
6155 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
6156 throw new TypeError("Private element is not present on this object");
6157 }
6158 function _checkPrivateRedeclaration(e, t) {
6159 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
6160 }
6161 function _classPrivateFieldGet2(s, a) {
6162 return s.get(_assertClassBrand(s, a));
6163 }
6164 function _classPrivateFieldInitSpec(e, t, a) {
6165 _checkPrivateRedeclaration(e, t), t.set(e, a);
6166 }
6167 function _classPrivateFieldSet2(s, a, r) {
6168 return s.set(_assertClassBrand(s, a), r), r;
6169 }
6170
6171 const RESTORE_FOCUS_TIMEOUT = 100;
6172
6173 /** @type {GlobalState} */
6174 const globalState = {};
6175 const focusPreviousActiveElement = () => {
6176 if (globalState.previousActiveElement instanceof HTMLElement) {
6177 globalState.previousActiveElement.focus();
6178 globalState.previousActiveElement = null;
6179 } else if (document.body) {
6180 document.body.focus();
6181 }
6182 };
6183
6184 /**
6185 * Restore previous active (focused) element
6186 *
6187 * @param {boolean} returnFocus
6188 * @returns {Promise<void>}
6189 */
6190 const restoreActiveElement = returnFocus => {
6191 return new Promise(resolve => {
6192 if (!returnFocus) {
6193 return resolve();
6194 }
6195 const x = window.scrollX;
6196 const y = window.scrollY;
6197 globalState.restoreFocusTimeout = setTimeout(() => {
6198 focusPreviousActiveElement();
6199 resolve();
6200 }, RESTORE_FOCUS_TIMEOUT); // issues/900
6201
6202 window.scrollTo(x, y);
6203 });
6204 };
6205
6206 const swalPrefix = 'swal2-';
6207
6208 /**
6209 * @typedef {Record<SwalClass, string>} SwalClasses
6210 */
6211
6212 /**
6213 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
6214 * @typedef {Record<SwalIcon, string>} SwalIcons
6215 */
6216
6217 /** @type {SwalClass[]} */
6218 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'];
6219 const swalClasses = classNames.reduce((acc, className) => {
6220 acc[className] = swalPrefix + className;
6221 return acc;
6222 }, /** @type {SwalClasses} */{});
6223
6224 /** @type {SwalIcon[]} */
6225 const icons = ['success', 'warning', 'info', 'question', 'error'];
6226 const iconTypes = icons.reduce((acc, icon) => {
6227 acc[icon] = swalPrefix + icon;
6228 return acc;
6229 }, /** @type {SwalIcons} */{});
6230
6231 const consolePrefix = 'SweetAlert2:';
6232
6233 /**
6234 * Capitalize the first letter of a string
6235 *
6236 * @param {string} str
6237 * @returns {string}
6238 */
6239 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
6240
6241 /**
6242 * Standardize console warnings
6243 *
6244 * @param {string | string[]} message
6245 */
6246 const warn = message => {
6247 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
6248 };
6249
6250 /**
6251 * Standardize console errors
6252 *
6253 * @param {string} message
6254 */
6255 const error = message => {
6256 console.error(`${consolePrefix} ${message}`);
6257 };
6258
6259 /**
6260 * Private global state for `warnOnce`
6261 *
6262 * @type {string[]}
6263 * @private
6264 */
6265 const previousWarnOnceMessages = [];
6266
6267 /**
6268 * Show a console warning, but only if it hasn't already been shown
6269 *
6270 * @param {string} message
6271 */
6272 const warnOnce = message => {
6273 if (!previousWarnOnceMessages.includes(message)) {
6274 previousWarnOnceMessages.push(message);
6275 warn(message);
6276 }
6277 };
6278
6279 /**
6280 * Show a one-time console warning about deprecated params/methods
6281 *
6282 * @param {string} deprecatedParam
6283 * @param {string?} useInstead
6284 */
6285 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
6286 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
6287 };
6288
6289 /**
6290 * If `arg` is a function, call it (with no arguments or context) and return the result.
6291 * Otherwise, just pass the value through
6292 *
6293 * @param {(() => *) | *} arg
6294 * @returns {*}
6295 */
6296 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
6297
6298 /**
6299 * @param {*} arg
6300 * @returns {boolean}
6301 */
6302 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
6303
6304 /**
6305 * @param {*} arg
6306 * @returns {Promise<*>}
6307 */
6308 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
6309
6310 /**
6311 * @param {*} arg
6312 * @returns {boolean}
6313 */
6314 const isPromise = arg => arg && Promise.resolve(arg) === arg;
6315
6316 /**
6317 * Gets the popup container which contains the backdrop and the popup itself.
6318 *
6319 * @returns {HTMLElement | null}
6320 */
6321 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
6322
6323 /**
6324 * @param {string} selectorString
6325 * @returns {HTMLElement | null}
6326 */
6327 const elementBySelector = selectorString => {
6328 const container = getContainer();
6329 return container ? container.querySelector(selectorString) : null;
6330 };
6331
6332 /**
6333 * @param {string} className
6334 * @returns {HTMLElement | null}
6335 */
6336 const elementByClass = className => {
6337 return elementBySelector(`.${className}`);
6338 };
6339
6340 /**
6341 * @returns {HTMLElement | null}
6342 */
6343 const getPopup = () => elementByClass(swalClasses.popup);
6344
6345 /**
6346 * @returns {HTMLElement | null}
6347 */
6348 const getIcon = () => elementByClass(swalClasses.icon);
6349
6350 /**
6351 * @returns {HTMLElement | null}
6352 */
6353 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6354
6355 /**
6356 * @returns {HTMLElement | null}
6357 */
6358 const getTitle = () => elementByClass(swalClasses.title);
6359
6360 /**
6361 * @returns {HTMLElement | null}
6362 */
6363 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6364
6365 /**
6366 * @returns {HTMLElement | null}
6367 */
6368 const getImage = () => elementByClass(swalClasses.image);
6369
6370 /**
6371 * @returns {HTMLElement | null}
6372 */
6373 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6374
6375 /**
6376 * @returns {HTMLElement | null}
6377 */
6378 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6379
6380 /**
6381 * @returns {HTMLButtonElement | null}
6382 */
6383 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6384
6385 /**
6386 * @returns {HTMLButtonElement | null}
6387 */
6388 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6389
6390 /**
6391 * @returns {HTMLButtonElement | null}
6392 */
6393 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6394
6395 /**
6396 * @returns {HTMLElement | null}
6397 */
6398 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6399
6400 /**
6401 * @returns {HTMLElement | null}
6402 */
6403 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6404
6405 /**
6406 * @returns {HTMLElement | null}
6407 */
6408 const getActions = () => elementByClass(swalClasses.actions);
6409
6410 /**
6411 * @returns {HTMLElement | null}
6412 */
6413 const getFooter = () => elementByClass(swalClasses.footer);
6414
6415 /**
6416 * @returns {HTMLElement | null}
6417 */
6418 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6419
6420 /**
6421 * @returns {HTMLElement | null}
6422 */
6423 const getCloseButton = () => elementByClass(swalClasses.close);
6424
6425 // https://github.com/jkup/focusable/blob/master/index.js
6426 const focusable = `
6427 a[href],
6428 area[href],
6429 input:not([disabled]),
6430 select:not([disabled]),
6431 textarea:not([disabled]),
6432 button:not([disabled]),
6433 iframe,
6434 object,
6435 embed,
6436 [tabindex="0"],
6437 [contenteditable],
6438 audio[controls],
6439 video[controls],
6440 summary
6441 `;
6442 /**
6443 * @returns {HTMLElement[]}
6444 */
6445 const getFocusableElements = () => {
6446 const popup = getPopup();
6447 if (!popup) {
6448 return [];
6449 }
6450 /** @type {NodeListOf<HTMLElement>} */
6451 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6452 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6453 // sort according to tabindex
6454 .sort((a, b) => {
6455 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6456 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6457 if (tabindexA > tabindexB) {
6458 return 1;
6459 } else if (tabindexA < tabindexB) {
6460 return -1;
6461 }
6462 return 0;
6463 });
6464
6465 /** @type {NodeListOf<HTMLElement>} */
6466 const otherFocusableElements = popup.querySelectorAll(focusable);
6467 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6468 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6469 };
6470
6471 /**
6472 * @returns {boolean}
6473 */
6474 const isModal = () => {
6475 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6476 };
6477
6478 /**
6479 * @returns {boolean}
6480 */
6481 const isToast = () => {
6482 const popup = getPopup();
6483 if (!popup) {
6484 return false;
6485 }
6486 return hasClass(popup, swalClasses.toast);
6487 };
6488
6489 /**
6490 * @returns {boolean}
6491 */
6492 const isLoading = () => {
6493 const popup = getPopup();
6494 if (!popup) {
6495 return false;
6496 }
6497 return popup.hasAttribute('data-loading');
6498 };
6499
6500 /**
6501 * Securely set innerHTML of an element
6502 * https://github.com/sweetalert2/sweetalert2/issues/1926
6503 *
6504 * @param {HTMLElement} elem
6505 * @param {string} html
6506 */
6507 const setInnerHtml = (elem, html) => {
6508 elem.textContent = '';
6509 if (html) {
6510 const parser = new DOMParser();
6511 const parsed = parser.parseFromString(html, `text/html`);
6512 const head = parsed.querySelector('head');
6513 if (head) {
6514 Array.from(head.childNodes).forEach(child => {
6515 elem.appendChild(child);
6516 });
6517 }
6518 const body = parsed.querySelector('body');
6519 if (body) {
6520 Array.from(body.childNodes).forEach(child => {
6521 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6522 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6523 } else {
6524 elem.appendChild(child);
6525 }
6526 });
6527 }
6528 }
6529 };
6530
6531 /**
6532 * @param {HTMLElement} elem
6533 * @param {string} className
6534 * @returns {boolean}
6535 */
6536 const hasClass = (elem, className) => {
6537 if (!className) {
6538 return false;
6539 }
6540 const classList = className.split(/\s+/);
6541 for (let i = 0; i < classList.length; i++) {
6542 if (!elem.classList.contains(classList[i])) {
6543 return false;
6544 }
6545 }
6546 return true;
6547 };
6548
6549 /**
6550 * @param {HTMLElement} elem
6551 * @param {SweetAlertOptions} params
6552 */
6553 const removeCustomClasses = (elem, params) => {
6554 Array.from(elem.classList).forEach(className => {
6555 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6556 elem.classList.remove(className);
6557 }
6558 });
6559 };
6560
6561 /**
6562 * @param {HTMLElement} elem
6563 * @param {SweetAlertOptions} params
6564 * @param {string} className
6565 */
6566 const applyCustomClass = (elem, params, className) => {
6567 removeCustomClasses(elem, params);
6568 if (!params.customClass) {
6569 return;
6570 }
6571 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6572 if (!customClass) {
6573 return;
6574 }
6575 if (typeof customClass !== 'string' && !customClass.forEach) {
6576 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6577 return;
6578 }
6579 addClass(elem, customClass);
6580 };
6581
6582 /**
6583 * @param {HTMLElement} popup
6584 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6585 * @returns {HTMLInputElement | null}
6586 */
6587 const getInput$1 = (popup, inputClass) => {
6588 if (!inputClass) {
6589 return null;
6590 }
6591 switch (inputClass) {
6592 case 'select':
6593 case 'textarea':
6594 case 'file':
6595 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6596 case 'checkbox':
6597 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6598 case 'radio':
6599 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6600 case 'range':
6601 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6602 default:
6603 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6604 }
6605 };
6606
6607 /**
6608 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6609 */
6610 const focusInput = input => {
6611 input.focus();
6612
6613 // place cursor at end of text in text input
6614 if (input.type !== 'file') {
6615 // http://stackoverflow.com/a/2345915
6616 const val = input.value;
6617 input.value = '';
6618 input.value = val;
6619 }
6620 };
6621
6622 /**
6623 * @param {HTMLElement | HTMLElement[] | null} target
6624 * @param {string | string[] | readonly string[] | undefined} classList
6625 * @param {boolean} condition
6626 */
6627 const toggleClass = (target, classList, condition) => {
6628 if (!target || !classList) {
6629 return;
6630 }
6631 if (typeof classList === 'string') {
6632 classList = classList.split(/\s+/).filter(Boolean);
6633 }
6634 classList.forEach(className => {
6635 if (Array.isArray(target)) {
6636 target.forEach(elem => {
6637 if (condition) {
6638 elem.classList.add(className);
6639 } else {
6640 elem.classList.remove(className);
6641 }
6642 });
6643 } else {
6644 if (condition) {
6645 target.classList.add(className);
6646 } else {
6647 target.classList.remove(className);
6648 }
6649 }
6650 });
6651 };
6652
6653 /**
6654 * @param {HTMLElement | HTMLElement[] | null} target
6655 * @param {string | string[] | readonly string[] | undefined} classList
6656 */
6657 const addClass = (target, classList) => {
6658 toggleClass(target, classList, true);
6659 };
6660
6661 /**
6662 * @param {HTMLElement | HTMLElement[] | null} target
6663 * @param {string | string[] | readonly string[] | undefined} classList
6664 */
6665 const removeClass = (target, classList) => {
6666 toggleClass(target, classList, false);
6667 };
6668
6669 /**
6670 * Get direct child of an element by class name
6671 *
6672 * @param {HTMLElement} elem
6673 * @param {string} className
6674 * @returns {HTMLElement | undefined}
6675 */
6676 const getDirectChildByClass = (elem, className) => {
6677 const children = Array.from(elem.children);
6678 for (let i = 0; i < children.length; i++) {
6679 const child = children[i];
6680 if (child instanceof HTMLElement && hasClass(child, className)) {
6681 return child;
6682 }
6683 }
6684 };
6685
6686 /**
6687 * @param {HTMLElement} elem
6688 * @param {string} property
6689 * @param {string | number | null | undefined} value
6690 */
6691 const applyNumericalStyle = (elem, property, value) => {
6692 if (value === `${parseInt(`${value}`)}`) {
6693 value = parseInt(value);
6694 }
6695 if (value || parseInt(`${value}`) === 0) {
6696 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
6697 } else {
6698 elem.style.removeProperty(property);
6699 }
6700 };
6701
6702 /**
6703 * @param {HTMLElement | null} elem
6704 * @param {string} display
6705 */
6706 const show = (elem, display = 'flex') => {
6707 if (!elem) {
6708 return;
6709 }
6710 elem.style.display = display;
6711 };
6712
6713 /**
6714 * @param {HTMLElement | null} elem
6715 */
6716 const hide = elem => {
6717 if (!elem) {
6718 return;
6719 }
6720 elem.style.display = 'none';
6721 };
6722
6723 /**
6724 * @param {HTMLElement | null} elem
6725 * @param {string} display
6726 */
6727 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6728 if (!elem) {
6729 return;
6730 }
6731 new MutationObserver(() => {
6732 toggle(elem, elem.innerHTML, display);
6733 }).observe(elem, {
6734 childList: true,
6735 subtree: true
6736 });
6737 };
6738
6739 /**
6740 * @param {HTMLElement} parent
6741 * @param {string} selector
6742 * @param {string} property
6743 * @param {string} value
6744 */
6745 const setStyle = (parent, selector, property, value) => {
6746 /** @type {HTMLElement | null} */
6747 const el = parent.querySelector(selector);
6748 if (el) {
6749 el.style.setProperty(property, value);
6750 }
6751 };
6752
6753 /**
6754 * @param {HTMLElement} elem
6755 * @param {boolean | string | null | undefined} condition
6756 * @param {string} display
6757 */
6758 const toggle = (elem, condition, display = 'flex') => {
6759 if (condition) {
6760 show(elem, display);
6761 } else {
6762 hide(elem);
6763 }
6764 };
6765
6766 /**
6767 * borrowed from jquery $(elem).is(':visible') implementation
6768 *
6769 * @param {HTMLElement | null} elem
6770 * @returns {boolean}
6771 */
6772 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6773
6774 /**
6775 * @returns {boolean}
6776 */
6777 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6778
6779 /**
6780 * @param {HTMLElement} elem
6781 * @returns {boolean}
6782 */
6783 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
6784
6785 /**
6786 * @param {HTMLElement} element
6787 * @param {HTMLElement} stopElement
6788 * @returns {boolean}
6789 */
6790 const selfOrParentIsScrollable = (element, stopElement) => {
6791 let parent = /** @type {HTMLElement | null} */element;
6792 while (parent && parent !== stopElement) {
6793 if (isScrollable(parent)) {
6794 return true;
6795 }
6796 parent = parent.parentElement;
6797 }
6798 return false;
6799 };
6800
6801 /**
6802 * borrowed from https://stackoverflow.com/a/46352119
6803 *
6804 * @param {HTMLElement} elem
6805 * @returns {boolean}
6806 */
6807 const hasCssAnimation = elem => {
6808 const style = window.getComputedStyle(elem);
6809 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6810 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6811 return animDuration > 0 || transDuration > 0;
6812 };
6813
6814 /**
6815 * @param {number} timer
6816 * @param {boolean} reset
6817 */
6818 const animateTimerProgressBar = (timer, reset = false) => {
6819 const timerProgressBar = getTimerProgressBar();
6820 if (!timerProgressBar) {
6821 return;
6822 }
6823 if (isVisible$1(timerProgressBar)) {
6824 if (reset) {
6825 timerProgressBar.style.transition = 'none';
6826 timerProgressBar.style.width = '100%';
6827 }
6828 setTimeout(() => {
6829 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6830 timerProgressBar.style.width = '0%';
6831 }, 10);
6832 }
6833 };
6834 const stopTimerProgressBar = () => {
6835 const timerProgressBar = getTimerProgressBar();
6836 if (!timerProgressBar) {
6837 return;
6838 }
6839 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6840 timerProgressBar.style.removeProperty('transition');
6841 timerProgressBar.style.width = '100%';
6842 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6843 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6844 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6845 };
6846
6847 /**
6848 * Detect Node env
6849 *
6850 * @returns {boolean}
6851 */
6852 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6853
6854 const sweetHTML = `
6855 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6856 <button type="button" class="${swalClasses.close}"></button>
6857 <ul class="${swalClasses['progress-steps']}"></ul>
6858 <div class="${swalClasses.icon}"></div>
6859 <img class="${swalClasses.image}" />
6860 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6861 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6862 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6863 <input type="file" class="${swalClasses.file}" />
6864 <div class="${swalClasses.range}">
6865 <input type="range" />
6866 <output></output>
6867 </div>
6868 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6869 <div class="${swalClasses.radio}"></div>
6870 <label class="${swalClasses.checkbox}">
6871 <input type="checkbox" id="${swalClasses.checkbox}" />
6872 <span class="${swalClasses.label}"></span>
6873 </label>
6874 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6875 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6876 <div class="${swalClasses.actions}">
6877 <div class="${swalClasses.loader}"></div>
6878 <button type="button" class="${swalClasses.confirm}"></button>
6879 <button type="button" class="${swalClasses.deny}"></button>
6880 <button type="button" class="${swalClasses.cancel}"></button>
6881 </div>
6882 <div class="${swalClasses.footer}"></div>
6883 <div class="${swalClasses['timer-progress-bar-container']}">
6884 <div class="${swalClasses['timer-progress-bar']}"></div>
6885 </div>
6886 </div>
6887 `.replace(/(^|\n)\s*/g, '');
6888
6889 /**
6890 * @returns {boolean}
6891 */
6892 const resetOldContainer = () => {
6893 const oldContainer = getContainer();
6894 if (!oldContainer) {
6895 return false;
6896 }
6897 oldContainer.remove();
6898 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
6899 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
6900 swalClasses['has-column']]);
6901 return true;
6902 };
6903 const resetValidationMessage$1 = () => {
6904 if (globalState.currentInstance) {
6905 globalState.currentInstance.resetValidationMessage();
6906 }
6907 };
6908 const addInputChangeListeners = () => {
6909 const popup = getPopup();
6910 if (!popup) {
6911 return;
6912 }
6913 const input = getDirectChildByClass(popup, swalClasses.input);
6914 const file = getDirectChildByClass(popup, swalClasses.file);
6915 /** @type {HTMLInputElement | null} */
6916 const range = popup.querySelector(`.${swalClasses.range} input`);
6917 /** @type {HTMLOutputElement | null} */
6918 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6919 const select = getDirectChildByClass(popup, swalClasses.select);
6920 /** @type {HTMLInputElement | null} */
6921 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6922 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6923 if (input) {
6924 input.oninput = resetValidationMessage$1;
6925 }
6926 if (file) {
6927 file.onchange = resetValidationMessage$1;
6928 }
6929 if (select) {
6930 select.onchange = resetValidationMessage$1;
6931 }
6932 if (checkbox) {
6933 checkbox.onchange = resetValidationMessage$1;
6934 }
6935 if (textarea) {
6936 textarea.oninput = resetValidationMessage$1;
6937 }
6938 if (range && rangeOutput) {
6939 range.oninput = () => {
6940 resetValidationMessage$1();
6941 rangeOutput.value = range.value;
6942 };
6943 range.onchange = () => {
6944 resetValidationMessage$1();
6945 rangeOutput.value = range.value;
6946 };
6947 }
6948 };
6949
6950 /**
6951 * @param {string | HTMLElement} target
6952 * @returns {HTMLElement}
6953 */
6954 const getTarget = target => {
6955 if (typeof target === 'string') {
6956 const element = document.querySelector(target);
6957 if (!element) {
6958 throw new Error(`Target element "${target}" not found`);
6959 }
6960 return /** @type {HTMLElement} */element;
6961 }
6962 return target;
6963 };
6964
6965 /**
6966 * @param {SweetAlertOptions} params
6967 */
6968 const setupAccessibility = params => {
6969 const popup = getPopup();
6970 if (!popup) {
6971 return;
6972 }
6973 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6974 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6975 if (!params.toast) {
6976 popup.setAttribute('aria-modal', 'true');
6977 }
6978 };
6979
6980 /**
6981 * @param {HTMLElement} targetElement
6982 */
6983 const setupRTL = targetElement => {
6984 if (window.getComputedStyle(targetElement).direction === 'rtl') {
6985 addClass(getContainer(), swalClasses.rtl);
6986 globalState.isRTL = true;
6987 }
6988 };
6989
6990 /**
6991 * Add modal + backdrop to DOM
6992 *
6993 * @param {SweetAlertOptions} params
6994 */
6995 const init = params => {
6996 // Clean up the old popup container if it exists
6997 const oldContainerExisted = resetOldContainer();
6998 if (isNodeEnv()) {
6999 error('SweetAlert2 requires document to initialize');
7000 return;
7001 }
7002 const container = document.createElement('div');
7003 container.className = swalClasses.container;
7004 if (oldContainerExisted) {
7005 addClass(container, swalClasses['no-transition']);
7006 }
7007 setInnerHtml(container, sweetHTML);
7008 container.dataset['swal2Theme'] = params.theme;
7009 const targetElement = getTarget(params.target || 'body');
7010 targetElement.appendChild(container);
7011 if (params.topLayer) {
7012 container.setAttribute('popover', '');
7013 container.showPopover();
7014 }
7015 setupAccessibility(params);
7016 setupRTL(targetElement);
7017 addInputChangeListeners();
7018 };
7019
7020 /**
7021 * @param {HTMLElement | object | string} param
7022 * @param {HTMLElement} target
7023 */
7024 const parseHtmlToContainer = (param, target) => {
7025 // DOM element
7026 if (param instanceof HTMLElement) {
7027 target.appendChild(param);
7028 }
7029
7030 // Object
7031 else if (typeof param === 'object') {
7032 handleObject(param, target);
7033 }
7034
7035 // Plain string
7036 else if (param) {
7037 setInnerHtml(target, param);
7038 }
7039 };
7040
7041 /**
7042 * @param {object} param
7043 * @param {HTMLElement} target
7044 */
7045 const handleObject = (param, target) => {
7046 // JQuery element(s)
7047 if ('jquery' in param) {
7048 handleJqueryElem(target, param);
7049 }
7050
7051 // For other objects use their string representation
7052 else {
7053 setInnerHtml(target, param.toString());
7054 }
7055 };
7056
7057 /**
7058 * @param {HTMLElement} target
7059 * @param {any} elem
7060 */
7061 const handleJqueryElem = (target, elem) => {
7062 target.textContent = '';
7063 if (0 in elem) {
7064 for (let i = 0; i in elem; i++) {
7065 target.appendChild(elem[i].cloneNode(true));
7066 }
7067 } else {
7068 target.appendChild(elem.cloneNode(true));
7069 }
7070 };
7071
7072 /**
7073 * @param {SweetAlert} instance
7074 * @param {SweetAlertOptions} params
7075 */
7076 const renderActions = (instance, params) => {
7077 const actions = getActions();
7078 const loader = getLoader();
7079 if (!actions || !loader) {
7080 return;
7081 }
7082
7083 // Actions (buttons) wrapper
7084 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
7085 hide(actions);
7086 } else {
7087 show(actions);
7088 }
7089
7090 // Custom class
7091 applyCustomClass(actions, params, 'actions');
7092
7093 // Render all the buttons
7094 renderButtons(actions, loader, params);
7095
7096 // Loader
7097 setInnerHtml(loader, params.loaderHtml || '');
7098 applyCustomClass(loader, params, 'loader');
7099 };
7100
7101 /**
7102 * @param {HTMLElement} actions
7103 * @param {HTMLElement} loader
7104 * @param {SweetAlertOptions} params
7105 */
7106 function renderButtons(actions, loader, params) {
7107 const confirmButton = getConfirmButton();
7108 const denyButton = getDenyButton();
7109 const cancelButton = getCancelButton();
7110 if (!confirmButton || !denyButton || !cancelButton) {
7111 return;
7112 }
7113
7114 // Render buttons
7115 renderButton(confirmButton, 'confirm', params);
7116 renderButton(denyButton, 'deny', params);
7117 renderButton(cancelButton, 'cancel', params);
7118 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
7119 if (params.reverseButtons) {
7120 if (params.toast) {
7121 actions.insertBefore(cancelButton, confirmButton);
7122 actions.insertBefore(denyButton, confirmButton);
7123 } else {
7124 actions.insertBefore(cancelButton, loader);
7125 actions.insertBefore(denyButton, loader);
7126 actions.insertBefore(confirmButton, loader);
7127 }
7128 }
7129 }
7130
7131 /**
7132 * @param {HTMLElement} confirmButton
7133 * @param {HTMLElement} denyButton
7134 * @param {HTMLElement} cancelButton
7135 * @param {SweetAlertOptions} params
7136 */
7137 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
7138 if (!params.buttonsStyling) {
7139 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7140 return;
7141 }
7142 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7143
7144 // Apply custom background colors to action buttons
7145 if (params.confirmButtonColor) {
7146 confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
7147 }
7148 if (params.denyButtonColor) {
7149 denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
7150 }
7151 if (params.cancelButtonColor) {
7152 cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
7153 }
7154
7155 // Apply the outline color to action buttons
7156 applyOutlineColor(confirmButton);
7157 applyOutlineColor(denyButton);
7158 applyOutlineColor(cancelButton);
7159 }
7160
7161 /**
7162 * @param {HTMLElement} button
7163 */
7164 function applyOutlineColor(button) {
7165 const buttonStyle = window.getComputedStyle(button);
7166 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
7167 // If the button already has a custom outline color, no need to change it
7168 return;
7169 }
7170 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
7171 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
7172 }
7173
7174 /**
7175 * @param {HTMLElement} button
7176 * @param {'confirm' | 'deny' | 'cancel'} buttonType
7177 * @param {SweetAlertOptions} params
7178 */
7179 function renderButton(button, buttonType, params) {
7180 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
7181 toggle(button, params[`show${buttonName}Button`], 'inline-block');
7182 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
7183 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
7184
7185 // Add buttons custom classes
7186 button.className = swalClasses[buttonType];
7187 applyCustomClass(button, params, `${buttonType}Button`);
7188 }
7189
7190 /**
7191 * @param {SweetAlert} instance
7192 * @param {SweetAlertOptions} params
7193 */
7194 const renderCloseButton = (instance, params) => {
7195 const closeButton = getCloseButton();
7196 if (!closeButton) {
7197 return;
7198 }
7199 setInnerHtml(closeButton, params.closeButtonHtml || '');
7200
7201 // Custom class
7202 applyCustomClass(closeButton, params, 'closeButton');
7203 toggle(closeButton, params.showCloseButton);
7204 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
7205 };
7206
7207 /**
7208 * @param {SweetAlert} instance
7209 * @param {SweetAlertOptions} params
7210 */
7211 const renderContainer = (instance, params) => {
7212 const container = getContainer();
7213 if (!container) {
7214 return;
7215 }
7216 handleBackdropParam(container, params.backdrop);
7217 handlePositionParam(container, params.position);
7218 handleGrowParam(container, params.grow);
7219
7220 // Custom class
7221 applyCustomClass(container, params, 'container');
7222 };
7223
7224 /**
7225 * @param {HTMLElement} container
7226 * @param {SweetAlertOptions['backdrop']} backdrop
7227 */
7228 function handleBackdropParam(container, backdrop) {
7229 if (typeof backdrop === 'string') {
7230 container.style.background = backdrop;
7231 } else if (!backdrop) {
7232 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
7233 }
7234 }
7235
7236 /**
7237 * @param {HTMLElement} container
7238 * @param {SweetAlertOptions['position']} position
7239 */
7240 function handlePositionParam(container, position) {
7241 if (!position) {
7242 return;
7243 }
7244 if (position in swalClasses) {
7245 addClass(container, swalClasses[position]);
7246 } else {
7247 warn('The "position" parameter is not valid, defaulting to "center"');
7248 addClass(container, swalClasses.center);
7249 }
7250 }
7251
7252 /**
7253 * @param {HTMLElement} container
7254 * @param {SweetAlertOptions['grow']} grow
7255 */
7256 function handleGrowParam(container, grow) {
7257 if (!grow) {
7258 return;
7259 }
7260 addClass(container, swalClasses[`grow-${grow}`]);
7261 }
7262
7263 /**
7264 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7265 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7266 * This is the approach that Babel will probably take to implement private methods/fields
7267 * https://github.com/tc39/proposal-private-methods
7268 * https://github.com/babel/babel/pull/7555
7269 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7270 * then we can use that language feature.
7271 */
7272
7273 var privateProps = {
7274 innerParams: new WeakMap(),
7275 domCache: new WeakMap()
7276 };
7277
7278 /// <reference path="../../../../sweetalert2.d.ts"/>
7279
7280
7281 /** @type {InputClass[]} */
7282 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
7283
7284 /**
7285 * @param {SweetAlert} instance
7286 * @param {SweetAlertOptions} params
7287 */
7288 const renderInput = (instance, params) => {
7289 const popup = getPopup();
7290 if (!popup) {
7291 return;
7292 }
7293 const innerParams = privateProps.innerParams.get(instance);
7294 const rerender = !innerParams || params.input !== innerParams.input;
7295 inputClasses.forEach(inputClass => {
7296 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
7297 if (!inputContainer) {
7298 return;
7299 }
7300
7301 // set attributes
7302 setAttributes(inputClass, params.inputAttributes);
7303
7304 // set class
7305 inputContainer.className = swalClasses[inputClass];
7306 if (rerender) {
7307 hide(inputContainer);
7308 }
7309 });
7310 if (params.input) {
7311 if (rerender) {
7312 showInput(params);
7313 }
7314 // set custom class
7315 setCustomClass(params);
7316 }
7317 };
7318
7319 /**
7320 * @param {SweetAlertOptions} params
7321 */
7322 const showInput = params => {
7323 if (!params.input) {
7324 return;
7325 }
7326 if (!renderInputType[params.input]) {
7327 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
7328 return;
7329 }
7330 const inputContainer = getInputContainer(params.input);
7331 if (!inputContainer) {
7332 return;
7333 }
7334 const input = renderInputType[params.input](inputContainer, params);
7335 show(inputContainer);
7336
7337 // input autofocus
7338 if (params.inputAutoFocus) {
7339 setTimeout(() => {
7340 focusInput(input);
7341 });
7342 }
7343 };
7344
7345 /**
7346 * @param {HTMLInputElement} input
7347 */
7348 const removeAttributes = input => {
7349 for (let i = 0; i < input.attributes.length; i++) {
7350 const attrName = input.attributes[i].name;
7351 if (!['id', 'type', 'value', 'style'].includes(attrName)) {
7352 input.removeAttribute(attrName);
7353 }
7354 }
7355 };
7356
7357 /**
7358 * @param {InputClass} inputClass
7359 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
7360 */
7361 const setAttributes = (inputClass, inputAttributes) => {
7362 const popup = getPopup();
7363 if (!popup) {
7364 return;
7365 }
7366 const input = getInput$1(popup, inputClass);
7367 if (!input) {
7368 return;
7369 }
7370 removeAttributes(input);
7371 for (const attr in inputAttributes) {
7372 input.setAttribute(attr, inputAttributes[attr]);
7373 }
7374 };
7375
7376 /**
7377 * @param {SweetAlertOptions} params
7378 */
7379 const setCustomClass = params => {
7380 if (!params.input) {
7381 return;
7382 }
7383 const inputContainer = getInputContainer(params.input);
7384 if (inputContainer) {
7385 applyCustomClass(inputContainer, params, 'input');
7386 }
7387 };
7388
7389 /**
7390 * @param {HTMLInputElement | HTMLTextAreaElement} input
7391 * @param {SweetAlertOptions} params
7392 */
7393 const setInputPlaceholder = (input, params) => {
7394 if (!input.placeholder && params.inputPlaceholder) {
7395 input.placeholder = params.inputPlaceholder;
7396 }
7397 };
7398
7399 /**
7400 * @param {Input} input
7401 * @param {Input} prependTo
7402 * @param {SweetAlertOptions} params
7403 */
7404 const setInputLabel = (input, prependTo, params) => {
7405 if (params.inputLabel) {
7406 const label = document.createElement('label');
7407 const labelClass = swalClasses['input-label'];
7408 label.setAttribute('for', input.id);
7409 label.className = labelClass;
7410 if (typeof params.customClass === 'object') {
7411 addClass(label, params.customClass.inputLabel);
7412 }
7413 label.innerText = params.inputLabel;
7414 prependTo.insertAdjacentElement('beforebegin', label);
7415 }
7416 };
7417
7418 /**
7419 * @param {SweetAlertInput} inputType
7420 * @returns {HTMLElement | undefined}
7421 */
7422 const getInputContainer = inputType => {
7423 const popup = getPopup();
7424 if (!popup) {
7425 return;
7426 }
7427 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7428 };
7429
7430 /**
7431 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7432 * @param {SweetAlertOptions['inputValue']} inputValue
7433 */
7434 const checkAndSetInputValue = (input, inputValue) => {
7435 if (['string', 'number'].includes(typeof inputValue)) {
7436 input.value = `${inputValue}`;
7437 } else if (!isPromise(inputValue)) {
7438 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7439 }
7440 };
7441
7442 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7443 const renderInputType = {};
7444
7445 /**
7446 * @param {Input | HTMLElement} input
7447 * @param {SweetAlertOptions} params
7448 * @returns {Input}
7449 */
7450 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} */
7451 (input, params) => {
7452 const inputElement = /** @type {HTMLInputElement} */input;
7453 checkAndSetInputValue(inputElement, params.inputValue);
7454 setInputLabel(inputElement, inputElement, params);
7455 setInputPlaceholder(inputElement, params);
7456 inputElement.type = /** @type {string} */params.input;
7457 return inputElement;
7458 };
7459
7460 /**
7461 * @param {Input | HTMLElement} input
7462 * @param {SweetAlertOptions} params
7463 * @returns {Input}
7464 */
7465 renderInputType.file = (input, params) => {
7466 const inputElement = /** @type {HTMLInputElement} */input;
7467 setInputLabel(inputElement, inputElement, params);
7468 setInputPlaceholder(inputElement, params);
7469 return inputElement;
7470 };
7471
7472 /**
7473 * @param {Input | HTMLElement} range
7474 * @param {SweetAlertOptions} params
7475 * @returns {Input}
7476 */
7477 renderInputType.range = (range, params) => {
7478 const rangeContainer = /** @type {HTMLElement} */range;
7479 const rangeInput = rangeContainer.querySelector('input');
7480 const rangeOutput = rangeContainer.querySelector('output');
7481 if (rangeInput) {
7482 checkAndSetInputValue(rangeInput, params.inputValue);
7483 rangeInput.type = /** @type {string} */params.input;
7484 setInputLabel(rangeInput, /** @type {Input} */range, params);
7485 }
7486 if (rangeOutput) {
7487 checkAndSetInputValue(rangeOutput, params.inputValue);
7488 }
7489 return /** @type {Input} */range;
7490 };
7491
7492 /**
7493 * @param {Input | HTMLElement} select
7494 * @param {SweetAlertOptions} params
7495 * @returns {Input}
7496 */
7497 renderInputType.select = (select, params) => {
7498 const selectElement = /** @type {HTMLSelectElement} */select;
7499 selectElement.textContent = '';
7500 if (params.inputPlaceholder) {
7501 const placeholder = document.createElement('option');
7502 setInnerHtml(placeholder, params.inputPlaceholder);
7503 placeholder.value = '';
7504 placeholder.disabled = true;
7505 placeholder.selected = true;
7506 selectElement.appendChild(placeholder);
7507 }
7508 setInputLabel(selectElement, selectElement, params);
7509 return selectElement;
7510 };
7511
7512 /**
7513 * @param {Input | HTMLElement} radio
7514 * @returns {Input}
7515 */
7516 renderInputType.radio = radio => {
7517 const radioElement = /** @type {HTMLElement} */radio;
7518 radioElement.textContent = '';
7519 return /** @type {Input} */radio;
7520 };
7521
7522 /**
7523 * @param {Input | HTMLElement} checkboxContainer
7524 * @param {SweetAlertOptions} params
7525 * @returns {Input}
7526 */
7527 renderInputType.checkbox = (checkboxContainer, params) => {
7528 const popup = getPopup();
7529 if (!popup) {
7530 throw new Error('Popup not found');
7531 }
7532 const checkbox = getInput$1(popup, 'checkbox');
7533 if (!checkbox) {
7534 throw new Error('Checkbox input not found');
7535 }
7536 checkbox.value = '1';
7537 checkbox.checked = Boolean(params.inputValue);
7538 const containerElement = /** @type {HTMLElement} */checkboxContainer;
7539 const label = containerElement.querySelector('span');
7540 if (label) {
7541 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
7542 if (placeholderOrLabel) {
7543 setInnerHtml(label, placeholderOrLabel);
7544 }
7545 }
7546 return checkbox;
7547 };
7548
7549 /**
7550 * @param {Input | HTMLElement} textarea
7551 * @param {SweetAlertOptions} params
7552 * @returns {Input}
7553 */
7554 renderInputType.textarea = (textarea, params) => {
7555 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
7556 checkAndSetInputValue(textareaElement, params.inputValue);
7557 setInputPlaceholder(textareaElement, params);
7558 setInputLabel(textareaElement, textareaElement, params);
7559
7560 /**
7561 * @param {HTMLElement} el
7562 * @returns {number}
7563 */
7564 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7565
7566 // https://github.com/sweetalert2/sweetalert2/issues/2291
7567 setTimeout(() => {
7568 // https://github.com/sweetalert2/sweetalert2/issues/1699
7569 if ('MutationObserver' in window) {
7570 const popup = getPopup();
7571 if (!popup) {
7572 return;
7573 }
7574 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
7575 const textareaResizeHandler = () => {
7576 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7577 if (!document.body.contains(textareaElement)) {
7578 return;
7579 }
7580 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
7581 const popupElement = getPopup();
7582 if (popupElement) {
7583 if (textareaWidth > initialPopupWidth) {
7584 popupElement.style.width = `${textareaWidth}px`;
7585 } else {
7586 applyNumericalStyle(popupElement, 'width', params.width);
7587 }
7588 }
7589 };
7590 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
7591 attributes: true,
7592 attributeFilter: ['style']
7593 });
7594 }
7595 });
7596 return textareaElement;
7597 };
7598
7599 /**
7600 * @param {SweetAlert} instance
7601 * @param {SweetAlertOptions} params
7602 */
7603 const renderContent = (instance, params) => {
7604 const htmlContainer = getHtmlContainer();
7605 if (!htmlContainer) {
7606 return;
7607 }
7608 showWhenInnerHtmlPresent(htmlContainer);
7609 applyCustomClass(htmlContainer, params, 'htmlContainer');
7610
7611 // Content as HTML
7612 if (params.html) {
7613 parseHtmlToContainer(params.html, htmlContainer);
7614 show(htmlContainer, 'block');
7615 }
7616
7617 // Content as plain text
7618 else if (params.text) {
7619 htmlContainer.textContent = params.text;
7620 show(htmlContainer, 'block');
7621 }
7622
7623 // No content
7624 else {
7625 hide(htmlContainer);
7626 }
7627 renderInput(instance, params);
7628 };
7629
7630 /**
7631 * @param {SweetAlert} instance
7632 * @param {SweetAlertOptions} params
7633 */
7634 const renderFooter = (instance, params) => {
7635 const footer = getFooter();
7636 if (!footer) {
7637 return;
7638 }
7639 showWhenInnerHtmlPresent(footer);
7640 toggle(footer, Boolean(params.footer), 'block');
7641 if (params.footer) {
7642 parseHtmlToContainer(params.footer, footer);
7643 }
7644
7645 // Custom class
7646 applyCustomClass(footer, params, 'footer');
7647 };
7648
7649 /**
7650 * @param {SweetAlert} instance
7651 * @param {SweetAlertOptions} params
7652 */
7653 const renderIcon = (instance, params) => {
7654 const innerParams = privateProps.innerParams.get(instance);
7655 const icon = getIcon();
7656 if (!icon) {
7657 return;
7658 }
7659
7660 // if the given icon already rendered, apply the styling without re-rendering the icon
7661 if (innerParams && params.icon === innerParams.icon) {
7662 // Custom or default content
7663 setContent(icon, params);
7664 applyStyles(icon, params);
7665 return;
7666 }
7667 if (!params.icon && !params.iconHtml) {
7668 hide(icon);
7669 return;
7670 }
7671 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7672 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7673 hide(icon);
7674 return;
7675 }
7676 show(icon);
7677
7678 // Custom or default content
7679 setContent(icon, params);
7680 applyStyles(icon, params);
7681
7682 // Animate icon
7683 addClass(icon, params.showClass && params.showClass.icon);
7684
7685 // Re-adjust the success icon on system theme change
7686 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7687 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7688 };
7689
7690 /**
7691 * @param {HTMLElement} icon
7692 * @param {SweetAlertOptions} params
7693 */
7694 const applyStyles = (icon, params) => {
7695 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7696 if (params.icon !== iconType) {
7697 removeClass(icon, iconClassName);
7698 }
7699 }
7700 addClass(icon, params.icon && iconTypes[params.icon]);
7701
7702 // Icon color
7703 setColor(icon, params);
7704
7705 // Success icon background color
7706 adjustSuccessIconBackgroundColor();
7707
7708 // Custom class
7709 applyCustomClass(icon, params, 'icon');
7710 };
7711
7712 // Adjust success icon background color to match the popup background color
7713 const adjustSuccessIconBackgroundColor = () => {
7714 const popup = getPopup();
7715 if (!popup) {
7716 return;
7717 }
7718 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7719 /** @type {NodeListOf<HTMLElement>} */
7720 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7721 for (let i = 0; i < successIconParts.length; i++) {
7722 successIconParts[i].style.backgroundColor = popupBackgroundColor;
7723 }
7724 };
7725
7726 /**
7727 *
7728 * @param {SweetAlertOptions} params
7729 * @returns {string}
7730 */
7731 const successIconHtml = params => `
7732 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7733 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7734 <div class="swal2-success-ring"></div>
7735 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7736 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7737 `;
7738 const errorIconHtml = `
7739 <span class="swal2-x-mark">
7740 <span class="swal2-x-mark-line-left"></span>
7741 <span class="swal2-x-mark-line-right"></span>
7742 </span>
7743 `;
7744
7745 /**
7746 * @param {HTMLElement} icon
7747 * @param {SweetAlertOptions} params
7748 */
7749 const setContent = (icon, params) => {
7750 if (!params.icon && !params.iconHtml) {
7751 return;
7752 }
7753 let oldContent = icon.innerHTML;
7754 let newContent = '';
7755 if (params.iconHtml) {
7756 newContent = iconContent(params.iconHtml);
7757 } else if (params.icon === 'success') {
7758 newContent = successIconHtml(params);
7759 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7760 } else if (params.icon === 'error') {
7761 newContent = errorIconHtml;
7762 } else if (params.icon) {
7763 const defaultIconHtml = {
7764 question: '?',
7765 warning: '!',
7766 info: 'i'
7767 };
7768 newContent = iconContent(defaultIconHtml[params.icon]);
7769 }
7770 if (oldContent.trim() !== newContent.trim()) {
7771 setInnerHtml(icon, newContent);
7772 }
7773 };
7774
7775 /**
7776 * @param {HTMLElement} icon
7777 * @param {SweetAlertOptions} params
7778 */
7779 const setColor = (icon, params) => {
7780 if (!params.iconColor) {
7781 return;
7782 }
7783 icon.style.color = params.iconColor;
7784 icon.style.borderColor = params.iconColor;
7785 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7786 setStyle(icon, sel, 'background-color', params.iconColor);
7787 }
7788 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7789 };
7790
7791 /**
7792 * @param {string} content
7793 * @returns {string}
7794 */
7795 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7796
7797 /**
7798 * @param {SweetAlert} instance
7799 * @param {SweetAlertOptions} params
7800 */
7801 const renderImage = (instance, params) => {
7802 const image = getImage();
7803 if (!image) {
7804 return;
7805 }
7806 if (!params.imageUrl) {
7807 hide(image);
7808 return;
7809 }
7810 show(image, '');
7811
7812 // Src, alt
7813 image.setAttribute('src', params.imageUrl);
7814 image.setAttribute('alt', params.imageAlt || '');
7815
7816 // Width, height
7817 applyNumericalStyle(image, 'width', params.imageWidth);
7818 applyNumericalStyle(image, 'height', params.imageHeight);
7819
7820 // Class
7821 image.className = swalClasses.image;
7822 applyCustomClass(image, params, 'image');
7823 };
7824
7825 let dragging = false;
7826 let mousedownX = 0;
7827 let mousedownY = 0;
7828 let initialX = 0;
7829 let initialY = 0;
7830
7831 /**
7832 * @param {HTMLElement} popup
7833 */
7834 const addDraggableListeners = popup => {
7835 popup.addEventListener('mousedown', down);
7836 document.body.addEventListener('mousemove', move);
7837 popup.addEventListener('mouseup', up);
7838 popup.addEventListener('touchstart', down);
7839 document.body.addEventListener('touchmove', move);
7840 popup.addEventListener('touchend', up);
7841 };
7842
7843 /**
7844 * @param {HTMLElement} popup
7845 */
7846 const removeDraggableListeners = popup => {
7847 popup.removeEventListener('mousedown', down);
7848 document.body.removeEventListener('mousemove', move);
7849 popup.removeEventListener('mouseup', up);
7850 popup.removeEventListener('touchstart', down);
7851 document.body.removeEventListener('touchmove', move);
7852 popup.removeEventListener('touchend', up);
7853 };
7854
7855 /**
7856 * @param {MouseEvent | TouchEvent} event
7857 */
7858 const down = event => {
7859 const popup = getPopup();
7860 if (!popup) {
7861 return;
7862 }
7863 const icon = getIcon();
7864 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
7865 dragging = true;
7866 const clientXY = getClientXY(event);
7867 mousedownX = clientXY.clientX;
7868 mousedownY = clientXY.clientY;
7869 initialX = parseInt(popup.style.insetInlineStart) || 0;
7870 initialY = parseInt(popup.style.insetBlockStart) || 0;
7871 addClass(popup, 'swal2-dragging');
7872 }
7873 };
7874
7875 /**
7876 * @param {MouseEvent | TouchEvent} event
7877 */
7878 const move = event => {
7879 const popup = getPopup();
7880 if (!popup) {
7881 return;
7882 }
7883 if (dragging) {
7884 let {
7885 clientX,
7886 clientY
7887 } = getClientXY(event);
7888 const deltaX = clientX - mousedownX;
7889 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
7890 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
7891 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7892 }
7893 };
7894 const up = () => {
7895 const popup = getPopup();
7896 dragging = false;
7897 removeClass(popup, 'swal2-dragging');
7898 };
7899
7900 /**
7901 * @param {MouseEvent | TouchEvent} event
7902 * @returns {{ clientX: number, clientY: number }}
7903 */
7904 const getClientXY = event => {
7905 let clientX = 0,
7906 clientY = 0;
7907 if (event.type.startsWith('mouse')) {
7908 clientX = /** @type {MouseEvent} */event.clientX;
7909 clientY = /** @type {MouseEvent} */event.clientY;
7910 } else if (event.type.startsWith('touch')) {
7911 clientX = /** @type {TouchEvent} */event.touches[0].clientX;
7912 clientY = /** @type {TouchEvent} */event.touches[0].clientY;
7913 }
7914 return {
7915 clientX,
7916 clientY
7917 };
7918 };
7919
7920 /**
7921 * @param {SweetAlert} instance
7922 * @param {SweetAlertOptions} params
7923 */
7924 const renderPopup = (instance, params) => {
7925 const container = getContainer();
7926 const popup = getPopup();
7927 if (!container || !popup) {
7928 return;
7929 }
7930
7931 // Width
7932 // https://github.com/sweetalert2/sweetalert2/issues/2170
7933 if (params.toast) {
7934 applyNumericalStyle(container, 'width', params.width);
7935 popup.style.width = '100%';
7936 const loader = getLoader();
7937 if (loader) {
7938 popup.insertBefore(loader, getIcon());
7939 }
7940 } else {
7941 applyNumericalStyle(popup, 'width', params.width);
7942 }
7943
7944 // Padding
7945 applyNumericalStyle(popup, 'padding', params.padding);
7946
7947 // Color
7948 if (params.color) {
7949 popup.style.color = params.color;
7950 }
7951
7952 // Background
7953 if (params.background) {
7954 popup.style.background = params.background;
7955 }
7956 hide(getValidationMessage());
7957
7958 // Classes
7959 addClasses$1(popup, params);
7960 if (params.draggable && !params.toast) {
7961 addClass(popup, swalClasses.draggable);
7962 addDraggableListeners(popup);
7963 } else {
7964 removeClass(popup, swalClasses.draggable);
7965 removeDraggableListeners(popup);
7966 }
7967 };
7968
7969 /**
7970 * @param {HTMLElement} popup
7971 * @param {SweetAlertOptions} params
7972 */
7973 const addClasses$1 = (popup, params) => {
7974 const showClass = params.showClass || {};
7975 // Default Class + showClass when updating Swal.update({})
7976 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7977 if (params.toast) {
7978 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7979 addClass(popup, swalClasses.toast);
7980 } else {
7981 addClass(popup, swalClasses.modal);
7982 }
7983
7984 // Custom class
7985 applyCustomClass(popup, params, 'popup');
7986 // TODO: remove in the next major
7987 if (typeof params.customClass === 'string') {
7988 addClass(popup, params.customClass);
7989 }
7990
7991 // Icon class (#1842)
7992 if (params.icon) {
7993 addClass(popup, swalClasses[`icon-${params.icon}`]);
7994 }
7995 };
7996
7997 /**
7998 * @param {SweetAlert} instance
7999 * @param {SweetAlertOptions} params
8000 */
8001 const renderProgressSteps = (instance, params) => {
8002 const progressStepsContainer = getProgressSteps();
8003 if (!progressStepsContainer) {
8004 return;
8005 }
8006 const {
8007 progressSteps,
8008 currentProgressStep
8009 } = params;
8010 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
8011 hide(progressStepsContainer);
8012 return;
8013 }
8014 show(progressStepsContainer);
8015 progressStepsContainer.textContent = '';
8016 if (currentProgressStep >= progressSteps.length) {
8017 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
8018 }
8019 progressSteps.forEach((step, index) => {
8020 const stepEl = createStepElement(step);
8021 progressStepsContainer.appendChild(stepEl);
8022 if (index === currentProgressStep) {
8023 addClass(stepEl, swalClasses['active-progress-step']);
8024 }
8025 if (index !== progressSteps.length - 1) {
8026 const lineEl = createLineElement(params);
8027 progressStepsContainer.appendChild(lineEl);
8028 }
8029 });
8030 };
8031
8032 /**
8033 * @param {string} step
8034 * @returns {HTMLLIElement}
8035 */
8036 const createStepElement = step => {
8037 const stepEl = document.createElement('li');
8038 addClass(stepEl, swalClasses['progress-step']);
8039 setInnerHtml(stepEl, step);
8040 return stepEl;
8041 };
8042
8043 /**
8044 * @param {SweetAlertOptions} params
8045 * @returns {HTMLLIElement}
8046 */
8047 const createLineElement = params => {
8048 const lineEl = document.createElement('li');
8049 addClass(lineEl, swalClasses['progress-step-line']);
8050 if (params.progressStepsDistance) {
8051 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
8052 }
8053 return lineEl;
8054 };
8055
8056 /**
8057 * @param {SweetAlert} instance
8058 * @param {SweetAlertOptions} params
8059 */
8060 const renderTitle = (instance, params) => {
8061 const title = getTitle();
8062 if (!title) {
8063 return;
8064 }
8065 showWhenInnerHtmlPresent(title);
8066 toggle(title, Boolean(params.title || params.titleText), 'block');
8067 if (params.title) {
8068 parseHtmlToContainer(params.title, title);
8069 }
8070 if (params.titleText) {
8071 title.innerText = params.titleText;
8072 }
8073
8074 // Custom class
8075 applyCustomClass(title, params, 'title');
8076 };
8077
8078 /**
8079 * @param {SweetAlert} instance
8080 * @param {SweetAlertOptions} params
8081 */
8082 const render = (instance, params) => {
8083 var _globalState$eventEmi;
8084 renderPopup(instance, params);
8085 renderContainer(instance, params);
8086 renderProgressSteps(instance, params);
8087 renderIcon(instance, params);
8088 renderImage(instance, params);
8089 renderTitle(instance, params);
8090 renderCloseButton(instance, params);
8091 renderContent(instance, params);
8092 renderActions(instance, params);
8093 renderFooter(instance, params);
8094 const popup = getPopup();
8095 if (typeof params.didRender === 'function' && popup) {
8096 params.didRender(popup);
8097 }
8098 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
8099 };
8100
8101 /*
8102 * Global function to determine if SweetAlert2 popup is shown
8103 */
8104 const isVisible = () => {
8105 return isVisible$1(getPopup());
8106 };
8107
8108 /*
8109 * Global function to click 'Confirm' button
8110 */
8111 const clickConfirm = () => {
8112 var _dom$getConfirmButton;
8113 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
8114 };
8115
8116 /*
8117 * Global function to click 'Deny' button
8118 */
8119 const clickDeny = () => {
8120 var _dom$getDenyButton;
8121 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
8122 };
8123
8124 /*
8125 * Global function to click 'Cancel' button
8126 */
8127 const clickCancel = () => {
8128 var _dom$getCancelButton;
8129 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
8130 };
8131
8132 /** @type {Record<DismissReason, DismissReason>} */
8133 const DismissReason = Object.freeze({
8134 cancel: 'cancel',
8135 backdrop: 'backdrop',
8136 close: 'close',
8137 esc: 'esc',
8138 timer: 'timer'
8139 });
8140
8141 /**
8142 * @param {GlobalState} globalState
8143 */
8144 const removeKeydownHandler = globalState => {
8145 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
8146 const handler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */globalState.keydownHandler;
8147 globalState.keydownTarget.removeEventListener('keydown', handler, {
8148 capture: globalState.keydownListenerCapture
8149 });
8150 globalState.keydownHandlerAdded = false;
8151 }
8152 };
8153
8154 /**
8155 * @param {GlobalState} globalState
8156 * @param {SweetAlertOptions} innerParams
8157 * @param {(dismiss: DismissReason) => void} dismissWith
8158 */
8159 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
8160 removeKeydownHandler(globalState);
8161 if (!innerParams.toast) {
8162 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
8163 const handler = e => keydownHandler(innerParams, e, dismissWith);
8164 globalState.keydownHandler = handler;
8165 const target = innerParams.keydownListenerCapture ? window : getPopup();
8166 if (target) {
8167 globalState.keydownTarget = target;
8168 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
8169 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
8170 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
8171 capture: globalState.keydownListenerCapture
8172 });
8173 globalState.keydownHandlerAdded = true;
8174 }
8175 }
8176 };
8177
8178 /**
8179 * @param {number} index
8180 * @param {number} increment
8181 */
8182 const setFocus = (index, increment) => {
8183 var _dom$getPopup;
8184 const focusableElements = getFocusableElements();
8185 // search for visible elements and select the next possible match
8186 if (focusableElements.length) {
8187 index = index + increment;
8188
8189 // shift + tab when .swal2-popup is focused
8190 if (index === -2) {
8191 index = focusableElements.length - 1;
8192 }
8193
8194 // rollover to first item
8195 if (index === focusableElements.length) {
8196 index = 0;
8197
8198 // go to last item
8199 } else if (index === -1) {
8200 index = focusableElements.length - 1;
8201 }
8202 focusableElements[index].focus();
8203 return;
8204 }
8205 // no visible focusable elements, focus the popup
8206 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
8207 };
8208 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
8209 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
8210
8211 /**
8212 * @param {SweetAlertOptions} innerParams
8213 * @param {KeyboardEvent} event
8214 * @param {(dismiss: DismissReason) => void} dismissWith
8215 */
8216 const keydownHandler = (innerParams, event, dismissWith) => {
8217 if (!innerParams) {
8218 return; // This instance has already been destroyed
8219 }
8220
8221 // Ignore keydown during IME composition
8222 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
8223 // https://github.com/sweetalert2/sweetalert2/issues/720
8224 // https://github.com/sweetalert2/sweetalert2/issues/2406
8225 if (event.isComposing || event.keyCode === 229) {
8226 return;
8227 }
8228 if (innerParams.stopKeydownPropagation) {
8229 event.stopPropagation();
8230 }
8231
8232 // ENTER
8233 if (event.key === 'Enter') {
8234 handleEnter(event, innerParams);
8235 }
8236
8237 // TAB
8238 else if (event.key === 'Tab') {
8239 handleTab(event);
8240 }
8241
8242 // ARROWS - switch focus between buttons
8243 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
8244 handleArrows(event.key);
8245 }
8246
8247 // ESC
8248 else if (event.key === 'Escape') {
8249 handleEsc(event, innerParams, dismissWith);
8250 }
8251 };
8252
8253 /**
8254 * @param {KeyboardEvent} event
8255 * @param {SweetAlertOptions} innerParams
8256 */
8257 const handleEnter = (event, innerParams) => {
8258 // https://github.com/sweetalert2/sweetalert2/issues/2386
8259 if (!callIfFunction(innerParams.allowEnterKey)) {
8260 return;
8261 }
8262 const popup = getPopup();
8263 if (!popup || !innerParams.input) {
8264 return;
8265 }
8266 const input = getInput$1(popup, innerParams.input);
8267 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
8268 if (['textarea', 'file'].includes(innerParams.input)) {
8269 return; // do not submit
8270 }
8271 clickConfirm();
8272 event.preventDefault();
8273 }
8274 };
8275
8276 /**
8277 * @param {KeyboardEvent} event
8278 */
8279 const handleTab = event => {
8280 const targetElement = event.target;
8281 const focusableElements = getFocusableElements();
8282 let btnIndex = -1;
8283 for (let i = 0; i < focusableElements.length; i++) {
8284 if (targetElement === focusableElements[i]) {
8285 btnIndex = i;
8286 break;
8287 }
8288 }
8289
8290 // Cycle to the next button
8291 if (!event.shiftKey) {
8292 setFocus(btnIndex, 1);
8293 }
8294
8295 // Cycle to the prev button
8296 else {
8297 setFocus(btnIndex, -1);
8298 }
8299 event.stopPropagation();
8300 event.preventDefault();
8301 };
8302
8303 /**
8304 * @param {string} key
8305 */
8306 const handleArrows = key => {
8307 const actions = getActions();
8308 const confirmButton = getConfirmButton();
8309 const denyButton = getDenyButton();
8310 const cancelButton = getCancelButton();
8311 if (!actions || !confirmButton || !denyButton || !cancelButton) {
8312 return;
8313 }
8314 /** @type HTMLElement[] */
8315 const buttons = [confirmButton, denyButton, cancelButton];
8316 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
8317 return;
8318 }
8319 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
8320 let buttonToFocus = document.activeElement;
8321 if (!buttonToFocus) {
8322 return;
8323 }
8324 for (let i = 0; i < actions.children.length; i++) {
8325 buttonToFocus = buttonToFocus[sibling];
8326 if (!buttonToFocus) {
8327 return;
8328 }
8329 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
8330 break;
8331 }
8332 }
8333 if (buttonToFocus instanceof HTMLButtonElement) {
8334 buttonToFocus.focus();
8335 }
8336 };
8337
8338 /**
8339 * @param {KeyboardEvent} event
8340 * @param {SweetAlertOptions} innerParams
8341 * @param {(dismiss: DismissReason) => void} dismissWith
8342 */
8343 const handleEsc = (event, innerParams, dismissWith) => {
8344 event.preventDefault();
8345 if (callIfFunction(innerParams.allowEscapeKey)) {
8346 dismissWith(DismissReason.esc);
8347 }
8348 };
8349
8350 /**
8351 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8352 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8353 * This is the approach that Babel will probably take to implement private methods/fields
8354 * https://github.com/tc39/proposal-private-methods
8355 * https://github.com/babel/babel/pull/7555
8356 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8357 * then we can use that language feature.
8358 */
8359
8360 var privateMethods = {
8361 swalPromiseResolve: new WeakMap(),
8362 swalPromiseReject: new WeakMap()
8363 };
8364
8365 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
8366 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
8367 // elements not within the active modal dialog will not be surfaced if a user opens a screen
8368 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
8369
8370 const setAriaHidden = () => {
8371 const container = getContainer();
8372 const bodyChildren = Array.from(document.body.children);
8373 bodyChildren.forEach(el => {
8374 if (el.contains(container)) {
8375 return;
8376 }
8377 if (el.hasAttribute('aria-hidden')) {
8378 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
8379 }
8380 el.setAttribute('aria-hidden', 'true');
8381 });
8382 };
8383 const unsetAriaHidden = () => {
8384 const bodyChildren = Array.from(document.body.children);
8385 bodyChildren.forEach(el => {
8386 if (el.hasAttribute('data-previous-aria-hidden')) {
8387 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
8388 el.removeAttribute('data-previous-aria-hidden');
8389 } else {
8390 el.removeAttribute('aria-hidden');
8391 }
8392 });
8393 };
8394
8395 // @ts-ignore
8396 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
8397
8398 /**
8399 * Fix iOS scrolling
8400 * http://stackoverflow.com/q/39626302
8401 */
8402 const iOSfix = () => {
8403 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
8404 const offset = document.body.scrollTop;
8405 document.body.style.top = `${offset * -1}px`;
8406 addClass(document.body, swalClasses.iosfix);
8407 lockBodyScroll();
8408 }
8409 };
8410
8411 /**
8412 * https://github.com/sweetalert2/sweetalert2/issues/1246
8413 */
8414 const lockBodyScroll = () => {
8415 const container = getContainer();
8416 if (!container) {
8417 return;
8418 }
8419 /** @type {boolean} */
8420 let preventTouchMove;
8421 /**
8422 * @param {TouchEvent} event
8423 */
8424 container.ontouchstart = event => {
8425 preventTouchMove = shouldPreventTouchMove(event);
8426 };
8427 /**
8428 * @param {TouchEvent} event
8429 */
8430 container.ontouchmove = event => {
8431 if (preventTouchMove) {
8432 event.preventDefault();
8433 event.stopPropagation();
8434 }
8435 };
8436 };
8437
8438 /**
8439 * @param {TouchEvent} event
8440 * @returns {boolean}
8441 */
8442 const shouldPreventTouchMove = event => {
8443 const target = event.target;
8444 const container = getContainer();
8445 const htmlContainer = getHtmlContainer();
8446 if (!container || !htmlContainer) {
8447 return false;
8448 }
8449 if (isStylus(event) || isZoom(event)) {
8450 return false;
8451 }
8452 if (target === container) {
8453 return true;
8454 }
8455 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8456 // #2823
8457 target.tagName !== 'INPUT' &&
8458 // #1603
8459 target.tagName !== 'TEXTAREA' &&
8460 // #2266
8461 !(isScrollable(htmlContainer) &&
8462 // #1944
8463 htmlContainer.contains(target))) {
8464 return true;
8465 }
8466 return false;
8467 };
8468
8469 /**
8470 * https://github.com/sweetalert2/sweetalert2/issues/1786
8471 *
8472 * @param {TouchEvent} event
8473 * @returns {boolean}
8474 */
8475 const isStylus = event => {
8476 return Boolean(event.touches && event.touches.length &&
8477 // @ts-ignore - touchType is not a standard property
8478 event.touches[0].touchType === 'stylus');
8479 };
8480
8481 /**
8482 * https://github.com/sweetalert2/sweetalert2/issues/1891
8483 *
8484 * @param {TouchEvent} event
8485 * @returns {boolean}
8486 */
8487 const isZoom = event => {
8488 return event.touches && event.touches.length > 1;
8489 };
8490 const undoIOSfix = () => {
8491 if (hasClass(document.body, swalClasses.iosfix)) {
8492 const offset = parseInt(document.body.style.top, 10);
8493 removeClass(document.body, swalClasses.iosfix);
8494 document.body.style.top = '';
8495 document.body.scrollTop = offset * -1;
8496 }
8497 };
8498
8499 /**
8500 * Measure scrollbar width for padding body during modal show/hide
8501 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8502 *
8503 * @returns {number}
8504 */
8505 const measureScrollbar = () => {
8506 const scrollDiv = document.createElement('div');
8507 scrollDiv.className = swalClasses['scrollbar-measure'];
8508 document.body.appendChild(scrollDiv);
8509 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8510 document.body.removeChild(scrollDiv);
8511 return scrollbarWidth;
8512 };
8513
8514 /**
8515 * Remember state in cases where opening and handling a modal will fiddle with it.
8516 * @type {number | null}
8517 */
8518 let previousBodyPadding = null;
8519
8520 /**
8521 * @param {string} initialBodyOverflow
8522 */
8523 const replaceScrollbarWithPadding = initialBodyOverflow => {
8524 // for queues, do not do this more than once
8525 if (previousBodyPadding !== null) {
8526 return;
8527 }
8528 // if the body has overflow
8529 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8530 ) {
8531 // add padding so the content doesn't shift after removal of scrollbar
8532 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8533 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8534 }
8535 };
8536 const undoReplaceScrollbarWithPadding = () => {
8537 if (previousBodyPadding !== null) {
8538 document.body.style.paddingRight = `${previousBodyPadding}px`;
8539 previousBodyPadding = null;
8540 }
8541 };
8542
8543 /**
8544 * @param {SweetAlert} instance
8545 * @param {HTMLElement} container
8546 * @param {boolean} returnFocus
8547 * @param {(() => void) | undefined} didClose
8548 */
8549 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8550 if (isToast()) {
8551 triggerDidCloseAndDispose(instance, didClose);
8552 } else {
8553 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8554 removeKeydownHandler(globalState);
8555 }
8556
8557 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8558 // for some reason removing the container in Safari will scroll the document to bottom
8559 if (isSafariOrIOS) {
8560 container.setAttribute('style', 'display:none !important');
8561 container.removeAttribute('class');
8562 container.innerHTML = '';
8563 } else {
8564 container.remove();
8565 }
8566 if (isModal()) {
8567 undoReplaceScrollbarWithPadding();
8568 undoIOSfix();
8569 unsetAriaHidden();
8570 }
8571 removeBodyClasses();
8572 }
8573
8574 /**
8575 * Remove SweetAlert2 classes from body
8576 */
8577 function removeBodyClasses() {
8578 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8579 }
8580
8581 /**
8582 * Instance method to close sweetAlert
8583 *
8584 * @param {SweetAlertResult | undefined} resolveValue
8585 * @this {SweetAlert}
8586 */
8587 function close(resolveValue) {
8588 resolveValue = prepareResolveValue(resolveValue);
8589 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8590 const didClose = triggerClosePopup(this);
8591 if (this.isAwaitingPromise) {
8592 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8593 if (!resolveValue.isDismissed) {
8594 handleAwaitingPromise(this);
8595 swalPromiseResolve(resolveValue);
8596 }
8597 } else if (didClose) {
8598 // Resolve Swal promise
8599 swalPromiseResolve(resolveValue);
8600 }
8601 }
8602
8603 /**
8604 * @param {SweetAlert} instance
8605 * @returns {boolean}
8606 */
8607 const triggerClosePopup = instance => {
8608 const popup = getPopup();
8609 if (!popup) {
8610 return false;
8611 }
8612 const innerParams = privateProps.innerParams.get(instance);
8613 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8614 return false;
8615 }
8616 removeClass(popup, innerParams.showClass.popup);
8617 addClass(popup, innerParams.hideClass.popup);
8618 const backdrop = getContainer();
8619 removeClass(backdrop, innerParams.showClass.backdrop);
8620 addClass(backdrop, innerParams.hideClass.backdrop);
8621 handlePopupAnimation(instance, popup, innerParams);
8622 return true;
8623 };
8624
8625 /**
8626 * @param {Error | string} error
8627 * @this {SweetAlert}
8628 */
8629 function rejectPromise(error) {
8630 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8631 handleAwaitingPromise(this);
8632 if (rejectPromise) {
8633 // Reject Swal promise
8634 rejectPromise(error);
8635 }
8636 }
8637
8638 /**
8639 * @param {SweetAlert} instance
8640 */
8641 const handleAwaitingPromise = instance => {
8642 if (instance.isAwaitingPromise) {
8643 // @ts-ignore
8644 delete instance.isAwaitingPromise;
8645 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8646 if (!privateProps.innerParams.get(instance)) {
8647 instance._destroy();
8648 }
8649 }
8650 };
8651
8652 /**
8653 * @param {SweetAlertResult | undefined} resolveValue
8654 * @returns {SweetAlertResult}
8655 */
8656 const prepareResolveValue = resolveValue => {
8657 // When user calls Swal.close()
8658 if (typeof resolveValue === 'undefined') {
8659 return {
8660 isConfirmed: false,
8661 isDenied: false,
8662 isDismissed: true
8663 };
8664 }
8665 return Object.assign({
8666 isConfirmed: false,
8667 isDenied: false,
8668 isDismissed: false
8669 }, resolveValue);
8670 };
8671
8672 /**
8673 * @param {SweetAlert} instance
8674 * @param {HTMLElement} popup
8675 * @param {SweetAlertOptions} innerParams
8676 */
8677 const handlePopupAnimation = (instance, popup, innerParams) => {
8678 var _globalState$eventEmi;
8679 const container = getContainer();
8680 // If animation is supported, animate
8681 const animationIsSupported = hasCssAnimation(popup);
8682 if (typeof innerParams.willClose === 'function') {
8683 innerParams.willClose(popup);
8684 }
8685 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8686 if (animationIsSupported && container) {
8687 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8688 } else if (container) {
8689 // Otherwise, remove immediately
8690 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8691 }
8692 };
8693
8694 /**
8695 * @param {SweetAlert} instance
8696 * @param {HTMLElement} popup
8697 * @param {HTMLElement} container
8698 * @param {boolean} returnFocus
8699 * @param {(() => void) | undefined} didClose
8700 */
8701 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8702 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8703 /**
8704 * @param {AnimationEvent | TransitionEvent} e
8705 */
8706 const swalCloseAnimationFinished = function (e) {
8707 if (e.target === popup) {
8708 var _globalState$swalClos;
8709 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8710 delete globalState.swalCloseEventFinishedCallback;
8711 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8712 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8713 }
8714 };
8715 popup.addEventListener('animationend', swalCloseAnimationFinished);
8716 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8717 };
8718
8719 /**
8720 * @param {SweetAlert} instance
8721 * @param {(() => void) | undefined} didClose
8722 */
8723 const triggerDidCloseAndDispose = (instance, didClose) => {
8724 setTimeout(() => {
8725 var _globalState$eventEmi2;
8726 if (typeof didClose === 'function') {
8727 didClose.bind(instance.params)();
8728 }
8729 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8730 // instance might have been destroyed already
8731 if (instance._destroy) {
8732 instance._destroy();
8733 }
8734 });
8735 };
8736
8737 /**
8738 * Shows loader (spinner), this is useful with AJAX requests.
8739 * By default the loader be shown instead of the "Confirm" button.
8740 *
8741 * @param {HTMLButtonElement | null} [buttonToReplace]
8742 */
8743 const showLoading = buttonToReplace => {
8744 let popup = getPopup();
8745 if (!popup) {
8746 new Swal();
8747 }
8748 popup = getPopup();
8749 if (!popup) {
8750 return;
8751 }
8752 const loader = getLoader();
8753 if (isToast()) {
8754 hide(getIcon());
8755 } else {
8756 replaceButton(popup, buttonToReplace);
8757 }
8758 show(loader);
8759 popup.setAttribute('data-loading', 'true');
8760 popup.setAttribute('aria-busy', 'true');
8761 popup.focus();
8762 };
8763
8764 /**
8765 * @param {HTMLElement} popup
8766 * @param {HTMLButtonElement | null} [buttonToReplace]
8767 */
8768 const replaceButton = (popup, buttonToReplace) => {
8769 const actions = getActions();
8770 const loader = getLoader();
8771 if (!actions || !loader) {
8772 return;
8773 }
8774 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8775 buttonToReplace = getConfirmButton();
8776 }
8777 show(actions);
8778 if (buttonToReplace) {
8779 hide(buttonToReplace);
8780 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8781 actions.insertBefore(loader, buttonToReplace);
8782 }
8783 addClass([popup, actions], swalClasses.loading);
8784 };
8785
8786 /**
8787 * @param {SweetAlert} instance
8788 * @param {SweetAlertOptions} params
8789 */
8790 const handleInputOptionsAndValue = (instance, params) => {
8791 if (params.input === 'select' || params.input === 'radio') {
8792 handleInputOptions(instance, params);
8793 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8794 showLoading(getConfirmButton());
8795 handleInputValue(instance, params);
8796 }
8797 };
8798
8799 /**
8800 * @param {SweetAlert} instance
8801 * @param {SweetAlertOptions} innerParams
8802 * @returns {SweetAlertInputValue}
8803 */
8804 const getInputValue = (instance, innerParams) => {
8805 const input = instance.getInput();
8806 if (!input) {
8807 return null;
8808 }
8809 switch (innerParams.input) {
8810 case 'checkbox':
8811 return getCheckboxValue(input);
8812 case 'radio':
8813 return getRadioValue(input);
8814 case 'file':
8815 return getFileValue(input);
8816 default:
8817 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8818 }
8819 };
8820
8821 /**
8822 * @param {HTMLInputElement} input
8823 * @returns {number}
8824 */
8825 const getCheckboxValue = input => input.checked ? 1 : 0;
8826
8827 /**
8828 * @param {HTMLInputElement} input
8829 * @returns {string | null}
8830 */
8831 const getRadioValue = input => input.checked ? input.value : null;
8832
8833 /**
8834 * @param {HTMLInputElement} input
8835 * @returns {FileList | File | null}
8836 */
8837 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8838
8839 /**
8840 * @param {SweetAlert} instance
8841 * @param {SweetAlertOptions} params
8842 */
8843 const handleInputOptions = (instance, params) => {
8844 const popup = getPopup();
8845 if (!popup) {
8846 return;
8847 }
8848 /**
8849 * @param {*} inputOptions
8850 */
8851 const processInputOptions = inputOptions => {
8852 if (params.input === 'select') {
8853 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8854 } else if (params.input === 'radio') {
8855 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8856 }
8857 };
8858 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8859 showLoading(getConfirmButton());
8860 asPromise(params.inputOptions).then(inputOptions => {
8861 instance.hideLoading();
8862 processInputOptions(inputOptions);
8863 });
8864 } else if (typeof params.inputOptions === 'object') {
8865 processInputOptions(params.inputOptions);
8866 } else {
8867 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8868 }
8869 };
8870
8871 /**
8872 * @param {SweetAlert} instance
8873 * @param {SweetAlertOptions} params
8874 */
8875 const handleInputValue = (instance, params) => {
8876 const input = instance.getInput();
8877 if (!input) {
8878 return;
8879 }
8880 hide(input);
8881 asPromise(params.inputValue).then(inputValue => {
8882 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8883 show(input);
8884 input.focus();
8885 instance.hideLoading();
8886 }).catch(err => {
8887 error(`Error in inputValue promise: ${err}`);
8888 input.value = '';
8889 show(input);
8890 input.focus();
8891 instance.hideLoading();
8892 });
8893 };
8894
8895 /**
8896 * @param {HTMLElement} popup
8897 * @param {InputOptionFlattened[]} inputOptions
8898 * @param {SweetAlertOptions} params
8899 */
8900 function populateSelectOptions(popup, inputOptions, params) {
8901 const select = getDirectChildByClass(popup, swalClasses.select);
8902 if (!select) {
8903 return;
8904 }
8905 /**
8906 * @param {HTMLElement} parent
8907 * @param {string} optionLabel
8908 * @param {string} optionValue
8909 */
8910 const renderOption = (parent, optionLabel, optionValue) => {
8911 const option = document.createElement('option');
8912 option.value = optionValue;
8913 setInnerHtml(option, optionLabel);
8914 option.selected = isSelected(optionValue, params.inputValue);
8915 parent.appendChild(option);
8916 };
8917 inputOptions.forEach(inputOption => {
8918 const optionValue = inputOption[0];
8919 const optionLabel = inputOption[1];
8920 // <optgroup> spec:
8921 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8922 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8923 // check whether this is a <optgroup>
8924 if (Array.isArray(optionLabel)) {
8925 // if it is an array, then it is an <optgroup>
8926 const optgroup = document.createElement('optgroup');
8927 optgroup.label = optionValue;
8928 optgroup.disabled = false; // not configurable for now
8929 select.appendChild(optgroup);
8930 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8931 } else {
8932 // case of <option>
8933 renderOption(select, optionLabel, optionValue);
8934 }
8935 });
8936 select.focus();
8937 }
8938
8939 /**
8940 * @param {HTMLElement} popup
8941 * @param {InputOptionFlattened[]} inputOptions
8942 * @param {SweetAlertOptions} params
8943 */
8944 function populateRadioOptions(popup, inputOptions, params) {
8945 const radio = getDirectChildByClass(popup, swalClasses.radio);
8946 if (!radio) {
8947 return;
8948 }
8949 inputOptions.forEach(inputOption => {
8950 const radioValue = inputOption[0];
8951 const radioLabel = inputOption[1];
8952 const radioInput = document.createElement('input');
8953 const radioLabelElement = document.createElement('label');
8954 radioInput.type = 'radio';
8955 radioInput.name = swalClasses.radio;
8956 radioInput.value = radioValue;
8957 if (isSelected(radioValue, params.inputValue)) {
8958 radioInput.checked = true;
8959 }
8960 const label = document.createElement('span');
8961 setInnerHtml(label, radioLabel);
8962 label.className = swalClasses.label;
8963 radioLabelElement.appendChild(radioInput);
8964 radioLabelElement.appendChild(label);
8965 radio.appendChild(radioLabelElement);
8966 });
8967 const radios = radio.querySelectorAll('input');
8968 if (radios.length) {
8969 radios[0].focus();
8970 }
8971 }
8972
8973 /**
8974 * Converts `inputOptions` into an array of `[value, label]`s
8975 *
8976 * @param {*} inputOptions
8977 * @typedef {string[]} InputOptionFlattened
8978 * @returns {InputOptionFlattened[]}
8979 */
8980 const formatInputOptions = inputOptions => {
8981 /** @type {InputOptionFlattened[]} */
8982 const result = [];
8983 if (inputOptions instanceof Map) {
8984 inputOptions.forEach((value, key) => {
8985 let valueFormatted = value;
8986 if (typeof valueFormatted === 'object') {
8987 // case of <optgroup>
8988 valueFormatted = formatInputOptions(valueFormatted);
8989 }
8990 result.push([key, valueFormatted]);
8991 });
8992 } else {
8993 Object.keys(inputOptions).forEach(key => {
8994 let valueFormatted = inputOptions[key];
8995 if (typeof valueFormatted === 'object') {
8996 // case of <optgroup>
8997 valueFormatted = formatInputOptions(valueFormatted);
8998 }
8999 result.push([key, valueFormatted]);
9000 });
9001 }
9002 return result;
9003 };
9004
9005 /**
9006 * @param {string} optionValue
9007 * @param {SweetAlertInputValue} inputValue
9008 * @returns {boolean}
9009 */
9010 const isSelected = (optionValue, inputValue) => {
9011 return Boolean(inputValue) && inputValue !== null && inputValue !== undefined && inputValue.toString() === optionValue.toString();
9012 };
9013
9014 /**
9015 * @param {SweetAlert} instance
9016 */
9017 const handleConfirmButtonClick = instance => {
9018 const innerParams = privateProps.innerParams.get(instance);
9019 instance.disableButtons();
9020 if (innerParams.input) {
9021 handleConfirmOrDenyWithInput(instance, 'confirm');
9022 } else {
9023 confirm(instance, true);
9024 }
9025 };
9026
9027 /**
9028 * @param {SweetAlert} instance
9029 */
9030 const handleDenyButtonClick = instance => {
9031 const innerParams = privateProps.innerParams.get(instance);
9032 instance.disableButtons();
9033 if (innerParams.returnInputValueOnDeny) {
9034 handleConfirmOrDenyWithInput(instance, 'deny');
9035 } else {
9036 deny(instance, false);
9037 }
9038 };
9039
9040 /**
9041 * @param {SweetAlert} instance
9042 * @param {(dismiss: DismissReason) => void} dismissWith
9043 */
9044 const handleCancelButtonClick = (instance, dismissWith) => {
9045 instance.disableButtons();
9046 dismissWith(DismissReason.cancel);
9047 };
9048
9049 /**
9050 * @param {SweetAlert} instance
9051 * @param {'confirm' | 'deny'} type
9052 */
9053 const handleConfirmOrDenyWithInput = (instance, type) => {
9054 const innerParams = privateProps.innerParams.get(instance);
9055 if (!innerParams.input) {
9056 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
9057 return;
9058 }
9059 const input = instance.getInput();
9060 const inputValue = getInputValue(instance, innerParams);
9061 if (innerParams.inputValidator) {
9062 handleInputValidator(instance, inputValue, type);
9063 } else if (input && !input.checkValidity()) {
9064 instance.enableButtons();
9065 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
9066 } else if (type === 'deny') {
9067 deny(instance, inputValue);
9068 } else {
9069 confirm(instance, inputValue);
9070 }
9071 };
9072
9073 /**
9074 * @param {SweetAlert} instance
9075 * @param {SweetAlertInputValue} inputValue
9076 * @param {'confirm' | 'deny'} type
9077 */
9078 const handleInputValidator = (instance, inputValue, type) => {
9079 const innerParams = privateProps.innerParams.get(instance);
9080 instance.disableInput();
9081 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
9082 validationPromise.then(validationMessage => {
9083 instance.enableButtons();
9084 instance.enableInput();
9085 if (validationMessage) {
9086 instance.showValidationMessage(validationMessage);
9087 } else if (type === 'deny') {
9088 deny(instance, inputValue);
9089 } else {
9090 confirm(instance, inputValue);
9091 }
9092 });
9093 };
9094
9095 /**
9096 * @param {SweetAlert} instance
9097 * @param {*} value
9098 */
9099 const deny = (instance, value) => {
9100 const innerParams = privateProps.innerParams.get(instance);
9101 if (innerParams.showLoaderOnDeny) {
9102 showLoading(getDenyButton());
9103 }
9104 if (innerParams.preDeny) {
9105 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
9106 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
9107 preDenyPromise.then(preDenyValue => {
9108 if (preDenyValue === false) {
9109 instance.hideLoading();
9110 handleAwaitingPromise(instance);
9111 } else {
9112 instance.close(/** @type SweetAlertResult */{
9113 isDenied: true,
9114 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
9115 });
9116 }
9117 }).catch(error => rejectWith(instance, error));
9118 } else {
9119 instance.close(/** @type SweetAlertResult */{
9120 isDenied: true,
9121 value
9122 });
9123 }
9124 };
9125
9126 /**
9127 * @param {SweetAlert} instance
9128 * @param {*} value
9129 */
9130 const succeedWith = (instance, value) => {
9131 instance.close(/** @type SweetAlertResult */{
9132 isConfirmed: true,
9133 value
9134 });
9135 };
9136
9137 /**
9138 *
9139 * @param {SweetAlert} instance
9140 * @param {string} error
9141 */
9142 const rejectWith = (instance, error) => {
9143 instance.rejectPromise(error);
9144 };
9145
9146 /**
9147 *
9148 * @param {SweetAlert} instance
9149 * @param {*} value
9150 */
9151 const confirm = (instance, value) => {
9152 const innerParams = privateProps.innerParams.get(instance);
9153 if (innerParams.showLoaderOnConfirm) {
9154 showLoading();
9155 }
9156 if (innerParams.preConfirm) {
9157 instance.resetValidationMessage();
9158 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
9159 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
9160 preConfirmPromise.then(preConfirmValue => {
9161 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
9162 instance.hideLoading();
9163 handleAwaitingPromise(instance);
9164 } else {
9165 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
9166 }
9167 }).catch(error => rejectWith(instance, error));
9168 } else {
9169 succeedWith(instance, value);
9170 }
9171 };
9172
9173 /**
9174 * Hides loader and shows back the button which was hidden by .showLoading()
9175 * @this {SweetAlert}
9176 */
9177 function hideLoading() {
9178 // do nothing if popup is closed
9179 const innerParams = privateProps.innerParams.get(this);
9180 if (!innerParams) {
9181 return;
9182 }
9183 const domCache = privateProps.domCache.get(this);
9184 hide(domCache.loader);
9185 if (isToast()) {
9186 if (innerParams.icon) {
9187 show(getIcon());
9188 }
9189 } else {
9190 showRelatedButton(domCache);
9191 }
9192 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
9193 domCache.popup.removeAttribute('aria-busy');
9194 domCache.popup.removeAttribute('data-loading');
9195 domCache.confirmButton.disabled = false;
9196 domCache.denyButton.disabled = false;
9197 domCache.cancelButton.disabled = false;
9198 }
9199
9200 /**
9201 * @param {DomCache} domCache
9202 */
9203 const showRelatedButton = domCache => {
9204 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
9205 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
9206 if (buttonToReplace.length) {
9207 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
9208 } else if (allButtonsAreHidden()) {
9209 hide(domCache.actions);
9210 }
9211 };
9212
9213 /**
9214 * Gets the input DOM node, this method works with input parameter.
9215 *
9216 * @returns {HTMLInputElement | null}
9217 * @this {SweetAlert}
9218 */
9219 function getInput() {
9220 const innerParams = privateProps.innerParams.get(this);
9221 const domCache = privateProps.domCache.get(this);
9222 if (!domCache) {
9223 return null;
9224 }
9225 return getInput$1(domCache.popup, innerParams.input);
9226 }
9227
9228 /**
9229 * @param {SweetAlert} instance
9230 * @param {string[]} buttons
9231 * @param {boolean} disabled
9232 */
9233 function setButtonsDisabled(instance, buttons, disabled) {
9234 const domCache = privateProps.domCache.get(instance);
9235 buttons.forEach(button => {
9236 domCache[button].disabled = disabled;
9237 });
9238 }
9239
9240 /**
9241 * @param {HTMLInputElement | null} input
9242 * @param {boolean} disabled
9243 */
9244 function setInputDisabled(input, disabled) {
9245 const popup = getPopup();
9246 if (!popup || !input) {
9247 return;
9248 }
9249 if (input.type === 'radio') {
9250 /** @type {NodeListOf<HTMLInputElement>} */
9251 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
9252 for (let i = 0; i < radios.length; i++) {
9253 radios[i].disabled = disabled;
9254 }
9255 } else {
9256 input.disabled = disabled;
9257 }
9258 }
9259
9260 /**
9261 * Enable all the buttons
9262 * @this {SweetAlert}
9263 */
9264 function enableButtons() {
9265 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
9266 }
9267
9268 /**
9269 * Disable all the buttons
9270 * @this {SweetAlert}
9271 */
9272 function disableButtons() {
9273 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
9274 }
9275
9276 /**
9277 * Enable the input field
9278 * @this {SweetAlert}
9279 */
9280 function enableInput() {
9281 setInputDisabled(this.getInput(), false);
9282 }
9283
9284 /**
9285 * Disable the input field
9286 * @this {SweetAlert}
9287 */
9288 function disableInput() {
9289 setInputDisabled(this.getInput(), true);
9290 }
9291
9292 /**
9293 * Show block with validation message
9294 *
9295 * @param {string} error
9296 * @this {SweetAlert}
9297 */
9298 function showValidationMessage(error) {
9299 const domCache = privateProps.domCache.get(this);
9300 const params = privateProps.innerParams.get(this);
9301 setInnerHtml(domCache.validationMessage, error);
9302 domCache.validationMessage.className = swalClasses['validation-message'];
9303 if (params.customClass && params.customClass.validationMessage) {
9304 addClass(domCache.validationMessage, params.customClass.validationMessage);
9305 }
9306 show(domCache.validationMessage);
9307 const input = this.getInput();
9308 if (input) {
9309 input.setAttribute('aria-invalid', 'true');
9310 input.setAttribute('aria-describedby', swalClasses['validation-message']);
9311 focusInput(input);
9312 addClass(input, swalClasses.inputerror);
9313 }
9314 }
9315
9316 /**
9317 * Hide block with validation message
9318 *
9319 * @this {SweetAlert}
9320 */
9321 function resetValidationMessage() {
9322 const domCache = privateProps.domCache.get(this);
9323 if (domCache.validationMessage) {
9324 hide(domCache.validationMessage);
9325 }
9326 const input = this.getInput();
9327 if (input) {
9328 input.removeAttribute('aria-invalid');
9329 input.removeAttribute('aria-describedby');
9330 removeClass(input, swalClasses.inputerror);
9331 }
9332 }
9333
9334 const defaultParams = {
9335 title: '',
9336 titleText: '',
9337 text: '',
9338 html: '',
9339 footer: '',
9340 icon: undefined,
9341 iconColor: undefined,
9342 iconHtml: undefined,
9343 template: undefined,
9344 toast: false,
9345 draggable: false,
9346 animation: true,
9347 theme: 'light',
9348 showClass: {
9349 popup: 'swal2-show',
9350 backdrop: 'swal2-backdrop-show',
9351 icon: 'swal2-icon-show'
9352 },
9353 hideClass: {
9354 popup: 'swal2-hide',
9355 backdrop: 'swal2-backdrop-hide',
9356 icon: 'swal2-icon-hide'
9357 },
9358 customClass: {},
9359 target: 'body',
9360 color: undefined,
9361 backdrop: true,
9362 heightAuto: true,
9363 allowOutsideClick: true,
9364 allowEscapeKey: true,
9365 allowEnterKey: true,
9366 stopKeydownPropagation: true,
9367 keydownListenerCapture: false,
9368 showConfirmButton: true,
9369 showDenyButton: false,
9370 showCancelButton: false,
9371 preConfirm: undefined,
9372 preDeny: undefined,
9373 confirmButtonText: 'OK',
9374 confirmButtonAriaLabel: '',
9375 confirmButtonColor: undefined,
9376 denyButtonText: 'No',
9377 denyButtonAriaLabel: '',
9378 denyButtonColor: undefined,
9379 cancelButtonText: 'Cancel',
9380 cancelButtonAriaLabel: '',
9381 cancelButtonColor: undefined,
9382 buttonsStyling: true,
9383 reverseButtons: false,
9384 focusConfirm: true,
9385 focusDeny: false,
9386 focusCancel: false,
9387 returnFocus: true,
9388 showCloseButton: false,
9389 closeButtonHtml: '&times;',
9390 closeButtonAriaLabel: 'Close this dialog',
9391 loaderHtml: '',
9392 showLoaderOnConfirm: false,
9393 showLoaderOnDeny: false,
9394 imageUrl: undefined,
9395 imageWidth: undefined,
9396 imageHeight: undefined,
9397 imageAlt: '',
9398 timer: undefined,
9399 timerProgressBar: false,
9400 width: undefined,
9401 padding: undefined,
9402 background: undefined,
9403 input: undefined,
9404 inputPlaceholder: '',
9405 inputLabel: '',
9406 inputValue: '',
9407 inputOptions: {},
9408 inputAutoFocus: true,
9409 inputAutoTrim: true,
9410 inputAttributes: {},
9411 inputValidator: undefined,
9412 returnInputValueOnDeny: false,
9413 validationMessage: undefined,
9414 grow: false,
9415 position: 'center',
9416 progressSteps: [],
9417 currentProgressStep: undefined,
9418 progressStepsDistance: undefined,
9419 willOpen: undefined,
9420 didOpen: undefined,
9421 didRender: undefined,
9422 willClose: undefined,
9423 didClose: undefined,
9424 didDestroy: undefined,
9425 scrollbarPadding: true,
9426 topLayer: false
9427 };
9428 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'];
9429
9430 /** @type {Record<string, string | undefined>} */
9431 const deprecatedParams = {
9432 allowEnterKey: undefined
9433 };
9434 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9435
9436 /**
9437 * Is valid parameter
9438 *
9439 * @param {string} paramName
9440 * @returns {boolean}
9441 */
9442 const isValidParameter = paramName => {
9443 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9444 };
9445
9446 /**
9447 * Is valid parameter for Swal.update() method
9448 *
9449 * @param {string} paramName
9450 * @returns {boolean}
9451 */
9452 const isUpdatableParameter = paramName => {
9453 return updatableParams.indexOf(paramName) !== -1;
9454 };
9455
9456 /**
9457 * Is deprecated parameter
9458 *
9459 * @param {string} paramName
9460 * @returns {string | undefined}
9461 */
9462 const isDeprecatedParameter = paramName => {
9463 return deprecatedParams[paramName];
9464 };
9465
9466 /**
9467 * @param {string} param
9468 */
9469 const checkIfParamIsValid = param => {
9470 if (!isValidParameter(param)) {
9471 warn(`Unknown parameter "${param}"`);
9472 }
9473 };
9474
9475 /**
9476 * @param {string} param
9477 */
9478 const checkIfToastParamIsValid = param => {
9479 if (toastIncompatibleParams.includes(param)) {
9480 warn(`The parameter "${param}" is incompatible with toasts`);
9481 }
9482 };
9483
9484 /**
9485 * @param {string} param
9486 */
9487 const checkIfParamIsDeprecated = param => {
9488 const isDeprecated = isDeprecatedParameter(param);
9489 if (isDeprecated) {
9490 warnAboutDeprecation(param, isDeprecated);
9491 }
9492 };
9493
9494 /**
9495 * Show relevant warnings for given params
9496 *
9497 * @param {SweetAlertOptions} params
9498 */
9499 const showWarningsForParams = params => {
9500 if (params.backdrop === false && params.allowOutsideClick) {
9501 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9502 }
9503 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)) {
9504 warn(`Invalid theme "${params.theme}"`);
9505 }
9506 for (const param in params) {
9507 checkIfParamIsValid(param);
9508 if (params.toast) {
9509 checkIfToastParamIsValid(param);
9510 }
9511 checkIfParamIsDeprecated(param);
9512 }
9513 };
9514
9515 /**
9516 * Updates popup parameters.
9517 *
9518 * @this {any}
9519 * @param {SweetAlertOptions} params
9520 */
9521 function update(params) {
9522 const container = getContainer();
9523 const popup = getPopup();
9524 const innerParams = privateProps.innerParams.get(this);
9525 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9526 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.`);
9527 return;
9528 }
9529 const validUpdatableParams = filterValidParams(params);
9530 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9531 showWarningsForParams(updatedParams);
9532 if (container) {
9533 container.dataset['swal2Theme'] = updatedParams.theme;
9534 }
9535 render(this, updatedParams);
9536 privateProps.innerParams.set(this, updatedParams);
9537 Object.defineProperties(this, {
9538 params: {
9539 value: Object.assign({}, this.params, params),
9540 writable: false,
9541 enumerable: true
9542 }
9543 });
9544 }
9545
9546 /**
9547 * @param {SweetAlertOptions} params
9548 * @returns {SweetAlertOptions}
9549 */
9550 const filterValidParams = params => {
9551 /** @type {Record<string, any>} */
9552 const validUpdatableParams = {};
9553 Object.keys(params).forEach(param => {
9554 if (isUpdatableParameter(param)) {
9555 const typedParams = /** @type {Record<string, any>} */params;
9556 validUpdatableParams[param] = typedParams[param];
9557 } else {
9558 warn(`Invalid parameter to update: ${param}`);
9559 }
9560 });
9561 return validUpdatableParams;
9562 };
9563
9564 /**
9565 * Dispose the current SweetAlert2 instance
9566 * @this {SweetAlert}
9567 */
9568 function _destroy() {
9569 var _globalState$eventEmi;
9570 const domCache = privateProps.domCache.get(this);
9571 const innerParams = privateProps.innerParams.get(this);
9572 if (!innerParams) {
9573 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9574 return; // This instance has already been destroyed
9575 }
9576
9577 // Check if there is another Swal closing
9578 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9579 globalState.swalCloseEventFinishedCallback();
9580 delete globalState.swalCloseEventFinishedCallback;
9581 }
9582 if (typeof innerParams.didDestroy === 'function') {
9583 innerParams.didDestroy();
9584 }
9585 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
9586 disposeSwal(this);
9587 }
9588
9589 /**
9590 * @param {SweetAlert} instance
9591 */
9592 const disposeSwal = instance => {
9593 disposeWeakMaps(instance);
9594 // Unset this.params so GC will dispose it (#1569)
9595 // @ts-ignore
9596 delete instance.params;
9597 // Unset globalState props so GC will dispose globalState (#1569)
9598 delete globalState.keydownHandler;
9599 delete globalState.keydownTarget;
9600 // Unset currentInstance
9601 delete globalState.currentInstance;
9602 };
9603
9604 /**
9605 * @param {SweetAlert} instance
9606 */
9607 const disposeWeakMaps = instance => {
9608 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9609 if (instance.isAwaitingPromise) {
9610 unsetWeakMaps(privateProps, instance);
9611 instance.isAwaitingPromise = true;
9612 } else {
9613 unsetWeakMaps(privateMethods, instance);
9614 unsetWeakMaps(privateProps, instance);
9615
9616 // @ts-ignore
9617 delete instance.isAwaitingPromise;
9618 // Unset instance methods
9619 // @ts-ignore
9620 delete instance.disableButtons;
9621 // @ts-ignore
9622 delete instance.enableButtons;
9623 // @ts-ignore
9624 delete instance.getInput;
9625 // @ts-ignore
9626 delete instance.disableInput;
9627 // @ts-ignore
9628 delete instance.enableInput;
9629 // @ts-ignore
9630 delete instance.hideLoading;
9631 // @ts-ignore
9632 delete instance.disableLoading;
9633 // @ts-ignore
9634 delete instance.showValidationMessage;
9635 // @ts-ignore
9636 delete instance.resetValidationMessage;
9637 // @ts-ignore
9638 delete instance.close;
9639 // @ts-ignore
9640 delete instance.closePopup;
9641 // @ts-ignore
9642 delete instance.closeModal;
9643 // @ts-ignore
9644 delete instance.closeToast;
9645 // @ts-ignore
9646 delete instance.rejectPromise;
9647 // @ts-ignore
9648 delete instance.update;
9649 // @ts-ignore
9650 delete instance._destroy;
9651 }
9652 };
9653
9654 /**
9655 * @param {Record<string, WeakMap<any, any>>} obj
9656 * @param {SweetAlert} instance
9657 */
9658 const unsetWeakMaps = (obj, instance) => {
9659 for (const i in obj) {
9660 obj[i].delete(instance);
9661 }
9662 };
9663
9664 var instanceMethods = /*#__PURE__*/Object.freeze({
9665 __proto__: null,
9666 _destroy: _destroy,
9667 close: close,
9668 closeModal: close,
9669 closePopup: close,
9670 closeToast: close,
9671 disableButtons: disableButtons,
9672 disableInput: disableInput,
9673 disableLoading: hideLoading,
9674 enableButtons: enableButtons,
9675 enableInput: enableInput,
9676 getInput: getInput,
9677 handleAwaitingPromise: handleAwaitingPromise,
9678 hideLoading: hideLoading,
9679 rejectPromise: rejectPromise,
9680 resetValidationMessage: resetValidationMessage,
9681 showValidationMessage: showValidationMessage,
9682 update: update
9683 });
9684
9685 /**
9686 * @param {SweetAlertOptions} innerParams
9687 * @param {DomCache} domCache
9688 * @param {(dismiss: DismissReason) => void} dismissWith
9689 */
9690 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9691 if (innerParams.toast) {
9692 handleToastClick(innerParams, domCache, dismissWith);
9693 } else {
9694 // Ignore click events that had mousedown on the popup but mouseup on the container
9695 // This can happen when the user drags a slider
9696 handleModalMousedown(domCache);
9697
9698 // Ignore click events that had mousedown on the container but mouseup on the popup
9699 handleContainerMousedown(domCache);
9700 handleModalClick(innerParams, domCache, dismissWith);
9701 }
9702 };
9703
9704 /**
9705 * @param {SweetAlertOptions} innerParams
9706 * @param {DomCache} domCache
9707 * @param {(dismiss: DismissReason) => void} dismissWith
9708 */
9709 const handleToastClick = (innerParams, domCache, dismissWith) => {
9710 // Closing toast by internal click
9711 domCache.popup.onclick = () => {
9712 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9713 return;
9714 }
9715 dismissWith(DismissReason.close);
9716 };
9717 };
9718
9719 /**
9720 * @param {SweetAlertOptions} innerParams
9721 * @returns {boolean}
9722 */
9723 const isAnyButtonShown = innerParams => {
9724 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9725 };
9726 let ignoreOutsideClick = false;
9727
9728 /**
9729 * @param {DomCache} domCache
9730 */
9731 const handleModalMousedown = domCache => {
9732 domCache.popup.onmousedown = () => {
9733 domCache.container.onmouseup = function (e) {
9734 domCache.container.onmouseup = () => {};
9735 // We only check if the mouseup target is the container because usually it doesn't
9736 // have any other direct children aside of the popup
9737 if (e.target === domCache.container) {
9738 ignoreOutsideClick = true;
9739 }
9740 };
9741 };
9742 };
9743
9744 /**
9745 * @param {DomCache} domCache
9746 */
9747 const handleContainerMousedown = domCache => {
9748 domCache.container.onmousedown = e => {
9749 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9750 if (e.target === domCache.container) {
9751 e.preventDefault();
9752 }
9753 domCache.popup.onmouseup = function (e) {
9754 domCache.popup.onmouseup = () => {};
9755 // We also need to check if the mouseup target is a child of the popup
9756 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9757 ignoreOutsideClick = true;
9758 }
9759 };
9760 };
9761 };
9762
9763 /**
9764 * @param {SweetAlertOptions} innerParams
9765 * @param {DomCache} domCache
9766 * @param {(dismiss: DismissReason) => void} dismissWith
9767 */
9768 const handleModalClick = (innerParams, domCache, dismissWith) => {
9769 domCache.container.onclick = e => {
9770 if (ignoreOutsideClick) {
9771 ignoreOutsideClick = false;
9772 return;
9773 }
9774 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9775 dismissWith(DismissReason.backdrop);
9776 }
9777 };
9778 };
9779
9780 /**
9781 * @param {any} elem
9782 * @returns {boolean}
9783 */
9784 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
9785
9786 /**
9787 * @param {any} elem
9788 * @returns {boolean}
9789 */
9790 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9791
9792 /**
9793 * @param {any[]} args
9794 * @returns {SweetAlertOptions}
9795 */
9796 const argsToParams = args => {
9797 /** @type {Record<string, any>} */
9798 const params = {};
9799 if (typeof args[0] === 'object' && !isElement(args[0])) {
9800 Object.assign(params, args[0]);
9801 } else {
9802 ['title', 'html', 'icon'].forEach((name, index) => {
9803 const arg = args[index];
9804 if (typeof arg === 'string' || isElement(arg)) {
9805 params[name] = arg;
9806 } else if (arg !== undefined) {
9807 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9808 }
9809 });
9810 }
9811 return params;
9812 };
9813
9814 /**
9815 * Main method to create a new SweetAlert2 popup
9816 *
9817 * @this {new (...args: any[]) => any}
9818 * @param {...SweetAlertOptions} args
9819 * @returns {Promise<SweetAlertResult>}
9820 */
9821 function fire(...args) {
9822 return new this(...args);
9823 }
9824
9825 /**
9826 * Returns an extended version of `Swal` containing `params` as defaults.
9827 * Useful for reusing Swal configuration.
9828 *
9829 * For example:
9830 *
9831 * Before:
9832 * const textPromptOptions = { input: 'text', showCancelButton: true }
9833 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9834 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9835 *
9836 * After:
9837 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9838 * const {value: firstName} = await TextPrompt('What is your first name?')
9839 * const {value: lastName} = await TextPrompt('What is your last name?')
9840 *
9841 * @param {SweetAlertOptions} mixinParams
9842 * @returns {SweetAlert}
9843 * @this {typeof import('../SweetAlert.js').SweetAlert}
9844 */
9845 function mixin(mixinParams) {
9846 // @ts-ignore: 'this' refers to the SweetAlert constructor
9847 class MixinSwal extends this {
9848 /**
9849 * @param {any} params
9850 * @param {any} priorityMixinParams
9851 */
9852 _main(params, priorityMixinParams) {
9853 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9854 }
9855 }
9856 // @ts-ignore
9857 return MixinSwal;
9858 }
9859
9860 /**
9861 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9862 * Otherwise, returns undefined.
9863 *
9864 * @returns {number | undefined}
9865 */
9866 const getTimerLeft = () => {
9867 return globalState.timeout && globalState.timeout.getTimerLeft();
9868 };
9869
9870 /**
9871 * Stop timer. Returns number of milliseconds of timer remained.
9872 * If `timer` parameter isn't set, returns undefined.
9873 *
9874 * @returns {number | undefined}
9875 */
9876 const stopTimer = () => {
9877 if (globalState.timeout) {
9878 stopTimerProgressBar();
9879 return globalState.timeout.stop();
9880 }
9881 };
9882
9883 /**
9884 * Resume timer. Returns number of milliseconds of timer remained.
9885 * If `timer` parameter isn't set, returns undefined.
9886 *
9887 * @returns {number | undefined}
9888 */
9889 const resumeTimer = () => {
9890 if (globalState.timeout) {
9891 const remaining = globalState.timeout.start();
9892 animateTimerProgressBar(remaining);
9893 return remaining;
9894 }
9895 };
9896
9897 /**
9898 * Resume timer. Returns number of milliseconds of timer remained.
9899 * If `timer` parameter isn't set, returns undefined.
9900 *
9901 * @returns {number | undefined}
9902 */
9903 const toggleTimer = () => {
9904 const timer = globalState.timeout;
9905 return timer && (timer.running ? stopTimer() : resumeTimer());
9906 };
9907
9908 /**
9909 * Increase timer. Returns number of milliseconds of an updated timer.
9910 * If `timer` parameter isn't set, returns undefined.
9911 *
9912 * @param {number} ms
9913 * @returns {number | undefined}
9914 */
9915 const increaseTimer = ms => {
9916 if (globalState.timeout) {
9917 const remaining = globalState.timeout.increase(ms);
9918 animateTimerProgressBar(remaining, true);
9919 return remaining;
9920 }
9921 };
9922
9923 /**
9924 * Check if timer is running. Returns true if timer is running
9925 * or false if timer is paused or stopped.
9926 * If `timer` parameter isn't set, returns undefined
9927 *
9928 * @returns {boolean}
9929 */
9930 const isTimerRunning = () => {
9931 return Boolean(globalState.timeout && globalState.timeout.isRunning());
9932 };
9933
9934 let bodyClickListenerAdded = false;
9935 /** @type {Record<string, any>} */
9936 const clickHandlers = {};
9937
9938 /**
9939 * @this {any}
9940 * @param {string} attr
9941 */
9942 function bindClickHandler(attr = 'data-swal-template') {
9943 clickHandlers[attr] = this;
9944 if (!bodyClickListenerAdded) {
9945 document.body.addEventListener('click', bodyClickListener);
9946 bodyClickListenerAdded = true;
9947 }
9948 }
9949
9950 /**
9951 * @param {MouseEvent} event
9952 */
9953 const bodyClickListener = event => {
9954 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
9955 for (const attr in clickHandlers) {
9956 const template = el.getAttribute && el.getAttribute(attr);
9957 if (template) {
9958 clickHandlers[attr].fire({
9959 template
9960 });
9961 return;
9962 }
9963 }
9964 }
9965 };
9966
9967 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9968
9969 class EventEmitter {
9970 constructor() {
9971 /** @type {Events} */
9972 this.events = {};
9973 }
9974
9975 /**
9976 * @param {string} eventName
9977 * @returns {EventHandlers}
9978 */
9979 _getHandlersByEventName(eventName) {
9980 if (typeof this.events[eventName] === 'undefined') {
9981 // not Set because we need to keep the FIFO order
9982 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
9983 this.events[eventName] = [];
9984 }
9985 return this.events[eventName];
9986 }
9987
9988 /**
9989 * @param {string} eventName
9990 * @param {EventHandler} eventHandler
9991 */
9992 on(eventName, eventHandler) {
9993 const currentHandlers = this._getHandlersByEventName(eventName);
9994 if (!currentHandlers.includes(eventHandler)) {
9995 currentHandlers.push(eventHandler);
9996 }
9997 }
9998
9999 /**
10000 * @param {string} eventName
10001 * @param {EventHandler} eventHandler
10002 */
10003 once(eventName, eventHandler) {
10004 /**
10005 * @param {...any} args
10006 */
10007 const onceFn = (...args) => {
10008 this.removeListener(eventName, onceFn);
10009 // @ts-ignore
10010 eventHandler.apply(this, args);
10011 };
10012 this.on(eventName, onceFn);
10013 }
10014
10015 /**
10016 * @param {string} eventName
10017 * @param {...any} args
10018 */
10019 emit(eventName, ...args) {
10020 this._getHandlersByEventName(eventName).forEach(
10021 /**
10022 * @param {EventHandler} eventHandler
10023 */
10024 eventHandler => {
10025 try {
10026 // @ts-ignore
10027 eventHandler.apply(this, args);
10028 } catch (error) {
10029 console.error(error);
10030 }
10031 });
10032 }
10033
10034 /**
10035 * @param {string} eventName
10036 * @param {EventHandler} eventHandler
10037 */
10038 removeListener(eventName, eventHandler) {
10039 const currentHandlers = this._getHandlersByEventName(eventName);
10040 const index = currentHandlers.indexOf(eventHandler);
10041 if (index > -1) {
10042 currentHandlers.splice(index, 1);
10043 }
10044 }
10045
10046 /**
10047 * @param {string} eventName
10048 */
10049 removeAllListeners(eventName) {
10050 if (this.events[eventName] !== undefined) {
10051 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
10052 this.events[eventName].length = 0;
10053 }
10054 }
10055 reset() {
10056 this.events = {};
10057 }
10058 }
10059
10060 globalState.eventEmitter = new EventEmitter();
10061
10062 /**
10063 * @param {string} eventName
10064 * @param {EventHandler} eventHandler
10065 */
10066 const on = (eventName, eventHandler) => {
10067 if (globalState.eventEmitter) {
10068 globalState.eventEmitter.on(eventName, eventHandler);
10069 }
10070 };
10071
10072 /**
10073 * @param {string} eventName
10074 * @param {EventHandler} eventHandler
10075 */
10076 const once = (eventName, eventHandler) => {
10077 if (globalState.eventEmitter) {
10078 globalState.eventEmitter.once(eventName, eventHandler);
10079 }
10080 };
10081
10082 /**
10083 * @param {string} [eventName]
10084 * @param {EventHandler} [eventHandler]
10085 */
10086 const off = (eventName, eventHandler) => {
10087 if (!globalState.eventEmitter) {
10088 return;
10089 }
10090
10091 // Remove all handlers for all events
10092 if (!eventName) {
10093 globalState.eventEmitter.reset();
10094 return;
10095 }
10096 if (eventHandler) {
10097 // Remove a specific handler
10098 globalState.eventEmitter.removeListener(eventName, eventHandler);
10099 } else {
10100 // Remove all handlers for a specific event
10101 globalState.eventEmitter.removeAllListeners(eventName);
10102 }
10103 };
10104
10105 var staticMethods = /*#__PURE__*/Object.freeze({
10106 __proto__: null,
10107 argsToParams: argsToParams,
10108 bindClickHandler: bindClickHandler,
10109 clickCancel: clickCancel,
10110 clickConfirm: clickConfirm,
10111 clickDeny: clickDeny,
10112 enableLoading: showLoading,
10113 fire: fire,
10114 getActions: getActions,
10115 getCancelButton: getCancelButton,
10116 getCloseButton: getCloseButton,
10117 getConfirmButton: getConfirmButton,
10118 getContainer: getContainer,
10119 getDenyButton: getDenyButton,
10120 getFocusableElements: getFocusableElements,
10121 getFooter: getFooter,
10122 getHtmlContainer: getHtmlContainer,
10123 getIcon: getIcon,
10124 getIconContent: getIconContent,
10125 getImage: getImage,
10126 getInputLabel: getInputLabel,
10127 getLoader: getLoader,
10128 getPopup: getPopup,
10129 getProgressSteps: getProgressSteps,
10130 getTimerLeft: getTimerLeft,
10131 getTimerProgressBar: getTimerProgressBar,
10132 getTitle: getTitle,
10133 getValidationMessage: getValidationMessage,
10134 increaseTimer: increaseTimer,
10135 isDeprecatedParameter: isDeprecatedParameter,
10136 isLoading: isLoading,
10137 isTimerRunning: isTimerRunning,
10138 isUpdatableParameter: isUpdatableParameter,
10139 isValidParameter: isValidParameter,
10140 isVisible: isVisible,
10141 mixin: mixin,
10142 off: off,
10143 on: on,
10144 once: once,
10145 resumeTimer: resumeTimer,
10146 showLoading: showLoading,
10147 stopTimer: stopTimer,
10148 toggleTimer: toggleTimer
10149 });
10150
10151 class Timer {
10152 /**
10153 * @param {() => void} callback
10154 * @param {number} delay
10155 */
10156 constructor(callback, delay) {
10157 this.callback = callback;
10158 this.remaining = delay;
10159 this.running = false;
10160 this.start();
10161 }
10162
10163 /**
10164 * @returns {number}
10165 */
10166 start() {
10167 if (!this.running) {
10168 this.running = true;
10169 this.started = new Date();
10170 this.id = setTimeout(this.callback, this.remaining);
10171 }
10172 return this.remaining;
10173 }
10174
10175 /**
10176 * @returns {number}
10177 */
10178 stop() {
10179 if (this.started && this.running) {
10180 this.running = false;
10181 clearTimeout(this.id);
10182 this.remaining -= new Date().getTime() - this.started.getTime();
10183 }
10184 return this.remaining;
10185 }
10186
10187 /**
10188 * @param {number} n
10189 * @returns {number}
10190 */
10191 increase(n) {
10192 const running = this.running;
10193 if (running) {
10194 this.stop();
10195 }
10196 this.remaining += n;
10197 if (running) {
10198 this.start();
10199 }
10200 return this.remaining;
10201 }
10202
10203 /**
10204 * @returns {number}
10205 */
10206 getTimerLeft() {
10207 if (this.running) {
10208 this.stop();
10209 this.start();
10210 }
10211 return this.remaining;
10212 }
10213
10214 /**
10215 * @returns {boolean}
10216 */
10217 isRunning() {
10218 return this.running;
10219 }
10220 }
10221
10222 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
10223
10224 /**
10225 * @param {SweetAlertOptions} params
10226 * @returns {SweetAlertOptions}
10227 */
10228 const getTemplateParams = params => {
10229 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
10230 if (!template) {
10231 return {};
10232 }
10233 /** @type {DocumentFragment} */
10234 const templateContent = template.content;
10235 showWarningsForElements(templateContent);
10236 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
10237 return result;
10238 };
10239
10240 /**
10241 * @param {DocumentFragment} templateContent
10242 * @returns {Record<string, string | boolean | number>}
10243 */
10244 const getSwalParams = templateContent => {
10245 /** @type {Record<string, string | boolean | number>} */
10246 const result = {};
10247 /** @type {HTMLElement[]} */
10248 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
10249 swalParams.forEach(param => {
10250 showWarningsForAttributes(param, ['name', 'value']);
10251 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10252 const value = param.getAttribute('value');
10253 if (!paramName || !value) {
10254 return;
10255 }
10256 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
10257 result[paramName] = value !== 'false';
10258 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
10259 result[paramName] = JSON.parse(value);
10260 } else {
10261 result[paramName] = value;
10262 }
10263 });
10264 return result;
10265 };
10266
10267 /**
10268 * @param {DocumentFragment} templateContent
10269 * @returns {Record<string, () => void>}
10270 */
10271 const getSwalFunctionParams = templateContent => {
10272 /** @type {Record<string, () => void>} */
10273 const result = {};
10274 /** @type {HTMLElement[]} */
10275 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
10276 swalFunctions.forEach(param => {
10277 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10278 const value = param.getAttribute('value');
10279 if (!paramName || !value) {
10280 return;
10281 }
10282 result[paramName] = new Function(`return ${value}`)();
10283 });
10284 return result;
10285 };
10286
10287 /**
10288 * @param {DocumentFragment} templateContent
10289 * @returns {Record<string, string | boolean>}
10290 */
10291 const getSwalButtons = templateContent => {
10292 /** @type {Record<string, string | boolean>} */
10293 const result = {};
10294 /** @type {HTMLElement[]} */
10295 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
10296 swalButtons.forEach(button => {
10297 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
10298 const type = button.getAttribute('type');
10299 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
10300 return;
10301 }
10302 result[`${type}ButtonText`] = button.innerHTML;
10303 result[`show${capitalizeFirstLetter(type)}Button`] = true;
10304 if (button.hasAttribute('color')) {
10305 const color = button.getAttribute('color');
10306 if (color !== null) {
10307 result[`${type}ButtonColor`] = color;
10308 }
10309 }
10310 if (button.hasAttribute('aria-label')) {
10311 const ariaLabel = button.getAttribute('aria-label');
10312 if (ariaLabel !== null) {
10313 result[`${type}ButtonAriaLabel`] = ariaLabel;
10314 }
10315 }
10316 });
10317 return result;
10318 };
10319
10320 /**
10321 * @param {DocumentFragment} templateContent
10322 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
10323 */
10324 const getSwalImage = templateContent => {
10325 const result = {};
10326 /** @type {HTMLElement | null} */
10327 const image = templateContent.querySelector('swal-image');
10328 if (image) {
10329 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
10330 if (image.hasAttribute('src')) {
10331 result.imageUrl = image.getAttribute('src') || undefined;
10332 }
10333 if (image.hasAttribute('width')) {
10334 result.imageWidth = image.getAttribute('width') || undefined;
10335 }
10336 if (image.hasAttribute('height')) {
10337 result.imageHeight = image.getAttribute('height') || undefined;
10338 }
10339 if (image.hasAttribute('alt')) {
10340 result.imageAlt = image.getAttribute('alt') || undefined;
10341 }
10342 }
10343 return result;
10344 };
10345
10346 /**
10347 * @param {DocumentFragment} templateContent
10348 * @returns {object}
10349 */
10350 const getSwalIcon = templateContent => {
10351 const result = {};
10352 /** @type {HTMLElement | null} */
10353 const icon = templateContent.querySelector('swal-icon');
10354 if (icon) {
10355 showWarningsForAttributes(icon, ['type', 'color']);
10356 if (icon.hasAttribute('type')) {
10357 result.icon = icon.getAttribute('type');
10358 }
10359 if (icon.hasAttribute('color')) {
10360 result.iconColor = icon.getAttribute('color');
10361 }
10362 result.iconHtml = icon.innerHTML;
10363 }
10364 return result;
10365 };
10366
10367 /**
10368 * @param {DocumentFragment} templateContent
10369 * @returns {object}
10370 */
10371 const getSwalInput = templateContent => {
10372 /** @type {Record<string, any>} */
10373 const result = {};
10374 /** @type {HTMLElement | null} */
10375 const input = templateContent.querySelector('swal-input');
10376 if (input) {
10377 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
10378 result.input = input.getAttribute('type') || 'text';
10379 if (input.hasAttribute('label')) {
10380 result.inputLabel = input.getAttribute('label');
10381 }
10382 if (input.hasAttribute('placeholder')) {
10383 result.inputPlaceholder = input.getAttribute('placeholder');
10384 }
10385 if (input.hasAttribute('value')) {
10386 result.inputValue = input.getAttribute('value');
10387 }
10388 }
10389 /** @type {HTMLElement[]} */
10390 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
10391 if (inputOptions.length) {
10392 result.inputOptions = {};
10393 inputOptions.forEach(option => {
10394 showWarningsForAttributes(option, ['value']);
10395 const optionValue = option.getAttribute('value');
10396 if (!optionValue) {
10397 return;
10398 }
10399 const optionName = option.innerHTML;
10400 result.inputOptions[optionValue] = optionName;
10401 });
10402 }
10403 return result;
10404 };
10405
10406 /**
10407 * @param {DocumentFragment} templateContent
10408 * @param {string[]} paramNames
10409 * @returns {Record<string, string>}
10410 */
10411 const getSwalStringParams = (templateContent, paramNames) => {
10412 /** @type {Record<string, string>} */
10413 const result = {};
10414 for (const i in paramNames) {
10415 const paramName = paramNames[i];
10416 /** @type {HTMLElement | null} */
10417 const tag = templateContent.querySelector(paramName);
10418 if (tag) {
10419 showWarningsForAttributes(tag, []);
10420 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
10421 }
10422 }
10423 return result;
10424 };
10425
10426 /**
10427 * @param {DocumentFragment} templateContent
10428 */
10429 const showWarningsForElements = templateContent => {
10430 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
10431 Array.from(templateContent.children).forEach(el => {
10432 const tagName = el.tagName.toLowerCase();
10433 if (!allowedElements.includes(tagName)) {
10434 warn(`Unrecognized element <${tagName}>`);
10435 }
10436 });
10437 };
10438
10439 /**
10440 * @param {HTMLElement} el
10441 * @param {string[]} allowedAttributes
10442 */
10443 const showWarningsForAttributes = (el, allowedAttributes) => {
10444 Array.from(el.attributes).forEach(attribute => {
10445 if (allowedAttributes.indexOf(attribute.name) === -1) {
10446 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.'}`]);
10447 }
10448 });
10449 };
10450
10451 const SHOW_CLASS_TIMEOUT = 10;
10452
10453 /**
10454 * Open popup, add necessary classes and styles, fix scrollbar
10455 *
10456 * @param {SweetAlertOptions} params
10457 */
10458 const openPopup = params => {
10459 var _globalState$eventEmi, _globalState$eventEmi2;
10460 const container = getContainer();
10461 const popup = getPopup();
10462 if (!container || !popup) {
10463 return;
10464 }
10465 if (typeof params.willOpen === 'function') {
10466 params.willOpen(popup);
10467 }
10468 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
10469 const bodyStyles = window.getComputedStyle(document.body);
10470 const initialBodyOverflow = bodyStyles.overflowY;
10471 addClasses(container, popup, params);
10472
10473 // scrolling is 'hidden' until animation is done, after that 'auto'
10474 setTimeout(() => {
10475 setScrollingVisibility(container, popup);
10476 }, SHOW_CLASS_TIMEOUT);
10477 if (isModal()) {
10478 // Using ternary instead of ?? operator for Webpack 4 compatibility
10479 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
10480 setAriaHidden();
10481 }
10482 if (!isToast() && !globalState.previousActiveElement) {
10483 globalState.previousActiveElement = document.activeElement;
10484 }
10485 if (typeof params.didOpen === 'function') {
10486 const didOpen = params.didOpen;
10487 setTimeout(() => didOpen(popup));
10488 }
10489 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
10490 };
10491
10492 /**
10493 * @param {Event} event
10494 */
10495 const swalOpenAnimationFinished = event => {
10496 const popup = getPopup();
10497 if (!popup || event.target !== popup) {
10498 return;
10499 }
10500 const container = getContainer();
10501 if (!container) {
10502 return;
10503 }
10504 popup.removeEventListener('animationend', swalOpenAnimationFinished);
10505 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
10506 container.style.overflowY = 'auto';
10507
10508 // no-transition is added in init() in case one swal is opened right after another
10509 removeClass(container, swalClasses['no-transition']);
10510 };
10511
10512 /**
10513 * @param {HTMLElement} container
10514 * @param {HTMLElement} popup
10515 */
10516 const setScrollingVisibility = (container, popup) => {
10517 if (hasCssAnimation(popup)) {
10518 container.style.overflowY = 'hidden';
10519 popup.addEventListener('animationend', swalOpenAnimationFinished);
10520 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10521 } else {
10522 container.style.overflowY = 'auto';
10523 }
10524 };
10525
10526 /**
10527 * @param {HTMLElement} container
10528 * @param {boolean} scrollbarPadding
10529 * @param {string} initialBodyOverflow
10530 */
10531 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10532 iOSfix();
10533 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10534 replaceScrollbarWithPadding(initialBodyOverflow);
10535 }
10536
10537 // sweetalert2/issues/1247
10538 setTimeout(() => {
10539 container.scrollTop = 0;
10540 });
10541 };
10542
10543 /**
10544 * @param {HTMLElement} container
10545 * @param {HTMLElement} popup
10546 * @param {SweetAlertOptions} params
10547 */
10548 const addClasses = (container, popup, params) => {
10549 var _params$showClass;
10550 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
10551 addClass(container, params.showClass.backdrop);
10552 }
10553 if (params.animation) {
10554 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10555 popup.style.setProperty('opacity', '0', 'important');
10556 show(popup, 'grid');
10557 setTimeout(() => {
10558 var _params$showClass2;
10559 // Animate popup right after showing it
10560 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
10561 addClass(popup, params.showClass.popup);
10562 }
10563 // and remove the opacity workaround
10564 popup.style.removeProperty('opacity');
10565 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10566 } else {
10567 show(popup, 'grid');
10568 }
10569 addClass([document.documentElement, document.body], swalClasses.shown);
10570 if (params.heightAuto && params.backdrop && !params.toast) {
10571 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10572 }
10573 };
10574
10575 var defaultInputValidators = {
10576 /**
10577 * @param {string} string
10578 * @param {string} [validationMessage]
10579 * @returns {Promise<string | void>}
10580 */
10581 email: (string, validationMessage) => {
10582 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10583 },
10584 /**
10585 * @param {string} string
10586 * @param {string} [validationMessage]
10587 * @returns {Promise<string | void>}
10588 */
10589 url: (string, validationMessage) => {
10590 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10591 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');
10592 }
10593 };
10594
10595 /**
10596 * @param {SweetAlertOptions} params
10597 */
10598 function setDefaultInputValidators(params) {
10599 // Use default `inputValidator` for supported input types if not provided
10600 if (params.inputValidator) {
10601 return;
10602 }
10603 if (params.input === 'email') {
10604 params.inputValidator = defaultInputValidators['email'];
10605 }
10606 if (params.input === 'url') {
10607 params.inputValidator = defaultInputValidators['url'];
10608 }
10609 }
10610
10611 /**
10612 * @param {SweetAlertOptions} params
10613 */
10614 function validateCustomTargetElement(params) {
10615 // Determine if the custom target element is valid
10616 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10617 warn('Target parameter is not valid, defaulting to "body"');
10618 params.target = 'body';
10619 }
10620 }
10621
10622 /**
10623 * Set type, text and actions on popup
10624 *
10625 * @param {SweetAlertOptions} params
10626 */
10627 function setParameters(params) {
10628 setDefaultInputValidators(params);
10629
10630 // showLoaderOnConfirm && preConfirm
10631 if (params.showLoaderOnConfirm && !params.preConfirm) {
10632 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');
10633 }
10634 validateCustomTargetElement(params);
10635
10636 // Replace newlines with <br> in title
10637 if (typeof params.title === 'string') {
10638 params.title = params.title.split('\n').join('<br />');
10639 }
10640 init(params);
10641 }
10642
10643 /** @type {SweetAlert} */
10644 let currentInstance;
10645 var _promise = /*#__PURE__*/new WeakMap();
10646 class SweetAlert {
10647 /**
10648 * @param {...(SweetAlertOptions | string)} args
10649 * @this {SweetAlert}
10650 */
10651 constructor(...args) {
10652 /**
10653 * @type {Promise<SweetAlertResult>}
10654 */
10655 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */Promise.resolve({
10656 isConfirmed: false,
10657 isDenied: false,
10658 isDismissed: true
10659 }));
10660 // Prevent run in Node env
10661 if (typeof window === 'undefined') {
10662 return;
10663 }
10664 currentInstance = this;
10665
10666 // @ts-ignore
10667 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10668
10669 /** @type {Readonly<SweetAlertOptions>} */
10670 this.params = outerParams;
10671
10672 /** @type {boolean} */
10673 this.isAwaitingPromise = false;
10674 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10675 }
10676
10677 /**
10678 * @param {any} userParams
10679 * @param {any} mixinParams
10680 */
10681 _main(userParams, mixinParams = {}) {
10682 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10683 if (globalState.currentInstance) {
10684 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10685 const {
10686 isAwaitingPromise
10687 } = globalState.currentInstance;
10688 globalState.currentInstance._destroy();
10689 if (!isAwaitingPromise) {
10690 swalPromiseResolve({
10691 isDismissed: true
10692 });
10693 }
10694 if (isModal()) {
10695 unsetAriaHidden();
10696 }
10697 }
10698 globalState.currentInstance = currentInstance;
10699 const innerParams = prepareParams(userParams, mixinParams);
10700 setParameters(innerParams);
10701 Object.freeze(innerParams);
10702
10703 // clear the previous timer
10704 if (globalState.timeout) {
10705 globalState.timeout.stop();
10706 delete globalState.timeout;
10707 }
10708
10709 // clear the restore focus timeout
10710 clearTimeout(globalState.restoreFocusTimeout);
10711 const domCache = populateDomCache(currentInstance);
10712 render(currentInstance, innerParams);
10713 privateProps.innerParams.set(currentInstance, innerParams);
10714 return swalPromise(currentInstance, domCache, innerParams);
10715 }
10716
10717 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10718 /**
10719 * @param {any} onFulfilled
10720 */
10721 then(onFulfilled) {
10722 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10723 }
10724
10725 /**
10726 * @param {any} onFinally
10727 */
10728 finally(onFinally) {
10729 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10730 }
10731 }
10732
10733 /**
10734 * @param {SweetAlert} instance
10735 * @param {DomCache} domCache
10736 * @param {SweetAlertOptions} innerParams
10737 * @returns {Promise<SweetAlertResult>}
10738 */
10739 const swalPromise = (instance, domCache, innerParams) => {
10740 return new Promise((resolve, reject) => {
10741 // functions to handle all closings/dismissals
10742 /**
10743 * @param {DismissReason} dismiss
10744 */
10745 const dismissWith = dismiss => {
10746 instance.close({
10747 isDismissed: true,
10748 dismiss,
10749 isConfirmed: false,
10750 isDenied: false
10751 });
10752 };
10753 privateMethods.swalPromiseResolve.set(instance, resolve);
10754 privateMethods.swalPromiseReject.set(instance, reject);
10755 domCache.confirmButton.onclick = () => {
10756 handleConfirmButtonClick(instance);
10757 };
10758 domCache.denyButton.onclick = () => {
10759 handleDenyButtonClick(instance);
10760 };
10761 domCache.cancelButton.onclick = () => {
10762 handleCancelButtonClick(instance, dismissWith);
10763 };
10764 domCache.closeButton.onclick = () => {
10765 dismissWith(DismissReason.close);
10766 };
10767 handlePopupClick(innerParams, domCache, dismissWith);
10768 addKeydownHandler(globalState, innerParams, dismissWith);
10769 handleInputOptionsAndValue(instance, innerParams);
10770 openPopup(innerParams);
10771 setupTimer(globalState, innerParams, dismissWith);
10772 initFocus(domCache, innerParams);
10773
10774 // Scroll container to top on open (#1247, #1946)
10775 setTimeout(() => {
10776 domCache.container.scrollTop = 0;
10777 });
10778 });
10779 };
10780
10781 /**
10782 * @param {SweetAlertOptions} userParams
10783 * @param {SweetAlertOptions} mixinParams
10784 * @returns {SweetAlertOptions}
10785 */
10786 const prepareParams = (userParams, mixinParams) => {
10787 const templateParams = getTemplateParams(userParams);
10788 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10789 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10790 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10791 if (params.animation === false) {
10792 params.showClass = {
10793 backdrop: 'swal2-noanimation'
10794 };
10795 params.hideClass = {};
10796 }
10797 return params;
10798 };
10799
10800 /**
10801 * @param {SweetAlert} instance
10802 * @returns {DomCache}
10803 */
10804 const populateDomCache = instance => {
10805 const domCache = /** @type {DomCache} */{
10806 popup: (/** @type {HTMLElement} */getPopup()),
10807 container: (/** @type {HTMLElement} */getContainer()),
10808 actions: (/** @type {HTMLElement} */getActions()),
10809 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
10810 denyButton: (/** @type {HTMLElement} */getDenyButton()),
10811 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
10812 loader: (/** @type {HTMLElement} */getLoader()),
10813 closeButton: (/** @type {HTMLElement} */getCloseButton()),
10814 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
10815 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
10816 };
10817 privateProps.domCache.set(instance, domCache);
10818 return domCache;
10819 };
10820
10821 /**
10822 * @param {GlobalState} globalState
10823 * @param {SweetAlertOptions} innerParams
10824 * @param {(dismiss: DismissReason) => void} dismissWith
10825 */
10826 const setupTimer = (globalState, innerParams, dismissWith) => {
10827 const timerProgressBar = getTimerProgressBar();
10828 hide(timerProgressBar);
10829 if (innerParams.timer) {
10830 globalState.timeout = new Timer(() => {
10831 dismissWith('timer');
10832 delete globalState.timeout;
10833 }, innerParams.timer);
10834 if (innerParams.timerProgressBar && timerProgressBar) {
10835 show(timerProgressBar);
10836 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10837 setTimeout(() => {
10838 if (globalState.timeout && globalState.timeout.running) {
10839 // timer can be already stopped or unset at this point
10840 animateTimerProgressBar(/** @type {number} */innerParams.timer);
10841 }
10842 });
10843 }
10844 }
10845 };
10846
10847 /**
10848 * Initialize focus in the popup:
10849 *
10850 * 1. If `toast` is `true`, don't steal focus from the document.
10851 * 2. Else if there is an [autofocus] element, focus it.
10852 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10853 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10854 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10855 * 6. Else focus the first focusable element in a popup (if any).
10856 *
10857 * @param {DomCache} domCache
10858 * @param {SweetAlertOptions} innerParams
10859 */
10860 const initFocus = (domCache, innerParams) => {
10861 if (innerParams.toast) {
10862 return;
10863 }
10864 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10865 if (!callIfFunction(innerParams.allowEnterKey)) {
10866 warnAboutDeprecation('allowEnterKey');
10867 blurActiveElement();
10868 return;
10869 }
10870 if (focusAutofocus(domCache)) {
10871 return;
10872 }
10873 if (focusButton(domCache, innerParams)) {
10874 return;
10875 }
10876 setFocus(-1, 1);
10877 };
10878
10879 /**
10880 * @param {DomCache} domCache
10881 * @returns {boolean}
10882 */
10883 const focusAutofocus = domCache => {
10884 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10885 for (const autofocusElement of autofocusElements) {
10886 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10887 autofocusElement.focus();
10888 return true;
10889 }
10890 }
10891 return false;
10892 };
10893
10894 /**
10895 * @param {DomCache} domCache
10896 * @param {SweetAlertOptions} innerParams
10897 * @returns {boolean}
10898 */
10899 const focusButton = (domCache, innerParams) => {
10900 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10901 domCache.denyButton.focus();
10902 return true;
10903 }
10904 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10905 domCache.cancelButton.focus();
10906 return true;
10907 }
10908 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10909 domCache.confirmButton.focus();
10910 return true;
10911 }
10912 return false;
10913 };
10914 const blurActiveElement = () => {
10915 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
10916 document.activeElement.blur();
10917 }
10918 };
10919
10920 // Assign instance methods from src/instanceMethods/*.js to prototype
10921 SweetAlert.prototype.disableButtons = disableButtons;
10922 SweetAlert.prototype.enableButtons = enableButtons;
10923 SweetAlert.prototype.getInput = getInput;
10924 SweetAlert.prototype.disableInput = disableInput;
10925 SweetAlert.prototype.enableInput = enableInput;
10926 SweetAlert.prototype.hideLoading = hideLoading;
10927 SweetAlert.prototype.disableLoading = hideLoading;
10928 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10929 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10930 SweetAlert.prototype.close = close;
10931 SweetAlert.prototype.closePopup = close;
10932 SweetAlert.prototype.closeModal = close;
10933 SweetAlert.prototype.closeToast = close;
10934 SweetAlert.prototype.rejectPromise = rejectPromise;
10935 SweetAlert.prototype.update = update;
10936 SweetAlert.prototype._destroy = _destroy;
10937
10938 // Assign static methods from src/staticMethods/*.js to constructor
10939 Object.assign(SweetAlert, staticMethods);
10940
10941 // Proxy to instance methods to constructor, for now, for backwards compatibility
10942 Object.keys(instanceMethods).forEach(key => {
10943 /**
10944 * @param {...(SweetAlertOptions | string | undefined)} args
10945 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
10946 */
10947 // @ts-ignore: Dynamic property assignment for backwards compatibility
10948 SweetAlert[key] = function (...args) {
10949 // @ts-ignore
10950 if (currentInstance && currentInstance[key]) {
10951 // @ts-ignore
10952 return currentInstance[key](...args);
10953 }
10954 return undefined;
10955 };
10956 });
10957 SweetAlert.DismissReason = DismissReason;
10958 SweetAlert.version = '11.26.17';
10959
10960 const Swal = SweetAlert;
10961 // @ts-ignore
10962 Swal.default = Swal;
10963
10964 return Swal;
10965
10966 }));
10967 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10968 "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}}");
10969
10970 /***/ },
10971
10972 /***/ "./node_modules/toastify-js/src/toastify.js"
10973 /*!**************************************************!*\
10974 !*** ./node_modules/toastify-js/src/toastify.js ***!
10975 \**************************************************/
10976 (module) {
10977
10978 /*!
10979 * Toastify js 1.12.0
10980 * https://github.com/apvarun/toastify-js
10981 * @license MIT licensed
10982 *
10983 * Copyright (C) 2018 Varun A P
10984 */
10985 (function(root, factory) {
10986 if ( true && module.exports) {
10987 module.exports = factory();
10988 } else {
10989 root.Toastify = factory();
10990 }
10991 })(this, function(global) {
10992 // Object initialization
10993 var Toastify = function(options) {
10994 // Returning a new init object
10995 return new Toastify.lib.init(options);
10996 },
10997 // Library version
10998 version = "1.12.0";
10999
11000 // Set the default global options
11001 Toastify.defaults = {
11002 oldestFirst: true,
11003 text: "Toastify is awesome!",
11004 node: undefined,
11005 duration: 3000,
11006 selector: undefined,
11007 callback: function () {
11008 },
11009 destination: undefined,
11010 newWindow: false,
11011 close: false,
11012 gravity: "toastify-top",
11013 positionLeft: false,
11014 position: '',
11015 backgroundColor: '',
11016 avatar: "",
11017 className: "",
11018 stopOnFocus: true,
11019 onClick: function () {
11020 },
11021 offset: {x: 0, y: 0},
11022 escapeMarkup: true,
11023 ariaLive: 'polite',
11024 style: {background: ''}
11025 };
11026
11027 // Defining the prototype of the object
11028 Toastify.lib = Toastify.prototype = {
11029 toastify: version,
11030
11031 constructor: Toastify,
11032
11033 // Initializing the object with required parameters
11034 init: function(options) {
11035 // Verifying and validating the input object
11036 if (!options) {
11037 options = {};
11038 }
11039
11040 // Creating the options object
11041 this.options = {};
11042
11043 this.toastElement = null;
11044
11045 // Validating the options
11046 this.options.text = options.text || Toastify.defaults.text; // Display message
11047 this.options.node = options.node || Toastify.defaults.node; // Display content as node
11048 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
11049 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
11050 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
11051 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
11052 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
11053 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
11054 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
11055 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
11056 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
11057 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
11058 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
11059 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
11060 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
11061 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
11062 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
11063 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
11064 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
11065 this.options.style = options.style || Toastify.defaults.style;
11066 if(options.backgroundColor) {
11067 this.options.style.background = options.backgroundColor;
11068 }
11069
11070 // Returning the current object for chaining functions
11071 return this;
11072 },
11073
11074 // Building the DOM element
11075 buildToast: function() {
11076 // Validating if the options are defined
11077 if (!this.options) {
11078 throw "Toastify is not initialized";
11079 }
11080
11081 // Creating the DOM object
11082 var divElement = document.createElement("div");
11083 divElement.className = "toastify on " + this.options.className;
11084
11085 // Positioning toast to left or right or center
11086 if (!!this.options.position) {
11087 divElement.className += " toastify-" + this.options.position;
11088 } else {
11089 // To be depreciated in further versions
11090 if (this.options.positionLeft === true) {
11091 divElement.className += " toastify-left";
11092 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
11093 } else {
11094 // Default position
11095 divElement.className += " toastify-right";
11096 }
11097 }
11098
11099 // Assigning gravity of element
11100 divElement.className += " " + this.options.gravity;
11101
11102 if (this.options.backgroundColor) {
11103 // This is being deprecated in favor of using the style HTML DOM property
11104 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
11105 }
11106
11107 // Loop through our style object and apply styles to divElement
11108 for (var property in this.options.style) {
11109 divElement.style[property] = this.options.style[property];
11110 }
11111
11112 // Announce the toast to screen readers
11113 if (this.options.ariaLive) {
11114 divElement.setAttribute('aria-live', this.options.ariaLive)
11115 }
11116
11117 // Adding the toast message/node
11118 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
11119 // If we have a valid node, we insert it
11120 divElement.appendChild(this.options.node)
11121 } else {
11122 if (this.options.escapeMarkup) {
11123 divElement.innerText = this.options.text;
11124 } else {
11125 divElement.innerHTML = this.options.text;
11126 }
11127
11128 if (this.options.avatar !== "") {
11129 var avatarElement = document.createElement("img");
11130 avatarElement.src = this.options.avatar;
11131
11132 avatarElement.className = "toastify-avatar";
11133
11134 if (this.options.position == "left" || this.options.positionLeft === true) {
11135 // Adding close icon on the left of content
11136 divElement.appendChild(avatarElement);
11137 } else {
11138 // Adding close icon on the right of content
11139 divElement.insertAdjacentElement("afterbegin", avatarElement);
11140 }
11141 }
11142 }
11143
11144 // Adding a close icon to the toast
11145 if (this.options.close === true) {
11146 // Create a span for close element
11147 var closeElement = document.createElement("button");
11148 closeElement.type = "button";
11149 closeElement.setAttribute("aria-label", "Close");
11150 closeElement.className = "toast-close";
11151 closeElement.innerHTML = "&#10006;";
11152
11153 // Triggering the removal of toast from DOM on close click
11154 closeElement.addEventListener(
11155 "click",
11156 function(event) {
11157 event.stopPropagation();
11158 this.removeElement(this.toastElement);
11159 window.clearTimeout(this.toastElement.timeOutValue);
11160 }.bind(this)
11161 );
11162
11163 //Calculating screen width
11164 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11165
11166 // Adding the close icon to the toast element
11167 // Display on the right if screen width is less than or equal to 360px
11168 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
11169 // Adding close icon on the left of content
11170 divElement.insertAdjacentElement("afterbegin", closeElement);
11171 } else {
11172 // Adding close icon on the right of content
11173 divElement.appendChild(closeElement);
11174 }
11175 }
11176
11177 // Clear timeout while toast is focused
11178 if (this.options.stopOnFocus && this.options.duration > 0) {
11179 var self = this;
11180 // stop countdown
11181 divElement.addEventListener(
11182 "mouseover",
11183 function(event) {
11184 window.clearTimeout(divElement.timeOutValue);
11185 }
11186 )
11187 // add back the timeout
11188 divElement.addEventListener(
11189 "mouseleave",
11190 function() {
11191 divElement.timeOutValue = window.setTimeout(
11192 function() {
11193 // Remove the toast from DOM
11194 self.removeElement(divElement);
11195 },
11196 self.options.duration
11197 )
11198 }
11199 )
11200 }
11201
11202 // Adding an on-click destination path
11203 if (typeof this.options.destination !== "undefined") {
11204 divElement.addEventListener(
11205 "click",
11206 function(event) {
11207 event.stopPropagation();
11208 if (this.options.newWindow === true) {
11209 window.open(this.options.destination, "_blank");
11210 } else {
11211 window.location = this.options.destination;
11212 }
11213 }.bind(this)
11214 );
11215 }
11216
11217 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
11218 divElement.addEventListener(
11219 "click",
11220 function(event) {
11221 event.stopPropagation();
11222 this.options.onClick();
11223 }.bind(this)
11224 );
11225 }
11226
11227 // Adding offset
11228 if(typeof this.options.offset === "object") {
11229
11230 var x = getAxisOffsetAValue("x", this.options);
11231 var y = getAxisOffsetAValue("y", this.options);
11232
11233 var xOffset = this.options.position == "left" ? x : "-" + x;
11234 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
11235
11236 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
11237
11238 }
11239
11240 // Returning the generated element
11241 return divElement;
11242 },
11243
11244 // Displaying the toast
11245 showToast: function() {
11246 // Creating the DOM object for the toast
11247 this.toastElement = this.buildToast();
11248
11249 // Getting the root element to with the toast needs to be added
11250 var rootElement;
11251 if (typeof this.options.selector === "string") {
11252 rootElement = document.getElementById(this.options.selector);
11253 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
11254 rootElement = this.options.selector;
11255 } else {
11256 rootElement = document.body;
11257 }
11258
11259 // Validating if root element is present in DOM
11260 if (!rootElement) {
11261 throw "Root element is not defined";
11262 }
11263
11264 // Adding the DOM element
11265 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
11266 rootElement.insertBefore(this.toastElement, elementToInsert);
11267
11268 // Repositioning the toasts in case multiple toasts are present
11269 Toastify.reposition();
11270
11271 if (this.options.duration > 0) {
11272 this.toastElement.timeOutValue = window.setTimeout(
11273 function() {
11274 // Remove the toast from DOM
11275 this.removeElement(this.toastElement);
11276 }.bind(this),
11277 this.options.duration
11278 ); // Binding `this` for function invocation
11279 }
11280
11281 // Supporting function chaining
11282 return this;
11283 },
11284
11285 hideToast: function() {
11286 if (this.toastElement.timeOutValue) {
11287 clearTimeout(this.toastElement.timeOutValue);
11288 }
11289 this.removeElement(this.toastElement);
11290 },
11291
11292 // Removing the element from the DOM
11293 removeElement: function(toastElement) {
11294 // Hiding the element
11295 // toastElement.classList.remove("on");
11296 toastElement.className = toastElement.className.replace(" on", "");
11297
11298 // Removing the element from DOM after transition end
11299 window.setTimeout(
11300 function() {
11301 // remove options node if any
11302 if (this.options.node && this.options.node.parentNode) {
11303 this.options.node.parentNode.removeChild(this.options.node);
11304 }
11305
11306 // Remove the element from the DOM, only when the parent node was not removed before.
11307 if (toastElement.parentNode) {
11308 toastElement.parentNode.removeChild(toastElement);
11309 }
11310
11311 // Calling the callback function
11312 this.options.callback.call(toastElement);
11313
11314 // Repositioning the toasts again
11315 Toastify.reposition();
11316 }.bind(this),
11317 400
11318 ); // Binding `this` for function invocation
11319 },
11320 };
11321
11322 // Positioning the toasts on the DOM
11323 Toastify.reposition = function() {
11324
11325 // Top margins with gravity
11326 var topLeftOffsetSize = {
11327 top: 15,
11328 bottom: 15,
11329 };
11330 var topRightOffsetSize = {
11331 top: 15,
11332 bottom: 15,
11333 };
11334 var offsetSize = {
11335 top: 15,
11336 bottom: 15,
11337 };
11338
11339 // Get all toast messages on the DOM
11340 var allToasts = document.getElementsByClassName("toastify");
11341
11342 var classUsed;
11343
11344 // Modifying the position of each toast element
11345 for (var i = 0; i < allToasts.length; i++) {
11346 // Getting the applied gravity
11347 if (containsClass(allToasts[i], "toastify-top") === true) {
11348 classUsed = "toastify-top";
11349 } else {
11350 classUsed = "toastify-bottom";
11351 }
11352
11353 var height = allToasts[i].offsetHeight;
11354 classUsed = classUsed.substr(9, classUsed.length-1)
11355 // Spacing between toasts
11356 var offset = 15;
11357
11358 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11359
11360 // Show toast in center if screen with less than or equal to 360px
11361 if (width <= 360) {
11362 // Setting the position
11363 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
11364
11365 offsetSize[classUsed] += height + offset;
11366 } else {
11367 if (containsClass(allToasts[i], "toastify-left") === true) {
11368 // Setting the position
11369 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
11370
11371 topLeftOffsetSize[classUsed] += height + offset;
11372 } else {
11373 // Setting the position
11374 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
11375
11376 topRightOffsetSize[classUsed] += height + offset;
11377 }
11378 }
11379 }
11380
11381 // Supporting function chaining
11382 return this;
11383 };
11384
11385 // Helper function to get offset.
11386 function getAxisOffsetAValue(axis, options) {
11387
11388 if(options.offset[axis]) {
11389 if(isNaN(options.offset[axis])) {
11390 return options.offset[axis];
11391 }
11392 else {
11393 return options.offset[axis] + 'px';
11394 }
11395 }
11396
11397 return '0px';
11398
11399 }
11400
11401 function containsClass(elem, yourClass) {
11402 if (!elem || typeof yourClass !== "string") {
11403 return false;
11404 } else if (
11405 elem.className &&
11406 elem.className
11407 .trim()
11408 .split(/\s+/gi)
11409 .indexOf(yourClass) > -1
11410 ) {
11411 return true;
11412 } else {
11413 return false;
11414 }
11415 }
11416
11417 // Setting up the prototype for the init object
11418 Toastify.lib.init.prototype = Toastify.lib;
11419
11420 // Returning the Toastify function to be assigned to the window object/module
11421 return Toastify;
11422 });
11423
11424
11425 /***/ }
11426
11427 /******/ });
11428 /************************************************************************/
11429 /******/ // The module cache
11430 /******/ var __webpack_module_cache__ = {};
11431 /******/
11432 /******/ // The require function
11433 /******/ function __webpack_require__(moduleId) {
11434 /******/ // Check if module is in cache
11435 /******/ var cachedModule = __webpack_module_cache__[moduleId];
11436 /******/ if (cachedModule !== undefined) {
11437 /******/ return cachedModule.exports;
11438 /******/ }
11439 /******/ // Create a new module (and put it into the cache)
11440 /******/ var module = __webpack_module_cache__[moduleId] = {
11441 /******/ id: moduleId,
11442 /******/ // no module.loaded needed
11443 /******/ exports: {}
11444 /******/ };
11445 /******/
11446 /******/ // Execute the module function
11447 /******/ if (!(moduleId in __webpack_modules__)) {
11448 /******/ delete __webpack_module_cache__[moduleId];
11449 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
11450 /******/ e.code = 'MODULE_NOT_FOUND';
11451 /******/ throw e;
11452 /******/ }
11453 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11454 /******/
11455 /******/ // Return the exports of the module
11456 /******/ return module.exports;
11457 /******/ }
11458 /******/
11459 /************************************************************************/
11460 /******/ /* webpack/runtime/compat get default export */
11461 /******/ (() => {
11462 /******/ // getDefaultExport function for compatibility with non-harmony modules
11463 /******/ __webpack_require__.n = (module) => {
11464 /******/ var getter = module && module.__esModule ?
11465 /******/ () => (module['default']) :
11466 /******/ () => (module);
11467 /******/ __webpack_require__.d(getter, { a: getter });
11468 /******/ return getter;
11469 /******/ };
11470 /******/ })();
11471 /******/
11472 /******/ /* webpack/runtime/define property getters */
11473 /******/ (() => {
11474 /******/ // define getter functions for harmony exports
11475 /******/ __webpack_require__.d = (exports, definition) => {
11476 /******/ for(var key in definition) {
11477 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11478 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11479 /******/ }
11480 /******/ }
11481 /******/ };
11482 /******/ })();
11483 /******/
11484 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11485 /******/ (() => {
11486 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
11487 /******/ })();
11488 /******/
11489 /******/ /* webpack/runtime/make namespace object */
11490 /******/ (() => {
11491 /******/ // define __esModule on exports
11492 /******/ __webpack_require__.r = (exports) => {
11493 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
11494 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11495 /******/ }
11496 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11497 /******/ };
11498 /******/ })();
11499 /******/
11500 /******/ /* webpack/runtime/nonce */
11501 /******/ (() => {
11502 /******/ __webpack_require__.nc = undefined;
11503 /******/ })();
11504 /******/
11505 /************************************************************************/
11506 var __webpack_exports__ = {};
11507 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11508 (() => {
11509 "use strict";
11510 /*!******************************************!*\
11511 !*** ./assets/src/js/admin/edit-quiz.js ***!
11512 \******************************************/
11513 __webpack_require__.r(__webpack_exports__);
11514 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ "./assets/src/js/utils.js");
11515 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
11516 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_1__);
11517 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
11518 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
11519 /* 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");
11520 /* harmony import */ var _edit_question_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./edit-question.js */ "./assets/src/js/admin/edit-question.js");
11521 /* harmony import */ var lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lpAssetsJsPath/lpPopupSelectItemToAdd.js */ "./assets/src/js/lpPopupSelectItemToAdd.js");
11522 /**
11523 * Edit Quiz JS handler as a class.
11524 *
11525 * @since 4.2.8.6
11526 * @version 1.0.3
11527 */
11528
11529
11530
11531
11532
11533
11534
11535 let editQuestion;
11536 const lpPopupSelectItemToAdd = new lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd();
11537 lpPopupSelectItemToAdd.init();
11538 class EditQuiz {
11539 constructor() {
11540 this.idUrlHandle = 'edit-quiz-questions';
11541 this.elEditQuizWrap = null;
11542 this.elEditListQuestions = null;
11543 this.quizID = null;
11544 }
11545 static selectors = {
11546 elEditQuizWrap: '.lp-edit-quiz-wrap',
11547 elQuestionEditMain: '.lp-question-edit-main',
11548 elQuestionToggleAll: '.lp-question-toggle-all',
11549 elEditListQuestions: '.lp-edit-list-questions',
11550 elQuestionItem: '.lp-question-item',
11551 elQuestionToggle: '.lp-question-toggle',
11552 elPopupItemsToSelectClone: '.lp-popup-items-to-select.clone',
11553 elBtnAddQuestion: '.lp-btn-add-question',
11554 elBtnRemoveQuestion: '.lp-btn-remove-question',
11555 elBtnUpdateQuestionTitle: '.lp-btn-update-question-title',
11556 elBtnCancelUpdateQuestionTitle: '.lp-btn-cancel-update-question-title',
11557 elQuestionTitleNewInput: '.lp-question-title-new-input',
11558 elQuestionTitleInput: '.lp-question-title-input',
11559 elQuestionTypeLabel: '.lp-question-type-label',
11560 elQuestionTypeNew: '.lp-question-type-new',
11561 elAddNewQuestion: 'add-new-question',
11562 elQuestionClone: '.lp-question-item.clone',
11563 LPTarget: '.lp-target',
11564 elCollapse: 'lp-collapse'
11565 };
11566 init() {
11567 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(EditQuiz.selectors.elEditQuizWrap, elEditQuizWrapFound => {
11568 this.elEditQuizWrap = elEditQuizWrapFound;
11569 this.elEditListQuestions = this.elEditQuizWrap.querySelector(EditQuiz.selectors.elEditListQuestions);
11570 const elLPTarget = this.elEditQuizWrap.closest(EditQuiz.selectors.LPTarget);
11571 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
11572 this.quizID = dataSend.args.quiz_id;
11573 this.sortAbleQuestion();
11574 editQuestion = new _edit_question_js__WEBPACK_IMPORTED_MODULE_5__.EditQuestion();
11575 editQuestion.init();
11576 const elQuestionEditMains = elEditQuizWrapFound.querySelectorAll(`${EditQuiz.selectors.elQuestionEditMain}`);
11577 elQuestionEditMains.forEach(elQuestionEditMain => {
11578 editQuestion.sortAbleQuestionAnswer(elQuestionEditMain);
11579 });
11580 this.events();
11581 });
11582 }
11583 events() {
11584 if (EditQuiz._loadedEvents) {
11585 return;
11586 }
11587 EditQuiz._loadedEvents = true;
11588 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
11589 selector: EditQuiz.selectors.elQuestionToggleAll,
11590 class: this,
11591 callBack: this.toggleQuestionAll.name
11592 }, {
11593 selector: EditQuiz.selectors.elBtnAddQuestion,
11594 class: this,
11595 callBack: this.addQuestion.name
11596 }, {
11597 selector: EditQuiz.selectors.elBtnRemoveQuestion,
11598 class: this,
11599 callBack: this.removeQuestion.name
11600 }, {
11601 selector: EditQuiz.selectors.elBtnUpdateQuestionTitle,
11602 class: this,
11603 callBack: this.updateQuestionTitle.name
11604 }, {
11605 selector: EditQuiz.selectors.elBtnCancelUpdateQuestionTitle,
11606 class: this,
11607 callBack: this.cancelChangeTitleQuestion.name
11608 }, {
11609 selector: lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected,
11610 class: lpPopupSelectItemToAdd,
11611 callBack: lpPopupSelectItemToAdd.addItemsSelectedToSection.name,
11612 callBackHandle: this.addQuestionsSelectedToQuiz.bind(this)
11613 }]);
11614
11615 // Keydown
11616 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keydown', [{
11617 selector: EditQuiz.selectors.elQuestionTitleInput,
11618 class: this,
11619 callBack: this.updateQuestionTitle.name,
11620 checkIsEventEnter: true
11621 }, {
11622 selector: EditQuiz.selectors.elQuestionTitleNewInput,
11623 class: this,
11624 callBack: this.addQuestion.name,
11625 checkIsEventEnter: true
11626 }]);
11627
11628 // Keyup
11629 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
11630 selector: EditQuiz.selectors.elQuestionTitleInput,
11631 class: this,
11632 callBack: this.changeTitleQuestion.name
11633 }, {
11634 selector: `${EditQuiz.selectors.elQuestionTitleNewInput}, ${EditQuiz.selectors.elQuestionTypeNew}`,
11635 class: this,
11636 callBack: this.checkCanAddQuestion.name
11637 }]);
11638
11639 // Change
11640 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('change', [{
11641 selector: EditQuiz.selectors.elQuestionTypeNew,
11642 class: this,
11643 callBack: this.checkCanAddQuestion.name
11644 }]);
11645
11646 // Click
11647 document.addEventListener('click', e => {
11648 const target = e.target;
11649 _utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCollapse(e, target, EditQuiz.selectors.elQuestionToggle, [], () => this.checkAllQuestionsCollapsed());
11650 });
11651 }
11652
11653 // Toggle all questions
11654 toggleQuestionAll(args) {
11655 const {
11656 e,
11657 target
11658 } = args;
11659 const elQuestionToggleAll = target.closest(`${EditQuiz.selectors.elQuestionToggleAll}`);
11660 if (!elQuestionToggleAll) {
11661 return;
11662 }
11663 const elQuestionItems = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11664 elQuestionToggleAll.classList.toggle(`${EditQuiz.selectors.elCollapse}`);
11665 elQuestionItems.forEach(el => {
11666 const shouldCollapse = elQuestionToggleAll.classList.contains(`${EditQuiz.selectors.elCollapse}`);
11667 el.classList.toggle(`${EditQuiz.selectors.elCollapse}`, shouldCollapse);
11668 });
11669 }
11670 checkAllQuestionsCollapsed() {
11671 const elQuestionItems = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11672 const elQuestionToggleAll = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionToggleAll}`);
11673 let isAllExpand = true;
11674 elQuestionItems.forEach(el => {
11675 if (el.classList.contains(`${EditQuiz.selectors.elCollapse}`)) {
11676 isAllExpand = false;
11677 return false; // Break
11678 }
11679 });
11680 if (isAllExpand) {
11681 elQuestionToggleAll.classList.remove(`${EditQuiz.selectors.elCollapse}`);
11682 } else {
11683 elQuestionToggleAll.classList.add(`${EditQuiz.selectors.elCollapse}`);
11684 }
11685 }
11686 updateCountItems() {
11687 const elCountItemsAll = this.elEditQuizWrap.querySelector('.total-items');
11688 const elItemsAll = this.elEditQuizWrap.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
11689 const itemsAllCount = elItemsAll.length;
11690 elCountItemsAll.dataset.count = itemsAllCount;
11691 elCountItemsAll.querySelector('.count').textContent = itemsAllCount;
11692 }
11693
11694 // Add question to quiz
11695 addQuestion(args) {
11696 const {
11697 e,
11698 target,
11699 callBackNest
11700 } = args;
11701 e.preventDefault();
11702 const elAddNewQuestion = target.closest(`.${EditQuiz.selectors.elAddNewQuestion}`);
11703 if (!elAddNewQuestion) {
11704 return;
11705 }
11706 const elQuestionTitleNewInput = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTitleNewInput}`);
11707 const questionTitle = elQuestionTitleNewInput.value.trim();
11708 if (!questionTitle) {
11709 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(elQuestionTitleNewInput.dataset.messEmptyTitle, 'error');
11710 return;
11711 }
11712 const elQuestionType = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTypeNew}`);
11713 const questionType = elQuestionType.value;
11714 if (!questionType) {
11715 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(elQuestionType.dataset.messEmptyType, 'error');
11716 return;
11717 }
11718 const elQuestionClone = this.elEditListQuestions.querySelector(`${EditQuiz.selectors.elQuestionItem}.clone`);
11719 const newQuestionItem = elQuestionClone.cloneNode(true);
11720 const elQuestionTitleInput = newQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11721 elQuestionTitleInput.value = questionTitle;
11722 elQuestionTitleNewInput.value = '';
11723 newQuestionItem.classList.remove('clone');
11724 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(newQuestionItem, 1);
11725 elQuestionClone.insertAdjacentElement('beforebegin', newQuestionItem);
11726 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(newQuestionItem, 1);
11727 const callBack = {
11728 success: response => {
11729 const {
11730 message,
11731 status,
11732 data
11733 } = response;
11734 const {
11735 question,
11736 html_edit_question
11737 } = data;
11738 if (status === 'error') {
11739 throw `Error: ${message}`;
11740 } else if (status === 'success') {
11741 newQuestionItem.dataset.questionId = question.ID;
11742 newQuestionItem.dataset.questionType = question.meta_data._lp_type;
11743 newQuestionItem.outerHTML = html_edit_question;
11744 const elQuestionItemCreated = this.elEditListQuestions.querySelector(`${EditQuiz.selectors.elQuestionItem}[data-question-id="${question.ID}"]`);
11745 elQuestionItemCreated.classList.remove(EditQuiz.selectors.elCollapse);
11746 this.updateCountItems();
11747 editQuestion.initTinyMCE();
11748 const elQuestionEditMain = elQuestionItemCreated.querySelector(`${EditQuiz.selectors.elQuestionEditMain}`);
11749 editQuestion.sortAbleQuestionAnswer(elQuestionEditMain);
11750
11751 // Callback nest
11752 if (callBackNest && typeof callBackNest.success === 'function') {
11753 callBackNest.success({
11754 response,
11755 elQuestionItemCreated
11756 });
11757 }
11758 }
11759 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11760 },
11761 error: error => {
11762 newQuestionItem.remove();
11763 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11764 if (callBackNest && typeof callBackNest.error === 'function') {
11765 callBackNest.error({
11766 error,
11767 newQuestionItem
11768 });
11769 }
11770 },
11771 completed: () => {
11772 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(newQuestionItem, 0);
11773 this.checkCanAddQuestion({
11774 e,
11775 target: elQuestionTitleNewInput
11776 });
11777 if (callBackNest && typeof callBackNest.completed === 'function') {
11778 callBackNest.completed({
11779 newQuestionItem
11780 });
11781 }
11782 }
11783 };
11784 let dataSend = JSON.parse(elQuestionTitleNewInput.dataset.send);
11785 dataSend = {
11786 ...dataSend,
11787 question_title: questionTitle,
11788 question_type: questionType
11789 };
11790 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11791 }
11792
11793 // Add questions selected from popup to quiz
11794 addQuestionsSelectedToQuiz(itemsSelected) {
11795 const questionIds = [];
11796 itemsSelected.forEach(item => {
11797 const elQuestionItemClone = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionItem}.clone`);
11798 if (!elQuestionItemClone) {
11799 return;
11800 }
11801 questionIds.push(item.id);
11802 const elQuestionItemNew = elQuestionItemClone.cloneNode(true);
11803 const elQuestionItemTitleInput = elQuestionItemNew.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11804 elQuestionItemNew.classList.remove('clone');
11805 elQuestionItemNew.dataset.questionId = item.id;
11806 elQuestionItemTitleInput.value = item.titleSelected;
11807 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItemNew, 1);
11808 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elQuestionItemNew, 1);
11809 elQuestionItemClone.insertAdjacentElement('beforebegin', elQuestionItemNew);
11810 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItemNew, 1);
11811 });
11812 const callBack = {
11813 success: response => {
11814 const {
11815 message,
11816 status,
11817 data
11818 } = response;
11819 if (status === 'success') {
11820 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11821 const {
11822 html_edit_question
11823 } = data;
11824 if (html_edit_question) {
11825 Object.entries(html_edit_question).forEach(([question_id, item_html]) => {
11826 const elQuestionItemNew = this.elEditQuizWrap.querySelector(`${EditQuiz.selectors.elQuestionItem}[data-question-id="${question_id}"]`);
11827 elQuestionItemNew.outerHTML = item_html;
11828 });
11829 }
11830 this.updateCountItems();
11831 editQuestion.initTinyMCE();
11832 } else {
11833 throw `Error: ${message}`;
11834 }
11835 },
11836 error: error => {
11837 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11838 },
11839 completed: () => {
11840 // completed handler intentionally empty
11841 }
11842 };
11843 const dataSend = {
11844 action: 'add_questions_to_quiz',
11845 quiz_id: this.quizID,
11846 question_ids: questionIds,
11847 args: {
11848 id_url: this.idUrlHandle
11849 }
11850 };
11851 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11852 }
11853 checkCanAddQuestion(args) {
11854 const {
11855 e,
11856 target
11857 } = args;
11858 const elTrigger = target.closest(EditQuiz.selectors.elQuestionTitleNewInput) || target.closest(EditQuiz.selectors.elQuestionTypeNew);
11859 if (!elTrigger) {
11860 return;
11861 }
11862 const elAddNewQuestion = elTrigger.closest(`.${EditQuiz.selectors.elAddNewQuestion}`);
11863 if (!elAddNewQuestion) {
11864 return;
11865 }
11866 const elBtnAddQuestion = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elBtnAddQuestion}`);
11867 if (!elBtnAddQuestion) {
11868 return;
11869 }
11870 const elQuestionTitleInput = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTitleNewInput}`);
11871 const elQuestionTypeNew = elAddNewQuestion.querySelector(`${EditQuiz.selectors.elQuestionTypeNew}`);
11872 const questionTitle = elQuestionTitleInput.value.trim();
11873 const questionType = elQuestionTypeNew.value;
11874 if (questionTitle && questionType) {
11875 elBtnAddQuestion.classList.add('active');
11876 } else {
11877 elBtnAddQuestion.classList.remove('active');
11878 }
11879 }
11880 removeQuestion(args) {
11881 const {
11882 e,
11883 target
11884 } = args;
11885 const elBtnRemoveQuestion = target.closest(`${EditQuiz.selectors.elBtnRemoveQuestion}`);
11886 if (!elBtnRemoveQuestion) {
11887 return;
11888 }
11889 const elQuestionItem = elBtnRemoveQuestion.closest(`${EditQuiz.selectors.elQuestionItem}`);
11890 if (!elQuestionItem) {
11891 return;
11892 }
11893 const questionId = elQuestionItem.dataset.questionId;
11894 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
11895 title: elBtnRemoveQuestion.dataset.title,
11896 text: elBtnRemoveQuestion.dataset.content,
11897 icon: 'warning',
11898 showCloseButton: true,
11899 showCancelButton: true,
11900 cancelButtonText: lpDataAdmin.i18n.cancel,
11901 confirmButtonText: lpDataAdmin.i18n.yes,
11902 reverseButtons: true
11903 }).then(result => {
11904 if (result.isConfirmed) {
11905 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11906 const callBack = {
11907 success: response => {
11908 const {
11909 message,
11910 status
11911 } = response;
11912 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11913 if (status === 'success') {
11914 elQuestionItem.remove();
11915 this.updateCountItems();
11916 }
11917 },
11918 error: error => {
11919 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11920 },
11921 completed: () => {
11922 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11923 }
11924 };
11925 const dataSend = {
11926 quiz_id: this.quizID,
11927 action: 'remove_question_from_quiz',
11928 question_id: questionId,
11929 args: {
11930 id_url: this.idUrlHandle
11931 }
11932 };
11933 window.lpAJAXG.fetchAJAX(dataSend, callBack);
11934 }
11935 });
11936 }
11937 updateQuestionTitle(args) {
11938 const {
11939 e,
11940 target
11941 } = args;
11942 let canHandle = false;
11943 if (target.closest(`${EditQuiz.selectors.elBtnUpdateQuestionTitle}`)) {
11944 canHandle = true;
11945 } else if (target.closest(`${EditQuiz.selectors.elQuestionTitleInput}`) && e.key === 'Enter') {
11946 canHandle = true;
11947 }
11948 if (!canHandle) {
11949 return;
11950 }
11951 e.preventDefault();
11952 const elQuestionItem = target.closest(`${EditQuiz.selectors.elQuestionItem}`);
11953 if (!elQuestionItem) {
11954 return;
11955 }
11956 const elQuestionTitleInput = elQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
11957 if (!elQuestionTitleInput) {
11958 return;
11959 }
11960 const questionId = elQuestionItem.dataset.questionId;
11961 const questionTitleValue = elQuestionTitleInput.value.trim();
11962 const titleOld = elQuestionTitleInput.dataset.old;
11963 const message = elQuestionTitleInput.dataset.messEmptyTitle;
11964 if (questionTitleValue.length === 0) {
11965 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, 'error');
11966 return;
11967 }
11968 if (questionTitleValue === titleOld) {
11969 return;
11970 }
11971 elQuestionTitleInput.blur();
11972 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
11973 const callBack = {
11974 success: response => {
11975 const {
11976 message,
11977 status
11978 } = response;
11979 if (status === 'success') {
11980 elQuestionTitleInput.dataset.old = questionTitleValue;
11981 } else {
11982 elQuestionTitleInput.value = titleOld;
11983 }
11984 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
11985 },
11986 error: error => {
11987 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
11988 },
11989 completed: () => {
11990 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
11991 elQuestionItem.classList.remove('editing');
11992 }
11993 };
11994 const dataSend = {
11995 quiz_id: this.quizID,
11996 action: 'update_question',
11997 question_id: questionId,
11998 question_title: questionTitleValue,
11999 args: {
12000 id_url: this.idUrlHandle
12001 }
12002 };
12003 window.lpAJAXG.fetchAJAX(dataSend, callBack);
12004 }
12005 changeTitleQuestion(args) {
12006 const {
12007 e,
12008 target
12009 } = args;
12010 const elQuestionTitleInput = target.closest(`${EditQuiz.selectors.elQuestionTitleInput}`);
12011 if (!elQuestionTitleInput) {
12012 return;
12013 }
12014 const elQuestionItem = elQuestionTitleInput.closest(`${EditQuiz.selectors.elQuestionItem}`);
12015 const titleValue = elQuestionTitleInput.value.trim();
12016 const titleValueOld = elQuestionTitleInput.dataset.old || '';
12017 if (titleValue === titleValueOld) {
12018 elQuestionItem.classList.remove('editing');
12019 } else {
12020 elQuestionItem.classList.add('editing');
12021 }
12022 }
12023 cancelChangeTitleQuestion(args) {
12024 const {
12025 e,
12026 target
12027 } = args;
12028 const elBtnCancelUpdateQuestionTitle = target.closest(`${EditQuiz.selectors.elBtnCancelUpdateQuestionTitle}`);
12029 if (!elBtnCancelUpdateQuestionTitle) {
12030 return;
12031 }
12032 const elQuestionItem = elBtnCancelUpdateQuestionTitle.closest(`${EditQuiz.selectors.elQuestionItem}`);
12033 const elQuestionTitleInput = elQuestionItem.querySelector(`${EditQuiz.selectors.elQuestionTitleInput}`);
12034 elQuestionTitleInput.value = elQuestionTitleInput.dataset.old || '';
12035 elQuestionItem.classList.remove('editing');
12036 }
12037 sortAbleQuestion() {
12038 let isUpdateSectionPosition = 0;
12039 let timeout;
12040 new sortablejs__WEBPACK_IMPORTED_MODULE_2__["default"](this.elEditListQuestions, {
12041 handle: '.drag',
12042 animation: 150,
12043 onEnd: evt => {
12044 const elQuestionItem = evt.item;
12045 if (!isUpdateSectionPosition) {
12046 return;
12047 }
12048 clearTimeout(timeout);
12049 timeout = setTimeout(() => {
12050 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 1);
12051 const questionIds = [];
12052 const elQuestionItems = this.elEditListQuestions.querySelectorAll(`${EditQuiz.selectors.elQuestionItem}:not(.clone)`);
12053 elQuestionItems.forEach(elItem => {
12054 const questionId = elItem.dataset.questionId;
12055 if (questionId) {
12056 questionIds.push(questionId);
12057 }
12058 });
12059 const callBack = {
12060 success: response => {
12061 const {
12062 message,
12063 status
12064 } = response;
12065 if (status === 'success') {
12066 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
12067 editQuestion.initTinyMCE();
12068 } else {
12069 throw `Error: ${message}`;
12070 }
12071 },
12072 error: error => {
12073 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
12074 },
12075 completed: () => {
12076 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(elQuestionItem, 0);
12077 isUpdateSectionPosition = 0;
12078 }
12079 };
12080 const dataSend = {
12081 quiz_id: this.quizID,
12082 action: 'update_questions_position',
12083 question_ids: questionIds,
12084 args: {
12085 id_url: this.idUrlHandle
12086 }
12087 };
12088 window.lpAJAXG.fetchAJAX(dataSend, callBack);
12089 }, 1000);
12090 },
12091 onMove: () => {
12092 clearTimeout(timeout);
12093 },
12094 onUpdate: () => {
12095 isUpdateSectionPosition = 1;
12096 }
12097 });
12098 }
12099 }
12100 const editQuiz = new EditQuiz();
12101 editQuiz.init();
12102 })();
12103
12104 /******/ })()
12105 ;
12106 //# sourceMappingURL=edit-quiz.js.map