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

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

12,687 lines 453.9 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.17
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 * Gets the popup container which contains the backdrop and the popup itself.
7472 *
7473 * @returns {HTMLElement | null}
7474 */
7475 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
7476
7477 /**
7478 * @param {string} selectorString
7479 * @returns {HTMLElement | null}
7480 */
7481 const elementBySelector = selectorString => {
7482 const container = getContainer();
7483 return container ? container.querySelector(selectorString) : null;
7484 };
7485
7486 /**
7487 * @param {string} className
7488 * @returns {HTMLElement | null}
7489 */
7490 const elementByClass = className => {
7491 return elementBySelector(`.${className}`);
7492 };
7493
7494 /**
7495 * @returns {HTMLElement | null}
7496 */
7497 const getPopup = () => elementByClass(swalClasses.popup);
7498
7499 /**
7500 * @returns {HTMLElement | null}
7501 */
7502 const getIcon = () => elementByClass(swalClasses.icon);
7503
7504 /**
7505 * @returns {HTMLElement | null}
7506 */
7507 const getIconContent = () => elementByClass(swalClasses['icon-content']);
7508
7509 /**
7510 * @returns {HTMLElement | null}
7511 */
7512 const getTitle = () => elementByClass(swalClasses.title);
7513
7514 /**
7515 * @returns {HTMLElement | null}
7516 */
7517 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
7518
7519 /**
7520 * @returns {HTMLElement | null}
7521 */
7522 const getImage = () => elementByClass(swalClasses.image);
7523
7524 /**
7525 * @returns {HTMLElement | null}
7526 */
7527 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
7528
7529 /**
7530 * @returns {HTMLElement | null}
7531 */
7532 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
7533
7534 /**
7535 * @returns {HTMLButtonElement | null}
7536 */
7537 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
7538
7539 /**
7540 * @returns {HTMLButtonElement | null}
7541 */
7542 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
7543
7544 /**
7545 * @returns {HTMLButtonElement | null}
7546 */
7547 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
7548
7549 /**
7550 * @returns {HTMLElement | null}
7551 */
7552 const getInputLabel = () => elementByClass(swalClasses['input-label']);
7553
7554 /**
7555 * @returns {HTMLElement | null}
7556 */
7557 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
7558
7559 /**
7560 * @returns {HTMLElement | null}
7561 */
7562 const getActions = () => elementByClass(swalClasses.actions);
7563
7564 /**
7565 * @returns {HTMLElement | null}
7566 */
7567 const getFooter = () => elementByClass(swalClasses.footer);
7568
7569 /**
7570 * @returns {HTMLElement | null}
7571 */
7572 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
7573
7574 /**
7575 * @returns {HTMLElement | null}
7576 */
7577 const getCloseButton = () => elementByClass(swalClasses.close);
7578
7579 // https://github.com/jkup/focusable/blob/master/index.js
7580 const focusable = `
7581 a[href],
7582 area[href],
7583 input:not([disabled]),
7584 select:not([disabled]),
7585 textarea:not([disabled]),
7586 button:not([disabled]),
7587 iframe,
7588 object,
7589 embed,
7590 [tabindex="0"],
7591 [contenteditable],
7592 audio[controls],
7593 video[controls],
7594 summary
7595 `;
7596 /**
7597 * @returns {HTMLElement[]}
7598 */
7599 const getFocusableElements = () => {
7600 const popup = getPopup();
7601 if (!popup) {
7602 return [];
7603 }
7604 /** @type {NodeListOf<HTMLElement>} */
7605 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
7606 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
7607 // sort according to tabindex
7608 .sort((a, b) => {
7609 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
7610 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
7611 if (tabindexA > tabindexB) {
7612 return 1;
7613 } else if (tabindexA < tabindexB) {
7614 return -1;
7615 }
7616 return 0;
7617 });
7618
7619 /** @type {NodeListOf<HTMLElement>} */
7620 const otherFocusableElements = popup.querySelectorAll(focusable);
7621 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
7622 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
7623 };
7624
7625 /**
7626 * @returns {boolean}
7627 */
7628 const isModal = () => {
7629 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
7630 };
7631
7632 /**
7633 * @returns {boolean}
7634 */
7635 const isToast = () => {
7636 const popup = getPopup();
7637 if (!popup) {
7638 return false;
7639 }
7640 return hasClass(popup, swalClasses.toast);
7641 };
7642
7643 /**
7644 * @returns {boolean}
7645 */
7646 const isLoading = () => {
7647 const popup = getPopup();
7648 if (!popup) {
7649 return false;
7650 }
7651 return popup.hasAttribute('data-loading');
7652 };
7653
7654 /**
7655 * Securely set innerHTML of an element
7656 * https://github.com/sweetalert2/sweetalert2/issues/1926
7657 *
7658 * @param {HTMLElement} elem
7659 * @param {string} html
7660 */
7661 const setInnerHtml = (elem, html) => {
7662 elem.textContent = '';
7663 if (html) {
7664 const parser = new DOMParser();
7665 const parsed = parser.parseFromString(html, `text/html`);
7666 const head = parsed.querySelector('head');
7667 if (head) {
7668 Array.from(head.childNodes).forEach(child => {
7669 elem.appendChild(child);
7670 });
7671 }
7672 const body = parsed.querySelector('body');
7673 if (body) {
7674 Array.from(body.childNodes).forEach(child => {
7675 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
7676 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
7677 } else {
7678 elem.appendChild(child);
7679 }
7680 });
7681 }
7682 }
7683 };
7684
7685 /**
7686 * @param {HTMLElement} elem
7687 * @param {string} className
7688 * @returns {boolean}
7689 */
7690 const hasClass = (elem, className) => {
7691 if (!className) {
7692 return false;
7693 }
7694 const classList = className.split(/\s+/);
7695 for (let i = 0; i < classList.length; i++) {
7696 if (!elem.classList.contains(classList[i])) {
7697 return false;
7698 }
7699 }
7700 return true;
7701 };
7702
7703 /**
7704 * @param {HTMLElement} elem
7705 * @param {SweetAlertOptions} params
7706 */
7707 const removeCustomClasses = (elem, params) => {
7708 Array.from(elem.classList).forEach(className => {
7709 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
7710 elem.classList.remove(className);
7711 }
7712 });
7713 };
7714
7715 /**
7716 * @param {HTMLElement} elem
7717 * @param {SweetAlertOptions} params
7718 * @param {string} className
7719 */
7720 const applyCustomClass = (elem, params, className) => {
7721 removeCustomClasses(elem, params);
7722 if (!params.customClass) {
7723 return;
7724 }
7725 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
7726 if (!customClass) {
7727 return;
7728 }
7729 if (typeof customClass !== 'string' && !customClass.forEach) {
7730 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
7731 return;
7732 }
7733 addClass(elem, customClass);
7734 };
7735
7736 /**
7737 * @param {HTMLElement} popup
7738 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
7739 * @returns {HTMLInputElement | null}
7740 */
7741 const getInput$1 = (popup, inputClass) => {
7742 if (!inputClass) {
7743 return null;
7744 }
7745 switch (inputClass) {
7746 case 'select':
7747 case 'textarea':
7748 case 'file':
7749 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
7750 case 'checkbox':
7751 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
7752 case 'radio':
7753 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
7754 case 'range':
7755 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
7756 default:
7757 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
7758 }
7759 };
7760
7761 /**
7762 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
7763 */
7764 const focusInput = input => {
7765 input.focus();
7766
7767 // place cursor at end of text in text input
7768 if (input.type !== 'file') {
7769 // http://stackoverflow.com/a/2345915
7770 const val = input.value;
7771 input.value = '';
7772 input.value = val;
7773 }
7774 };
7775
7776 /**
7777 * @param {HTMLElement | HTMLElement[] | null} target
7778 * @param {string | string[] | readonly string[] | undefined} classList
7779 * @param {boolean} condition
7780 */
7781 const toggleClass = (target, classList, condition) => {
7782 if (!target || !classList) {
7783 return;
7784 }
7785 if (typeof classList === 'string') {
7786 classList = classList.split(/\s+/).filter(Boolean);
7787 }
7788 classList.forEach(className => {
7789 if (Array.isArray(target)) {
7790 target.forEach(elem => {
7791 if (condition) {
7792 elem.classList.add(className);
7793 } else {
7794 elem.classList.remove(className);
7795 }
7796 });
7797 } else {
7798 if (condition) {
7799 target.classList.add(className);
7800 } else {
7801 target.classList.remove(className);
7802 }
7803 }
7804 });
7805 };
7806
7807 /**
7808 * @param {HTMLElement | HTMLElement[] | null} target
7809 * @param {string | string[] | readonly string[] | undefined} classList
7810 */
7811 const addClass = (target, classList) => {
7812 toggleClass(target, classList, true);
7813 };
7814
7815 /**
7816 * @param {HTMLElement | HTMLElement[] | null} target
7817 * @param {string | string[] | readonly string[] | undefined} classList
7818 */
7819 const removeClass = (target, classList) => {
7820 toggleClass(target, classList, false);
7821 };
7822
7823 /**
7824 * Get direct child of an element by class name
7825 *
7826 * @param {HTMLElement} elem
7827 * @param {string} className
7828 * @returns {HTMLElement | undefined}
7829 */
7830 const getDirectChildByClass = (elem, className) => {
7831 const children = Array.from(elem.children);
7832 for (let i = 0; i < children.length; i++) {
7833 const child = children[i];
7834 if (child instanceof HTMLElement && hasClass(child, className)) {
7835 return child;
7836 }
7837 }
7838 };
7839
7840 /**
7841 * @param {HTMLElement} elem
7842 * @param {string} property
7843 * @param {string | number | null | undefined} value
7844 */
7845 const applyNumericalStyle = (elem, property, value) => {
7846 if (value === `${parseInt(`${value}`)}`) {
7847 value = parseInt(value);
7848 }
7849 if (value || parseInt(`${value}`) === 0) {
7850 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
7851 } else {
7852 elem.style.removeProperty(property);
7853 }
7854 };
7855
7856 /**
7857 * @param {HTMLElement | null} elem
7858 * @param {string} display
7859 */
7860 const show = (elem, display = 'flex') => {
7861 if (!elem) {
7862 return;
7863 }
7864 elem.style.display = display;
7865 };
7866
7867 /**
7868 * @param {HTMLElement | null} elem
7869 */
7870 const hide = elem => {
7871 if (!elem) {
7872 return;
7873 }
7874 elem.style.display = 'none';
7875 };
7876
7877 /**
7878 * @param {HTMLElement | null} elem
7879 * @param {string} display
7880 */
7881 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
7882 if (!elem) {
7883 return;
7884 }
7885 new MutationObserver(() => {
7886 toggle(elem, elem.innerHTML, display);
7887 }).observe(elem, {
7888 childList: true,
7889 subtree: true
7890 });
7891 };
7892
7893 /**
7894 * @param {HTMLElement} parent
7895 * @param {string} selector
7896 * @param {string} property
7897 * @param {string} value
7898 */
7899 const setStyle = (parent, selector, property, value) => {
7900 /** @type {HTMLElement | null} */
7901 const el = parent.querySelector(selector);
7902 if (el) {
7903 el.style.setProperty(property, value);
7904 }
7905 };
7906
7907 /**
7908 * @param {HTMLElement} elem
7909 * @param {boolean | string | null | undefined} condition
7910 * @param {string} display
7911 */
7912 const toggle = (elem, condition, display = 'flex') => {
7913 if (condition) {
7914 show(elem, display);
7915 } else {
7916 hide(elem);
7917 }
7918 };
7919
7920 /**
7921 * borrowed from jquery $(elem).is(':visible') implementation
7922 *
7923 * @param {HTMLElement | null} elem
7924 * @returns {boolean}
7925 */
7926 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
7927
7928 /**
7929 * @returns {boolean}
7930 */
7931 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
7932
7933 /**
7934 * @param {HTMLElement} elem
7935 * @returns {boolean}
7936 */
7937 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
7938
7939 /**
7940 * @param {HTMLElement} element
7941 * @param {HTMLElement} stopElement
7942 * @returns {boolean}
7943 */
7944 const selfOrParentIsScrollable = (element, stopElement) => {
7945 let parent = /** @type {HTMLElement | null} */element;
7946 while (parent && parent !== stopElement) {
7947 if (isScrollable(parent)) {
7948 return true;
7949 }
7950 parent = parent.parentElement;
7951 }
7952 return false;
7953 };
7954
7955 /**
7956 * borrowed from https://stackoverflow.com/a/46352119
7957 *
7958 * @param {HTMLElement} elem
7959 * @returns {boolean}
7960 */
7961 const hasCssAnimation = elem => {
7962 const style = window.getComputedStyle(elem);
7963 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
7964 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
7965 return animDuration > 0 || transDuration > 0;
7966 };
7967
7968 /**
7969 * @param {number} timer
7970 * @param {boolean} reset
7971 */
7972 const animateTimerProgressBar = (timer, reset = false) => {
7973 const timerProgressBar = getTimerProgressBar();
7974 if (!timerProgressBar) {
7975 return;
7976 }
7977 if (isVisible$1(timerProgressBar)) {
7978 if (reset) {
7979 timerProgressBar.style.transition = 'none';
7980 timerProgressBar.style.width = '100%';
7981 }
7982 setTimeout(() => {
7983 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
7984 timerProgressBar.style.width = '0%';
7985 }, 10);
7986 }
7987 };
7988 const stopTimerProgressBar = () => {
7989 const timerProgressBar = getTimerProgressBar();
7990 if (!timerProgressBar) {
7991 return;
7992 }
7993 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
7994 timerProgressBar.style.removeProperty('transition');
7995 timerProgressBar.style.width = '100%';
7996 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
7997 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
7998 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
7999 };
8000
8001 /**
8002 * Detect Node env
8003 *
8004 * @returns {boolean}
8005 */
8006 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
8007
8008 const sweetHTML = `
8009 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
8010 <button type="button" class="${swalClasses.close}"></button>
8011 <ul class="${swalClasses['progress-steps']}"></ul>
8012 <div class="${swalClasses.icon}"></div>
8013 <img class="${swalClasses.image}" />
8014 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
8015 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
8016 <input class="${swalClasses.input}" id="${swalClasses.input}" />
8017 <input type="file" class="${swalClasses.file}" />
8018 <div class="${swalClasses.range}">
8019 <input type="range" />
8020 <output></output>
8021 </div>
8022 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
8023 <div class="${swalClasses.radio}"></div>
8024 <label class="${swalClasses.checkbox}">
8025 <input type="checkbox" id="${swalClasses.checkbox}" />
8026 <span class="${swalClasses.label}"></span>
8027 </label>
8028 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
8029 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
8030 <div class="${swalClasses.actions}">
8031 <div class="${swalClasses.loader}"></div>
8032 <button type="button" class="${swalClasses.confirm}"></button>
8033 <button type="button" class="${swalClasses.deny}"></button>
8034 <button type="button" class="${swalClasses.cancel}"></button>
8035 </div>
8036 <div class="${swalClasses.footer}"></div>
8037 <div class="${swalClasses['timer-progress-bar-container']}">
8038 <div class="${swalClasses['timer-progress-bar']}"></div>
8039 </div>
8040 </div>
8041 `.replace(/(^|\n)\s*/g, '');
8042
8043 /**
8044 * @returns {boolean}
8045 */
8046 const resetOldContainer = () => {
8047 const oldContainer = getContainer();
8048 if (!oldContainer) {
8049 return false;
8050 }
8051 oldContainer.remove();
8052 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
8053 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
8054 swalClasses['has-column']]);
8055 return true;
8056 };
8057 const resetValidationMessage$1 = () => {
8058 if (globalState.currentInstance) {
8059 globalState.currentInstance.resetValidationMessage();
8060 }
8061 };
8062 const addInputChangeListeners = () => {
8063 const popup = getPopup();
8064 if (!popup) {
8065 return;
8066 }
8067 const input = getDirectChildByClass(popup, swalClasses.input);
8068 const file = getDirectChildByClass(popup, swalClasses.file);
8069 /** @type {HTMLInputElement | null} */
8070 const range = popup.querySelector(`.${swalClasses.range} input`);
8071 /** @type {HTMLOutputElement | null} */
8072 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
8073 const select = getDirectChildByClass(popup, swalClasses.select);
8074 /** @type {HTMLInputElement | null} */
8075 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
8076 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
8077 if (input) {
8078 input.oninput = resetValidationMessage$1;
8079 }
8080 if (file) {
8081 file.onchange = resetValidationMessage$1;
8082 }
8083 if (select) {
8084 select.onchange = resetValidationMessage$1;
8085 }
8086 if (checkbox) {
8087 checkbox.onchange = resetValidationMessage$1;
8088 }
8089 if (textarea) {
8090 textarea.oninput = resetValidationMessage$1;
8091 }
8092 if (range && rangeOutput) {
8093 range.oninput = () => {
8094 resetValidationMessage$1();
8095 rangeOutput.value = range.value;
8096 };
8097 range.onchange = () => {
8098 resetValidationMessage$1();
8099 rangeOutput.value = range.value;
8100 };
8101 }
8102 };
8103
8104 /**
8105 * @param {string | HTMLElement} target
8106 * @returns {HTMLElement}
8107 */
8108 const getTarget = target => {
8109 if (typeof target === 'string') {
8110 const element = document.querySelector(target);
8111 if (!element) {
8112 throw new Error(`Target element "${target}" not found`);
8113 }
8114 return /** @type {HTMLElement} */element;
8115 }
8116 return target;
8117 };
8118
8119 /**
8120 * @param {SweetAlertOptions} params
8121 */
8122 const setupAccessibility = params => {
8123 const popup = getPopup();
8124 if (!popup) {
8125 return;
8126 }
8127 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
8128 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
8129 if (!params.toast) {
8130 popup.setAttribute('aria-modal', 'true');
8131 }
8132 };
8133
8134 /**
8135 * @param {HTMLElement} targetElement
8136 */
8137 const setupRTL = targetElement => {
8138 if (window.getComputedStyle(targetElement).direction === 'rtl') {
8139 addClass(getContainer(), swalClasses.rtl);
8140 globalState.isRTL = true;
8141 }
8142 };
8143
8144 /**
8145 * Add modal + backdrop to DOM
8146 *
8147 * @param {SweetAlertOptions} params
8148 */
8149 const init = params => {
8150 // Clean up the old popup container if it exists
8151 const oldContainerExisted = resetOldContainer();
8152 if (isNodeEnv()) {
8153 error('SweetAlert2 requires document to initialize');
8154 return;
8155 }
8156 const container = document.createElement('div');
8157 container.className = swalClasses.container;
8158 if (oldContainerExisted) {
8159 addClass(container, swalClasses['no-transition']);
8160 }
8161 setInnerHtml(container, sweetHTML);
8162 container.dataset['swal2Theme'] = params.theme;
8163 const targetElement = getTarget(params.target || 'body');
8164 targetElement.appendChild(container);
8165 if (params.topLayer) {
8166 container.setAttribute('popover', '');
8167 container.showPopover();
8168 }
8169 setupAccessibility(params);
8170 setupRTL(targetElement);
8171 addInputChangeListeners();
8172 };
8173
8174 /**
8175 * @param {HTMLElement | object | string} param
8176 * @param {HTMLElement} target
8177 */
8178 const parseHtmlToContainer = (param, target) => {
8179 // DOM element
8180 if (param instanceof HTMLElement) {
8181 target.appendChild(param);
8182 }
8183
8184 // Object
8185 else if (typeof param === 'object') {
8186 handleObject(param, target);
8187 }
8188
8189 // Plain string
8190 else if (param) {
8191 setInnerHtml(target, param);
8192 }
8193 };
8194
8195 /**
8196 * @param {object} param
8197 * @param {HTMLElement} target
8198 */
8199 const handleObject = (param, target) => {
8200 // JQuery element(s)
8201 if ('jquery' in param) {
8202 handleJqueryElem(target, param);
8203 }
8204
8205 // For other objects use their string representation
8206 else {
8207 setInnerHtml(target, param.toString());
8208 }
8209 };
8210
8211 /**
8212 * @param {HTMLElement} target
8213 * @param {any} elem
8214 */
8215 const handleJqueryElem = (target, elem) => {
8216 target.textContent = '';
8217 if (0 in elem) {
8218 for (let i = 0; i in elem; i++) {
8219 target.appendChild(elem[i].cloneNode(true));
8220 }
8221 } else {
8222 target.appendChild(elem.cloneNode(true));
8223 }
8224 };
8225
8226 /**
8227 * @param {SweetAlert} instance
8228 * @param {SweetAlertOptions} params
8229 */
8230 const renderActions = (instance, params) => {
8231 const actions = getActions();
8232 const loader = getLoader();
8233 if (!actions || !loader) {
8234 return;
8235 }
8236
8237 // Actions (buttons) wrapper
8238 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
8239 hide(actions);
8240 } else {
8241 show(actions);
8242 }
8243
8244 // Custom class
8245 applyCustomClass(actions, params, 'actions');
8246
8247 // Render all the buttons
8248 renderButtons(actions, loader, params);
8249
8250 // Loader
8251 setInnerHtml(loader, params.loaderHtml || '');
8252 applyCustomClass(loader, params, 'loader');
8253 };
8254
8255 /**
8256 * @param {HTMLElement} actions
8257 * @param {HTMLElement} loader
8258 * @param {SweetAlertOptions} params
8259 */
8260 function renderButtons(actions, loader, params) {
8261 const confirmButton = getConfirmButton();
8262 const denyButton = getDenyButton();
8263 const cancelButton = getCancelButton();
8264 if (!confirmButton || !denyButton || !cancelButton) {
8265 return;
8266 }
8267
8268 // Render buttons
8269 renderButton(confirmButton, 'confirm', params);
8270 renderButton(denyButton, 'deny', params);
8271 renderButton(cancelButton, 'cancel', params);
8272 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
8273 if (params.reverseButtons) {
8274 if (params.toast) {
8275 actions.insertBefore(cancelButton, confirmButton);
8276 actions.insertBefore(denyButton, confirmButton);
8277 } else {
8278 actions.insertBefore(cancelButton, loader);
8279 actions.insertBefore(denyButton, loader);
8280 actions.insertBefore(confirmButton, loader);
8281 }
8282 }
8283 }
8284
8285 /**
8286 * @param {HTMLElement} confirmButton
8287 * @param {HTMLElement} denyButton
8288 * @param {HTMLElement} cancelButton
8289 * @param {SweetAlertOptions} params
8290 */
8291 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
8292 if (!params.buttonsStyling) {
8293 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
8294 return;
8295 }
8296 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
8297
8298 // Apply custom background colors to action buttons
8299 if (params.confirmButtonColor) {
8300 confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
8301 }
8302 if (params.denyButtonColor) {
8303 denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
8304 }
8305 if (params.cancelButtonColor) {
8306 cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
8307 }
8308
8309 // Apply the outline color to action buttons
8310 applyOutlineColor(confirmButton);
8311 applyOutlineColor(denyButton);
8312 applyOutlineColor(cancelButton);
8313 }
8314
8315 /**
8316 * @param {HTMLElement} button
8317 */
8318 function applyOutlineColor(button) {
8319 const buttonStyle = window.getComputedStyle(button);
8320 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
8321 // If the button already has a custom outline color, no need to change it
8322 return;
8323 }
8324 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
8325 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
8326 }
8327
8328 /**
8329 * @param {HTMLElement} button
8330 * @param {'confirm' | 'deny' | 'cancel'} buttonType
8331 * @param {SweetAlertOptions} params
8332 */
8333 function renderButton(button, buttonType, params) {
8334 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
8335 toggle(button, params[`show${buttonName}Button`], 'inline-block');
8336 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
8337 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
8338
8339 // Add buttons custom classes
8340 button.className = swalClasses[buttonType];
8341 applyCustomClass(button, params, `${buttonType}Button`);
8342 }
8343
8344 /**
8345 * @param {SweetAlert} instance
8346 * @param {SweetAlertOptions} params
8347 */
8348 const renderCloseButton = (instance, params) => {
8349 const closeButton = getCloseButton();
8350 if (!closeButton) {
8351 return;
8352 }
8353 setInnerHtml(closeButton, params.closeButtonHtml || '');
8354
8355 // Custom class
8356 applyCustomClass(closeButton, params, 'closeButton');
8357 toggle(closeButton, params.showCloseButton);
8358 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
8359 };
8360
8361 /**
8362 * @param {SweetAlert} instance
8363 * @param {SweetAlertOptions} params
8364 */
8365 const renderContainer = (instance, params) => {
8366 const container = getContainer();
8367 if (!container) {
8368 return;
8369 }
8370 handleBackdropParam(container, params.backdrop);
8371 handlePositionParam(container, params.position);
8372 handleGrowParam(container, params.grow);
8373
8374 // Custom class
8375 applyCustomClass(container, params, 'container');
8376 };
8377
8378 /**
8379 * @param {HTMLElement} container
8380 * @param {SweetAlertOptions['backdrop']} backdrop
8381 */
8382 function handleBackdropParam(container, backdrop) {
8383 if (typeof backdrop === 'string') {
8384 container.style.background = backdrop;
8385 } else if (!backdrop) {
8386 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
8387 }
8388 }
8389
8390 /**
8391 * @param {HTMLElement} container
8392 * @param {SweetAlertOptions['position']} position
8393 */
8394 function handlePositionParam(container, position) {
8395 if (!position) {
8396 return;
8397 }
8398 if (position in swalClasses) {
8399 addClass(container, swalClasses[position]);
8400 } else {
8401 warn('The "position" parameter is not valid, defaulting to "center"');
8402 addClass(container, swalClasses.center);
8403 }
8404 }
8405
8406 /**
8407 * @param {HTMLElement} container
8408 * @param {SweetAlertOptions['grow']} grow
8409 */
8410 function handleGrowParam(container, grow) {
8411 if (!grow) {
8412 return;
8413 }
8414 addClass(container, swalClasses[`grow-${grow}`]);
8415 }
8416
8417 /**
8418 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8419 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8420 * This is the approach that Babel will probably take to implement private methods/fields
8421 * https://github.com/tc39/proposal-private-methods
8422 * https://github.com/babel/babel/pull/7555
8423 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8424 * then we can use that language feature.
8425 */
8426
8427 var privateProps = {
8428 innerParams: new WeakMap(),
8429 domCache: new WeakMap()
8430 };
8431
8432 /// <reference path="../../../../sweetalert2.d.ts"/>
8433
8434
8435 /** @type {InputClass[]} */
8436 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
8437
8438 /**
8439 * @param {SweetAlert} instance
8440 * @param {SweetAlertOptions} params
8441 */
8442 const renderInput = (instance, params) => {
8443 const popup = getPopup();
8444 if (!popup) {
8445 return;
8446 }
8447 const innerParams = privateProps.innerParams.get(instance);
8448 const rerender = !innerParams || params.input !== innerParams.input;
8449 inputClasses.forEach(inputClass => {
8450 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
8451 if (!inputContainer) {
8452 return;
8453 }
8454
8455 // set attributes
8456 setAttributes(inputClass, params.inputAttributes);
8457
8458 // set class
8459 inputContainer.className = swalClasses[inputClass];
8460 if (rerender) {
8461 hide(inputContainer);
8462 }
8463 });
8464 if (params.input) {
8465 if (rerender) {
8466 showInput(params);
8467 }
8468 // set custom class
8469 setCustomClass(params);
8470 }
8471 };
8472
8473 /**
8474 * @param {SweetAlertOptions} params
8475 */
8476 const showInput = params => {
8477 if (!params.input) {
8478 return;
8479 }
8480 if (!renderInputType[params.input]) {
8481 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
8482 return;
8483 }
8484 const inputContainer = getInputContainer(params.input);
8485 if (!inputContainer) {
8486 return;
8487 }
8488 const input = renderInputType[params.input](inputContainer, params);
8489 show(inputContainer);
8490
8491 // input autofocus
8492 if (params.inputAutoFocus) {
8493 setTimeout(() => {
8494 focusInput(input);
8495 });
8496 }
8497 };
8498
8499 /**
8500 * @param {HTMLInputElement} input
8501 */
8502 const removeAttributes = input => {
8503 for (let i = 0; i < input.attributes.length; i++) {
8504 const attrName = input.attributes[i].name;
8505 if (!['id', 'type', 'value', 'style'].includes(attrName)) {
8506 input.removeAttribute(attrName);
8507 }
8508 }
8509 };
8510
8511 /**
8512 * @param {InputClass} inputClass
8513 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
8514 */
8515 const setAttributes = (inputClass, inputAttributes) => {
8516 const popup = getPopup();
8517 if (!popup) {
8518 return;
8519 }
8520 const input = getInput$1(popup, inputClass);
8521 if (!input) {
8522 return;
8523 }
8524 removeAttributes(input);
8525 for (const attr in inputAttributes) {
8526 input.setAttribute(attr, inputAttributes[attr]);
8527 }
8528 };
8529
8530 /**
8531 * @param {SweetAlertOptions} params
8532 */
8533 const setCustomClass = params => {
8534 if (!params.input) {
8535 return;
8536 }
8537 const inputContainer = getInputContainer(params.input);
8538 if (inputContainer) {
8539 applyCustomClass(inputContainer, params, 'input');
8540 }
8541 };
8542
8543 /**
8544 * @param {HTMLInputElement | HTMLTextAreaElement} input
8545 * @param {SweetAlertOptions} params
8546 */
8547 const setInputPlaceholder = (input, params) => {
8548 if (!input.placeholder && params.inputPlaceholder) {
8549 input.placeholder = params.inputPlaceholder;
8550 }
8551 };
8552
8553 /**
8554 * @param {Input} input
8555 * @param {Input} prependTo
8556 * @param {SweetAlertOptions} params
8557 */
8558 const setInputLabel = (input, prependTo, params) => {
8559 if (params.inputLabel) {
8560 const label = document.createElement('label');
8561 const labelClass = swalClasses['input-label'];
8562 label.setAttribute('for', input.id);
8563 label.className = labelClass;
8564 if (typeof params.customClass === 'object') {
8565 addClass(label, params.customClass.inputLabel);
8566 }
8567 label.innerText = params.inputLabel;
8568 prependTo.insertAdjacentElement('beforebegin', label);
8569 }
8570 };
8571
8572 /**
8573 * @param {SweetAlertInput} inputType
8574 * @returns {HTMLElement | undefined}
8575 */
8576 const getInputContainer = inputType => {
8577 const popup = getPopup();
8578 if (!popup) {
8579 return;
8580 }
8581 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
8582 };
8583
8584 /**
8585 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
8586 * @param {SweetAlertOptions['inputValue']} inputValue
8587 */
8588 const checkAndSetInputValue = (input, inputValue) => {
8589 if (['string', 'number'].includes(typeof inputValue)) {
8590 input.value = `${inputValue}`;
8591 } else if (!isPromise(inputValue)) {
8592 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
8593 }
8594 };
8595
8596 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
8597 const renderInputType = {};
8598
8599 /**
8600 * @param {Input | HTMLElement} input
8601 * @param {SweetAlertOptions} params
8602 * @returns {Input}
8603 */
8604 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} */
8605 (input, params) => {
8606 const inputElement = /** @type {HTMLInputElement} */input;
8607 checkAndSetInputValue(inputElement, params.inputValue);
8608 setInputLabel(inputElement, inputElement, params);
8609 setInputPlaceholder(inputElement, params);
8610 inputElement.type = /** @type {string} */params.input;
8611 return inputElement;
8612 };
8613
8614 /**
8615 * @param {Input | HTMLElement} input
8616 * @param {SweetAlertOptions} params
8617 * @returns {Input}
8618 */
8619 renderInputType.file = (input, params) => {
8620 const inputElement = /** @type {HTMLInputElement} */input;
8621 setInputLabel(inputElement, inputElement, params);
8622 setInputPlaceholder(inputElement, params);
8623 return inputElement;
8624 };
8625
8626 /**
8627 * @param {Input | HTMLElement} range
8628 * @param {SweetAlertOptions} params
8629 * @returns {Input}
8630 */
8631 renderInputType.range = (range, params) => {
8632 const rangeContainer = /** @type {HTMLElement} */range;
8633 const rangeInput = rangeContainer.querySelector('input');
8634 const rangeOutput = rangeContainer.querySelector('output');
8635 if (rangeInput) {
8636 checkAndSetInputValue(rangeInput, params.inputValue);
8637 rangeInput.type = /** @type {string} */params.input;
8638 setInputLabel(rangeInput, /** @type {Input} */range, params);
8639 }
8640 if (rangeOutput) {
8641 checkAndSetInputValue(rangeOutput, params.inputValue);
8642 }
8643 return /** @type {Input} */range;
8644 };
8645
8646 /**
8647 * @param {Input | HTMLElement} select
8648 * @param {SweetAlertOptions} params
8649 * @returns {Input}
8650 */
8651 renderInputType.select = (select, params) => {
8652 const selectElement = /** @type {HTMLSelectElement} */select;
8653 selectElement.textContent = '';
8654 if (params.inputPlaceholder) {
8655 const placeholder = document.createElement('option');
8656 setInnerHtml(placeholder, params.inputPlaceholder);
8657 placeholder.value = '';
8658 placeholder.disabled = true;
8659 placeholder.selected = true;
8660 selectElement.appendChild(placeholder);
8661 }
8662 setInputLabel(selectElement, selectElement, params);
8663 return selectElement;
8664 };
8665
8666 /**
8667 * @param {Input | HTMLElement} radio
8668 * @returns {Input}
8669 */
8670 renderInputType.radio = radio => {
8671 const radioElement = /** @type {HTMLElement} */radio;
8672 radioElement.textContent = '';
8673 return /** @type {Input} */radio;
8674 };
8675
8676 /**
8677 * @param {Input | HTMLElement} checkboxContainer
8678 * @param {SweetAlertOptions} params
8679 * @returns {Input}
8680 */
8681 renderInputType.checkbox = (checkboxContainer, params) => {
8682 const popup = getPopup();
8683 if (!popup) {
8684 throw new Error('Popup not found');
8685 }
8686 const checkbox = getInput$1(popup, 'checkbox');
8687 if (!checkbox) {
8688 throw new Error('Checkbox input not found');
8689 }
8690 checkbox.value = '1';
8691 checkbox.checked = Boolean(params.inputValue);
8692 const containerElement = /** @type {HTMLElement} */checkboxContainer;
8693 const label = containerElement.querySelector('span');
8694 if (label) {
8695 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
8696 if (placeholderOrLabel) {
8697 setInnerHtml(label, placeholderOrLabel);
8698 }
8699 }
8700 return checkbox;
8701 };
8702
8703 /**
8704 * @param {Input | HTMLElement} textarea
8705 * @param {SweetAlertOptions} params
8706 * @returns {Input}
8707 */
8708 renderInputType.textarea = (textarea, params) => {
8709 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
8710 checkAndSetInputValue(textareaElement, params.inputValue);
8711 setInputPlaceholder(textareaElement, params);
8712 setInputLabel(textareaElement, textareaElement, params);
8713
8714 /**
8715 * @param {HTMLElement} el
8716 * @returns {number}
8717 */
8718 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
8719
8720 // https://github.com/sweetalert2/sweetalert2/issues/2291
8721 setTimeout(() => {
8722 // https://github.com/sweetalert2/sweetalert2/issues/1699
8723 if ('MutationObserver' in window) {
8724 const popup = getPopup();
8725 if (!popup) {
8726 return;
8727 }
8728 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
8729 const textareaResizeHandler = () => {
8730 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
8731 if (!document.body.contains(textareaElement)) {
8732 return;
8733 }
8734 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
8735 const popupElement = getPopup();
8736 if (popupElement) {
8737 if (textareaWidth > initialPopupWidth) {
8738 popupElement.style.width = `${textareaWidth}px`;
8739 } else {
8740 applyNumericalStyle(popupElement, 'width', params.width);
8741 }
8742 }
8743 };
8744 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
8745 attributes: true,
8746 attributeFilter: ['style']
8747 });
8748 }
8749 });
8750 return textareaElement;
8751 };
8752
8753 /**
8754 * @param {SweetAlert} instance
8755 * @param {SweetAlertOptions} params
8756 */
8757 const renderContent = (instance, params) => {
8758 const htmlContainer = getHtmlContainer();
8759 if (!htmlContainer) {
8760 return;
8761 }
8762 showWhenInnerHtmlPresent(htmlContainer);
8763 applyCustomClass(htmlContainer, params, 'htmlContainer');
8764
8765 // Content as HTML
8766 if (params.html) {
8767 parseHtmlToContainer(params.html, htmlContainer);
8768 show(htmlContainer, 'block');
8769 }
8770
8771 // Content as plain text
8772 else if (params.text) {
8773 htmlContainer.textContent = params.text;
8774 show(htmlContainer, 'block');
8775 }
8776
8777 // No content
8778 else {
8779 hide(htmlContainer);
8780 }
8781 renderInput(instance, params);
8782 };
8783
8784 /**
8785 * @param {SweetAlert} instance
8786 * @param {SweetAlertOptions} params
8787 */
8788 const renderFooter = (instance, params) => {
8789 const footer = getFooter();
8790 if (!footer) {
8791 return;
8792 }
8793 showWhenInnerHtmlPresent(footer);
8794 toggle(footer, Boolean(params.footer), 'block');
8795 if (params.footer) {
8796 parseHtmlToContainer(params.footer, footer);
8797 }
8798
8799 // Custom class
8800 applyCustomClass(footer, params, 'footer');
8801 };
8802
8803 /**
8804 * @param {SweetAlert} instance
8805 * @param {SweetAlertOptions} params
8806 */
8807 const renderIcon = (instance, params) => {
8808 const innerParams = privateProps.innerParams.get(instance);
8809 const icon = getIcon();
8810 if (!icon) {
8811 return;
8812 }
8813
8814 // if the given icon already rendered, apply the styling without re-rendering the icon
8815 if (innerParams && params.icon === innerParams.icon) {
8816 // Custom or default content
8817 setContent(icon, params);
8818 applyStyles(icon, params);
8819 return;
8820 }
8821 if (!params.icon && !params.iconHtml) {
8822 hide(icon);
8823 return;
8824 }
8825 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
8826 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
8827 hide(icon);
8828 return;
8829 }
8830 show(icon);
8831
8832 // Custom or default content
8833 setContent(icon, params);
8834 applyStyles(icon, params);
8835
8836 // Animate icon
8837 addClass(icon, params.showClass && params.showClass.icon);
8838
8839 // Re-adjust the success icon on system theme change
8840 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
8841 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
8842 };
8843
8844 /**
8845 * @param {HTMLElement} icon
8846 * @param {SweetAlertOptions} params
8847 */
8848 const applyStyles = (icon, params) => {
8849 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
8850 if (params.icon !== iconType) {
8851 removeClass(icon, iconClassName);
8852 }
8853 }
8854 addClass(icon, params.icon && iconTypes[params.icon]);
8855
8856 // Icon color
8857 setColor(icon, params);
8858
8859 // Success icon background color
8860 adjustSuccessIconBackgroundColor();
8861
8862 // Custom class
8863 applyCustomClass(icon, params, 'icon');
8864 };
8865
8866 // Adjust success icon background color to match the popup background color
8867 const adjustSuccessIconBackgroundColor = () => {
8868 const popup = getPopup();
8869 if (!popup) {
8870 return;
8871 }
8872 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
8873 /** @type {NodeListOf<HTMLElement>} */
8874 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
8875 for (let i = 0; i < successIconParts.length; i++) {
8876 successIconParts[i].style.backgroundColor = popupBackgroundColor;
8877 }
8878 };
8879
8880 /**
8881 *
8882 * @param {SweetAlertOptions} params
8883 * @returns {string}
8884 */
8885 const successIconHtml = params => `
8886 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
8887 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
8888 <div class="swal2-success-ring"></div>
8889 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
8890 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
8891 `;
8892 const errorIconHtml = `
8893 <span class="swal2-x-mark">
8894 <span class="swal2-x-mark-line-left"></span>
8895 <span class="swal2-x-mark-line-right"></span>
8896 </span>
8897 `;
8898
8899 /**
8900 * @param {HTMLElement} icon
8901 * @param {SweetAlertOptions} params
8902 */
8903 const setContent = (icon, params) => {
8904 if (!params.icon && !params.iconHtml) {
8905 return;
8906 }
8907 let oldContent = icon.innerHTML;
8908 let newContent = '';
8909 if (params.iconHtml) {
8910 newContent = iconContent(params.iconHtml);
8911 } else if (params.icon === 'success') {
8912 newContent = successIconHtml(params);
8913 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
8914 } else if (params.icon === 'error') {
8915 newContent = errorIconHtml;
8916 } else if (params.icon) {
8917 const defaultIconHtml = {
8918 question: '?',
8919 warning: '!',
8920 info: 'i'
8921 };
8922 newContent = iconContent(defaultIconHtml[params.icon]);
8923 }
8924 if (oldContent.trim() !== newContent.trim()) {
8925 setInnerHtml(icon, newContent);
8926 }
8927 };
8928
8929 /**
8930 * @param {HTMLElement} icon
8931 * @param {SweetAlertOptions} params
8932 */
8933 const setColor = (icon, params) => {
8934 if (!params.iconColor) {
8935 return;
8936 }
8937 icon.style.color = params.iconColor;
8938 icon.style.borderColor = params.iconColor;
8939 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
8940 setStyle(icon, sel, 'background-color', params.iconColor);
8941 }
8942 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
8943 };
8944
8945 /**
8946 * @param {string} content
8947 * @returns {string}
8948 */
8949 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
8950
8951 /**
8952 * @param {SweetAlert} instance
8953 * @param {SweetAlertOptions} params
8954 */
8955 const renderImage = (instance, params) => {
8956 const image = getImage();
8957 if (!image) {
8958 return;
8959 }
8960 if (!params.imageUrl) {
8961 hide(image);
8962 return;
8963 }
8964 show(image, '');
8965
8966 // Src, alt
8967 image.setAttribute('src', params.imageUrl);
8968 image.setAttribute('alt', params.imageAlt || '');
8969
8970 // Width, height
8971 applyNumericalStyle(image, 'width', params.imageWidth);
8972 applyNumericalStyle(image, 'height', params.imageHeight);
8973
8974 // Class
8975 image.className = swalClasses.image;
8976 applyCustomClass(image, params, 'image');
8977 };
8978
8979 let dragging = false;
8980 let mousedownX = 0;
8981 let mousedownY = 0;
8982 let initialX = 0;
8983 let initialY = 0;
8984
8985 /**
8986 * @param {HTMLElement} popup
8987 */
8988 const addDraggableListeners = popup => {
8989 popup.addEventListener('mousedown', down);
8990 document.body.addEventListener('mousemove', move);
8991 popup.addEventListener('mouseup', up);
8992 popup.addEventListener('touchstart', down);
8993 document.body.addEventListener('touchmove', move);
8994 popup.addEventListener('touchend', up);
8995 };
8996
8997 /**
8998 * @param {HTMLElement} popup
8999 */
9000 const removeDraggableListeners = popup => {
9001 popup.removeEventListener('mousedown', down);
9002 document.body.removeEventListener('mousemove', move);
9003 popup.removeEventListener('mouseup', up);
9004 popup.removeEventListener('touchstart', down);
9005 document.body.removeEventListener('touchmove', move);
9006 popup.removeEventListener('touchend', up);
9007 };
9008
9009 /**
9010 * @param {MouseEvent | TouchEvent} event
9011 */
9012 const down = event => {
9013 const popup = getPopup();
9014 if (!popup) {
9015 return;
9016 }
9017 const icon = getIcon();
9018 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
9019 dragging = true;
9020 const clientXY = getClientXY(event);
9021 mousedownX = clientXY.clientX;
9022 mousedownY = clientXY.clientY;
9023 initialX = parseInt(popup.style.insetInlineStart) || 0;
9024 initialY = parseInt(popup.style.insetBlockStart) || 0;
9025 addClass(popup, 'swal2-dragging');
9026 }
9027 };
9028
9029 /**
9030 * @param {MouseEvent | TouchEvent} event
9031 */
9032 const move = event => {
9033 const popup = getPopup();
9034 if (!popup) {
9035 return;
9036 }
9037 if (dragging) {
9038 let {
9039 clientX,
9040 clientY
9041 } = getClientXY(event);
9042 const deltaX = clientX - mousedownX;
9043 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
9044 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
9045 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
9046 }
9047 };
9048 const up = () => {
9049 const popup = getPopup();
9050 dragging = false;
9051 removeClass(popup, 'swal2-dragging');
9052 };
9053
9054 /**
9055 * @param {MouseEvent | TouchEvent} event
9056 * @returns {{ clientX: number, clientY: number }}
9057 */
9058 const getClientXY = event => {
9059 let clientX = 0,
9060 clientY = 0;
9061 if (event.type.startsWith('mouse')) {
9062 clientX = /** @type {MouseEvent} */event.clientX;
9063 clientY = /** @type {MouseEvent} */event.clientY;
9064 } else if (event.type.startsWith('touch')) {
9065 clientX = /** @type {TouchEvent} */event.touches[0].clientX;
9066 clientY = /** @type {TouchEvent} */event.touches[0].clientY;
9067 }
9068 return {
9069 clientX,
9070 clientY
9071 };
9072 };
9073
9074 /**
9075 * @param {SweetAlert} instance
9076 * @param {SweetAlertOptions} params
9077 */
9078 const renderPopup = (instance, params) => {
9079 const container = getContainer();
9080 const popup = getPopup();
9081 if (!container || !popup) {
9082 return;
9083 }
9084
9085 // Width
9086 // https://github.com/sweetalert2/sweetalert2/issues/2170
9087 if (params.toast) {
9088 applyNumericalStyle(container, 'width', params.width);
9089 popup.style.width = '100%';
9090 const loader = getLoader();
9091 if (loader) {
9092 popup.insertBefore(loader, getIcon());
9093 }
9094 } else {
9095 applyNumericalStyle(popup, 'width', params.width);
9096 }
9097
9098 // Padding
9099 applyNumericalStyle(popup, 'padding', params.padding);
9100
9101 // Color
9102 if (params.color) {
9103 popup.style.color = params.color;
9104 }
9105
9106 // Background
9107 if (params.background) {
9108 popup.style.background = params.background;
9109 }
9110 hide(getValidationMessage());
9111
9112 // Classes
9113 addClasses$1(popup, params);
9114 if (params.draggable && !params.toast) {
9115 addClass(popup, swalClasses.draggable);
9116 addDraggableListeners(popup);
9117 } else {
9118 removeClass(popup, swalClasses.draggable);
9119 removeDraggableListeners(popup);
9120 }
9121 };
9122
9123 /**
9124 * @param {HTMLElement} popup
9125 * @param {SweetAlertOptions} params
9126 */
9127 const addClasses$1 = (popup, params) => {
9128 const showClass = params.showClass || {};
9129 // Default Class + showClass when updating Swal.update({})
9130 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
9131 if (params.toast) {
9132 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
9133 addClass(popup, swalClasses.toast);
9134 } else {
9135 addClass(popup, swalClasses.modal);
9136 }
9137
9138 // Custom class
9139 applyCustomClass(popup, params, 'popup');
9140 // TODO: remove in the next major
9141 if (typeof params.customClass === 'string') {
9142 addClass(popup, params.customClass);
9143 }
9144
9145 // Icon class (#1842)
9146 if (params.icon) {
9147 addClass(popup, swalClasses[`icon-${params.icon}`]);
9148 }
9149 };
9150
9151 /**
9152 * @param {SweetAlert} instance
9153 * @param {SweetAlertOptions} params
9154 */
9155 const renderProgressSteps = (instance, params) => {
9156 const progressStepsContainer = getProgressSteps();
9157 if (!progressStepsContainer) {
9158 return;
9159 }
9160 const {
9161 progressSteps,
9162 currentProgressStep
9163 } = params;
9164 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
9165 hide(progressStepsContainer);
9166 return;
9167 }
9168 show(progressStepsContainer);
9169 progressStepsContainer.textContent = '';
9170 if (currentProgressStep >= progressSteps.length) {
9171 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
9172 }
9173 progressSteps.forEach((step, index) => {
9174 const stepEl = createStepElement(step);
9175 progressStepsContainer.appendChild(stepEl);
9176 if (index === currentProgressStep) {
9177 addClass(stepEl, swalClasses['active-progress-step']);
9178 }
9179 if (index !== progressSteps.length - 1) {
9180 const lineEl = createLineElement(params);
9181 progressStepsContainer.appendChild(lineEl);
9182 }
9183 });
9184 };
9185
9186 /**
9187 * @param {string} step
9188 * @returns {HTMLLIElement}
9189 */
9190 const createStepElement = step => {
9191 const stepEl = document.createElement('li');
9192 addClass(stepEl, swalClasses['progress-step']);
9193 setInnerHtml(stepEl, step);
9194 return stepEl;
9195 };
9196
9197 /**
9198 * @param {SweetAlertOptions} params
9199 * @returns {HTMLLIElement}
9200 */
9201 const createLineElement = params => {
9202 const lineEl = document.createElement('li');
9203 addClass(lineEl, swalClasses['progress-step-line']);
9204 if (params.progressStepsDistance) {
9205 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
9206 }
9207 return lineEl;
9208 };
9209
9210 /**
9211 * @param {SweetAlert} instance
9212 * @param {SweetAlertOptions} params
9213 */
9214 const renderTitle = (instance, params) => {
9215 const title = getTitle();
9216 if (!title) {
9217 return;
9218 }
9219 showWhenInnerHtmlPresent(title);
9220 toggle(title, Boolean(params.title || params.titleText), 'block');
9221 if (params.title) {
9222 parseHtmlToContainer(params.title, title);
9223 }
9224 if (params.titleText) {
9225 title.innerText = params.titleText;
9226 }
9227
9228 // Custom class
9229 applyCustomClass(title, params, 'title');
9230 };
9231
9232 /**
9233 * @param {SweetAlert} instance
9234 * @param {SweetAlertOptions} params
9235 */
9236 const render = (instance, params) => {
9237 var _globalState$eventEmi;
9238 renderPopup(instance, params);
9239 renderContainer(instance, params);
9240 renderProgressSteps(instance, params);
9241 renderIcon(instance, params);
9242 renderImage(instance, params);
9243 renderTitle(instance, params);
9244 renderCloseButton(instance, params);
9245 renderContent(instance, params);
9246 renderActions(instance, params);
9247 renderFooter(instance, params);
9248 const popup = getPopup();
9249 if (typeof params.didRender === 'function' && popup) {
9250 params.didRender(popup);
9251 }
9252 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
9253 };
9254
9255 /*
9256 * Global function to determine if SweetAlert2 popup is shown
9257 */
9258 const isVisible = () => {
9259 return isVisible$1(getPopup());
9260 };
9261
9262 /*
9263 * Global function to click 'Confirm' button
9264 */
9265 const clickConfirm = () => {
9266 var _dom$getConfirmButton;
9267 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
9268 };
9269
9270 /*
9271 * Global function to click 'Deny' button
9272 */
9273 const clickDeny = () => {
9274 var _dom$getDenyButton;
9275 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
9276 };
9277
9278 /*
9279 * Global function to click 'Cancel' button
9280 */
9281 const clickCancel = () => {
9282 var _dom$getCancelButton;
9283 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
9284 };
9285
9286 /** @type {Record<DismissReason, DismissReason>} */
9287 const DismissReason = Object.freeze({
9288 cancel: 'cancel',
9289 backdrop: 'backdrop',
9290 close: 'close',
9291 esc: 'esc',
9292 timer: 'timer'
9293 });
9294
9295 /**
9296 * @param {GlobalState} globalState
9297 */
9298 const removeKeydownHandler = globalState => {
9299 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
9300 const handler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */globalState.keydownHandler;
9301 globalState.keydownTarget.removeEventListener('keydown', handler, {
9302 capture: globalState.keydownListenerCapture
9303 });
9304 globalState.keydownHandlerAdded = false;
9305 }
9306 };
9307
9308 /**
9309 * @param {GlobalState} globalState
9310 * @param {SweetAlertOptions} innerParams
9311 * @param {(dismiss: DismissReason) => void} dismissWith
9312 */
9313 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
9314 removeKeydownHandler(globalState);
9315 if (!innerParams.toast) {
9316 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
9317 const handler = e => keydownHandler(innerParams, e, dismissWith);
9318 globalState.keydownHandler = handler;
9319 const target = innerParams.keydownListenerCapture ? window : getPopup();
9320 if (target) {
9321 globalState.keydownTarget = target;
9322 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
9323 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
9324 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
9325 capture: globalState.keydownListenerCapture
9326 });
9327 globalState.keydownHandlerAdded = true;
9328 }
9329 }
9330 };
9331
9332 /**
9333 * @param {number} index
9334 * @param {number} increment
9335 */
9336 const setFocus = (index, increment) => {
9337 var _dom$getPopup;
9338 const focusableElements = getFocusableElements();
9339 // search for visible elements and select the next possible match
9340 if (focusableElements.length) {
9341 index = index + increment;
9342
9343 // shift + tab when .swal2-popup is focused
9344 if (index === -2) {
9345 index = focusableElements.length - 1;
9346 }
9347
9348 // rollover to first item
9349 if (index === focusableElements.length) {
9350 index = 0;
9351
9352 // go to last item
9353 } else if (index === -1) {
9354 index = focusableElements.length - 1;
9355 }
9356 focusableElements[index].focus();
9357 return;
9358 }
9359 // no visible focusable elements, focus the popup
9360 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
9361 };
9362 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
9363 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
9364
9365 /**
9366 * @param {SweetAlertOptions} innerParams
9367 * @param {KeyboardEvent} event
9368 * @param {(dismiss: DismissReason) => void} dismissWith
9369 */
9370 const keydownHandler = (innerParams, event, dismissWith) => {
9371 if (!innerParams) {
9372 return; // This instance has already been destroyed
9373 }
9374
9375 // Ignore keydown during IME composition
9376 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
9377 // https://github.com/sweetalert2/sweetalert2/issues/720
9378 // https://github.com/sweetalert2/sweetalert2/issues/2406
9379 if (event.isComposing || event.keyCode === 229) {
9380 return;
9381 }
9382 if (innerParams.stopKeydownPropagation) {
9383 event.stopPropagation();
9384 }
9385
9386 // ENTER
9387 if (event.key === 'Enter') {
9388 handleEnter(event, innerParams);
9389 }
9390
9391 // TAB
9392 else if (event.key === 'Tab') {
9393 handleTab(event);
9394 }
9395
9396 // ARROWS - switch focus between buttons
9397 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
9398 handleArrows(event.key);
9399 }
9400
9401 // ESC
9402 else if (event.key === 'Escape') {
9403 handleEsc(event, innerParams, dismissWith);
9404 }
9405 };
9406
9407 /**
9408 * @param {KeyboardEvent} event
9409 * @param {SweetAlertOptions} innerParams
9410 */
9411 const handleEnter = (event, innerParams) => {
9412 // https://github.com/sweetalert2/sweetalert2/issues/2386
9413 if (!callIfFunction(innerParams.allowEnterKey)) {
9414 return;
9415 }
9416 const popup = getPopup();
9417 if (!popup || !innerParams.input) {
9418 return;
9419 }
9420 const input = getInput$1(popup, innerParams.input);
9421 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
9422 if (['textarea', 'file'].includes(innerParams.input)) {
9423 return; // do not submit
9424 }
9425 clickConfirm();
9426 event.preventDefault();
9427 }
9428 };
9429
9430 /**
9431 * @param {KeyboardEvent} event
9432 */
9433 const handleTab = event => {
9434 const targetElement = event.target;
9435 const focusableElements = getFocusableElements();
9436 let btnIndex = -1;
9437 for (let i = 0; i < focusableElements.length; i++) {
9438 if (targetElement === focusableElements[i]) {
9439 btnIndex = i;
9440 break;
9441 }
9442 }
9443
9444 // Cycle to the next button
9445 if (!event.shiftKey) {
9446 setFocus(btnIndex, 1);
9447 }
9448
9449 // Cycle to the prev button
9450 else {
9451 setFocus(btnIndex, -1);
9452 }
9453 event.stopPropagation();
9454 event.preventDefault();
9455 };
9456
9457 /**
9458 * @param {string} key
9459 */
9460 const handleArrows = key => {
9461 const actions = getActions();
9462 const confirmButton = getConfirmButton();
9463 const denyButton = getDenyButton();
9464 const cancelButton = getCancelButton();
9465 if (!actions || !confirmButton || !denyButton || !cancelButton) {
9466 return;
9467 }
9468 /** @type HTMLElement[] */
9469 const buttons = [confirmButton, denyButton, cancelButton];
9470 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
9471 return;
9472 }
9473 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
9474 let buttonToFocus = document.activeElement;
9475 if (!buttonToFocus) {
9476 return;
9477 }
9478 for (let i = 0; i < actions.children.length; i++) {
9479 buttonToFocus = buttonToFocus[sibling];
9480 if (!buttonToFocus) {
9481 return;
9482 }
9483 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
9484 break;
9485 }
9486 }
9487 if (buttonToFocus instanceof HTMLButtonElement) {
9488 buttonToFocus.focus();
9489 }
9490 };
9491
9492 /**
9493 * @param {KeyboardEvent} event
9494 * @param {SweetAlertOptions} innerParams
9495 * @param {(dismiss: DismissReason) => void} dismissWith
9496 */
9497 const handleEsc = (event, innerParams, dismissWith) => {
9498 event.preventDefault();
9499 if (callIfFunction(innerParams.allowEscapeKey)) {
9500 dismissWith(DismissReason.esc);
9501 }
9502 };
9503
9504 /**
9505 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
9506 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
9507 * This is the approach that Babel will probably take to implement private methods/fields
9508 * https://github.com/tc39/proposal-private-methods
9509 * https://github.com/babel/babel/pull/7555
9510 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
9511 * then we can use that language feature.
9512 */
9513
9514 var privateMethods = {
9515 swalPromiseResolve: new WeakMap(),
9516 swalPromiseReject: new WeakMap()
9517 };
9518
9519 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
9520 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
9521 // elements not within the active modal dialog will not be surfaced if a user opens a screen
9522 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
9523
9524 const setAriaHidden = () => {
9525 const container = getContainer();
9526 const bodyChildren = Array.from(document.body.children);
9527 bodyChildren.forEach(el => {
9528 if (el.contains(container)) {
9529 return;
9530 }
9531 if (el.hasAttribute('aria-hidden')) {
9532 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
9533 }
9534 el.setAttribute('aria-hidden', 'true');
9535 });
9536 };
9537 const unsetAriaHidden = () => {
9538 const bodyChildren = Array.from(document.body.children);
9539 bodyChildren.forEach(el => {
9540 if (el.hasAttribute('data-previous-aria-hidden')) {
9541 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
9542 el.removeAttribute('data-previous-aria-hidden');
9543 } else {
9544 el.removeAttribute('aria-hidden');
9545 }
9546 });
9547 };
9548
9549 // @ts-ignore
9550 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
9551
9552 /**
9553 * Fix iOS scrolling
9554 * http://stackoverflow.com/q/39626302
9555 */
9556 const iOSfix = () => {
9557 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
9558 const offset = document.body.scrollTop;
9559 document.body.style.top = `${offset * -1}px`;
9560 addClass(document.body, swalClasses.iosfix);
9561 lockBodyScroll();
9562 }
9563 };
9564
9565 /**
9566 * https://github.com/sweetalert2/sweetalert2/issues/1246
9567 */
9568 const lockBodyScroll = () => {
9569 const container = getContainer();
9570 if (!container) {
9571 return;
9572 }
9573 /** @type {boolean} */
9574 let preventTouchMove;
9575 /**
9576 * @param {TouchEvent} event
9577 */
9578 container.ontouchstart = event => {
9579 preventTouchMove = shouldPreventTouchMove(event);
9580 };
9581 /**
9582 * @param {TouchEvent} event
9583 */
9584 container.ontouchmove = event => {
9585 if (preventTouchMove) {
9586 event.preventDefault();
9587 event.stopPropagation();
9588 }
9589 };
9590 };
9591
9592 /**
9593 * @param {TouchEvent} event
9594 * @returns {boolean}
9595 */
9596 const shouldPreventTouchMove = event => {
9597 const target = event.target;
9598 const container = getContainer();
9599 const htmlContainer = getHtmlContainer();
9600 if (!container || !htmlContainer) {
9601 return false;
9602 }
9603 if (isStylus(event) || isZoom(event)) {
9604 return false;
9605 }
9606 if (target === container) {
9607 return true;
9608 }
9609 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
9610 // #2823
9611 target.tagName !== 'INPUT' &&
9612 // #1603
9613 target.tagName !== 'TEXTAREA' &&
9614 // #2266
9615 !(isScrollable(htmlContainer) &&
9616 // #1944
9617 htmlContainer.contains(target))) {
9618 return true;
9619 }
9620 return false;
9621 };
9622
9623 /**
9624 * https://github.com/sweetalert2/sweetalert2/issues/1786
9625 *
9626 * @param {TouchEvent} event
9627 * @returns {boolean}
9628 */
9629 const isStylus = event => {
9630 return Boolean(event.touches && event.touches.length &&
9631 // @ts-ignore - touchType is not a standard property
9632 event.touches[0].touchType === 'stylus');
9633 };
9634
9635 /**
9636 * https://github.com/sweetalert2/sweetalert2/issues/1891
9637 *
9638 * @param {TouchEvent} event
9639 * @returns {boolean}
9640 */
9641 const isZoom = event => {
9642 return event.touches && event.touches.length > 1;
9643 };
9644 const undoIOSfix = () => {
9645 if (hasClass(document.body, swalClasses.iosfix)) {
9646 const offset = parseInt(document.body.style.top, 10);
9647 removeClass(document.body, swalClasses.iosfix);
9648 document.body.style.top = '';
9649 document.body.scrollTop = offset * -1;
9650 }
9651 };
9652
9653 /**
9654 * Measure scrollbar width for padding body during modal show/hide
9655 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
9656 *
9657 * @returns {number}
9658 */
9659 const measureScrollbar = () => {
9660 const scrollDiv = document.createElement('div');
9661 scrollDiv.className = swalClasses['scrollbar-measure'];
9662 document.body.appendChild(scrollDiv);
9663 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
9664 document.body.removeChild(scrollDiv);
9665 return scrollbarWidth;
9666 };
9667
9668 /**
9669 * Remember state in cases where opening and handling a modal will fiddle with it.
9670 * @type {number | null}
9671 */
9672 let previousBodyPadding = null;
9673
9674 /**
9675 * @param {string} initialBodyOverflow
9676 */
9677 const replaceScrollbarWithPadding = initialBodyOverflow => {
9678 // for queues, do not do this more than once
9679 if (previousBodyPadding !== null) {
9680 return;
9681 }
9682 // if the body has overflow
9683 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
9684 ) {
9685 // add padding so the content doesn't shift after removal of scrollbar
9686 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
9687 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
9688 }
9689 };
9690 const undoReplaceScrollbarWithPadding = () => {
9691 if (previousBodyPadding !== null) {
9692 document.body.style.paddingRight = `${previousBodyPadding}px`;
9693 previousBodyPadding = null;
9694 }
9695 };
9696
9697 /**
9698 * @param {SweetAlert} instance
9699 * @param {HTMLElement} container
9700 * @param {boolean} returnFocus
9701 * @param {(() => void) | undefined} didClose
9702 */
9703 function removePopupAndResetState(instance, container, returnFocus, didClose) {
9704 if (isToast()) {
9705 triggerDidCloseAndDispose(instance, didClose);
9706 } else {
9707 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
9708 removeKeydownHandler(globalState);
9709 }
9710
9711 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
9712 // for some reason removing the container in Safari will scroll the document to bottom
9713 if (isSafariOrIOS) {
9714 container.setAttribute('style', 'display:none !important');
9715 container.removeAttribute('class');
9716 container.innerHTML = '';
9717 } else {
9718 container.remove();
9719 }
9720 if (isModal()) {
9721 undoReplaceScrollbarWithPadding();
9722 undoIOSfix();
9723 unsetAriaHidden();
9724 }
9725 removeBodyClasses();
9726 }
9727
9728 /**
9729 * Remove SweetAlert2 classes from body
9730 */
9731 function removeBodyClasses() {
9732 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
9733 }
9734
9735 /**
9736 * Instance method to close sweetAlert
9737 *
9738 * @param {SweetAlertResult | undefined} resolveValue
9739 * @this {SweetAlert}
9740 */
9741 function close(resolveValue) {
9742 resolveValue = prepareResolveValue(resolveValue);
9743 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
9744 const didClose = triggerClosePopup(this);
9745 if (this.isAwaitingPromise) {
9746 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
9747 if (!resolveValue.isDismissed) {
9748 handleAwaitingPromise(this);
9749 swalPromiseResolve(resolveValue);
9750 }
9751 } else if (didClose) {
9752 // Resolve Swal promise
9753 swalPromiseResolve(resolveValue);
9754 }
9755 }
9756
9757 /**
9758 * @param {SweetAlert} instance
9759 * @returns {boolean}
9760 */
9761 const triggerClosePopup = instance => {
9762 const popup = getPopup();
9763 if (!popup) {
9764 return false;
9765 }
9766 const innerParams = privateProps.innerParams.get(instance);
9767 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
9768 return false;
9769 }
9770 removeClass(popup, innerParams.showClass.popup);
9771 addClass(popup, innerParams.hideClass.popup);
9772 const backdrop = getContainer();
9773 removeClass(backdrop, innerParams.showClass.backdrop);
9774 addClass(backdrop, innerParams.hideClass.backdrop);
9775 handlePopupAnimation(instance, popup, innerParams);
9776 return true;
9777 };
9778
9779 /**
9780 * @param {Error | string} error
9781 * @this {SweetAlert}
9782 */
9783 function rejectPromise(error) {
9784 const rejectPromise = privateMethods.swalPromiseReject.get(this);
9785 handleAwaitingPromise(this);
9786 if (rejectPromise) {
9787 // Reject Swal promise
9788 rejectPromise(error);
9789 }
9790 }
9791
9792 /**
9793 * @param {SweetAlert} instance
9794 */
9795 const handleAwaitingPromise = instance => {
9796 if (instance.isAwaitingPromise) {
9797 // @ts-ignore
9798 delete instance.isAwaitingPromise;
9799 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
9800 if (!privateProps.innerParams.get(instance)) {
9801 instance._destroy();
9802 }
9803 }
9804 };
9805
9806 /**
9807 * @param {SweetAlertResult | undefined} resolveValue
9808 * @returns {SweetAlertResult}
9809 */
9810 const prepareResolveValue = resolveValue => {
9811 // When user calls Swal.close()
9812 if (typeof resolveValue === 'undefined') {
9813 return {
9814 isConfirmed: false,
9815 isDenied: false,
9816 isDismissed: true
9817 };
9818 }
9819 return Object.assign({
9820 isConfirmed: false,
9821 isDenied: false,
9822 isDismissed: false
9823 }, resolveValue);
9824 };
9825
9826 /**
9827 * @param {SweetAlert} instance
9828 * @param {HTMLElement} popup
9829 * @param {SweetAlertOptions} innerParams
9830 */
9831 const handlePopupAnimation = (instance, popup, innerParams) => {
9832 var _globalState$eventEmi;
9833 const container = getContainer();
9834 // If animation is supported, animate
9835 const animationIsSupported = hasCssAnimation(popup);
9836 if (typeof innerParams.willClose === 'function') {
9837 innerParams.willClose(popup);
9838 }
9839 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
9840 if (animationIsSupported && container) {
9841 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
9842 } else if (container) {
9843 // Otherwise, remove immediately
9844 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
9845 }
9846 };
9847
9848 /**
9849 * @param {SweetAlert} instance
9850 * @param {HTMLElement} popup
9851 * @param {HTMLElement} container
9852 * @param {boolean} returnFocus
9853 * @param {(() => void) | undefined} didClose
9854 */
9855 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
9856 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
9857 /**
9858 * @param {AnimationEvent | TransitionEvent} e
9859 */
9860 const swalCloseAnimationFinished = function (e) {
9861 if (e.target === popup) {
9862 var _globalState$swalClos;
9863 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
9864 delete globalState.swalCloseEventFinishedCallback;
9865 popup.removeEventListener('animationend', swalCloseAnimationFinished);
9866 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
9867 }
9868 };
9869 popup.addEventListener('animationend', swalCloseAnimationFinished);
9870 popup.addEventListener('transitionend', swalCloseAnimationFinished);
9871 };
9872
9873 /**
9874 * @param {SweetAlert} instance
9875 * @param {(() => void) | undefined} didClose
9876 */
9877 const triggerDidCloseAndDispose = (instance, didClose) => {
9878 setTimeout(() => {
9879 var _globalState$eventEmi2;
9880 if (typeof didClose === 'function') {
9881 didClose.bind(instance.params)();
9882 }
9883 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
9884 // instance might have been destroyed already
9885 if (instance._destroy) {
9886 instance._destroy();
9887 }
9888 });
9889 };
9890
9891 /**
9892 * Shows loader (spinner), this is useful with AJAX requests.
9893 * By default the loader be shown instead of the "Confirm" button.
9894 *
9895 * @param {HTMLButtonElement | null} [buttonToReplace]
9896 */
9897 const showLoading = buttonToReplace => {
9898 let popup = getPopup();
9899 if (!popup) {
9900 new Swal();
9901 }
9902 popup = getPopup();
9903 if (!popup) {
9904 return;
9905 }
9906 const loader = getLoader();
9907 if (isToast()) {
9908 hide(getIcon());
9909 } else {
9910 replaceButton(popup, buttonToReplace);
9911 }
9912 show(loader);
9913 popup.setAttribute('data-loading', 'true');
9914 popup.setAttribute('aria-busy', 'true');
9915 popup.focus();
9916 };
9917
9918 /**
9919 * @param {HTMLElement} popup
9920 * @param {HTMLButtonElement | null} [buttonToReplace]
9921 */
9922 const replaceButton = (popup, buttonToReplace) => {
9923 const actions = getActions();
9924 const loader = getLoader();
9925 if (!actions || !loader) {
9926 return;
9927 }
9928 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
9929 buttonToReplace = getConfirmButton();
9930 }
9931 show(actions);
9932 if (buttonToReplace) {
9933 hide(buttonToReplace);
9934 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
9935 actions.insertBefore(loader, buttonToReplace);
9936 }
9937 addClass([popup, actions], swalClasses.loading);
9938 };
9939
9940 /**
9941 * @param {SweetAlert} instance
9942 * @param {SweetAlertOptions} params
9943 */
9944 const handleInputOptionsAndValue = (instance, params) => {
9945 if (params.input === 'select' || params.input === 'radio') {
9946 handleInputOptions(instance, params);
9947 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
9948 showLoading(getConfirmButton());
9949 handleInputValue(instance, params);
9950 }
9951 };
9952
9953 /**
9954 * @param {SweetAlert} instance
9955 * @param {SweetAlertOptions} innerParams
9956 * @returns {SweetAlertInputValue}
9957 */
9958 const getInputValue = (instance, innerParams) => {
9959 const input = instance.getInput();
9960 if (!input) {
9961 return null;
9962 }
9963 switch (innerParams.input) {
9964 case 'checkbox':
9965 return getCheckboxValue(input);
9966 case 'radio':
9967 return getRadioValue(input);
9968 case 'file':
9969 return getFileValue(input);
9970 default:
9971 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
9972 }
9973 };
9974
9975 /**
9976 * @param {HTMLInputElement} input
9977 * @returns {number}
9978 */
9979 const getCheckboxValue = input => input.checked ? 1 : 0;
9980
9981 /**
9982 * @param {HTMLInputElement} input
9983 * @returns {string | null}
9984 */
9985 const getRadioValue = input => input.checked ? input.value : null;
9986
9987 /**
9988 * @param {HTMLInputElement} input
9989 * @returns {FileList | File | null}
9990 */
9991 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
9992
9993 /**
9994 * @param {SweetAlert} instance
9995 * @param {SweetAlertOptions} params
9996 */
9997 const handleInputOptions = (instance, params) => {
9998 const popup = getPopup();
9999 if (!popup) {
10000 return;
10001 }
10002 /**
10003 * @param {*} inputOptions
10004 */
10005 const processInputOptions = inputOptions => {
10006 if (params.input === 'select') {
10007 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
10008 } else if (params.input === 'radio') {
10009 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
10010 }
10011 };
10012 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
10013 showLoading(getConfirmButton());
10014 asPromise(params.inputOptions).then(inputOptions => {
10015 instance.hideLoading();
10016 processInputOptions(inputOptions);
10017 });
10018 } else if (typeof params.inputOptions === 'object') {
10019 processInputOptions(params.inputOptions);
10020 } else {
10021 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
10022 }
10023 };
10024
10025 /**
10026 * @param {SweetAlert} instance
10027 * @param {SweetAlertOptions} params
10028 */
10029 const handleInputValue = (instance, params) => {
10030 const input = instance.getInput();
10031 if (!input) {
10032 return;
10033 }
10034 hide(input);
10035 asPromise(params.inputValue).then(inputValue => {
10036 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
10037 show(input);
10038 input.focus();
10039 instance.hideLoading();
10040 }).catch(err => {
10041 error(`Error in inputValue promise: ${err}`);
10042 input.value = '';
10043 show(input);
10044 input.focus();
10045 instance.hideLoading();
10046 });
10047 };
10048
10049 /**
10050 * @param {HTMLElement} popup
10051 * @param {InputOptionFlattened[]} inputOptions
10052 * @param {SweetAlertOptions} params
10053 */
10054 function populateSelectOptions(popup, inputOptions, params) {
10055 const select = getDirectChildByClass(popup, swalClasses.select);
10056 if (!select) {
10057 return;
10058 }
10059 /**
10060 * @param {HTMLElement} parent
10061 * @param {string} optionLabel
10062 * @param {string} optionValue
10063 */
10064 const renderOption = (parent, optionLabel, optionValue) => {
10065 const option = document.createElement('option');
10066 option.value = optionValue;
10067 setInnerHtml(option, optionLabel);
10068 option.selected = isSelected(optionValue, params.inputValue);
10069 parent.appendChild(option);
10070 };
10071 inputOptions.forEach(inputOption => {
10072 const optionValue = inputOption[0];
10073 const optionLabel = inputOption[1];
10074 // <optgroup> spec:
10075 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
10076 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
10077 // check whether this is a <optgroup>
10078 if (Array.isArray(optionLabel)) {
10079 // if it is an array, then it is an <optgroup>
10080 const optgroup = document.createElement('optgroup');
10081 optgroup.label = optionValue;
10082 optgroup.disabled = false; // not configurable for now
10083 select.appendChild(optgroup);
10084 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
10085 } else {
10086 // case of <option>
10087 renderOption(select, optionLabel, optionValue);
10088 }
10089 });
10090 select.focus();
10091 }
10092
10093 /**
10094 * @param {HTMLElement} popup
10095 * @param {InputOptionFlattened[]} inputOptions
10096 * @param {SweetAlertOptions} params
10097 */
10098 function populateRadioOptions(popup, inputOptions, params) {
10099 const radio = getDirectChildByClass(popup, swalClasses.radio);
10100 if (!radio) {
10101 return;
10102 }
10103 inputOptions.forEach(inputOption => {
10104 const radioValue = inputOption[0];
10105 const radioLabel = inputOption[1];
10106 const radioInput = document.createElement('input');
10107 const radioLabelElement = document.createElement('label');
10108 radioInput.type = 'radio';
10109 radioInput.name = swalClasses.radio;
10110 radioInput.value = radioValue;
10111 if (isSelected(radioValue, params.inputValue)) {
10112 radioInput.checked = true;
10113 }
10114 const label = document.createElement('span');
10115 setInnerHtml(label, radioLabel);
10116 label.className = swalClasses.label;
10117 radioLabelElement.appendChild(radioInput);
10118 radioLabelElement.appendChild(label);
10119 radio.appendChild(radioLabelElement);
10120 });
10121 const radios = radio.querySelectorAll('input');
10122 if (radios.length) {
10123 radios[0].focus();
10124 }
10125 }
10126
10127 /**
10128 * Converts `inputOptions` into an array of `[value, label]`s
10129 *
10130 * @param {*} inputOptions
10131 * @typedef {string[]} InputOptionFlattened
10132 * @returns {InputOptionFlattened[]}
10133 */
10134 const formatInputOptions = inputOptions => {
10135 /** @type {InputOptionFlattened[]} */
10136 const result = [];
10137 if (inputOptions instanceof Map) {
10138 inputOptions.forEach((value, key) => {
10139 let valueFormatted = value;
10140 if (typeof valueFormatted === 'object') {
10141 // case of <optgroup>
10142 valueFormatted = formatInputOptions(valueFormatted);
10143 }
10144 result.push([key, valueFormatted]);
10145 });
10146 } else {
10147 Object.keys(inputOptions).forEach(key => {
10148 let valueFormatted = inputOptions[key];
10149 if (typeof valueFormatted === 'object') {
10150 // case of <optgroup>
10151 valueFormatted = formatInputOptions(valueFormatted);
10152 }
10153 result.push([key, valueFormatted]);
10154 });
10155 }
10156 return result;
10157 };
10158
10159 /**
10160 * @param {string} optionValue
10161 * @param {SweetAlertInputValue} inputValue
10162 * @returns {boolean}
10163 */
10164 const isSelected = (optionValue, inputValue) => {
10165 return Boolean(inputValue) && inputValue !== null && inputValue !== undefined && inputValue.toString() === optionValue.toString();
10166 };
10167
10168 /**
10169 * @param {SweetAlert} instance
10170 */
10171 const handleConfirmButtonClick = instance => {
10172 const innerParams = privateProps.innerParams.get(instance);
10173 instance.disableButtons();
10174 if (innerParams.input) {
10175 handleConfirmOrDenyWithInput(instance, 'confirm');
10176 } else {
10177 confirm(instance, true);
10178 }
10179 };
10180
10181 /**
10182 * @param {SweetAlert} instance
10183 */
10184 const handleDenyButtonClick = instance => {
10185 const innerParams = privateProps.innerParams.get(instance);
10186 instance.disableButtons();
10187 if (innerParams.returnInputValueOnDeny) {
10188 handleConfirmOrDenyWithInput(instance, 'deny');
10189 } else {
10190 deny(instance, false);
10191 }
10192 };
10193
10194 /**
10195 * @param {SweetAlert} instance
10196 * @param {(dismiss: DismissReason) => void} dismissWith
10197 */
10198 const handleCancelButtonClick = (instance, dismissWith) => {
10199 instance.disableButtons();
10200 dismissWith(DismissReason.cancel);
10201 };
10202
10203 /**
10204 * @param {SweetAlert} instance
10205 * @param {'confirm' | 'deny'} type
10206 */
10207 const handleConfirmOrDenyWithInput = (instance, type) => {
10208 const innerParams = privateProps.innerParams.get(instance);
10209 if (!innerParams.input) {
10210 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
10211 return;
10212 }
10213 const input = instance.getInput();
10214 const inputValue = getInputValue(instance, innerParams);
10215 if (innerParams.inputValidator) {
10216 handleInputValidator(instance, inputValue, type);
10217 } else if (input && !input.checkValidity()) {
10218 instance.enableButtons();
10219 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
10220 } else if (type === 'deny') {
10221 deny(instance, inputValue);
10222 } else {
10223 confirm(instance, inputValue);
10224 }
10225 };
10226
10227 /**
10228 * @param {SweetAlert} instance
10229 * @param {SweetAlertInputValue} inputValue
10230 * @param {'confirm' | 'deny'} type
10231 */
10232 const handleInputValidator = (instance, inputValue, type) => {
10233 const innerParams = privateProps.innerParams.get(instance);
10234 instance.disableInput();
10235 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
10236 validationPromise.then(validationMessage => {
10237 instance.enableButtons();
10238 instance.enableInput();
10239 if (validationMessage) {
10240 instance.showValidationMessage(validationMessage);
10241 } else if (type === 'deny') {
10242 deny(instance, inputValue);
10243 } else {
10244 confirm(instance, inputValue);
10245 }
10246 });
10247 };
10248
10249 /**
10250 * @param {SweetAlert} instance
10251 * @param {*} value
10252 */
10253 const deny = (instance, value) => {
10254 const innerParams = privateProps.innerParams.get(instance);
10255 if (innerParams.showLoaderOnDeny) {
10256 showLoading(getDenyButton());
10257 }
10258 if (innerParams.preDeny) {
10259 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
10260 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
10261 preDenyPromise.then(preDenyValue => {
10262 if (preDenyValue === false) {
10263 instance.hideLoading();
10264 handleAwaitingPromise(instance);
10265 } else {
10266 instance.close(/** @type SweetAlertResult */{
10267 isDenied: true,
10268 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
10269 });
10270 }
10271 }).catch(error => rejectWith(instance, error));
10272 } else {
10273 instance.close(/** @type SweetAlertResult */{
10274 isDenied: true,
10275 value
10276 });
10277 }
10278 };
10279
10280 /**
10281 * @param {SweetAlert} instance
10282 * @param {*} value
10283 */
10284 const succeedWith = (instance, value) => {
10285 instance.close(/** @type SweetAlertResult */{
10286 isConfirmed: true,
10287 value
10288 });
10289 };
10290
10291 /**
10292 *
10293 * @param {SweetAlert} instance
10294 * @param {string} error
10295 */
10296 const rejectWith = (instance, error) => {
10297 instance.rejectPromise(error);
10298 };
10299
10300 /**
10301 *
10302 * @param {SweetAlert} instance
10303 * @param {*} value
10304 */
10305 const confirm = (instance, value) => {
10306 const innerParams = privateProps.innerParams.get(instance);
10307 if (innerParams.showLoaderOnConfirm) {
10308 showLoading();
10309 }
10310 if (innerParams.preConfirm) {
10311 instance.resetValidationMessage();
10312 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
10313 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
10314 preConfirmPromise.then(preConfirmValue => {
10315 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
10316 instance.hideLoading();
10317 handleAwaitingPromise(instance);
10318 } else {
10319 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
10320 }
10321 }).catch(error => rejectWith(instance, error));
10322 } else {
10323 succeedWith(instance, value);
10324 }
10325 };
10326
10327 /**
10328 * Hides loader and shows back the button which was hidden by .showLoading()
10329 * @this {SweetAlert}
10330 */
10331 function hideLoading() {
10332 // do nothing if popup is closed
10333 const innerParams = privateProps.innerParams.get(this);
10334 if (!innerParams) {
10335 return;
10336 }
10337 const domCache = privateProps.domCache.get(this);
10338 hide(domCache.loader);
10339 if (isToast()) {
10340 if (innerParams.icon) {
10341 show(getIcon());
10342 }
10343 } else {
10344 showRelatedButton(domCache);
10345 }
10346 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
10347 domCache.popup.removeAttribute('aria-busy');
10348 domCache.popup.removeAttribute('data-loading');
10349 domCache.confirmButton.disabled = false;
10350 domCache.denyButton.disabled = false;
10351 domCache.cancelButton.disabled = false;
10352 }
10353
10354 /**
10355 * @param {DomCache} domCache
10356 */
10357 const showRelatedButton = domCache => {
10358 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
10359 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
10360 if (buttonToReplace.length) {
10361 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
10362 } else if (allButtonsAreHidden()) {
10363 hide(domCache.actions);
10364 }
10365 };
10366
10367 /**
10368 * Gets the input DOM node, this method works with input parameter.
10369 *
10370 * @returns {HTMLInputElement | null}
10371 * @this {SweetAlert}
10372 */
10373 function getInput() {
10374 const innerParams = privateProps.innerParams.get(this);
10375 const domCache = privateProps.domCache.get(this);
10376 if (!domCache) {
10377 return null;
10378 }
10379 return getInput$1(domCache.popup, innerParams.input);
10380 }
10381
10382 /**
10383 * @param {SweetAlert} instance
10384 * @param {string[]} buttons
10385 * @param {boolean} disabled
10386 */
10387 function setButtonsDisabled(instance, buttons, disabled) {
10388 const domCache = privateProps.domCache.get(instance);
10389 buttons.forEach(button => {
10390 domCache[button].disabled = disabled;
10391 });
10392 }
10393
10394 /**
10395 * @param {HTMLInputElement | null} input
10396 * @param {boolean} disabled
10397 */
10398 function setInputDisabled(input, disabled) {
10399 const popup = getPopup();
10400 if (!popup || !input) {
10401 return;
10402 }
10403 if (input.type === 'radio') {
10404 /** @type {NodeListOf<HTMLInputElement>} */
10405 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
10406 for (let i = 0; i < radios.length; i++) {
10407 radios[i].disabled = disabled;
10408 }
10409 } else {
10410 input.disabled = disabled;
10411 }
10412 }
10413
10414 /**
10415 * Enable all the buttons
10416 * @this {SweetAlert}
10417 */
10418 function enableButtons() {
10419 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
10420 }
10421
10422 /**
10423 * Disable all the buttons
10424 * @this {SweetAlert}
10425 */
10426 function disableButtons() {
10427 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
10428 }
10429
10430 /**
10431 * Enable the input field
10432 * @this {SweetAlert}
10433 */
10434 function enableInput() {
10435 setInputDisabled(this.getInput(), false);
10436 }
10437
10438 /**
10439 * Disable the input field
10440 * @this {SweetAlert}
10441 */
10442 function disableInput() {
10443 setInputDisabled(this.getInput(), true);
10444 }
10445
10446 /**
10447 * Show block with validation message
10448 *
10449 * @param {string} error
10450 * @this {SweetAlert}
10451 */
10452 function showValidationMessage(error) {
10453 const domCache = privateProps.domCache.get(this);
10454 const params = privateProps.innerParams.get(this);
10455 setInnerHtml(domCache.validationMessage, error);
10456 domCache.validationMessage.className = swalClasses['validation-message'];
10457 if (params.customClass && params.customClass.validationMessage) {
10458 addClass(domCache.validationMessage, params.customClass.validationMessage);
10459 }
10460 show(domCache.validationMessage);
10461 const input = this.getInput();
10462 if (input) {
10463 input.setAttribute('aria-invalid', 'true');
10464 input.setAttribute('aria-describedby', swalClasses['validation-message']);
10465 focusInput(input);
10466 addClass(input, swalClasses.inputerror);
10467 }
10468 }
10469
10470 /**
10471 * Hide block with validation message
10472 *
10473 * @this {SweetAlert}
10474 */
10475 function resetValidationMessage() {
10476 const domCache = privateProps.domCache.get(this);
10477 if (domCache.validationMessage) {
10478 hide(domCache.validationMessage);
10479 }
10480 const input = this.getInput();
10481 if (input) {
10482 input.removeAttribute('aria-invalid');
10483 input.removeAttribute('aria-describedby');
10484 removeClass(input, swalClasses.inputerror);
10485 }
10486 }
10487
10488 const defaultParams = {
10489 title: '',
10490 titleText: '',
10491 text: '',
10492 html: '',
10493 footer: '',
10494 icon: undefined,
10495 iconColor: undefined,
10496 iconHtml: undefined,
10497 template: undefined,
10498 toast: false,
10499 draggable: false,
10500 animation: true,
10501 theme: 'light',
10502 showClass: {
10503 popup: 'swal2-show',
10504 backdrop: 'swal2-backdrop-show',
10505 icon: 'swal2-icon-show'
10506 },
10507 hideClass: {
10508 popup: 'swal2-hide',
10509 backdrop: 'swal2-backdrop-hide',
10510 icon: 'swal2-icon-hide'
10511 },
10512 customClass: {},
10513 target: 'body',
10514 color: undefined,
10515 backdrop: true,
10516 heightAuto: true,
10517 allowOutsideClick: true,
10518 allowEscapeKey: true,
10519 allowEnterKey: true,
10520 stopKeydownPropagation: true,
10521 keydownListenerCapture: false,
10522 showConfirmButton: true,
10523 showDenyButton: false,
10524 showCancelButton: false,
10525 preConfirm: undefined,
10526 preDeny: undefined,
10527 confirmButtonText: 'OK',
10528 confirmButtonAriaLabel: '',
10529 confirmButtonColor: undefined,
10530 denyButtonText: 'No',
10531 denyButtonAriaLabel: '',
10532 denyButtonColor: undefined,
10533 cancelButtonText: 'Cancel',
10534 cancelButtonAriaLabel: '',
10535 cancelButtonColor: undefined,
10536 buttonsStyling: true,
10537 reverseButtons: false,
10538 focusConfirm: true,
10539 focusDeny: false,
10540 focusCancel: false,
10541 returnFocus: true,
10542 showCloseButton: false,
10543 closeButtonHtml: '&times;',
10544 closeButtonAriaLabel: 'Close this dialog',
10545 loaderHtml: '',
10546 showLoaderOnConfirm: false,
10547 showLoaderOnDeny: false,
10548 imageUrl: undefined,
10549 imageWidth: undefined,
10550 imageHeight: undefined,
10551 imageAlt: '',
10552 timer: undefined,
10553 timerProgressBar: false,
10554 width: undefined,
10555 padding: undefined,
10556 background: undefined,
10557 input: undefined,
10558 inputPlaceholder: '',
10559 inputLabel: '',
10560 inputValue: '',
10561 inputOptions: {},
10562 inputAutoFocus: true,
10563 inputAutoTrim: true,
10564 inputAttributes: {},
10565 inputValidator: undefined,
10566 returnInputValueOnDeny: false,
10567 validationMessage: undefined,
10568 grow: false,
10569 position: 'center',
10570 progressSteps: [],
10571 currentProgressStep: undefined,
10572 progressStepsDistance: undefined,
10573 willOpen: undefined,
10574 didOpen: undefined,
10575 didRender: undefined,
10576 willClose: undefined,
10577 didClose: undefined,
10578 didDestroy: undefined,
10579 scrollbarPadding: true,
10580 topLayer: false
10581 };
10582 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'];
10583
10584 /** @type {Record<string, string | undefined>} */
10585 const deprecatedParams = {
10586 allowEnterKey: undefined
10587 };
10588 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
10589
10590 /**
10591 * Is valid parameter
10592 *
10593 * @param {string} paramName
10594 * @returns {boolean}
10595 */
10596 const isValidParameter = paramName => {
10597 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
10598 };
10599
10600 /**
10601 * Is valid parameter for Swal.update() method
10602 *
10603 * @param {string} paramName
10604 * @returns {boolean}
10605 */
10606 const isUpdatableParameter = paramName => {
10607 return updatableParams.indexOf(paramName) !== -1;
10608 };
10609
10610 /**
10611 * Is deprecated parameter
10612 *
10613 * @param {string} paramName
10614 * @returns {string | undefined}
10615 */
10616 const isDeprecatedParameter = paramName => {
10617 return deprecatedParams[paramName];
10618 };
10619
10620 /**
10621 * @param {string} param
10622 */
10623 const checkIfParamIsValid = param => {
10624 if (!isValidParameter(param)) {
10625 warn(`Unknown parameter "${param}"`);
10626 }
10627 };
10628
10629 /**
10630 * @param {string} param
10631 */
10632 const checkIfToastParamIsValid = param => {
10633 if (toastIncompatibleParams.includes(param)) {
10634 warn(`The parameter "${param}" is incompatible with toasts`);
10635 }
10636 };
10637
10638 /**
10639 * @param {string} param
10640 */
10641 const checkIfParamIsDeprecated = param => {
10642 const isDeprecated = isDeprecatedParameter(param);
10643 if (isDeprecated) {
10644 warnAboutDeprecation(param, isDeprecated);
10645 }
10646 };
10647
10648 /**
10649 * Show relevant warnings for given params
10650 *
10651 * @param {SweetAlertOptions} params
10652 */
10653 const showWarningsForParams = params => {
10654 if (params.backdrop === false && params.allowOutsideClick) {
10655 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
10656 }
10657 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)) {
10658 warn(`Invalid theme "${params.theme}"`);
10659 }
10660 for (const param in params) {
10661 checkIfParamIsValid(param);
10662 if (params.toast) {
10663 checkIfToastParamIsValid(param);
10664 }
10665 checkIfParamIsDeprecated(param);
10666 }
10667 };
10668
10669 /**
10670 * Updates popup parameters.
10671 *
10672 * @this {any}
10673 * @param {SweetAlertOptions} params
10674 */
10675 function update(params) {
10676 const container = getContainer();
10677 const popup = getPopup();
10678 const innerParams = privateProps.innerParams.get(this);
10679 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
10680 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.`);
10681 return;
10682 }
10683 const validUpdatableParams = filterValidParams(params);
10684 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
10685 showWarningsForParams(updatedParams);
10686 if (container) {
10687 container.dataset['swal2Theme'] = updatedParams.theme;
10688 }
10689 render(this, updatedParams);
10690 privateProps.innerParams.set(this, updatedParams);
10691 Object.defineProperties(this, {
10692 params: {
10693 value: Object.assign({}, this.params, params),
10694 writable: false,
10695 enumerable: true
10696 }
10697 });
10698 }
10699
10700 /**
10701 * @param {SweetAlertOptions} params
10702 * @returns {SweetAlertOptions}
10703 */
10704 const filterValidParams = params => {
10705 /** @type {Record<string, any>} */
10706 const validUpdatableParams = {};
10707 Object.keys(params).forEach(param => {
10708 if (isUpdatableParameter(param)) {
10709 const typedParams = /** @type {Record<string, any>} */params;
10710 validUpdatableParams[param] = typedParams[param];
10711 } else {
10712 warn(`Invalid parameter to update: ${param}`);
10713 }
10714 });
10715 return validUpdatableParams;
10716 };
10717
10718 /**
10719 * Dispose the current SweetAlert2 instance
10720 * @this {SweetAlert}
10721 */
10722 function _destroy() {
10723 var _globalState$eventEmi;
10724 const domCache = privateProps.domCache.get(this);
10725 const innerParams = privateProps.innerParams.get(this);
10726 if (!innerParams) {
10727 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
10728 return; // This instance has already been destroyed
10729 }
10730
10731 // Check if there is another Swal closing
10732 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
10733 globalState.swalCloseEventFinishedCallback();
10734 delete globalState.swalCloseEventFinishedCallback;
10735 }
10736 if (typeof innerParams.didDestroy === 'function') {
10737 innerParams.didDestroy();
10738 }
10739 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
10740 disposeSwal(this);
10741 }
10742
10743 /**
10744 * @param {SweetAlert} instance
10745 */
10746 const disposeSwal = instance => {
10747 disposeWeakMaps(instance);
10748 // Unset this.params so GC will dispose it (#1569)
10749 // @ts-ignore
10750 delete instance.params;
10751 // Unset globalState props so GC will dispose globalState (#1569)
10752 delete globalState.keydownHandler;
10753 delete globalState.keydownTarget;
10754 // Unset currentInstance
10755 delete globalState.currentInstance;
10756 };
10757
10758 /**
10759 * @param {SweetAlert} instance
10760 */
10761 const disposeWeakMaps = instance => {
10762 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
10763 if (instance.isAwaitingPromise) {
10764 unsetWeakMaps(privateProps, instance);
10765 instance.isAwaitingPromise = true;
10766 } else {
10767 unsetWeakMaps(privateMethods, instance);
10768 unsetWeakMaps(privateProps, instance);
10769
10770 // @ts-ignore
10771 delete instance.isAwaitingPromise;
10772 // Unset instance methods
10773 // @ts-ignore
10774 delete instance.disableButtons;
10775 // @ts-ignore
10776 delete instance.enableButtons;
10777 // @ts-ignore
10778 delete instance.getInput;
10779 // @ts-ignore
10780 delete instance.disableInput;
10781 // @ts-ignore
10782 delete instance.enableInput;
10783 // @ts-ignore
10784 delete instance.hideLoading;
10785 // @ts-ignore
10786 delete instance.disableLoading;
10787 // @ts-ignore
10788 delete instance.showValidationMessage;
10789 // @ts-ignore
10790 delete instance.resetValidationMessage;
10791 // @ts-ignore
10792 delete instance.close;
10793 // @ts-ignore
10794 delete instance.closePopup;
10795 // @ts-ignore
10796 delete instance.closeModal;
10797 // @ts-ignore
10798 delete instance.closeToast;
10799 // @ts-ignore
10800 delete instance.rejectPromise;
10801 // @ts-ignore
10802 delete instance.update;
10803 // @ts-ignore
10804 delete instance._destroy;
10805 }
10806 };
10807
10808 /**
10809 * @param {Record<string, WeakMap<any, any>>} obj
10810 * @param {SweetAlert} instance
10811 */
10812 const unsetWeakMaps = (obj, instance) => {
10813 for (const i in obj) {
10814 obj[i].delete(instance);
10815 }
10816 };
10817
10818 var instanceMethods = /*#__PURE__*/Object.freeze({
10819 __proto__: null,
10820 _destroy: _destroy,
10821 close: close,
10822 closeModal: close,
10823 closePopup: close,
10824 closeToast: close,
10825 disableButtons: disableButtons,
10826 disableInput: disableInput,
10827 disableLoading: hideLoading,
10828 enableButtons: enableButtons,
10829 enableInput: enableInput,
10830 getInput: getInput,
10831 handleAwaitingPromise: handleAwaitingPromise,
10832 hideLoading: hideLoading,
10833 rejectPromise: rejectPromise,
10834 resetValidationMessage: resetValidationMessage,
10835 showValidationMessage: showValidationMessage,
10836 update: update
10837 });
10838
10839 /**
10840 * @param {SweetAlertOptions} innerParams
10841 * @param {DomCache} domCache
10842 * @param {(dismiss: DismissReason) => void} dismissWith
10843 */
10844 const handlePopupClick = (innerParams, domCache, dismissWith) => {
10845 if (innerParams.toast) {
10846 handleToastClick(innerParams, domCache, dismissWith);
10847 } else {
10848 // Ignore click events that had mousedown on the popup but mouseup on the container
10849 // This can happen when the user drags a slider
10850 handleModalMousedown(domCache);
10851
10852 // Ignore click events that had mousedown on the container but mouseup on the popup
10853 handleContainerMousedown(domCache);
10854 handleModalClick(innerParams, domCache, dismissWith);
10855 }
10856 };
10857
10858 /**
10859 * @param {SweetAlertOptions} innerParams
10860 * @param {DomCache} domCache
10861 * @param {(dismiss: DismissReason) => void} dismissWith
10862 */
10863 const handleToastClick = (innerParams, domCache, dismissWith) => {
10864 // Closing toast by internal click
10865 domCache.popup.onclick = () => {
10866 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
10867 return;
10868 }
10869 dismissWith(DismissReason.close);
10870 };
10871 };
10872
10873 /**
10874 * @param {SweetAlertOptions} innerParams
10875 * @returns {boolean}
10876 */
10877 const isAnyButtonShown = innerParams => {
10878 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
10879 };
10880 let ignoreOutsideClick = false;
10881
10882 /**
10883 * @param {DomCache} domCache
10884 */
10885 const handleModalMousedown = domCache => {
10886 domCache.popup.onmousedown = () => {
10887 domCache.container.onmouseup = function (e) {
10888 domCache.container.onmouseup = () => {};
10889 // We only check if the mouseup target is the container because usually it doesn't
10890 // have any other direct children aside of the popup
10891 if (e.target === domCache.container) {
10892 ignoreOutsideClick = true;
10893 }
10894 };
10895 };
10896 };
10897
10898 /**
10899 * @param {DomCache} domCache
10900 */
10901 const handleContainerMousedown = domCache => {
10902 domCache.container.onmousedown = e => {
10903 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
10904 if (e.target === domCache.container) {
10905 e.preventDefault();
10906 }
10907 domCache.popup.onmouseup = function (e) {
10908 domCache.popup.onmouseup = () => {};
10909 // We also need to check if the mouseup target is a child of the popup
10910 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
10911 ignoreOutsideClick = true;
10912 }
10913 };
10914 };
10915 };
10916
10917 /**
10918 * @param {SweetAlertOptions} innerParams
10919 * @param {DomCache} domCache
10920 * @param {(dismiss: DismissReason) => void} dismissWith
10921 */
10922 const handleModalClick = (innerParams, domCache, dismissWith) => {
10923 domCache.container.onclick = e => {
10924 if (ignoreOutsideClick) {
10925 ignoreOutsideClick = false;
10926 return;
10927 }
10928 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
10929 dismissWith(DismissReason.backdrop);
10930 }
10931 };
10932 };
10933
10934 /**
10935 * @param {any} elem
10936 * @returns {boolean}
10937 */
10938 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
10939
10940 /**
10941 * @param {any} elem
10942 * @returns {boolean}
10943 */
10944 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
10945
10946 /**
10947 * @param {any[]} args
10948 * @returns {SweetAlertOptions}
10949 */
10950 const argsToParams = args => {
10951 /** @type {Record<string, any>} */
10952 const params = {};
10953 if (typeof args[0] === 'object' && !isElement(args[0])) {
10954 Object.assign(params, args[0]);
10955 } else {
10956 ['title', 'html', 'icon'].forEach((name, index) => {
10957 const arg = args[index];
10958 if (typeof arg === 'string' || isElement(arg)) {
10959 params[name] = arg;
10960 } else if (arg !== undefined) {
10961 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
10962 }
10963 });
10964 }
10965 return params;
10966 };
10967
10968 /**
10969 * Main method to create a new SweetAlert2 popup
10970 *
10971 * @this {new (...args: any[]) => any}
10972 * @param {...SweetAlertOptions} args
10973 * @returns {Promise<SweetAlertResult>}
10974 */
10975 function fire(...args) {
10976 return new this(...args);
10977 }
10978
10979 /**
10980 * Returns an extended version of `Swal` containing `params` as defaults.
10981 * Useful for reusing Swal configuration.
10982 *
10983 * For example:
10984 *
10985 * Before:
10986 * const textPromptOptions = { input: 'text', showCancelButton: true }
10987 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
10988 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
10989 *
10990 * After:
10991 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
10992 * const {value: firstName} = await TextPrompt('What is your first name?')
10993 * const {value: lastName} = await TextPrompt('What is your last name?')
10994 *
10995 * @param {SweetAlertOptions} mixinParams
10996 * @returns {SweetAlert}
10997 * @this {typeof import('../SweetAlert.js').SweetAlert}
10998 */
10999 function mixin(mixinParams) {
11000 // @ts-ignore: 'this' refers to the SweetAlert constructor
11001 class MixinSwal extends this {
11002 /**
11003 * @param {any} params
11004 * @param {any} priorityMixinParams
11005 */
11006 _main(params, priorityMixinParams) {
11007 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
11008 }
11009 }
11010 // @ts-ignore
11011 return MixinSwal;
11012 }
11013
11014 /**
11015 * If `timer` parameter is set, returns number of milliseconds of timer remained.
11016 * Otherwise, returns undefined.
11017 *
11018 * @returns {number | undefined}
11019 */
11020 const getTimerLeft = () => {
11021 return globalState.timeout && globalState.timeout.getTimerLeft();
11022 };
11023
11024 /**
11025 * Stop timer. Returns number of milliseconds of timer remained.
11026 * If `timer` parameter isn't set, returns undefined.
11027 *
11028 * @returns {number | undefined}
11029 */
11030 const stopTimer = () => {
11031 if (globalState.timeout) {
11032 stopTimerProgressBar();
11033 return globalState.timeout.stop();
11034 }
11035 };
11036
11037 /**
11038 * Resume timer. Returns number of milliseconds of timer remained.
11039 * If `timer` parameter isn't set, returns undefined.
11040 *
11041 * @returns {number | undefined}
11042 */
11043 const resumeTimer = () => {
11044 if (globalState.timeout) {
11045 const remaining = globalState.timeout.start();
11046 animateTimerProgressBar(remaining);
11047 return remaining;
11048 }
11049 };
11050
11051 /**
11052 * Resume timer. Returns number of milliseconds of timer remained.
11053 * If `timer` parameter isn't set, returns undefined.
11054 *
11055 * @returns {number | undefined}
11056 */
11057 const toggleTimer = () => {
11058 const timer = globalState.timeout;
11059 return timer && (timer.running ? stopTimer() : resumeTimer());
11060 };
11061
11062 /**
11063 * Increase timer. Returns number of milliseconds of an updated timer.
11064 * If `timer` parameter isn't set, returns undefined.
11065 *
11066 * @param {number} ms
11067 * @returns {number | undefined}
11068 */
11069 const increaseTimer = ms => {
11070 if (globalState.timeout) {
11071 const remaining = globalState.timeout.increase(ms);
11072 animateTimerProgressBar(remaining, true);
11073 return remaining;
11074 }
11075 };
11076
11077 /**
11078 * Check if timer is running. Returns true if timer is running
11079 * or false if timer is paused or stopped.
11080 * If `timer` parameter isn't set, returns undefined
11081 *
11082 * @returns {boolean}
11083 */
11084 const isTimerRunning = () => {
11085 return Boolean(globalState.timeout && globalState.timeout.isRunning());
11086 };
11087
11088 let bodyClickListenerAdded = false;
11089 /** @type {Record<string, any>} */
11090 const clickHandlers = {};
11091
11092 /**
11093 * @this {any}
11094 * @param {string} attr
11095 */
11096 function bindClickHandler(attr = 'data-swal-template') {
11097 clickHandlers[attr] = this;
11098 if (!bodyClickListenerAdded) {
11099 document.body.addEventListener('click', bodyClickListener);
11100 bodyClickListenerAdded = true;
11101 }
11102 }
11103
11104 /**
11105 * @param {MouseEvent} event
11106 */
11107 const bodyClickListener = event => {
11108 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
11109 for (const attr in clickHandlers) {
11110 const template = el.getAttribute && el.getAttribute(attr);
11111 if (template) {
11112 clickHandlers[attr].fire({
11113 template
11114 });
11115 return;
11116 }
11117 }
11118 }
11119 };
11120
11121 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
11122
11123 class EventEmitter {
11124 constructor() {
11125 /** @type {Events} */
11126 this.events = {};
11127 }
11128
11129 /**
11130 * @param {string} eventName
11131 * @returns {EventHandlers}
11132 */
11133 _getHandlersByEventName(eventName) {
11134 if (typeof this.events[eventName] === 'undefined') {
11135 // not Set because we need to keep the FIFO order
11136 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
11137 this.events[eventName] = [];
11138 }
11139 return this.events[eventName];
11140 }
11141
11142 /**
11143 * @param {string} eventName
11144 * @param {EventHandler} eventHandler
11145 */
11146 on(eventName, eventHandler) {
11147 const currentHandlers = this._getHandlersByEventName(eventName);
11148 if (!currentHandlers.includes(eventHandler)) {
11149 currentHandlers.push(eventHandler);
11150 }
11151 }
11152
11153 /**
11154 * @param {string} eventName
11155 * @param {EventHandler} eventHandler
11156 */
11157 once(eventName, eventHandler) {
11158 /**
11159 * @param {...any} args
11160 */
11161 const onceFn = (...args) => {
11162 this.removeListener(eventName, onceFn);
11163 // @ts-ignore
11164 eventHandler.apply(this, args);
11165 };
11166 this.on(eventName, onceFn);
11167 }
11168
11169 /**
11170 * @param {string} eventName
11171 * @param {...any} args
11172 */
11173 emit(eventName, ...args) {
11174 this._getHandlersByEventName(eventName).forEach(
11175 /**
11176 * @param {EventHandler} eventHandler
11177 */
11178 eventHandler => {
11179 try {
11180 // @ts-ignore
11181 eventHandler.apply(this, args);
11182 } catch (error) {
11183 console.error(error);
11184 }
11185 });
11186 }
11187
11188 /**
11189 * @param {string} eventName
11190 * @param {EventHandler} eventHandler
11191 */
11192 removeListener(eventName, eventHandler) {
11193 const currentHandlers = this._getHandlersByEventName(eventName);
11194 const index = currentHandlers.indexOf(eventHandler);
11195 if (index > -1) {
11196 currentHandlers.splice(index, 1);
11197 }
11198 }
11199
11200 /**
11201 * @param {string} eventName
11202 */
11203 removeAllListeners(eventName) {
11204 if (this.events[eventName] !== undefined) {
11205 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
11206 this.events[eventName].length = 0;
11207 }
11208 }
11209 reset() {
11210 this.events = {};
11211 }
11212 }
11213
11214 globalState.eventEmitter = new EventEmitter();
11215
11216 /**
11217 * @param {string} eventName
11218 * @param {EventHandler} eventHandler
11219 */
11220 const on = (eventName, eventHandler) => {
11221 if (globalState.eventEmitter) {
11222 globalState.eventEmitter.on(eventName, eventHandler);
11223 }
11224 };
11225
11226 /**
11227 * @param {string} eventName
11228 * @param {EventHandler} eventHandler
11229 */
11230 const once = (eventName, eventHandler) => {
11231 if (globalState.eventEmitter) {
11232 globalState.eventEmitter.once(eventName, eventHandler);
11233 }
11234 };
11235
11236 /**
11237 * @param {string} [eventName]
11238 * @param {EventHandler} [eventHandler]
11239 */
11240 const off = (eventName, eventHandler) => {
11241 if (!globalState.eventEmitter) {
11242 return;
11243 }
11244
11245 // Remove all handlers for all events
11246 if (!eventName) {
11247 globalState.eventEmitter.reset();
11248 return;
11249 }
11250 if (eventHandler) {
11251 // Remove a specific handler
11252 globalState.eventEmitter.removeListener(eventName, eventHandler);
11253 } else {
11254 // Remove all handlers for a specific event
11255 globalState.eventEmitter.removeAllListeners(eventName);
11256 }
11257 };
11258
11259 var staticMethods = /*#__PURE__*/Object.freeze({
11260 __proto__: null,
11261 argsToParams: argsToParams,
11262 bindClickHandler: bindClickHandler,
11263 clickCancel: clickCancel,
11264 clickConfirm: clickConfirm,
11265 clickDeny: clickDeny,
11266 enableLoading: showLoading,
11267 fire: fire,
11268 getActions: getActions,
11269 getCancelButton: getCancelButton,
11270 getCloseButton: getCloseButton,
11271 getConfirmButton: getConfirmButton,
11272 getContainer: getContainer,
11273 getDenyButton: getDenyButton,
11274 getFocusableElements: getFocusableElements,
11275 getFooter: getFooter,
11276 getHtmlContainer: getHtmlContainer,
11277 getIcon: getIcon,
11278 getIconContent: getIconContent,
11279 getImage: getImage,
11280 getInputLabel: getInputLabel,
11281 getLoader: getLoader,
11282 getPopup: getPopup,
11283 getProgressSteps: getProgressSteps,
11284 getTimerLeft: getTimerLeft,
11285 getTimerProgressBar: getTimerProgressBar,
11286 getTitle: getTitle,
11287 getValidationMessage: getValidationMessage,
11288 increaseTimer: increaseTimer,
11289 isDeprecatedParameter: isDeprecatedParameter,
11290 isLoading: isLoading,
11291 isTimerRunning: isTimerRunning,
11292 isUpdatableParameter: isUpdatableParameter,
11293 isValidParameter: isValidParameter,
11294 isVisible: isVisible,
11295 mixin: mixin,
11296 off: off,
11297 on: on,
11298 once: once,
11299 resumeTimer: resumeTimer,
11300 showLoading: showLoading,
11301 stopTimer: stopTimer,
11302 toggleTimer: toggleTimer
11303 });
11304
11305 class Timer {
11306 /**
11307 * @param {() => void} callback
11308 * @param {number} delay
11309 */
11310 constructor(callback, delay) {
11311 this.callback = callback;
11312 this.remaining = delay;
11313 this.running = false;
11314 this.start();
11315 }
11316
11317 /**
11318 * @returns {number}
11319 */
11320 start() {
11321 if (!this.running) {
11322 this.running = true;
11323 this.started = new Date();
11324 this.id = setTimeout(this.callback, this.remaining);
11325 }
11326 return this.remaining;
11327 }
11328
11329 /**
11330 * @returns {number}
11331 */
11332 stop() {
11333 if (this.started && this.running) {
11334 this.running = false;
11335 clearTimeout(this.id);
11336 this.remaining -= new Date().getTime() - this.started.getTime();
11337 }
11338 return this.remaining;
11339 }
11340
11341 /**
11342 * @param {number} n
11343 * @returns {number}
11344 */
11345 increase(n) {
11346 const running = this.running;
11347 if (running) {
11348 this.stop();
11349 }
11350 this.remaining += n;
11351 if (running) {
11352 this.start();
11353 }
11354 return this.remaining;
11355 }
11356
11357 /**
11358 * @returns {number}
11359 */
11360 getTimerLeft() {
11361 if (this.running) {
11362 this.stop();
11363 this.start();
11364 }
11365 return this.remaining;
11366 }
11367
11368 /**
11369 * @returns {boolean}
11370 */
11371 isRunning() {
11372 return this.running;
11373 }
11374 }
11375
11376 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
11377
11378 /**
11379 * @param {SweetAlertOptions} params
11380 * @returns {SweetAlertOptions}
11381 */
11382 const getTemplateParams = params => {
11383 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
11384 if (!template) {
11385 return {};
11386 }
11387 /** @type {DocumentFragment} */
11388 const templateContent = template.content;
11389 showWarningsForElements(templateContent);
11390 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
11391 return result;
11392 };
11393
11394 /**
11395 * @param {DocumentFragment} templateContent
11396 * @returns {Record<string, string | boolean | number>}
11397 */
11398 const getSwalParams = templateContent => {
11399 /** @type {Record<string, string | boolean | number>} */
11400 const result = {};
11401 /** @type {HTMLElement[]} */
11402 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
11403 swalParams.forEach(param => {
11404 showWarningsForAttributes(param, ['name', 'value']);
11405 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
11406 const value = param.getAttribute('value');
11407 if (!paramName || !value) {
11408 return;
11409 }
11410 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
11411 result[paramName] = value !== 'false';
11412 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
11413 result[paramName] = JSON.parse(value);
11414 } else {
11415 result[paramName] = value;
11416 }
11417 });
11418 return result;
11419 };
11420
11421 /**
11422 * @param {DocumentFragment} templateContent
11423 * @returns {Record<string, () => void>}
11424 */
11425 const getSwalFunctionParams = templateContent => {
11426 /** @type {Record<string, () => void>} */
11427 const result = {};
11428 /** @type {HTMLElement[]} */
11429 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
11430 swalFunctions.forEach(param => {
11431 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
11432 const value = param.getAttribute('value');
11433 if (!paramName || !value) {
11434 return;
11435 }
11436 result[paramName] = new Function(`return ${value}`)();
11437 });
11438 return result;
11439 };
11440
11441 /**
11442 * @param {DocumentFragment} templateContent
11443 * @returns {Record<string, string | boolean>}
11444 */
11445 const getSwalButtons = templateContent => {
11446 /** @type {Record<string, string | boolean>} */
11447 const result = {};
11448 /** @type {HTMLElement[]} */
11449 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
11450 swalButtons.forEach(button => {
11451 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
11452 const type = button.getAttribute('type');
11453 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
11454 return;
11455 }
11456 result[`${type}ButtonText`] = button.innerHTML;
11457 result[`show${capitalizeFirstLetter(type)}Button`] = true;
11458 if (button.hasAttribute('color')) {
11459 const color = button.getAttribute('color');
11460 if (color !== null) {
11461 result[`${type}ButtonColor`] = color;
11462 }
11463 }
11464 if (button.hasAttribute('aria-label')) {
11465 const ariaLabel = button.getAttribute('aria-label');
11466 if (ariaLabel !== null) {
11467 result[`${type}ButtonAriaLabel`] = ariaLabel;
11468 }
11469 }
11470 });
11471 return result;
11472 };
11473
11474 /**
11475 * @param {DocumentFragment} templateContent
11476 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
11477 */
11478 const getSwalImage = templateContent => {
11479 const result = {};
11480 /** @type {HTMLElement | null} */
11481 const image = templateContent.querySelector('swal-image');
11482 if (image) {
11483 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
11484 if (image.hasAttribute('src')) {
11485 result.imageUrl = image.getAttribute('src') || undefined;
11486 }
11487 if (image.hasAttribute('width')) {
11488 result.imageWidth = image.getAttribute('width') || undefined;
11489 }
11490 if (image.hasAttribute('height')) {
11491 result.imageHeight = image.getAttribute('height') || undefined;
11492 }
11493 if (image.hasAttribute('alt')) {
11494 result.imageAlt = image.getAttribute('alt') || undefined;
11495 }
11496 }
11497 return result;
11498 };
11499
11500 /**
11501 * @param {DocumentFragment} templateContent
11502 * @returns {object}
11503 */
11504 const getSwalIcon = templateContent => {
11505 const result = {};
11506 /** @type {HTMLElement | null} */
11507 const icon = templateContent.querySelector('swal-icon');
11508 if (icon) {
11509 showWarningsForAttributes(icon, ['type', 'color']);
11510 if (icon.hasAttribute('type')) {
11511 result.icon = icon.getAttribute('type');
11512 }
11513 if (icon.hasAttribute('color')) {
11514 result.iconColor = icon.getAttribute('color');
11515 }
11516 result.iconHtml = icon.innerHTML;
11517 }
11518 return result;
11519 };
11520
11521 /**
11522 * @param {DocumentFragment} templateContent
11523 * @returns {object}
11524 */
11525 const getSwalInput = templateContent => {
11526 /** @type {Record<string, any>} */
11527 const result = {};
11528 /** @type {HTMLElement | null} */
11529 const input = templateContent.querySelector('swal-input');
11530 if (input) {
11531 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
11532 result.input = input.getAttribute('type') || 'text';
11533 if (input.hasAttribute('label')) {
11534 result.inputLabel = input.getAttribute('label');
11535 }
11536 if (input.hasAttribute('placeholder')) {
11537 result.inputPlaceholder = input.getAttribute('placeholder');
11538 }
11539 if (input.hasAttribute('value')) {
11540 result.inputValue = input.getAttribute('value');
11541 }
11542 }
11543 /** @type {HTMLElement[]} */
11544 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
11545 if (inputOptions.length) {
11546 result.inputOptions = {};
11547 inputOptions.forEach(option => {
11548 showWarningsForAttributes(option, ['value']);
11549 const optionValue = option.getAttribute('value');
11550 if (!optionValue) {
11551 return;
11552 }
11553 const optionName = option.innerHTML;
11554 result.inputOptions[optionValue] = optionName;
11555 });
11556 }
11557 return result;
11558 };
11559
11560 /**
11561 * @param {DocumentFragment} templateContent
11562 * @param {string[]} paramNames
11563 * @returns {Record<string, string>}
11564 */
11565 const getSwalStringParams = (templateContent, paramNames) => {
11566 /** @type {Record<string, string>} */
11567 const result = {};
11568 for (const i in paramNames) {
11569 const paramName = paramNames[i];
11570 /** @type {HTMLElement | null} */
11571 const tag = templateContent.querySelector(paramName);
11572 if (tag) {
11573 showWarningsForAttributes(tag, []);
11574 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
11575 }
11576 }
11577 return result;
11578 };
11579
11580 /**
11581 * @param {DocumentFragment} templateContent
11582 */
11583 const showWarningsForElements = templateContent => {
11584 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
11585 Array.from(templateContent.children).forEach(el => {
11586 const tagName = el.tagName.toLowerCase();
11587 if (!allowedElements.includes(tagName)) {
11588 warn(`Unrecognized element <${tagName}>`);
11589 }
11590 });
11591 };
11592
11593 /**
11594 * @param {HTMLElement} el
11595 * @param {string[]} allowedAttributes
11596 */
11597 const showWarningsForAttributes = (el, allowedAttributes) => {
11598 Array.from(el.attributes).forEach(attribute => {
11599 if (allowedAttributes.indexOf(attribute.name) === -1) {
11600 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.'}`]);
11601 }
11602 });
11603 };
11604
11605 const SHOW_CLASS_TIMEOUT = 10;
11606
11607 /**
11608 * Open popup, add necessary classes and styles, fix scrollbar
11609 *
11610 * @param {SweetAlertOptions} params
11611 */
11612 const openPopup = params => {
11613 var _globalState$eventEmi, _globalState$eventEmi2;
11614 const container = getContainer();
11615 const popup = getPopup();
11616 if (!container || !popup) {
11617 return;
11618 }
11619 if (typeof params.willOpen === 'function') {
11620 params.willOpen(popup);
11621 }
11622 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
11623 const bodyStyles = window.getComputedStyle(document.body);
11624 const initialBodyOverflow = bodyStyles.overflowY;
11625 addClasses(container, popup, params);
11626
11627 // scrolling is 'hidden' until animation is done, after that 'auto'
11628 setTimeout(() => {
11629 setScrollingVisibility(container, popup);
11630 }, SHOW_CLASS_TIMEOUT);
11631 if (isModal()) {
11632 // Using ternary instead of ?? operator for Webpack 4 compatibility
11633 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
11634 setAriaHidden();
11635 }
11636 if (!isToast() && !globalState.previousActiveElement) {
11637 globalState.previousActiveElement = document.activeElement;
11638 }
11639 if (typeof params.didOpen === 'function') {
11640 const didOpen = params.didOpen;
11641 setTimeout(() => didOpen(popup));
11642 }
11643 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
11644 };
11645
11646 /**
11647 * @param {Event} event
11648 */
11649 const swalOpenAnimationFinished = event => {
11650 const popup = getPopup();
11651 if (!popup || event.target !== popup) {
11652 return;
11653 }
11654 const container = getContainer();
11655 if (!container) {
11656 return;
11657 }
11658 popup.removeEventListener('animationend', swalOpenAnimationFinished);
11659 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
11660 container.style.overflowY = 'auto';
11661
11662 // no-transition is added in init() in case one swal is opened right after another
11663 removeClass(container, swalClasses['no-transition']);
11664 };
11665
11666 /**
11667 * @param {HTMLElement} container
11668 * @param {HTMLElement} popup
11669 */
11670 const setScrollingVisibility = (container, popup) => {
11671 if (hasCssAnimation(popup)) {
11672 container.style.overflowY = 'hidden';
11673 popup.addEventListener('animationend', swalOpenAnimationFinished);
11674 popup.addEventListener('transitionend', swalOpenAnimationFinished);
11675 } else {
11676 container.style.overflowY = 'auto';
11677 }
11678 };
11679
11680 /**
11681 * @param {HTMLElement} container
11682 * @param {boolean} scrollbarPadding
11683 * @param {string} initialBodyOverflow
11684 */
11685 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
11686 iOSfix();
11687 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
11688 replaceScrollbarWithPadding(initialBodyOverflow);
11689 }
11690
11691 // sweetalert2/issues/1247
11692 setTimeout(() => {
11693 container.scrollTop = 0;
11694 });
11695 };
11696
11697 /**
11698 * @param {HTMLElement} container
11699 * @param {HTMLElement} popup
11700 * @param {SweetAlertOptions} params
11701 */
11702 const addClasses = (container, popup, params) => {
11703 var _params$showClass;
11704 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
11705 addClass(container, params.showClass.backdrop);
11706 }
11707 if (params.animation) {
11708 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
11709 popup.style.setProperty('opacity', '0', 'important');
11710 show(popup, 'grid');
11711 setTimeout(() => {
11712 var _params$showClass2;
11713 // Animate popup right after showing it
11714 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
11715 addClass(popup, params.showClass.popup);
11716 }
11717 // and remove the opacity workaround
11718 popup.style.removeProperty('opacity');
11719 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
11720 } else {
11721 show(popup, 'grid');
11722 }
11723 addClass([document.documentElement, document.body], swalClasses.shown);
11724 if (params.heightAuto && params.backdrop && !params.toast) {
11725 addClass([document.documentElement, document.body], swalClasses['height-auto']);
11726 }
11727 };
11728
11729 var defaultInputValidators = {
11730 /**
11731 * @param {string} string
11732 * @param {string} [validationMessage]
11733 * @returns {Promise<string | void>}
11734 */
11735 email: (string, validationMessage) => {
11736 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
11737 },
11738 /**
11739 * @param {string} string
11740 * @param {string} [validationMessage]
11741 * @returns {Promise<string | void>}
11742 */
11743 url: (string, validationMessage) => {
11744 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
11745 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');
11746 }
11747 };
11748
11749 /**
11750 * @param {SweetAlertOptions} params
11751 */
11752 function setDefaultInputValidators(params) {
11753 // Use default `inputValidator` for supported input types if not provided
11754 if (params.inputValidator) {
11755 return;
11756 }
11757 if (params.input === 'email') {
11758 params.inputValidator = defaultInputValidators['email'];
11759 }
11760 if (params.input === 'url') {
11761 params.inputValidator = defaultInputValidators['url'];
11762 }
11763 }
11764
11765 /**
11766 * @param {SweetAlertOptions} params
11767 */
11768 function validateCustomTargetElement(params) {
11769 // Determine if the custom target element is valid
11770 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
11771 warn('Target parameter is not valid, defaulting to "body"');
11772 params.target = 'body';
11773 }
11774 }
11775
11776 /**
11777 * Set type, text and actions on popup
11778 *
11779 * @param {SweetAlertOptions} params
11780 */
11781 function setParameters(params) {
11782 setDefaultInputValidators(params);
11783
11784 // showLoaderOnConfirm && preConfirm
11785 if (params.showLoaderOnConfirm && !params.preConfirm) {
11786 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');
11787 }
11788 validateCustomTargetElement(params);
11789
11790 // Replace newlines with <br> in title
11791 if (typeof params.title === 'string') {
11792 params.title = params.title.split('\n').join('<br />');
11793 }
11794 init(params);
11795 }
11796
11797 /** @type {SweetAlert} */
11798 let currentInstance;
11799 var _promise = /*#__PURE__*/new WeakMap();
11800 class SweetAlert {
11801 /**
11802 * @param {...(SweetAlertOptions | string)} args
11803 * @this {SweetAlert}
11804 */
11805 constructor(...args) {
11806 /**
11807 * @type {Promise<SweetAlertResult>}
11808 */
11809 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */Promise.resolve({
11810 isConfirmed: false,
11811 isDenied: false,
11812 isDismissed: true
11813 }));
11814 // Prevent run in Node env
11815 if (typeof window === 'undefined') {
11816 return;
11817 }
11818 currentInstance = this;
11819
11820 // @ts-ignore
11821 const outerParams = Object.freeze(this.constructor.argsToParams(args));
11822
11823 /** @type {Readonly<SweetAlertOptions>} */
11824 this.params = outerParams;
11825
11826 /** @type {boolean} */
11827 this.isAwaitingPromise = false;
11828 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
11829 }
11830
11831 /**
11832 * @param {any} userParams
11833 * @param {any} mixinParams
11834 */
11835 _main(userParams, mixinParams = {}) {
11836 showWarningsForParams(Object.assign({}, mixinParams, userParams));
11837 if (globalState.currentInstance) {
11838 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
11839 const {
11840 isAwaitingPromise
11841 } = globalState.currentInstance;
11842 globalState.currentInstance._destroy();
11843 if (!isAwaitingPromise) {
11844 swalPromiseResolve({
11845 isDismissed: true
11846 });
11847 }
11848 if (isModal()) {
11849 unsetAriaHidden();
11850 }
11851 }
11852 globalState.currentInstance = currentInstance;
11853 const innerParams = prepareParams(userParams, mixinParams);
11854 setParameters(innerParams);
11855 Object.freeze(innerParams);
11856
11857 // clear the previous timer
11858 if (globalState.timeout) {
11859 globalState.timeout.stop();
11860 delete globalState.timeout;
11861 }
11862
11863 // clear the restore focus timeout
11864 clearTimeout(globalState.restoreFocusTimeout);
11865 const domCache = populateDomCache(currentInstance);
11866 render(currentInstance, innerParams);
11867 privateProps.innerParams.set(currentInstance, innerParams);
11868 return swalPromise(currentInstance, domCache, innerParams);
11869 }
11870
11871 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
11872 /**
11873 * @param {any} onFulfilled
11874 */
11875 then(onFulfilled) {
11876 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
11877 }
11878
11879 /**
11880 * @param {any} onFinally
11881 */
11882 finally(onFinally) {
11883 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
11884 }
11885 }
11886
11887 /**
11888 * @param {SweetAlert} instance
11889 * @param {DomCache} domCache
11890 * @param {SweetAlertOptions} innerParams
11891 * @returns {Promise<SweetAlertResult>}
11892 */
11893 const swalPromise = (instance, domCache, innerParams) => {
11894 return new Promise((resolve, reject) => {
11895 // functions to handle all closings/dismissals
11896 /**
11897 * @param {DismissReason} dismiss
11898 */
11899 const dismissWith = dismiss => {
11900 instance.close({
11901 isDismissed: true,
11902 dismiss,
11903 isConfirmed: false,
11904 isDenied: false
11905 });
11906 };
11907 privateMethods.swalPromiseResolve.set(instance, resolve);
11908 privateMethods.swalPromiseReject.set(instance, reject);
11909 domCache.confirmButton.onclick = () => {
11910 handleConfirmButtonClick(instance);
11911 };
11912 domCache.denyButton.onclick = () => {
11913 handleDenyButtonClick(instance);
11914 };
11915 domCache.cancelButton.onclick = () => {
11916 handleCancelButtonClick(instance, dismissWith);
11917 };
11918 domCache.closeButton.onclick = () => {
11919 dismissWith(DismissReason.close);
11920 };
11921 handlePopupClick(innerParams, domCache, dismissWith);
11922 addKeydownHandler(globalState, innerParams, dismissWith);
11923 handleInputOptionsAndValue(instance, innerParams);
11924 openPopup(innerParams);
11925 setupTimer(globalState, innerParams, dismissWith);
11926 initFocus(domCache, innerParams);
11927
11928 // Scroll container to top on open (#1247, #1946)
11929 setTimeout(() => {
11930 domCache.container.scrollTop = 0;
11931 });
11932 });
11933 };
11934
11935 /**
11936 * @param {SweetAlertOptions} userParams
11937 * @param {SweetAlertOptions} mixinParams
11938 * @returns {SweetAlertOptions}
11939 */
11940 const prepareParams = (userParams, mixinParams) => {
11941 const templateParams = getTemplateParams(userParams);
11942 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
11943 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
11944 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
11945 if (params.animation === false) {
11946 params.showClass = {
11947 backdrop: 'swal2-noanimation'
11948 };
11949 params.hideClass = {};
11950 }
11951 return params;
11952 };
11953
11954 /**
11955 * @param {SweetAlert} instance
11956 * @returns {DomCache}
11957 */
11958 const populateDomCache = instance => {
11959 const domCache = /** @type {DomCache} */{
11960 popup: (/** @type {HTMLElement} */getPopup()),
11961 container: (/** @type {HTMLElement} */getContainer()),
11962 actions: (/** @type {HTMLElement} */getActions()),
11963 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
11964 denyButton: (/** @type {HTMLElement} */getDenyButton()),
11965 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
11966 loader: (/** @type {HTMLElement} */getLoader()),
11967 closeButton: (/** @type {HTMLElement} */getCloseButton()),
11968 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
11969 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
11970 };
11971 privateProps.domCache.set(instance, domCache);
11972 return domCache;
11973 };
11974
11975 /**
11976 * @param {GlobalState} globalState
11977 * @param {SweetAlertOptions} innerParams
11978 * @param {(dismiss: DismissReason) => void} dismissWith
11979 */
11980 const setupTimer = (globalState, innerParams, dismissWith) => {
11981 const timerProgressBar = getTimerProgressBar();
11982 hide(timerProgressBar);
11983 if (innerParams.timer) {
11984 globalState.timeout = new Timer(() => {
11985 dismissWith('timer');
11986 delete globalState.timeout;
11987 }, innerParams.timer);
11988 if (innerParams.timerProgressBar && timerProgressBar) {
11989 show(timerProgressBar);
11990 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
11991 setTimeout(() => {
11992 if (globalState.timeout && globalState.timeout.running) {
11993 // timer can be already stopped or unset at this point
11994 animateTimerProgressBar(/** @type {number} */innerParams.timer);
11995 }
11996 });
11997 }
11998 }
11999 };
12000
12001 /**
12002 * Initialize focus in the popup:
12003 *
12004 * 1. If `toast` is `true`, don't steal focus from the document.
12005 * 2. Else if there is an [autofocus] element, focus it.
12006 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
12007 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
12008 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
12009 * 6. Else focus the first focusable element in a popup (if any).
12010 *
12011 * @param {DomCache} domCache
12012 * @param {SweetAlertOptions} innerParams
12013 */
12014 const initFocus = (domCache, innerParams) => {
12015 if (innerParams.toast) {
12016 return;
12017 }
12018 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
12019 if (!callIfFunction(innerParams.allowEnterKey)) {
12020 warnAboutDeprecation('allowEnterKey');
12021 blurActiveElement();
12022 return;
12023 }
12024 if (focusAutofocus(domCache)) {
12025 return;
12026 }
12027 if (focusButton(domCache, innerParams)) {
12028 return;
12029 }
12030 setFocus(-1, 1);
12031 };
12032
12033 /**
12034 * @param {DomCache} domCache
12035 * @returns {boolean}
12036 */
12037 const focusAutofocus = domCache => {
12038 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
12039 for (const autofocusElement of autofocusElements) {
12040 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
12041 autofocusElement.focus();
12042 return true;
12043 }
12044 }
12045 return false;
12046 };
12047
12048 /**
12049 * @param {DomCache} domCache
12050 * @param {SweetAlertOptions} innerParams
12051 * @returns {boolean}
12052 */
12053 const focusButton = (domCache, innerParams) => {
12054 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
12055 domCache.denyButton.focus();
12056 return true;
12057 }
12058 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
12059 domCache.cancelButton.focus();
12060 return true;
12061 }
12062 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
12063 domCache.confirmButton.focus();
12064 return true;
12065 }
12066 return false;
12067 };
12068 const blurActiveElement = () => {
12069 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
12070 document.activeElement.blur();
12071 }
12072 };
12073
12074 // Assign instance methods from src/instanceMethods/*.js to prototype
12075 SweetAlert.prototype.disableButtons = disableButtons;
12076 SweetAlert.prototype.enableButtons = enableButtons;
12077 SweetAlert.prototype.getInput = getInput;
12078 SweetAlert.prototype.disableInput = disableInput;
12079 SweetAlert.prototype.enableInput = enableInput;
12080 SweetAlert.prototype.hideLoading = hideLoading;
12081 SweetAlert.prototype.disableLoading = hideLoading;
12082 SweetAlert.prototype.showValidationMessage = showValidationMessage;
12083 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
12084 SweetAlert.prototype.close = close;
12085 SweetAlert.prototype.closePopup = close;
12086 SweetAlert.prototype.closeModal = close;
12087 SweetAlert.prototype.closeToast = close;
12088 SweetAlert.prototype.rejectPromise = rejectPromise;
12089 SweetAlert.prototype.update = update;
12090 SweetAlert.prototype._destroy = _destroy;
12091
12092 // Assign static methods from src/staticMethods/*.js to constructor
12093 Object.assign(SweetAlert, staticMethods);
12094
12095 // Proxy to instance methods to constructor, for now, for backwards compatibility
12096 Object.keys(instanceMethods).forEach(key => {
12097 /**
12098 * @param {...(SweetAlertOptions | string | undefined)} args
12099 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
12100 */
12101 // @ts-ignore: Dynamic property assignment for backwards compatibility
12102 SweetAlert[key] = function (...args) {
12103 // @ts-ignore
12104 if (currentInstance && currentInstance[key]) {
12105 // @ts-ignore
12106 return currentInstance[key](...args);
12107 }
12108 return undefined;
12109 };
12110 });
12111 SweetAlert.DismissReason = DismissReason;
12112 SweetAlert.version = '11.26.17';
12113
12114 const Swal = SweetAlert;
12115 // @ts-ignore
12116 Swal.default = Swal;
12117
12118 return Swal;
12119
12120 }));
12121 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
12122 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-icon-animations: true;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem;container-name:swal2-popup}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}@container swal2-popup style(--swal2-icon-animations:true){.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
12123
12124 /***/ },
12125
12126 /***/ "./node_modules/toastify-js/src/toastify.js"
12127 /*!**************************************************!*\
12128 !*** ./node_modules/toastify-js/src/toastify.js ***!
12129 \**************************************************/
12130 (module) {
12131
12132 /*!
12133 * Toastify js 1.12.0
12134 * https://github.com/apvarun/toastify-js
12135 * @license MIT licensed
12136 *
12137 * Copyright (C) 2018 Varun A P
12138 */
12139 (function(root, factory) {
12140 if ( true && module.exports) {
12141 module.exports = factory();
12142 } else {
12143 root.Toastify = factory();
12144 }
12145 })(this, function(global) {
12146 // Object initialization
12147 var Toastify = function(options) {
12148 // Returning a new init object
12149 return new Toastify.lib.init(options);
12150 },
12151 // Library version
12152 version = "1.12.0";
12153
12154 // Set the default global options
12155 Toastify.defaults = {
12156 oldestFirst: true,
12157 text: "Toastify is awesome!",
12158 node: undefined,
12159 duration: 3000,
12160 selector: undefined,
12161 callback: function () {
12162 },
12163 destination: undefined,
12164 newWindow: false,
12165 close: false,
12166 gravity: "toastify-top",
12167 positionLeft: false,
12168 position: '',
12169 backgroundColor: '',
12170 avatar: "",
12171 className: "",
12172 stopOnFocus: true,
12173 onClick: function () {
12174 },
12175 offset: {x: 0, y: 0},
12176 escapeMarkup: true,
12177 ariaLive: 'polite',
12178 style: {background: ''}
12179 };
12180
12181 // Defining the prototype of the object
12182 Toastify.lib = Toastify.prototype = {
12183 toastify: version,
12184
12185 constructor: Toastify,
12186
12187 // Initializing the object with required parameters
12188 init: function(options) {
12189 // Verifying and validating the input object
12190 if (!options) {
12191 options = {};
12192 }
12193
12194 // Creating the options object
12195 this.options = {};
12196
12197 this.toastElement = null;
12198
12199 // Validating the options
12200 this.options.text = options.text || Toastify.defaults.text; // Display message
12201 this.options.node = options.node || Toastify.defaults.node; // Display content as node
12202 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
12203 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
12204 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
12205 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
12206 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
12207 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
12208 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
12209 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
12210 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
12211 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
12212 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
12213 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
12214 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
12215 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
12216 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
12217 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
12218 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
12219 this.options.style = options.style || Toastify.defaults.style;
12220 if(options.backgroundColor) {
12221 this.options.style.background = options.backgroundColor;
12222 }
12223
12224 // Returning the current object for chaining functions
12225 return this;
12226 },
12227
12228 // Building the DOM element
12229 buildToast: function() {
12230 // Validating if the options are defined
12231 if (!this.options) {
12232 throw "Toastify is not initialized";
12233 }
12234
12235 // Creating the DOM object
12236 var divElement = document.createElement("div");
12237 divElement.className = "toastify on " + this.options.className;
12238
12239 // Positioning toast to left or right or center
12240 if (!!this.options.position) {
12241 divElement.className += " toastify-" + this.options.position;
12242 } else {
12243 // To be depreciated in further versions
12244 if (this.options.positionLeft === true) {
12245 divElement.className += " toastify-left";
12246 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
12247 } else {
12248 // Default position
12249 divElement.className += " toastify-right";
12250 }
12251 }
12252
12253 // Assigning gravity of element
12254 divElement.className += " " + this.options.gravity;
12255
12256 if (this.options.backgroundColor) {
12257 // This is being deprecated in favor of using the style HTML DOM property
12258 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
12259 }
12260
12261 // Loop through our style object and apply styles to divElement
12262 for (var property in this.options.style) {
12263 divElement.style[property] = this.options.style[property];
12264 }
12265
12266 // Announce the toast to screen readers
12267 if (this.options.ariaLive) {
12268 divElement.setAttribute('aria-live', this.options.ariaLive)
12269 }
12270
12271 // Adding the toast message/node
12272 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
12273 // If we have a valid node, we insert it
12274 divElement.appendChild(this.options.node)
12275 } else {
12276 if (this.options.escapeMarkup) {
12277 divElement.innerText = this.options.text;
12278 } else {
12279 divElement.innerHTML = this.options.text;
12280 }
12281
12282 if (this.options.avatar !== "") {
12283 var avatarElement = document.createElement("img");
12284 avatarElement.src = this.options.avatar;
12285
12286 avatarElement.className = "toastify-avatar";
12287
12288 if (this.options.position == "left" || this.options.positionLeft === true) {
12289 // Adding close icon on the left of content
12290 divElement.appendChild(avatarElement);
12291 } else {
12292 // Adding close icon on the right of content
12293 divElement.insertAdjacentElement("afterbegin", avatarElement);
12294 }
12295 }
12296 }
12297
12298 // Adding a close icon to the toast
12299 if (this.options.close === true) {
12300 // Create a span for close element
12301 var closeElement = document.createElement("button");
12302 closeElement.type = "button";
12303 closeElement.setAttribute("aria-label", "Close");
12304 closeElement.className = "toast-close";
12305 closeElement.innerHTML = "&#10006;";
12306
12307 // Triggering the removal of toast from DOM on close click
12308 closeElement.addEventListener(
12309 "click",
12310 function(event) {
12311 event.stopPropagation();
12312 this.removeElement(this.toastElement);
12313 window.clearTimeout(this.toastElement.timeOutValue);
12314 }.bind(this)
12315 );
12316
12317 //Calculating screen width
12318 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
12319
12320 // Adding the close icon to the toast element
12321 // Display on the right if screen width is less than or equal to 360px
12322 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
12323 // Adding close icon on the left of content
12324 divElement.insertAdjacentElement("afterbegin", closeElement);
12325 } else {
12326 // Adding close icon on the right of content
12327 divElement.appendChild(closeElement);
12328 }
12329 }
12330
12331 // Clear timeout while toast is focused
12332 if (this.options.stopOnFocus && this.options.duration > 0) {
12333 var self = this;
12334 // stop countdown
12335 divElement.addEventListener(
12336 "mouseover",
12337 function(event) {
12338 window.clearTimeout(divElement.timeOutValue);
12339 }
12340 )
12341 // add back the timeout
12342 divElement.addEventListener(
12343 "mouseleave",
12344 function() {
12345 divElement.timeOutValue = window.setTimeout(
12346 function() {
12347 // Remove the toast from DOM
12348 self.removeElement(divElement);
12349 },
12350 self.options.duration
12351 )
12352 }
12353 )
12354 }
12355
12356 // Adding an on-click destination path
12357 if (typeof this.options.destination !== "undefined") {
12358 divElement.addEventListener(
12359 "click",
12360 function(event) {
12361 event.stopPropagation();
12362 if (this.options.newWindow === true) {
12363 window.open(this.options.destination, "_blank");
12364 } else {
12365 window.location = this.options.destination;
12366 }
12367 }.bind(this)
12368 );
12369 }
12370
12371 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
12372 divElement.addEventListener(
12373 "click",
12374 function(event) {
12375 event.stopPropagation();
12376 this.options.onClick();
12377 }.bind(this)
12378 );
12379 }
12380
12381 // Adding offset
12382 if(typeof this.options.offset === "object") {
12383
12384 var x = getAxisOffsetAValue("x", this.options);
12385 var y = getAxisOffsetAValue("y", this.options);
12386
12387 var xOffset = this.options.position == "left" ? x : "-" + x;
12388 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
12389
12390 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
12391
12392 }
12393
12394 // Returning the generated element
12395 return divElement;
12396 },
12397
12398 // Displaying the toast
12399 showToast: function() {
12400 // Creating the DOM object for the toast
12401 this.toastElement = this.buildToast();
12402
12403 // Getting the root element to with the toast needs to be added
12404 var rootElement;
12405 if (typeof this.options.selector === "string") {
12406 rootElement = document.getElementById(this.options.selector);
12407 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
12408 rootElement = this.options.selector;
12409 } else {
12410 rootElement = document.body;
12411 }
12412
12413 // Validating if root element is present in DOM
12414 if (!rootElement) {
12415 throw "Root element is not defined";
12416 }
12417
12418 // Adding the DOM element
12419 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
12420 rootElement.insertBefore(this.toastElement, elementToInsert);
12421
12422 // Repositioning the toasts in case multiple toasts are present
12423 Toastify.reposition();
12424
12425 if (this.options.duration > 0) {
12426 this.toastElement.timeOutValue = window.setTimeout(
12427 function() {
12428 // Remove the toast from DOM
12429 this.removeElement(this.toastElement);
12430 }.bind(this),
12431 this.options.duration
12432 ); // Binding `this` for function invocation
12433 }
12434
12435 // Supporting function chaining
12436 return this;
12437 },
12438
12439 hideToast: function() {
12440 if (this.toastElement.timeOutValue) {
12441 clearTimeout(this.toastElement.timeOutValue);
12442 }
12443 this.removeElement(this.toastElement);
12444 },
12445
12446 // Removing the element from the DOM
12447 removeElement: function(toastElement) {
12448 // Hiding the element
12449 // toastElement.classList.remove("on");
12450 toastElement.className = toastElement.className.replace(" on", "");
12451
12452 // Removing the element from DOM after transition end
12453 window.setTimeout(
12454 function() {
12455 // remove options node if any
12456 if (this.options.node && this.options.node.parentNode) {
12457 this.options.node.parentNode.removeChild(this.options.node);
12458 }
12459
12460 // Remove the element from the DOM, only when the parent node was not removed before.
12461 if (toastElement.parentNode) {
12462 toastElement.parentNode.removeChild(toastElement);
12463 }
12464
12465 // Calling the callback function
12466 this.options.callback.call(toastElement);
12467
12468 // Repositioning the toasts again
12469 Toastify.reposition();
12470 }.bind(this),
12471 400
12472 ); // Binding `this` for function invocation
12473 },
12474 };
12475
12476 // Positioning the toasts on the DOM
12477 Toastify.reposition = function() {
12478
12479 // Top margins with gravity
12480 var topLeftOffsetSize = {
12481 top: 15,
12482 bottom: 15,
12483 };
12484 var topRightOffsetSize = {
12485 top: 15,
12486 bottom: 15,
12487 };
12488 var offsetSize = {
12489 top: 15,
12490 bottom: 15,
12491 };
12492
12493 // Get all toast messages on the DOM
12494 var allToasts = document.getElementsByClassName("toastify");
12495
12496 var classUsed;
12497
12498 // Modifying the position of each toast element
12499 for (var i = 0; i < allToasts.length; i++) {
12500 // Getting the applied gravity
12501 if (containsClass(allToasts[i], "toastify-top") === true) {
12502 classUsed = "toastify-top";
12503 } else {
12504 classUsed = "toastify-bottom";
12505 }
12506
12507 var height = allToasts[i].offsetHeight;
12508 classUsed = classUsed.substr(9, classUsed.length-1)
12509 // Spacing between toasts
12510 var offset = 15;
12511
12512 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
12513
12514 // Show toast in center if screen with less than or equal to 360px
12515 if (width <= 360) {
12516 // Setting the position
12517 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
12518
12519 offsetSize[classUsed] += height + offset;
12520 } else {
12521 if (containsClass(allToasts[i], "toastify-left") === true) {
12522 // Setting the position
12523 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
12524
12525 topLeftOffsetSize[classUsed] += height + offset;
12526 } else {
12527 // Setting the position
12528 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
12529
12530 topRightOffsetSize[classUsed] += height + offset;
12531 }
12532 }
12533 }
12534
12535 // Supporting function chaining
12536 return this;
12537 };
12538
12539 // Helper function to get offset.
12540 function getAxisOffsetAValue(axis, options) {
12541
12542 if(options.offset[axis]) {
12543 if(isNaN(options.offset[axis])) {
12544 return options.offset[axis];
12545 }
12546 else {
12547 return options.offset[axis] + 'px';
12548 }
12549 }
12550
12551 return '0px';
12552
12553 }
12554
12555 function containsClass(elem, yourClass) {
12556 if (!elem || typeof yourClass !== "string") {
12557 return false;
12558 } else if (
12559 elem.className &&
12560 elem.className
12561 .trim()
12562 .split(/\s+/gi)
12563 .indexOf(yourClass) > -1
12564 ) {
12565 return true;
12566 } else {
12567 return false;
12568 }
12569 }
12570
12571 // Setting up the prototype for the init object
12572 Toastify.lib.init.prototype = Toastify.lib;
12573
12574 // Returning the Toastify function to be assigned to the window object/module
12575 return Toastify;
12576 });
12577
12578
12579 /***/ }
12580
12581 /******/ });
12582 /************************************************************************/
12583 /******/ // The module cache
12584 /******/ var __webpack_module_cache__ = {};
12585 /******/
12586 /******/ // The require function
12587 /******/ function __webpack_require__(moduleId) {
12588 /******/ // Check if module is in cache
12589 /******/ var cachedModule = __webpack_module_cache__[moduleId];
12590 /******/ if (cachedModule !== undefined) {
12591 /******/ return cachedModule.exports;
12592 /******/ }
12593 /******/ // Create a new module (and put it into the cache)
12594 /******/ var module = __webpack_module_cache__[moduleId] = {
12595 /******/ id: moduleId,
12596 /******/ // no module.loaded needed
12597 /******/ exports: {}
12598 /******/ };
12599 /******/
12600 /******/ // Execute the module function
12601 /******/ if (!(moduleId in __webpack_modules__)) {
12602 /******/ delete __webpack_module_cache__[moduleId];
12603 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
12604 /******/ e.code = 'MODULE_NOT_FOUND';
12605 /******/ throw e;
12606 /******/ }
12607 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
12608 /******/
12609 /******/ // Return the exports of the module
12610 /******/ return module.exports;
12611 /******/ }
12612 /******/
12613 /************************************************************************/
12614 /******/ /* webpack/runtime/compat get default export */
12615 /******/ (() => {
12616 /******/ // getDefaultExport function for compatibility with non-harmony modules
12617 /******/ __webpack_require__.n = (module) => {
12618 /******/ var getter = module && module.__esModule ?
12619 /******/ () => (module['default']) :
12620 /******/ () => (module);
12621 /******/ __webpack_require__.d(getter, { a: getter });
12622 /******/ return getter;
12623 /******/ };
12624 /******/ })();
12625 /******/
12626 /******/ /* webpack/runtime/define property getters */
12627 /******/ (() => {
12628 /******/ // define getter functions for harmony exports
12629 /******/ __webpack_require__.d = (exports, definition) => {
12630 /******/ for(var key in definition) {
12631 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
12632 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
12633 /******/ }
12634 /******/ }
12635 /******/ };
12636 /******/ })();
12637 /******/
12638 /******/ /* webpack/runtime/hasOwnProperty shorthand */
12639 /******/ (() => {
12640 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
12641 /******/ })();
12642 /******/
12643 /******/ /* webpack/runtime/make namespace object */
12644 /******/ (() => {
12645 /******/ // define __esModule on exports
12646 /******/ __webpack_require__.r = (exports) => {
12647 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
12648 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
12649 /******/ }
12650 /******/ Object.defineProperty(exports, '__esModule', { value: true });
12651 /******/ };
12652 /******/ })();
12653 /******/
12654 /******/ /* webpack/runtime/nonce */
12655 /******/ (() => {
12656 /******/ __webpack_require__.nc = undefined;
12657 /******/ })();
12658 /******/
12659 /************************************************************************/
12660 var __webpack_exports__ = {};
12661 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
12662 (() => {
12663 "use strict";
12664 /*!********************************************!*\
12665 !*** ./assets/src/js/admin/edit-course.js ***!
12666 \********************************************/
12667 __webpack_require__.r(__webpack_exports__);
12668 /* 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");
12669 /* 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");
12670 /* 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");
12671 /**
12672 * Edit course JS handler.
12673 *
12674 * @since 4.3.0
12675 * @version 1.0.0
12676 */
12677
12678
12679
12680 new _edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_0__.EditCourseCurriculum();
12681 new _generate_with_openai_js__WEBPACK_IMPORTED_MODULE_1__.GenerateWithOpenai();
12682 new _edit_course_edit_curriculum_edit_curriculum_ai_js__WEBPACK_IMPORTED_MODULE_2__.EditCurriculumAi();
12683 })();
12684
12685 /******/ })()
12686 ;
12687 //# sourceMappingURL=edit-course.js.map