PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.3
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.3
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.3, at assets/dist/js/admin/edit-quiz.js

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