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

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

12,664 lines 453.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./assets/src/js/admin/edit-course/edit-curriculum.js"
5 /*!************************************************************!*\
6 !*** ./assets/src/js/admin/edit-course/edit-curriculum.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 */ EditCourseCurriculum: () => (/* binding */ EditCourseCurriculum)
14 /* harmony export */ });
15 /* harmony import */ var _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./edit-curriculum/edit-section.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js");
16 /* harmony import */ var _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./edit-curriculum/edit-section-item.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js");
17 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
18 /**
19 * Edit Curriculum JS handler.
20 *
21 * @since 4.2.8.6
22 * @version 1.0.2
23 */
24
25
26
27 const sectionEdit = new _edit_curriculum_edit_section_js__WEBPACK_IMPORTED_MODULE_0__.EditSection();
28 const sectionItemEdit = new _edit_curriculum_edit_section_item_js__WEBPACK_IMPORTED_MODULE_1__.EditSectionItem();
29 class EditCourseCurriculum {
30 constructor() {
31 this.init();
32 }
33 static selectors = {
34 idElEditCurriculum: '#lp-course-edit-curriculum',
35 elCurriculumSections: '.curriculum-sections',
36 elToggleAllSections: '.course-toggle-all-sections',
37 LPTarget: '.lp-target',
38 elCollapse: 'lp-collapse'
39 };
40 init() {
41 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpOnElementReady(`${EditCourseCurriculum.selectors.idElEditCurriculum}`, elEditCurriculum => {
42 // Set variables use for section edit
43 sectionEdit.init();
44
45 // Set variables use for edit section item
46 sectionItemEdit.init();
47 });
48 }
49 }
50
51 /***/ },
52
53 /***/ "./assets/src/js/admin/edit-course/edit-curriculum/edit-curriculum-ai.js"
54 /*!*******************************************************************************!*\
55 !*** ./assets/src/js/admin/edit-course/edit-curriculum/edit-curriculum-ai.js ***!
56 \*******************************************************************************/
57 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
58
59 "use strict";
60 __webpack_require__.r(__webpack_exports__);
61 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
62 /* harmony export */ EditCurriculumAi: () => (/* binding */ EditCurriculumAi)
63 /* harmony export */ });
64 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
65 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
66 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
67 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
68 /* harmony import */ var _edit_section_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./edit-section.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js");
69 /* harmony import */ var _edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./edit-section-item.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js");
70 /* harmony import */ var lpAssetsJsPath_admin_edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lpAssetsJsPath/admin/edit-course/edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
71 /**
72 * Generate data with OpenAI
73 */
74
75
76
77
78
79
80
81 let editSection = null;
82 let editSectionItem = null;
83 class EditCurriculumAi {
84 constructor(options = {}) {
85 this.options = {
86 isCourseBuilder: false,
87 ...options
88 };
89 this.init();
90 }
91 static selectors = {
92 elBtnApplyCurriculum: '.lp-btn-apply-curriculum'
93 };
94 init() {
95 if (!lpData?.enable_open_ai) {
96 return;
97 }
98 if (this.options.isCourseBuilder) {
99 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(lpAssetsJsPath_admin_edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.idElEditCurriculum, el => {
100 const elCountSections = el.querySelector(_edit_section_js__WEBPACK_IMPORTED_MODULE_3__.EditSection.selectors.elCountSections);
101 elCountSections.insertAdjacentHTML('beforebegin', `<button type="button"
102 class="cb-course-edit-ai-btn lp-btn-generate-with-ai"
103 data-template="#lp-tmpl-edit-course-curriculum-ai">
104 <i class="lp-ico-ai"></i>
105 </button>`);
106 });
107 } else {
108 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady(lpAssetsJsPath_admin_edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.idElEditCurriculum, el => {
109 const elCountSections = el.querySelector(_edit_section_js__WEBPACK_IMPORTED_MODULE_3__.EditSection.selectors.elCountSections);
110 elCountSections.insertAdjacentHTML('afterend', `<button type="button"
111 class="lp-btn-generate-with-ai lp-btn-ai-style"
112 data-template="#lp-tmpl-edit-course-curriculum-ai">
113 <i class="lp-ico-ai"></i><span>Generate with AI</span>
114 </button>`);
115 });
116 }
117 this.events();
118 }
119 events() {
120 if (EditCurriculumAi._loadedEvents) {
121 return;
122 }
123 EditCurriculumAi._loadedEvents = true;
124 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
125 selector: EditCurriculumAi.selectors.elBtnApplyCurriculum,
126 class: this,
127 callBack: this.applyData.name
128 }]);
129 }
130 async applyData(args) {
131 const {
132 e,
133 target
134 } = args;
135 let dataSend = JSON.parse(target.dataset.send);
136 dataSend = lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(target.closest('form'), dataSend);
137 if (!dataSend['lp-openai-generated-data']) {
138 return;
139 }
140 const data = JSON.parse(dataSend['lp-openai-generated-data']);
141
142 //console.log( 'Generated Data:', data );
143
144 const sections = data[0].sections;
145 if (!sections || sections.length === 0) {
146 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show('No sections found in the generated data.', 'error');
147 }
148
149 // console.log( 'Generated Sections:', sections );
150
151 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().close();
152
153 // Wait half second to ensure SweetAlert is closed completely
154 await new Promise(resolve => setTimeout(resolve, 500));
155
156 // New edit section instance
157 editSection = new _edit_section_js__WEBPACK_IMPORTED_MODULE_3__.EditSection();
158 editSection.init();
159
160 // New edit section item instance
161 editSectionItem = new _edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__.EditSectionItem();
162 editSectionItem.init();
163
164 // Scroll to element add section
165 const elEditCurriculum = document.querySelector(lpAssetsJsPath_admin_edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.idElEditCurriculum);
166 const elDivAddNewSection = elEditCurriculum.querySelector(_edit_section_js__WEBPACK_IMPORTED_MODULE_3__.EditSection.selectors.elDivAddNewSection);
167 elDivAddNewSection.scrollIntoView({
168 behavior: 'smooth',
169 block: 'center'
170 });
171
172 // Wait 800ms to ensure scroll completely
173 await new Promise(resolve => setTimeout(resolve, 800));
174 for (const sectionData of sections) {
175 // Set title
176 const elSectionTitleNewInput = elEditCurriculum.querySelector(_edit_section_js__WEBPACK_IMPORTED_MODULE_3__.EditSection.selectors.elSectionTitleNewInput);
177 const elBtnAddSection = elEditCurriculum.querySelector(_edit_section_js__WEBPACK_IMPORTED_MODULE_3__.EditSection.selectors.elBtnAddSection);
178 elSectionTitleNewInput.value = sectionData.section_title || '';
179 await new Promise(resolve => {
180 editSection.addSection({
181 e: new PointerEvent('click'),
182 target: elBtnAddSection,
183 callBackNest: this.updateSectionDescription({
184 sectionData,
185 elEditCurriculum
186 }),
187 resolve
188 });
189 });
190 }
191 }
192
193 /**
194 * Update section description after create new section
195 * @param args
196 */
197 updateSectionDescription(args) {
198 const {
199 sectionData,
200 elEditCurriculum
201 } = args;
202 return {
203 success: async args => {
204 const {
205 elSection
206 } = args;
207 await new Promise(resolve => setTimeout(resolve, 1000));
208
209 // Set description for the new section
210 const elSectionDesInput = elSection.querySelector(_edit_section_js__WEBPACK_IMPORTED_MODULE_3__.EditSection.selectors.elSectionDesInput);
211 elSectionDesInput.value = sectionData.section_description || '';
212
213 // Call AJAX to save description
214 await new Promise(resolve => {
215 editSection.updateSectionDescription({
216 e: new PointerEvent('click'),
217 target: elSectionDesInput,
218 callBackNest: this.addSectionItems({
219 sectionData,
220 elEditCurriculum
221 }),
222 resolve
223 });
224 });
225 setTimeout(args.resolve, 1);
226 },
227 error: error => {},
228 completed: () => {}
229 };
230 }
231 addSectionItems(args) {
232 const {
233 sectionData,
234 elEditCurriculum
235 } = args;
236 const lessons = sectionData.lessons || [];
237 const quizzes = sectionData.quizzes || [];
238 return {
239 success: async args => {
240 //await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) );
241 const {
242 elSection
243 } = args;
244 const elBtnSelectItemTypeLesson = elSection.querySelector(`${_edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__.EditSectionItem.selectors.elBtnSelectItemType}[data-item-type=lp_lesson]`);
245 const elBtnSelectItemTypeQuiz = elSection.querySelector(`${_edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__.EditSectionItem.selectors.elBtnSelectItemType}[data-item-type=lp_quiz]`);
246 for (const itemData of lessons) {
247 elBtnSelectItemTypeLesson.click();
248 await this.addItemToSection({
249 itemData,
250 elSection,
251 elEditCurriculum
252 });
253 }
254 for (const itemData of quizzes) {
255 elBtnSelectItemTypeQuiz.click();
256 await this.addItemToSection({
257 itemData,
258 elSection,
259 elEditCurriculum
260 });
261 }
262 setTimeout(args.resolve, 1);
263 },
264 error: error => {},
265 completed: () => {}
266 };
267 }
268 async addItemToSection(args) {
269 const {
270 itemData,
271 elSection,
272 elEditCurriculum
273 } = args;
274 const elBtnAddItem = elSection.querySelector(_edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__.EditSectionItem.selectors.elBtnAddItem);
275 const elAddItemTypeTitleInput = elSection.querySelector(_edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__.EditSectionItem.selectors.elAddItemTypeTitleInput);
276 elAddItemTypeTitleInput.value = itemData.lesson_title || itemData.quiz_title || '';
277
278 // Scroll to element add item
279 elBtnAddItem.scrollIntoView({
280 behavior: 'smooth',
281 block: 'center'
282 });
283
284 // Call AJAX to add item to section
285 await new Promise(resolve => {
286 editSectionItem.addItemToSection({
287 e: new PointerEvent('click'),
288 target: elBtnAddItem,
289 resolve,
290 callBackNest: {
291 completed: async args => {
292 setTimeout(resolve, 1000);
293 }
294 }
295 });
296 });
297 setTimeout(args.resolve, 1);
298 }
299 }
300
301 /***/ },
302
303 /***/ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js"
304 /*!******************************************************************************!*\
305 !*** ./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js ***!
306 \******************************************************************************/
307 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
308
309 "use strict";
310 __webpack_require__.r(__webpack_exports__);
311 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
312 /* harmony export */ EditSectionItem: () => (/* binding */ EditSectionItem)
313 /* harmony export */ });
314 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
315 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_0__);
316 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
317 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
318 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
319 /* harmony import */ var _edit_curriculum_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
320 /* harmony import */ var _edit_section_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./edit-section.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js");
321 /* harmony import */ var lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! lpAssetsJsPath/lpPopupSelectItemToAdd.js */ "./assets/src/js/lpPopupSelectItemToAdd.js");
322 /**
323 * Edit Section item Script on Curriculum
324 *
325 * @version 1.0.3
326 * @since 4.2.8.6
327 */
328
329
330
331
332
333
334
335 const idUrlHandle = 'edit-course-curriculum';
336 const lpPopupSelectItemToAdd = new lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd();
337 class EditSectionItem {
338 constructor() {
339 this.courseId = null;
340 this.elCurriculumSections = null;
341 this.sectionIdSelected = null;
342 }
343 static selectors = {
344 elSectionListItems: '.section-list-items',
345 elItemClone: '.section-item.clone',
346 elSectionItem: '.section-item',
347 elBtnSelectItemType: '.lp-btn-select-item-type',
348 elAddItemTypeClone: '.lp-add-item-type.clone',
349 elSectionActions: '.section-actions',
350 elAddItemType: '.lp-add-item-type',
351 elAddItemTypeTitleInput: '.lp-add-item-type-title-input',
352 elBtnAddItemCancel: '.lp-btn-add-item-cancel',
353 elBtnAddItem: '.lp-btn-add-item',
354 elItemTitleInput: '.lp-item-title-input',
355 elBtnUpdateItemTitle: '.lp-btn-update-item-title',
356 elBtnCancelUpdateTitle: '.lp-btn-cancel-update-item-title',
357 elBtnDeleteItem: '.lp-btn-delete-item',
358 elBtnSetPreviewItem: '.lp-btn-set-preview-item'
359 };
360 init() {
361 this.elEditCurriculum = document.querySelector(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_4__.EditCourseCurriculum.selectors.idElEditCurriculum}`);
362 this.elCurriculumSections = this.elEditCurriculum.querySelector(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_4__.EditCourseCurriculum.selectors.elCurriculumSections}`);
363 const elLPTarget = this.elEditCurriculum.closest(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_4__.EditCourseCurriculum.selectors.LPTarget}`);
364 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
365 this.courseId = dataSend.args.course_id;
366 this.events();
367 this.sortAbleItem();
368 lpPopupSelectItemToAdd.init();
369 }
370
371 /* Events */
372 events() {
373 // Check and attach events only once
374 if (EditSectionItem._loadedEvents) {
375 return;
376 }
377 EditSectionItem._loadedEvents = this;
378
379 // Click events
380 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('click', [{
381 selector: EditSectionItem.selectors.elBtnSelectItemType,
382 class: this,
383 callBack: this.addItemType.name
384 }, {
385 selector: EditSectionItem.selectors.elBtnAddItem,
386 class: this,
387 callBack: this.addItemToSection.name
388 }, {
389 selector: EditSectionItem.selectors.elBtnAddItemCancel,
390 class: this,
391 callBack: this.cancelAddItemType.name
392 }, {
393 selector: EditSectionItem.selectors.elBtnUpdateItemTitle,
394 class: this,
395 callBack: this.updateTitle.name
396 }, {
397 selector: EditSectionItem.selectors.elBtnCancelUpdateTitle,
398 class: this,
399 callBack: this.cancelUpdateTitle.name
400 }, {
401 selector: EditSectionItem.selectors.elBtnDeleteItem,
402 class: this,
403 callBack: this.deleteItem.name
404 }, {
405 selector: lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect,
406 class: this,
407 callBack: this.handleShowPopupItemsToSelect.name
408 }, {
409 selector: lpAssetsJsPath_lpPopupSelectItemToAdd_js__WEBPACK_IMPORTED_MODULE_6__.LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected,
410 class: lpPopupSelectItemToAdd,
411 callBack: lpPopupSelectItemToAdd.addItemsSelectedToSection.name,
412 callBackHandle: this.addItemsSelectedToSection.bind(this)
413 }, {
414 selector: EditSectionItem.selectors.elBtnSetPreviewItem,
415 class: this,
416 callBack: this.updatePreviewItem.name
417 }]);
418
419 // Keyup events
420 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('keyup', [{
421 selector: EditSectionItem.selectors.elItemTitleInput,
422 class: this,
423 callBack: this.changeTitle.name
424 }, {
425 selector: EditSectionItem.selectors.elAddItemTypeTitleInput,
426 class: this,
427 callBack: this.changeTitleAddNew.name
428 }]);
429
430 // Keydown events
431 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('keydown', [{
432 selector: EditSectionItem.selectors.elAddItemTypeTitleInput,
433 class: this,
434 callBack: this.addItemToSection.name,
435 checkIsEventEnter: true
436 }, {
437 selector: EditSectionItem.selectors.elItemTitleInput,
438 class: this,
439 callBack: this.updateTitle.name,
440 checkIsEventEnter: true
441 }]);
442
443 // Focusin events
444 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('focusin', [{
445 selector: EditSectionItem.selectors.elItemTitleInput,
446 class: this,
447 callBack: this.focusTitleInput.name
448 }]);
449
450 // Focusout events
451 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('focusout', [{
452 selector: EditSectionItem.selectors.elItemTitleInput,
453 class: this,
454 callBack: this.focusTitleInput.name,
455 focusIn: false
456 }]);
457 }
458
459 /* Handle show popup items to select - set sectionIdSelected */
460 handleShowPopupItemsToSelect(args) {
461 const {
462 e,
463 target
464 } = args;
465 const elQuizWrap = target.closest('.lp-edit-quiz-wrap');
466 if (elQuizWrap) {
467 this.sectionIdSelected = null;
468 return;
469 }
470 const elSection = target.closest(_edit_section_js__WEBPACK_IMPORTED_MODULE_5__.EditSection.selectors.elSection);
471 const elEditCurriculum = target.closest('#lp-course-edit-curriculum') || target.closest('.lp-edit-curriculum-wrap');
472 if (elSection && elEditCurriculum) {
473 this.sectionIdSelected = elSection.dataset.sectionId;
474 } else {
475 this.sectionIdSelected = null;
476 }
477 }
478
479 /* Add item type */
480 addItemType(args) {
481 const {
482 e,
483 target
484 } = args;
485 const elBtnSelectItemType = target;
486 const itemType = elBtnSelectItemType.dataset.itemType;
487 const itemPlaceholder = elBtnSelectItemType.dataset.placeholder;
488 const itemBtnAddText = elBtnSelectItemType.dataset.buttonAddText;
489 const elSection = elBtnSelectItemType.closest(`${_edit_section_js__WEBPACK_IMPORTED_MODULE_5__.EditSection.selectors.elSection}`);
490 const elSectionActions = elSection.querySelector(`${EditSectionItem.selectors.elSectionActions}`);
491
492 // Insert input item type to add
493 const elAddItemTypeClone = elSectionActions.querySelector(`${EditSectionItem.selectors.elAddItemTypeClone}`);
494 const elNewItemByType = elAddItemTypeClone.cloneNode(true);
495 const elAddItemTypeInput = elNewItemByType.querySelector(`${EditSectionItem.selectors.elAddItemTypeTitleInput}`);
496 const elBtnAddItem = elNewItemByType.querySelector(`${EditSectionItem.selectors.elBtnAddItem}`);
497 elNewItemByType.classList.remove('clone');
498 elNewItemByType.classList.add(itemType);
499 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elNewItemByType, 1);
500 elAddItemTypeInput.setAttribute('placeholder', itemPlaceholder);
501 elAddItemTypeInput.dataset.itemType = itemType;
502 elBtnAddItem.textContent = itemBtnAddText;
503 elSectionActions.insertAdjacentElement('beforebegin', elNewItemByType);
504 elAddItemTypeInput.focus();
505 }
506
507 /* Cancel add item type */
508 cancelAddItemType(args) {
509 const {
510 e,
511 target
512 } = args;
513 const elAddItemType = target.closest(`${EditSectionItem.selectors.elAddItemType}`);
514 if (elAddItemType) {
515 elAddItemType.remove();
516 }
517 }
518
519 /* Add item to section */
520 addItemToSection(args) {
521 const {
522 e,
523 target,
524 callBackNest
525 } = args;
526 e.preventDefault();
527 const elAddItemType = target.closest(`${EditSectionItem.selectors.elAddItemType}`);
528 const elSection = elAddItemType.closest(`${_edit_section_js__WEBPACK_IMPORTED_MODULE_5__.EditSection.selectors.elSection}`);
529 const sectionId = elSection.dataset.sectionId;
530 const elAddItemTypeTitleInput = elAddItemType.querySelector(`${EditSectionItem.selectors.elAddItemTypeTitleInput}`);
531 const titleValue = elAddItemTypeTitleInput.value.trim();
532 const typeValue = elAddItemTypeTitleInput.dataset.itemType;
533 const message = elAddItemTypeTitleInput.dataset.messEmptyTitle;
534 if (titleValue.length === 0) {
535 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, 'error');
536 return;
537 }
538
539 // Clone new section item
540 const elItemClone = elSection.querySelector(`${EditSectionItem.selectors.elItemClone}`);
541 const elItemNew = elItemClone.cloneNode(true);
542 const elItemTitleInput = elItemNew.querySelector(`${EditSectionItem.selectors.elItemTitleInput}`);
543 elItemNew.classList.remove('clone');
544 elItemNew.classList.add(typeValue);
545 elItemNew.dataset.itemType = typeValue;
546 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elItemNew, 1);
547 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elItemNew, 1);
548 elItemTitleInput.value = titleValue;
549 elItemTitleInput.dataset.old = titleValue;
550 elItemClone.insertAdjacentElement('beforebegin', elItemNew);
551 elAddItemType.remove();
552
553 // Call ajax to add item to section
554 const callBack = {
555 success: response => {
556 const {
557 message,
558 status,
559 data
560 } = response;
561 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
562 if (status === 'error') {
563 elItemNew.remove();
564 } else if (status === 'success') {
565 const {
566 section_item,
567 item_link
568 } = data || {};
569 const itemId = section_item.item_id || 0;
570 elItemNew.dataset.itemId = itemId;
571 elItemNew.querySelector('.edit-link').setAttribute('href', item_link || '');
572
573 // Add popup attributes for Course Builder context
574 this.addPopupAttributesToItem(elItemNew, itemId, typeValue);
575
576 // Call callback nest if exists
577 if (callBackNest && typeof callBackNest.success === 'function') {
578 args.elItemNew = elItemNew;
579 callBackNest.success(args);
580 }
581 }
582 },
583 error: error => {
584 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
585 elItemNew.remove();
586 },
587 completed: () => {
588 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elItemNew, 0);
589 this.updateCountItems(elSection);
590
591 // Call callback nest if exists
592 if (callBackNest && typeof callBackNest.completed === 'function') {
593 args.elItemNew = elItemNew;
594 callBackNest.completed(args);
595 }
596 }
597 };
598 const dataSend = {
599 course_id: this.courseId,
600 action: 'create_item_add_to_section',
601 section_id: sectionId,
602 item_title: titleValue,
603 item_type: typeValue,
604 args: {
605 id_url: idUrlHandle
606 }
607 };
608 if (document.querySelector('#lp-course-builder')) {
609 dataSend.is_course_builder = 1;
610 }
611 window.lpAJAXG.fetchAJAX(dataSend, callBack);
612 }
613
614 /* Typing in title input */
615 changeTitle(args) {
616 const {
617 target
618 } = args;
619 const elItemTitleInput = target.closest(`${EditSectionItem.selectors.elItemTitleInput}`);
620 if (!elItemTitleInput) {
621 return;
622 }
623 const elSectionItem = elItemTitleInput.closest(`${EditSectionItem.selectors.elSectionItem}`);
624 if (!elSectionItem) {
625 return;
626 }
627 const titleValue = elItemTitleInput.value.trim();
628 const titleValueOld = elItemTitleInput.dataset.old || '';
629 if (titleValue === titleValueOld) {
630 elSectionItem.classList.remove('editing');
631 } else {
632 elSectionItem.classList.add('editing');
633 }
634 }
635
636 /* Focus in item title input */
637 focusTitleInput(args) {
638 const {
639 target,
640 focusIn = true
641 } = args;
642 const elItemTitleInput = target.closest(`${EditSectionItem.selectors.elItemTitleInput}`);
643 if (!elItemTitleInput) {
644 return;
645 }
646 const elSectionItem = elItemTitleInput.closest(`${EditSectionItem.selectors.elSectionItem}`);
647 if (!elSectionItem) {
648 return;
649 }
650 if (focusIn) {
651 elSectionItem.classList.add('focus');
652 } else {
653 elSectionItem.classList.remove('focus');
654 }
655 }
656 changeTitleAddNew(args) {
657 const {
658 target
659 } = args;
660 const elAddItemTypeTitleInput = target.closest(`${EditSectionItem.selectors.elAddItemTypeTitleInput}`);
661 if (!elAddItemTypeTitleInput) {
662 return;
663 }
664 const elAddItemType = elAddItemTypeTitleInput.closest(`${EditSectionItem.selectors.elAddItemType}`);
665 if (!elAddItemType) {
666 return;
667 }
668 const elBtnAddItem = elAddItemType.querySelector(`${EditSectionItem.selectors.elBtnAddItem}`);
669 if (!elBtnAddItem) {
670 return;
671 }
672 const titleValue = elAddItemTypeTitleInput.value.trim();
673 if (titleValue.length === 0) {
674 elBtnAddItem.classList.remove('active');
675 } else {
676 elBtnAddItem.classList.add('active');
677 }
678 }
679
680 /* Update item title */
681 updateTitle(args) {
682 const {
683 e,
684 target
685 } = args;
686 e.preventDefault();
687 const elSectionItem = target.closest(`${EditSectionItem.selectors.elSectionItem}`);
688 if (!elSectionItem) {
689 return;
690 }
691 const elSection = elSectionItem.closest(`${_edit_section_js__WEBPACK_IMPORTED_MODULE_5__.EditSection.selectors.elSection}`);
692 if (!elSection) {
693 return;
694 }
695 const elItemTitleInput = elSectionItem.querySelector(`${EditSectionItem.selectors.elItemTitleInput}`);
696 if (!elItemTitleInput) {
697 return;
698 }
699 const itemId = elSectionItem.dataset.itemId;
700 const itemType = elSectionItem.dataset.itemType;
701 const itemTitleValue = elItemTitleInput.value.trim();
702 const titleOld = elItemTitleInput.dataset.old;
703 const message = elItemTitleInput.dataset.messEmptyTitle;
704 if (itemTitleValue.length === 0) {
705 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, 'error');
706 return;
707 }
708 if (itemTitleValue === titleOld) {
709 return;
710 }
711
712 // Un-focus input item title
713 elItemTitleInput.blur();
714 // show loading
715 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSectionItem, 1);
716 // Call ajax to update item title
717 const callBack = {
718 success: response => {
719 const {
720 message,
721 status
722 } = response;
723 if (status === 'success') {
724 elItemTitleInput.dataset.old = itemTitleValue;
725 } else {
726 elItemTitleInput.value = titleOld;
727 }
728 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
729 },
730 error: error => {
731 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
732 },
733 completed: () => {
734 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSectionItem, 0);
735 elSectionItem.classList.remove('editing');
736 }
737 };
738 const dataSend = {
739 course_id: this.courseId,
740 action: 'update_item_of_section',
741 section_id: elSection.dataset.sectionId,
742 item_id: itemId,
743 item_type: itemType,
744 item_title: itemTitleValue,
745 args: {
746 id_url: idUrlHandle
747 }
748 };
749 window.lpAJAXG.fetchAJAX(dataSend, callBack);
750 }
751
752 /* Cancel update item title */
753 cancelUpdateTitle(args) {
754 const {
755 e,
756 target
757 } = args;
758 const elBtnCancelUpdateTitle = target.closest(`${EditSectionItem.selectors.elBtnCancelUpdateTitle}`);
759 if (!elBtnCancelUpdateTitle) {
760 return;
761 }
762 const elSectionItem = elBtnCancelUpdateTitle.closest(`${EditSectionItem.selectors.elSectionItem}`);
763 const elItemTitleInput = elSectionItem.querySelector(`${EditSectionItem.selectors.elItemTitleInput}`);
764 elItemTitleInput.value = elItemTitleInput.dataset.old || '';
765 elSectionItem.classList.remove('editing');
766 }
767
768 /* Delete item from section */
769 deleteItem(args) {
770 const {
771 e,
772 target
773 } = args;
774 const elBtnDeleteItem = target.closest(`${EditSectionItem.selectors.elBtnDeleteItem}`);
775 if (!elBtnDeleteItem) {
776 return;
777 }
778 const elSectionItem = elBtnDeleteItem.closest(`${EditSectionItem.selectors.elSectionItem}`);
779 if (!elSectionItem) {
780 return;
781 }
782 const itemId = elSectionItem.dataset.itemId;
783 const elSection = elSectionItem.closest(`${_edit_section_js__WEBPACK_IMPORTED_MODULE_5__.EditSection.selectors.elSection}`);
784 const sectionId = elSection.dataset.sectionId;
785 sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
786 title: elBtnDeleteItem.dataset.title,
787 text: elBtnDeleteItem.dataset.content,
788 icon: 'warning',
789 showCloseButton: true,
790 showCancelButton: true,
791 cancelButtonText: lpData.i18n.cancel,
792 confirmButtonText: lpData.i18n.yes,
793 reverseButtons: true
794 }).then(result => {
795 if (result.isConfirmed) {
796 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSectionItem, 1);
797
798 // Call ajax to delete item from section
799 const callBack = {
800 success: response => {
801 const {
802 message,
803 status
804 } = response;
805 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
806 if (status === 'success') {
807 elSectionItem.remove();
808 }
809 },
810 error: error => {
811 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
812 },
813 completed: () => {
814 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSectionItem, 0);
815 this.updateCountItems(elSection);
816 }
817 };
818 const dataSend = {
819 course_id: this.courseId,
820 action: 'delete_item_from_section',
821 section_id: sectionId,
822 item_id: itemId,
823 args: {
824 id_url: idUrlHandle
825 }
826 };
827 window.lpAJAXG.fetchAJAX(dataSend, callBack);
828 }
829 });
830 }
831
832 /* Sortable items, can drop on multiple sections */
833 sortAbleItem() {
834 const elSectionListItems = this.elCurriculumSections.querySelectorAll(`${EditSectionItem.selectors.elSectionListItems}`);
835 let itemIdChoose = 0;
836 let elSectionChoose;
837 let sectionIdChoose = 0;
838 let sectionIdEnd = 0;
839 let timeout;
840 elSectionListItems.forEach(elItem => {
841 new sortablejs__WEBPACK_IMPORTED_MODULE_1__["default"](elItem, {
842 handle: '.drag',
843 animation: 150,
844 group: {
845 name: 'shared'
846 },
847 onEnd: evt => {
848 const dataSectionsItems = [];
849 const elItemDragged = evt.item;
850 sectionIdEnd = elItemDragged.closest(`${_edit_section_js__WEBPACK_IMPORTED_MODULE_5__.EditSection.selectors.elSection}`).dataset.sectionId;
851 const dataSend = {
852 course_id: this.courseId,
853 args: {
854 id_url: idUrlHandle
855 }
856 };
857 dataSend.action = 'update_item_section_and_position';
858 dataSend.item_id_change = itemIdChoose;
859 dataSend.section_id_new_of_item = sectionIdEnd;
860 dataSend.section_id_old_of_item = sectionIdChoose;
861
862 // Send list items position
863 const section = this.elCurriculumSections.querySelector(`.section[data-section-id="${sectionIdEnd}"]`);
864 const items = section.querySelectorAll(`${EditSectionItem.selectors.elSectionItem}`);
865 items.forEach(elItem => {
866 const itemId = parseInt(elItem.dataset.itemId || 0);
867 if (itemId === 0) {
868 return;
869 }
870 dataSectionsItems.push(itemId);
871 });
872 dataSend.items_position = dataSectionsItems;
873
874 // Call ajax to update items position
875 const callBack = {
876 success: response => {
877 const {
878 message,
879 status
880 } = response;
881 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
882 },
883 error: error => {
884 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
885 },
886 completed: () => {
887 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elItemDragged, 0);
888 this.updateCountItems(section);
889 if (sectionIdChoose !== sectionIdEnd) {
890 this.updateCountItems(elSectionChoose);
891 }
892 }
893 };
894 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elItemDragged, 1);
895 window.lpAJAXG.fetchAJAX(dataSend, callBack);
896 },
897 onMove: (/*evt*/) => {},
898 onChoose: evt => {
899 const elChooseItem = evt.item;
900 itemIdChoose = elChooseItem.dataset.itemId;
901 elSectionChoose = elChooseItem.closest(`${_edit_section_js__WEBPACK_IMPORTED_MODULE_5__.EditSection.selectors.elSection}`);
902 sectionIdChoose = elSectionChoose.dataset.sectionId;
903 },
904 onUpdate: (/*evt*/) => {}
905 });
906 });
907 }
908
909 /* Add items selected to section */
910 addItemsSelectedToSection(itemsSelectedData) {
911 // Skip if not in curriculum context (e.g., quiz popup)
912 if (!this.sectionIdSelected) {
913 return;
914 }
915 const elSection = document.querySelector(`.section[data-section-id="${this.sectionIdSelected}"]`);
916
917 // Skip if section element not found
918 if (!elSection) {
919 return;
920 }
921 const elItemClone = elSection.querySelector(`${EditSectionItem.selectors.elItemClone}`);
922
923 // Check if we're in Course Builder context
924 const isCourseBuilder = document.querySelector('#lp-course-builder') !== null;
925 itemsSelectedData.forEach(item => {
926 const elItemNew = elItemClone.cloneNode(true);
927 const elInputTitleNew = elItemNew.querySelector(`${EditSectionItem.selectors.elItemTitleInput}`);
928 elItemNew.dataset.itemId = item.id;
929 elItemNew.classList.add(item.type);
930 elItemNew.classList.remove('clone');
931 elItemNew.dataset.itemType = item.type;
932 elItemNew.querySelector('.edit-link').setAttribute('href', item.editLink || '');
933 elInputTitleNew.value = item.titleSelected || '';
934 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elItemNew, 1);
935 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elItemNew, 1);
936 elItemClone.insertAdjacentElement('beforebegin', elItemNew);
937 });
938 sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().close();
939 const dataSend = {
940 course_id: this.courseId,
941 action: 'add_items_to_section',
942 section_id: this.sectionIdSelected,
943 items: itemsSelectedData,
944 is_course_builder: isCourseBuilder ? 1 : 0,
945 args: {
946 id_url: idUrlHandle
947 }
948 };
949 window.lpAJAXG.fetchAJAX(dataSend, {
950 success: response => {
951 const {
952 message,
953 status,
954 data
955 } = response;
956 const {
957 html
958 } = data || '';
959 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
960 itemsSelectedData.forEach(item => {
961 const elItemAdded = elSection.querySelector(`${EditSectionItem.selectors.elSectionItem}[data-item-id="${item.id}"]`);
962 if (elItemAdded) {
963 elItemAdded.remove();
964 }
965 });
966 if (status === 'success' && html) {
967 // Server returns HTML with popup attributes already included when is_course_builder=1
968 elItemClone.insertAdjacentHTML('beforebegin', html);
969 }
970 },
971 error: error => {
972 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
973 },
974 completed: () => {
975 this.updateCountItems(elSection);
976 }
977 });
978 }
979
980 /* Enable/disable preview item */
981 updatePreviewItem(args) {
982 const {
983 e,
984 target
985 } = args;
986 const elBtnSetPreviewItem = target.closest(`${EditSectionItem.selectors.elBtnSetPreviewItem}`);
987 if (!elBtnSetPreviewItem) {
988 return;
989 }
990 const elSectionItem = elBtnSetPreviewItem.closest(`${EditSectionItem.selectors.elSectionItem}`);
991 if (!elSectionItem) {
992 return;
993 }
994 const icon = elBtnSetPreviewItem.querySelector('a');
995 icon.classList.toggle('lp-icon-eye');
996 icon.classList.toggle('lp-icon-eye-slash');
997 const enablePreview = !icon.classList.contains('lp-icon-eye-slash');
998 const itemId = elSectionItem.dataset.itemId;
999 const itemType = elSectionItem.dataset.itemType;
1000 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSectionItem, 1);
1001
1002 // Call ajax to update item preview
1003 const callBack = {
1004 success: response => {
1005 const {
1006 message,
1007 status
1008 } = response;
1009 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
1010 if (status === 'error') {
1011 icon.classList.toggle('lp-icon-eye');
1012 icon.classList.toggle('lp-icon-eye-slash');
1013 }
1014 },
1015 error: error => {
1016 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
1017 icon.classList.toggle('lp-icon-eye');
1018 icon.classList.toggle('lp-icon-eye-slash');
1019 },
1020 completed: () => {
1021 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSectionItem, 0);
1022 }
1023 };
1024 const dataSend = {
1025 course_id: this.courseId,
1026 action: 'update_item_preview',
1027 item_id: itemId,
1028 item_type: itemType,
1029 enable_preview: enablePreview ? 1 : 0,
1030 args: {
1031 id_url: idUrlHandle
1032 }
1033 };
1034 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1035 }
1036
1037 /* Update count items when item add/delete or section delete */
1038 updateCountItems(elSection) {
1039 const elEditCurriculum = this.elEditCurriculum;
1040 const elCountItemsAll = elEditCurriculum.querySelector('.total-items');
1041 const elItemsAll = elEditCurriculum.querySelectorAll(`${EditSectionItem.selectors.elSectionItem}:not(.clone)`);
1042 const itemsAllCount = elItemsAll.length;
1043 elCountItemsAll.dataset.count = itemsAllCount;
1044 elCountItemsAll.querySelector('.count').textContent = itemsAllCount;
1045
1046 // Count items in section
1047 const elSectionItemsCount = elSection.querySelector('.section-items-counts');
1048 const elItems = elSection.querySelectorAll(`${EditSectionItem.selectors.elSectionItem}:not(.clone)`);
1049 const itemsCount = elItems.length;
1050 elSectionItemsCount.dataset.count = itemsCount;
1051 elSectionItemsCount.querySelector('.count').textContent = itemsCount;
1052 }
1053
1054 /**
1055 * Add popup attributes to item element for Course Builder context.
1056 * Only applies when in Course Builder (not admin edit course page).
1057 *
1058 * @param {HTMLElement} elItem - The item element
1059 * @param {number} itemId - The item ID
1060 * @param {string} itemType - The item type (lp_lesson, lp_quiz, lp_assignment)
1061 */
1062 addPopupAttributesToItem(elItem, itemId, itemType) {
1063 // Check if we're in Course Builder context
1064 const isCourseBuilder = document.querySelector('#lp-course-builder') !== null;
1065 if (!isCourseBuilder || !itemId) {
1066 return;
1067 }
1068 const popupType = itemType.replace(/^lp_/, '');
1069 const templateSelector = `#lp-tmpl-builder-popup-curriculum-${popupType}-course-${this.courseId}`;
1070 if (!popupType || !document.querySelector(templateSelector)) {
1071 return;
1072 }
1073
1074 // Find the edit link element - it's an <a> with class 'edit-link' inside .item-actions
1075 const editLink = elItem.querySelector('.item-actions .edit-link');
1076 if (!editLink) {
1077 return;
1078 }
1079
1080 // Get the parent <li> element of the edit link
1081 const editBtn = editLink.closest('li');
1082 if (!editBtn) {
1083 return;
1084 }
1085
1086 // Add popup data attributes based on item type
1087 if (itemType === 'lp_lesson') {
1088 editBtn.setAttribute('data-popup-lesson', itemId);
1089 } else if (itemType === 'lp_quiz') {
1090 editBtn.setAttribute('data-popup-quiz', itemId);
1091 }
1092
1093 // Add popup class to the <li> element
1094 editBtn.classList.add('lp-btn-edit-item-popup');
1095
1096 // Update edit link: remove target="_blank" and update classes for popup behavior
1097 editLink.removeAttribute('target');
1098 editLink.removeAttribute('href');
1099 editLink.classList.add('edit-popup-link');
1100
1101 // Store additional data for popup on the <li> element
1102 editBtn.setAttribute('data-course-id', this.courseId);
1103 editBtn.setAttribute('data-popup-type', popupType);
1104 editBtn.setAttribute('data-popup-id', itemId);
1105 editBtn.setAttribute('data-template', templateSelector);
1106 }
1107 }
1108
1109 /***/ },
1110
1111 /***/ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js"
1112 /*!*************************************************************************!*\
1113 !*** ./assets/src/js/admin/edit-course/edit-curriculum/edit-section.js ***!
1114 \*************************************************************************/
1115 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1116
1117 "use strict";
1118 __webpack_require__.r(__webpack_exports__);
1119 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1120 /* harmony export */ EditSection: () => (/* binding */ EditSection)
1121 /* harmony export */ });
1122 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1123 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_0__);
1124 /* harmony import */ var sortablejs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sortablejs */ "./node_modules/sortablejs/modular/sortable.esm.js");
1125 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
1126 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
1127 /* harmony import */ var _edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./edit-section-item.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-section-item.js");
1128 /* harmony import */ var _edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
1129 /**
1130 * Edit Section Script on Curriculum
1131 *
1132 * @since 4.2.8.6
1133 * @version 1.0.3
1134 */
1135
1136
1137
1138
1139
1140
1141 class EditSection {
1142 constructor() {
1143 this.courseId = null;
1144 this.elEditCurriculum = null;
1145 this.elCurriculumSections = null;
1146 this.editSectionItem = new _edit_section_item_js__WEBPACK_IMPORTED_MODULE_4__.EditSectionItem();
1147 }
1148 static selectors = {
1149 elSection: '.section',
1150 elDivAddNewSection: '.add-new-section',
1151 elSectionClone: '.section.clone',
1152 elSectionTitleNewInput: '.lp-section-title-new-input',
1153 elSectionTitleInput: '.lp-section-title-input',
1154 etBtnEditTitle: '.lp-btn-edit-section-title',
1155 elSectionDesInput: '.lp-section-description-input',
1156 elBtnAddSection: '.lp-btn-add-section',
1157 elBtnUpdateTitle: '.lp-btn-update-section-title',
1158 elBtnUpdateDes: '.lp-btn-update-section-description',
1159 elBtnCancelUpdateTitle: '.lp-btn-cancel-update-section-title',
1160 elBtnCancelUpdateDes: '.lp-btn-cancel-update-section-description',
1161 elBtnDeleteSection: '.lp-btn-delete-section',
1162 elSectionDesc: '.section-description',
1163 elSectionToggle: '.section-toggle',
1164 elCountSections: '.count-sections'
1165 };
1166 init() {
1167 this.elEditCurriculum = document.querySelector(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.idElEditCurriculum}`);
1168 this.elCurriculumSections = this.elEditCurriculum.querySelector(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCurriculumSections}`);
1169 const elLPTarget = this.elEditCurriculum.closest(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.LPTarget}`);
1170 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
1171 this.courseId = dataSend.args.course_id;
1172 this.editSectionItem.init();
1173 this.events();
1174 this.sortAbleSection();
1175 }
1176 events() {
1177 // Check and attach events only once
1178 if (EditSection._loadedEvents) {
1179 return;
1180 }
1181 EditSection._loadedEvents = this;
1182
1183 // Click events
1184 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('click', [{
1185 selector: EditSection.selectors.elBtnAddSection,
1186 class: this,
1187 callBack: this.addSection.name
1188 }, {
1189 selector: `${EditSection.selectors.elBtnUpdateDes}`,
1190 class: this,
1191 callBack: this.updateSectionDescription.name
1192 }, {
1193 selector: `${EditSection.selectors.etBtnEditTitle}`,
1194 class: this,
1195 callBack: this.setFocusTitleInput.name
1196 }, {
1197 selector: `${EditSection.selectors.elSectionToggle}`,
1198 class: this,
1199 callBack: this.toggleSection.name
1200 }, {
1201 selector: `${EditSection.selectors.elBtnCancelUpdateDes}`,
1202 class: this,
1203 callBack: this.cancelSectionDescription.name
1204 }, {
1205 selector: `${EditSection.selectors.elBtnDeleteSection}`,
1206 class: this,
1207 callBack: this.deleteSection.name
1208 }, {
1209 selector: `${EditSection.selectors.elBtnUpdateTitle}`,
1210 class: this,
1211 callBack: this.updateSectionTitle.name
1212 }, {
1213 selector: `${EditSection.selectors.elBtnCancelUpdateTitle}`,
1214 class: this,
1215 callBack: this.cancelSectionTitle.name
1216 }, {
1217 selector: _edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elToggleAllSections,
1218 class: this,
1219 callBack: this.toggleSectionAll.name
1220 }]);
1221
1222 // Keyup events
1223 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('keyup', [{
1224 selector: EditSection.selectors.elSectionTitleNewInput,
1225 class: this,
1226 callBack: this.changeTitleBeforeAdd.name
1227 }, {
1228 selector: EditSection.selectors.elSectionTitleInput,
1229 class: this,
1230 callBack: this.changeTitle.name
1231 }, {
1232 selector: EditSection.selectors.elSectionDesInput,
1233 class: this,
1234 callBack: this.changeDescription.name
1235 }]);
1236
1237 // Keydown events
1238 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('keydown', [{
1239 selector: EditSection.selectors.elSectionTitleNewInput,
1240 class: this,
1241 callBack: this.addSection.name,
1242 checkIsEventEnter: true
1243 }, {
1244 selector: EditSection.selectors.elSectionDesInput,
1245 class: this,
1246 callBack: this.updateSectionDescription.name,
1247 checkIsEventEnter: true
1248 }, {
1249 selector: EditSection.selectors.elSectionTitleInput,
1250 class: this,
1251 callBack: this.updateSectionTitle.name,
1252 checkIsEventEnter: true
1253 }]);
1254
1255 // Focusin events
1256 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('focusin', [{
1257 selector: EditSection.selectors.elSectionTitleNewInput,
1258 class: this,
1259 callBack: this.focusTitleNewInput.name
1260 }, {
1261 selector: EditSection.selectors.elSectionTitleInput,
1262 class: this,
1263 callBack: this.focusTitleInput.name
1264 }]);
1265
1266 // Focusin events
1267 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('focusout', [{
1268 selector: EditSection.selectors.elSectionTitleNewInput,
1269 class: this,
1270 callBack: this.focusTitleNewInput.name,
1271 focusIn: false
1272 }, {
1273 selector: `${EditSection.selectors.elSectionTitleInput}`,
1274 class: this,
1275 callBack: this.focusTitleInput.name,
1276 focusIn: false
1277 }]);
1278 }
1279
1280 /* Typing in new section title input */
1281 changeTitleBeforeAdd(args) {
1282 const {
1283 e,
1284 target
1285 } = args;
1286 const elSectionTitleNewInput = target;
1287 const elAddNewSection = elSectionTitleNewInput.closest(`${EditSection.selectors.elDivAddNewSection}`);
1288 if (!elAddNewSection) {
1289 return;
1290 }
1291 const elBtnAddSection = elAddNewSection.querySelector(`${EditSection.selectors.elBtnAddSection}`);
1292 const titleValue = elSectionTitleNewInput.value.trim();
1293 if (titleValue.length === 0) {
1294 elBtnAddSection.classList.remove('active');
1295 } else {
1296 elBtnAddSection.classList.add('active');
1297 }
1298 }
1299
1300 /* Focus on new section title input */
1301 focusTitleNewInput(args) {
1302 const {
1303 e,
1304 target,
1305 focusIn = true
1306 } = args;
1307 const elAddNewSection = target.closest(`${EditSection.selectors.elDivAddNewSection}`);
1308 if (!elAddNewSection) {
1309 return;
1310 }
1311 if (focusIn) {
1312 elAddNewSection.classList.add('focus');
1313 } else {
1314 elAddNewSection.classList.remove('focus');
1315 }
1316 }
1317
1318 /* Add new section */
1319 addSection(args) {
1320 const {
1321 e,
1322 target,
1323 callBackNest
1324 } = args;
1325 const elDivAddNewSection = target.closest(`${EditSection.selectors.elDivAddNewSection}`);
1326 if (!elDivAddNewSection) {
1327 return;
1328 }
1329 e.preventDefault();
1330 const elSectionTitleNewInput = elDivAddNewSection.querySelector(`${EditSection.selectors.elSectionTitleNewInput}`);
1331 const titleValue = elSectionTitleNewInput.value.trim();
1332 const message = elSectionTitleNewInput.dataset.messEmptyTitle;
1333 if (titleValue.length === 0) {
1334 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, 'error');
1335 return;
1336 }
1337
1338 // Clear input after add
1339 elSectionTitleNewInput.value = '';
1340 elSectionTitleNewInput.blur();
1341
1342 // Add and set data for new section
1343 const elSectionClone = this.elCurriculumSections.querySelector(`${EditSection.selectors.elSectionClone}`);
1344 const newSection = elSectionClone.cloneNode(true);
1345 newSection.classList.remove('clone');
1346 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(newSection, 1);
1347 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(newSection, 1);
1348 const elSectionTitleInput = newSection.querySelector(`${EditSection.selectors.elSectionTitleInput}`);
1349 elSectionTitleInput.value = titleValue;
1350 this.elCurriculumSections.insertAdjacentElement('beforeend', newSection);
1351 // End
1352
1353 // Call ajax to add new section
1354 const callBack = {
1355 success: response => {
1356 const {
1357 message,
1358 status,
1359 data
1360 } = response;
1361 if (status === 'error') {
1362 newSection.remove();
1363 throw message;
1364 } else if (status === 'success') {
1365 const {
1366 section
1367 } = data;
1368 newSection.dataset.sectionId = section.section_id || '';
1369
1370 // Initialize EditSectionItem for the new section to make its items sortable
1371 this.editSectionItem.sortAbleItem();
1372 if (callBackNest && typeof callBackNest.success === 'function') {
1373 args.elSection = newSection;
1374 args.response = response;
1375 callBackNest.success(args);
1376 }
1377 }
1378 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
1379 },
1380 error: error => {
1381 newSection.remove();
1382 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
1383 if (callBackNest && typeof callBackNest.error === 'function') {
1384 args.error = error;
1385 callBackNest.error(args);
1386 }
1387 },
1388 completed: () => {
1389 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(newSection, 0);
1390 newSection.classList.remove(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`);
1391 const elSectionDesInput = newSection.querySelector(`${EditSection.selectors.elSectionDesInput}`);
1392 elSectionDesInput.focus();
1393 this.updateCountSections(this.elEditCurriculum);
1394 if (callBackNest && typeof callBackNest.completed === 'function') {
1395 args.elSection = newSection;
1396 callBackNest.completed(args);
1397 }
1398 }
1399 };
1400 const dataSend = JSON.parse(elSectionTitleNewInput.dataset.send);
1401 dataSend.section_name = titleValue;
1402 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1403 }
1404
1405 /* Delete section */
1406 deleteSection(args) {
1407 const {
1408 e,
1409 target
1410 } = args;
1411 const elBtnDeleteSection = target;
1412 const elEditCurriculum = elBtnDeleteSection.closest(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.idElEditCurriculum}`);
1413 sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
1414 title: elBtnDeleteSection.dataset.title,
1415 text: elBtnDeleteSection.dataset.content,
1416 icon: 'warning',
1417 showCloseButton: true,
1418 showCancelButton: true,
1419 cancelButtonText: lpData.i18n.cancel,
1420 confirmButtonText: lpData.i18n.yes,
1421 reverseButtons: true
1422 }).then(result => {
1423 if (result.isConfirmed) {
1424 const elSection = elBtnDeleteSection.closest('.section');
1425 const sectionId = elSection.dataset.sectionId;
1426 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 1);
1427
1428 // Call ajax to delete section
1429 const callBack = {
1430 success: response => {
1431 const {
1432 message,
1433 status
1434 } = response;
1435 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
1436 },
1437 error: error => {
1438 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
1439 },
1440 completed: () => {
1441 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 0);
1442 elSection.remove();
1443 this.editSectionItem.updateCountItems(elSection);
1444 this.updateCountSections(elEditCurriculum);
1445 }
1446 };
1447 const dataSend = JSON.parse(elBtnDeleteSection.dataset.send);
1448 dataSend.section_id = sectionId;
1449 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1450 }
1451 });
1452 }
1453
1454 /* Focus on section title input */
1455 focusTitleInput(args) {
1456 const {
1457 e,
1458 target,
1459 focusIn = true
1460 } = args;
1461 const elSection = target.closest(`${EditSection.selectors.elSection}`);
1462 if (!elSection) {
1463 return;
1464 }
1465 if (focusIn) {
1466 elSection.classList.add('focus');
1467 } else {
1468 elSection.classList.remove('focus');
1469 }
1470 }
1471
1472 /* Set focus on section title input */
1473 setFocusTitleInput(args) {
1474 const {
1475 e,
1476 target
1477 } = args;
1478 const elSection = target.closest(`${EditSection.selectors.elSection}`);
1479 if (!elSection) {
1480 return;
1481 }
1482 const elSectionTitleInput = elSection.querySelector(`${EditSection.selectors.elSectionTitleInput}`);
1483 elSectionTitleInput.setSelectionRange(elSectionTitleInput.value.length, elSectionTitleInput.value.length);
1484 elSectionTitleInput.focus();
1485 }
1486
1487 /* Typing in section title input */
1488 changeTitle(args) {
1489 const {
1490 e,
1491 target
1492 } = args;
1493 const elSectionTitleInput = target;
1494 const elSection = elSectionTitleInput.closest(`${EditSection.selectors.elSection}`);
1495 const titleValue = elSectionTitleInput.value.trim();
1496 const titleValueOld = elSectionTitleInput.dataset.old || '';
1497 if (titleValue === titleValueOld) {
1498 elSection.classList.remove('editing');
1499 } else {
1500 elSection.classList.add('editing');
1501 }
1502 }
1503
1504 /* Update section title to server */
1505 updateSectionTitle(args) {
1506 const {
1507 e,
1508 target
1509 } = args;
1510 const elSection = target.closest(`${EditSection.selectors.elSection}`);
1511 if (!elSection) {
1512 return;
1513 }
1514 e.preventDefault();
1515 const elSectionTitleInput = elSection.querySelector(`${EditSection.selectors.elSectionTitleInput}`);
1516 if (!elSectionTitleInput) {
1517 return;
1518 }
1519 const sectionId = elSection.dataset.sectionId;
1520 const titleValue = elSectionTitleInput.value.trim();
1521 const titleValueOld = elSectionTitleInput.dataset.old || '';
1522 const message = elSectionTitleInput.dataset.messEmptyTitle;
1523 if (titleValue.length === 0) {
1524 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, 'error');
1525 return;
1526 }
1527 if (titleValue === titleValueOld) {
1528 return;
1529 }
1530 elSectionTitleInput.blur();
1531 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 1);
1532
1533 // Call ajax to update section title
1534 const callBack = {
1535 success: response => {
1536 const {
1537 message,
1538 status
1539 } = response;
1540 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
1541 if (status === 'success') {
1542 elSectionTitleInput.dataset.old = titleValue;
1543 }
1544 },
1545 error: error => {
1546 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
1547 },
1548 completed: () => {
1549 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 0);
1550 elSection.classList.remove('editing');
1551 }
1552 };
1553 const dataSend = JSON.parse(elSectionTitleInput.dataset.send);
1554 dataSend.section_id = sectionId;
1555 dataSend.section_name = titleValue;
1556 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1557 }
1558
1559 /* Cancel updating section title */
1560 cancelSectionTitle(args) {
1561 const {
1562 e,
1563 target
1564 } = args;
1565 const elBtnCancelUpdateTitle = target.closest(`${EditSection.selectors.elBtnCancelUpdateTitle}`);
1566 if (!elBtnCancelUpdateTitle) {
1567 return;
1568 }
1569 const elSection = elBtnCancelUpdateTitle.closest(`${EditSection.selectors.elSection}`);
1570 const elSectionTitleInput = elSection.querySelector(`${EditSection.selectors.elSectionTitleInput}`);
1571 elSectionTitleInput.value = elSectionTitleInput.dataset.old || '';
1572 elSection.classList.remove('editing');
1573 }
1574
1575 /* Update section description to server */
1576 updateSectionDescription(args) {
1577 const {
1578 e,
1579 target,
1580 callBackNest
1581 } = args;
1582 const elSectionDesc = target.closest(`${EditSection.selectors.elSectionDesc}`);
1583 if (!elSectionDesc) {
1584 return;
1585 }
1586 const elSectionDesInput = elSectionDesc.querySelector(`${EditSection.selectors.elSectionDesInput}`);
1587 if (!elSectionDesInput) {
1588 return;
1589 }
1590 e.preventDefault();
1591 const elSection = elSectionDesInput.closest(`${EditSection.selectors.elSection}`);
1592 const sectionId = elSection.dataset.sectionId;
1593 const descValue = elSectionDesInput.value.trim();
1594 const descValueOld = elSectionDesInput.dataset.old || '';
1595 if (descValue === descValueOld) {
1596 return;
1597 }
1598 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 1);
1599 const callBack = {
1600 success: response => {
1601 const {
1602 message,
1603 status
1604 } = response;
1605 if (callBackNest && typeof callBackNest.success === 'function') {
1606 args.elSection = elSection;
1607 args.response = response;
1608 callBackNest.success(args);
1609 }
1610 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
1611 },
1612 error: error => {
1613 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
1614 if (callBackNest && typeof callBackNest.error === 'function') {
1615 callBackNest.error(elSection, error);
1616 }
1617 },
1618 completed: () => {
1619 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 0);
1620 const elSectionDesc = elSectionDesInput.closest(`${EditSection.selectors.elSectionDesc}`);
1621 elSectionDesc.classList.remove('editing');
1622 elSectionDesInput.dataset.old = descValue;
1623 if (callBackNest && typeof callBackNest.completed === 'function') {
1624 callBackNest.completed(elSection);
1625 }
1626 }
1627 };
1628 const dataSend = JSON.parse(elSectionDesInput.dataset.send);
1629 dataSend.section_id = sectionId;
1630 dataSend.section_description = descValue;
1631 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1632 }
1633
1634 /* Cancel updating section description */
1635 cancelSectionDescription(args) {
1636 const {
1637 e,
1638 target
1639 } = args;
1640 const elSectionDesc = target.closest(`${EditSection.selectors.elSectionDesc}`);
1641 const elSectionDesInput = elSectionDesc.querySelector(`${EditSection.selectors.elSectionDesInput}`);
1642 elSectionDesInput.value = elSectionDesInput.dataset.old || '';
1643 elSectionDesc.classList.remove('editing');
1644 }
1645
1646 /* Typing in description input */
1647 changeDescription(ags) {
1648 const {
1649 e,
1650 target
1651 } = ags;
1652 const elSectionDesInput = target.closest(`${EditSection.selectors.elSectionDesInput}`);
1653 if (!elSectionDesInput) {
1654 return;
1655 }
1656 const elSectionDesc = elSectionDesInput.closest(`${EditSection.selectors.elSectionDesc}`);
1657 const descValue = elSectionDesInput.value.trim();
1658 const descValueOld = elSectionDesInput.dataset.old || '';
1659 if (descValue === descValueOld) {
1660 elSectionDesc.classList.remove('editing');
1661 } else {
1662 elSectionDesc.classList.add('editing');
1663 }
1664 }
1665 toggleSectionAll(args) {
1666 const {
1667 e,
1668 target
1669 } = args;
1670 const elToggleAllSections = target.closest(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elToggleAllSections}`);
1671 if (!elToggleAllSections) {
1672 return;
1673 }
1674 const elEditCurriculum = elToggleAllSections.closest(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.idElEditCurriculum}`);
1675 const elSections = elEditCurriculum.querySelectorAll(`${EditSection.selectors.elSection}:not(.clone)`);
1676 elToggleAllSections.classList.toggle(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`);
1677 elSections.forEach(el => {
1678 const shouldCollapse = elToggleAllSections.classList.contains(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`);
1679 el.classList.toggle(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`, shouldCollapse);
1680 });
1681 }
1682
1683 /* Toggle section */
1684 toggleSection(args) {
1685 const {
1686 e,
1687 target
1688 } = args;
1689 const elSection = target.closest(`${EditSection.selectors.elSection}`);
1690 const elCurriculumSections = elSection.closest(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCurriculumSections}`);
1691 if (!elCurriculumSections) {
1692 return;
1693 }
1694
1695 // Toggle section
1696 elSection.classList.toggle(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`);
1697
1698 // Check all sections collapsed
1699 this.checkAllSectionsCollapsed();
1700 }
1701
1702 /* Check if all sections are collapsed */
1703 checkAllSectionsCollapsed() {
1704 const elSections = this.elEditCurriculum.querySelectorAll(`${EditSection.selectors.elSection}:not(.clone)`);
1705 const elToggleAllSections = this.elEditCurriculum.querySelector(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elToggleAllSections}`);
1706 let isAllExpand = true;
1707 elSections.forEach(el => {
1708 if (el.classList.contains(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`)) {
1709 isAllExpand = false;
1710 return false; // Break the loop
1711 }
1712 });
1713 if (isAllExpand) {
1714 elToggleAllSections.classList.remove(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`);
1715 } else {
1716 elToggleAllSections.classList.add(`${_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_5__.EditCourseCurriculum.selectors.elCollapse}`);
1717 }
1718 }
1719
1720 /* Sortable sections, drag and drop to change section position */
1721 sortAbleSection() {
1722 let isUpdateSectionPosition = 0;
1723 let timeout;
1724 new sortablejs__WEBPACK_IMPORTED_MODULE_1__["default"](this.elCurriculumSections, {
1725 handle: '.drag',
1726 animation: 150,
1727 onEnd: evt => {
1728 const target = evt.item;
1729 if (!isUpdateSectionPosition) {
1730 return;
1731 }
1732 const elSection = target.closest(`${EditSection.selectors.elSection}`);
1733 const elSections = this.elCurriculumSections.querySelectorAll(`${EditSection.selectors.elSection}`);
1734 const sectionIds = [];
1735 elSections.forEach(elSection => {
1736 const sectionId = elSection.dataset.sectionId;
1737 sectionIds.push(sectionId);
1738 });
1739
1740 // Call ajax to update section position
1741 const callBack = {
1742 success: response => {
1743 const {
1744 message,
1745 status
1746 } = response;
1747 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(message, status);
1748 },
1749 error: error => {
1750 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_3__.show(error, 'error');
1751 },
1752 completed: () => {
1753 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 0);
1754 isUpdateSectionPosition = 0;
1755 }
1756 };
1757 const dataSend = {
1758 action: 'course_update_section_position',
1759 course_id: this.courseId,
1760 new_position: sectionIds,
1761 args: {
1762 id_url: 'course-update-section-position'
1763 }
1764 };
1765 clearTimeout(timeout);
1766 timeout = setTimeout(() => {
1767 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elSection, 1);
1768 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1769 }, 1000);
1770 },
1771 onMove: evt => {
1772 clearTimeout(timeout);
1773 },
1774 onUpdate: evt => {
1775 isUpdateSectionPosition = 1;
1776 }
1777 });
1778 }
1779
1780 /* Update count sections, when add or delete section */
1781 updateCountSections(elEditCurriculum) {
1782 const elCountSections = elEditCurriculum.querySelector(`${EditSection.selectors.elCountSections}`);
1783 const elSections = elEditCurriculum.querySelectorAll(`${EditSection.selectors.elSection}:not(.clone)`);
1784 const sectionsCount = elSections.length;
1785 elCountSections.dataset.count = sectionsCount;
1786 elCountSections.querySelector('.count').textContent = sectionsCount;
1787 }
1788 }
1789
1790 /***/ },
1791
1792 /***/ "./assets/src/js/admin/generate-with-openai.js"
1793 /*!*****************************************************!*\
1794 !*** ./assets/src/js/admin/generate-with-openai.js ***!
1795 \*****************************************************/
1796 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1797
1798 "use strict";
1799 __webpack_require__.r(__webpack_exports__);
1800 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1801 /* harmony export */ GenerateWithOpenai: () => (/* binding */ GenerateWithOpenai)
1802 /* harmony export */ });
1803 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../utils.js */ "./assets/src/js/utils.js");
1804 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1805 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_1__);
1806 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
1807 /**
1808 * Generate data with OpenAI
1809 */
1810
1811
1812
1813
1814 let lp_structure_course;
1815 let popupSweetAlert = null;
1816 let lp_is_generating_course_data = false;
1817 const lp_course_ai_setting = JSON.parse(localStorage.getItem('lp_course_ai_setting')) || {};
1818 let isLayoutGutenberg = false;
1819 let selectGutenberg;
1820 let dispatchGutenberg;
1821 let editorGutenberg;
1822 class GenerateWithOpenai {
1823 constructor(options = {}) {
1824 this.options = {
1825 autoInsertButtons: true,
1826 isCourseBuilder: false,
1827 titleInputSelector: 'input[name=post_title]',
1828 courseBuilderTitleInputSelector: 'input[name=course_title]',
1829 editorIdClassic: 'content',
1830 editorIdCourseBuilder: 'course_description_editor',
1831 ...options
1832 };
1833 this.init();
1834 }
1835 static selectors = {
1836 elBtnGenerateWithAi: '.lp-btn-generate-with-ai',
1837 elGenerateDataAiWrap: '.lp-generate-data-ai-wrap'
1838 };
1839 init() {
1840 if (!lpData?.enable_open_ai) {
1841 return;
1842 }
1843 if (this.options.autoInsertButtons) {
1844 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('#titlewrap', el => {
1845 el.insertAdjacentHTML('afterend', `<button type="button"
1846 style="margin-left: 5px"
1847 class="lp-btn-generate-with-ai lp-btn-ai-style"
1848 data-template="#lp-tmpl-edit-title-ai">
1849 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1850 </button>`);
1851 });
1852 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('#wp-content-media-buttons', el => {
1853 el.insertAdjacentHTML('beforeend', `<button type="button"
1854 class="lp-btn-generate-with-ai lp-btn-ai-style"
1855 data-template="#lp-tmpl-edit-description-ai">
1856 <i class="lp-ico-ai"></i><span>Generate description with AI</span>
1857 </button>`);
1858 });
1859 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('#postimagediv', el => {
1860 const elInside = el.querySelector('.postbox-header');
1861 elInside.insertAdjacentHTML('afterend', `<button type="button"
1862 class="lp-btn-generate-with-ai lp-btn-ai-style"
1863 data-template="#lp-tmpl-edit-image-ai">
1864 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1865 </button>`);
1866 });
1867
1868 // Check is layout Gutenberg
1869 if (wp.data && wp.data.select('core/editor')) {
1870 isLayoutGutenberg = true;
1871 selectGutenberg = wp.data.select;
1872 dispatchGutenberg = wp.data.dispatch;
1873 editorGutenberg = selectGutenberg('core/editor');
1874
1875 // For layout Gutenberg - button for title
1876 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-document-bar', el => {
1877 el.insertAdjacentHTML('afterend', `<button type="button"
1878 style="margin-left: 5px"
1879 class="lp-btn-generate-with-ai"
1880 data-template="#lp-tmpl-edit-title-ai">
1881 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1882 </button>`);
1883 });
1884
1885 // For layout Gutenberg - button for description
1886 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-post-featured-image', el => {
1887 el.insertAdjacentHTML('beforebegin', `<button type="button"
1888 class="lp-btn-generate-with-ai"
1889 data-template="#lp-tmpl-edit-description-ai">
1890 <i class="lp-ico-ai"></i><span>Generate description with AI</span>
1891 </button>`);
1892 });
1893
1894 // For layout Gutenberg - button for image
1895 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-post-featured-image', el => {
1896 el.insertAdjacentHTML('afterend', `<button type="button"
1897 class="lp-btn-generate-with-ai"
1898 data-template="#lp-tmpl-edit-image-ai">
1899 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1900 </button>`);
1901 });
1902 }
1903 }
1904 this.events();
1905 }
1906 getTitleInputSelector() {
1907 return this.options.isCourseBuilder ? this.options.courseBuilderTitleInputSelector : this.options.titleInputSelector;
1908 }
1909 getEditorId() {
1910 return this.options.isCourseBuilder ? this.options.editorIdCourseBuilder : this.options.editorIdClassic;
1911 }
1912 setCourseBuilderPostId(form) {
1913 if (!this.options.isCourseBuilder || !form) {
1914 return;
1915 }
1916 const postIdInput = form.querySelector('[name="post-id"]');
1917 if (!postIdInput) {
1918 return;
1919 }
1920 const courseEditWrap = document.querySelector('.cb-section__course-edit[data-course-id]');
1921 const courseId = courseEditWrap?.dataset?.courseId || '';
1922 if (courseId) {
1923 postIdInput.value = courseId;
1924 }
1925 }
1926 extractImageSourceFromHtml(html) {
1927 if (!html) {
1928 return '';
1929 }
1930 const tempWrapper = document.createElement('div');
1931 tempWrapper.innerHTML = html;
1932 return tempWrapper.querySelector('img')?.getAttribute('src') || '';
1933 }
1934 applyCourseBuilderFeaturedImage(attachmentId, imageSrc) {
1935 if (!attachmentId || !imageSrc) {
1936 return false;
1937 }
1938 document.dispatchEvent(new CustomEvent('lp-course-builder/ai-featured-image-applied', {
1939 detail: {
1940 attachmentId,
1941 imageSrc
1942 }
1943 }));
1944 return true;
1945 }
1946 events() {
1947 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
1948 selector: GenerateWithOpenai.selectors.elBtnGenerateWithAi,
1949 class: this,
1950 callBack: this.showPopup.name
1951 }, {
1952 selector: '.lp-btn-step',
1953 class: this,
1954 callBack: this.showStep.name
1955 }, {
1956 selector: '.lp-btn-generate-prompt',
1957 class: this,
1958 callBack: this.generatePrompt.name
1959 }, {
1960 selector: '.lp-btn-call-open-ai',
1961 class: this,
1962 callBack: this.generateData.name
1963 }, {
1964 selector: '.lp-btn-copy',
1965 class: this,
1966 callBack: this.copyGeneratedData.name
1967 }, {
1968 selector: '.lp-btn-apply',
1969 class: this,
1970 callBack: this.applyGeneratedData.name
1971 }, {
1972 selector: '.lp-btn-ai-apply-image',
1973 class: this,
1974 callBack: this.applyImageData.name
1975 }, {
1976 selector: '.lp-btn-close-ai-popup',
1977 //class: this,
1978 callBack: args => {
1979 const {
1980 e,
1981 target
1982 } = args;
1983 const message = lpData.i18n.confirm_close_ai;
1984 if (!lp_is_generating_course_data) {
1985 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
1986 } else if (confirm(message)) {
1987 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
1988 }
1989
1990 // Testing custom confirm box
1991 /*if ( confirm( message ) ) {
1992 SweetAlert.close();
1993 }*/
1994 }
1995 }]);
1996 }
1997 showPopup(args) {
1998 const {
1999 e,
2000 target
2001 } = args;
2002 const templateId = target.dataset.template || target.closest('.lp-btn-generate-with-ai').dataset.template || target.closest('.lp-generate-data-ai-wrap').dataset.template || '';
2003 const modalTemplate = document.querySelector(templateId);
2004 if (!modalTemplate) {
2005 console.error(`Template ${templateId} not found!`);
2006 return;
2007 }
2008 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
2009 html: modalTemplate.innerHTML,
2010 width: '60%',
2011 showCloseButton: false,
2012 showConfirmButton: false,
2013 allowOutsideClick: false,
2014 allowEscapeKey: false,
2015 didOpen: () => {
2016 popupSweetAlert = sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().getPopup();
2017 // Click to show tomSelect style
2018 popupSweetAlert.click();
2019
2020 // Set post title and post content to hidden fields of form to AI prompt reference
2021 const elPostTitleInput = document.querySelector(this.getTitleInputSelector());
2022 let post_title = '';
2023 if (elPostTitleInput) {
2024 post_title = elPostTitleInput.value;
2025 } else if (isLayoutGutenberg) {
2026 const elGutenbergTitle = document.querySelector('.editor-post-card-panel__title-name');
2027 if (elGutenbergTitle) {
2028 post_title = elGutenbergTitle.textContent;
2029 }
2030 }
2031 let post_content = '';
2032 if (!isLayoutGutenberg) {
2033 const editorId = this.getEditorId();
2034 if (!window.tinymce || !window.tinymce.get(editorId)) {
2035 const editorElement = document.querySelector(`#${editorId}`);
2036 post_content = editorElement ? editorElement.value : '';
2037 } else {
2038 post_content = window.tinymce.get(editorId).getContent({
2039 format: 'text'
2040 });
2041 }
2042 } else {
2043 const content = editorGutenberg.getEditedPostContent();
2044 post_content = content.replace(/(<([^>]+)>)/gi, ''); // Remove HTML tags
2045 }
2046 const form = popupSweetAlert.querySelector('form');
2047 this.setCourseBuilderPostId(form);
2048 const elPostTitle = form.querySelector('[name=post-title]');
2049 if (elPostTitle) {
2050 elPostTitle.value = post_title;
2051 if (!post_title) {
2052 const elGroup = elPostTitle.closest('.form-group');
2053 const elReferWarning = elGroup.querySelector('.lp-ai-warning-refer');
2054 if (elReferWarning) {
2055 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elReferWarning, 1);
2056 }
2057 }
2058 }
2059 const elPostContent = form.querySelector('[name=post-content]');
2060 if (elPostContent) {
2061 elPostContent.value = post_content;
2062 if (post_content.length < 2) {
2063 const elGroup = elPostContent.closest('.form-group');
2064 const elReferWarning = elGroup.querySelector('.lp-ai-warning-refer');
2065 if (elReferWarning) {
2066 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elReferWarning, 1);
2067 }
2068 }
2069 }
2070 const targetAudience = popupSweetAlert.querySelector('select[name="target_audience"]');
2071 if (targetAudience) {
2072 if (lp_course_ai_setting?.target_audience) {
2073 targetAudience.tomselect.setValue(lp_course_ai_setting.target_audience);
2074 }
2075 targetAudience.addEventListener('change', event => {
2076 lp_course_ai_setting.target_audience = targetAudience.tomselect.getValue();
2077 localStorage.setItem('lp_course_ai_setting', JSON.stringify(lp_course_ai_setting));
2078 });
2079 }
2080 const tone = popupSweetAlert.querySelector('select[name="tone"]');
2081 if (tone) {
2082 if (lp_course_ai_setting?.tone) {
2083 tone.tomselect.setValue(lp_course_ai_setting.tone);
2084 }
2085 tone.addEventListener('change', event => {
2086 lp_course_ai_setting.tone = tone.tomselect.getValue();
2087 localStorage.setItem('lp_course_ai_setting', JSON.stringify(lp_course_ai_setting));
2088 });
2089 }
2090 const language = popupSweetAlert.querySelector('select[name="language"]');
2091 if (language) {
2092 if (lp_course_ai_setting?.language) {
2093 language.tomselect.setValue(lp_course_ai_setting.language);
2094 }
2095 language.addEventListener('change', event => {
2096 const value = language.tomselect.getValue();
2097 lp_course_ai_setting.language = value ? [value] : [];
2098 localStorage.setItem('lp_course_ai_setting', JSON.stringify(lp_course_ai_setting));
2099 });
2100 }
2101 }
2102 }).then(result => {
2103 if (result.isDismissed) {
2104 if (lp_is_generating_course_data) {
2105 lp_is_generating_course_data = false;
2106 }
2107 }
2108 });
2109 }
2110 showStep(args) {
2111 const {
2112 e,
2113 target
2114 } = args;
2115 e.preventDefault();
2116 const elBtnActions = target.closest('.button-actions');
2117 const elCreateCourseAIWrap = elBtnActions.closest(GenerateWithOpenai.selectors.elGenerateDataAiWrap);
2118 let step = parseInt(elBtnActions.dataset.step);
2119 const stepAction = target.dataset.action;
2120 if (stepAction === 'next') {
2121 step++;
2122 } else if (stepAction === 'prev') {
2123 step--;
2124 }
2125 elBtnActions.dataset.step = step;
2126 const elForm = target.closest('form');
2127 const elContentStep = elForm.querySelector(`.step-content[data-step="${step}"]`);
2128 const elItemStep = elCreateCourseAIWrap.querySelector(`.step-item[data-step="${step}"]`);
2129 elForm.querySelectorAll('.step-content').forEach(el => el.classList.remove('active'));
2130 elContentStep.classList.add('active');
2131 elCreateCourseAIWrap.querySelectorAll('.step-item').forEach(el => el.classList.remove('active'));
2132 elItemStep.classList.add('active');
2133
2134 // Get all buttons step to show/hide
2135 const form = target.closest('form');
2136 const elBtnSteps = form.querySelectorAll('button[data-step-show]');
2137 elBtnSteps.forEach(el => {
2138 const stepsShow = el.dataset.stepShow.split(',').map(s => parseInt(s.trim()));
2139 if (stepsShow.includes(step)) {
2140 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(el, 1);
2141 } else {
2142 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(el, 0);
2143 }
2144 });
2145 }
2146
2147 /**
2148 * Create prompt from data config
2149 * @param args
2150 */
2151 generatePrompt(args) {
2152 const {
2153 e,
2154 target
2155 } = args;
2156 e.preventDefault();
2157 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, true);
2158
2159 // Get dataSend
2160 const form = target.closest('form');
2161 let dataSend = JSON.parse(target.dataset.send);
2162 dataSend = _utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(form, dataSend);
2163
2164 // Ajax to generate prompt
2165 const callBack = {
2166 success: response => {
2167 const {
2168 message,
2169 status,
2170 data
2171 } = response;
2172 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(message, status);
2173 if (status === 'success') {
2174 const elPromptTextarea = form.querySelector('textarea[name=lp-openai-prompt-generated-field]');
2175 elPromptTextarea.value = data;
2176 const elBtnNext = form.querySelector('.lp-btn-step[data-action=next]');
2177 elBtnNext.click();
2178 }
2179 },
2180 error: error => {
2181 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(error, 'error');
2182 },
2183 completed: () => {
2184 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, false);
2185 }
2186 };
2187 window.lpAJAXG.fetchAJAX(dataSend, callBack);
2188 }
2189
2190 /**
2191 * Submit prompt to OpenAI to generate course data
2192 * @param args
2193 */
2194 generateData(args) {
2195 const {
2196 e,
2197 target
2198 } = args;
2199 e.preventDefault();
2200 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, true);
2201
2202 // Get dataSend
2203 const form = target.closest('form');
2204 let dataSend = JSON.parse(target.dataset.send);
2205 dataSend = _utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(form, dataSend);
2206 const btnPrev = form.querySelector('.lp-btn-step[data-action=prev]');
2207 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(btnPrev, 0);
2208
2209 // Ajax to generate prompt
2210 const callBack = {
2211 success: response => {
2212 const {
2213 message,
2214 status,
2215 data
2216 } = response;
2217 if (lp_is_generating_course_data) {
2218 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(message, status);
2219 }
2220 if (status === 'success') {
2221 // Save structure data
2222 lp_structure_course = data.lp_structure_course;
2223
2224 // Set preview HTML
2225 const elResults = form.querySelector('.lp-ai-generated-results');
2226 elResults.innerHTML = data.lp_html_preview;
2227 const elBtnNext = form.querySelector('.lp-btn-step[data-action=next]');
2228 elBtnNext.click();
2229 }
2230 },
2231 error: error => {
2232 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(error, 'error');
2233 },
2234 completed: () => {
2235 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, false);
2236 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(btnPrev, 1);
2237 lp_is_generating_course_data = false;
2238 }
2239 };
2240 lp_is_generating_course_data = true;
2241 window.lpAJAXG.fetchAJAX(dataSend, callBack);
2242 }
2243 applyGeneratedData(args) {
2244 const {
2245 e,
2246 target
2247 } = args;
2248 e.preventDefault();
2249 const dataApply = target.dataset.apply;
2250 const dataTarget = target.dataset.target;
2251 if (dataTarget) {
2252 if (!isLayoutGutenberg) {
2253 if (dataTarget === 'set-wp-editor-content') {
2254 this.setWPEditorContent(dataApply);
2255 } else if (dataTarget === 'set-wp-title') {
2256 const elTitleInput = document.querySelector(this.getTitleInputSelector());
2257 if (elTitleInput) {
2258 elTitleInput.value = dataApply;
2259 elTitleInput.dispatchEvent(new Event('input', {
2260 bubbles: true
2261 }));
2262 }
2263 }
2264 } else if (dataTarget === 'set-wp-editor-content') {
2265 dispatchGutenberg('core/editor').editPost({
2266 content: dataApply
2267 });
2268 } else if (dataTarget === 'set-wp-title') {
2269 dispatchGutenberg('core/editor').editPost({
2270 title: dataApply
2271 });
2272 }
2273 }
2274 if (popupSweetAlert) {
2275 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
2276 }
2277 }
2278 copyGeneratedData(args) {
2279 const {
2280 e,
2281 target
2282 } = args;
2283 e.preventDefault();
2284 const dataCopy = target.dataset.copy;
2285 if (navigator.clipboard) {
2286 navigator.clipboard.writeText(dataCopy).then(() => {
2287 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Copied to clipboard!', 'success');
2288 }).catch(err => {
2289 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Failed to copy text: ' + err, 'error');
2290 });
2291 } else {
2292 // Fallback when clipboard API is unavailable
2293 const textarea = document.createElement('textarea');
2294 textarea.value = dataCopy;
2295 textarea.style.position = 'fixed';
2296 textarea.style.left = '-9999px';
2297 document.body.appendChild(textarea);
2298 textarea.select();
2299 try {
2300 const successful = document.execCommand('copy');
2301 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(successful ? 'Copied to clipboard!' : 'Failed to copy text', successful ? 'success' : 'error');
2302 } catch (err) {
2303 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Failed to copy text: ' + err, 'error');
2304 }
2305 document.body.removeChild(textarea);
2306 }
2307
2308 /*navigator.clipboard.writeText( dataCopy ).then( () => {
2309 lpToastify.show( 'Copied to clipboard!', 'success' );
2310 } ).catch( ( err ) => {
2311 lpToastify.show( 'Failed to copy text: ' + err, 'error' );
2312 } );*/
2313 }
2314 setWPEditorContent(htmlContent) {
2315 const editorId = this.getEditorId();
2316 const editor = window.tinymce?.get(editorId);
2317 if (editor) {
2318 editor.setContent(htmlContent);
2319 return;
2320 }
2321 const editorElement = document.querySelector(`#${editorId}`);
2322 if (editorElement) {
2323 editorElement.value = htmlContent;
2324 editorElement.dispatchEvent(new Event('input', {
2325 bubbles: true
2326 }));
2327 }
2328 }
2329 applyImageData(args) {
2330 const {
2331 e,
2332 target
2333 } = args;
2334 let dataSend = JSON.parse(target.dataset.send);
2335 dataSend = _utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(target.closest('form'), dataSend);
2336 //e.preventDefault();
2337 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, true);
2338
2339 // Ajax to generate prompt
2340 const callBack = {
2341 success: response => {
2342 const {
2343 message,
2344 status,
2345 data
2346 } = response;
2347 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(message, status);
2348 if (status === 'success') {
2349 if (this.options.isCourseBuilder) {
2350 const attachmentId = parseInt(data?.attachment_id || 0, 10);
2351 const imageSrc = this.extractImageSourceFromHtml(data?.html_image || '');
2352 const applied = this.applyCourseBuilderFeaturedImage(attachmentId, imageSrc);
2353 if (!applied) {
2354 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Failed to apply image to course featured image.', 'error');
2355 return;
2356 }
2357 } else if (!isLayoutGutenberg) {
2358 // Set image
2359 const elImagePreview = document.querySelector('#postimagediv .inside');
2360 elImagePreview.outerHTML = data.html_image;
2361 } else {
2362 dispatchGutenberg('core/editor').editPost({
2363 featured_media: data.attachment_id
2364 });
2365 }
2366 if (popupSweetAlert) {
2367 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
2368 }
2369 }
2370 },
2371 error: error => {
2372 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(error, 'error');
2373 },
2374 completed: () => {
2375 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, false);
2376 }
2377 };
2378 window.lpAJAXG.fetchAJAX(dataSend, callBack);
2379 }
2380 }
2381
2382 /***/ },
2383
2384 /***/ "./assets/src/js/lpPopupSelectItemToAdd.js"
2385 /*!*************************************************!*\
2386 !*** ./assets/src/js/lpPopupSelectItemToAdd.js ***!
2387 \*************************************************/
2388 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2389
2390 "use strict";
2391 __webpack_require__.r(__webpack_exports__);
2392 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2393 /* harmony export */ LpPopupSelectItemToAdd: () => (/* binding */ LpPopupSelectItemToAdd)
2394 /* harmony export */ });
2395 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
2396 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
2397 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
2398 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
2399 /**
2400 * LearnPress Popup Select Item
2401 *
2402 * Handles load(search) item from API, show in popup and select item.
2403 */
2404
2405
2406
2407
2408 let itemsSelectedData = [];
2409 let elPopup;
2410 let timeSearchTitleItem;
2411 class LpPopupSelectItemToAdd {
2412 constructor() {
2413 this.init();
2414 }
2415 static selectors = {
2416 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
2417 elBtnAddItemsSelected: '.lp-btn-add-items-selected',
2418 elBtnCountItemsSelected: '.lp-btn-count-items-selected',
2419 elHeaderCountItemSelected: '.header-count-items-selected',
2420 elSelectItem: '.lp-select-item',
2421 elListItems: '.list-items',
2422 elPopupItemsToSelect: '.lp-popup-items-to-select',
2423 elSearchTitleItem: '.lp-search-title-item',
2424 elBtnBackListItems: '.lp-btn-back-to-select-items',
2425 elListItemsWrap: '.list-items-wrap',
2426 elListItemsSelected: '.list-items-selected',
2427 elItemSelectedClone: '.li-item-selected.clone',
2428 elItemSelected: '.li-item-selected',
2429 LPTarget: '.lp-target'
2430 };
2431 init() {
2432 this.events();
2433 }
2434 events = () => {
2435 if (LpPopupSelectItemToAdd._loadedEvents) {
2436 return;
2437 }
2438 LpPopupSelectItemToAdd._loadedEvents = true;
2439 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
2440 selector: LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect,
2441 callBack: this.showPopupItemsToSelect.name,
2442 class: this
2443 }, {
2444 selector: LpPopupSelectItemToAdd.selectors.elSelectItem,
2445 callBack: this.selectItemsFromList.name,
2446 class: this
2447 }, {
2448 selector: LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected,
2449 callBack: this.showItemsSelected.name,
2450 class: this
2451 }, {
2452 selector: LpPopupSelectItemToAdd.selectors.elBtnBackListItems,
2453 callBack: this.backToSelectItems.name,
2454 class: this
2455 }, {
2456 selector: LpPopupSelectItemToAdd.selectors.elItemSelected,
2457 callBack: this.removeItemSelected.name,
2458 class: this
2459 }, {
2460 selector: '.tabs .tab',
2461 callBack: this.chooseTabItemsType.name,
2462 class: this
2463 }]);
2464 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
2465 selector: LpPopupSelectItemToAdd.selectors.elSearchTitleItem,
2466 callBack: this.searchTitleItemToSelect.name,
2467 class: this
2468 }]);
2469 };
2470
2471 // Show popup items to select
2472 showPopupItemsToSelect = args => {
2473 const {
2474 e,
2475 target = false,
2476 callBack
2477 } = args;
2478 const elBtnShowPopupItemsToSelect = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect}`);
2479 if (!elBtnShowPopupItemsToSelect) {
2480 return;
2481 }
2482
2483 // Reset items selected data when opening popup
2484 itemsSelectedData = [];
2485 const templateId = target.dataset.template || '';
2486 const modalTemplate = document.querySelector(templateId);
2487 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
2488 html: modalTemplate.innerHTML,
2489 showConfirmButton: false,
2490 showCloseButton: true,
2491 width: 'max(350px, 65vw)',
2492 customClass: {
2493 popup: 'lp-select-items-popup',
2494 htmlContainer: 'lp-select-items-html-container',
2495 container: 'lp-select-items-container'
2496 },
2497 willOpen: () => {
2498 elPopup = sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().getPopup();
2499 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2500
2501 // Avoid duplicate AJAX: loadAJAX.js handles fresh elements; skip if already loaded. Set timeout to ensure DOM is ready handle.
2502 setTimeout(() => {
2503 const elLoadAjaxElement = elLPTarget.closest('.lp-load-ajax-element:not(.loaded)');
2504 if (!elLoadAjaxElement) {
2505 return;
2506 }
2507 if (elLPTarget) {
2508 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2509 dataSend.args.paged = 1;
2510 dataSend.args.item_selecting = itemsSelectedData || [];
2511 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
2512 window.lpAJAXG.fetchAJAX(dataSend, {
2513 success: response => {
2514 const {
2515 data
2516 } = response;
2517 const elSkeleton = elPopup.querySelector('.lp-skeleton-animation');
2518 elSkeleton.remove();
2519 elLPTarget.innerHTML = data.content || '';
2520 this.watchItemsSelectedDataChange();
2521 }
2522 });
2523 }
2524 }, 1);
2525 }
2526 }).then(result => {
2527 if (result.isDismissed) {}
2528 });
2529 };
2530
2531 // Choose tab items type
2532 chooseTabItemsType = args => {
2533 const {
2534 e,
2535 target,
2536 callBack
2537 } = args;
2538 const elTabType = target.closest('.tab');
2539 if (!elTabType) {
2540 return;
2541 }
2542 e.preventDefault();
2543 const elTabs = elTabType.closest('.tabs');
2544 if (!elTabs) {
2545 return;
2546 }
2547 const elSelectItemsToAdd = elTabs.closest(`${LpPopupSelectItemToAdd.selectors.elPopupItemsToSelect}`);
2548 const elInputSearch = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.elSearchTitleItem}`);
2549 const itemType = elTabType.dataset.type;
2550 const elTabLis = elTabs.querySelectorAll('.tab');
2551 elTabLis.forEach(elTabLi => {
2552 if (elTabLi.classList.contains('active')) {
2553 elTabLi.classList.remove('active');
2554 }
2555 });
2556 elTabType.classList.add('active');
2557 // Reset search input
2558 elInputSearch.value = '';
2559 const elLPTarget = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2560 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2561 dataSend.args.item_type = itemType;
2562 dataSend.args.paged = 1;
2563 dataSend.args.item_selecting = itemsSelectedData || [];
2564 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
2565 window.lpAJAXG.showHideLoading(elLPTarget, 1);
2566 window.lpAJAXG.fetchAJAX(dataSend, {
2567 success: response => {
2568 const {
2569 data
2570 } = response;
2571 elLPTarget.innerHTML = data.content || '';
2572 },
2573 error: error => {
2574 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
2575 },
2576 completed: () => {
2577 window.lpAJAXG.showHideLoading(elLPTarget, 0);
2578 this.watchItemsSelectedDataChange();
2579 }
2580 });
2581 };
2582
2583 // Choice items to add list items selected before adding to section
2584 selectItemsFromList = args => {
2585 const {
2586 e,
2587 target
2588 } = args;
2589 const elItemAttend = target.closest(`${LpPopupSelectItemToAdd.selectors.elSelectItem}`);
2590 if (!elItemAttend) {
2591 return;
2592 }
2593 const elInput = elItemAttend.querySelector('input[type="checkbox"]');
2594 if (target.tagName !== 'INPUT') {
2595 elInput.click();
2596 return;
2597 }
2598 const elUl = elItemAttend.closest(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
2599 if (!elUl) {
2600 return;
2601 }
2602 const itemSelected = {
2603 ...elInput.dataset
2604 };
2605 //console.log( 'itemSelected', itemSelected );
2606
2607 if (elInput.checked) {
2608 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
2609 if (!exists) {
2610 itemsSelectedData.push(itemSelected);
2611 }
2612 } else {
2613 const index = itemsSelectedData.findIndex(item => item.id === itemSelected.id);
2614 if (index !== -1) {
2615 itemsSelectedData.splice(index, 1);
2616 }
2617 }
2618 this.watchItemsSelectedDataChange();
2619 };
2620
2621 // Search title item
2622 searchTitleItemToSelect = args => {
2623 const {
2624 e,
2625 target
2626 } = args;
2627 const elInputSearch = target.closest(LpPopupSelectItemToAdd.selectors.elSearchTitleItem);
2628 if (!elInputSearch) {
2629 return;
2630 }
2631 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2632 clearTimeout(timeSearchTitleItem);
2633 timeSearchTitleItem = setTimeout(() => {
2634 const dataSet = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2635 dataSet.args.search_title = elInputSearch.value.trim();
2636 dataSet.args.item_selecting = itemsSelectedData;
2637 dataSet.args.paged = 1;
2638 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSet);
2639
2640 // Show loading
2641 window.lpAJAXG.showHideLoading(elLPTarget, 1);
2642 window.lpAJAXG.fetchAJAX(dataSet, {
2643 success: response => {
2644 const {
2645 data
2646 } = response;
2647 elLPTarget.innerHTML = data.content || '';
2648 },
2649 error: error => {
2650 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
2651 },
2652 completed: () => {
2653 window.lpAJAXG.showHideLoading(elLPTarget, 0);
2654 }
2655 });
2656 }, 800);
2657 };
2658
2659 // Show list of items, to choose items to add to section
2660 showItemsSelected = args => {
2661 const {
2662 e,
2663 target
2664 } = args;
2665 const elBtnCountItemsSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
2666 if (!elBtnCountItemsSelected) {
2667 return;
2668 }
2669 const elBtnBack = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
2670 const elTabs = elPopup.querySelector('.tabs');
2671 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
2672 const elHeaderItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
2673 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
2674 const elItemClone = elListItemsSelected.querySelector(`${LpPopupSelectItemToAdd.selectors.elItemSelectedClone}`);
2675 elHeaderItemsSelected.innerHTML = elBtnCountItemsSelected.innerHTML;
2676 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 0);
2677 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 0);
2678 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 0);
2679 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 1);
2680 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderItemsSelected, 1);
2681 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 1);
2682 elListItemsSelected.querySelectorAll(`${LpPopupSelectItemToAdd.selectors.elItemSelected}:not(.clone)`).forEach(elItem => {
2683 elItem.remove();
2684 });
2685 itemsSelectedData.forEach(item => {
2686 const elItemSelected = elItemClone.cloneNode(true);
2687 elItemSelected.classList.remove('clone');
2688 Object.entries(item).forEach(([key, value]) => {
2689 elItemSelected.dataset[key] = value;
2690 });
2691 const elTitleDisplay = elItemSelected.querySelector('.title-display');
2692 elTitleDisplay.innerHTML = item.title;
2693 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elItemSelected, 1);
2694 elItemClone.insertAdjacentElement('beforebegin', elItemSelected);
2695 });
2696 };
2697
2698 // Back to list of items
2699 backToSelectItems = args => {
2700 const {
2701 e,
2702 target
2703 } = args;
2704 const elBtnBack = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
2705 if (!elBtnBack) {
2706 return;
2707 }
2708 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
2709 const elTabs = elPopup.querySelector('.tabs');
2710 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
2711 const elHeaderCountItemSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
2712 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
2713 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 1);
2714 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 1);
2715 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 1);
2716 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 0);
2717 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderCountItemSelected, 0);
2718 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 0);
2719 };
2720
2721 // Remove item selected from list items selected
2722 removeItemSelected = args => {
2723 const {
2724 e,
2725 target
2726 } = args;
2727 const elRemoveItemSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elItemSelected}`);
2728 if (!elRemoveItemSelected) {
2729 return;
2730 }
2731 const itemRemove = elRemoveItemSelected.dataset;
2732 const index = itemsSelectedData.findIndex(item => item.id === itemRemove.id);
2733 if (index !== -1) {
2734 itemsSelectedData.splice(index, 1);
2735 }
2736 elRemoveItemSelected.remove();
2737 this.watchItemsSelectedDataChange();
2738 };
2739
2740 // Watch items selected when data change
2741 watchItemsSelectedDataChange = () => {
2742 // Update count items selected, disable/enable buttons
2743 const elBtnAddItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected}`);
2744 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
2745 const elSpanCount = elBtnCountItemsSelected.querySelector('span');
2746 const elHeaderCount = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
2747 const elTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2748 if (itemsSelectedData.length !== 0) {
2749 elBtnCountItemsSelected.disabled = false;
2750 elBtnAddItemsSelected.disabled = false;
2751 elBtnAddItemsSelected.classList.add('active');
2752 elSpanCount.textContent = `(${itemsSelectedData.length})`;
2753 elHeaderCount.innerHTML = elBtnCountItemsSelected.innerHTML;
2754 } else {
2755 elBtnCountItemsSelected.disabled = true;
2756 elBtnAddItemsSelected.disabled = true;
2757 elBtnAddItemsSelected.classList.remove('active');
2758 elSpanCount.textContent = '';
2759 elHeaderCount.textContent = '';
2760 }
2761
2762 // Update list input checked, when items removed, or change tab type
2763 const elListItems = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
2764 const elInputs = elListItems.querySelectorAll('input[type="checkbox"]');
2765 elInputs.forEach(elInputItem => {
2766 const itemSelected = elInputItem.dataset;
2767 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
2768 elInputItem.checked = exists;
2769 });
2770
2771 // Set item selecting data to dataset for query.
2772 const dataSet = window.lpAJAXG.getDataSetCurrent(elTarget);
2773 dataSet.args.item_selecting = itemsSelectedData;
2774 window.lpAJAXG.setDataSetCurrent(elTarget, dataSet);
2775 };
2776
2777 // Add items selected to section
2778 addItemsSelectedToSection = args => {
2779 const {
2780 e,
2781 target,
2782 callBackHandle
2783 } = args;
2784 if (!elPopup) {
2785 return;
2786 }
2787 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().close();
2788 if (typeof callBackHandle === 'function') {
2789 callBackHandle(itemsSelectedData);
2790 itemsSelectedData = [];
2791 }
2792 };
2793 }
2794
2795 /***/ },
2796
2797 /***/ "./assets/src/js/lpToastify.js"
2798 /*!*************************************!*\
2799 !*** ./assets/src/js/lpToastify.js ***!
2800 \*************************************/
2801 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2802
2803 "use strict";
2804 __webpack_require__.r(__webpack_exports__);
2805 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2806 /* harmony export */ show: () => (/* binding */ show)
2807 /* harmony export */ });
2808 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
2809 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
2810 /* 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");
2811 /**
2812 * Utils functions
2813 *
2814 * @param url
2815 * @param data
2816 * @param functions
2817 * @since 4.3.0
2818 * @version 1.0.0
2819 */
2820
2821
2822 const argsToastify = {
2823 text: '',
2824 gravity: lpData.toast.gravity,
2825 // `top` or `bottom`
2826 position: lpData.toast.position,
2827 // `left`, `center` or `right`
2828 className: `${lpData.toast.classPrefix}`,
2829 close: lpData.toast.close == 1,
2830 stopOnFocus: lpData.toast.stopOnFocus == 1,
2831 duration: lpData.toast.duration
2832 };
2833 const show = (message, status = 'success', argsCustom) => {
2834 let args = argsToastify;
2835 if (argsCustom) {
2836 args = {
2837 ...args,
2838 ...argsCustom
2839 };
2840 }
2841 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
2842 ...args,
2843 text: message,
2844 className: `${lpData.toast.classPrefix} ${status}`
2845 });
2846 toastify.showToast();
2847 };
2848
2849 /***/ },
2850
2851 /***/ "./assets/src/js/utils.js"
2852 /*!********************************!*\
2853 !*** ./assets/src/js/utils.js ***!
2854 \********************************/
2855 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2856
2857 "use strict";
2858 __webpack_require__.r(__webpack_exports__);
2859 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2860 /* harmony export */ debounce: () => (/* binding */ debounce),
2861 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
2862 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
2863 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
2864 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
2865 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
2866 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
2867 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
2868 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
2869 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
2870 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
2871 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
2872 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
2873 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
2874 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
2875 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
2876 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
2877 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
2878 /* harmony export */ });
2879 /**
2880 * Utils functions
2881 *
2882 * @param url
2883 * @param data
2884 * @param functions
2885 * @since 4.2.5.1
2886 * @version 1.0.7
2887 */
2888 const lpClassName = {
2889 hidden: 'lp-hidden',
2890 loading: 'loading',
2891 elCollapse: 'lp-collapse',
2892 elSectionToggle: '.lp-section-toggle',
2893 elTriggerToggle: '.lp-trigger-toggle',
2894 elBtnFullScreen: '.lp-btn-full-screen-view',
2895 elFullScreen: 'lp-full-screen-view',
2896 elBtnFullScreenClose: 'lp-full-screen-view__close'
2897 };
2898 const lpFetchAPI = (url, data = {}, functions = {}) => {
2899 if ('function' === typeof functions.before) {
2900 functions.before();
2901 }
2902 fetch(url, {
2903 method: 'GET',
2904 ...data
2905 }).then(response => response.json()).then(response => {
2906 if ('function' === typeof functions.success) {
2907 functions.success(response);
2908 }
2909 }).catch(err => {
2910 if ('function' === typeof functions.error) {
2911 functions.error(err);
2912 }
2913 }).finally(() => {
2914 if ('function' === typeof functions.completed) {
2915 functions.completed();
2916 }
2917 });
2918 };
2919
2920 /**
2921 * Get current URL without params.
2922 *
2923 * @since 4.2.5.1
2924 */
2925 const lpGetCurrentURLNoParam = () => {
2926 let currentUrl = window.location.href;
2927 const hasParams = currentUrl.includes('?');
2928 if (hasParams) {
2929 currentUrl = currentUrl.split('?')[0];
2930 }
2931 return currentUrl;
2932 };
2933 const lpAddQueryArgs = (endpoint, args) => {
2934 const url = new URL(endpoint);
2935 Object.keys(args).forEach(arg => {
2936 url.searchParams.set(arg, args[arg]);
2937 });
2938 return url;
2939 };
2940
2941 /**
2942 * Listen element viewed.
2943 *
2944 * @param el
2945 * @param callback
2946 * @since 4.2.5.8
2947 */
2948 const listenElementViewed = (el, callback) => {
2949 const observerSeeItem = new IntersectionObserver(function (entries) {
2950 for (const entry of entries) {
2951 if (entry.isIntersecting) {
2952 callback(entry);
2953 }
2954 }
2955 });
2956 observerSeeItem.observe(el);
2957 };
2958
2959 /**
2960 * Listen element created.
2961 *
2962 * @param callback
2963 * @since 4.2.5.8
2964 */
2965 const listenElementCreated = callback => {
2966 const observerCreateItem = new MutationObserver(function (mutations) {
2967 mutations.forEach(function (mutation) {
2968 if (mutation.addedNodes) {
2969 mutation.addedNodes.forEach(function (node) {
2970 if (node.nodeType === 1) {
2971 callback(node);
2972 }
2973 });
2974 }
2975 });
2976 });
2977 observerCreateItem.observe(document, {
2978 childList: true,
2979 subtree: true
2980 });
2981 // End.
2982 };
2983
2984 /**
2985 * Listen element created.
2986 *
2987 * @param selector
2988 * @param callback
2989 * @since 4.2.7.1
2990 */
2991 const lpOnElementReady = (selector, callback) => {
2992 const element = document.querySelector(selector);
2993 if (element) {
2994 callback(element);
2995 return;
2996 }
2997 const observer = new MutationObserver((mutations, obs) => {
2998 const element = document.querySelector(selector);
2999 if (element) {
3000 obs.disconnect();
3001 callback(element);
3002 }
3003 });
3004 observer.observe(document.documentElement, {
3005 childList: true,
3006 subtree: true
3007 });
3008 };
3009
3010 // Parse JSON from string with content include LP_AJAX_START.
3011 const lpAjaxParseJsonOld = data => {
3012 if (typeof data !== 'string') {
3013 return data;
3014 }
3015 const m = String.raw({
3016 raw: data
3017 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
3018 try {
3019 if (m) {
3020 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
3021 } else {
3022 data = JSON.parse(data);
3023 }
3024 } catch (e) {
3025 data = {};
3026 }
3027 return data;
3028 };
3029
3030 // status 0: hide, 1: show
3031 const lpShowHideEl = (el, status = 0) => {
3032 if (!el) {
3033 return;
3034 }
3035 if (!status) {
3036 el.classList.add(lpClassName.hidden);
3037 } else {
3038 el.classList.remove(lpClassName.hidden);
3039 }
3040 };
3041
3042 // status 0: hide, 1: show
3043 const lpSetLoadingEl = (el, status) => {
3044 if (!el) {
3045 return;
3046 }
3047 if (!status) {
3048 el.classList.remove(lpClassName.loading);
3049 } else {
3050 el.classList.add(lpClassName.loading);
3051 }
3052 };
3053
3054 // Toggle collapse section
3055 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
3056 if (!elTriggerClassName) {
3057 elTriggerClassName = lpClassName.elTriggerToggle;
3058 }
3059
3060 // Exclude elements, which should not trigger the collapse toggle
3061 if (elsExclude && elsExclude.length > 0) {
3062 for (const elExclude of elsExclude) {
3063 if (target.closest(elExclude)) {
3064 return;
3065 }
3066 }
3067 }
3068 const elTrigger = target.closest(elTriggerClassName);
3069 if (!elTrigger) {
3070 return;
3071 }
3072
3073 //console.log( 'elTrigger', elTrigger );
3074
3075 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
3076 if (!elSectionToggle) {
3077 return;
3078 }
3079 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
3080 if ('function' === typeof callback) {
3081 callback(elSectionToggle);
3082 }
3083 };
3084
3085 // Get data of form
3086 const getDataOfForm = form => {
3087 const dataSend = {};
3088 const formData = new FormData(form);
3089 for (const pair of formData.entries()) {
3090 const key = pair[0];
3091 const value = formData.getAll(key);
3092 if (!dataSend.hasOwnProperty(key)) {
3093 // Convert value array to string.
3094 dataSend[key] = value.join(',');
3095 }
3096 }
3097 return dataSend;
3098 };
3099
3100 // Get field keys of form
3101 const getFieldKeysOfForm = form => {
3102 const keys = [];
3103 const elements = form.elements;
3104 for (let i = 0; i < elements.length; i++) {
3105 const name = elements[i].name;
3106 if (name && !keys.includes(name)) {
3107 keys.push(name);
3108 }
3109 }
3110 return keys;
3111 };
3112
3113 // Merge data handle with data form.
3114 const mergeDataWithDatForm = (elForm, dataHandle) => {
3115 const dataForm = getDataOfForm(elForm);
3116 const keys = getFieldKeysOfForm(elForm);
3117 keys.forEach(key => {
3118 if (!dataForm.hasOwnProperty(key)) {
3119 delete dataHandle[key];
3120 } else if (dataForm[key][0] === '') {
3121 delete dataForm[key];
3122 delete dataHandle[key];
3123 }
3124 });
3125 dataHandle = {
3126 ...dataHandle,
3127 ...dataForm
3128 };
3129 return dataHandle;
3130 };
3131
3132 /**
3133 * Event trigger
3134 * For each list of event handlers, listen event on document.
3135 *
3136 * eventName: 'click', 'change', ...
3137 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
3138 *
3139 * @param eventName
3140 * @param eventHandlers
3141 */
3142 const eventHandlers = (eventName, eventHandlers) => {
3143 document.addEventListener(eventName, e => {
3144 const target = e.target;
3145 let args = {
3146 e,
3147 target
3148 };
3149 eventHandlers.forEach(eventHandler => {
3150 args = {
3151 ...args,
3152 ...eventHandler
3153 };
3154
3155 //console.log( args );
3156
3157 // Check condition before call back
3158 if (eventHandler.conditionBeforeCallBack) {
3159 if (eventHandler.conditionBeforeCallBack(args) !== true) {
3160 return;
3161 }
3162 }
3163
3164 // Special check for keydown event with checkIsEventEnter = true
3165 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
3166 if (e.key !== 'Enter') {
3167 return;
3168 }
3169 }
3170 if (target.closest(eventHandler.selector)) {
3171 if (eventHandler.class) {
3172 // Call method of class, function callBack will understand exactly {this} is class object.
3173 eventHandler.class[eventHandler.callBack](args);
3174 } else {
3175 // For send args is objected, {this} is eventHandler object, not class object.
3176 eventHandler.callBack(args);
3177 }
3178 }
3179 });
3180 });
3181 };
3182
3183 /**
3184 * Debounce - delays function execution until after `wait` ms of inactivity.
3185 *
3186 * Each call resets the timer. Only the last call in a burst executes.
3187 *
3188 * USE CASES:
3189 * - Search inputs, form validation, window resize
3190 * - Multiple elements need independent timers
3191 * - When you need to call with different arguments
3192 *
3193 * EXAMPLES:
3194 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
3195 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
3196 *
3197 * const debouncedResize = debounce( recalculateLayout, 250 );
3198 * window.addEventListener('resize', debouncedResize);
3199 *
3200 * ⚠️ Create ONCE outside event handlers, not inside.
3201 *
3202 * @param {Function} func - Function to debounce (can be anonymous)
3203 * @param {number} wait - Milliseconds to wait (default: 500)
3204 * @return {Function} Debounced wrapper function
3205 * @since 4.3.7
3206 * @version 1.0.0
3207 */
3208 const debounce = (func, wait = 500) => {
3209 let timer;
3210 return args => {
3211 clearTimeout(timer);
3212 timer = setTimeout(() => func(args), wait);
3213 };
3214 };
3215
3216 /**
3217 * Initialize lp-toggle-enable components.
3218 *
3219 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
3220 * Reads initial state from `data-enabled` attribute ("true"/"false").
3221 * Calls `data-on-toggle` callback (if provided via options) on state change.
3222 *
3223 * HTML structure:
3224 * <label class="lp-toggle-enable" data-enabled="true">
3225 * <input type="checkbox" class="lp-toggle-enable__input" />
3226 * <span class="lp-toggle-enable__track"></span>
3227 * </label>
3228 *
3229 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
3230 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
3231 * @since 4.4.5
3232 * @version 1.0.0
3233 */
3234 window.lpToggleEnableInit = 0;
3235 const toggleEnable = (onToggle = null) => {
3236 if (window.lpToggleEnableInit) {
3237 return;
3238 }
3239 window.lpToggleEnableInit = 1;
3240 const selector = '.lp-toggle-enable';
3241 const updateUI = (toggle, isEnabled) => {
3242 toggle.classList.toggle('is-enabled', isEnabled);
3243 const input = toggle.querySelector('.lp-toggle-enable__input');
3244 if (input) {
3245 input.checked = isEnabled;
3246 input.value = isEnabled ? '1' : '0';
3247 }
3248 };
3249
3250 // Delegate click handling via eventHandlers.
3251 eventHandlers('click', [{
3252 selector,
3253 callBack: args => {
3254 const {
3255 e,
3256 target
3257 } = args;
3258 const toggle = target.closest(selector);
3259 if (!toggle || toggle.classList.contains('is-disabled')) {
3260 return;
3261 }
3262 e.preventDefault();
3263 const isEnabled = !toggle.classList.contains('is-enabled');
3264 updateUI(toggle, isEnabled);
3265 if ('function' === typeof onToggle) {
3266 onToggle(toggle, isEnabled);
3267 }
3268 }
3269 }]);
3270 };
3271
3272 /**
3273 * Initialize custom fullscreen view buttons.
3274 *
3275 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
3276 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
3277 * target element. Falls back to the button's parent element when
3278 * `data-target` is not provided.
3279 *
3280 * @since 4.4.5
3281 * @version 1.0.0
3282 */
3283 window.lpFullScreenViewInit = 0;
3284 const fullScreenView = () => {
3285 if (window.lpFullScreenViewInit) {
3286 return;
3287 }
3288 window.lpFullScreenViewInit = 1;
3289 let lastScrollY = 0;
3290 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
3291 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
3292 if (isFullscreen) {
3293 elTarget.classList.remove(lpClassName.elFullScreen);
3294 document.documentElement.classList.remove('lp-full-screen-active');
3295 window.scrollTo(0, lastScrollY);
3296 } else {
3297 lastScrollY = window.scrollY;
3298 elTarget.classList.add(lpClassName.elFullScreen);
3299 document.documentElement.classList.add('lp-full-screen-active');
3300 }
3301 if (!isFullscreen) {
3302 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
3303 const closeButton = document.createElement('button');
3304 closeButton.type = 'button';
3305 closeButton.className = lpClassName.elBtnFullScreenClose;
3306 closeButton.setAttribute('aria-label', 'Close');
3307 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
3308 closeButton.addEventListener('click', e => {
3309 e.preventDefault();
3310 lpToggleFullscreenView(elTarget);
3311 });
3312 elTarget.appendChild(closeButton);
3313 }
3314 } else {
3315 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
3316 if (closeButton) {
3317 closeButton.remove();
3318 }
3319 }
3320 };
3321 eventHandlers('click', [{
3322 selector: lpClassName.elBtnFullScreen,
3323 callBack: args => {
3324 const {
3325 e,
3326 target
3327 } = args;
3328 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
3329 if (!elBtnFullScreen) {
3330 console.log('No full screen button found');
3331 return;
3332 }
3333 e.preventDefault();
3334 let elTarget = null;
3335 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
3336 console.log(targetSelector);
3337 if (targetSelector) {
3338 elTarget = document.querySelector(targetSelector);
3339 }
3340 if (!elTarget) {
3341 console.log('No target element found');
3342 return;
3343 }
3344 lpToggleFullscreenView(elTarget, elBtnFullScreen);
3345 }
3346 }]);
3347 };
3348
3349 /***/ },
3350
3351 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
3352 /*!*****************************************************************************************!*\
3353 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
3354 \*****************************************************************************************/
3355 (module, __webpack_exports__, __webpack_require__) {
3356
3357 "use strict";
3358 __webpack_require__.r(__webpack_exports__);
3359 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3360 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
3361 /* harmony export */ });
3362 /* 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");
3363 /* 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__);
3364 /* 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");
3365 /* 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__);
3366 // Imports
3367
3368
3369 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()));
3370 // Module
3371 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
3372 * Toastify js 1.12.0
3373 * https://github.com/apvarun/toastify-js
3374 * @license MIT licensed
3375 *
3376 * Copyright (C) 2018 Varun A P
3377 */
3378
3379 .toastify {
3380 padding: 12px 20px;
3381 color: #ffffff;
3382 display: inline-block;
3383 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
3384 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
3385 background: linear-gradient(135deg, #73a5ff, #5477f5);
3386 position: fixed;
3387 opacity: 0;
3388 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
3389 border-radius: 2px;
3390 cursor: pointer;
3391 text-decoration: none;
3392 max-width: calc(50% - 20px);
3393 z-index: 2147483647;
3394 }
3395
3396 .toastify.on {
3397 opacity: 1;
3398 }
3399
3400 .toast-close {
3401 background: transparent;
3402 border: 0;
3403 color: white;
3404 cursor: pointer;
3405 font-family: inherit;
3406 font-size: 1em;
3407 opacity: 0.4;
3408 padding: 0 5px;
3409 }
3410
3411 .toastify-right {
3412 right: 15px;
3413 }
3414
3415 .toastify-left {
3416 left: 15px;
3417 }
3418
3419 .toastify-top {
3420 top: -150px;
3421 }
3422
3423 .toastify-bottom {
3424 bottom: -150px;
3425 }
3426
3427 .toastify-rounded {
3428 border-radius: 25px;
3429 }
3430
3431 .toastify-avatar {
3432 width: 1.5em;
3433 height: 1.5em;
3434 margin: -7px 5px;
3435 border-radius: 2px;
3436 }
3437
3438 .toastify-center {
3439 margin-left: auto;
3440 margin-right: auto;
3441 left: 0;
3442 right: 0;
3443 max-width: fit-content;
3444 max-width: -moz-fit-content;
3445 }
3446
3447 @media only screen and (max-width: 360px) {
3448 .toastify-right, .toastify-left {
3449 margin-left: auto;
3450 margin-right: auto;
3451 left: 0;
3452 right: 0;
3453 max-width: fit-content;
3454 }
3455 }
3456 `, "",{"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":""}]);
3457 // Exports
3458 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
3459
3460
3461 /***/ },
3462
3463 /***/ "./node_modules/css-loader/dist/runtime/api.js"
3464 /*!*****************************************************!*\
3465 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
3466 \*****************************************************/
3467 (module) {
3468
3469 "use strict";
3470
3471
3472 /*
3473 MIT License http://www.opensource.org/licenses/mit-license.php
3474 Author Tobias Koppers @sokra
3475 */
3476 module.exports = function (cssWithMappingToString) {
3477 var list = [];
3478
3479 // return the list of modules as css string
3480 list.toString = function toString() {
3481 return this.map(function (item) {
3482 var content = "";
3483 var needLayer = typeof item[5] !== "undefined";
3484 if (item[4]) {
3485 content += "@supports (".concat(item[4], ") {");
3486 }
3487 if (item[2]) {
3488 content += "@media ".concat(item[2], " {");
3489 }
3490 if (needLayer) {
3491 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
3492 }
3493 content += cssWithMappingToString(item);
3494 if (needLayer) {
3495 content += "}";
3496 }
3497 if (item[2]) {
3498 content += "}";
3499 }
3500 if (item[4]) {
3501 content += "}";
3502 }
3503 return content;
3504 }).join("");
3505 };
3506
3507 // import a list of modules into the list
3508 list.i = function i(modules, media, dedupe, supports, layer) {
3509 if (typeof modules === "string") {
3510 modules = [[null, modules, undefined]];
3511 }
3512 var alreadyImportedModules = {};
3513 if (dedupe) {
3514 for (var k = 0; k < this.length; k++) {
3515 var id = this[k][0];
3516 if (id != null) {
3517 alreadyImportedModules[id] = true;
3518 }
3519 }
3520 }
3521 for (var _k = 0; _k < modules.length; _k++) {
3522 var item = [].concat(modules[_k]);
3523 if (dedupe && alreadyImportedModules[item[0]]) {
3524 continue;
3525 }
3526 if (typeof layer !== "undefined") {
3527 if (typeof item[5] === "undefined") {
3528 item[5] = layer;
3529 } else {
3530 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
3531 item[5] = layer;
3532 }
3533 }
3534 if (media) {
3535 if (!item[2]) {
3536 item[2] = media;
3537 } else {
3538 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
3539 item[2] = media;
3540 }
3541 }
3542 if (supports) {
3543 if (!item[4]) {
3544 item[4] = "".concat(supports);
3545 } else {
3546 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
3547 item[4] = supports;
3548 }
3549 }
3550 list.push(item);
3551 }
3552 };
3553 return list;
3554 };
3555
3556 /***/ },
3557
3558 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
3559 /*!************************************************************!*\
3560 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
3561 \************************************************************/
3562 (module) {
3563
3564 "use strict";
3565
3566
3567 module.exports = function (item) {
3568 var content = item[1];
3569 var cssMapping = item[3];
3570 if (!cssMapping) {
3571 return content;
3572 }
3573 if (typeof btoa === "function") {
3574 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
3575 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
3576 var sourceMapping = "/*# ".concat(data, " */");
3577 return [content].concat([sourceMapping]).join("\n");
3578 }
3579 return [content].join("\n");
3580 };
3581
3582 /***/ },
3583
3584 /***/ "./node_modules/sortablejs/modular/sortable.esm.js"
3585 /*!*********************************************************!*\
3586 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
3587 \*********************************************************/
3588 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3589
3590 "use strict";
3591 __webpack_require__.r(__webpack_exports__);
3592 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3593 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
3594 /* harmony export */ Sortable: () => (/* binding */ Sortable),
3595 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
3596 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
3597 /* harmony export */ });
3598 /**!
3599 * Sortable 1.15.7
3600 * @author RubaXa <trash@rubaxa.org>
3601 * @author owenm <owen23355@gmail.com>
3602 * @license MIT
3603 */
3604 function _arrayLikeToArray(r, a) {
3605 (null == a || a > r.length) && (a = r.length);
3606 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
3607 return n;
3608 }
3609 function _arrayWithoutHoles(r) {
3610 if (Array.isArray(r)) return _arrayLikeToArray(r);
3611 }
3612 function _defineProperty(e, r, t) {
3613 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
3614 value: t,
3615 enumerable: !0,
3616 configurable: !0,
3617 writable: !0
3618 }) : e[r] = t, e;
3619 }
3620 function _extends() {
3621 return _extends = Object.assign ? Object.assign.bind() : function (n) {
3622 for (var e = 1; e < arguments.length; e++) {
3623 var t = arguments[e];
3624 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
3625 }
3626 return n;
3627 }, _extends.apply(null, arguments);
3628 }
3629 function _iterableToArray(r) {
3630 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
3631 }
3632 function _nonIterableSpread() {
3633 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3634 }
3635 function ownKeys(e, r) {
3636 var t = Object.keys(e);
3637 if (Object.getOwnPropertySymbols) {
3638 var o = Object.getOwnPropertySymbols(e);
3639 r && (o = o.filter(function (r) {
3640 return Object.getOwnPropertyDescriptor(e, r).enumerable;
3641 })), t.push.apply(t, o);
3642 }
3643 return t;
3644 }
3645 function _objectSpread2(e) {
3646 for (var r = 1; r < arguments.length; r++) {
3647 var t = null != arguments[r] ? arguments[r] : {};
3648 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
3649 _defineProperty(e, r, t[r]);
3650 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
3651 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
3652 });
3653 }
3654 return e;
3655 }
3656 function _objectWithoutProperties(e, t) {
3657 if (null == e) return {};
3658 var o,
3659 r,
3660 i = _objectWithoutPropertiesLoose(e, t);
3661 if (Object.getOwnPropertySymbols) {
3662 var n = Object.getOwnPropertySymbols(e);
3663 for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
3664 }
3665 return i;
3666 }
3667 function _objectWithoutPropertiesLoose(r, e) {
3668 if (null == r) return {};
3669 var t = {};
3670 for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
3671 if (-1 !== e.indexOf(n)) continue;
3672 t[n] = r[n];
3673 }
3674 return t;
3675 }
3676 function _toConsumableArray(r) {
3677 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
3678 }
3679 function _toPrimitive(t, r) {
3680 if ("object" != typeof t || !t) return t;
3681 var e = t[Symbol.toPrimitive];
3682 if (void 0 !== e) {
3683 var i = e.call(t, r || "default");
3684 if ("object" != typeof i) return i;
3685 throw new TypeError("@@toPrimitive must return a primitive value.");
3686 }
3687 return ("string" === r ? String : Number)(t);
3688 }
3689 function _toPropertyKey(t) {
3690 var i = _toPrimitive(t, "string");
3691 return "symbol" == typeof i ? i : i + "";
3692 }
3693 function _typeof(o) {
3694 "@babel/helpers - typeof";
3695
3696 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
3697 return typeof o;
3698 } : function (o) {
3699 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
3700 }, _typeof(o);
3701 }
3702 function _unsupportedIterableToArray(r, a) {
3703 if (r) {
3704 if ("string" == typeof r) return _arrayLikeToArray(r, a);
3705 var t = {}.toString.call(r).slice(8, -1);
3706 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;
3707 }
3708 }
3709
3710 var version = "1.15.7";
3711
3712 function userAgent(pattern) {
3713 if (typeof window !== 'undefined' && window.navigator) {
3714 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
3715 }
3716 }
3717 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
3718 var Edge = userAgent(/Edge/i);
3719 var FireFox = userAgent(/firefox/i);
3720 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
3721 var IOS = userAgent(/iP(ad|od|hone)/i);
3722 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
3723
3724 var captureMode = {
3725 capture: false,
3726 passive: false
3727 };
3728 function on(el, event, fn) {
3729 el.addEventListener(event, fn, !IE11OrLess && captureMode);
3730 }
3731 function off(el, event, fn) {
3732 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
3733 }
3734 function matches( /**HTMLElement*/el, /**String*/selector) {
3735 if (!selector) return;
3736 selector[0] === '>' && (selector = selector.substring(1));
3737 if (el) {
3738 try {
3739 if (el.matches) {
3740 return el.matches(selector);
3741 } else if (el.msMatchesSelector) {
3742 return el.msMatchesSelector(selector);
3743 } else if (el.webkitMatchesSelector) {
3744 return el.webkitMatchesSelector(selector);
3745 }
3746 } catch (_) {
3747 return false;
3748 }
3749 }
3750 return false;
3751 }
3752 function getParentOrHost(el) {
3753 return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
3754 }
3755 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
3756 if (el) {
3757 ctx = ctx || document;
3758 do {
3759 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
3760 return el;
3761 }
3762 if (el === ctx) break;
3763 /* jshint boss:true */
3764 } while (el = getParentOrHost(el));
3765 }
3766 return null;
3767 }
3768 var R_SPACE = /\s+/g;
3769 function toggleClass(el, name, state) {
3770 if (el && name) {
3771 if (el.classList) {
3772 el.classList[state ? 'add' : 'remove'](name);
3773 } else {
3774 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
3775 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
3776 }
3777 }
3778 }
3779 function css(el, prop, val) {
3780 var style = el && el.style;
3781 if (style) {
3782 if (val === void 0) {
3783 if (document.defaultView && document.defaultView.getComputedStyle) {
3784 val = document.defaultView.getComputedStyle(el, '');
3785 } else if (el.currentStyle) {
3786 val = el.currentStyle;
3787 }
3788 return prop === void 0 ? val : val[prop];
3789 } else {
3790 if (!(prop in style) && prop.indexOf('webkit') === -1) {
3791 prop = '-webkit-' + prop;
3792 }
3793 style[prop] = val + (typeof val === 'string' ? '' : 'px');
3794 }
3795 }
3796 }
3797 function matrix(el, selfOnly) {
3798 var appliedTransforms = '';
3799 if (typeof el === 'string') {
3800 appliedTransforms = el;
3801 } else {
3802 do {
3803 var transform = css(el, 'transform');
3804 if (transform && transform !== 'none') {
3805 appliedTransforms = transform + ' ' + appliedTransforms;
3806 }
3807 /* jshint boss:true */
3808 } while (!selfOnly && (el = el.parentNode));
3809 }
3810 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
3811 /*jshint -W056 */
3812 return matrixFn && new matrixFn(appliedTransforms);
3813 }
3814 function find(ctx, tagName, iterator) {
3815 if (ctx) {
3816 var list = ctx.getElementsByTagName(tagName),
3817 i = 0,
3818 n = list.length;
3819 if (iterator) {
3820 for (; i < n; i++) {
3821 iterator(list[i], i);
3822 }
3823 }
3824 return list;
3825 }
3826 return [];
3827 }
3828 function getWindowScrollingElement() {
3829 var scrollingElement = document.scrollingElement;
3830 if (scrollingElement) {
3831 return scrollingElement;
3832 } else {
3833 return document.documentElement;
3834 }
3835 }
3836
3837 /**
3838 * Returns the "bounding client rect" of given element
3839 * @param {HTMLElement} el The element whose boundingClientRect is wanted
3840 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
3841 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
3842 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
3843 * @param {[HTMLElement]} container The parent the element will be placed in
3844 * @return {Object} The boundingClientRect of el, with specified adjustments
3845 */
3846 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
3847 if (!el.getBoundingClientRect && el !== window) return;
3848 var elRect, top, left, bottom, right, height, width;
3849 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
3850 elRect = el.getBoundingClientRect();
3851 top = elRect.top;
3852 left = elRect.left;
3853 bottom = elRect.bottom;
3854 right = elRect.right;
3855 height = elRect.height;
3856 width = elRect.width;
3857 } else {
3858 top = 0;
3859 left = 0;
3860 bottom = window.innerHeight;
3861 right = window.innerWidth;
3862 height = window.innerHeight;
3863 width = window.innerWidth;
3864 }
3865 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
3866 // Adjust for translate()
3867 container = container || el.parentNode;
3868
3869 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
3870 // Not needed on <= IE11
3871 if (!IE11OrLess) {
3872 do {
3873 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
3874 var containerRect = container.getBoundingClientRect();
3875
3876 // Set relative to edges of padding box of container
3877 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
3878 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
3879 bottom = top + elRect.height;
3880 right = left + elRect.width;
3881 break;
3882 }
3883 /* jshint boss:true */
3884 } while (container = container.parentNode);
3885 }
3886 }
3887 if (undoScale && el !== window) {
3888 // Adjust for scale()
3889 var elMatrix = matrix(container || el),
3890 scaleX = elMatrix && elMatrix.a,
3891 scaleY = elMatrix && elMatrix.d;
3892 if (elMatrix) {
3893 top /= scaleY;
3894 left /= scaleX;
3895 width /= scaleX;
3896 height /= scaleY;
3897 bottom = top + height;
3898 right = left + width;
3899 }
3900 }
3901 return {
3902 top: top,
3903 left: left,
3904 bottom: bottom,
3905 right: right,
3906 width: width,
3907 height: height
3908 };
3909 }
3910
3911 /**
3912 * Checks if a side of an element is scrolled past a side of its parents
3913 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
3914 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
3915 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
3916 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
3917 */
3918 function isScrolledPast(el, elSide, parentSide) {
3919 var parent = getParentAutoScrollElement(el, true),
3920 elSideVal = getRect(el)[elSide];
3921
3922 /* jshint boss:true */
3923 while (parent) {
3924 var parentSideVal = getRect(parent)[parentSide],
3925 visible = void 0;
3926 if (parentSide === 'top' || parentSide === 'left') {
3927 visible = elSideVal >= parentSideVal;
3928 } else {
3929 visible = elSideVal <= parentSideVal;
3930 }
3931 if (!visible) return parent;
3932 if (parent === getWindowScrollingElement()) break;
3933 parent = getParentAutoScrollElement(parent, false);
3934 }
3935 return false;
3936 }
3937
3938 /**
3939 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
3940 * and non-draggable elements
3941 * @param {HTMLElement} el The parent element
3942 * @param {Number} childNum The index of the child
3943 * @param {Object} options Parent Sortable's options
3944 * @return {HTMLElement} The child at index childNum, or null if not found
3945 */
3946 function getChild(el, childNum, options, includeDragEl) {
3947 var currentChild = 0,
3948 i = 0,
3949 children = el.children;
3950 while (i < children.length) {
3951 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
3952 if (currentChild === childNum) {
3953 return children[i];
3954 }
3955 currentChild++;
3956 }
3957 i++;
3958 }
3959 return null;
3960 }
3961
3962 /**
3963 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
3964 * @param {HTMLElement} el Parent element
3965 * @param {selector} selector Any other elements that should be ignored
3966 * @return {HTMLElement} The last child, ignoring ghostEl
3967 */
3968 function lastChild(el, selector) {
3969 var last = el.lastElementChild;
3970 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
3971 last = last.previousElementSibling;
3972 }
3973 return last || null;
3974 }
3975
3976 /**
3977 * Returns the index of an element within its parent for a selected set of
3978 * elements
3979 * @param {HTMLElement} el
3980 * @param {selector} selector
3981 * @return {number}
3982 */
3983 function index(el, selector) {
3984 var index = 0;
3985 if (!el || !el.parentNode) {
3986 return -1;
3987 }
3988
3989 /* jshint boss:true */
3990 while (el = el.previousElementSibling) {
3991 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
3992 index++;
3993 }
3994 }
3995 return index;
3996 }
3997
3998 /**
3999 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
4000 * The value is returned in real pixels.
4001 * @param {HTMLElement} el
4002 * @return {Array} Offsets in the format of [left, top]
4003 */
4004 function getRelativeScrollOffset(el) {
4005 var offsetLeft = 0,
4006 offsetTop = 0,
4007 winScroller = getWindowScrollingElement();
4008 if (el) {
4009 do {
4010 var elMatrix = matrix(el),
4011 scaleX = elMatrix.a,
4012 scaleY = elMatrix.d;
4013 offsetLeft += el.scrollLeft * scaleX;
4014 offsetTop += el.scrollTop * scaleY;
4015 } while (el !== winScroller && (el = el.parentNode));
4016 }
4017 return [offsetLeft, offsetTop];
4018 }
4019
4020 /**
4021 * Returns the index of the object within the given array
4022 * @param {Array} arr Array that may or may not hold the object
4023 * @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
4024 * @return {Number} The index of the object in the array, or -1
4025 */
4026 function indexOfObject(arr, obj) {
4027 for (var i in arr) {
4028 if (!arr.hasOwnProperty(i)) continue;
4029 for (var key in obj) {
4030 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
4031 }
4032 }
4033 return -1;
4034 }
4035 function getParentAutoScrollElement(el, includeSelf) {
4036 // skip to window
4037 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
4038 var elem = el;
4039 var gotSelf = false;
4040 do {
4041 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
4042 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
4043 var elemCSS = css(elem);
4044 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
4045 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
4046 if (gotSelf || includeSelf) return elem;
4047 gotSelf = true;
4048 }
4049 }
4050 /* jshint boss:true */
4051 } while (elem = elem.parentNode);
4052 return getWindowScrollingElement();
4053 }
4054 function extend(dst, src) {
4055 if (dst && src) {
4056 for (var key in src) {
4057 if (src.hasOwnProperty(key)) {
4058 dst[key] = src[key];
4059 }
4060 }
4061 }
4062 return dst;
4063 }
4064 function isRectEqual(rect1, rect2) {
4065 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);
4066 }
4067 var _throttleTimeout;
4068 function throttle(callback, ms) {
4069 return function () {
4070 if (!_throttleTimeout) {
4071 var args = arguments,
4072 _this = this;
4073 if (args.length === 1) {
4074 callback.call(_this, args[0]);
4075 } else {
4076 callback.apply(_this, args);
4077 }
4078 _throttleTimeout = setTimeout(function () {
4079 _throttleTimeout = void 0;
4080 }, ms);
4081 }
4082 };
4083 }
4084 function cancelThrottle() {
4085 clearTimeout(_throttleTimeout);
4086 _throttleTimeout = void 0;
4087 }
4088 function scrollBy(el, x, y) {
4089 el.scrollLeft += x;
4090 el.scrollTop += y;
4091 }
4092 function clone(el) {
4093 var Polymer = window.Polymer;
4094 var $ = window.jQuery || window.Zepto;
4095 if (Polymer && Polymer.dom) {
4096 return Polymer.dom(el).cloneNode(true);
4097 } else if ($) {
4098 return $(el).clone(true)[0];
4099 } else {
4100 return el.cloneNode(true);
4101 }
4102 }
4103 function setRect(el, rect) {
4104 css(el, 'position', 'absolute');
4105 css(el, 'top', rect.top);
4106 css(el, 'left', rect.left);
4107 css(el, 'width', rect.width);
4108 css(el, 'height', rect.height);
4109 }
4110 function unsetRect(el) {
4111 css(el, 'position', '');
4112 css(el, 'top', '');
4113 css(el, 'left', '');
4114 css(el, 'width', '');
4115 css(el, 'height', '');
4116 }
4117 function getChildContainingRectFromElement(container, options, ghostEl) {
4118 var rect = {};
4119 Array.from(container.children).forEach(function (child) {
4120 var _rect$left, _rect$top, _rect$right, _rect$bottom;
4121 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
4122 var childRect = getRect(child);
4123 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
4124 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
4125 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
4126 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
4127 });
4128 rect.width = rect.right - rect.left;
4129 rect.height = rect.bottom - rect.top;
4130 rect.x = rect.left;
4131 rect.y = rect.top;
4132 return rect;
4133 }
4134 var expando = 'Sortable' + new Date().getTime();
4135
4136 function AnimationStateManager() {
4137 var animationStates = [],
4138 animationCallbackId;
4139 return {
4140 captureAnimationState: function captureAnimationState() {
4141 animationStates = [];
4142 if (!this.options.animation) return;
4143 var children = [].slice.call(this.el.children);
4144 children.forEach(function (child) {
4145 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
4146 animationStates.push({
4147 target: child,
4148 rect: getRect(child)
4149 });
4150 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
4151
4152 // If animating: compensate for current animation
4153 if (child.thisAnimationDuration) {
4154 var childMatrix = matrix(child, true);
4155 if (childMatrix) {
4156 fromRect.top -= childMatrix.f;
4157 fromRect.left -= childMatrix.e;
4158 }
4159 }
4160 child.fromRect = fromRect;
4161 });
4162 },
4163 addAnimationState: function addAnimationState(state) {
4164 animationStates.push(state);
4165 },
4166 removeAnimationState: function removeAnimationState(target) {
4167 animationStates.splice(indexOfObject(animationStates, {
4168 target: target
4169 }), 1);
4170 },
4171 animateAll: function animateAll(callback) {
4172 var _this = this;
4173 if (!this.options.animation) {
4174 clearTimeout(animationCallbackId);
4175 if (typeof callback === 'function') callback();
4176 return;
4177 }
4178 var animating = false,
4179 animationTime = 0;
4180 animationStates.forEach(function (state) {
4181 var time = 0,
4182 target = state.target,
4183 fromRect = target.fromRect,
4184 toRect = getRect(target),
4185 prevFromRect = target.prevFromRect,
4186 prevToRect = target.prevToRect,
4187 animatingRect = state.rect,
4188 targetMatrix = matrix(target, true);
4189 if (targetMatrix) {
4190 // Compensate for current animation
4191 toRect.top -= targetMatrix.f;
4192 toRect.left -= targetMatrix.e;
4193 }
4194 target.toRect = toRect;
4195 if (target.thisAnimationDuration) {
4196 // Could also check if animatingRect is between fromRect and toRect
4197 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
4198 // Make sure animatingRect is on line between toRect & fromRect
4199 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
4200 // If returning to same place as started from animation and on same axis
4201 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
4202 }
4203 }
4204
4205 // if fromRect != toRect: animate
4206 if (!isRectEqual(toRect, fromRect)) {
4207 target.prevFromRect = fromRect;
4208 target.prevToRect = toRect;
4209 if (!time) {
4210 time = _this.options.animation;
4211 }
4212 _this.animate(target, animatingRect, toRect, time);
4213 }
4214 if (time) {
4215 animating = true;
4216 animationTime = Math.max(animationTime, time);
4217 clearTimeout(target.animationResetTimer);
4218 target.animationResetTimer = setTimeout(function () {
4219 target.animationTime = 0;
4220 target.prevFromRect = null;
4221 target.fromRect = null;
4222 target.prevToRect = null;
4223 target.thisAnimationDuration = null;
4224 }, time);
4225 target.thisAnimationDuration = time;
4226 }
4227 });
4228 clearTimeout(animationCallbackId);
4229 if (!animating) {
4230 if (typeof callback === 'function') callback();
4231 } else {
4232 animationCallbackId = setTimeout(function () {
4233 if (typeof callback === 'function') callback();
4234 }, animationTime);
4235 }
4236 animationStates = [];
4237 },
4238 animate: function animate(target, currentRect, toRect, duration) {
4239 if (duration) {
4240 css(target, 'transition', '');
4241 css(target, 'transform', '');
4242 var elMatrix = matrix(this.el),
4243 scaleX = elMatrix && elMatrix.a,
4244 scaleY = elMatrix && elMatrix.d,
4245 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
4246 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
4247 target.animatingX = !!translateX;
4248 target.animatingY = !!translateY;
4249 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
4250 this.forRepaintDummy = repaint(target); // repaint
4251
4252 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
4253 css(target, 'transform', 'translate3d(0,0,0)');
4254 typeof target.animated === 'number' && clearTimeout(target.animated);
4255 target.animated = setTimeout(function () {
4256 css(target, 'transition', '');
4257 css(target, 'transform', '');
4258 target.animated = false;
4259 target.animatingX = false;
4260 target.animatingY = false;
4261 }, duration);
4262 }
4263 }
4264 };
4265 }
4266 function repaint(target) {
4267 return target.offsetWidth;
4268 }
4269 function calculateRealTime(animatingRect, fromRect, toRect, options) {
4270 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;
4271 }
4272
4273 var plugins = [];
4274 var defaults = {
4275 initializeByDefault: true
4276 };
4277 var PluginManager = {
4278 mount: function mount(plugin) {
4279 // Set default static properties
4280 for (var option in defaults) {
4281 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
4282 plugin[option] = defaults[option];
4283 }
4284 }
4285 plugins.forEach(function (p) {
4286 if (p.pluginName === plugin.pluginName) {
4287 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
4288 }
4289 });
4290 plugins.push(plugin);
4291 },
4292 pluginEvent: function pluginEvent(eventName, sortable, evt) {
4293 var _this = this;
4294 this.eventCanceled = false;
4295 evt.cancel = function () {
4296 _this.eventCanceled = true;
4297 };
4298 var eventNameGlobal = eventName + 'Global';
4299 plugins.forEach(function (plugin) {
4300 if (!sortable[plugin.pluginName]) return;
4301 // Fire global events if it exists in this sortable
4302 if (sortable[plugin.pluginName][eventNameGlobal]) {
4303 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
4304 sortable: sortable
4305 }, evt));
4306 }
4307
4308 // Only fire plugin event if plugin is enabled in this sortable,
4309 // and plugin has event defined
4310 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
4311 sortable[plugin.pluginName][eventName](_objectSpread2({
4312 sortable: sortable
4313 }, evt));
4314 }
4315 });
4316 },
4317 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
4318 plugins.forEach(function (plugin) {
4319 var pluginName = plugin.pluginName;
4320 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
4321 var initialized = new plugin(sortable, el, sortable.options);
4322 initialized.sortable = sortable;
4323 initialized.options = sortable.options;
4324 sortable[pluginName] = initialized;
4325
4326 // Add default options from plugin
4327 _extends(defaults, initialized.defaults);
4328 });
4329 for (var option in sortable.options) {
4330 if (!sortable.options.hasOwnProperty(option)) continue;
4331 var modified = this.modifyOption(sortable, option, sortable.options[option]);
4332 if (typeof modified !== 'undefined') {
4333 sortable.options[option] = modified;
4334 }
4335 }
4336 },
4337 getEventProperties: function getEventProperties(name, sortable) {
4338 var eventProperties = {};
4339 plugins.forEach(function (plugin) {
4340 if (typeof plugin.eventProperties !== 'function') return;
4341 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
4342 });
4343 return eventProperties;
4344 },
4345 modifyOption: function modifyOption(sortable, name, value) {
4346 var modifiedValue;
4347 plugins.forEach(function (plugin) {
4348 // Plugin must exist on the Sortable
4349 if (!sortable[plugin.pluginName]) return;
4350
4351 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
4352 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
4353 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
4354 }
4355 });
4356 return modifiedValue;
4357 }
4358 };
4359
4360 function dispatchEvent(_ref) {
4361 var sortable = _ref.sortable,
4362 rootEl = _ref.rootEl,
4363 name = _ref.name,
4364 targetEl = _ref.targetEl,
4365 cloneEl = _ref.cloneEl,
4366 toEl = _ref.toEl,
4367 fromEl = _ref.fromEl,
4368 oldIndex = _ref.oldIndex,
4369 newIndex = _ref.newIndex,
4370 oldDraggableIndex = _ref.oldDraggableIndex,
4371 newDraggableIndex = _ref.newDraggableIndex,
4372 originalEvent = _ref.originalEvent,
4373 putSortable = _ref.putSortable,
4374 extraEventProperties = _ref.extraEventProperties;
4375 sortable = sortable || rootEl && rootEl[expando];
4376 if (!sortable) return;
4377 var evt,
4378 options = sortable.options,
4379 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
4380 // Support for new CustomEvent feature
4381 if (window.CustomEvent && !IE11OrLess && !Edge) {
4382 evt = new CustomEvent(name, {
4383 bubbles: true,
4384 cancelable: true
4385 });
4386 } else {
4387 evt = document.createEvent('Event');
4388 evt.initEvent(name, true, true);
4389 }
4390 evt.to = toEl || rootEl;
4391 evt.from = fromEl || rootEl;
4392 evt.item = targetEl || rootEl;
4393 evt.clone = cloneEl;
4394 evt.oldIndex = oldIndex;
4395 evt.newIndex = newIndex;
4396 evt.oldDraggableIndex = oldDraggableIndex;
4397 evt.newDraggableIndex = newDraggableIndex;
4398 evt.originalEvent = originalEvent;
4399 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
4400 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
4401 for (var option in allEventProperties) {
4402 evt[option] = allEventProperties[option];
4403 }
4404 if (rootEl) {
4405 rootEl.dispatchEvent(evt);
4406 }
4407 if (options[onName]) {
4408 options[onName].call(sortable, evt);
4409 }
4410 }
4411
4412 var _excluded = ["evt"];
4413 var pluginEvent = function pluginEvent(eventName, sortable) {
4414 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
4415 originalEvent = _ref.evt,
4416 data = _objectWithoutProperties(_ref, _excluded);
4417 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
4418 dragEl: dragEl,
4419 parentEl: parentEl,
4420 ghostEl: ghostEl,
4421 rootEl: rootEl,
4422 nextEl: nextEl,
4423 lastDownEl: lastDownEl,
4424 cloneEl: cloneEl,
4425 cloneHidden: cloneHidden,
4426 dragStarted: moved,
4427 putSortable: putSortable,
4428 activeSortable: Sortable.active,
4429 originalEvent: originalEvent,
4430 oldIndex: oldIndex,
4431 oldDraggableIndex: oldDraggableIndex,
4432 newIndex: newIndex,
4433 newDraggableIndex: newDraggableIndex,
4434 hideGhostForTarget: _hideGhostForTarget,
4435 unhideGhostForTarget: _unhideGhostForTarget,
4436 cloneNowHidden: function cloneNowHidden() {
4437 cloneHidden = true;
4438 },
4439 cloneNowShown: function cloneNowShown() {
4440 cloneHidden = false;
4441 },
4442 dispatchSortableEvent: function dispatchSortableEvent(name) {
4443 _dispatchEvent({
4444 sortable: sortable,
4445 name: name,
4446 originalEvent: originalEvent
4447 });
4448 }
4449 }, data));
4450 };
4451 function _dispatchEvent(info) {
4452 dispatchEvent(_objectSpread2({
4453 putSortable: putSortable,
4454 cloneEl: cloneEl,
4455 targetEl: dragEl,
4456 rootEl: rootEl,
4457 oldIndex: oldIndex,
4458 oldDraggableIndex: oldDraggableIndex,
4459 newIndex: newIndex,
4460 newDraggableIndex: newDraggableIndex
4461 }, info));
4462 }
4463 var dragEl,
4464 parentEl,
4465 ghostEl,
4466 rootEl,
4467 nextEl,
4468 lastDownEl,
4469 cloneEl,
4470 cloneHidden,
4471 oldIndex,
4472 newIndex,
4473 oldDraggableIndex,
4474 newDraggableIndex,
4475 activeGroup,
4476 putSortable,
4477 awaitingDragStarted = false,
4478 ignoreNextClick = false,
4479 sortables = [],
4480 tapEvt,
4481 touchEvt,
4482 lastDx,
4483 lastDy,
4484 tapDistanceLeft,
4485 tapDistanceTop,
4486 moved,
4487 lastTarget,
4488 lastDirection,
4489 pastFirstInvertThresh = false,
4490 isCircumstantialInvert = false,
4491 targetMoveDistance,
4492 // For positioning ghost absolutely
4493 ghostRelativeParent,
4494 ghostRelativeParentInitialScroll = [],
4495 // (left, top)
4496
4497 _silent = false,
4498 savedInputChecked = [];
4499
4500 /** @const */
4501 var documentExists = typeof document !== 'undefined',
4502 PositionGhostAbsolutely = IOS,
4503 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
4504 // This will not pass for IE9, because IE9 DnD only works on anchors
4505 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
4506 supportCssPointerEvents = function () {
4507 if (!documentExists) return;
4508 // false when <= IE11
4509 if (IE11OrLess) {
4510 return false;
4511 }
4512 var el = document.createElement('x');
4513 el.style.cssText = 'pointer-events:auto';
4514 return el.style.pointerEvents === 'auto';
4515 }(),
4516 _detectDirection = function _detectDirection(el, options) {
4517 var elCSS = css(el),
4518 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
4519 child1 = getChild(el, 0, options),
4520 child2 = getChild(el, 1, options),
4521 firstChildCSS = child1 && css(child1),
4522 secondChildCSS = child2 && css(child2),
4523 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
4524 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
4525 if (elCSS.display === 'flex') {
4526 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
4527 }
4528 if (elCSS.display === 'grid') {
4529 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
4530 }
4531 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
4532 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
4533 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
4534 }
4535 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';
4536 },
4537 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
4538 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
4539 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
4540 dragElOppLength = vertical ? dragRect.width : dragRect.height,
4541 targetS1Opp = vertical ? targetRect.left : targetRect.top,
4542 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
4543 targetOppLength = vertical ? targetRect.width : targetRect.height;
4544 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
4545 },
4546 /**
4547 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
4548 * @param {Number} x X position
4549 * @param {Number} y Y position
4550 * @return {HTMLElement} Element of the first found nearest Sortable
4551 */
4552 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
4553 var ret;
4554 sortables.some(function (sortable) {
4555 var threshold = sortable[expando].options.emptyInsertThreshold;
4556 if (!threshold || lastChild(sortable)) return;
4557 var rect = getRect(sortable),
4558 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
4559 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
4560 if (insideHorizontally && insideVertically) {
4561 return ret = sortable;
4562 }
4563 });
4564 return ret;
4565 },
4566 _prepareGroup = function _prepareGroup(options) {
4567 function toFn(value, pull) {
4568 return function (to, from, dragEl, evt) {
4569 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
4570 if (value == null && (pull || sameGroup)) {
4571 // Default pull value
4572 // Default pull and put value if same group
4573 return true;
4574 } else if (value == null || value === false) {
4575 return false;
4576 } else if (pull && value === 'clone') {
4577 return value;
4578 } else if (typeof value === 'function') {
4579 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
4580 } else {
4581 var otherGroup = (pull ? to : from).options.group.name;
4582 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
4583 }
4584 };
4585 }
4586 var group = {};
4587 var originalGroup = options.group;
4588 if (!originalGroup || _typeof(originalGroup) != 'object') {
4589 originalGroup = {
4590 name: originalGroup
4591 };
4592 }
4593 group.name = originalGroup.name;
4594 group.checkPull = toFn(originalGroup.pull, true);
4595 group.checkPut = toFn(originalGroup.put);
4596 group.revertClone = originalGroup.revertClone;
4597 options.group = group;
4598 },
4599 _hideGhostForTarget = function _hideGhostForTarget() {
4600 if (!supportCssPointerEvents && ghostEl) {
4601 css(ghostEl, 'display', 'none');
4602 }
4603 },
4604 _unhideGhostForTarget = function _unhideGhostForTarget() {
4605 if (!supportCssPointerEvents && ghostEl) {
4606 css(ghostEl, 'display', '');
4607 }
4608 };
4609
4610 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
4611 if (documentExists && !ChromeForAndroid) {
4612 document.addEventListener('click', function (evt) {
4613 if (ignoreNextClick) {
4614 evt.preventDefault();
4615 evt.stopPropagation && evt.stopPropagation();
4616 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
4617 ignoreNextClick = false;
4618 return false;
4619 }
4620 }, true);
4621 }
4622 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
4623 if (dragEl) {
4624 evt = evt.touches ? evt.touches[0] : evt;
4625 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
4626 if (nearest) {
4627 // Create imitation event
4628 var event = {};
4629 for (var i in evt) {
4630 if (evt.hasOwnProperty(i)) {
4631 event[i] = evt[i];
4632 }
4633 }
4634 event.target = event.rootEl = nearest;
4635 event.preventDefault = void 0;
4636 event.stopPropagation = void 0;
4637 nearest[expando]._onDragOver(event);
4638 }
4639 }
4640 };
4641 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
4642 if (dragEl) {
4643 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
4644 }
4645 };
4646
4647 /**
4648 * @class Sortable
4649 * @param {HTMLElement} el
4650 * @param {Object} [options]
4651 */
4652 function Sortable(el, options) {
4653 if (!(el && el.nodeType && el.nodeType === 1)) {
4654 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
4655 }
4656 this.el = el; // root element
4657 this.options = options = _extends({}, options);
4658
4659 // Export instance
4660 el[expando] = this;
4661 var defaults = {
4662 group: null,
4663 sort: true,
4664 disabled: false,
4665 store: null,
4666 handle: null,
4667 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
4668 swapThreshold: 1,
4669 // percentage; 0 <= x <= 1
4670 invertSwap: false,
4671 // invert always
4672 invertedSwapThreshold: null,
4673 // will be set to same as swapThreshold if default
4674 removeCloneOnHide: true,
4675 direction: function direction() {
4676 return _detectDirection(el, this.options);
4677 },
4678 ghostClass: 'sortable-ghost',
4679 chosenClass: 'sortable-chosen',
4680 dragClass: 'sortable-drag',
4681 ignore: 'a, img',
4682 filter: null,
4683 preventOnFilter: true,
4684 animation: 0,
4685 easing: null,
4686 setData: function setData(dataTransfer, dragEl) {
4687 dataTransfer.setData('Text', dragEl.textContent);
4688 },
4689 dropBubble: false,
4690 dragoverBubble: false,
4691 dataIdAttr: 'data-id',
4692 delay: 0,
4693 delayOnTouchOnly: false,
4694 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
4695 forceFallback: false,
4696 fallbackClass: 'sortable-fallback',
4697 fallbackOnBody: false,
4698 fallbackTolerance: 0,
4699 fallbackOffset: {
4700 x: 0,
4701 y: 0
4702 },
4703 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
4704 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
4705 emptyInsertThreshold: 5
4706 };
4707 PluginManager.initializePlugins(this, el, defaults);
4708
4709 // Set default options
4710 for (var name in defaults) {
4711 !(name in options) && (options[name] = defaults[name]);
4712 }
4713 _prepareGroup(options);
4714
4715 // Bind all private methods
4716 for (var fn in this) {
4717 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
4718 this[fn] = this[fn].bind(this);
4719 }
4720 }
4721
4722 // Setup drag mode
4723 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
4724 if (this.nativeDraggable) {
4725 // Touch start threshold cannot be greater than the native dragstart threshold
4726 this.options.touchStartThreshold = 1;
4727 }
4728
4729 // Bind events
4730 if (options.supportPointer) {
4731 on(el, 'pointerdown', this._onTapStart);
4732 } else {
4733 on(el, 'mousedown', this._onTapStart);
4734 on(el, 'touchstart', this._onTapStart);
4735 }
4736 if (this.nativeDraggable) {
4737 on(el, 'dragover', this);
4738 on(el, 'dragenter', this);
4739 }
4740 sortables.push(this.el);
4741
4742 // Restore sorting
4743 options.store && options.store.get && this.sort(options.store.get(this) || []);
4744
4745 // Add animation state manager
4746 _extends(this, AnimationStateManager());
4747 }
4748 Sortable.prototype = /** @lends Sortable.prototype */{
4749 constructor: Sortable,
4750 _isOutsideThisEl: function _isOutsideThisEl(target) {
4751 if (!this.el.contains(target) && target !== this.el) {
4752 lastTarget = null;
4753 }
4754 },
4755 _getDirection: function _getDirection(evt, target) {
4756 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
4757 },
4758 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
4759 if (!evt.cancelable) return;
4760 var _this = this,
4761 el = this.el,
4762 options = this.options,
4763 preventOnFilter = options.preventOnFilter,
4764 type = evt.type,
4765 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
4766 target = (touch || evt).target,
4767 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
4768 filter = options.filter;
4769 _saveInputCheckedState(el);
4770
4771 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
4772 if (dragEl) {
4773 return;
4774 }
4775 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
4776 return; // only left button and enabled
4777 }
4778
4779 // cancel dnd if original target is content editable
4780 if (originalTarget.isContentEditable) {
4781 return;
4782 }
4783
4784 // Safari ignores further event handling after mousedown
4785 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
4786 return;
4787 }
4788 target = closest(target, options.draggable, el, false);
4789 if (target && target.animated) {
4790 return;
4791 }
4792 if (lastDownEl === target) {
4793 // Ignoring duplicate `down`
4794 return;
4795 }
4796
4797 // Get the index of the dragged element within its parent
4798 oldIndex = index(target);
4799 oldDraggableIndex = index(target, options.draggable);
4800
4801 // Check filter
4802 if (typeof filter === 'function') {
4803 if (filter.call(this, evt, target, this)) {
4804 _dispatchEvent({
4805 sortable: _this,
4806 rootEl: originalTarget,
4807 name: 'filter',
4808 targetEl: target,
4809 toEl: el,
4810 fromEl: el
4811 });
4812 pluginEvent('filter', _this, {
4813 evt: evt
4814 });
4815 preventOnFilter && evt.preventDefault();
4816 return; // cancel dnd
4817 }
4818 } else if (filter) {
4819 filter = filter.split(',').some(function (criteria) {
4820 criteria = closest(originalTarget, criteria.trim(), el, false);
4821 if (criteria) {
4822 _dispatchEvent({
4823 sortable: _this,
4824 rootEl: criteria,
4825 name: 'filter',
4826 targetEl: target,
4827 fromEl: el,
4828 toEl: el
4829 });
4830 pluginEvent('filter', _this, {
4831 evt: evt
4832 });
4833 return true;
4834 }
4835 });
4836 if (filter) {
4837 preventOnFilter && evt.preventDefault();
4838 return; // cancel dnd
4839 }
4840 }
4841 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
4842 return;
4843 }
4844
4845 // Prepare `dragstart`
4846 this._prepareDragStart(evt, touch, target);
4847 },
4848 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
4849 var _this = this,
4850 el = _this.el,
4851 options = _this.options,
4852 ownerDocument = el.ownerDocument,
4853 dragStartFn;
4854 if (target && !dragEl && target.parentNode === el) {
4855 var dragRect = getRect(target);
4856 rootEl = el;
4857 dragEl = target;
4858 parentEl = dragEl.parentNode;
4859 nextEl = dragEl.nextSibling;
4860 lastDownEl = target;
4861 activeGroup = options.group;
4862 Sortable.dragged = dragEl;
4863 tapEvt = {
4864 target: dragEl,
4865 clientX: (touch || evt).clientX,
4866 clientY: (touch || evt).clientY
4867 };
4868 tapDistanceLeft = tapEvt.clientX - dragRect.left;
4869 tapDistanceTop = tapEvt.clientY - dragRect.top;
4870 this._lastX = (touch || evt).clientX;
4871 this._lastY = (touch || evt).clientY;
4872 dragEl.style['will-change'] = 'all';
4873 dragStartFn = function dragStartFn() {
4874 pluginEvent('delayEnded', _this, {
4875 evt: evt
4876 });
4877 if (Sortable.eventCanceled) {
4878 _this._onDrop();
4879 return;
4880 }
4881 // Delayed drag has been triggered
4882 // we can re-enable the events: touchmove/mousemove
4883 _this._disableDelayedDragEvents();
4884 if (!FireFox && _this.nativeDraggable) {
4885 dragEl.draggable = true;
4886 }
4887
4888 // Bind the events: dragstart/dragend
4889 _this._triggerDragStart(evt, touch);
4890
4891 // Drag start event
4892 _dispatchEvent({
4893 sortable: _this,
4894 name: 'choose',
4895 originalEvent: evt
4896 });
4897
4898 // Chosen item
4899 toggleClass(dragEl, options.chosenClass, true);
4900 };
4901
4902 // Disable "draggable"
4903 options.ignore.split(',').forEach(function (criteria) {
4904 find(dragEl, criteria.trim(), _disableDraggable);
4905 });
4906 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
4907 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
4908 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
4909 if (options.supportPointer) {
4910 on(ownerDocument, 'pointerup', _this._onDrop);
4911 // Native D&D triggers pointercancel
4912 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
4913 } else {
4914 on(ownerDocument, 'mouseup', _this._onDrop);
4915 on(ownerDocument, 'touchend', _this._onDrop);
4916 on(ownerDocument, 'touchcancel', _this._onDrop);
4917 }
4918
4919 // Make dragEl draggable (must be before delay for FireFox)
4920 if (FireFox && this.nativeDraggable) {
4921 this.options.touchStartThreshold = 4;
4922 dragEl.draggable = true;
4923 }
4924 pluginEvent('delayStart', this, {
4925 evt: evt
4926 });
4927
4928 // Delay is impossible for native DnD in Edge or IE
4929 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
4930 if (Sortable.eventCanceled) {
4931 this._onDrop();
4932 return;
4933 }
4934 // If the user moves the pointer or let go the click or touch
4935 // before the delay has been reached:
4936 // disable the delayed drag
4937 if (options.supportPointer) {
4938 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
4939 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
4940 } else {
4941 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
4942 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
4943 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
4944 }
4945 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
4946 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
4947 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
4948 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
4949 } else {
4950 dragStartFn();
4951 }
4952 }
4953 },
4954 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
4955 var touch = e.touches ? e.touches[0] : e;
4956 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))) {
4957 this._disableDelayedDrag();
4958 }
4959 },
4960 _disableDelayedDrag: function _disableDelayedDrag() {
4961 dragEl && _disableDraggable(dragEl);
4962 clearTimeout(this._dragStartTimer);
4963 this._disableDelayedDragEvents();
4964 },
4965 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
4966 var ownerDocument = this.el.ownerDocument;
4967 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
4968 off(ownerDocument, 'touchend', this._disableDelayedDrag);
4969 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
4970 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
4971 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
4972 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
4973 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
4974 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
4975 },
4976 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
4977 touch = touch || evt.pointerType == 'touch' && evt;
4978 if (!this.nativeDraggable || touch) {
4979 if (this.options.supportPointer) {
4980 on(document, 'pointermove', this._onTouchMove);
4981 } else if (touch) {
4982 on(document, 'touchmove', this._onTouchMove);
4983 } else {
4984 on(document, 'mousemove', this._onTouchMove);
4985 }
4986 } else {
4987 on(dragEl, 'dragend', this);
4988 on(rootEl, 'dragstart', this._onDragStart);
4989 }
4990 try {
4991 if (document.selection) {
4992 _nextTick(function () {
4993 document.selection.empty();
4994 });
4995 } else {
4996 window.getSelection().removeAllRanges();
4997 }
4998 } catch (err) {}
4999 },
5000 _dragStarted: function _dragStarted(fallback, evt) {
5001 awaitingDragStarted = false;
5002 if (rootEl && dragEl) {
5003 pluginEvent('dragStarted', this, {
5004 evt: evt
5005 });
5006 if (this.nativeDraggable) {
5007 on(document, 'dragover', _checkOutsideTargetEl);
5008 }
5009 var options = this.options;
5010
5011 // Apply effect
5012 !fallback && toggleClass(dragEl, options.dragClass, false);
5013 toggleClass(dragEl, options.ghostClass, true);
5014 Sortable.active = this;
5015 fallback && this._appendGhost();
5016
5017 // Drag start event
5018 _dispatchEvent({
5019 sortable: this,
5020 name: 'start',
5021 originalEvent: evt
5022 });
5023 } else {
5024 this._nulling();
5025 }
5026 },
5027 _emulateDragOver: function _emulateDragOver() {
5028 if (touchEvt) {
5029 this._lastX = touchEvt.clientX;
5030 this._lastY = touchEvt.clientY;
5031 _hideGhostForTarget();
5032 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
5033 var parent = target;
5034 while (target && target.shadowRoot) {
5035 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
5036 if (target === parent) break;
5037 parent = target;
5038 }
5039 dragEl.parentNode[expando]._isOutsideThisEl(target);
5040 if (parent) {
5041 do {
5042 if (parent[expando]) {
5043 var inserted = void 0;
5044 inserted = parent[expando]._onDragOver({
5045 clientX: touchEvt.clientX,
5046 clientY: touchEvt.clientY,
5047 target: target,
5048 rootEl: parent
5049 });
5050 if (inserted && !this.options.dragoverBubble) {
5051 break;
5052 }
5053 }
5054 target = parent; // store last element
5055 }
5056 /* jshint boss:true */ while (parent = getParentOrHost(parent));
5057 }
5058 _unhideGhostForTarget();
5059 }
5060 },
5061 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
5062 if (tapEvt) {
5063 var options = this.options,
5064 fallbackTolerance = options.fallbackTolerance,
5065 fallbackOffset = options.fallbackOffset,
5066 touch = evt.touches ? evt.touches[0] : evt,
5067 ghostMatrix = ghostEl && matrix(ghostEl, true),
5068 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
5069 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
5070 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
5071 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
5072 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
5073
5074 // only set the status to dragging, when we are actually dragging
5075 if (!Sortable.active && !awaitingDragStarted) {
5076 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
5077 return;
5078 }
5079 this._onDragStart(evt, true);
5080 }
5081 if (ghostEl) {
5082 if (ghostMatrix) {
5083 ghostMatrix.e += dx - (lastDx || 0);
5084 ghostMatrix.f += dy - (lastDy || 0);
5085 } else {
5086 ghostMatrix = {
5087 a: 1,
5088 b: 0,
5089 c: 0,
5090 d: 1,
5091 e: dx,
5092 f: dy
5093 };
5094 }
5095 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
5096 css(ghostEl, 'webkitTransform', cssMatrix);
5097 css(ghostEl, 'mozTransform', cssMatrix);
5098 css(ghostEl, 'msTransform', cssMatrix);
5099 css(ghostEl, 'transform', cssMatrix);
5100 lastDx = dx;
5101 lastDy = dy;
5102 touchEvt = touch;
5103 }
5104 evt.cancelable && evt.preventDefault();
5105 }
5106 },
5107 _appendGhost: function _appendGhost() {
5108 // Bug if using scale(): https://stackoverflow.com/questions/2637058
5109 // Not being adjusted for
5110 if (!ghostEl) {
5111 var container = this.options.fallbackOnBody ? document.body : rootEl,
5112 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
5113 options = this.options;
5114
5115 // Position absolutely
5116 if (PositionGhostAbsolutely) {
5117 // Get relatively positioned parent
5118 ghostRelativeParent = container;
5119 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
5120 ghostRelativeParent = ghostRelativeParent.parentNode;
5121 }
5122 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
5123 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
5124 rect.top += ghostRelativeParent.scrollTop;
5125 rect.left += ghostRelativeParent.scrollLeft;
5126 } else {
5127 ghostRelativeParent = getWindowScrollingElement();
5128 }
5129 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
5130 }
5131 ghostEl = dragEl.cloneNode(true);
5132 toggleClass(ghostEl, options.ghostClass, false);
5133 toggleClass(ghostEl, options.fallbackClass, true);
5134 toggleClass(ghostEl, options.dragClass, true);
5135 css(ghostEl, 'transition', '');
5136 css(ghostEl, 'transform', '');
5137 css(ghostEl, 'box-sizing', 'border-box');
5138 css(ghostEl, 'margin', 0);
5139 css(ghostEl, 'top', rect.top);
5140 css(ghostEl, 'left', rect.left);
5141 css(ghostEl, 'width', rect.width);
5142 css(ghostEl, 'height', rect.height);
5143 css(ghostEl, 'opacity', '0.8');
5144 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
5145 css(ghostEl, 'zIndex', '100000');
5146 css(ghostEl, 'pointerEvents', 'none');
5147 Sortable.ghost = ghostEl;
5148 container.appendChild(ghostEl);
5149
5150 // Set transform-origin
5151 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
5152 }
5153 },
5154 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
5155 var _this = this;
5156 var dataTransfer = evt.dataTransfer;
5157 var options = _this.options;
5158 pluginEvent('dragStart', this, {
5159 evt: evt
5160 });
5161 if (Sortable.eventCanceled) {
5162 this._onDrop();
5163 return;
5164 }
5165 pluginEvent('setupClone', this);
5166 if (!Sortable.eventCanceled) {
5167 cloneEl = clone(dragEl);
5168 cloneEl.removeAttribute("id");
5169 cloneEl.draggable = false;
5170 cloneEl.style['will-change'] = '';
5171 this._hideClone();
5172 toggleClass(cloneEl, this.options.chosenClass, false);
5173 Sortable.clone = cloneEl;
5174 }
5175
5176 // #1143: IFrame support workaround
5177 _this.cloneId = _nextTick(function () {
5178 pluginEvent('clone', _this);
5179 if (Sortable.eventCanceled) return;
5180 if (!_this.options.removeCloneOnHide) {
5181 rootEl.insertBefore(cloneEl, dragEl);
5182 }
5183 _this._hideClone();
5184 _dispatchEvent({
5185 sortable: _this,
5186 name: 'clone'
5187 });
5188 });
5189 !fallback && toggleClass(dragEl, options.dragClass, true);
5190
5191 // Set proper drop events
5192 if (fallback) {
5193 ignoreNextClick = true;
5194 _this._loopId = setInterval(_this._emulateDragOver, 50);
5195 } else {
5196 // Undo what was set in _prepareDragStart before drag started
5197 off(document, 'mouseup', _this._onDrop);
5198 off(document, 'touchend', _this._onDrop);
5199 off(document, 'touchcancel', _this._onDrop);
5200 if (dataTransfer) {
5201 dataTransfer.effectAllowed = 'move';
5202 options.setData && options.setData.call(_this, dataTransfer, dragEl);
5203 }
5204 on(document, 'drop', _this);
5205
5206 // #1276 fix:
5207 css(dragEl, 'transform', 'translateZ(0)');
5208 }
5209 awaitingDragStarted = true;
5210 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
5211 on(document, 'selectstart', _this);
5212 moved = true;
5213 window.getSelection().removeAllRanges();
5214 if (Safari) {
5215 css(document.body, 'user-select', 'none');
5216 }
5217 },
5218 // Returns true - if no further action is needed (either inserted or another condition)
5219 _onDragOver: function _onDragOver( /**Event*/evt) {
5220 var el = this.el,
5221 target = evt.target,
5222 dragRect,
5223 targetRect,
5224 revert,
5225 options = this.options,
5226 group = options.group,
5227 activeSortable = Sortable.active,
5228 isOwner = activeGroup === group,
5229 canSort = options.sort,
5230 fromSortable = putSortable || activeSortable,
5231 vertical,
5232 _this = this,
5233 completedFired = false;
5234 if (_silent) return;
5235 function dragOverEvent(name, extra) {
5236 pluginEvent(name, _this, _objectSpread2({
5237 evt: evt,
5238 isOwner: isOwner,
5239 axis: vertical ? 'vertical' : 'horizontal',
5240 revert: revert,
5241 dragRect: dragRect,
5242 targetRect: targetRect,
5243 canSort: canSort,
5244 fromSortable: fromSortable,
5245 target: target,
5246 completed: completed,
5247 onMove: function onMove(target, after) {
5248 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
5249 },
5250 changed: changed
5251 }, extra));
5252 }
5253
5254 // Capture animation state
5255 function capture() {
5256 dragOverEvent('dragOverAnimationCapture');
5257 _this.captureAnimationState();
5258 if (_this !== fromSortable) {
5259 fromSortable.captureAnimationState();
5260 }
5261 }
5262
5263 // Return invocation when dragEl is inserted (or completed)
5264 function completed(insertion) {
5265 dragOverEvent('dragOverCompleted', {
5266 insertion: insertion
5267 });
5268 if (insertion) {
5269 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
5270 if (isOwner) {
5271 activeSortable._hideClone();
5272 } else {
5273 activeSortable._showClone(_this);
5274 }
5275 if (_this !== fromSortable) {
5276 // Set ghost class to new sortable's ghost class
5277 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
5278 toggleClass(dragEl, options.ghostClass, true);
5279 }
5280 if (putSortable !== _this && _this !== Sortable.active) {
5281 putSortable = _this;
5282 } else if (_this === Sortable.active && putSortable) {
5283 putSortable = null;
5284 }
5285
5286 // Animation
5287 if (fromSortable === _this) {
5288 _this._ignoreWhileAnimating = target;
5289 }
5290 _this.animateAll(function () {
5291 dragOverEvent('dragOverAnimationComplete');
5292 _this._ignoreWhileAnimating = null;
5293 });
5294 if (_this !== fromSortable) {
5295 fromSortable.animateAll();
5296 fromSortable._ignoreWhileAnimating = null;
5297 }
5298 }
5299
5300 // Null lastTarget if it is not inside a previously swapped element
5301 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
5302 lastTarget = null;
5303 }
5304
5305 // no bubbling and not fallback
5306 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
5307 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
5308
5309 // Do not detect for empty insert if already inserted
5310 !insertion && nearestEmptyInsertDetectEvent(evt);
5311 }
5312 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
5313 return completedFired = true;
5314 }
5315
5316 // Call when dragEl has been inserted
5317 function changed() {
5318 newIndex = index(dragEl);
5319 newDraggableIndex = index(dragEl, options.draggable);
5320 _dispatchEvent({
5321 sortable: _this,
5322 name: 'change',
5323 toEl: el,
5324 newIndex: newIndex,
5325 newDraggableIndex: newDraggableIndex,
5326 originalEvent: evt
5327 });
5328 }
5329 if (evt.preventDefault !== void 0) {
5330 evt.cancelable && evt.preventDefault();
5331 }
5332 target = closest(target, options.draggable, el, true);
5333 dragOverEvent('dragOver');
5334 if (Sortable.eventCanceled) return completedFired;
5335 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
5336 return completed(false);
5337 }
5338 ignoreNextClick = false;
5339 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
5340 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
5341 vertical = this._getDirection(evt, target) === 'vertical';
5342 dragRect = getRect(dragEl);
5343 dragOverEvent('dragOverValid');
5344 if (Sortable.eventCanceled) return completedFired;
5345 if (revert) {
5346 parentEl = rootEl; // actualization
5347 capture();
5348 this._hideClone();
5349 dragOverEvent('revert');
5350 if (!Sortable.eventCanceled) {
5351 if (nextEl) {
5352 rootEl.insertBefore(dragEl, nextEl);
5353 } else {
5354 rootEl.appendChild(dragEl);
5355 }
5356 }
5357 return completed(true);
5358 }
5359 var elLastChild = lastChild(el, options.draggable);
5360 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
5361 // Insert to end of list
5362
5363 // If already at end of list: Do not insert
5364 if (elLastChild === dragEl) {
5365 return completed(false);
5366 }
5367
5368 // if there is a last element, it is the target
5369 if (elLastChild && el === evt.target) {
5370 target = elLastChild;
5371 }
5372 if (target) {
5373 targetRect = getRect(target);
5374 }
5375 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
5376 capture();
5377 if (elLastChild && elLastChild.nextSibling) {
5378 // the last draggable element is not the last node
5379 el.insertBefore(dragEl, elLastChild.nextSibling);
5380 } else {
5381 el.appendChild(dragEl);
5382 }
5383 parentEl = el; // actualization
5384
5385 changed();
5386 return completed(true);
5387 }
5388 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
5389 // Insert to start of list
5390 var firstChild = getChild(el, 0, options, true);
5391 if (firstChild === dragEl) {
5392 return completed(false);
5393 }
5394 target = firstChild;
5395 targetRect = getRect(target);
5396 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
5397 capture();
5398 el.insertBefore(dragEl, firstChild);
5399 parentEl = el; // actualization
5400
5401 changed();
5402 return completed(true);
5403 }
5404 } else if (target.parentNode === el) {
5405 targetRect = getRect(target);
5406 var direction = 0,
5407 targetBeforeFirstSwap,
5408 differentLevel = dragEl.parentNode !== el,
5409 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
5410 side1 = vertical ? 'top' : 'left',
5411 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
5412 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
5413 if (lastTarget !== target) {
5414 targetBeforeFirstSwap = targetRect[side1];
5415 pastFirstInvertThresh = false;
5416 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
5417 }
5418 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
5419 var sibling;
5420 if (direction !== 0) {
5421 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
5422 var dragIndex = index(dragEl);
5423 do {
5424 dragIndex -= direction;
5425 sibling = parentEl.children[dragIndex];
5426 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
5427 }
5428 // If dragEl is already beside target: Do not insert
5429 if (direction === 0 || sibling === target) {
5430 return completed(false);
5431 }
5432 lastTarget = target;
5433 lastDirection = direction;
5434 var nextSibling = target.nextElementSibling,
5435 after = false;
5436 after = direction === 1;
5437 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
5438 if (moveVector !== false) {
5439 if (moveVector === 1 || moveVector === -1) {
5440 after = moveVector === 1;
5441 }
5442 _silent = true;
5443 setTimeout(_unsilent, 30);
5444 capture();
5445 if (after && !nextSibling) {
5446 el.appendChild(dragEl);
5447 } else {
5448 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
5449 }
5450
5451 // Undo chrome's scroll adjustment (has no effect on other browsers)
5452 if (scrolledPastTop) {
5453 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
5454 }
5455 parentEl = dragEl.parentNode; // actualization
5456
5457 // must be done before animation
5458 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
5459 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
5460 }
5461 changed();
5462 return completed(true);
5463 }
5464 }
5465 if (el.contains(dragEl)) {
5466 return completed(false);
5467 }
5468 }
5469 return false;
5470 },
5471 _ignoreWhileAnimating: null,
5472 _offMoveEvents: function _offMoveEvents() {
5473 off(document, 'mousemove', this._onTouchMove);
5474 off(document, 'touchmove', this._onTouchMove);
5475 off(document, 'pointermove', this._onTouchMove);
5476 off(document, 'dragover', nearestEmptyInsertDetectEvent);
5477 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
5478 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
5479 },
5480 _offUpEvents: function _offUpEvents() {
5481 var ownerDocument = this.el.ownerDocument;
5482 off(ownerDocument, 'mouseup', this._onDrop);
5483 off(ownerDocument, 'touchend', this._onDrop);
5484 off(ownerDocument, 'pointerup', this._onDrop);
5485 off(ownerDocument, 'pointercancel', this._onDrop);
5486 off(ownerDocument, 'touchcancel', this._onDrop);
5487 off(document, 'selectstart', this);
5488 },
5489 _onDrop: function _onDrop( /**Event*/evt) {
5490 var el = this.el,
5491 options = this.options;
5492
5493 // Get the index of the dragged element within its parent
5494 newIndex = index(dragEl);
5495 newDraggableIndex = index(dragEl, options.draggable);
5496 pluginEvent('drop', this, {
5497 evt: evt
5498 });
5499 parentEl = dragEl && dragEl.parentNode;
5500
5501 // Get again after plugin event
5502 newIndex = index(dragEl);
5503 newDraggableIndex = index(dragEl, options.draggable);
5504 if (Sortable.eventCanceled) {
5505 this._nulling();
5506 return;
5507 }
5508 awaitingDragStarted = false;
5509 isCircumstantialInvert = false;
5510 pastFirstInvertThresh = false;
5511 clearInterval(this._loopId);
5512 clearTimeout(this._dragStartTimer);
5513 _cancelNextTick(this.cloneId);
5514 _cancelNextTick(this._dragStartId);
5515
5516 // Unbind events
5517 if (this.nativeDraggable) {
5518 off(document, 'drop', this);
5519 off(el, 'dragstart', this._onDragStart);
5520 }
5521 this._offMoveEvents();
5522 this._offUpEvents();
5523 if (Safari) {
5524 css(document.body, 'user-select', '');
5525 }
5526 css(dragEl, 'transform', '');
5527 if (evt) {
5528 if (moved) {
5529 evt.cancelable && evt.preventDefault();
5530 !options.dropBubble && evt.stopPropagation();
5531 }
5532 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
5533 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
5534 // Remove clone(s)
5535 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
5536 }
5537 if (dragEl) {
5538 if (this.nativeDraggable) {
5539 off(dragEl, 'dragend', this);
5540 }
5541 _disableDraggable(dragEl);
5542 dragEl.style['will-change'] = '';
5543
5544 // Remove classes
5545 // ghostClass is added in dragStarted
5546 if (moved && !awaitingDragStarted) {
5547 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
5548 }
5549 toggleClass(dragEl, this.options.chosenClass, false);
5550
5551 // Drag stop event
5552 _dispatchEvent({
5553 sortable: this,
5554 name: 'unchoose',
5555 toEl: parentEl,
5556 newIndex: null,
5557 newDraggableIndex: null,
5558 originalEvent: evt
5559 });
5560 if (rootEl !== parentEl) {
5561 if (newIndex >= 0) {
5562 // Add event
5563 _dispatchEvent({
5564 rootEl: parentEl,
5565 name: 'add',
5566 toEl: parentEl,
5567 fromEl: rootEl,
5568 originalEvent: evt
5569 });
5570
5571 // Remove event
5572 _dispatchEvent({
5573 sortable: this,
5574 name: 'remove',
5575 toEl: parentEl,
5576 originalEvent: evt
5577 });
5578
5579 // drag from one list and drop into another
5580 _dispatchEvent({
5581 rootEl: parentEl,
5582 name: 'sort',
5583 toEl: parentEl,
5584 fromEl: rootEl,
5585 originalEvent: evt
5586 });
5587 _dispatchEvent({
5588 sortable: this,
5589 name: 'sort',
5590 toEl: parentEl,
5591 originalEvent: evt
5592 });
5593 }
5594 putSortable && putSortable.save();
5595 } else {
5596 if (newIndex !== oldIndex) {
5597 if (newIndex >= 0) {
5598 // drag & drop within the same list
5599 _dispatchEvent({
5600 sortable: this,
5601 name: 'update',
5602 toEl: parentEl,
5603 originalEvent: evt
5604 });
5605 _dispatchEvent({
5606 sortable: this,
5607 name: 'sort',
5608 toEl: parentEl,
5609 originalEvent: evt
5610 });
5611 }
5612 }
5613 }
5614 if (Sortable.active) {
5615 /* jshint eqnull:true */
5616 if (newIndex == null || newIndex === -1) {
5617 newIndex = oldIndex;
5618 newDraggableIndex = oldDraggableIndex;
5619 }
5620 _dispatchEvent({
5621 sortable: this,
5622 name: 'end',
5623 toEl: parentEl,
5624 originalEvent: evt
5625 });
5626
5627 // Save sorting
5628 this.save();
5629 }
5630 }
5631 }
5632 this._nulling();
5633 },
5634 _nulling: function _nulling() {
5635 pluginEvent('nulling', this);
5636 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;
5637 var el = this.el;
5638 savedInputChecked.forEach(function (checkEl) {
5639 if (el.contains(checkEl)) {
5640 checkEl.checked = true;
5641 }
5642 });
5643 savedInputChecked.length = lastDx = lastDy = 0;
5644 },
5645 handleEvent: function handleEvent( /**Event*/evt) {
5646 switch (evt.type) {
5647 case 'drop':
5648 case 'dragend':
5649 this._onDrop(evt);
5650 break;
5651 case 'dragenter':
5652 case 'dragover':
5653 if (dragEl) {
5654 this._onDragOver(evt);
5655 _globalDragOver(evt);
5656 }
5657 break;
5658 case 'selectstart':
5659 evt.preventDefault();
5660 break;
5661 }
5662 },
5663 /**
5664 * Serializes the item into an array of string.
5665 * @returns {String[]}
5666 */
5667 toArray: function toArray() {
5668 var order = [],
5669 el,
5670 children = this.el.children,
5671 i = 0,
5672 n = children.length,
5673 options = this.options;
5674 for (; i < n; i++) {
5675 el = children[i];
5676 if (closest(el, options.draggable, this.el, false)) {
5677 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
5678 }
5679 }
5680 return order;
5681 },
5682 /**
5683 * Sorts the elements according to the array.
5684 * @param {String[]} order order of the items
5685 */
5686 sort: function sort(order, useAnimation) {
5687 var items = {},
5688 rootEl = this.el;
5689 this.toArray().forEach(function (id, i) {
5690 var el = rootEl.children[i];
5691 if (closest(el, this.options.draggable, rootEl, false)) {
5692 items[id] = el;
5693 }
5694 }, this);
5695 useAnimation && this.captureAnimationState();
5696 order.forEach(function (id) {
5697 if (items[id]) {
5698 rootEl.removeChild(items[id]);
5699 rootEl.appendChild(items[id]);
5700 }
5701 });
5702 useAnimation && this.animateAll();
5703 },
5704 /**
5705 * Save the current sorting
5706 */
5707 save: function save() {
5708 var store = this.options.store;
5709 store && store.set && store.set(this);
5710 },
5711 /**
5712 * 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.
5713 * @param {HTMLElement} el
5714 * @param {String} [selector] default: `options.draggable`
5715 * @returns {HTMLElement|null}
5716 */
5717 closest: function closest$1(el, selector) {
5718 return closest(el, selector || this.options.draggable, this.el, false);
5719 },
5720 /**
5721 * Set/get option
5722 * @param {string} name
5723 * @param {*} [value]
5724 * @returns {*}
5725 */
5726 option: function option(name, value) {
5727 var options = this.options;
5728 if (value === void 0) {
5729 return options[name];
5730 } else {
5731 var modifiedValue = PluginManager.modifyOption(this, name, value);
5732 if (typeof modifiedValue !== 'undefined') {
5733 options[name] = modifiedValue;
5734 } else {
5735 options[name] = value;
5736 }
5737 if (name === 'group') {
5738 _prepareGroup(options);
5739 }
5740 }
5741 },
5742 /**
5743 * Destroy
5744 */
5745 destroy: function destroy() {
5746 pluginEvent('destroy', this);
5747 var el = this.el;
5748 el[expando] = null;
5749 off(el, 'mousedown', this._onTapStart);
5750 off(el, 'touchstart', this._onTapStart);
5751 off(el, 'pointerdown', this._onTapStart);
5752 if (this.nativeDraggable) {
5753 off(el, 'dragover', this);
5754 off(el, 'dragenter', this);
5755 }
5756 // Remove draggable attributes
5757 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
5758 el.removeAttribute('draggable');
5759 });
5760 this._onDrop();
5761 this._disableDelayedDragEvents();
5762 sortables.splice(sortables.indexOf(this.el), 1);
5763 this.el = el = null;
5764 },
5765 _hideClone: function _hideClone() {
5766 if (!cloneHidden) {
5767 pluginEvent('hideClone', this);
5768 if (Sortable.eventCanceled) return;
5769 css(cloneEl, 'display', 'none');
5770 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
5771 cloneEl.parentNode.removeChild(cloneEl);
5772 }
5773 cloneHidden = true;
5774 }
5775 },
5776 _showClone: function _showClone(putSortable) {
5777 if (putSortable.lastPutMode !== 'clone') {
5778 this._hideClone();
5779 return;
5780 }
5781 if (cloneHidden) {
5782 pluginEvent('showClone', this);
5783 if (Sortable.eventCanceled) return;
5784
5785 // show clone at dragEl or original position
5786 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
5787 rootEl.insertBefore(cloneEl, dragEl);
5788 } else if (nextEl) {
5789 rootEl.insertBefore(cloneEl, nextEl);
5790 } else {
5791 rootEl.appendChild(cloneEl);
5792 }
5793 if (this.options.group.revertClone) {
5794 this.animate(dragEl, cloneEl);
5795 }
5796 css(cloneEl, 'display', '');
5797 cloneHidden = false;
5798 }
5799 }
5800 };
5801 function _globalDragOver( /**Event*/evt) {
5802 if (evt.dataTransfer) {
5803 evt.dataTransfer.dropEffect = 'move';
5804 }
5805 evt.cancelable && evt.preventDefault();
5806 }
5807 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
5808 var evt,
5809 sortable = fromEl[expando],
5810 onMoveFn = sortable.options.onMove,
5811 retVal;
5812 // Support for new CustomEvent feature
5813 if (window.CustomEvent && !IE11OrLess && !Edge) {
5814 evt = new CustomEvent('move', {
5815 bubbles: true,
5816 cancelable: true
5817 });
5818 } else {
5819 evt = document.createEvent('Event');
5820 evt.initEvent('move', true, true);
5821 }
5822 evt.to = toEl;
5823 evt.from = fromEl;
5824 evt.dragged = dragEl;
5825 evt.draggedRect = dragRect;
5826 evt.related = targetEl || toEl;
5827 evt.relatedRect = targetRect || getRect(toEl);
5828 evt.willInsertAfter = willInsertAfter;
5829 evt.originalEvent = originalEvent;
5830 fromEl.dispatchEvent(evt);
5831 if (onMoveFn) {
5832 retVal = onMoveFn.call(sortable, evt, originalEvent);
5833 }
5834 return retVal;
5835 }
5836 function _disableDraggable(el) {
5837 el.draggable = false;
5838 }
5839 function _unsilent() {
5840 _silent = false;
5841 }
5842 function _ghostIsFirst(evt, vertical, sortable) {
5843 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
5844 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
5845 var spacer = 10;
5846 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;
5847 }
5848 function _ghostIsLast(evt, vertical, sortable) {
5849 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
5850 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
5851 var spacer = 10;
5852 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;
5853 }
5854 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
5855 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
5856 targetLength = vertical ? targetRect.height : targetRect.width,
5857 targetS1 = vertical ? targetRect.top : targetRect.left,
5858 targetS2 = vertical ? targetRect.bottom : targetRect.right,
5859 invert = false;
5860 if (!invertSwap) {
5861 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
5862 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
5863 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
5864 // check if past first invert threshold on side opposite of lastDirection
5865 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
5866 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
5867 pastFirstInvertThresh = true;
5868 }
5869 if (!pastFirstInvertThresh) {
5870 // dragEl shadow (target move distance shadow)
5871 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
5872 : mouseOnAxis > targetS2 - targetMoveDistance) {
5873 return -lastDirection;
5874 }
5875 } else {
5876 invert = true;
5877 }
5878 } else {
5879 // Regular
5880 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
5881 return _getInsertDirection(target);
5882 }
5883 }
5884 }
5885 invert = invert || invertSwap;
5886 if (invert) {
5887 // Invert of regular
5888 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
5889 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
5890 }
5891 }
5892 return 0;
5893 }
5894
5895 /**
5896 * Gets the direction dragEl must be swapped relative to target in order to make it
5897 * seem that dragEl has been "inserted" into that element's position
5898 * @param {HTMLElement} target The target whose position dragEl is being inserted at
5899 * @return {Number} Direction dragEl must be swapped
5900 */
5901 function _getInsertDirection(target) {
5902 if (index(dragEl) < index(target)) {
5903 return 1;
5904 } else {
5905 return -1;
5906 }
5907 }
5908
5909 /**
5910 * Generate id
5911 * @param {HTMLElement} el
5912 * @returns {String}
5913 * @private
5914 */
5915 function _generateId(el) {
5916 var str = el.tagName + el.className + el.src + el.href + el.textContent,
5917 i = str.length,
5918 sum = 0;
5919 while (i--) {
5920 sum += str.charCodeAt(i);
5921 }
5922 return sum.toString(36);
5923 }
5924 function _saveInputCheckedState(root) {
5925 savedInputChecked.length = 0;
5926 var inputs = root.getElementsByTagName('input');
5927 var idx = inputs.length;
5928 while (idx--) {
5929 var el = inputs[idx];
5930 el.checked && savedInputChecked.push(el);
5931 }
5932 }
5933 function _nextTick(fn) {
5934 return setTimeout(fn, 0);
5935 }
5936 function _cancelNextTick(id) {
5937 return clearTimeout(id);
5938 }
5939
5940 // Fixed #973:
5941 if (documentExists) {
5942 on(document, 'touchmove', function (evt) {
5943 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
5944 evt.preventDefault();
5945 }
5946 });
5947 }
5948
5949 // Export utils
5950 Sortable.utils = {
5951 on: on,
5952 off: off,
5953 css: css,
5954 find: find,
5955 is: function is(el, selector) {
5956 return !!closest(el, selector, el, false);
5957 },
5958 extend: extend,
5959 throttle: throttle,
5960 closest: closest,
5961 toggleClass: toggleClass,
5962 clone: clone,
5963 index: index,
5964 nextTick: _nextTick,
5965 cancelNextTick: _cancelNextTick,
5966 detectDirection: _detectDirection,
5967 getChild: getChild,
5968 expando: expando
5969 };
5970
5971 /**
5972 * Get the Sortable instance of an element
5973 * @param {HTMLElement} element The element
5974 * @return {Sortable|undefined} The instance of Sortable
5975 */
5976 Sortable.get = function (element) {
5977 return element[expando];
5978 };
5979
5980 /**
5981 * Mount a plugin to Sortable
5982 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
5983 */
5984 Sortable.mount = function () {
5985 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
5986 plugins[_key] = arguments[_key];
5987 }
5988 if (plugins[0].constructor === Array) plugins = plugins[0];
5989 plugins.forEach(function (plugin) {
5990 if (!plugin.prototype || !plugin.prototype.constructor) {
5991 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
5992 }
5993 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
5994 PluginManager.mount(plugin);
5995 });
5996 };
5997
5998 /**
5999 * Create sortable instance
6000 * @param {HTMLElement} el
6001 * @param {Object} [options]
6002 */
6003 Sortable.create = function (el, options) {
6004 return new Sortable(el, options);
6005 };
6006
6007 // Export
6008 Sortable.version = version;
6009
6010 var autoScrolls = [],
6011 scrollEl,
6012 scrollRootEl,
6013 scrolling = false,
6014 lastAutoScrollX,
6015 lastAutoScrollY,
6016 touchEvt$1,
6017 pointerElemChangedInterval;
6018 function AutoScrollPlugin() {
6019 function AutoScroll() {
6020 this.defaults = {
6021 scroll: true,
6022 forceAutoScrollFallback: false,
6023 scrollSensitivity: 30,
6024 scrollSpeed: 10,
6025 bubbleScroll: true
6026 };
6027
6028 // Bind all private methods
6029 for (var fn in this) {
6030 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
6031 this[fn] = this[fn].bind(this);
6032 }
6033 }
6034 }
6035 AutoScroll.prototype = {
6036 dragStarted: function dragStarted(_ref) {
6037 var originalEvent = _ref.originalEvent;
6038 if (this.sortable.nativeDraggable) {
6039 on(document, 'dragover', this._handleAutoScroll);
6040 } else {
6041 if (this.options.supportPointer) {
6042 on(document, 'pointermove', this._handleFallbackAutoScroll);
6043 } else if (originalEvent.touches) {
6044 on(document, 'touchmove', this._handleFallbackAutoScroll);
6045 } else {
6046 on(document, 'mousemove', this._handleFallbackAutoScroll);
6047 }
6048 }
6049 },
6050 dragOverCompleted: function dragOverCompleted(_ref2) {
6051 var originalEvent = _ref2.originalEvent;
6052 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
6053 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
6054 this._handleAutoScroll(originalEvent);
6055 }
6056 },
6057 drop: function drop() {
6058 if (this.sortable.nativeDraggable) {
6059 off(document, 'dragover', this._handleAutoScroll);
6060 } else {
6061 off(document, 'pointermove', this._handleFallbackAutoScroll);
6062 off(document, 'touchmove', this._handleFallbackAutoScroll);
6063 off(document, 'mousemove', this._handleFallbackAutoScroll);
6064 }
6065 clearPointerElemChangedInterval();
6066 clearAutoScrolls();
6067 cancelThrottle();
6068 },
6069 nulling: function nulling() {
6070 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
6071 autoScrolls.length = 0;
6072 },
6073 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
6074 this._handleAutoScroll(evt, true);
6075 },
6076 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
6077 var _this = this;
6078 var x = (evt.touches ? evt.touches[0] : evt).clientX,
6079 y = (evt.touches ? evt.touches[0] : evt).clientY,
6080 elem = document.elementFromPoint(x, y);
6081 touchEvt$1 = evt;
6082
6083 // IE does not seem to have native autoscroll,
6084 // Edge's autoscroll seems too conditional,
6085 // MACOS Safari does not have autoscroll,
6086 // Firefox and Chrome are good
6087 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
6088 autoScroll(evt, this.options, elem, fallback);
6089
6090 // Listener for pointer element change
6091 var ogElemScroller = getParentAutoScrollElement(elem, true);
6092 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
6093 pointerElemChangedInterval && clearPointerElemChangedInterval();
6094 // Detect for pointer elem change, emulating native DnD behaviour
6095 pointerElemChangedInterval = setInterval(function () {
6096 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
6097 if (newElem !== ogElemScroller) {
6098 ogElemScroller = newElem;
6099 clearAutoScrolls();
6100 }
6101 autoScroll(evt, _this.options, newElem, fallback);
6102 }, 10);
6103 lastAutoScrollX = x;
6104 lastAutoScrollY = y;
6105 }
6106 } else {
6107 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
6108 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
6109 clearAutoScrolls();
6110 return;
6111 }
6112 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
6113 }
6114 }
6115 };
6116 return _extends(AutoScroll, {
6117 pluginName: 'scroll',
6118 initializeByDefault: true
6119 });
6120 }
6121 function clearAutoScrolls() {
6122 autoScrolls.forEach(function (autoScroll) {
6123 clearInterval(autoScroll.pid);
6124 });
6125 autoScrolls = [];
6126 }
6127 function clearPointerElemChangedInterval() {
6128 clearInterval(pointerElemChangedInterval);
6129 }
6130 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
6131 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
6132 if (!options.scroll) return;
6133 var x = (evt.touches ? evt.touches[0] : evt).clientX,
6134 y = (evt.touches ? evt.touches[0] : evt).clientY,
6135 sens = options.scrollSensitivity,
6136 speed = options.scrollSpeed,
6137 winScroller = getWindowScrollingElement();
6138 var scrollThisInstance = false,
6139 scrollCustomFn;
6140
6141 // New scroll root, set scrollEl
6142 if (scrollRootEl !== rootEl) {
6143 scrollRootEl = rootEl;
6144 clearAutoScrolls();
6145 scrollEl = options.scroll;
6146 scrollCustomFn = options.scrollFn;
6147 if (scrollEl === true) {
6148 scrollEl = getParentAutoScrollElement(rootEl, true);
6149 }
6150 }
6151 var layersOut = 0;
6152 var currentParent = scrollEl;
6153 do {
6154 var el = currentParent,
6155 rect = getRect(el),
6156 top = rect.top,
6157 bottom = rect.bottom,
6158 left = rect.left,
6159 right = rect.right,
6160 width = rect.width,
6161 height = rect.height,
6162 canScrollX = void 0,
6163 canScrollY = void 0,
6164 scrollWidth = el.scrollWidth,
6165 scrollHeight = el.scrollHeight,
6166 elCSS = css(el),
6167 scrollPosX = el.scrollLeft,
6168 scrollPosY = el.scrollTop;
6169 if (el === winScroller) {
6170 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
6171 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
6172 } else {
6173 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
6174 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
6175 }
6176 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
6177 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
6178 if (!autoScrolls[layersOut]) {
6179 for (var i = 0; i <= layersOut; i++) {
6180 if (!autoScrolls[i]) {
6181 autoScrolls[i] = {};
6182 }
6183 }
6184 }
6185 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
6186 autoScrolls[layersOut].el = el;
6187 autoScrolls[layersOut].vx = vx;
6188 autoScrolls[layersOut].vy = vy;
6189 clearInterval(autoScrolls[layersOut].pid);
6190 if (vx != 0 || vy != 0) {
6191 scrollThisInstance = true;
6192 /* jshint loopfunc:true */
6193 autoScrolls[layersOut].pid = setInterval(function () {
6194 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
6195 if (isFallback && this.layer === 0) {
6196 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
6197 }
6198 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
6199 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
6200 if (typeof scrollCustomFn === 'function') {
6201 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
6202 return;
6203 }
6204 }
6205 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
6206 }.bind({
6207 layer: layersOut
6208 }), 24);
6209 }
6210 }
6211 layersOut++;
6212 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
6213 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
6214 }, 30);
6215
6216 var drop = function drop(_ref) {
6217 var originalEvent = _ref.originalEvent,
6218 putSortable = _ref.putSortable,
6219 dragEl = _ref.dragEl,
6220 activeSortable = _ref.activeSortable,
6221 dispatchSortableEvent = _ref.dispatchSortableEvent,
6222 hideGhostForTarget = _ref.hideGhostForTarget,
6223 unhideGhostForTarget = _ref.unhideGhostForTarget;
6224 if (!originalEvent) return;
6225 var toSortable = putSortable || activeSortable;
6226 hideGhostForTarget();
6227 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
6228 var target = document.elementFromPoint(touch.clientX, touch.clientY);
6229 unhideGhostForTarget();
6230 if (toSortable && !toSortable.el.contains(target)) {
6231 dispatchSortableEvent('spill');
6232 this.onSpill({
6233 dragEl: dragEl,
6234 putSortable: putSortable
6235 });
6236 }
6237 };
6238 function Revert() {}
6239 Revert.prototype = {
6240 startIndex: null,
6241 dragStart: function dragStart(_ref2) {
6242 var oldDraggableIndex = _ref2.oldDraggableIndex;
6243 this.startIndex = oldDraggableIndex;
6244 },
6245 onSpill: function onSpill(_ref3) {
6246 var dragEl = _ref3.dragEl,
6247 putSortable = _ref3.putSortable;
6248 this.sortable.captureAnimationState();
6249 if (putSortable) {
6250 putSortable.captureAnimationState();
6251 }
6252 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
6253 if (nextSibling) {
6254 this.sortable.el.insertBefore(dragEl, nextSibling);
6255 } else {
6256 this.sortable.el.appendChild(dragEl);
6257 }
6258 this.sortable.animateAll();
6259 if (putSortable) {
6260 putSortable.animateAll();
6261 }
6262 },
6263 drop: drop
6264 };
6265 _extends(Revert, {
6266 pluginName: 'revertOnSpill'
6267 });
6268 function Remove() {}
6269 Remove.prototype = {
6270 onSpill: function onSpill(_ref4) {
6271 var dragEl = _ref4.dragEl,
6272 putSortable = _ref4.putSortable;
6273 var parentSortable = putSortable || this.sortable;
6274 parentSortable.captureAnimationState();
6275 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
6276 parentSortable.animateAll();
6277 },
6278 drop: drop
6279 };
6280 _extends(Remove, {
6281 pluginName: 'removeOnSpill'
6282 });
6283
6284 var lastSwapEl;
6285 function SwapPlugin() {
6286 function Swap() {
6287 this.defaults = {
6288 swapClass: 'sortable-swap-highlight'
6289 };
6290 }
6291 Swap.prototype = {
6292 dragStart: function dragStart(_ref) {
6293 var dragEl = _ref.dragEl;
6294 lastSwapEl = dragEl;
6295 },
6296 dragOverValid: function dragOverValid(_ref2) {
6297 var completed = _ref2.completed,
6298 target = _ref2.target,
6299 onMove = _ref2.onMove,
6300 activeSortable = _ref2.activeSortable,
6301 changed = _ref2.changed,
6302 cancel = _ref2.cancel;
6303 if (!activeSortable.options.swap) return;
6304 var el = this.sortable.el,
6305 options = this.options;
6306 if (target && target !== el) {
6307 var prevSwapEl = lastSwapEl;
6308 if (onMove(target) !== false) {
6309 toggleClass(target, options.swapClass, true);
6310 lastSwapEl = target;
6311 } else {
6312 lastSwapEl = null;
6313 }
6314 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
6315 toggleClass(prevSwapEl, options.swapClass, false);
6316 }
6317 }
6318 changed();
6319 completed(true);
6320 cancel();
6321 },
6322 drop: function drop(_ref3) {
6323 var activeSortable = _ref3.activeSortable,
6324 putSortable = _ref3.putSortable,
6325 dragEl = _ref3.dragEl;
6326 var toSortable = putSortable || this.sortable;
6327 var options = this.options;
6328 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
6329 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
6330 if (dragEl !== lastSwapEl) {
6331 toSortable.captureAnimationState();
6332 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
6333 swapNodes(dragEl, lastSwapEl);
6334 toSortable.animateAll();
6335 if (toSortable !== activeSortable) activeSortable.animateAll();
6336 }
6337 }
6338 },
6339 nulling: function nulling() {
6340 lastSwapEl = null;
6341 }
6342 };
6343 return _extends(Swap, {
6344 pluginName: 'swap',
6345 eventProperties: function eventProperties() {
6346 return {
6347 swapItem: lastSwapEl
6348 };
6349 }
6350 });
6351 }
6352 function swapNodes(n1, n2) {
6353 var p1 = n1.parentNode,
6354 p2 = n2.parentNode,
6355 i1,
6356 i2;
6357 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
6358 i1 = index(n1);
6359 i2 = index(n2);
6360 if (p1.isEqualNode(p2) && i1 < i2) {
6361 i2++;
6362 }
6363 p1.insertBefore(n2, p1.children[i1]);
6364 p2.insertBefore(n1, p2.children[i2]);
6365 }
6366
6367 var multiDragElements = [],
6368 multiDragClones = [],
6369 lastMultiDragSelect,
6370 // for selection with modifier key down (SHIFT)
6371 multiDragSortable,
6372 initialFolding = false,
6373 // Initial multi-drag fold when drag started
6374 folding = false,
6375 // Folding any other time
6376 dragStarted = false,
6377 dragEl$1,
6378 clonesFromRect,
6379 clonesHidden;
6380 function MultiDragPlugin() {
6381 function MultiDrag(sortable) {
6382 // Bind all private methods
6383 for (var fn in this) {
6384 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
6385 this[fn] = this[fn].bind(this);
6386 }
6387 }
6388 if (!sortable.options.avoidImplicitDeselect) {
6389 if (sortable.options.supportPointer) {
6390 on(document, 'pointerup', this._deselectMultiDrag);
6391 } else {
6392 on(document, 'mouseup', this._deselectMultiDrag);
6393 on(document, 'touchend', this._deselectMultiDrag);
6394 }
6395 }
6396 on(document, 'keydown', this._checkKeyDown);
6397 on(document, 'keyup', this._checkKeyUp);
6398 this.defaults = {
6399 selectedClass: 'sortable-selected',
6400 multiDragKey: null,
6401 avoidImplicitDeselect: false,
6402 setData: function setData(dataTransfer, dragEl) {
6403 var data = '';
6404 if (multiDragElements.length && multiDragSortable === sortable) {
6405 multiDragElements.forEach(function (multiDragElement, i) {
6406 data += (!i ? '' : ', ') + multiDragElement.textContent;
6407 });
6408 } else {
6409 data = dragEl.textContent;
6410 }
6411 dataTransfer.setData('Text', data);
6412 }
6413 };
6414 }
6415 MultiDrag.prototype = {
6416 multiDragKeyDown: false,
6417 isMultiDrag: false,
6418 delayStartGlobal: function delayStartGlobal(_ref) {
6419 var dragged = _ref.dragEl;
6420 dragEl$1 = dragged;
6421 },
6422 delayEnded: function delayEnded() {
6423 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
6424 },
6425 setupClone: function setupClone(_ref2) {
6426 var sortable = _ref2.sortable,
6427 cancel = _ref2.cancel;
6428 if (!this.isMultiDrag) return;
6429 for (var i = 0; i < multiDragElements.length; i++) {
6430 multiDragClones.push(clone(multiDragElements[i]));
6431 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
6432 multiDragClones[i].draggable = false;
6433 multiDragClones[i].style['will-change'] = '';
6434 toggleClass(multiDragClones[i], this.options.selectedClass, false);
6435 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
6436 }
6437 sortable._hideClone();
6438 cancel();
6439 },
6440 clone: function clone(_ref3) {
6441 var sortable = _ref3.sortable,
6442 rootEl = _ref3.rootEl,
6443 dispatchSortableEvent = _ref3.dispatchSortableEvent,
6444 cancel = _ref3.cancel;
6445 if (!this.isMultiDrag) return;
6446 if (!this.options.removeCloneOnHide) {
6447 if (multiDragElements.length && multiDragSortable === sortable) {
6448 insertMultiDragClones(true, rootEl);
6449 dispatchSortableEvent('clone');
6450 cancel();
6451 }
6452 }
6453 },
6454 showClone: function showClone(_ref4) {
6455 var cloneNowShown = _ref4.cloneNowShown,
6456 rootEl = _ref4.rootEl,
6457 cancel = _ref4.cancel;
6458 if (!this.isMultiDrag) return;
6459 insertMultiDragClones(false, rootEl);
6460 multiDragClones.forEach(function (clone) {
6461 css(clone, 'display', '');
6462 });
6463 cloneNowShown();
6464 clonesHidden = false;
6465 cancel();
6466 },
6467 hideClone: function hideClone(_ref5) {
6468 var _this = this;
6469 var sortable = _ref5.sortable,
6470 cloneNowHidden = _ref5.cloneNowHidden,
6471 cancel = _ref5.cancel;
6472 if (!this.isMultiDrag) return;
6473 multiDragClones.forEach(function (clone) {
6474 css(clone, 'display', 'none');
6475 if (_this.options.removeCloneOnHide && clone.parentNode) {
6476 clone.parentNode.removeChild(clone);
6477 }
6478 });
6479 cloneNowHidden();
6480 clonesHidden = true;
6481 cancel();
6482 },
6483 dragStartGlobal: function dragStartGlobal(_ref6) {
6484 var sortable = _ref6.sortable;
6485 if (!this.isMultiDrag && multiDragSortable) {
6486 multiDragSortable.multiDrag._deselectMultiDrag();
6487 }
6488 multiDragElements.forEach(function (multiDragElement) {
6489 multiDragElement.sortableIndex = index(multiDragElement);
6490 });
6491
6492 // Sort multi-drag elements
6493 multiDragElements = multiDragElements.sort(function (a, b) {
6494 return a.sortableIndex - b.sortableIndex;
6495 });
6496 dragStarted = true;
6497 },
6498 dragStarted: function dragStarted(_ref7) {
6499 var _this2 = this;
6500 var sortable = _ref7.sortable;
6501 if (!this.isMultiDrag) return;
6502 if (this.options.sort) {
6503 // Capture rects,
6504 // hide multi drag elements (by positioning them absolute),
6505 // set multi drag elements rects to dragRect,
6506 // show multi drag elements,
6507 // animate to rects,
6508 // unset rects & remove from DOM
6509
6510 sortable.captureAnimationState();
6511 if (this.options.animation) {
6512 multiDragElements.forEach(function (multiDragElement) {
6513 if (multiDragElement === dragEl$1) return;
6514 css(multiDragElement, 'position', 'absolute');
6515 });
6516 var dragRect = getRect(dragEl$1, false, true, true);
6517 multiDragElements.forEach(function (multiDragElement) {
6518 if (multiDragElement === dragEl$1) return;
6519 setRect(multiDragElement, dragRect);
6520 });
6521 folding = true;
6522 initialFolding = true;
6523 }
6524 }
6525 sortable.animateAll(function () {
6526 folding = false;
6527 initialFolding = false;
6528 if (_this2.options.animation) {
6529 multiDragElements.forEach(function (multiDragElement) {
6530 unsetRect(multiDragElement);
6531 });
6532 }
6533
6534 // Remove all auxiliary multidrag items from el, if sorting enabled
6535 if (_this2.options.sort) {
6536 removeMultiDragElements();
6537 }
6538 });
6539 },
6540 dragOver: function dragOver(_ref8) {
6541 var target = _ref8.target,
6542 completed = _ref8.completed,
6543 cancel = _ref8.cancel;
6544 if (folding && ~multiDragElements.indexOf(target)) {
6545 completed(false);
6546 cancel();
6547 }
6548 },
6549 revert: function revert(_ref9) {
6550 var fromSortable = _ref9.fromSortable,
6551 rootEl = _ref9.rootEl,
6552 sortable = _ref9.sortable,
6553 dragRect = _ref9.dragRect;
6554 if (multiDragElements.length > 1) {
6555 // Setup unfold animation
6556 multiDragElements.forEach(function (multiDragElement) {
6557 sortable.addAnimationState({
6558 target: multiDragElement,
6559 rect: folding ? getRect(multiDragElement) : dragRect
6560 });
6561 unsetRect(multiDragElement);
6562 multiDragElement.fromRect = dragRect;
6563 fromSortable.removeAnimationState(multiDragElement);
6564 });
6565 folding = false;
6566 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
6567 }
6568 },
6569 dragOverCompleted: function dragOverCompleted(_ref10) {
6570 var sortable = _ref10.sortable,
6571 isOwner = _ref10.isOwner,
6572 insertion = _ref10.insertion,
6573 activeSortable = _ref10.activeSortable,
6574 parentEl = _ref10.parentEl,
6575 putSortable = _ref10.putSortable;
6576 var options = this.options;
6577 if (insertion) {
6578 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
6579 if (isOwner) {
6580 activeSortable._hideClone();
6581 }
6582 initialFolding = false;
6583 // If leaving sort:false root, or already folding - Fold to new location
6584 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
6585 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
6586 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
6587 multiDragElements.forEach(function (multiDragElement) {
6588 if (multiDragElement === dragEl$1) return;
6589 setRect(multiDragElement, dragRectAbsolute);
6590
6591 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
6592 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
6593 parentEl.appendChild(multiDragElement);
6594 });
6595 folding = true;
6596 }
6597
6598 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
6599 if (!isOwner) {
6600 // Only remove if not folding (folding will remove them anyways)
6601 if (!folding) {
6602 removeMultiDragElements();
6603 }
6604 if (multiDragElements.length > 1) {
6605 var clonesHiddenBefore = clonesHidden;
6606 activeSortable._showClone(sortable);
6607
6608 // Unfold animation for clones if showing from hidden
6609 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
6610 multiDragClones.forEach(function (clone) {
6611 activeSortable.addAnimationState({
6612 target: clone,
6613 rect: clonesFromRect
6614 });
6615 clone.fromRect = clonesFromRect;
6616 clone.thisAnimationDuration = null;
6617 });
6618 }
6619 } else {
6620 activeSortable._showClone(sortable);
6621 }
6622 }
6623 }
6624 },
6625 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
6626 var dragRect = _ref11.dragRect,
6627 isOwner = _ref11.isOwner,
6628 activeSortable = _ref11.activeSortable;
6629 multiDragElements.forEach(function (multiDragElement) {
6630 multiDragElement.thisAnimationDuration = null;
6631 });
6632 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
6633 clonesFromRect = _extends({}, dragRect);
6634 var dragMatrix = matrix(dragEl$1, true);
6635 clonesFromRect.top -= dragMatrix.f;
6636 clonesFromRect.left -= dragMatrix.e;
6637 }
6638 },
6639 dragOverAnimationComplete: function dragOverAnimationComplete() {
6640 if (folding) {
6641 folding = false;
6642 removeMultiDragElements();
6643 }
6644 },
6645 drop: function drop(_ref12) {
6646 var evt = _ref12.originalEvent,
6647 rootEl = _ref12.rootEl,
6648 parentEl = _ref12.parentEl,
6649 sortable = _ref12.sortable,
6650 dispatchSortableEvent = _ref12.dispatchSortableEvent,
6651 oldIndex = _ref12.oldIndex,
6652 putSortable = _ref12.putSortable;
6653 var toSortable = putSortable || this.sortable;
6654 if (!evt) return;
6655 var options = this.options,
6656 children = parentEl.children;
6657
6658 // Multi-drag selection
6659 if (!dragStarted) {
6660 if (options.multiDragKey && !this.multiDragKeyDown) {
6661 this._deselectMultiDrag();
6662 }
6663 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
6664 if (!~multiDragElements.indexOf(dragEl$1)) {
6665 multiDragElements.push(dragEl$1);
6666 dispatchEvent({
6667 sortable: sortable,
6668 rootEl: rootEl,
6669 name: 'select',
6670 targetEl: dragEl$1,
6671 originalEvent: evt
6672 });
6673
6674 // Modifier activated, select from last to dragEl
6675 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
6676 var lastIndex = index(lastMultiDragSelect),
6677 currentIndex = index(dragEl$1);
6678 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
6679 (function () {
6680 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
6681 // (but previous selection existed)
6682 var n, i;
6683 if (currentIndex > lastIndex) {
6684 i = lastIndex;
6685 n = currentIndex;
6686 } else {
6687 i = currentIndex;
6688 n = lastIndex + 1;
6689 }
6690 var filter = options.filter;
6691 for (; i < n; i++) {
6692 if (~multiDragElements.indexOf(children[i])) continue;
6693 // Check if element is draggable
6694 if (!closest(children[i], options.draggable, parentEl, false)) continue;
6695 // Check if element is filtered
6696 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
6697 return closest(children[i], criteria.trim(), parentEl, false);
6698 }));
6699 if (filtered) continue;
6700 toggleClass(children[i], options.selectedClass, true);
6701 multiDragElements.push(children[i]);
6702 dispatchEvent({
6703 sortable: sortable,
6704 rootEl: rootEl,
6705 name: 'select',
6706 targetEl: children[i],
6707 originalEvent: evt
6708 });
6709 }
6710 })();
6711 }
6712 } else {
6713 lastMultiDragSelect = dragEl$1;
6714 }
6715 multiDragSortable = toSortable;
6716 } else {
6717 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
6718 lastMultiDragSelect = null;
6719 dispatchEvent({
6720 sortable: sortable,
6721 rootEl: rootEl,
6722 name: 'deselect',
6723 targetEl: dragEl$1,
6724 originalEvent: evt
6725 });
6726 }
6727 }
6728
6729 // Multi-drag drop
6730 if (dragStarted && this.isMultiDrag) {
6731 folding = false;
6732 // Do not "unfold" after around dragEl if reverted
6733 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
6734 var dragRect = getRect(dragEl$1),
6735 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
6736 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
6737 toSortable.captureAnimationState();
6738 if (!initialFolding) {
6739 if (options.animation) {
6740 dragEl$1.fromRect = dragRect;
6741 multiDragElements.forEach(function (multiDragElement) {
6742 multiDragElement.thisAnimationDuration = null;
6743 if (multiDragElement !== dragEl$1) {
6744 var rect = folding ? getRect(multiDragElement) : dragRect;
6745 multiDragElement.fromRect = rect;
6746
6747 // Prepare unfold animation
6748 toSortable.addAnimationState({
6749 target: multiDragElement,
6750 rect: rect
6751 });
6752 }
6753 });
6754 }
6755
6756 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
6757 // properly they must all be removed
6758 removeMultiDragElements();
6759 multiDragElements.forEach(function (multiDragElement) {
6760 if (children[multiDragIndex]) {
6761 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
6762 } else {
6763 parentEl.appendChild(multiDragElement);
6764 }
6765 multiDragIndex++;
6766 });
6767
6768 // If initial folding is done, the elements may have changed position because they are now
6769 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
6770 // must be fired here as Sortable will not.
6771 if (oldIndex === index(dragEl$1)) {
6772 var update = false;
6773 multiDragElements.forEach(function (multiDragElement) {
6774 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
6775 update = true;
6776 return;
6777 }
6778 });
6779 if (update) {
6780 dispatchSortableEvent('update');
6781 dispatchSortableEvent('sort');
6782 }
6783 }
6784 }
6785
6786 // Must be done after capturing individual rects (scroll bar)
6787 multiDragElements.forEach(function (multiDragElement) {
6788 unsetRect(multiDragElement);
6789 });
6790 toSortable.animateAll();
6791 }
6792 multiDragSortable = toSortable;
6793 }
6794
6795 // Remove clones if necessary
6796 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
6797 multiDragClones.forEach(function (clone) {
6798 clone.parentNode && clone.parentNode.removeChild(clone);
6799 });
6800 }
6801 },
6802 nullingGlobal: function nullingGlobal() {
6803 this.isMultiDrag = dragStarted = false;
6804 multiDragClones.length = 0;
6805 },
6806 destroyGlobal: function destroyGlobal() {
6807 this._deselectMultiDrag();
6808 off(document, 'pointerup', this._deselectMultiDrag);
6809 off(document, 'mouseup', this._deselectMultiDrag);
6810 off(document, 'touchend', this._deselectMultiDrag);
6811 off(document, 'keydown', this._checkKeyDown);
6812 off(document, 'keyup', this._checkKeyUp);
6813 },
6814 _deselectMultiDrag: function _deselectMultiDrag(evt) {
6815 if (typeof dragStarted !== "undefined" && dragStarted) return;
6816
6817 // Only deselect if selection is in this sortable
6818 if (multiDragSortable !== this.sortable) return;
6819
6820 // Only deselect if target is not item in this sortable
6821 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
6822
6823 // Only deselect if left click
6824 if (evt && evt.button !== 0) return;
6825 while (multiDragElements.length) {
6826 var el = multiDragElements[0];
6827 toggleClass(el, this.options.selectedClass, false);
6828 multiDragElements.shift();
6829 dispatchEvent({
6830 sortable: this.sortable,
6831 rootEl: this.sortable.el,
6832 name: 'deselect',
6833 targetEl: el,
6834 originalEvent: evt
6835 });
6836 }
6837 },
6838 _checkKeyDown: function _checkKeyDown(evt) {
6839 if (evt.key === this.options.multiDragKey) {
6840 this.multiDragKeyDown = true;
6841 }
6842 },
6843 _checkKeyUp: function _checkKeyUp(evt) {
6844 if (evt.key === this.options.multiDragKey) {
6845 this.multiDragKeyDown = false;
6846 }
6847 }
6848 };
6849 return _extends(MultiDrag, {
6850 // Static methods & properties
6851 pluginName: 'multiDrag',
6852 utils: {
6853 /**
6854 * Selects the provided multi-drag item
6855 * @param {HTMLElement} el The element to be selected
6856 */
6857 select: function select(el) {
6858 var sortable = el.parentNode[expando];
6859 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
6860 if (multiDragSortable && multiDragSortable !== sortable) {
6861 multiDragSortable.multiDrag._deselectMultiDrag();
6862 multiDragSortable = sortable;
6863 }
6864 toggleClass(el, sortable.options.selectedClass, true);
6865 multiDragElements.push(el);
6866 },
6867 /**
6868 * Deselects the provided multi-drag item
6869 * @param {HTMLElement} el The element to be deselected
6870 */
6871 deselect: function deselect(el) {
6872 var sortable = el.parentNode[expando],
6873 index = multiDragElements.indexOf(el);
6874 if (!sortable || !sortable.options.multiDrag || !~index) return;
6875 toggleClass(el, sortable.options.selectedClass, false);
6876 multiDragElements.splice(index, 1);
6877 }
6878 },
6879 eventProperties: function eventProperties() {
6880 var _this3 = this;
6881 var oldIndicies = [],
6882 newIndicies = [];
6883 multiDragElements.forEach(function (multiDragElement) {
6884 oldIndicies.push({
6885 multiDragElement: multiDragElement,
6886 index: multiDragElement.sortableIndex
6887 });
6888
6889 // multiDragElements will already be sorted if folding
6890 var newIndex;
6891 if (folding && multiDragElement !== dragEl$1) {
6892 newIndex = -1;
6893 } else if (folding) {
6894 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
6895 } else {
6896 newIndex = index(multiDragElement);
6897 }
6898 newIndicies.push({
6899 multiDragElement: multiDragElement,
6900 index: newIndex
6901 });
6902 });
6903 return {
6904 items: _toConsumableArray(multiDragElements),
6905 clones: [].concat(multiDragClones),
6906 oldIndicies: oldIndicies,
6907 newIndicies: newIndicies
6908 };
6909 },
6910 optionListeners: {
6911 multiDragKey: function multiDragKey(key) {
6912 key = key.toLowerCase();
6913 if (key === 'ctrl') {
6914 key = 'Control';
6915 } else if (key.length > 1) {
6916 key = key.charAt(0).toUpperCase() + key.substr(1);
6917 }
6918 return key;
6919 }
6920 }
6921 });
6922 }
6923 function insertMultiDragElements(clonesInserted, rootEl) {
6924 multiDragElements.forEach(function (multiDragElement, i) {
6925 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
6926 if (target) {
6927 rootEl.insertBefore(multiDragElement, target);
6928 } else {
6929 rootEl.appendChild(multiDragElement);
6930 }
6931 });
6932 }
6933
6934 /**
6935 * Insert multi-drag clones
6936 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
6937 * @param {HTMLElement} rootEl
6938 */
6939 function insertMultiDragClones(elementsInserted, rootEl) {
6940 multiDragClones.forEach(function (clone, i) {
6941 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
6942 if (target) {
6943 rootEl.insertBefore(clone, target);
6944 } else {
6945 rootEl.appendChild(clone);
6946 }
6947 });
6948 }
6949 function removeMultiDragElements() {
6950 multiDragElements.forEach(function (multiDragElement) {
6951 if (multiDragElement === dragEl$1) return;
6952 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
6953 });
6954 }
6955
6956 Sortable.mount(new AutoScrollPlugin());
6957 Sortable.mount(Remove, Revert);
6958
6959 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
6960
6961
6962
6963 /***/ },
6964
6965 /***/ "./node_modules/toastify-js/src/toastify.css"
6966 /*!***************************************************!*\
6967 !*** ./node_modules/toastify-js/src/toastify.css ***!
6968 \***************************************************/
6969 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
6970
6971 "use strict";
6972 __webpack_require__.r(__webpack_exports__);
6973 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6974 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
6975 /* harmony export */ });
6976 /* 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");
6977 /* 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__);
6978 /* 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");
6979 /* 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__);
6980 /* 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");
6981 /* 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__);
6982 /* 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");
6983 /* 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__);
6984 /* 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");
6985 /* 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__);
6986 /* 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");
6987 /* 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__);
6988 /* 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");
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000 var options = {};
7001
7002 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
7003 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
7004
7005 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
7006
7007 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
7008 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
7009
7010 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);
7011
7012
7013
7014
7015 /* 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);
7016
7017
7018 /***/ },
7019
7020 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
7021 /*!****************************************************************************!*\
7022 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
7023 \****************************************************************************/
7024 (module) {
7025
7026 "use strict";
7027
7028
7029 var stylesInDOM = [];
7030 function getIndexByIdentifier(identifier) {
7031 var result = -1;
7032 for (var i = 0; i < stylesInDOM.length; i++) {
7033 if (stylesInDOM[i].identifier === identifier) {
7034 result = i;
7035 break;
7036 }
7037 }
7038 return result;
7039 }
7040 function modulesToDom(list, options) {
7041 var idCountMap = {};
7042 var identifiers = [];
7043 for (var i = 0; i < list.length; i++) {
7044 var item = list[i];
7045 var id = options.base ? item[0] + options.base : item[0];
7046 var count = idCountMap[id] || 0;
7047 var identifier = "".concat(id, " ").concat(count);
7048 idCountMap[id] = count + 1;
7049 var indexByIdentifier = getIndexByIdentifier(identifier);
7050 var obj = {
7051 css: item[1],
7052 media: item[2],
7053 sourceMap: item[3],
7054 supports: item[4],
7055 layer: item[5]
7056 };
7057 if (indexByIdentifier !== -1) {
7058 stylesInDOM[indexByIdentifier].references++;
7059 stylesInDOM[indexByIdentifier].updater(obj);
7060 } else {
7061 var updater = addElementStyle(obj, options);
7062 options.byIndex = i;
7063 stylesInDOM.splice(i, 0, {
7064 identifier: identifier,
7065 updater: updater,
7066 references: 1
7067 });
7068 }
7069 identifiers.push(identifier);
7070 }
7071 return identifiers;
7072 }
7073 function addElementStyle(obj, options) {
7074 var api = options.domAPI(options);
7075 api.update(obj);
7076 var updater = function updater(newObj) {
7077 if (newObj) {
7078 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
7079 return;
7080 }
7081 api.update(obj = newObj);
7082 } else {
7083 api.remove();
7084 }
7085 };
7086 return updater;
7087 }
7088 module.exports = function (list, options) {
7089 options = options || {};
7090 list = list || [];
7091 var lastIdentifiers = modulesToDom(list, options);
7092 return function update(newList) {
7093 newList = newList || [];
7094 for (var i = 0; i < lastIdentifiers.length; i++) {
7095 var identifier = lastIdentifiers[i];
7096 var index = getIndexByIdentifier(identifier);
7097 stylesInDOM[index].references--;
7098 }
7099 var newLastIdentifiers = modulesToDom(newList, options);
7100 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
7101 var _identifier = lastIdentifiers[_i];
7102 var _index = getIndexByIdentifier(_identifier);
7103 if (stylesInDOM[_index].references === 0) {
7104 stylesInDOM[_index].updater();
7105 stylesInDOM.splice(_index, 1);
7106 }
7107 }
7108 lastIdentifiers = newLastIdentifiers;
7109 };
7110 };
7111
7112 /***/ },
7113
7114 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
7115 /*!********************************************************************!*\
7116 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
7117 \********************************************************************/
7118 (module) {
7119
7120 "use strict";
7121
7122
7123 var memo = {};
7124
7125 /* istanbul ignore next */
7126 function getTarget(target) {
7127 if (typeof memo[target] === "undefined") {
7128 var styleTarget = document.querySelector(target);
7129
7130 // Special case to return head of iframe instead of iframe itself
7131 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
7132 try {
7133 // This will throw an exception if access to iframe is blocked
7134 // due to cross-origin restrictions
7135 styleTarget = styleTarget.contentDocument.head;
7136 } catch (e) {
7137 // istanbul ignore next
7138 styleTarget = null;
7139 }
7140 }
7141 memo[target] = styleTarget;
7142 }
7143 return memo[target];
7144 }
7145
7146 /* istanbul ignore next */
7147 function insertBySelector(insert, style) {
7148 var target = getTarget(insert);
7149 if (!target) {
7150 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
7151 }
7152 target.appendChild(style);
7153 }
7154 module.exports = insertBySelector;
7155
7156 /***/ },
7157
7158 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
7159 /*!**********************************************************************!*\
7160 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
7161 \**********************************************************************/
7162 (module) {
7163
7164 "use strict";
7165
7166
7167 /* istanbul ignore next */
7168 function insertStyleElement(options) {
7169 var element = document.createElement("style");
7170 options.setAttributes(element, options.attributes);
7171 options.insert(element, options.options);
7172 return element;
7173 }
7174 module.exports = insertStyleElement;
7175
7176 /***/ },
7177
7178 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
7179 /*!**********************************************************************************!*\
7180 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
7181 \**********************************************************************************/
7182 (module, __unused_webpack_exports, __webpack_require__) {
7183
7184 "use strict";
7185
7186
7187 /* istanbul ignore next */
7188 function setAttributesWithoutAttributes(styleElement) {
7189 var nonce = true ? __webpack_require__.nc : 0;
7190 if (nonce) {
7191 styleElement.setAttribute("nonce", nonce);
7192 }
7193 }
7194 module.exports = setAttributesWithoutAttributes;
7195
7196 /***/ },
7197
7198 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
7199 /*!***************************************************************!*\
7200 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
7201 \***************************************************************/
7202 (module) {
7203
7204 "use strict";
7205
7206
7207 /* istanbul ignore next */
7208 function apply(styleElement, options, obj) {
7209 var css = "";
7210 if (obj.supports) {
7211 css += "@supports (".concat(obj.supports, ") {");
7212 }
7213 if (obj.media) {
7214 css += "@media ".concat(obj.media, " {");
7215 }
7216 var needLayer = typeof obj.layer !== "undefined";
7217 if (needLayer) {
7218 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
7219 }
7220 css += obj.css;
7221 if (needLayer) {
7222 css += "}";
7223 }
7224 if (obj.media) {
7225 css += "}";
7226 }
7227 if (obj.supports) {
7228 css += "}";
7229 }
7230 var sourceMap = obj.sourceMap;
7231 if (sourceMap && typeof btoa !== "undefined") {
7232 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
7233 }
7234
7235 // For old IE
7236 /* istanbul ignore if */
7237 options.styleTagTransform(css, styleElement, options.options);
7238 }
7239 function removeStyleElement(styleElement) {
7240 // istanbul ignore if
7241 if (styleElement.parentNode === null) {
7242 return false;
7243 }
7244 styleElement.parentNode.removeChild(styleElement);
7245 }
7246
7247 /* istanbul ignore next */
7248 function domAPI(options) {
7249 if (typeof document === "undefined") {
7250 return {
7251 update: function update() {},
7252 remove: function remove() {}
7253 };
7254 }
7255 var styleElement = options.insertStyleElement(options);
7256 return {
7257 update: function update(obj) {
7258 apply(styleElement, options, obj);
7259 },
7260 remove: function remove() {
7261 removeStyleElement(styleElement);
7262 }
7263 };
7264 }
7265 module.exports = domAPI;
7266
7267 /***/ },
7268
7269 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
7270 /*!*********************************************************************!*\
7271 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
7272 \*********************************************************************/
7273 (module) {
7274
7275 "use strict";
7276
7277
7278 /* istanbul ignore next */
7279 function styleTagTransform(css, styleElement) {
7280 if (styleElement.styleSheet) {
7281 styleElement.styleSheet.cssText = css;
7282 } else {
7283 while (styleElement.firstChild) {
7284 styleElement.removeChild(styleElement.firstChild);
7285 }
7286 styleElement.appendChild(document.createTextNode(css));
7287 }
7288 }
7289 module.exports = styleTagTransform;
7290
7291 /***/ },
7292
7293 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
7294 /*!**********************************************************!*\
7295 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
7296 \**********************************************************/
7297 (module) {
7298
7299 /*!
7300 * sweetalert2 v11.26.25
7301 * Released under the MIT License.
7302 */
7303 (function (global, factory) {
7304 true ? module.exports = factory() :
7305 0;
7306 })(this, (function () { 'use strict';
7307
7308 function _assertClassBrand(e, t, n) {
7309 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
7310 throw new TypeError("Private element is not present on this object");
7311 }
7312 function _checkPrivateRedeclaration(e, t) {
7313 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
7314 }
7315 function _classPrivateFieldGet2(s, a) {
7316 return s.get(_assertClassBrand(s, a));
7317 }
7318 function _classPrivateFieldInitSpec(e, t, a) {
7319 _checkPrivateRedeclaration(e, t), t.set(e, a);
7320 }
7321 function _classPrivateFieldSet2(s, a, r) {
7322 return s.set(_assertClassBrand(s, a), r), r;
7323 }
7324
7325 const RESTORE_FOCUS_TIMEOUT = 100;
7326
7327 /** @type {GlobalState} */
7328 const globalState = {};
7329 const focusPreviousActiveElement = () => {
7330 if (globalState.previousActiveElement instanceof HTMLElement) {
7331 globalState.previousActiveElement.focus();
7332 globalState.previousActiveElement = null;
7333 } else if (document.body) {
7334 document.body.focus();
7335 }
7336 };
7337
7338 /**
7339 * Restore previous active (focused) element
7340 *
7341 * @param {boolean} returnFocus
7342 * @returns {Promise<void>}
7343 */
7344 const restoreActiveElement = returnFocus => {
7345 return new Promise(resolve => {
7346 if (!returnFocus) {
7347 return resolve();
7348 }
7349 const x = window.scrollX;
7350 const y = window.scrollY;
7351 globalState.restoreFocusTimeout = setTimeout(() => {
7352 focusPreviousActiveElement();
7353 resolve();
7354 }, RESTORE_FOCUS_TIMEOUT); // issues/900
7355
7356 window.scrollTo(x, y);
7357 });
7358 };
7359
7360 const swalPrefix = 'swal2-';
7361
7362 /**
7363 * @typedef {Record<SwalClass, string>} SwalClasses
7364 */
7365
7366 /**
7367 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
7368 * @typedef {Record<SwalIcon, string>} SwalIcons
7369 */
7370
7371 /** @type {SwalClass[]} */
7372 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'];
7373 const swalClasses = classNames.reduce((acc, className) => {
7374 acc[className] = swalPrefix + className;
7375 return acc;
7376 }, /** @type {SwalClasses} */{});
7377
7378 /** @type {SwalIcon[]} */
7379 const icons = ['success', 'warning', 'info', 'question', 'error'];
7380 const iconTypes = icons.reduce((acc, icon) => {
7381 acc[icon] = swalPrefix + icon;
7382 return acc;
7383 }, /** @type {SwalIcons} */{});
7384
7385 const consolePrefix = 'SweetAlert2:';
7386
7387 /**
7388 * Capitalize the first letter of a string
7389 *
7390 * @param {string} str
7391 * @returns {string}
7392 */
7393 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
7394
7395 /**
7396 * Standardize console warnings
7397 *
7398 * @param {string | string[]} message
7399 */
7400 const warn = message => {
7401 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
7402 };
7403
7404 /**
7405 * Standardize console errors
7406 *
7407 * @param {string} message
7408 */
7409 const error = message => {
7410 console.error(`${consolePrefix} ${message}`);
7411 };
7412
7413 /**
7414 * Private global state for `warnOnce`
7415 *
7416 * @type {string[]}
7417 * @private
7418 */
7419 const previousWarnOnceMessages = [];
7420
7421 /**
7422 * Show a console warning, but only if it hasn't already been shown
7423 *
7424 * @param {string} message
7425 */
7426 const warnOnce = message => {
7427 if (!previousWarnOnceMessages.includes(message)) {
7428 previousWarnOnceMessages.push(message);
7429 warn(message);
7430 }
7431 };
7432
7433 /**
7434 * Show a one-time console warning about deprecated params/methods
7435 *
7436 * @param {string} deprecatedParam
7437 * @param {string?} useInstead
7438 */
7439 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
7440 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
7441 };
7442
7443 /**
7444 * If `arg` is a function, call it (with no arguments or context) and return the result.
7445 * Otherwise, just pass the value through
7446 *
7447 * @param {(() => *) | *} arg
7448 * @returns {*}
7449 */
7450 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
7451
7452 /**
7453 * @param {*} arg
7454 * @returns {boolean}
7455 */
7456 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
7457
7458 /**
7459 * @param {*} arg
7460 * @returns {Promise<*>}
7461 */
7462 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
7463
7464 /**
7465 * @param {*} arg
7466 * @returns {boolean}
7467 */
7468 const isPromise = arg => arg && Promise.resolve(arg) === arg;
7469
7470 /**
7471 * @returns {boolean}
7472 */
7473 const isFirefox = () => navigator.userAgent.includes('Firefox');
7474
7475 /**
7476 * Gets the popup container which contains the backdrop and the popup itself.
7477 *
7478 * @returns {HTMLElement | null}
7479 */
7480 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
7481
7482 /**
7483 * @param {string} selectorString
7484 * @returns {HTMLElement | null}
7485 */
7486 const elementBySelector = selectorString => {
7487 const container = getContainer();
7488 return container ? container.querySelector(selectorString) : null;
7489 };
7490
7491 /**
7492 * @param {string} className
7493 * @returns {HTMLElement | null}
7494 */
7495 const elementByClass = className => {
7496 return elementBySelector(`.${className}`);
7497 };
7498
7499 /**
7500 * @returns {HTMLElement | null}
7501 */
7502 const getPopup = () => elementByClass(swalClasses.popup);
7503
7504 /**
7505 * @returns {HTMLElement | null}
7506 */
7507 const getIcon = () => elementByClass(swalClasses.icon);
7508
7509 /**
7510 * @returns {HTMLElement | null}
7511 */
7512 const getIconContent = () => elementByClass(swalClasses['icon-content']);
7513
7514 /**
7515 * @returns {HTMLElement | null}
7516 */
7517 const getTitle = () => elementByClass(swalClasses.title);
7518
7519 /**
7520 * @returns {HTMLElement | null}
7521 */
7522 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
7523
7524 /**
7525 * @returns {HTMLElement | null}
7526 */
7527 const getImage = () => elementByClass(swalClasses.image);
7528
7529 /**
7530 * @returns {HTMLElement | null}
7531 */
7532 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
7533
7534 /**
7535 * @returns {HTMLElement | null}
7536 */
7537 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
7538
7539 /**
7540 * @returns {HTMLButtonElement | null}
7541 */
7542 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
7543
7544 /**
7545 * @returns {HTMLButtonElement | null}
7546 */
7547 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
7548
7549 /**
7550 * @returns {HTMLButtonElement | null}
7551 */
7552 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
7553
7554 /**
7555 * @returns {HTMLElement | null}
7556 */
7557 const getInputLabel = () => elementByClass(swalClasses['input-label']);
7558
7559 /**
7560 * @returns {HTMLElement | null}
7561 */
7562 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
7563
7564 /**
7565 * @returns {HTMLElement | null}
7566 */
7567 const getActions = () => elementByClass(swalClasses.actions);
7568
7569 /**
7570 * @returns {HTMLElement | null}
7571 */
7572 const getFooter = () => elementByClass(swalClasses.footer);
7573
7574 /**
7575 * @returns {HTMLElement | null}
7576 */
7577 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
7578
7579 /**
7580 * @returns {HTMLElement | null}
7581 */
7582 const getCloseButton = () => elementByClass(swalClasses.close);
7583
7584 // https://github.com/jkup/focusable/blob/master/index.js
7585 const focusable = `
7586 a[href],
7587 area[href],
7588 input:not([disabled]),
7589 select:not([disabled]),
7590 textarea:not([disabled]),
7591 button:not([disabled]),
7592 iframe,
7593 object,
7594 embed,
7595 [tabindex="0"],
7596 [contenteditable],
7597 audio[controls],
7598 video[controls],
7599 summary
7600 `;
7601 /**
7602 * @returns {HTMLElement[]}
7603 */
7604 const getFocusableElements = () => {
7605 const popup = getPopup();
7606 if (!popup) {
7607 return [];
7608 }
7609 /** @type {NodeListOf<HTMLElement>} */
7610 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
7611 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
7612 // sort according to tabindex
7613 .sort((a, b) => {
7614 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
7615 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
7616 if (tabindexA > tabindexB) {
7617 return 1;
7618 } else if (tabindexA < tabindexB) {
7619 return -1;
7620 }
7621 return 0;
7622 });
7623
7624 /** @type {NodeListOf<HTMLElement>} */
7625 const otherFocusableElements = popup.querySelectorAll(focusable);
7626 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
7627 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
7628 };
7629
7630 /**
7631 * @returns {boolean}
7632 */
7633 const isModal = () => {
7634 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
7635 };
7636
7637 /**
7638 * @returns {boolean}
7639 */
7640 const isToast = () => {
7641 const popup = getPopup();
7642 if (!popup) {
7643 return false;
7644 }
7645 return hasClass(popup, swalClasses.toast);
7646 };
7647
7648 /**
7649 * @returns {boolean}
7650 */
7651 const isLoading = () => {
7652 const popup = getPopup();
7653 if (!popup) {
7654 return false;
7655 }
7656 return popup.hasAttribute('data-loading');
7657 };
7658
7659 /**
7660 * Securely set innerHTML of an element
7661 * https://github.com/sweetalert2/sweetalert2/issues/1926
7662 *
7663 * @param {HTMLElement} elem
7664 * @param {string} html
7665 */
7666 const setInnerHtml = (elem, html) => {
7667 elem.textContent = '';
7668 if (html) {
7669 const parser = new DOMParser();
7670 const parsed = parser.parseFromString(html, `text/html`);
7671 const head = parsed.querySelector('head');
7672 if (head) {
7673 Array.from(head.childNodes).forEach(child => {
7674 elem.appendChild(child);
7675 });
7676 }
7677 const body = parsed.querySelector('body');
7678 if (body) {
7679 Array.from(body.childNodes).forEach(child => {
7680 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
7681 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
7682 } else {
7683 elem.appendChild(child);
7684 }
7685 });
7686 }
7687 }
7688 };
7689
7690 /**
7691 * @param {HTMLElement} elem
7692 * @param {string} className
7693 * @returns {boolean}
7694 */
7695 const hasClass = (elem, className) => {
7696 if (!className) {
7697 return false;
7698 }
7699 return className.split(/\s+/).every(cls => elem.classList.contains(cls));
7700 };
7701
7702 /**
7703 * @param {HTMLElement} elem
7704 * @param {SweetAlertOptions} params
7705 */
7706 const removeCustomClasses = (elem, params) => {
7707 Array.from(elem.classList).forEach(className => {
7708 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
7709 elem.classList.remove(className);
7710 }
7711 });
7712 };
7713
7714 /**
7715 * @param {HTMLElement} elem
7716 * @param {SweetAlertOptions} params
7717 * @param {string} className
7718 */
7719 const applyCustomClass = (elem, params, className) => {
7720 removeCustomClasses(elem, params);
7721 if (!params.customClass) {
7722 return;
7723 }
7724 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
7725 if (!customClass) {
7726 return;
7727 }
7728 if (typeof customClass !== 'string' && !customClass.forEach) {
7729 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
7730 return;
7731 }
7732 addClass(elem, customClass);
7733 };
7734
7735 /**
7736 * @param {HTMLElement} popup
7737 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
7738 * @returns {HTMLInputElement | null}
7739 */
7740 const getInput$1 = (popup, inputClass) => {
7741 if (!inputClass) {
7742 return null;
7743 }
7744 switch (inputClass) {
7745 case 'select':
7746 case 'textarea':
7747 case 'file':
7748 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
7749 case 'checkbox':
7750 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
7751 case 'radio':
7752 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
7753 case 'range':
7754 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
7755 default:
7756 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
7757 }
7758 };
7759
7760 /**
7761 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
7762 */
7763 const focusInput = input => {
7764 input.focus();
7765
7766 // place cursor at end of text in text input
7767 if (input.type !== 'file') {
7768 // http://stackoverflow.com/a/2345915
7769 const val = input.value;
7770 input.value = '';
7771 input.value = val;
7772 }
7773 };
7774
7775 /**
7776 * @param {HTMLElement | HTMLElement[] | null} target
7777 * @param {string | string[] | readonly string[] | undefined} classList
7778 * @param {boolean} condition
7779 */
7780 const toggleClass = (target, classList, condition) => {
7781 if (!target || !classList) {
7782 return;
7783 }
7784 const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
7785 const targets = Array.isArray(target) ? target : [target];
7786 targets.forEach(elem => {
7787 classes.forEach(className => {
7788 if (condition) {
7789 elem.classList.add(className);
7790 } else {
7791 elem.classList.remove(className);
7792 }
7793 });
7794 });
7795 };
7796
7797 /**
7798 * @param {HTMLElement | HTMLElement[] | null} target
7799 * @param {string | string[] | readonly string[] | undefined} classList
7800 */
7801 const addClass = (target, classList) => {
7802 toggleClass(target, classList, true);
7803 };
7804
7805 /**
7806 * @param {HTMLElement | HTMLElement[] | null} target
7807 * @param {string | string[] | readonly string[] | undefined} classList
7808 */
7809 const removeClass = (target, classList) => {
7810 toggleClass(target, classList, false);
7811 };
7812
7813 /**
7814 * Get direct child of an element by class name
7815 *
7816 * @param {HTMLElement} elem
7817 * @param {string} className
7818 * @returns {HTMLElement | undefined}
7819 */
7820 const getDirectChildByClass = (elem, className) => (/** @type {HTMLElement | undefined} */
7821 Array.from(elem.children).find(child => child instanceof HTMLElement && hasClass(child, className)));
7822
7823 /**
7824 * @param {HTMLElement} elem
7825 * @param {string} property
7826 * @param {string | number | null | undefined} value
7827 */
7828 const applyNumericalStyle = (elem, property, value) => {
7829 if (value === `${parseInt(`${value}`)}`) {
7830 value = parseInt(value);
7831 }
7832 if (value || value === 0) {
7833 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
7834 } else {
7835 elem.style.removeProperty(property);
7836 }
7837 };
7838
7839 /**
7840 * @param {HTMLElement | null} elem
7841 * @param {string} display
7842 */
7843 const show = (elem, display = 'flex') => {
7844 if (!elem) {
7845 return;
7846 }
7847 elem.style.display = display;
7848 };
7849
7850 /**
7851 * @param {HTMLElement | null} elem
7852 */
7853 const hide = elem => {
7854 if (!elem) {
7855 return;
7856 }
7857 elem.style.display = 'none';
7858 };
7859
7860 /**
7861 * @param {HTMLElement | null} elem
7862 * @param {string} display
7863 */
7864 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
7865 if (!elem) {
7866 return;
7867 }
7868 new MutationObserver(() => {
7869 toggle(elem, elem.innerHTML, display);
7870 }).observe(elem, {
7871 childList: true,
7872 subtree: true
7873 });
7874 };
7875
7876 /**
7877 * @param {HTMLElement} parent
7878 * @param {string} selector
7879 * @param {string} property
7880 * @param {string} value
7881 */
7882 const setStyle = (parent, selector, property, value) => {
7883 /** @type {HTMLElement | null} */
7884 const el = parent.querySelector(selector);
7885 if (el) {
7886 el.style.setProperty(property, value);
7887 }
7888 };
7889
7890 /**
7891 * @param {HTMLElement} elem
7892 * @param {boolean | string | null | undefined} condition
7893 * @param {string} display
7894 */
7895 const toggle = (elem, condition, display = 'flex') => {
7896 if (condition) {
7897 show(elem, display);
7898 } else {
7899 hide(elem);
7900 }
7901 };
7902
7903 /**
7904 * borrowed from jquery $(elem).is(':visible') implementation
7905 *
7906 * @param {HTMLElement | null} elem
7907 * @returns {boolean}
7908 */
7909 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
7910
7911 /**
7912 * @returns {boolean}
7913 */
7914 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
7915
7916 /**
7917 * @param {HTMLElement} elem
7918 * @returns {boolean}
7919 */
7920 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
7921
7922 /**
7923 * @param {HTMLElement} element
7924 * @param {HTMLElement} stopElement
7925 * @returns {boolean}
7926 */
7927 const selfOrParentIsScrollable = (element, stopElement) => {
7928 let parent = /** @type {HTMLElement | null} */element;
7929 while (parent && parent !== stopElement) {
7930 if (isScrollable(parent)) {
7931 return true;
7932 }
7933 parent = parent.parentElement;
7934 }
7935 return false;
7936 };
7937
7938 /**
7939 * borrowed from https://stackoverflow.com/a/46352119
7940 *
7941 * @param {HTMLElement} elem
7942 * @returns {boolean}
7943 */
7944 const hasCssAnimation = elem => {
7945 const style = window.getComputedStyle(elem);
7946 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
7947 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
7948 return animDuration > 0 || transDuration > 0;
7949 };
7950
7951 /**
7952 * @param {number} timer
7953 * @param {boolean} reset
7954 */
7955 const animateTimerProgressBar = (timer, reset = false) => {
7956 const timerProgressBar = getTimerProgressBar();
7957 if (!timerProgressBar) {
7958 return;
7959 }
7960 if (isVisible$1(timerProgressBar)) {
7961 if (reset) {
7962 timerProgressBar.style.transition = 'none';
7963 timerProgressBar.style.width = '100%';
7964 }
7965 setTimeout(() => {
7966 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
7967 timerProgressBar.style.width = '0%';
7968 }, 10);
7969 }
7970 };
7971 const stopTimerProgressBar = () => {
7972 const timerProgressBar = getTimerProgressBar();
7973 if (!timerProgressBar) {
7974 return;
7975 }
7976 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
7977 timerProgressBar.style.removeProperty('transition');
7978 timerProgressBar.style.width = '100%';
7979 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
7980 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
7981 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
7982 };
7983
7984 /**
7985 * Detect Node env
7986 *
7987 * @returns {boolean}
7988 */
7989 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
7990
7991 const sweetHTML = `
7992 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
7993 <button type="button" class="${swalClasses.close}"></button>
7994 <ul class="${swalClasses['progress-steps']}"></ul>
7995 <div class="${swalClasses.icon}"></div>
7996 <img class="${swalClasses.image}" />
7997 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
7998 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
7999 <input class="${swalClasses.input}" id="${swalClasses.input}" />
8000 <input type="file" class="${swalClasses.file}" />
8001 <div class="${swalClasses.range}">
8002 <input type="range" />
8003 <output></output>
8004 </div>
8005 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
8006 <div class="${swalClasses.radio}"></div>
8007 <label class="${swalClasses.checkbox}">
8008 <input type="checkbox" id="${swalClasses.checkbox}" />
8009 <span class="${swalClasses.label}"></span>
8010 </label>
8011 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
8012 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
8013 <div class="${swalClasses.actions}">
8014 <div class="${swalClasses.loader}"></div>
8015 <button type="button" class="${swalClasses.confirm}"></button>
8016 <button type="button" class="${swalClasses.deny}"></button>
8017 <button type="button" class="${swalClasses.cancel}"></button>
8018 </div>
8019 <div class="${swalClasses.footer}"></div>
8020 <div class="${swalClasses['timer-progress-bar-container']}">
8021 <div class="${swalClasses['timer-progress-bar']}"></div>
8022 </div>
8023 </div>
8024 `.replace(/(^|\n)\s*/g, '');
8025
8026 /**
8027 * @returns {boolean}
8028 */
8029 const resetOldContainer = () => {
8030 const oldContainer = getContainer();
8031 if (!oldContainer) {
8032 return false;
8033 }
8034 oldContainer.remove();
8035 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
8036 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
8037 swalClasses['has-column']]);
8038 return true;
8039 };
8040 const resetValidationMessage$1 = () => {
8041 if (globalState.currentInstance) {
8042 globalState.currentInstance.resetValidationMessage();
8043 }
8044 };
8045 const addInputChangeListeners = () => {
8046 const popup = getPopup();
8047 if (!popup) {
8048 return;
8049 }
8050 const input = getDirectChildByClass(popup, swalClasses.input);
8051 const file = getDirectChildByClass(popup, swalClasses.file);
8052 /** @type {HTMLInputElement | null} */
8053 const range = popup.querySelector(`.${swalClasses.range} input`);
8054 /** @type {HTMLOutputElement | null} */
8055 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
8056 const select = getDirectChildByClass(popup, swalClasses.select);
8057 /** @type {HTMLInputElement | null} */
8058 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
8059 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
8060 if (input) {
8061 input.oninput = resetValidationMessage$1;
8062 }
8063 if (file) {
8064 file.onchange = resetValidationMessage$1;
8065 }
8066 if (select) {
8067 select.onchange = resetValidationMessage$1;
8068 }
8069 if (checkbox) {
8070 checkbox.onchange = resetValidationMessage$1;
8071 }
8072 if (textarea) {
8073 textarea.oninput = resetValidationMessage$1;
8074 }
8075 if (range && rangeOutput) {
8076 range.oninput = () => {
8077 resetValidationMessage$1();
8078 rangeOutput.value = range.value;
8079 };
8080 range.onchange = () => {
8081 resetValidationMessage$1();
8082 rangeOutput.value = range.value;
8083 };
8084 }
8085 };
8086
8087 /**
8088 * @param {string | HTMLElement} target
8089 * @returns {HTMLElement}
8090 */
8091 const getTarget = target => {
8092 if (typeof target === 'string') {
8093 const element = document.querySelector(target);
8094 if (!element) {
8095 throw new Error(`Target element "${target}" not found`);
8096 }
8097 return /** @type {HTMLElement} */element;
8098 }
8099 return target;
8100 };
8101
8102 /**
8103 * @param {SweetAlertOptions} params
8104 */
8105 const setupAccessibility = params => {
8106 const popup = getPopup();
8107 if (!popup) {
8108 return;
8109 }
8110 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
8111 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
8112 if (!params.toast) {
8113 popup.setAttribute('aria-modal', 'true');
8114 }
8115 };
8116
8117 /**
8118 * @param {HTMLElement} targetElement
8119 */
8120 const setupRTL = targetElement => {
8121 if (window.getComputedStyle(targetElement).direction === 'rtl') {
8122 addClass(getContainer(), swalClasses.rtl);
8123 globalState.isRTL = true;
8124 }
8125 };
8126
8127 /**
8128 * Add modal + backdrop to DOM
8129 *
8130 * @param {SweetAlertOptions} params
8131 */
8132 const init = params => {
8133 // Clean up the old popup container if it exists
8134 const oldContainerExisted = resetOldContainer();
8135 if (isNodeEnv()) {
8136 error('SweetAlert2 requires document to initialize');
8137 return;
8138 }
8139 const container = document.createElement('div');
8140 container.className = swalClasses.container;
8141 if (oldContainerExisted) {
8142 addClass(container, swalClasses['no-transition']);
8143 }
8144 setInnerHtml(container, sweetHTML);
8145 container.dataset['swal2Theme'] = params.theme;
8146 const targetElement = getTarget(params.target || 'body');
8147 targetElement.appendChild(container);
8148 if (params.topLayer) {
8149 container.setAttribute('popover', '');
8150 container.showPopover();
8151 }
8152 setupAccessibility(params);
8153 setupRTL(targetElement);
8154 addInputChangeListeners();
8155 };
8156
8157 /**
8158 * @param {HTMLElement | object | string} param
8159 * @param {HTMLElement} target
8160 */
8161 const parseHtmlToContainer = (param, target) => {
8162 // DOM element
8163 if (param instanceof HTMLElement) {
8164 target.appendChild(param);
8165 }
8166
8167 // Object
8168 else if (typeof param === 'object') {
8169 handleObject(param, target);
8170 }
8171
8172 // Plain string
8173 else if (param) {
8174 setInnerHtml(target, param);
8175 }
8176 };
8177
8178 /**
8179 * @param {object} param
8180 * @param {HTMLElement} target
8181 */
8182 const handleObject = (param, target) => {
8183 // JQuery element(s)
8184 if ('jquery' in param) {
8185 handleJqueryElem(target, param);
8186 }
8187
8188 // For other objects use their string representation
8189 else {
8190 setInnerHtml(target, param.toString());
8191 }
8192 };
8193
8194 /**
8195 * @param {HTMLElement} target
8196 * @param {any} elem
8197 */
8198 const handleJqueryElem = (target, elem) => {
8199 target.textContent = '';
8200 if (0 in elem) {
8201 for (let i = 0; i in elem; i++) {
8202 target.appendChild(elem[i].cloneNode(true));
8203 }
8204 } else {
8205 target.appendChild(elem.cloneNode(true));
8206 }
8207 };
8208
8209 /**
8210 * @param {SweetAlert} instance
8211 * @param {SweetAlertOptions} params
8212 */
8213 const renderActions = (instance, params) => {
8214 const actions = getActions();
8215 const loader = getLoader();
8216 if (!actions || !loader) {
8217 return;
8218 }
8219
8220 // Actions (buttons) wrapper
8221 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
8222 hide(actions);
8223 } else {
8224 show(actions);
8225 }
8226
8227 // Custom class
8228 applyCustomClass(actions, params, 'actions');
8229
8230 // Render all the buttons
8231 renderButtons(actions, loader, params);
8232
8233 // Loader
8234 setInnerHtml(loader, params.loaderHtml || '');
8235 applyCustomClass(loader, params, 'loader');
8236 };
8237
8238 /**
8239 * @param {HTMLElement} actions
8240 * @param {HTMLElement} loader
8241 * @param {SweetAlertOptions} params
8242 */
8243 function renderButtons(actions, loader, params) {
8244 const confirmButton = getConfirmButton();
8245 const denyButton = getDenyButton();
8246 const cancelButton = getCancelButton();
8247 if (!confirmButton || !denyButton || !cancelButton) {
8248 return;
8249 }
8250
8251 // Render buttons
8252 renderButton(confirmButton, 'confirm', params);
8253 renderButton(denyButton, 'deny', params);
8254 renderButton(cancelButton, 'cancel', params);
8255 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
8256 if (params.reverseButtons) {
8257 if (params.toast) {
8258 actions.insertBefore(cancelButton, confirmButton);
8259 actions.insertBefore(denyButton, confirmButton);
8260 } else {
8261 actions.insertBefore(cancelButton, loader);
8262 actions.insertBefore(denyButton, loader);
8263 actions.insertBefore(confirmButton, loader);
8264 }
8265 }
8266 }
8267
8268 /**
8269 * @param {HTMLElement} confirmButton
8270 * @param {HTMLElement} denyButton
8271 * @param {HTMLElement} cancelButton
8272 * @param {SweetAlertOptions} params
8273 */
8274 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
8275 if (!params.buttonsStyling) {
8276 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
8277 return;
8278 }
8279 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
8280
8281 // Apply custom background colors and outline colors to action buttons
8282 /** @type {[HTMLElement, string, string | undefined][]} */
8283 const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
8284 buttons.forEach(([button, type, color]) => {
8285 if (color) {
8286 button.style.setProperty(`--swal2-${type}-button-background-color`, color);
8287 }
8288 applyOutlineColor(button);
8289 });
8290 }
8291
8292 /**
8293 * @param {HTMLElement} button
8294 */
8295 function applyOutlineColor(button) {
8296 const buttonStyle = window.getComputedStyle(button);
8297 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
8298 // If the button already has a custom outline color, no need to change it
8299 return;
8300 }
8301 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
8302 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
8303 }
8304
8305 /**
8306 * @param {HTMLElement} button
8307 * @param {'confirm' | 'deny' | 'cancel'} buttonType
8308 * @param {SweetAlertOptions} params
8309 */
8310 function renderButton(button, buttonType, params) {
8311 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
8312 toggle(button, params[`show${buttonName}Button`], 'inline-block');
8313 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
8314 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
8315
8316 // Add buttons custom classes
8317 button.className = swalClasses[buttonType];
8318 applyCustomClass(button, params, `${buttonType}Button`);
8319 }
8320
8321 /**
8322 * @param {SweetAlert} instance
8323 * @param {SweetAlertOptions} params
8324 */
8325 const renderCloseButton = (instance, params) => {
8326 const closeButton = getCloseButton();
8327 if (!closeButton) {
8328 return;
8329 }
8330 setInnerHtml(closeButton, params.closeButtonHtml || '');
8331
8332 // Custom class
8333 applyCustomClass(closeButton, params, 'closeButton');
8334 toggle(closeButton, params.showCloseButton);
8335 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
8336 };
8337
8338 /**
8339 * @param {SweetAlert} instance
8340 * @param {SweetAlertOptions} params
8341 */
8342 const renderContainer = (instance, params) => {
8343 const container = getContainer();
8344 if (!container) {
8345 return;
8346 }
8347 handleBackdropParam(container, params.backdrop);
8348 handlePositionParam(container, params.position);
8349 handleGrowParam(container, params.grow);
8350
8351 // Custom class
8352 applyCustomClass(container, params, 'container');
8353 };
8354
8355 /**
8356 * @param {HTMLElement} container
8357 * @param {SweetAlertOptions['backdrop']} backdrop
8358 */
8359 function handleBackdropParam(container, backdrop) {
8360 if (typeof backdrop === 'string') {
8361 container.style.background = backdrop;
8362 } else if (!backdrop) {
8363 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
8364 }
8365 }
8366
8367 /**
8368 * @param {HTMLElement} container
8369 * @param {SweetAlertOptions['position']} position
8370 */
8371 function handlePositionParam(container, position) {
8372 if (!position) {
8373 return;
8374 }
8375 if (position in swalClasses) {
8376 addClass(container, swalClasses[position]);
8377 } else {
8378 warn('The "position" parameter is not valid, defaulting to "center"');
8379 addClass(container, swalClasses.center);
8380 }
8381 }
8382
8383 /**
8384 * @param {HTMLElement} container
8385 * @param {SweetAlertOptions['grow']} grow
8386 */
8387 function handleGrowParam(container, grow) {
8388 if (!grow) {
8389 return;
8390 }
8391 addClass(container, swalClasses[`grow-${grow}`]);
8392 }
8393
8394 /**
8395 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8396 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8397 * This is the approach that Babel will probably take to implement private methods/fields
8398 * https://github.com/tc39/proposal-private-methods
8399 * https://github.com/babel/babel/pull/7555
8400 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8401 * then we can use that language feature.
8402 */
8403
8404 var privateProps = {
8405 innerParams: new WeakMap(),
8406 domCache: new WeakMap(),
8407 focusedElement: new WeakMap()
8408 };
8409
8410 /// <reference path="../../../../sweetalert2.d.ts"/>
8411
8412
8413 /** @type {InputClass[]} */
8414 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
8415
8416 /**
8417 * @param {SweetAlert} instance
8418 * @param {SweetAlertOptions} params
8419 */
8420 const renderInput = (instance, params) => {
8421 const popup = getPopup();
8422 if (!popup) {
8423 return;
8424 }
8425 const innerParams = privateProps.innerParams.get(instance);
8426 const rerender = !innerParams || params.input !== innerParams.input;
8427 inputClasses.forEach(inputClass => {
8428 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
8429 if (!inputContainer) {
8430 return;
8431 }
8432
8433 // set attributes
8434 setAttributes(inputClass, params.inputAttributes);
8435
8436 // set class
8437 inputContainer.className = swalClasses[inputClass];
8438 if (rerender) {
8439 hide(inputContainer);
8440 }
8441 });
8442 if (params.input) {
8443 if (rerender) {
8444 showInput(params);
8445 }
8446 // set custom class
8447 setCustomClass(params);
8448 }
8449 };
8450
8451 /**
8452 * @param {SweetAlertOptions} params
8453 */
8454 const showInput = params => {
8455 if (!params.input) {
8456 return;
8457 }
8458 if (!renderInputType[params.input]) {
8459 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
8460 return;
8461 }
8462 const inputContainer = getInputContainer(params.input);
8463 if (!inputContainer) {
8464 return;
8465 }
8466 const input = renderInputType[params.input](inputContainer, params);
8467 show(inputContainer);
8468
8469 // input autofocus
8470 if (params.inputAutoFocus) {
8471 setTimeout(() => {
8472 focusInput(input);
8473 });
8474 }
8475 };
8476
8477 /**
8478 * @param {HTMLInputElement} input
8479 */
8480 const removeAttributes = input => {
8481 for (const {
8482 name
8483 } of Array.from(input.attributes)) {
8484 if (!['id', 'type', 'value', 'style'].includes(name)) {
8485 input.removeAttribute(name);
8486 }
8487 }
8488 };
8489
8490 /**
8491 * @param {InputClass} inputClass
8492 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
8493 */
8494 const setAttributes = (inputClass, inputAttributes) => {
8495 const popup = getPopup();
8496 if (!popup) {
8497 return;
8498 }
8499 const input = getInput$1(popup, inputClass);
8500 if (!input) {
8501 return;
8502 }
8503 removeAttributes(input);
8504 for (const attr in inputAttributes) {
8505 input.setAttribute(attr, inputAttributes[attr]);
8506 }
8507 };
8508
8509 /**
8510 * @param {SweetAlertOptions} params
8511 */
8512 const setCustomClass = params => {
8513 if (!params.input) {
8514 return;
8515 }
8516 const inputContainer = getInputContainer(params.input);
8517 if (inputContainer) {
8518 applyCustomClass(inputContainer, params, 'input');
8519 }
8520 };
8521
8522 /**
8523 * @param {HTMLInputElement | HTMLTextAreaElement} input
8524 * @param {SweetAlertOptions} params
8525 */
8526 const setInputPlaceholder = (input, params) => {
8527 if (!input.placeholder && params.inputPlaceholder) {
8528 input.placeholder = params.inputPlaceholder;
8529 }
8530 };
8531
8532 /**
8533 * @param {Input} input
8534 * @param {Input} prependTo
8535 * @param {SweetAlertOptions} params
8536 */
8537 const setInputLabel = (input, prependTo, params) => {
8538 if (params.inputLabel) {
8539 const label = document.createElement('label');
8540 const labelClass = swalClasses['input-label'];
8541 label.setAttribute('for', input.id);
8542 label.className = labelClass;
8543 if (typeof params.customClass === 'object') {
8544 addClass(label, params.customClass.inputLabel);
8545 }
8546 label.innerText = params.inputLabel;
8547 prependTo.insertAdjacentElement('beforebegin', label);
8548 }
8549 };
8550
8551 /**
8552 * @param {SweetAlertInput} inputType
8553 * @returns {HTMLElement | undefined}
8554 */
8555 const getInputContainer = inputType => {
8556 const popup = getPopup();
8557 if (!popup) {
8558 return;
8559 }
8560 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
8561 };
8562
8563 /**
8564 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
8565 * @param {SweetAlertOptions['inputValue']} inputValue
8566 */
8567 const checkAndSetInputValue = (input, inputValue) => {
8568 if (['string', 'number'].includes(typeof inputValue)) {
8569 input.value = `${inputValue}`;
8570 } else if (!isPromise(inputValue)) {
8571 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
8572 }
8573 };
8574
8575 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
8576 const renderInputType = {};
8577
8578 /**
8579 * @param {Input | HTMLElement} input
8580 * @param {SweetAlertOptions} params
8581 * @returns {Input}
8582 */
8583 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} */
8584 (input, params) => {
8585 // oxfmt-ignore
8586 const inputElement = /** @type {HTMLInputElement} */input;
8587 checkAndSetInputValue(inputElement, params.inputValue);
8588 setInputLabel(inputElement, inputElement, params);
8589 setInputPlaceholder(inputElement, params);
8590 // oxfmt-ignore
8591 inputElement.type = /** @type {string} */params.input;
8592 return inputElement;
8593 };
8594
8595 /**
8596 * @param {Input | HTMLElement} input
8597 * @param {SweetAlertOptions} params
8598 * @returns {Input}
8599 */
8600 renderInputType.file = (input, params) => {
8601 const inputElement = /** @type {HTMLInputElement} */input;
8602 setInputLabel(inputElement, inputElement, params);
8603 setInputPlaceholder(inputElement, params);
8604 return inputElement;
8605 };
8606
8607 /**
8608 * @param {Input | HTMLElement} range
8609 * @param {SweetAlertOptions} params
8610 * @returns {Input}
8611 */
8612 renderInputType.range = (range, params) => {
8613 const rangeContainer = /** @type {HTMLElement} */range;
8614 const rangeInput = rangeContainer.querySelector('input');
8615 const rangeOutput = rangeContainer.querySelector('output');
8616 if (rangeInput) {
8617 checkAndSetInputValue(rangeInput, params.inputValue);
8618 rangeInput.type = /** @type {string} */params.input;
8619 setInputLabel(rangeInput, /** @type {Input} */range, params);
8620 }
8621 if (rangeOutput) {
8622 checkAndSetInputValue(rangeOutput, params.inputValue);
8623 }
8624 return /** @type {Input} */range;
8625 };
8626
8627 /**
8628 * @param {Input | HTMLElement} select
8629 * @param {SweetAlertOptions} params
8630 * @returns {Input}
8631 */
8632 renderInputType.select = (select, params) => {
8633 const selectElement = /** @type {HTMLSelectElement} */select;
8634 selectElement.textContent = '';
8635 if (params.inputPlaceholder) {
8636 const placeholder = document.createElement('option');
8637 setInnerHtml(placeholder, params.inputPlaceholder);
8638 placeholder.value = '';
8639 placeholder.disabled = true;
8640 placeholder.selected = true;
8641 selectElement.appendChild(placeholder);
8642 }
8643 setInputLabel(selectElement, selectElement, params);
8644 return selectElement;
8645 };
8646
8647 /**
8648 * @param {Input | HTMLElement} radio
8649 * @returns {Input}
8650 */
8651 renderInputType.radio = radio => {
8652 const radioElement = /** @type {HTMLElement} */radio;
8653 radioElement.textContent = '';
8654 return /** @type {Input} */radio;
8655 };
8656
8657 /**
8658 * @param {Input | HTMLElement} checkboxContainer
8659 * @param {SweetAlertOptions} params
8660 * @returns {Input}
8661 */
8662 renderInputType.checkbox = (checkboxContainer, params) => {
8663 const popup = getPopup();
8664 if (!popup) {
8665 throw new Error('Popup not found');
8666 }
8667 const checkbox = getInput$1(popup, 'checkbox');
8668 if (!checkbox) {
8669 throw new Error('Checkbox input not found');
8670 }
8671 checkbox.value = '1';
8672 checkbox.checked = Boolean(params.inputValue);
8673 const containerElement = /** @type {HTMLElement} */checkboxContainer;
8674 const label = containerElement.querySelector('span');
8675 if (label) {
8676 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
8677 if (placeholderOrLabel) {
8678 setInnerHtml(label, placeholderOrLabel);
8679 }
8680 }
8681 return checkbox;
8682 };
8683
8684 /**
8685 * @param {Input | HTMLElement} textarea
8686 * @param {SweetAlertOptions} params
8687 * @returns {Input}
8688 */
8689 renderInputType.textarea = (textarea, params) => {
8690 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
8691 checkAndSetInputValue(textareaElement, params.inputValue);
8692 setInputPlaceholder(textareaElement, params);
8693 setInputLabel(textareaElement, textareaElement, params);
8694
8695 /**
8696 * @param {HTMLElement} el
8697 * @returns {number}
8698 */
8699 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
8700
8701 // https://github.com/sweetalert2/sweetalert2/issues/2291
8702 setTimeout(() => {
8703 // https://github.com/sweetalert2/sweetalert2/issues/1699
8704 if ('MutationObserver' in window) {
8705 const popup = getPopup();
8706 if (!popup) {
8707 return;
8708 }
8709 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
8710 const textareaResizeHandler = () => {
8711 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
8712 if (!document.body.contains(textareaElement)) {
8713 return;
8714 }
8715 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
8716 const popupElement = getPopup();
8717 if (popupElement) {
8718 if (textareaWidth > initialPopupWidth) {
8719 popupElement.style.width = `${textareaWidth}px`;
8720 } else {
8721 applyNumericalStyle(popupElement, 'width', params.width);
8722 }
8723 }
8724 };
8725 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
8726 attributes: true,
8727 attributeFilter: ['style']
8728 });
8729 }
8730 });
8731 return textareaElement;
8732 };
8733
8734 /**
8735 * @param {SweetAlert} instance
8736 * @param {SweetAlertOptions} params
8737 */
8738 const renderContent = (instance, params) => {
8739 const htmlContainer = getHtmlContainer();
8740 if (!htmlContainer) {
8741 return;
8742 }
8743 showWhenInnerHtmlPresent(htmlContainer);
8744 applyCustomClass(htmlContainer, params, 'htmlContainer');
8745
8746 // Content as HTML
8747 if (params.html) {
8748 parseHtmlToContainer(params.html, htmlContainer);
8749 show(htmlContainer, 'block');
8750 }
8751
8752 // Content as plain text
8753 else if (params.text) {
8754 htmlContainer.textContent = params.text;
8755 show(htmlContainer, 'block');
8756 }
8757
8758 // No content
8759 else {
8760 hide(htmlContainer);
8761 }
8762 renderInput(instance, params);
8763 };
8764
8765 /**
8766 * @param {SweetAlert} instance
8767 * @param {SweetAlertOptions} params
8768 */
8769 const renderFooter = (instance, params) => {
8770 const footer = getFooter();
8771 if (!footer) {
8772 return;
8773 }
8774 showWhenInnerHtmlPresent(footer);
8775 toggle(footer, Boolean(params.footer), 'block');
8776 if (params.footer) {
8777 parseHtmlToContainer(params.footer, footer);
8778 }
8779
8780 // Custom class
8781 applyCustomClass(footer, params, 'footer');
8782 };
8783
8784 /**
8785 * @param {SweetAlert} instance
8786 * @param {SweetAlertOptions} params
8787 */
8788 const renderIcon = (instance, params) => {
8789 const innerParams = privateProps.innerParams.get(instance);
8790 const icon = getIcon();
8791 if (!icon) {
8792 return;
8793 }
8794
8795 // if the given icon already rendered, apply the styling without re-rendering the icon
8796 if (innerParams && params.icon === innerParams.icon) {
8797 // Custom or default content
8798 setContent(icon, params);
8799 applyStyles(icon, params);
8800 return;
8801 }
8802 if (!params.icon && !params.iconHtml) {
8803 hide(icon);
8804 return;
8805 }
8806 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
8807 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
8808 hide(icon);
8809 return;
8810 }
8811 show(icon);
8812
8813 // Custom or default content
8814 setContent(icon, params);
8815 applyStyles(icon, params);
8816
8817 // Animate icon
8818 addClass(icon, params.showClass && params.showClass.icon);
8819
8820 // Re-adjust the success icon on system theme change
8821 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
8822 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
8823 };
8824
8825 /**
8826 * @param {HTMLElement} icon
8827 * @param {SweetAlertOptions} params
8828 */
8829 const applyStyles = (icon, params) => {
8830 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
8831 if (params.icon !== iconType) {
8832 removeClass(icon, iconClassName);
8833 }
8834 }
8835 addClass(icon, params.icon && iconTypes[params.icon]);
8836
8837 // Icon color
8838 setColor(icon, params);
8839
8840 // Success icon background color
8841 adjustSuccessIconBackgroundColor();
8842
8843 // Custom class
8844 applyCustomClass(icon, params, 'icon');
8845 };
8846
8847 // Adjust success icon background color to match the popup background color
8848 const adjustSuccessIconBackgroundColor = () => {
8849 const popup = getPopup();
8850 if (!popup) {
8851 return;
8852 }
8853 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
8854 /** @type {NodeListOf<HTMLElement>} */
8855 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
8856 successIconParts.forEach(part => {
8857 part.style.backgroundColor = popupBackgroundColor;
8858 });
8859 };
8860
8861 /**
8862 *
8863 * @param {SweetAlertOptions} params
8864 * @returns {string}
8865 */
8866 const successIconHtml = params => `
8867 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
8868 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
8869 <div class="swal2-success-ring"></div>
8870 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
8871 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
8872 `;
8873 const errorIconHtml = `
8874 <span class="swal2-x-mark">
8875 <span class="swal2-x-mark-line-left"></span>
8876 <span class="swal2-x-mark-line-right"></span>
8877 </span>
8878 `;
8879
8880 /**
8881 * @param {HTMLElement} icon
8882 * @param {SweetAlertOptions} params
8883 */
8884 const setContent = (icon, params) => {
8885 if (!params.icon && !params.iconHtml) {
8886 return;
8887 }
8888 let oldContent = icon.innerHTML;
8889 let newContent = '';
8890 if (params.iconHtml) {
8891 newContent = iconContent(params.iconHtml);
8892 } else if (params.icon === 'success') {
8893 newContent = successIconHtml(params);
8894 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
8895 } else if (params.icon === 'error') {
8896 newContent = errorIconHtml;
8897 } else if (params.icon) {
8898 const defaultIconHtml = {
8899 question: '?',
8900 warning: '!',
8901 info: 'i'
8902 };
8903 newContent = iconContent(defaultIconHtml[params.icon]);
8904 }
8905 if (oldContent.trim() !== newContent.trim()) {
8906 setInnerHtml(icon, newContent);
8907 }
8908 };
8909
8910 /**
8911 * @param {HTMLElement} icon
8912 * @param {SweetAlertOptions} params
8913 */
8914 const setColor = (icon, params) => {
8915 if (!params.iconColor) {
8916 return;
8917 }
8918 icon.style.color = params.iconColor;
8919 icon.style.borderColor = params.iconColor;
8920 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
8921 setStyle(icon, sel, 'background-color', params.iconColor);
8922 }
8923 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
8924 };
8925
8926 /**
8927 * @param {string} content
8928 * @returns {string}
8929 */
8930 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
8931
8932 /**
8933 * @param {SweetAlert} instance
8934 * @param {SweetAlertOptions} params
8935 */
8936 const renderImage = (instance, params) => {
8937 const image = getImage();
8938 if (!image) {
8939 return;
8940 }
8941 if (!params.imageUrl) {
8942 hide(image);
8943 return;
8944 }
8945 show(image, '');
8946
8947 // Src, alt
8948 image.setAttribute('src', params.imageUrl);
8949 image.setAttribute('alt', params.imageAlt || '');
8950
8951 // Width, height
8952 applyNumericalStyle(image, 'width', params.imageWidth);
8953 applyNumericalStyle(image, 'height', params.imageHeight);
8954
8955 // Class
8956 image.className = swalClasses.image;
8957 applyCustomClass(image, params, 'image');
8958 };
8959
8960 let dragging = false;
8961 let mousedownX = 0;
8962 let mousedownY = 0;
8963 let initialX = 0;
8964 let initialY = 0;
8965
8966 /**
8967 * @param {HTMLElement} popup
8968 */
8969 const addDraggableListeners = popup => {
8970 popup.addEventListener('mousedown', down);
8971 document.body.addEventListener('mousemove', move);
8972 popup.addEventListener('mouseup', up);
8973 popup.addEventListener('touchstart', down);
8974 document.body.addEventListener('touchmove', move);
8975 popup.addEventListener('touchend', up);
8976 };
8977
8978 /**
8979 * @param {HTMLElement} popup
8980 */
8981 const removeDraggableListeners = popup => {
8982 popup.removeEventListener('mousedown', down);
8983 document.body.removeEventListener('mousemove', move);
8984 popup.removeEventListener('mouseup', up);
8985 popup.removeEventListener('touchstart', down);
8986 document.body.removeEventListener('touchmove', move);
8987 popup.removeEventListener('touchend', up);
8988 };
8989
8990 /**
8991 * @param {MouseEvent | TouchEvent} event
8992 */
8993 const down = event => {
8994 const popup = getPopup();
8995 if (!popup) {
8996 return;
8997 }
8998 const icon = getIcon();
8999 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
9000 dragging = true;
9001 const clientXY = getClientXY(event);
9002 mousedownX = clientXY.clientX;
9003 mousedownY = clientXY.clientY;
9004 initialX = parseInt(popup.style.insetInlineStart) || 0;
9005 initialY = parseInt(popup.style.insetBlockStart) || 0;
9006 addClass(popup, 'swal2-dragging');
9007 }
9008 };
9009
9010 /**
9011 * @param {MouseEvent | TouchEvent} event
9012 */
9013 const move = event => {
9014 const popup = getPopup();
9015 if (!popup) {
9016 return;
9017 }
9018 if (dragging) {
9019 let {
9020 clientX,
9021 clientY
9022 } = getClientXY(event);
9023 const deltaX = clientX - mousedownX;
9024 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
9025 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
9026 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
9027 }
9028 };
9029 const up = () => {
9030 const popup = getPopup();
9031 dragging = false;
9032 removeClass(popup, 'swal2-dragging');
9033 };
9034
9035 /**
9036 * @param {MouseEvent | TouchEvent} event
9037 * @returns {{ clientX: number, clientY: number }}
9038 */
9039 const getClientXY = event => {
9040 const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
9041 return {
9042 clientX: source.clientX,
9043 clientY: source.clientY
9044 };
9045 };
9046
9047 /**
9048 * @param {SweetAlert} instance
9049 * @param {SweetAlertOptions} params
9050 */
9051 const renderPopup = (instance, params) => {
9052 const container = getContainer();
9053 const popup = getPopup();
9054 if (!container || !popup) {
9055 return;
9056 }
9057
9058 // Width
9059 // https://github.com/sweetalert2/sweetalert2/issues/2170
9060 if (params.toast) {
9061 applyNumericalStyle(container, 'width', params.width);
9062 popup.style.width = '100%';
9063 const loader = getLoader();
9064 if (loader) {
9065 popup.insertBefore(loader, getIcon());
9066 }
9067 } else {
9068 applyNumericalStyle(popup, 'width', params.width);
9069 }
9070
9071 // Padding
9072 applyNumericalStyle(popup, 'padding', params.padding);
9073
9074 // Color
9075 if (params.color) {
9076 popup.style.color = params.color;
9077 }
9078
9079 // Background
9080 if (params.background) {
9081 popup.style.background = params.background;
9082 }
9083 hide(getValidationMessage());
9084
9085 // Classes
9086 addClasses$1(popup, params);
9087 if (params.draggable && !params.toast) {
9088 addClass(popup, swalClasses.draggable);
9089 addDraggableListeners(popup);
9090 } else {
9091 removeClass(popup, swalClasses.draggable);
9092 removeDraggableListeners(popup);
9093 }
9094 };
9095
9096 /**
9097 * @param {HTMLElement} popup
9098 * @param {SweetAlertOptions} params
9099 */
9100 const addClasses$1 = (popup, params) => {
9101 const showClass = params.showClass || {};
9102 // Default Class + showClass when updating Swal.update({})
9103 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
9104 if (params.toast) {
9105 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
9106 addClass(popup, swalClasses.toast);
9107 } else {
9108 addClass(popup, swalClasses.modal);
9109 }
9110
9111 // Custom class
9112 applyCustomClass(popup, params, 'popup');
9113 // TODO: remove in the next major
9114 if (typeof params.customClass === 'string') {
9115 addClass(popup, params.customClass);
9116 }
9117
9118 // Icon class (#1842)
9119 if (params.icon) {
9120 addClass(popup, swalClasses[`icon-${params.icon}`]);
9121 }
9122 };
9123
9124 /**
9125 * @param {SweetAlert} instance
9126 * @param {SweetAlertOptions} params
9127 */
9128 const renderProgressSteps = (instance, params) => {
9129 const progressStepsContainer = getProgressSteps();
9130 if (!progressStepsContainer) {
9131 return;
9132 }
9133 const {
9134 progressSteps,
9135 currentProgressStep
9136 } = params;
9137 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
9138 hide(progressStepsContainer);
9139 return;
9140 }
9141 show(progressStepsContainer);
9142 progressStepsContainer.textContent = '';
9143 if (currentProgressStep >= progressSteps.length) {
9144 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
9145 }
9146 progressSteps.forEach((step, index) => {
9147 const stepEl = createStepElement(step);
9148 progressStepsContainer.appendChild(stepEl);
9149 if (index === currentProgressStep) {
9150 addClass(stepEl, swalClasses['active-progress-step']);
9151 }
9152 if (index !== progressSteps.length - 1) {
9153 const lineEl = createLineElement(params);
9154 progressStepsContainer.appendChild(lineEl);
9155 }
9156 });
9157 };
9158
9159 /**
9160 * @param {string} step
9161 * @returns {HTMLLIElement}
9162 */
9163 const createStepElement = step => {
9164 const stepEl = document.createElement('li');
9165 addClass(stepEl, swalClasses['progress-step']);
9166 setInnerHtml(stepEl, step);
9167 return stepEl;
9168 };
9169
9170 /**
9171 * @param {SweetAlertOptions} params
9172 * @returns {HTMLLIElement}
9173 */
9174 const createLineElement = params => {
9175 const lineEl = document.createElement('li');
9176 addClass(lineEl, swalClasses['progress-step-line']);
9177 if (params.progressStepsDistance) {
9178 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
9179 }
9180 return lineEl;
9181 };
9182
9183 /**
9184 * @param {SweetAlert} instance
9185 * @param {SweetAlertOptions} params
9186 */
9187 const renderTitle = (instance, params) => {
9188 const title = getTitle();
9189 if (!title) {
9190 return;
9191 }
9192 showWhenInnerHtmlPresent(title);
9193 toggle(title, Boolean(params.title || params.titleText), 'block');
9194 if (params.title) {
9195 parseHtmlToContainer(params.title, title);
9196 }
9197 if (params.titleText) {
9198 title.innerText = params.titleText;
9199 }
9200
9201 // Custom class
9202 applyCustomClass(title, params, 'title');
9203 };
9204
9205 /**
9206 * @param {SweetAlert} instance
9207 * @param {SweetAlertOptions} params
9208 */
9209 const render = (instance, params) => {
9210 var _globalState$eventEmi;
9211 renderPopup(instance, params);
9212 renderContainer(instance, params);
9213 renderProgressSteps(instance, params);
9214 renderIcon(instance, params);
9215 renderImage(instance, params);
9216 renderTitle(instance, params);
9217 renderCloseButton(instance, params);
9218 renderContent(instance, params);
9219 renderActions(instance, params);
9220 renderFooter(instance, params);
9221 const popup = getPopup();
9222 if (typeof params.didRender === 'function' && popup) {
9223 params.didRender(popup);
9224 }
9225 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
9226 };
9227
9228 /*
9229 * Global function to determine if SweetAlert2 popup is shown
9230 */
9231 const isVisible = () => {
9232 return isVisible$1(getPopup());
9233 };
9234
9235 /*
9236 * Global function to click 'Confirm' button
9237 */
9238 const clickConfirm = () => {
9239 var _dom$getConfirmButton;
9240 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
9241 };
9242
9243 /*
9244 * Global function to click 'Deny' button
9245 */
9246 const clickDeny = () => {
9247 var _dom$getDenyButton;
9248 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
9249 };
9250
9251 /*
9252 * Global function to click 'Cancel' button
9253 */
9254 const clickCancel = () => {
9255 var _dom$getCancelButton;
9256 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
9257 };
9258
9259 /** @type {Record<DismissReason, DismissReason>} */
9260 const DismissReason = Object.freeze({
9261 cancel: 'cancel',
9262 backdrop: 'backdrop',
9263 close: 'close',
9264 esc: 'esc',
9265 timer: 'timer'
9266 });
9267
9268 /**
9269 * @param {GlobalState} globalState
9270 */
9271 const removeKeydownHandler = globalState => {
9272 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
9273 const handler = /** @type {EventListenerOrEventListenerObject} */
9274 /** @type {unknown} */globalState.keydownHandler;
9275 globalState.keydownTarget.removeEventListener('keydown', handler, {
9276 capture: globalState.keydownListenerCapture
9277 });
9278 globalState.keydownHandlerAdded = false;
9279 }
9280 };
9281
9282 /**
9283 * @param {GlobalState} globalState
9284 * @param {SweetAlertOptions} innerParams
9285 * @param {(dismiss: DismissReason) => void} dismissWith
9286 */
9287 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
9288 removeKeydownHandler(globalState);
9289 if (!innerParams.toast) {
9290 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
9291 const handler = e => keydownHandler(innerParams, e, dismissWith);
9292 globalState.keydownHandler = handler;
9293 const target = innerParams.keydownListenerCapture ? window : getPopup();
9294 if (target) {
9295 globalState.keydownTarget = target;
9296 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
9297 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
9298 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
9299 capture: globalState.keydownListenerCapture
9300 });
9301 globalState.keydownHandlerAdded = true;
9302 }
9303 }
9304 };
9305
9306 /**
9307 * @param {number} index
9308 * @param {number} increment
9309 * @returns {boolean} shouldPreventDefault
9310 */
9311 const setFocus = (index, increment) => {
9312 var _dom$getPopup;
9313 const focusableElements = getFocusableElements();
9314 // search for visible elements and select the next possible match
9315 if (focusableElements.length) {
9316 index = index + increment;
9317
9318 // shift + tab when .swal2-popup is focused
9319 if (index === -2) {
9320 index = focusableElements.length - 1;
9321 }
9322
9323 // rollover to first item
9324 if (index === focusableElements.length) {
9325 index = 0;
9326
9327 // go to last item
9328 } else if (index === -1) {
9329 index = focusableElements.length - 1;
9330 }
9331 focusableElements[index].focus();
9332
9333 // don't prevent default for iframes (Firefox fix)
9334 // https://github.com/sweetalert2/sweetalert2/issues/2931
9335 if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
9336 return false;
9337 }
9338 return true;
9339 }
9340 // no visible focusable elements, focus the popup
9341 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
9342 return true;
9343 };
9344 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
9345 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
9346
9347 /**
9348 * @param {SweetAlertOptions} innerParams
9349 * @param {KeyboardEvent} event
9350 * @param {(dismiss: DismissReason) => void} dismissWith
9351 */
9352 const keydownHandler = (innerParams, event, dismissWith) => {
9353 if (!innerParams) {
9354 return; // This instance has already been destroyed
9355 }
9356
9357 // Ignore keydown during IME composition
9358 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
9359 // https://github.com/sweetalert2/sweetalert2/issues/720
9360 // https://github.com/sweetalert2/sweetalert2/issues/2406
9361 if (event.isComposing || event.keyCode === 229) {
9362 return;
9363 }
9364 if (innerParams.stopKeydownPropagation) {
9365 event.stopPropagation();
9366 }
9367
9368 // ENTER
9369 if (event.key === 'Enter') {
9370 handleEnter(event, innerParams);
9371 }
9372
9373 // TAB
9374 else if (event.key === 'Tab') {
9375 handleTab(event);
9376 }
9377
9378 // ARROWS - switch focus between buttons
9379 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
9380 handleArrows(event.key);
9381 }
9382
9383 // ESC
9384 else if (event.key === 'Escape') {
9385 handleEsc(event, innerParams, dismissWith);
9386 }
9387 };
9388
9389 /**
9390 * @param {KeyboardEvent} event
9391 * @param {SweetAlertOptions} innerParams
9392 */
9393 const handleEnter = (event, innerParams) => {
9394 // https://github.com/sweetalert2/sweetalert2/issues/2386
9395 if (!callIfFunction(innerParams.allowEnterKey)) {
9396 return;
9397 }
9398 const popup = getPopup();
9399 if (!popup || !innerParams.input) {
9400 return;
9401 }
9402 const input = getInput$1(popup, innerParams.input);
9403 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
9404 if (['textarea', 'file'].includes(innerParams.input)) {
9405 return; // do not submit
9406 }
9407 clickConfirm();
9408 event.preventDefault();
9409 }
9410 };
9411
9412 /**
9413 * @param {KeyboardEvent} event
9414 */
9415 const handleTab = event => {
9416 const targetElement = event.target;
9417 const focusableElements = getFocusableElements();
9418 const btnIndex = focusableElements.findIndex(el => el === targetElement);
9419
9420 // don't prevent default for iframes (Firefox fix)
9421 // https://github.com/sweetalert2/sweetalert2/issues/2931
9422 let shouldPreventDefault = true;
9423
9424 // Cycle to the next button
9425 if (!event.shiftKey) {
9426 shouldPreventDefault = setFocus(btnIndex, 1);
9427 }
9428
9429 // Cycle to the prev button
9430 else {
9431 shouldPreventDefault = setFocus(btnIndex, -1);
9432 }
9433 event.stopPropagation();
9434 if (shouldPreventDefault) {
9435 event.preventDefault();
9436 }
9437 };
9438
9439 /**
9440 * @param {string} key
9441 */
9442 const handleArrows = key => {
9443 const actions = getActions();
9444 const confirmButton = getConfirmButton();
9445 const denyButton = getDenyButton();
9446 const cancelButton = getCancelButton();
9447 if (!actions || !confirmButton || !denyButton || !cancelButton) {
9448 return;
9449 }
9450 /** @type HTMLElement[] */
9451 const buttons = [confirmButton, denyButton, cancelButton];
9452 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
9453 return;
9454 }
9455 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
9456 let buttonToFocus = document.activeElement;
9457 if (!buttonToFocus) {
9458 return;
9459 }
9460 for (let i = 0; i < actions.children.length; i++) {
9461 buttonToFocus = buttonToFocus[sibling];
9462 if (!buttonToFocus) {
9463 return;
9464 }
9465 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
9466 break;
9467 }
9468 }
9469 if (buttonToFocus instanceof HTMLButtonElement) {
9470 buttonToFocus.focus();
9471 }
9472 };
9473
9474 /**
9475 * @param {KeyboardEvent} event
9476 * @param {SweetAlertOptions} innerParams
9477 * @param {(dismiss: DismissReason) => void} dismissWith
9478 */
9479 const handleEsc = (event, innerParams, dismissWith) => {
9480 event.preventDefault();
9481 if (callIfFunction(innerParams.allowEscapeKey)) {
9482 dismissWith(DismissReason.esc);
9483 }
9484 };
9485
9486 /**
9487 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
9488 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
9489 * This is the approach that Babel will probably take to implement private methods/fields
9490 * https://github.com/tc39/proposal-private-methods
9491 * https://github.com/babel/babel/pull/7555
9492 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
9493 * then we can use that language feature.
9494 */
9495
9496 var privateMethods = {
9497 swalPromiseResolve: new WeakMap(),
9498 swalPromiseReject: new WeakMap()
9499 };
9500
9501 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
9502 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
9503 // elements not within the active modal dialog will not be surfaced if a user opens a screen
9504 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
9505
9506 const setAriaHidden = () => {
9507 const container = getContainer();
9508 const bodyChildren = Array.from(document.body.children);
9509 bodyChildren.forEach(el => {
9510 if (el.contains(container)) {
9511 return;
9512 }
9513 if (el.hasAttribute('aria-hidden')) {
9514 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
9515 }
9516 el.setAttribute('aria-hidden', 'true');
9517 });
9518 };
9519 const unsetAriaHidden = () => {
9520 const bodyChildren = Array.from(document.body.children);
9521 bodyChildren.forEach(el => {
9522 if (el.hasAttribute('data-previous-aria-hidden')) {
9523 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
9524 el.removeAttribute('data-previous-aria-hidden');
9525 } else {
9526 el.removeAttribute('aria-hidden');
9527 }
9528 });
9529 };
9530
9531 // @ts-ignore
9532 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
9533
9534 // @ts-ignore
9535 const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
9536
9537 /**
9538 * Fix iOS scrolling
9539 * http://stackoverflow.com/q/39626302
9540 */
9541 const iOSfix = () => {
9542 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
9543 const offset = document.body.scrollTop;
9544 document.body.style.top = `${offset * -1}px`;
9545 addClass(document.body, swalClasses.iosfix);
9546 lockBodyScroll();
9547 }
9548 };
9549
9550 /**
9551 * https://github.com/sweetalert2/sweetalert2/issues/1246
9552 */
9553 const lockBodyScroll = () => {
9554 const container = getContainer();
9555 if (!container) {
9556 return;
9557 }
9558 /** @type {boolean} */
9559 let preventTouchMove;
9560 /**
9561 * @param {TouchEvent} event
9562 */
9563 container.ontouchstart = event => {
9564 preventTouchMove = shouldPreventTouchMove(event);
9565 };
9566 /**
9567 * @param {TouchEvent} event
9568 */
9569 container.ontouchmove = event => {
9570 if (preventTouchMove) {
9571 event.preventDefault();
9572 event.stopPropagation();
9573 }
9574 };
9575 };
9576
9577 /**
9578 * @param {TouchEvent} event
9579 * @returns {boolean}
9580 */
9581 const shouldPreventTouchMove = event => {
9582 const target = event.target;
9583 const container = getContainer();
9584 const htmlContainer = getHtmlContainer();
9585 if (!container || !htmlContainer) {
9586 return false;
9587 }
9588 if (isStylus(event) || isZoom(event)) {
9589 return false;
9590 }
9591 if (target === container) {
9592 return true;
9593 }
9594 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
9595 // #2823
9596 target.tagName !== 'INPUT' &&
9597 // #1603
9598 target.tagName !== 'TEXTAREA' &&
9599 // #2266
9600 !(isScrollable(htmlContainer) &&
9601 // #1944
9602 htmlContainer.contains(target))) {
9603 return true;
9604 }
9605 return false;
9606 };
9607
9608 /**
9609 * https://github.com/sweetalert2/sweetalert2/issues/1786
9610 *
9611 * @param {TouchEvent} event
9612 * @returns {boolean}
9613 */
9614 const isStylus = event => {
9615 return Boolean(event.touches && event.touches.length &&
9616 // @ts-ignore - touchType is not a standard property
9617 event.touches[0].touchType === 'stylus');
9618 };
9619
9620 /**
9621 * https://github.com/sweetalert2/sweetalert2/issues/1891
9622 *
9623 * @param {TouchEvent} event
9624 * @returns {boolean}
9625 */
9626 const isZoom = event => {
9627 return event.touches && event.touches.length > 1;
9628 };
9629 const undoIOSfix = () => {
9630 if (hasClass(document.body, swalClasses.iosfix)) {
9631 const offset = parseInt(document.body.style.top, 10);
9632 removeClass(document.body, swalClasses.iosfix);
9633 document.body.style.top = '';
9634 document.body.scrollTop = offset * -1;
9635 }
9636 };
9637
9638 /**
9639 * Measure scrollbar width for padding body during modal show/hide
9640 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
9641 *
9642 * @returns {number}
9643 */
9644 const measureScrollbar = () => {
9645 const scrollDiv = document.createElement('div');
9646 scrollDiv.className = swalClasses['scrollbar-measure'];
9647 document.body.appendChild(scrollDiv);
9648 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
9649 document.body.removeChild(scrollDiv);
9650 return scrollbarWidth;
9651 };
9652
9653 /**
9654 * Remember state in cases where opening and handling a modal will fiddle with it.
9655 * @type {number | null}
9656 */
9657 let previousBodyPadding = null;
9658
9659 /**
9660 * @param {string} initialBodyOverflow
9661 */
9662 const replaceScrollbarWithPadding = initialBodyOverflow => {
9663 // for queues, do not do this more than once
9664 if (previousBodyPadding !== null) {
9665 return;
9666 }
9667 // if the body has overflow
9668 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
9669 ) {
9670 // add padding so the content doesn't shift after removal of scrollbar
9671 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
9672 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
9673 }
9674 };
9675 const undoReplaceScrollbarWithPadding = () => {
9676 if (previousBodyPadding !== null) {
9677 document.body.style.paddingRight = `${previousBodyPadding}px`;
9678 previousBodyPadding = null;
9679 }
9680 };
9681
9682 /**
9683 * @param {SweetAlert} instance
9684 * @param {HTMLElement} container
9685 * @param {boolean} returnFocus
9686 * @param {(() => void) | undefined} didClose
9687 */
9688 function removePopupAndResetState(instance, container, returnFocus, didClose) {
9689 if (isToast()) {
9690 triggerDidCloseAndDispose(instance, didClose);
9691 } else {
9692 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
9693 removeKeydownHandler(globalState);
9694 }
9695
9696 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
9697 // for some reason removing the container in Safari will scroll the document to bottom
9698 if (isSafariOrIOS) {
9699 container.setAttribute('style', 'display:none !important');
9700 container.removeAttribute('class');
9701 container.innerHTML = '';
9702 } else {
9703 container.remove();
9704 }
9705 if (isModal()) {
9706 undoReplaceScrollbarWithPadding();
9707 undoIOSfix();
9708 unsetAriaHidden();
9709 }
9710 removeBodyClasses();
9711 }
9712
9713 /**
9714 * Remove SweetAlert2 classes from body
9715 */
9716 function removeBodyClasses() {
9717 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
9718 }
9719
9720 /**
9721 * Instance method to close sweetAlert
9722 *
9723 * @param {SweetAlertResult | undefined} resolveValue
9724 * @this {SweetAlert}
9725 */
9726 function close(resolveValue) {
9727 resolveValue = prepareResolveValue(resolveValue);
9728 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
9729 const didClose = triggerClosePopup(this);
9730 if (this.isAwaitingPromise) {
9731 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
9732 if (!resolveValue.isDismissed) {
9733 handleAwaitingPromise(this);
9734 swalPromiseResolve(resolveValue);
9735 }
9736 } else if (didClose) {
9737 // Resolve Swal promise
9738 swalPromiseResolve(resolveValue);
9739 }
9740 }
9741
9742 /**
9743 * @param {SweetAlert} instance
9744 * @returns {boolean}
9745 */
9746 const triggerClosePopup = instance => {
9747 const popup = getPopup();
9748 if (!popup) {
9749 return false;
9750 }
9751 const innerParams = privateProps.innerParams.get(instance);
9752 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
9753 return false;
9754 }
9755 removeClass(popup, innerParams.showClass.popup);
9756 addClass(popup, innerParams.hideClass.popup);
9757 const backdrop = getContainer();
9758 removeClass(backdrop, innerParams.showClass.backdrop);
9759 addClass(backdrop, innerParams.hideClass.backdrop);
9760 handlePopupAnimation(instance, popup, innerParams);
9761 return true;
9762 };
9763
9764 /**
9765 * @param {Error | string} error
9766 * @this {SweetAlert}
9767 */
9768 function rejectPromise(error) {
9769 const rejectPromise = privateMethods.swalPromiseReject.get(this);
9770 handleAwaitingPromise(this);
9771 if (rejectPromise) {
9772 // Reject Swal promise
9773 rejectPromise(error);
9774 }
9775 }
9776
9777 /**
9778 * @param {SweetAlert} instance
9779 */
9780 const handleAwaitingPromise = instance => {
9781 if (instance.isAwaitingPromise) {
9782 // @ts-ignore
9783 delete instance.isAwaitingPromise;
9784 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
9785 if (!privateProps.innerParams.get(instance)) {
9786 instance._destroy();
9787 }
9788 }
9789 };
9790
9791 /**
9792 * @param {SweetAlertResult | undefined} resolveValue
9793 * @returns {SweetAlertResult}
9794 */
9795 const prepareResolveValue = resolveValue => {
9796 // When user calls Swal.close()
9797 if (typeof resolveValue === 'undefined') {
9798 return {
9799 isConfirmed: false,
9800 isDenied: false,
9801 isDismissed: true
9802 };
9803 }
9804 return Object.assign({
9805 isConfirmed: false,
9806 isDenied: false,
9807 isDismissed: false
9808 }, resolveValue);
9809 };
9810
9811 /**
9812 * @param {SweetAlert} instance
9813 * @param {HTMLElement} popup
9814 * @param {SweetAlertOptions} innerParams
9815 */
9816 const handlePopupAnimation = (instance, popup, innerParams) => {
9817 var _globalState$eventEmi;
9818 const container = getContainer();
9819 // If animation is supported, animate
9820 const animationIsSupported = hasCssAnimation(popup);
9821 if (typeof innerParams.willClose === 'function') {
9822 innerParams.willClose(popup);
9823 }
9824 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
9825 if (animationIsSupported && container) {
9826 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
9827 } else if (container) {
9828 // Otherwise, remove immediately
9829 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
9830 }
9831 };
9832
9833 /**
9834 * @param {SweetAlert} instance
9835 * @param {HTMLElement} popup
9836 * @param {HTMLElement} container
9837 * @param {boolean} returnFocus
9838 * @param {(() => void) | undefined} didClose
9839 */
9840 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
9841 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
9842 /**
9843 * @param {AnimationEvent | TransitionEvent} e
9844 */
9845 const swalCloseAnimationFinished = function (e) {
9846 if (e.target === popup) {
9847 var _globalState$swalClos;
9848 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
9849 delete globalState.swalCloseEventFinishedCallback;
9850 popup.removeEventListener('animationend', swalCloseAnimationFinished);
9851 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
9852 }
9853 };
9854 popup.addEventListener('animationend', swalCloseAnimationFinished);
9855 popup.addEventListener('transitionend', swalCloseAnimationFinished);
9856 };
9857
9858 /**
9859 * @param {SweetAlert} instance
9860 * @param {(() => void) | undefined} didClose
9861 */
9862 const triggerDidCloseAndDispose = (instance, didClose) => {
9863 setTimeout(() => {
9864 var _globalState$eventEmi2;
9865 if (typeof didClose === 'function') {
9866 didClose.bind(instance.params)();
9867 }
9868 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
9869 // instance might have been destroyed already
9870 if (instance._destroy) {
9871 instance._destroy();
9872 }
9873 });
9874 };
9875
9876 /**
9877 * Shows loader (spinner), this is useful with AJAX requests.
9878 * By default the loader be shown instead of the "Confirm" button.
9879 *
9880 * @param {HTMLButtonElement | null} [buttonToReplace]
9881 */
9882 const showLoading = buttonToReplace => {
9883 let popup = getPopup();
9884 if (!popup) {
9885 new Swal();
9886 }
9887 popup = getPopup();
9888 if (!popup) {
9889 return;
9890 }
9891 const loader = getLoader();
9892 if (isToast()) {
9893 hide(getIcon());
9894 } else {
9895 replaceButton(popup, buttonToReplace);
9896 }
9897 show(loader);
9898 popup.setAttribute('data-loading', 'true');
9899 popup.setAttribute('aria-busy', 'true');
9900 popup.focus();
9901 };
9902
9903 /**
9904 * @param {HTMLElement} popup
9905 * @param {HTMLButtonElement | null} [buttonToReplace]
9906 */
9907 const replaceButton = (popup, buttonToReplace) => {
9908 const actions = getActions();
9909 const loader = getLoader();
9910 if (!actions || !loader) {
9911 return;
9912 }
9913 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
9914 buttonToReplace = getConfirmButton();
9915 }
9916 show(actions);
9917 if (buttonToReplace) {
9918 hide(buttonToReplace);
9919 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
9920 actions.insertBefore(loader, buttonToReplace);
9921 }
9922 addClass([popup, actions], swalClasses.loading);
9923 };
9924
9925 /**
9926 * @param {SweetAlert} instance
9927 * @param {SweetAlertOptions} params
9928 */
9929 const handleInputOptionsAndValue = (instance, params) => {
9930 if (params.input === 'select' || params.input === 'radio') {
9931 handleInputOptions(instance, params);
9932 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
9933 showLoading(getConfirmButton());
9934 handleInputValue(instance, params);
9935 }
9936 };
9937
9938 /**
9939 * @param {SweetAlert} instance
9940 * @param {SweetAlertOptions} innerParams
9941 * @returns {SweetAlertInputValue}
9942 */
9943 const getInputValue = (instance, innerParams) => {
9944 const input = instance.getInput();
9945 if (!input) {
9946 return null;
9947 }
9948 switch (innerParams.input) {
9949 case 'checkbox':
9950 return getCheckboxValue(input);
9951 case 'radio':
9952 return getRadioValue(input);
9953 case 'file':
9954 return getFileValue(input);
9955 default:
9956 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
9957 }
9958 };
9959
9960 /**
9961 * @param {HTMLInputElement} input
9962 * @returns {number}
9963 */
9964 const getCheckboxValue = input => input.checked ? 1 : 0;
9965
9966 /**
9967 * @param {HTMLInputElement} input
9968 * @returns {string | null}
9969 */
9970 const getRadioValue = input => input.checked ? input.value : null;
9971
9972 /**
9973 * @param {HTMLInputElement} input
9974 * @returns {FileList | File | null}
9975 */
9976 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
9977
9978 /**
9979 * @param {SweetAlert} instance
9980 * @param {SweetAlertOptions} params
9981 */
9982 const handleInputOptions = (instance, params) => {
9983 const popup = getPopup();
9984 if (!popup) {
9985 return;
9986 }
9987 /**
9988 * @param {*} inputOptions
9989 */
9990 const processInputOptions = inputOptions => {
9991 if (params.input === 'select') {
9992 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
9993 } else if (params.input === 'radio') {
9994 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
9995 }
9996 };
9997 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
9998 showLoading(getConfirmButton());
9999 asPromise(params.inputOptions).then(inputOptions => {
10000 instance.hideLoading();
10001 processInputOptions(inputOptions);
10002 });
10003 } else if (typeof params.inputOptions === 'object') {
10004 processInputOptions(params.inputOptions);
10005 } else {
10006 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
10007 }
10008 };
10009
10010 /**
10011 * @param {SweetAlert} instance
10012 * @param {SweetAlertOptions} params
10013 */
10014 const handleInputValue = (instance, params) => {
10015 const input = instance.getInput();
10016 if (!input) {
10017 return;
10018 }
10019 hide(input);
10020 asPromise(params.inputValue).then(inputValue => {
10021 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
10022 show(input);
10023 input.focus();
10024 instance.hideLoading();
10025 }).catch(err => {
10026 error(`Error in inputValue promise: ${err}`);
10027 input.value = '';
10028 show(input);
10029 input.focus();
10030 instance.hideLoading();
10031 });
10032 };
10033
10034 /**
10035 * @param {HTMLElement} popup
10036 * @param {InputOptionFlattened[]} inputOptions
10037 * @param {SweetAlertOptions} params
10038 */
10039 function populateSelectOptions(popup, inputOptions, params) {
10040 const select = getDirectChildByClass(popup, swalClasses.select);
10041 if (!select) {
10042 return;
10043 }
10044 /**
10045 * @param {HTMLElement} parent
10046 * @param {string} optionLabel
10047 * @param {string} optionValue
10048 */
10049 const renderOption = (parent, optionLabel, optionValue) => {
10050 const option = document.createElement('option');
10051 option.value = optionValue;
10052 setInnerHtml(option, optionLabel);
10053 option.selected = isSelected(optionValue, params.inputValue);
10054 parent.appendChild(option);
10055 };
10056 inputOptions.forEach(inputOption => {
10057 const optionValue = inputOption[0];
10058 const optionLabel = inputOption[1];
10059 // <optgroup> spec:
10060 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
10061 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
10062 // check whether this is a <optgroup>
10063 if (Array.isArray(optionLabel)) {
10064 // if it is an array, then it is an <optgroup>
10065 const optgroup = document.createElement('optgroup');
10066 optgroup.label = optionValue;
10067 optgroup.disabled = false; // not configurable for now
10068 select.appendChild(optgroup);
10069 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
10070 } else {
10071 // case of <option>
10072 renderOption(select, optionLabel, optionValue);
10073 }
10074 });
10075 select.focus();
10076 }
10077
10078 /**
10079 * @param {HTMLElement} popup
10080 * @param {InputOptionFlattened[]} inputOptions
10081 * @param {SweetAlertOptions} params
10082 */
10083 function populateRadioOptions(popup, inputOptions, params) {
10084 const radio = getDirectChildByClass(popup, swalClasses.radio);
10085 if (!radio) {
10086 return;
10087 }
10088 inputOptions.forEach(inputOption => {
10089 const radioValue = inputOption[0];
10090 const radioLabel = inputOption[1];
10091 const radioInput = document.createElement('input');
10092 const radioLabelElement = document.createElement('label');
10093 radioInput.type = 'radio';
10094 radioInput.name = swalClasses.radio;
10095 radioInput.value = radioValue;
10096 if (isSelected(radioValue, params.inputValue)) {
10097 radioInput.checked = true;
10098 }
10099 const label = document.createElement('span');
10100 setInnerHtml(label, radioLabel);
10101 label.className = swalClasses.label;
10102 radioLabelElement.appendChild(radioInput);
10103 radioLabelElement.appendChild(label);
10104 radio.appendChild(radioLabelElement);
10105 });
10106 const radios = radio.querySelectorAll('input');
10107 if (radios.length) {
10108 radios[0].focus();
10109 }
10110 }
10111
10112 /**
10113 * Converts `inputOptions` into an array of `[value, label]`s
10114 *
10115 * @param {*} inputOptions
10116 * @typedef {string[]} InputOptionFlattened
10117 * @returns {InputOptionFlattened[]}
10118 */
10119 const formatInputOptions = inputOptions => {
10120 const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
10121 return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
10122 };
10123
10124 /**
10125 * @param {string} optionValue
10126 * @param {SweetAlertInputValue} inputValue
10127 * @returns {boolean}
10128 */
10129 const isSelected = (optionValue, inputValue) => Boolean(inputValue) && inputValue != null && inputValue.toString() === optionValue.toString();
10130
10131 /**
10132 * @param {SweetAlert} instance
10133 */
10134 const handleConfirmButtonClick = instance => {
10135 const innerParams = privateProps.innerParams.get(instance);
10136 instance.disableButtons();
10137 if (innerParams.input) {
10138 handleConfirmOrDenyWithInput(instance, 'confirm');
10139 } else {
10140 confirm(instance, true);
10141 }
10142 };
10143
10144 /**
10145 * @param {SweetAlert} instance
10146 */
10147 const handleDenyButtonClick = instance => {
10148 const innerParams = privateProps.innerParams.get(instance);
10149 instance.disableButtons();
10150 if (innerParams.returnInputValueOnDeny) {
10151 handleConfirmOrDenyWithInput(instance, 'deny');
10152 } else {
10153 deny(instance, false);
10154 }
10155 };
10156
10157 /**
10158 * @param {SweetAlert} instance
10159 * @param {(dismiss: DismissReason) => void} dismissWith
10160 */
10161 const handleCancelButtonClick = (instance, dismissWith) => {
10162 instance.disableButtons();
10163 dismissWith(DismissReason.cancel);
10164 };
10165
10166 /**
10167 * @param {SweetAlert} instance
10168 * @param {'confirm' | 'deny'} type
10169 */
10170 const handleConfirmOrDenyWithInput = (instance, type) => {
10171 const innerParams = privateProps.innerParams.get(instance);
10172 if (!innerParams.input) {
10173 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
10174 return;
10175 }
10176 const input = instance.getInput();
10177 const inputValue = getInputValue(instance, innerParams);
10178 if (innerParams.inputValidator) {
10179 handleInputValidator(instance, inputValue, type);
10180 } else if (input && !input.checkValidity()) {
10181 instance.enableButtons();
10182 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
10183 } else if (type === 'deny') {
10184 deny(instance, inputValue);
10185 } else {
10186 confirm(instance, inputValue);
10187 }
10188 };
10189
10190 /**
10191 * @param {SweetAlert} instance
10192 * @param {SweetAlertInputValue} inputValue
10193 * @param {'confirm' | 'deny'} type
10194 */
10195 const handleInputValidator = (instance, inputValue, type) => {
10196 const innerParams = privateProps.innerParams.get(instance);
10197 instance.disableInput();
10198 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
10199 validationPromise.then(validationMessage => {
10200 instance.enableButtons();
10201 instance.enableInput();
10202 if (validationMessage) {
10203 instance.showValidationMessage(validationMessage);
10204 } else if (type === 'deny') {
10205 deny(instance, inputValue);
10206 } else {
10207 confirm(instance, inputValue);
10208 }
10209 });
10210 };
10211
10212 /**
10213 * @param {SweetAlert} instance
10214 * @param {*} value
10215 */
10216 const deny = (instance, value) => {
10217 const innerParams = privateProps.innerParams.get(instance);
10218 if (innerParams.showLoaderOnDeny) {
10219 showLoading(getDenyButton());
10220 }
10221 if (innerParams.preDeny) {
10222 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
10223 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
10224 preDenyPromise.then(preDenyValue => {
10225 if (preDenyValue === false) {
10226 instance.hideLoading();
10227 handleAwaitingPromise(instance);
10228 } else {
10229 instance.close(/** @type SweetAlertResult */{
10230 isDenied: true,
10231 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
10232 });
10233 }
10234 }).catch(error => rejectWith(instance, error));
10235 } else {
10236 instance.close(/** @type SweetAlertResult */{
10237 isDenied: true,
10238 value
10239 });
10240 }
10241 };
10242
10243 /**
10244 * @param {SweetAlert} instance
10245 * @param {*} value
10246 */
10247 const succeedWith = (instance, value) => {
10248 instance.close(/** @type SweetAlertResult */{
10249 isConfirmed: true,
10250 value
10251 });
10252 };
10253
10254 /**
10255 *
10256 * @param {SweetAlert} instance
10257 * @param {string} error
10258 */
10259 const rejectWith = (instance, error) => {
10260 instance.rejectPromise(error);
10261 };
10262
10263 /**
10264 *
10265 * @param {SweetAlert} instance
10266 * @param {*} value
10267 */
10268 const confirm = (instance, value) => {
10269 const innerParams = privateProps.innerParams.get(instance);
10270 if (innerParams.showLoaderOnConfirm) {
10271 showLoading();
10272 }
10273 if (innerParams.preConfirm) {
10274 instance.resetValidationMessage();
10275 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
10276 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
10277 preConfirmPromise.then(preConfirmValue => {
10278 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
10279 instance.hideLoading();
10280 handleAwaitingPromise(instance);
10281 } else {
10282 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
10283 }
10284 }).catch(error => rejectWith(instance, error));
10285 } else {
10286 succeedWith(instance, value);
10287 }
10288 };
10289
10290 /**
10291 * Hides loader and shows back the button which was hidden by .showLoading()
10292 * @this {SweetAlert}
10293 */
10294 function hideLoading() {
10295 // do nothing if popup is closed
10296 const innerParams = privateProps.innerParams.get(this);
10297 if (!innerParams) {
10298 return;
10299 }
10300 const domCache = privateProps.domCache.get(this);
10301 hide(domCache.loader);
10302 if (isToast()) {
10303 if (innerParams.icon) {
10304 show(getIcon());
10305 }
10306 } else {
10307 showRelatedButton(domCache);
10308 }
10309 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
10310 domCache.popup.removeAttribute('aria-busy');
10311 domCache.popup.removeAttribute('data-loading');
10312 this.enableButtons();
10313 }
10314
10315 /**
10316 * @param {DomCache} domCache
10317 */
10318 const showRelatedButton = domCache => {
10319 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
10320 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
10321 if (buttonToReplace.length) {
10322 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
10323 } else if (allButtonsAreHidden()) {
10324 hide(domCache.actions);
10325 }
10326 };
10327
10328 /**
10329 * Gets the input DOM node, this method works with input parameter.
10330 *
10331 * @returns {HTMLInputElement | null}
10332 * @this {SweetAlert}
10333 */
10334 function getInput() {
10335 const innerParams = privateProps.innerParams.get(this);
10336 const domCache = privateProps.domCache.get(this);
10337 if (!domCache) {
10338 return null;
10339 }
10340 return getInput$1(domCache.popup, innerParams.input);
10341 }
10342
10343 /**
10344 * @param {SweetAlert} instance
10345 * @param {string[]} buttons
10346 * @param {boolean} disabled
10347 */
10348 function setButtonsDisabled(instance, buttons, disabled) {
10349 const domCache = privateProps.domCache.get(instance);
10350 buttons.forEach(button => {
10351 domCache[button].disabled = disabled;
10352 });
10353 }
10354
10355 /**
10356 * @param {HTMLInputElement | null} input
10357 * @param {boolean} disabled
10358 */
10359 function setInputDisabled(input, disabled) {
10360 const popup = getPopup();
10361 if (!popup || !input) {
10362 return;
10363 }
10364 if (input.type === 'radio') {
10365 /** @type {NodeListOf<HTMLInputElement>} */
10366 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
10367 radios.forEach(radio => {
10368 radio.disabled = disabled;
10369 });
10370 } else {
10371 input.disabled = disabled;
10372 }
10373 }
10374
10375 /**
10376 * Enable all the buttons
10377 * @this {SweetAlert}
10378 */
10379 function enableButtons() {
10380 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
10381 const focusedElement = privateProps.focusedElement.get(this);
10382 if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
10383 focusedElement.focus();
10384 }
10385 privateProps.focusedElement.delete(this);
10386 }
10387
10388 /**
10389 * Disable all the buttons
10390 * @this {SweetAlert}
10391 */
10392 function disableButtons() {
10393 privateProps.focusedElement.set(this, document.activeElement);
10394 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
10395 }
10396
10397 /**
10398 * Enable the input field
10399 * @this {SweetAlert}
10400 */
10401 function enableInput() {
10402 setInputDisabled(this.getInput(), false);
10403 }
10404
10405 /**
10406 * Disable the input field
10407 * @this {SweetAlert}
10408 */
10409 function disableInput() {
10410 setInputDisabled(this.getInput(), true);
10411 }
10412
10413 /**
10414 * Show block with validation message
10415 *
10416 * @param {string} error
10417 * @this {SweetAlert}
10418 */
10419 function showValidationMessage(error) {
10420 const domCache = privateProps.domCache.get(this);
10421 const params = privateProps.innerParams.get(this);
10422 setInnerHtml(domCache.validationMessage, error);
10423 domCache.validationMessage.className = swalClasses['validation-message'];
10424 if (params.customClass && params.customClass.validationMessage) {
10425 addClass(domCache.validationMessage, params.customClass.validationMessage);
10426 }
10427 show(domCache.validationMessage);
10428 const input = this.getInput();
10429 if (input) {
10430 input.setAttribute('aria-invalid', 'true');
10431 input.setAttribute('aria-describedby', swalClasses['validation-message']);
10432 focusInput(input);
10433 addClass(input, swalClasses.inputerror);
10434 }
10435 }
10436
10437 /**
10438 * Hide block with validation message
10439 *
10440 * @this {SweetAlert}
10441 */
10442 function resetValidationMessage() {
10443 const domCache = privateProps.domCache.get(this);
10444 if (domCache.validationMessage) {
10445 hide(domCache.validationMessage);
10446 }
10447 const input = this.getInput();
10448 if (input) {
10449 input.removeAttribute('aria-invalid');
10450 input.removeAttribute('aria-describedby');
10451 removeClass(input, swalClasses.inputerror);
10452 }
10453 }
10454
10455 const defaultParams = {
10456 title: '',
10457 titleText: '',
10458 text: '',
10459 html: '',
10460 footer: '',
10461 icon: undefined,
10462 iconColor: undefined,
10463 iconHtml: undefined,
10464 template: undefined,
10465 toast: false,
10466 draggable: false,
10467 animation: true,
10468 theme: 'light',
10469 showClass: {
10470 popup: 'swal2-show',
10471 backdrop: 'swal2-backdrop-show',
10472 icon: 'swal2-icon-show'
10473 },
10474 hideClass: {
10475 popup: 'swal2-hide',
10476 backdrop: 'swal2-backdrop-hide',
10477 icon: 'swal2-icon-hide'
10478 },
10479 customClass: {},
10480 target: 'body',
10481 color: undefined,
10482 backdrop: true,
10483 heightAuto: true,
10484 allowOutsideClick: true,
10485 allowEscapeKey: true,
10486 allowEnterKey: true,
10487 stopKeydownPropagation: true,
10488 keydownListenerCapture: false,
10489 showConfirmButton: true,
10490 showDenyButton: false,
10491 showCancelButton: false,
10492 preConfirm: undefined,
10493 preDeny: undefined,
10494 confirmButtonText: 'OK',
10495 confirmButtonAriaLabel: '',
10496 confirmButtonColor: undefined,
10497 denyButtonText: 'No',
10498 denyButtonAriaLabel: '',
10499 denyButtonColor: undefined,
10500 cancelButtonText: 'Cancel',
10501 cancelButtonAriaLabel: '',
10502 cancelButtonColor: undefined,
10503 buttonsStyling: true,
10504 reverseButtons: false,
10505 focusConfirm: true,
10506 focusDeny: false,
10507 focusCancel: false,
10508 returnFocus: true,
10509 showCloseButton: false,
10510 closeButtonHtml: '&times;',
10511 closeButtonAriaLabel: 'Close this dialog',
10512 loaderHtml: '',
10513 showLoaderOnConfirm: false,
10514 showLoaderOnDeny: false,
10515 imageUrl: undefined,
10516 imageWidth: undefined,
10517 imageHeight: undefined,
10518 imageAlt: '',
10519 timer: undefined,
10520 timerProgressBar: false,
10521 width: undefined,
10522 padding: undefined,
10523 background: undefined,
10524 input: undefined,
10525 inputPlaceholder: '',
10526 inputLabel: '',
10527 inputValue: '',
10528 inputOptions: {},
10529 inputAutoFocus: true,
10530 inputAutoTrim: true,
10531 inputAttributes: {},
10532 inputValidator: undefined,
10533 returnInputValueOnDeny: false,
10534 validationMessage: undefined,
10535 grow: false,
10536 position: 'center',
10537 progressSteps: [],
10538 currentProgressStep: undefined,
10539 progressStepsDistance: undefined,
10540 willOpen: undefined,
10541 didOpen: undefined,
10542 didRender: undefined,
10543 willClose: undefined,
10544 didClose: undefined,
10545 didDestroy: undefined,
10546 scrollbarPadding: true,
10547 topLayer: false
10548 };
10549 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'];
10550
10551 /** @type {Record<string, string | undefined>} */
10552 const deprecatedParams = {
10553 allowEnterKey: undefined
10554 };
10555 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
10556
10557 /**
10558 * Is valid parameter
10559 *
10560 * @param {string} paramName
10561 * @returns {boolean}
10562 */
10563 const isValidParameter = paramName => {
10564 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
10565 };
10566
10567 /**
10568 * Is valid parameter for Swal.update() method
10569 *
10570 * @param {string} paramName
10571 * @returns {boolean}
10572 */
10573 const isUpdatableParameter = paramName => {
10574 return updatableParams.indexOf(paramName) !== -1;
10575 };
10576
10577 /**
10578 * Is deprecated parameter
10579 *
10580 * @param {string} paramName
10581 * @returns {string | undefined}
10582 */
10583 const isDeprecatedParameter = paramName => {
10584 return deprecatedParams[paramName];
10585 };
10586
10587 /**
10588 * @param {string} param
10589 */
10590 const checkIfParamIsValid = param => {
10591 if (!isValidParameter(param)) {
10592 warn(`Unknown parameter "${param}"`);
10593 }
10594 };
10595
10596 /**
10597 * @param {string} param
10598 */
10599 const checkIfToastParamIsValid = param => {
10600 if (toastIncompatibleParams.includes(param)) {
10601 warn(`The parameter "${param}" is incompatible with toasts`);
10602 }
10603 };
10604
10605 /**
10606 * @param {string} param
10607 */
10608 const checkIfParamIsDeprecated = param => {
10609 const isDeprecated = isDeprecatedParameter(param);
10610 if (isDeprecated) {
10611 warnAboutDeprecation(param, isDeprecated);
10612 }
10613 };
10614
10615 /**
10616 * Show relevant warnings for given params
10617 *
10618 * @param {SweetAlertOptions} params
10619 */
10620 const showWarningsForParams = params => {
10621 if (params.backdrop === false && params.allowOutsideClick) {
10622 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
10623 }
10624 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)) {
10625 warn(`Invalid theme "${params.theme}"`);
10626 }
10627 for (const param in params) {
10628 checkIfParamIsValid(param);
10629 if (params.toast) {
10630 checkIfToastParamIsValid(param);
10631 }
10632 checkIfParamIsDeprecated(param);
10633 }
10634 };
10635
10636 /**
10637 * Updates popup parameters.
10638 *
10639 * @this {any}
10640 * @param {SweetAlertOptions} params
10641 */
10642 function update(params) {
10643 const container = getContainer();
10644 const popup = getPopup();
10645 const innerParams = privateProps.innerParams.get(this);
10646 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
10647 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.`);
10648 return;
10649 }
10650 const validUpdatableParams = filterValidParams(params);
10651 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
10652 showWarningsForParams(updatedParams);
10653 if (container) {
10654 container.dataset['swal2Theme'] = updatedParams.theme;
10655 }
10656 render(this, updatedParams);
10657 privateProps.innerParams.set(this, updatedParams);
10658 Object.defineProperties(this, {
10659 params: {
10660 value: Object.assign({}, this.params, params),
10661 writable: false,
10662 enumerable: true
10663 }
10664 });
10665 }
10666
10667 /**
10668 * @param {SweetAlertOptions} params
10669 * @returns {SweetAlertOptions}
10670 */
10671 const filterValidParams = params => {
10672 /** @type {Record<string, any>} */
10673 const validUpdatableParams = {};
10674 Object.keys(params).forEach(param => {
10675 if (isUpdatableParameter(param)) {
10676 const typedParams = /** @type {Record<string, any>} */params;
10677 validUpdatableParams[param] = typedParams[param];
10678 } else {
10679 warn(`Invalid parameter to update: ${param}`);
10680 }
10681 });
10682 return validUpdatableParams;
10683 };
10684
10685 /**
10686 * Dispose the current SweetAlert2 instance
10687 * @this {SweetAlert}
10688 */
10689 function _destroy() {
10690 var _globalState$eventEmi;
10691 const domCache = privateProps.domCache.get(this);
10692 const innerParams = privateProps.innerParams.get(this);
10693 if (!innerParams) {
10694 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
10695 return; // This instance has already been destroyed
10696 }
10697
10698 // Check if there is another Swal closing
10699 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
10700 globalState.swalCloseEventFinishedCallback();
10701 delete globalState.swalCloseEventFinishedCallback;
10702 }
10703 if (typeof innerParams.didDestroy === 'function') {
10704 innerParams.didDestroy();
10705 }
10706 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
10707 disposeSwal(this);
10708 }
10709
10710 /**
10711 * @param {SweetAlert} instance
10712 */
10713 const disposeSwal = instance => {
10714 disposeWeakMaps(instance);
10715 // Unset this.params so GC will dispose it (#1569)
10716 // @ts-ignore
10717 delete instance.params;
10718 // Unset globalState props so GC will dispose globalState (#1569)
10719 delete globalState.keydownHandler;
10720 delete globalState.keydownTarget;
10721 // Unset currentInstance
10722 delete globalState.currentInstance;
10723 };
10724
10725 /**
10726 * @param {SweetAlert} instance
10727 */
10728 const disposeWeakMaps = instance => {
10729 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
10730 if (instance.isAwaitingPromise) {
10731 unsetWeakMaps(privateProps, instance);
10732 instance.isAwaitingPromise = true;
10733 } else {
10734 unsetWeakMaps(privateMethods, instance);
10735 unsetWeakMaps(privateProps, instance);
10736
10737 // @ts-ignore
10738 delete instance.isAwaitingPromise;
10739 // Unset instance methods
10740 // @ts-ignore
10741 delete instance.disableButtons;
10742 // @ts-ignore
10743 delete instance.enableButtons;
10744 // @ts-ignore
10745 delete instance.getInput;
10746 // @ts-ignore
10747 delete instance.disableInput;
10748 // @ts-ignore
10749 delete instance.enableInput;
10750 // @ts-ignore
10751 delete instance.hideLoading;
10752 // @ts-ignore
10753 delete instance.disableLoading;
10754 // @ts-ignore
10755 delete instance.showValidationMessage;
10756 // @ts-ignore
10757 delete instance.resetValidationMessage;
10758 // @ts-ignore
10759 delete instance.close;
10760 // @ts-ignore
10761 delete instance.closePopup;
10762 // @ts-ignore
10763 delete instance.closeModal;
10764 // @ts-ignore
10765 delete instance.closeToast;
10766 // @ts-ignore
10767 delete instance.rejectPromise;
10768 // @ts-ignore
10769 delete instance.update;
10770 // @ts-ignore
10771 delete instance._destroy;
10772 }
10773 };
10774
10775 /**
10776 * @param {Record<string, WeakMap<any, any>>} obj
10777 * @param {SweetAlert} instance
10778 */
10779 const unsetWeakMaps = (obj, instance) => {
10780 for (const i in obj) {
10781 obj[i].delete(instance);
10782 }
10783 };
10784
10785 var instanceMethods = /*#__PURE__*/Object.freeze({
10786 __proto__: null,
10787 _destroy: _destroy,
10788 close: close,
10789 closeModal: close,
10790 closePopup: close,
10791 closeToast: close,
10792 disableButtons: disableButtons,
10793 disableInput: disableInput,
10794 disableLoading: hideLoading,
10795 enableButtons: enableButtons,
10796 enableInput: enableInput,
10797 getInput: getInput,
10798 handleAwaitingPromise: handleAwaitingPromise,
10799 hideLoading: hideLoading,
10800 rejectPromise: rejectPromise,
10801 resetValidationMessage: resetValidationMessage,
10802 showValidationMessage: showValidationMessage,
10803 update: update
10804 });
10805
10806 /**
10807 * @param {SweetAlertOptions} innerParams
10808 * @param {DomCache} domCache
10809 * @param {(dismiss: DismissReason) => void} dismissWith
10810 */
10811 const handlePopupClick = (innerParams, domCache, dismissWith) => {
10812 if (innerParams.toast) {
10813 handleToastClick(innerParams, domCache, dismissWith);
10814 } else {
10815 // Ignore click events that had mousedown on the popup but mouseup on the container
10816 // This can happen when the user drags a slider
10817 handleModalMousedown(domCache);
10818
10819 // Ignore click events that had mousedown on the container but mouseup on the popup
10820 handleContainerMousedown(domCache);
10821 handleModalClick(innerParams, domCache, dismissWith);
10822 }
10823 };
10824
10825 /**
10826 * @param {SweetAlertOptions} innerParams
10827 * @param {DomCache} domCache
10828 * @param {(dismiss: DismissReason) => void} dismissWith
10829 */
10830 const handleToastClick = (innerParams, domCache, dismissWith) => {
10831 // Closing toast by internal click
10832 domCache.popup.onclick = () => {
10833 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
10834 return;
10835 }
10836 dismissWith(DismissReason.close);
10837 };
10838 };
10839
10840 /**
10841 * @param {SweetAlertOptions} innerParams
10842 * @returns {boolean}
10843 */
10844 const isAnyButtonShown = innerParams => {
10845 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
10846 };
10847 let ignoreOutsideClick = false;
10848
10849 /**
10850 * @param {DomCache} domCache
10851 */
10852 const handleModalMousedown = domCache => {
10853 domCache.popup.onmousedown = () => {
10854 domCache.container.onmouseup = function (e) {
10855 domCache.container.onmouseup = () => {};
10856 // We only check if the mouseup target is the container because usually it doesn't
10857 // have any other direct children aside of the popup
10858 if (e.target === domCache.container) {
10859 ignoreOutsideClick = true;
10860 }
10861 };
10862 };
10863 };
10864
10865 /**
10866 * @param {DomCache} domCache
10867 */
10868 const handleContainerMousedown = domCache => {
10869 domCache.container.onmousedown = e => {
10870 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
10871 if (e.target === domCache.container) {
10872 e.preventDefault();
10873 }
10874 domCache.popup.onmouseup = function (e) {
10875 domCache.popup.onmouseup = () => {};
10876 // We also need to check if the mouseup target is a child of the popup
10877 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
10878 ignoreOutsideClick = true;
10879 }
10880 };
10881 };
10882 };
10883
10884 /**
10885 * @param {SweetAlertOptions} innerParams
10886 * @param {DomCache} domCache
10887 * @param {(dismiss: DismissReason) => void} dismissWith
10888 */
10889 const handleModalClick = (innerParams, domCache, dismissWith) => {
10890 domCache.container.onclick = e => {
10891 if (ignoreOutsideClick) {
10892 ignoreOutsideClick = false;
10893 return;
10894 }
10895 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
10896 dismissWith(DismissReason.backdrop);
10897 }
10898 };
10899 };
10900
10901 /**
10902 * @param {unknown} elem
10903 * @returns {boolean}
10904 */
10905 const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
10906
10907 /**
10908 * @param {unknown} elem
10909 * @returns {boolean}
10910 */
10911 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
10912
10913 /**
10914 * @param {ReadonlyArray<unknown>} args
10915 * @returns {SweetAlertOptions}
10916 */
10917 const argsToParams = args => {
10918 /** @type {Record<string, unknown>} */
10919 const params = {};
10920 if (typeof args[0] === 'object' && !isElement(args[0])) {
10921 Object.assign(params, args[0]);
10922 } else {
10923 ['title', 'html', 'icon'].forEach((name, index) => {
10924 const arg = args[index];
10925 if (typeof arg === 'string' || isElement(arg)) {
10926 params[name] = arg;
10927 } else if (arg !== undefined) {
10928 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
10929 }
10930 });
10931 }
10932 return /** @type {SweetAlertOptions} */params;
10933 };
10934
10935 /**
10936 * Main method to create a new SweetAlert2 popup
10937 *
10938 * @this {new (...args: any[]) => any}
10939 * @param {...SweetAlertOptions} args
10940 * @returns {Promise<SweetAlertResult>}
10941 */
10942 function fire(...args) {
10943 return new this(...args);
10944 }
10945
10946 /**
10947 * Returns an extended version of `Swal` containing `params` as defaults.
10948 * Useful for reusing Swal configuration.
10949 *
10950 * For example:
10951 *
10952 * Before:
10953 * const textPromptOptions = { input: 'text', showCancelButton: true }
10954 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
10955 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
10956 *
10957 * After:
10958 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
10959 * const {value: firstName} = await TextPrompt('What is your first name?')
10960 * const {value: lastName} = await TextPrompt('What is your last name?')
10961 *
10962 * @param {SweetAlertOptions} mixinParams
10963 * @returns {SweetAlert}
10964 * @this {typeof import('../SweetAlert.js').SweetAlert}
10965 */
10966 function mixin(mixinParams) {
10967 // @ts-ignore: 'this' refers to the SweetAlert constructor
10968 class MixinSwal extends this {
10969 /**
10970 * @param {any} params
10971 * @param {any} priorityMixinParams
10972 */
10973 _main(params, priorityMixinParams) {
10974 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
10975 }
10976 }
10977 // @ts-ignore
10978 return MixinSwal;
10979 }
10980
10981 /**
10982 * If `timer` parameter is set, returns number of milliseconds of timer remained.
10983 * Otherwise, returns undefined.
10984 *
10985 * @returns {number | undefined}
10986 */
10987 const getTimerLeft = () => {
10988 return globalState.timeout && globalState.timeout.getTimerLeft();
10989 };
10990
10991 /**
10992 * Stop timer. Returns number of milliseconds of timer remained.
10993 * If `timer` parameter isn't set, returns undefined.
10994 *
10995 * @returns {number | undefined}
10996 */
10997 const stopTimer = () => {
10998 if (globalState.timeout) {
10999 stopTimerProgressBar();
11000 return globalState.timeout.stop();
11001 }
11002 };
11003
11004 /**
11005 * Resume timer. Returns number of milliseconds of timer remained.
11006 * If `timer` parameter isn't set, returns undefined.
11007 *
11008 * @returns {number | undefined}
11009 */
11010 const resumeTimer = () => {
11011 if (globalState.timeout) {
11012 const remaining = globalState.timeout.start();
11013 animateTimerProgressBar(remaining);
11014 return remaining;
11015 }
11016 };
11017
11018 /**
11019 * Resume timer. Returns number of milliseconds of timer remained.
11020 * If `timer` parameter isn't set, returns undefined.
11021 *
11022 * @returns {number | undefined}
11023 */
11024 const toggleTimer = () => {
11025 const timer = globalState.timeout;
11026 return timer && (timer.running ? stopTimer() : resumeTimer());
11027 };
11028
11029 /**
11030 * Increase timer. Returns number of milliseconds of an updated timer.
11031 * If `timer` parameter isn't set, returns undefined.
11032 *
11033 * @param {number} ms
11034 * @returns {number | undefined}
11035 */
11036 const increaseTimer = ms => {
11037 if (globalState.timeout) {
11038 const remaining = globalState.timeout.increase(ms);
11039 animateTimerProgressBar(remaining, true);
11040 return remaining;
11041 }
11042 };
11043
11044 /**
11045 * Check if timer is running. Returns true if timer is running
11046 * or false if timer is paused or stopped.
11047 * If `timer` parameter isn't set, returns undefined
11048 *
11049 * @returns {boolean}
11050 */
11051 const isTimerRunning = () => {
11052 return Boolean(globalState.timeout && globalState.timeout.isRunning());
11053 };
11054
11055 let bodyClickListenerAdded = false;
11056 /** @type {Record<string, any>} */
11057 const clickHandlers = {};
11058
11059 /**
11060 * @this {any}
11061 * @param {string} attr
11062 */
11063 function bindClickHandler(attr = 'data-swal-template') {
11064 clickHandlers[attr] = this;
11065 if (!bodyClickListenerAdded) {
11066 document.body.addEventListener('click', bodyClickListener);
11067 bodyClickListenerAdded = true;
11068 }
11069 }
11070
11071 /**
11072 * @param {MouseEvent} event
11073 */
11074 const bodyClickListener = event => {
11075 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
11076 for (const attr in clickHandlers) {
11077 const template = el.getAttribute && el.getAttribute(attr);
11078 if (template) {
11079 clickHandlers[attr].fire({
11080 template
11081 });
11082 return;
11083 }
11084 }
11085 }
11086 };
11087
11088 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
11089
11090 class EventEmitter {
11091 constructor() {
11092 /** @type {Events} */
11093 this.events = {};
11094 }
11095
11096 /**
11097 * @param {string} eventName
11098 * @returns {EventHandlers}
11099 */
11100 _getHandlersByEventName(eventName) {
11101 if (typeof this.events[eventName] === 'undefined') {
11102 // not Set because we need to keep the FIFO order
11103 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
11104 this.events[eventName] = [];
11105 }
11106 return this.events[eventName];
11107 }
11108
11109 /**
11110 * @param {string} eventName
11111 * @param {EventHandler} eventHandler
11112 */
11113 on(eventName, eventHandler) {
11114 const currentHandlers = this._getHandlersByEventName(eventName);
11115 if (!currentHandlers.includes(eventHandler)) {
11116 currentHandlers.push(eventHandler);
11117 }
11118 }
11119
11120 /**
11121 * @param {string} eventName
11122 * @param {EventHandler} eventHandler
11123 */
11124 once(eventName, eventHandler) {
11125 /**
11126 * @param {...any} args
11127 */
11128 const onceFn = (...args) => {
11129 this.removeListener(eventName, onceFn);
11130 // @ts-ignore
11131 eventHandler.apply(this, args);
11132 };
11133 this.on(eventName, onceFn);
11134 }
11135
11136 /**
11137 * @param {string} eventName
11138 * @param {...any} args
11139 */
11140 emit(eventName, ...args) {
11141 this._getHandlersByEventName(eventName).forEach(
11142 /**
11143 * @param {EventHandler} eventHandler
11144 */
11145 eventHandler => {
11146 try {
11147 // @ts-ignore
11148 eventHandler.apply(this, args);
11149 } catch (error) {
11150 console.error(error);
11151 }
11152 });
11153 }
11154
11155 /**
11156 * @param {string} eventName
11157 * @param {EventHandler} eventHandler
11158 */
11159 removeListener(eventName, eventHandler) {
11160 const currentHandlers = this._getHandlersByEventName(eventName);
11161 const index = currentHandlers.indexOf(eventHandler);
11162 if (index > -1) {
11163 currentHandlers.splice(index, 1);
11164 }
11165 }
11166
11167 /**
11168 * @param {string} eventName
11169 */
11170 removeAllListeners(eventName) {
11171 if (this.events[eventName] !== undefined) {
11172 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
11173 this.events[eventName].length = 0;
11174 }
11175 }
11176 reset() {
11177 this.events = {};
11178 }
11179 }
11180
11181 globalState.eventEmitter = new EventEmitter();
11182
11183 /**
11184 * @param {string} eventName
11185 * @param {EventHandler} eventHandler
11186 */
11187 const on = (eventName, eventHandler) => {
11188 if (globalState.eventEmitter) {
11189 globalState.eventEmitter.on(eventName, eventHandler);
11190 }
11191 };
11192
11193 /**
11194 * @param {string} eventName
11195 * @param {EventHandler} eventHandler
11196 */
11197 const once = (eventName, eventHandler) => {
11198 if (globalState.eventEmitter) {
11199 globalState.eventEmitter.once(eventName, eventHandler);
11200 }
11201 };
11202
11203 /**
11204 * @param {string} [eventName]
11205 * @param {EventHandler} [eventHandler]
11206 */
11207 const off = (eventName, eventHandler) => {
11208 if (!globalState.eventEmitter) {
11209 return;
11210 }
11211
11212 // Remove all handlers for all events
11213 if (!eventName) {
11214 globalState.eventEmitter.reset();
11215 return;
11216 }
11217 if (eventHandler) {
11218 // Remove a specific handler
11219 globalState.eventEmitter.removeListener(eventName, eventHandler);
11220 } else {
11221 // Remove all handlers for a specific event
11222 globalState.eventEmitter.removeAllListeners(eventName);
11223 }
11224 };
11225
11226 var staticMethods = /*#__PURE__*/Object.freeze({
11227 __proto__: null,
11228 argsToParams: argsToParams,
11229 bindClickHandler: bindClickHandler,
11230 clickCancel: clickCancel,
11231 clickConfirm: clickConfirm,
11232 clickDeny: clickDeny,
11233 enableLoading: showLoading,
11234 fire: fire,
11235 getActions: getActions,
11236 getCancelButton: getCancelButton,
11237 getCloseButton: getCloseButton,
11238 getConfirmButton: getConfirmButton,
11239 getContainer: getContainer,
11240 getDenyButton: getDenyButton,
11241 getFocusableElements: getFocusableElements,
11242 getFooter: getFooter,
11243 getHtmlContainer: getHtmlContainer,
11244 getIcon: getIcon,
11245 getIconContent: getIconContent,
11246 getImage: getImage,
11247 getInputLabel: getInputLabel,
11248 getLoader: getLoader,
11249 getPopup: getPopup,
11250 getProgressSteps: getProgressSteps,
11251 getTimerLeft: getTimerLeft,
11252 getTimerProgressBar: getTimerProgressBar,
11253 getTitle: getTitle,
11254 getValidationMessage: getValidationMessage,
11255 increaseTimer: increaseTimer,
11256 isDeprecatedParameter: isDeprecatedParameter,
11257 isLoading: isLoading,
11258 isTimerRunning: isTimerRunning,
11259 isUpdatableParameter: isUpdatableParameter,
11260 isValidParameter: isValidParameter,
11261 isVisible: isVisible,
11262 mixin: mixin,
11263 off: off,
11264 on: on,
11265 once: once,
11266 resumeTimer: resumeTimer,
11267 showLoading: showLoading,
11268 stopTimer: stopTimer,
11269 toggleTimer: toggleTimer
11270 });
11271
11272 class Timer {
11273 /**
11274 * @param {() => void} callback
11275 * @param {number} delay
11276 */
11277 constructor(callback, delay) {
11278 this.callback = callback;
11279 this.remaining = delay;
11280 this.running = false;
11281 this.start();
11282 }
11283
11284 /**
11285 * @returns {number}
11286 */
11287 start() {
11288 if (!this.running) {
11289 this.running = true;
11290 this.started = new Date();
11291 this.id = setTimeout(this.callback, this.remaining);
11292 }
11293 return this.remaining;
11294 }
11295
11296 /**
11297 * @returns {number}
11298 */
11299 stop() {
11300 if (this.started && this.running) {
11301 this.running = false;
11302 clearTimeout(this.id);
11303 this.remaining -= new Date().getTime() - this.started.getTime();
11304 }
11305 return this.remaining;
11306 }
11307
11308 /**
11309 * @param {number} n
11310 * @returns {number}
11311 */
11312 increase(n) {
11313 const running = this.running;
11314 if (running) {
11315 this.stop();
11316 }
11317 this.remaining += n;
11318 if (running) {
11319 this.start();
11320 }
11321 return this.remaining;
11322 }
11323
11324 /**
11325 * @returns {number}
11326 */
11327 getTimerLeft() {
11328 if (this.running) {
11329 this.stop();
11330 this.start();
11331 }
11332 return this.remaining;
11333 }
11334
11335 /**
11336 * @returns {boolean}
11337 */
11338 isRunning() {
11339 return this.running;
11340 }
11341 }
11342
11343 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
11344
11345 /**
11346 * @param {SweetAlertOptions} params
11347 * @returns {SweetAlertOptions}
11348 */
11349 const getTemplateParams = params => {
11350 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
11351 if (!template) {
11352 return {};
11353 }
11354 /** @type {DocumentFragment} */
11355 const templateContent = template.content;
11356 showWarningsForElements(templateContent);
11357 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
11358 return result;
11359 };
11360
11361 /**
11362 * @param {DocumentFragment} templateContent
11363 * @returns {Record<string, string | boolean | number>}
11364 */
11365 const getSwalParams = templateContent => {
11366 /** @type {Record<string, string | boolean | number>} */
11367 const result = {};
11368 /** @type {HTMLElement[]} */
11369 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
11370 swalParams.forEach(param => {
11371 showWarningsForAttributes(param, ['name', 'value']);
11372 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
11373 const value = param.getAttribute('value');
11374 if (!paramName || !value) {
11375 return;
11376 }
11377 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
11378 result[paramName] = value !== 'false';
11379 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
11380 result[paramName] = JSON.parse(value);
11381 } else {
11382 result[paramName] = value;
11383 }
11384 });
11385 return result;
11386 };
11387
11388 /**
11389 * @param {DocumentFragment} templateContent
11390 * @returns {Record<string, () => void>}
11391 */
11392 const getSwalFunctionParams = templateContent => {
11393 /** @type {Record<string, () => void>} */
11394 const result = {};
11395 /** @type {HTMLElement[]} */
11396 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
11397 swalFunctions.forEach(param => {
11398 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
11399 const value = param.getAttribute('value');
11400 if (!paramName || !value) {
11401 return;
11402 }
11403 result[paramName] = new Function(`return ${value}`)();
11404 });
11405 return result;
11406 };
11407
11408 /**
11409 * @param {DocumentFragment} templateContent
11410 * @returns {Record<string, string | boolean>}
11411 */
11412 const getSwalButtons = templateContent => {
11413 /** @type {Record<string, string | boolean>} */
11414 const result = {};
11415 /** @type {HTMLElement[]} */
11416 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
11417 swalButtons.forEach(button => {
11418 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
11419 const type = button.getAttribute('type');
11420 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
11421 return;
11422 }
11423 result[`${type}ButtonText`] = button.innerHTML;
11424 result[`show${capitalizeFirstLetter(type)}Button`] = true;
11425 const color = button.getAttribute('color');
11426 if (color !== null) {
11427 result[`${type}ButtonColor`] = color;
11428 }
11429 const ariaLabel = button.getAttribute('aria-label');
11430 if (ariaLabel !== null) {
11431 result[`${type}ButtonAriaLabel`] = ariaLabel;
11432 }
11433 });
11434 return result;
11435 };
11436
11437 /**
11438 * @param {DocumentFragment} templateContent
11439 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
11440 */
11441 const getSwalImage = templateContent => {
11442 const result = {};
11443 /** @type {HTMLElement | null} */
11444 const image = templateContent.querySelector('swal-image');
11445 if (image) {
11446 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
11447 // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
11448 const src = image.getAttribute('src');
11449 if (src !== null) result.imageUrl = src || undefined;
11450 const width = image.getAttribute('width');
11451 if (width !== null) result.imageWidth = width || undefined;
11452 const height = image.getAttribute('height');
11453 if (height !== null) result.imageHeight = height || undefined;
11454 const alt = image.getAttribute('alt');
11455 if (alt !== null) result.imageAlt = alt || undefined;
11456 }
11457 return result;
11458 };
11459
11460 /**
11461 * @param {DocumentFragment} templateContent
11462 * @returns {object}
11463 */
11464 const getSwalIcon = templateContent => {
11465 const result = {};
11466 /** @type {HTMLElement | null} */
11467 const icon = templateContent.querySelector('swal-icon');
11468 if (icon) {
11469 showWarningsForAttributes(icon, ['type', 'color']);
11470 if (icon.hasAttribute('type')) {
11471 result.icon = icon.getAttribute('type');
11472 }
11473 if (icon.hasAttribute('color')) {
11474 result.iconColor = icon.getAttribute('color');
11475 }
11476 result.iconHtml = icon.innerHTML;
11477 }
11478 return result;
11479 };
11480
11481 /**
11482 * @param {DocumentFragment} templateContent
11483 * @returns {object}
11484 */
11485 const getSwalInput = templateContent => {
11486 /** @type {Record<string, any>} */
11487 const result = {};
11488 /** @type {HTMLElement | null} */
11489 const input = templateContent.querySelector('swal-input');
11490 if (input) {
11491 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
11492 result.input = input.getAttribute('type') || 'text';
11493 if (input.hasAttribute('label')) {
11494 result.inputLabel = input.getAttribute('label');
11495 }
11496 if (input.hasAttribute('placeholder')) {
11497 result.inputPlaceholder = input.getAttribute('placeholder');
11498 }
11499 if (input.hasAttribute('value')) {
11500 result.inputValue = input.getAttribute('value');
11501 }
11502 }
11503 /** @type {HTMLElement[]} */
11504 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
11505 if (inputOptions.length) {
11506 result.inputOptions = {};
11507 inputOptions.forEach(option => {
11508 showWarningsForAttributes(option, ['value']);
11509 const optionValue = option.getAttribute('value');
11510 if (!optionValue) {
11511 return;
11512 }
11513 const optionName = option.innerHTML;
11514 result.inputOptions[optionValue] = optionName;
11515 });
11516 }
11517 return result;
11518 };
11519
11520 /**
11521 * @param {DocumentFragment} templateContent
11522 * @param {string[]} paramNames
11523 * @returns {Record<string, string>}
11524 */
11525 const getSwalStringParams = (templateContent, paramNames) => {
11526 /** @type {Record<string, string>} */
11527 const result = {};
11528 for (const i in paramNames) {
11529 const paramName = paramNames[i];
11530 /** @type {HTMLElement | null} */
11531 const tag = templateContent.querySelector(paramName);
11532 if (tag) {
11533 showWarningsForAttributes(tag, []);
11534 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
11535 }
11536 }
11537 return result;
11538 };
11539
11540 /**
11541 * @param {DocumentFragment} templateContent
11542 */
11543 const showWarningsForElements = templateContent => {
11544 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
11545 Array.from(templateContent.children).forEach(el => {
11546 const tagName = el.tagName.toLowerCase();
11547 if (!allowedElements.includes(tagName)) {
11548 warn(`Unrecognized element <${tagName}>`);
11549 }
11550 });
11551 };
11552
11553 /**
11554 * @param {HTMLElement} el
11555 * @param {string[]} allowedAttributes
11556 */
11557 const showWarningsForAttributes = (el, allowedAttributes) => {
11558 Array.from(el.attributes).forEach(attribute => {
11559 if (allowedAttributes.indexOf(attribute.name) === -1) {
11560 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.'}`]);
11561 }
11562 });
11563 };
11564
11565 const SHOW_CLASS_TIMEOUT = 10;
11566
11567 /**
11568 * Open popup, add necessary classes and styles, fix scrollbar
11569 *
11570 * @param {SweetAlertOptions} params
11571 */
11572 const openPopup = params => {
11573 var _globalState$eventEmi, _globalState$eventEmi2;
11574 const container = getContainer();
11575 const popup = getPopup();
11576 if (!container || !popup) {
11577 return;
11578 }
11579 if (typeof params.willOpen === 'function') {
11580 params.willOpen(popup);
11581 }
11582 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
11583 const bodyStyles = window.getComputedStyle(document.body);
11584 const initialBodyOverflow = bodyStyles.overflowY;
11585 addClasses(container, popup, params);
11586
11587 // scrolling is 'hidden' until animation is done, after that 'auto'
11588 setTimeout(() => {
11589 setScrollingVisibility(container, popup);
11590 }, SHOW_CLASS_TIMEOUT);
11591 if (isModal()) {
11592 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
11593 setAriaHidden();
11594 }
11595
11596 // https://github.com/sweetalert2/sweetalert2/issues/2923
11597 if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
11598 // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
11599 container.style.pointerEvents = 'auto';
11600 }
11601 if (!isToast() && !globalState.previousActiveElement) {
11602 globalState.previousActiveElement = document.activeElement;
11603 }
11604 if (typeof params.didOpen === 'function') {
11605 const didOpen = params.didOpen;
11606 setTimeout(() => didOpen(popup));
11607 }
11608 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
11609 };
11610
11611 /**
11612 * @param {Event} event
11613 */
11614 const swalOpenAnimationFinished = event => {
11615 const popup = getPopup();
11616 if (!popup || event.target !== popup) {
11617 return;
11618 }
11619 const container = getContainer();
11620 if (!container) {
11621 return;
11622 }
11623 popup.removeEventListener('animationend', swalOpenAnimationFinished);
11624 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
11625 container.style.overflowY = 'auto';
11626
11627 // no-transition is added in init() in case one swal is opened right after another
11628 removeClass(container, swalClasses['no-transition']);
11629 };
11630
11631 /**
11632 * @param {HTMLElement} container
11633 * @param {HTMLElement} popup
11634 */
11635 const setScrollingVisibility = (container, popup) => {
11636 if (hasCssAnimation(popup)) {
11637 container.style.overflowY = 'hidden';
11638 popup.addEventListener('animationend', swalOpenAnimationFinished);
11639 popup.addEventListener('transitionend', swalOpenAnimationFinished);
11640 } else {
11641 container.style.overflowY = 'auto';
11642 }
11643 };
11644
11645 /**
11646 * @param {HTMLElement} container
11647 * @param {boolean} scrollbarPadding
11648 * @param {string} initialBodyOverflow
11649 */
11650 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
11651 iOSfix();
11652 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
11653 replaceScrollbarWithPadding(initialBodyOverflow);
11654 }
11655
11656 // sweetalert2/issues/1247
11657 setTimeout(() => {
11658 container.scrollTop = 0;
11659 });
11660 };
11661
11662 /**
11663 * @param {HTMLElement} container
11664 * @param {HTMLElement} popup
11665 * @param {SweetAlertOptions} params
11666 */
11667 const addClasses = (container, popup, params) => {
11668 var _params$showClass;
11669 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
11670 addClass(container, params.showClass.backdrop);
11671 }
11672 if (params.animation) {
11673 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
11674 popup.style.setProperty('opacity', '0', 'important');
11675 show(popup, 'grid');
11676 setTimeout(() => {
11677 var _params$showClass2;
11678 // Animate popup right after showing it
11679 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
11680 addClass(popup, params.showClass.popup);
11681 }
11682 // and remove the opacity workaround
11683 popup.style.removeProperty('opacity');
11684 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
11685 } else {
11686 show(popup, 'grid');
11687 }
11688 addClass([document.documentElement, document.body], swalClasses.shown);
11689 if (params.heightAuto && params.backdrop && !params.toast) {
11690 addClass([document.documentElement, document.body], swalClasses['height-auto']);
11691 }
11692 };
11693
11694 var defaultInputValidators = {
11695 /**
11696 * @param {string} string
11697 * @param {string} [validationMessage]
11698 * @returns {Promise<string | void>}
11699 */
11700 email: (string, validationMessage) => {
11701 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
11702 },
11703 /**
11704 * @param {string} string
11705 * @param {string} [validationMessage]
11706 * @returns {Promise<string | void>}
11707 */
11708 url: (string, validationMessage) => {
11709 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
11710 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');
11711 }
11712 };
11713
11714 /**
11715 * @param {SweetAlertOptions} params
11716 */
11717 function setDefaultInputValidators(params) {
11718 // Use default `inputValidator` for supported input types if not provided
11719 if (params.inputValidator) {
11720 return;
11721 }
11722 if (params.input === 'email') {
11723 params.inputValidator = defaultInputValidators['email'];
11724 }
11725 if (params.input === 'url') {
11726 params.inputValidator = defaultInputValidators['url'];
11727 }
11728 }
11729
11730 /**
11731 * @param {SweetAlertOptions} params
11732 */
11733 function validateCustomTargetElement(params) {
11734 // Determine if the custom target element is valid
11735 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
11736 warn('Target parameter is not valid, defaulting to "body"');
11737 params.target = 'body';
11738 }
11739 }
11740
11741 /**
11742 * Set type, text and actions on popup
11743 *
11744 * @param {SweetAlertOptions} params
11745 */
11746 function setParameters(params) {
11747 setDefaultInputValidators(params);
11748
11749 // showLoaderOnConfirm && preConfirm
11750 if (params.showLoaderOnConfirm && !params.preConfirm) {
11751 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');
11752 }
11753 validateCustomTargetElement(params);
11754
11755 // Replace newlines with <br> in title
11756 if (typeof params.title === 'string') {
11757 params.title = params.title.split('\n').join('<br />');
11758 }
11759 init(params);
11760 }
11761
11762 /** @type {SweetAlert} */
11763 let currentInstance;
11764 var _promise = /*#__PURE__*/new WeakMap();
11765 class SweetAlert {
11766 /**
11767 * @param {...(SweetAlertOptions | string)} args
11768 * @this {SweetAlert}
11769 */
11770 constructor(...args) {
11771 /**
11772 * @type {Promise<SweetAlertResult>}
11773 */
11774 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
11775 Promise.resolve({
11776 isConfirmed: false,
11777 isDenied: false,
11778 isDismissed: true
11779 }));
11780 // Prevent run in Node env
11781 if (typeof window === 'undefined') {
11782 return;
11783 }
11784 currentInstance = this;
11785
11786 // @ts-ignore
11787 const outerParams = Object.freeze(this.constructor.argsToParams(args));
11788
11789 /** @type {Readonly<SweetAlertOptions>} */
11790 this.params = outerParams;
11791
11792 /** @type {boolean} */
11793 this.isAwaitingPromise = false;
11794 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
11795 }
11796
11797 /**
11798 * @param {any} userParams
11799 * @param {any} mixinParams
11800 */
11801 _main(userParams, mixinParams = {}) {
11802 showWarningsForParams(Object.assign({}, mixinParams, userParams));
11803 if (globalState.currentInstance) {
11804 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
11805 const {
11806 isAwaitingPromise
11807 } = globalState.currentInstance;
11808 globalState.currentInstance._destroy();
11809 if (!isAwaitingPromise) {
11810 swalPromiseResolve({
11811 isDismissed: true
11812 });
11813 }
11814 if (isModal()) {
11815 unsetAriaHidden();
11816 }
11817 }
11818 globalState.currentInstance = currentInstance;
11819 const innerParams = prepareParams(userParams, mixinParams);
11820 setParameters(innerParams);
11821 Object.freeze(innerParams);
11822
11823 // clear the previous timer
11824 if (globalState.timeout) {
11825 globalState.timeout.stop();
11826 delete globalState.timeout;
11827 }
11828
11829 // clear the restore focus timeout
11830 clearTimeout(globalState.restoreFocusTimeout);
11831 const domCache = populateDomCache(currentInstance);
11832 render(currentInstance, innerParams);
11833 privateProps.innerParams.set(currentInstance, innerParams);
11834 return swalPromise(currentInstance, domCache, innerParams);
11835 }
11836
11837 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
11838 /**
11839 * @param {any} onFulfilled
11840 */
11841 // oxlint-disable-next-line unicorn/no-thenable
11842 then(onFulfilled) {
11843 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
11844 }
11845
11846 /**
11847 * @param {any} onFinally
11848 */
11849 finally(onFinally) {
11850 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
11851 }
11852 }
11853
11854 /**
11855 * @param {SweetAlert} instance
11856 * @param {DomCache} domCache
11857 * @param {SweetAlertOptions} innerParams
11858 * @returns {Promise<SweetAlertResult>}
11859 */
11860 const swalPromise = (instance, domCache, innerParams) => {
11861 return new Promise((resolve, reject) => {
11862 // functions to handle all closings/dismissals
11863 /**
11864 * @param {DismissReason} dismiss
11865 */
11866 const dismissWith = dismiss => {
11867 instance.close({
11868 isDismissed: true,
11869 dismiss,
11870 isConfirmed: false,
11871 isDenied: false
11872 });
11873 };
11874 privateMethods.swalPromiseResolve.set(instance, resolve);
11875 privateMethods.swalPromiseReject.set(instance, reject);
11876 domCache.confirmButton.onclick = () => {
11877 handleConfirmButtonClick(instance);
11878 };
11879 domCache.denyButton.onclick = () => {
11880 handleDenyButtonClick(instance);
11881 };
11882 domCache.cancelButton.onclick = () => {
11883 handleCancelButtonClick(instance, dismissWith);
11884 };
11885 domCache.closeButton.onclick = () => {
11886 dismissWith(DismissReason.close);
11887 };
11888 handlePopupClick(innerParams, domCache, dismissWith);
11889 addKeydownHandler(globalState, innerParams, dismissWith);
11890 handleInputOptionsAndValue(instance, innerParams);
11891 openPopup(innerParams);
11892 setupTimer(globalState, innerParams, dismissWith);
11893 initFocus(domCache, innerParams);
11894
11895 // Scroll container to top on open (#1247, #1946)
11896 setTimeout(() => {
11897 domCache.container.scrollTop = 0;
11898 });
11899 });
11900 };
11901
11902 /**
11903 * @param {SweetAlertOptions} userParams
11904 * @param {SweetAlertOptions} mixinParams
11905 * @returns {SweetAlertOptions}
11906 */
11907 const prepareParams = (userParams, mixinParams) => {
11908 const templateParams = getTemplateParams(userParams);
11909 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
11910 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
11911 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
11912 if (params.animation === false) {
11913 params.showClass = {
11914 backdrop: 'swal2-noanimation'
11915 };
11916 params.hideClass = {};
11917 }
11918 return params;
11919 };
11920
11921 /**
11922 * @param {SweetAlert} instance
11923 * @returns {DomCache}
11924 */
11925 const populateDomCache = instance => {
11926 const domCache = /** @type {DomCache} */{
11927 popup: (/** @type {HTMLElement} */getPopup()),
11928 container: (/** @type {HTMLElement} */getContainer()),
11929 actions: (/** @type {HTMLElement} */getActions()),
11930 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
11931 denyButton: (/** @type {HTMLElement} */getDenyButton()),
11932 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
11933 loader: (/** @type {HTMLElement} */getLoader()),
11934 closeButton: (/** @type {HTMLElement} */getCloseButton()),
11935 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
11936 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
11937 };
11938 privateProps.domCache.set(instance, domCache);
11939 return domCache;
11940 };
11941
11942 /**
11943 * @param {GlobalState} globalState
11944 * @param {SweetAlertOptions} innerParams
11945 * @param {(dismiss: DismissReason) => void} dismissWith
11946 */
11947 const setupTimer = (globalState, innerParams, dismissWith) => {
11948 const timerProgressBar = getTimerProgressBar();
11949 hide(timerProgressBar);
11950 if (innerParams.timer) {
11951 globalState.timeout = new Timer(() => {
11952 dismissWith('timer');
11953 delete globalState.timeout;
11954 }, innerParams.timer);
11955 if (innerParams.timerProgressBar && timerProgressBar) {
11956 show(timerProgressBar);
11957 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
11958 setTimeout(() => {
11959 if (globalState.timeout && globalState.timeout.running) {
11960 // timer can be already stopped or unset at this point
11961 animateTimerProgressBar(/** @type {number} */innerParams.timer);
11962 }
11963 });
11964 }
11965 }
11966 };
11967
11968 /**
11969 * Initialize focus in the popup:
11970 *
11971 * 1. If `toast` is `true`, don't steal focus from the document.
11972 * 2. Else if there is an [autofocus] element, focus it.
11973 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
11974 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
11975 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
11976 * 6. Else focus the first focusable element in a popup (if any).
11977 *
11978 * @param {DomCache} domCache
11979 * @param {SweetAlertOptions} innerParams
11980 */
11981 const initFocus = (domCache, innerParams) => {
11982 if (innerParams.toast) {
11983 return;
11984 }
11985 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
11986 if (!callIfFunction(innerParams.allowEnterKey)) {
11987 warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
11988 domCache.popup.focus();
11989 return;
11990 }
11991 if (focusAutofocus(domCache)) {
11992 return;
11993 }
11994 if (focusButton(domCache, innerParams)) {
11995 return;
11996 }
11997 setFocus(-1, 1);
11998 };
11999
12000 /**
12001 * @param {DomCache} domCache
12002 * @returns {boolean}
12003 */
12004 const focusAutofocus = domCache => {
12005 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
12006 for (const autofocusElement of autofocusElements) {
12007 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
12008 autofocusElement.focus();
12009 return true;
12010 }
12011 }
12012 return false;
12013 };
12014
12015 /**
12016 * @param {DomCache} domCache
12017 * @param {SweetAlertOptions} innerParams
12018 * @returns {boolean}
12019 */
12020 const focusButton = (domCache, innerParams) => {
12021 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
12022 domCache.denyButton.focus();
12023 return true;
12024 }
12025 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
12026 domCache.cancelButton.focus();
12027 return true;
12028 }
12029 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
12030 domCache.confirmButton.focus();
12031 return true;
12032 }
12033 return false;
12034 };
12035
12036 // Assign instance methods from src/instanceMethods/*.js to prototype
12037 SweetAlert.prototype.disableButtons = disableButtons;
12038 SweetAlert.prototype.enableButtons = enableButtons;
12039 SweetAlert.prototype.getInput = getInput;
12040 SweetAlert.prototype.disableInput = disableInput;
12041 SweetAlert.prototype.enableInput = enableInput;
12042 SweetAlert.prototype.hideLoading = hideLoading;
12043 SweetAlert.prototype.disableLoading = hideLoading;
12044 SweetAlert.prototype.showValidationMessage = showValidationMessage;
12045 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
12046 SweetAlert.prototype.close = close;
12047 SweetAlert.prototype.closePopup = close;
12048 SweetAlert.prototype.closeModal = close;
12049 SweetAlert.prototype.closeToast = close;
12050 SweetAlert.prototype.rejectPromise = rejectPromise;
12051 SweetAlert.prototype.update = update;
12052 SweetAlert.prototype._destroy = _destroy;
12053
12054 // Assign static methods from src/staticMethods/*.js to constructor
12055 Object.assign(SweetAlert, staticMethods);
12056
12057 // Proxy to instance methods to constructor, for now, for backwards compatibility
12058 Object.keys(instanceMethods).forEach(key => {
12059 /**
12060 * @param {...(SweetAlertOptions | string | undefined)} args
12061 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
12062 */
12063 // @ts-ignore: Dynamic property assignment for backwards compatibility
12064 SweetAlert[key] = function (...args) {
12065 // @ts-ignore
12066 if (currentInstance && currentInstance[key]) {
12067 // @ts-ignore
12068 return currentInstance[key](...args);
12069 }
12070 return undefined;
12071 };
12072 });
12073 SweetAlert.DismissReason = DismissReason;
12074 SweetAlert.version = '11.26.25';
12075
12076 const Swal = SweetAlert;
12077 // @ts-ignore
12078 Swal.default = Swal;
12079
12080 return Swal;
12081
12082 }));
12083 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
12084 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:auto}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:auto}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
12085
12086 /***/ },
12087
12088 /***/ "./node_modules/toastify-js/src/toastify.js"
12089 /*!**************************************************!*\
12090 !*** ./node_modules/toastify-js/src/toastify.js ***!
12091 \**************************************************/
12092 (module) {
12093
12094 /*!
12095 * Toastify js 1.12.0
12096 * https://github.com/apvarun/toastify-js
12097 * @license MIT licensed
12098 *
12099 * Copyright (C) 2018 Varun A P
12100 */
12101 (function(root, factory) {
12102 if ( true && module.exports) {
12103 module.exports = factory();
12104 } else {
12105 root.Toastify = factory();
12106 }
12107 })(this, function(global) {
12108 // Object initialization
12109 var Toastify = function(options) {
12110 // Returning a new init object
12111 return new Toastify.lib.init(options);
12112 },
12113 // Library version
12114 version = "1.12.0";
12115
12116 // Set the default global options
12117 Toastify.defaults = {
12118 oldestFirst: true,
12119 text: "Toastify is awesome!",
12120 node: undefined,
12121 duration: 3000,
12122 selector: undefined,
12123 callback: function () {
12124 },
12125 destination: undefined,
12126 newWindow: false,
12127 close: false,
12128 gravity: "toastify-top",
12129 positionLeft: false,
12130 position: '',
12131 backgroundColor: '',
12132 avatar: "",
12133 className: "",
12134 stopOnFocus: true,
12135 onClick: function () {
12136 },
12137 offset: {x: 0, y: 0},
12138 escapeMarkup: true,
12139 ariaLive: 'polite',
12140 style: {background: ''}
12141 };
12142
12143 // Defining the prototype of the object
12144 Toastify.lib = Toastify.prototype = {
12145 toastify: version,
12146
12147 constructor: Toastify,
12148
12149 // Initializing the object with required parameters
12150 init: function(options) {
12151 // Verifying and validating the input object
12152 if (!options) {
12153 options = {};
12154 }
12155
12156 // Creating the options object
12157 this.options = {};
12158
12159 this.toastElement = null;
12160
12161 // Validating the options
12162 this.options.text = options.text || Toastify.defaults.text; // Display message
12163 this.options.node = options.node || Toastify.defaults.node; // Display content as node
12164 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
12165 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
12166 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
12167 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
12168 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
12169 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
12170 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
12171 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
12172 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
12173 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
12174 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
12175 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
12176 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
12177 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
12178 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
12179 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
12180 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
12181 this.options.style = options.style || Toastify.defaults.style;
12182 if(options.backgroundColor) {
12183 this.options.style.background = options.backgroundColor;
12184 }
12185
12186 // Returning the current object for chaining functions
12187 return this;
12188 },
12189
12190 // Building the DOM element
12191 buildToast: function() {
12192 // Validating if the options are defined
12193 if (!this.options) {
12194 throw "Toastify is not initialized";
12195 }
12196
12197 // Creating the DOM object
12198 var divElement = document.createElement("div");
12199 divElement.className = "toastify on " + this.options.className;
12200
12201 // Positioning toast to left or right or center
12202 if (!!this.options.position) {
12203 divElement.className += " toastify-" + this.options.position;
12204 } else {
12205 // To be depreciated in further versions
12206 if (this.options.positionLeft === true) {
12207 divElement.className += " toastify-left";
12208 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
12209 } else {
12210 // Default position
12211 divElement.className += " toastify-right";
12212 }
12213 }
12214
12215 // Assigning gravity of element
12216 divElement.className += " " + this.options.gravity;
12217
12218 if (this.options.backgroundColor) {
12219 // This is being deprecated in favor of using the style HTML DOM property
12220 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
12221 }
12222
12223 // Loop through our style object and apply styles to divElement
12224 for (var property in this.options.style) {
12225 divElement.style[property] = this.options.style[property];
12226 }
12227
12228 // Announce the toast to screen readers
12229 if (this.options.ariaLive) {
12230 divElement.setAttribute('aria-live', this.options.ariaLive)
12231 }
12232
12233 // Adding the toast message/node
12234 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
12235 // If we have a valid node, we insert it
12236 divElement.appendChild(this.options.node)
12237 } else {
12238 if (this.options.escapeMarkup) {
12239 divElement.innerText = this.options.text;
12240 } else {
12241 divElement.innerHTML = this.options.text;
12242 }
12243
12244 if (this.options.avatar !== "") {
12245 var avatarElement = document.createElement("img");
12246 avatarElement.src = this.options.avatar;
12247
12248 avatarElement.className = "toastify-avatar";
12249
12250 if (this.options.position == "left" || this.options.positionLeft === true) {
12251 // Adding close icon on the left of content
12252 divElement.appendChild(avatarElement);
12253 } else {
12254 // Adding close icon on the right of content
12255 divElement.insertAdjacentElement("afterbegin", avatarElement);
12256 }
12257 }
12258 }
12259
12260 // Adding a close icon to the toast
12261 if (this.options.close === true) {
12262 // Create a span for close element
12263 var closeElement = document.createElement("button");
12264 closeElement.type = "button";
12265 closeElement.setAttribute("aria-label", "Close");
12266 closeElement.className = "toast-close";
12267 closeElement.innerHTML = "&#10006;";
12268
12269 // Triggering the removal of toast from DOM on close click
12270 closeElement.addEventListener(
12271 "click",
12272 function(event) {
12273 event.stopPropagation();
12274 this.removeElement(this.toastElement);
12275 window.clearTimeout(this.toastElement.timeOutValue);
12276 }.bind(this)
12277 );
12278
12279 //Calculating screen width
12280 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
12281
12282 // Adding the close icon to the toast element
12283 // Display on the right if screen width is less than or equal to 360px
12284 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
12285 // Adding close icon on the left of content
12286 divElement.insertAdjacentElement("afterbegin", closeElement);
12287 } else {
12288 // Adding close icon on the right of content
12289 divElement.appendChild(closeElement);
12290 }
12291 }
12292
12293 // Clear timeout while toast is focused
12294 if (this.options.stopOnFocus && this.options.duration > 0) {
12295 var self = this;
12296 // stop countdown
12297 divElement.addEventListener(
12298 "mouseover",
12299 function(event) {
12300 window.clearTimeout(divElement.timeOutValue);
12301 }
12302 )
12303 // add back the timeout
12304 divElement.addEventListener(
12305 "mouseleave",
12306 function() {
12307 divElement.timeOutValue = window.setTimeout(
12308 function() {
12309 // Remove the toast from DOM
12310 self.removeElement(divElement);
12311 },
12312 self.options.duration
12313 )
12314 }
12315 )
12316 }
12317
12318 // Adding an on-click destination path
12319 if (typeof this.options.destination !== "undefined") {
12320 divElement.addEventListener(
12321 "click",
12322 function(event) {
12323 event.stopPropagation();
12324 if (this.options.newWindow === true) {
12325 window.open(this.options.destination, "_blank");
12326 } else {
12327 window.location = this.options.destination;
12328 }
12329 }.bind(this)
12330 );
12331 }
12332
12333 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
12334 divElement.addEventListener(
12335 "click",
12336 function(event) {
12337 event.stopPropagation();
12338 this.options.onClick();
12339 }.bind(this)
12340 );
12341 }
12342
12343 // Adding offset
12344 if(typeof this.options.offset === "object") {
12345
12346 var x = getAxisOffsetAValue("x", this.options);
12347 var y = getAxisOffsetAValue("y", this.options);
12348
12349 var xOffset = this.options.position == "left" ? x : "-" + x;
12350 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
12351
12352 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
12353
12354 }
12355
12356 // Returning the generated element
12357 return divElement;
12358 },
12359
12360 // Displaying the toast
12361 showToast: function() {
12362 // Creating the DOM object for the toast
12363 this.toastElement = this.buildToast();
12364
12365 // Getting the root element to with the toast needs to be added
12366 var rootElement;
12367 if (typeof this.options.selector === "string") {
12368 rootElement = document.getElementById(this.options.selector);
12369 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
12370 rootElement = this.options.selector;
12371 } else {
12372 rootElement = document.body;
12373 }
12374
12375 // Validating if root element is present in DOM
12376 if (!rootElement) {
12377 throw "Root element is not defined";
12378 }
12379
12380 // Adding the DOM element
12381 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
12382 rootElement.insertBefore(this.toastElement, elementToInsert);
12383
12384 // Repositioning the toasts in case multiple toasts are present
12385 Toastify.reposition();
12386
12387 if (this.options.duration > 0) {
12388 this.toastElement.timeOutValue = window.setTimeout(
12389 function() {
12390 // Remove the toast from DOM
12391 this.removeElement(this.toastElement);
12392 }.bind(this),
12393 this.options.duration
12394 ); // Binding `this` for function invocation
12395 }
12396
12397 // Supporting function chaining
12398 return this;
12399 },
12400
12401 hideToast: function() {
12402 if (this.toastElement.timeOutValue) {
12403 clearTimeout(this.toastElement.timeOutValue);
12404 }
12405 this.removeElement(this.toastElement);
12406 },
12407
12408 // Removing the element from the DOM
12409 removeElement: function(toastElement) {
12410 // Hiding the element
12411 // toastElement.classList.remove("on");
12412 toastElement.className = toastElement.className.replace(" on", "");
12413
12414 // Removing the element from DOM after transition end
12415 window.setTimeout(
12416 function() {
12417 // remove options node if any
12418 if (this.options.node && this.options.node.parentNode) {
12419 this.options.node.parentNode.removeChild(this.options.node);
12420 }
12421
12422 // Remove the element from the DOM, only when the parent node was not removed before.
12423 if (toastElement.parentNode) {
12424 toastElement.parentNode.removeChild(toastElement);
12425 }
12426
12427 // Calling the callback function
12428 this.options.callback.call(toastElement);
12429
12430 // Repositioning the toasts again
12431 Toastify.reposition();
12432 }.bind(this),
12433 400
12434 ); // Binding `this` for function invocation
12435 },
12436 };
12437
12438 // Positioning the toasts on the DOM
12439 Toastify.reposition = function() {
12440
12441 // Top margins with gravity
12442 var topLeftOffsetSize = {
12443 top: 15,
12444 bottom: 15,
12445 };
12446 var topRightOffsetSize = {
12447 top: 15,
12448 bottom: 15,
12449 };
12450 var offsetSize = {
12451 top: 15,
12452 bottom: 15,
12453 };
12454
12455 // Get all toast messages on the DOM
12456 var allToasts = document.getElementsByClassName("toastify");
12457
12458 var classUsed;
12459
12460 // Modifying the position of each toast element
12461 for (var i = 0; i < allToasts.length; i++) {
12462 // Getting the applied gravity
12463 if (containsClass(allToasts[i], "toastify-top") === true) {
12464 classUsed = "toastify-top";
12465 } else {
12466 classUsed = "toastify-bottom";
12467 }
12468
12469 var height = allToasts[i].offsetHeight;
12470 classUsed = classUsed.substr(9, classUsed.length-1)
12471 // Spacing between toasts
12472 var offset = 15;
12473
12474 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
12475
12476 // Show toast in center if screen with less than or equal to 360px
12477 if (width <= 360) {
12478 // Setting the position
12479 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
12480
12481 offsetSize[classUsed] += height + offset;
12482 } else {
12483 if (containsClass(allToasts[i], "toastify-left") === true) {
12484 // Setting the position
12485 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
12486
12487 topLeftOffsetSize[classUsed] += height + offset;
12488 } else {
12489 // Setting the position
12490 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
12491
12492 topRightOffsetSize[classUsed] += height + offset;
12493 }
12494 }
12495 }
12496
12497 // Supporting function chaining
12498 return this;
12499 };
12500
12501 // Helper function to get offset.
12502 function getAxisOffsetAValue(axis, options) {
12503
12504 if(options.offset[axis]) {
12505 if(isNaN(options.offset[axis])) {
12506 return options.offset[axis];
12507 }
12508 else {
12509 return options.offset[axis] + 'px';
12510 }
12511 }
12512
12513 return '0px';
12514
12515 }
12516
12517 function containsClass(elem, yourClass) {
12518 if (!elem || typeof yourClass !== "string") {
12519 return false;
12520 } else if (
12521 elem.className &&
12522 elem.className
12523 .trim()
12524 .split(/\s+/gi)
12525 .indexOf(yourClass) > -1
12526 ) {
12527 return true;
12528 } else {
12529 return false;
12530 }
12531 }
12532
12533 // Setting up the prototype for the init object
12534 Toastify.lib.init.prototype = Toastify.lib;
12535
12536 // Returning the Toastify function to be assigned to the window object/module
12537 return Toastify;
12538 });
12539
12540
12541 /***/ }
12542
12543 /******/ });
12544 /************************************************************************/
12545 /******/ // The module cache
12546 /******/ const __webpack_module_cache__ = {};
12547 /******/
12548 /******/ // The require function
12549 /******/ function __webpack_require__(moduleId) {
12550 /******/ // Check if module is in cache
12551 /******/ const cachedModule = __webpack_module_cache__[moduleId];
12552 /******/ if (cachedModule !== undefined) {
12553 /******/ return cachedModule.exports;
12554 /******/ }
12555 /******/ // Create a new module (and put it into the cache)
12556 /******/ const module = __webpack_module_cache__[moduleId] = {
12557 /******/ id: moduleId,
12558 /******/ // no module.loaded needed
12559 /******/ exports: {}
12560 /******/ };
12561 /******/
12562 /******/ // Execute the module function
12563 /******/ if (!(moduleId in __webpack_modules__)) {
12564 /******/ delete __webpack_module_cache__[moduleId];
12565 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
12566 /******/ e.code = 'MODULE_NOT_FOUND';
12567 /******/ throw e;
12568 /******/ }
12569 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
12570 /******/
12571 /******/ // Return the exports of the module
12572 /******/ return module.exports;
12573 /******/ }
12574 /******/
12575 /************************************************************************/
12576 /******/ /* webpack/runtime/compat get default export */
12577 /******/ (() => {
12578 /******/ // getDefaultExport function for compatibility with non-harmony modules
12579 /******/ __webpack_require__.n = (module) => {
12580 /******/ const getter = module && module.__esModule ?
12581 /******/ () => (module['default']) :
12582 /******/ () => (module);
12583 /******/ __webpack_require__.d(getter, { a: getter });
12584 /******/ return getter;
12585 /******/ };
12586 /******/ })();
12587 /******/
12588 /******/ /* webpack/runtime/define property getters */
12589 /******/ (() => {
12590 /******/ // define getter/value functions for harmony exports
12591 /******/ __webpack_require__.d = (exports, definition) => {
12592 /******/ if(Array.isArray(definition)) {
12593 /******/ var i = 0;
12594 /******/ while(i < definition.length) {
12595 /******/ var key = definition[i++];
12596 /******/ var binding = definition[i++];
12597 /******/ if(!__webpack_require__.o(exports, key)) {
12598 /******/ if(binding === 0) {
12599 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
12600 /******/ } else {
12601 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
12602 /******/ }
12603 /******/ } else if(binding === 0) { i++; }
12604 /******/ }
12605 /******/ } else {
12606 /******/ for(var key in definition) {
12607 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
12608 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
12609 /******/ }
12610 /******/ }
12611 /******/ }
12612 /******/ };
12613 /******/ })();
12614 /******/
12615 /******/ /* webpack/runtime/hasOwnProperty shorthand */
12616 /******/ (() => {
12617 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
12618 /******/ })();
12619 /******/
12620 /******/ /* webpack/runtime/make namespace object */
12621 /******/ (() => {
12622 /******/ // define __esModule on exports
12623 /******/ __webpack_require__.r = (exports) => {
12624 /******/ if(Symbol.toStringTag) {
12625 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
12626 /******/ }
12627 /******/ Object.defineProperty(exports, '__esModule', { value: true });
12628 /******/ };
12629 /******/ })();
12630 /******/
12631 /******/ /* webpack/runtime/nonce */
12632 /******/ (() => {
12633 /******/ __webpack_require__.nc = undefined;
12634 /******/ })();
12635 /******/
12636 /************************************************************************/
12637 let __webpack_exports__ = {};
12638 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
12639 (() => {
12640 "use strict";
12641 /*!********************************************!*\
12642 !*** ./assets/src/js/admin/edit-course.js ***!
12643 \********************************************/
12644 __webpack_require__.r(__webpack_exports__);
12645 /* harmony import */ var _edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./edit-course/edit-curriculum.js */ "./assets/src/js/admin/edit-course/edit-curriculum.js");
12646 /* harmony import */ var _generate_with_openai_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./generate-with-openai.js */ "./assets/src/js/admin/generate-with-openai.js");
12647 /* harmony import */ var _edit_course_edit_curriculum_edit_curriculum_ai_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edit-course/edit-curriculum/edit-curriculum-ai.js */ "./assets/src/js/admin/edit-course/edit-curriculum/edit-curriculum-ai.js");
12648 /**
12649 * Edit course JS handler.
12650 *
12651 * @since 4.3.0
12652 * @version 1.0.0
12653 */
12654
12655
12656
12657 new _edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_0__.EditCourseCurriculum();
12658 new _generate_with_openai_js__WEBPACK_IMPORTED_MODULE_1__.GenerateWithOpenai();
12659 new _edit_course_edit_curriculum_edit_curriculum_ai_js__WEBPACK_IMPORTED_MODULE_2__.EditCurriculumAi();
12660 })();
12661
12662 /******/ })()
12663 ;
12664 //# sourceMappingURL=edit-course.js.map