PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.4
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.4
4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 All 140 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.4, at assets/dist/js/admin/edit-course.js

12,522 lines 449.2 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 style="padding: 5px 10px; justify-content: center;"
1855 class="lp-btn-generate-with-ai lp-btn-ai-style"
1856 data-template="#lp-tmpl-edit-description-ai">
1857 <i class="lp-ico-ai"></i><span>Generate description with AI</span>
1858 </button>`);
1859 });
1860 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('#postimagediv', el => {
1861 const elInside = el.querySelector('.postbox-header');
1862 elInside.insertAdjacentHTML('afterend', `<button type="button"
1863 style="padding: 5px 10px; justify-content: center;"
1864 class="lp-btn-generate-with-ai lp-btn-ai-style"
1865 data-template="#lp-tmpl-edit-image-ai">
1866 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1867 </button>`);
1868 });
1869
1870 // Check is layout Gutenberg
1871 if (wp.data && wp.data.select('core/editor')) {
1872 isLayoutGutenberg = true;
1873 selectGutenberg = wp.data.select;
1874 dispatchGutenberg = wp.data.dispatch;
1875 editorGutenberg = selectGutenberg('core/editor');
1876
1877 // For layout Gutenberg - button for title
1878 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-document-bar', el => {
1879 el.insertAdjacentHTML('afterend', `<button type="button"
1880 style="margin-left: 5px"
1881 class="lp-btn-generate-with-ai"
1882 data-template="#lp-tmpl-edit-title-ai">
1883 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1884 </button>`);
1885 });
1886
1887 // For layout Gutenberg - button for description
1888 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-post-featured-image', el => {
1889 el.insertAdjacentHTML('beforebegin', `<button type="button"
1890 style="padding: 5px 10px; justify-content: center;"
1891 class="lp-btn-generate-with-ai"
1892 data-template="#lp-tmpl-edit-description-ai">
1893 <i class="lp-ico-ai"></i><span>Generate description with AI</span>
1894 </button>`);
1895 });
1896
1897 // For layout Gutenberg - button for image
1898 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady('.editor-post-featured-image', el => {
1899 el.insertAdjacentHTML('afterend', `<button type="button"
1900 style="padding: 5px 10px; justify-content: center;"
1901 class="lp-btn-generate-with-ai"
1902 data-template="#lp-tmpl-edit-image-ai">
1903 <i class="lp-ico-ai"></i><span>${lpData.i18n.generate_with_ai}</span>
1904 </button>`);
1905 });
1906 }
1907 }
1908 this.events();
1909 }
1910 getTitleInputSelector() {
1911 return this.options.isCourseBuilder ? this.options.courseBuilderTitleInputSelector : this.options.titleInputSelector;
1912 }
1913 getEditorId() {
1914 return this.options.isCourseBuilder ? this.options.editorIdCourseBuilder : this.options.editorIdClassic;
1915 }
1916 setCourseBuilderPostId(form) {
1917 if (!this.options.isCourseBuilder || !form) {
1918 return;
1919 }
1920 const postIdInput = form.querySelector('[name="post-id"]');
1921 if (!postIdInput) {
1922 return;
1923 }
1924 const courseEditWrap = document.querySelector('.cb-section__course-edit[data-course-id]');
1925 const courseId = courseEditWrap?.dataset?.courseId || '';
1926 if (courseId) {
1927 postIdInput.value = courseId;
1928 }
1929 }
1930 extractImageSourceFromHtml(html) {
1931 if (!html) {
1932 return '';
1933 }
1934 const tempWrapper = document.createElement('div');
1935 tempWrapper.innerHTML = html;
1936 return tempWrapper.querySelector('img')?.getAttribute('src') || '';
1937 }
1938 applyCourseBuilderFeaturedImage(attachmentId, imageSrc) {
1939 if (!attachmentId || !imageSrc) {
1940 return false;
1941 }
1942 document.dispatchEvent(new CustomEvent('lp-course-builder/ai-featured-image-applied', {
1943 detail: {
1944 attachmentId,
1945 imageSrc
1946 }
1947 }));
1948 return true;
1949 }
1950 events() {
1951 _utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
1952 selector: GenerateWithOpenai.selectors.elBtnGenerateWithAi,
1953 class: this,
1954 callBack: this.showPopup.name
1955 }, {
1956 selector: '.lp-btn-step',
1957 class: this,
1958 callBack: this.showStep.name
1959 }, {
1960 selector: '.lp-btn-generate-prompt',
1961 class: this,
1962 callBack: this.generatePrompt.name
1963 }, {
1964 selector: '.lp-btn-call-open-ai',
1965 class: this,
1966 callBack: this.generateData.name
1967 }, {
1968 selector: '.lp-btn-copy',
1969 class: this,
1970 callBack: this.copyGeneratedData.name
1971 }, {
1972 selector: '.lp-btn-apply',
1973 class: this,
1974 callBack: this.applyGeneratedData.name
1975 }, {
1976 selector: '.lp-btn-ai-apply-image',
1977 class: this,
1978 callBack: this.applyImageData.name
1979 }, {
1980 selector: '.lp-btn-close-ai-popup',
1981 //class: this,
1982 callBack: args => {
1983 const {
1984 e,
1985 target
1986 } = args;
1987 const message = lpData.i18n.confirm_close_ai;
1988 if (!lp_is_generating_course_data) {
1989 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
1990 } else if (confirm(message)) {
1991 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
1992 }
1993
1994 // Testing custom confirm box
1995 /*if ( confirm( message ) ) {
1996 SweetAlert.close();
1997 }*/
1998 }
1999 }]);
2000 }
2001 showPopup(args) {
2002 const {
2003 e,
2004 target
2005 } = args;
2006 const templateId = target.dataset.template || target.closest('.lp-btn-generate-with-ai').dataset.template || target.closest('.lp-generate-data-ai-wrap').dataset.template || '';
2007 const modalTemplate = document.querySelector(templateId);
2008 if (!modalTemplate) {
2009 console.error(`Template ${templateId} not found!`);
2010 return;
2011 }
2012 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().fire({
2013 html: modalTemplate.innerHTML,
2014 width: '60%',
2015 showCloseButton: false,
2016 showConfirmButton: false,
2017 allowOutsideClick: false,
2018 allowEscapeKey: false,
2019 didOpen: () => {
2020 popupSweetAlert = sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().getPopup();
2021 // Click to show tomSelect style
2022 popupSweetAlert.click();
2023
2024 // Set post title and post content to hidden fields of form to AI prompt reference
2025 const elPostTitleInput = document.querySelector(this.getTitleInputSelector());
2026 let post_title = '';
2027 if (elPostTitleInput) {
2028 post_title = elPostTitleInput.value;
2029 } else if (isLayoutGutenberg) {
2030 const elGutenbergTitle = document.querySelector('.editor-post-card-panel__title-name');
2031 if (elGutenbergTitle) {
2032 post_title = elGutenbergTitle.textContent;
2033 }
2034 }
2035 let post_content = '';
2036 if (!isLayoutGutenberg) {
2037 const editorId = this.getEditorId();
2038 if (!window.tinymce || !window.tinymce.get(editorId)) {
2039 const editorElement = document.querySelector(`#${editorId}`);
2040 post_content = editorElement ? editorElement.value : '';
2041 } else {
2042 post_content = window.tinymce.get(editorId).getContent({
2043 format: 'text'
2044 });
2045 }
2046 } else {
2047 const content = editorGutenberg.getEditedPostContent();
2048 post_content = content.replace(/(<([^>]+)>)/gi, ''); // Remove HTML tags
2049 }
2050 const form = popupSweetAlert.querySelector('form');
2051 this.setCourseBuilderPostId(form);
2052 const elPostTitle = form.querySelector('[name=post-title]');
2053 if (elPostTitle) {
2054 elPostTitle.value = post_title;
2055 if (!post_title) {
2056 const elGroup = elPostTitle.closest('.form-group');
2057 const elReferWarning = elGroup.querySelector('.lp-ai-warning-refer');
2058 if (elReferWarning) {
2059 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elReferWarning, 1);
2060 }
2061 }
2062 }
2063 const elPostContent = form.querySelector('[name=post-content]');
2064 if (elPostContent) {
2065 elPostContent.value = post_content;
2066 if (post_content.length < 2) {
2067 const elGroup = elPostContent.closest('.form-group');
2068 const elReferWarning = elGroup.querySelector('.lp-ai-warning-refer');
2069 if (elReferWarning) {
2070 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elReferWarning, 1);
2071 }
2072 }
2073 }
2074 const targetAudience = popupSweetAlert.querySelector('select[name="target_audience"]');
2075 if (targetAudience) {
2076 if (lp_course_ai_setting?.target_audience) {
2077 targetAudience.tomselect.setValue(lp_course_ai_setting.target_audience);
2078 }
2079 targetAudience.addEventListener('change', event => {
2080 lp_course_ai_setting.target_audience = targetAudience.tomselect.getValue();
2081 localStorage.setItem('lp_course_ai_setting', JSON.stringify(lp_course_ai_setting));
2082 });
2083 }
2084 const tone = popupSweetAlert.querySelector('select[name="tone"]');
2085 if (tone) {
2086 if (lp_course_ai_setting?.tone) {
2087 tone.tomselect.setValue(lp_course_ai_setting.tone);
2088 }
2089 tone.addEventListener('change', event => {
2090 lp_course_ai_setting.tone = tone.tomselect.getValue();
2091 localStorage.setItem('lp_course_ai_setting', JSON.stringify(lp_course_ai_setting));
2092 });
2093 }
2094 const language = popupSweetAlert.querySelector('select[name="language"]');
2095 if (language) {
2096 if (lp_course_ai_setting?.language) {
2097 language.tomselect.setValue(lp_course_ai_setting.language);
2098 }
2099 language.addEventListener('change', event => {
2100 const value = language.tomselect.getValue();
2101 lp_course_ai_setting.language = value ? [value] : [];
2102 localStorage.setItem('lp_course_ai_setting', JSON.stringify(lp_course_ai_setting));
2103 });
2104 }
2105 }
2106 }).then(result => {
2107 if (result.isDismissed) {
2108 if (lp_is_generating_course_data) {
2109 lp_is_generating_course_data = false;
2110 }
2111 }
2112 });
2113 }
2114 showStep(args) {
2115 const {
2116 e,
2117 target
2118 } = args;
2119 e.preventDefault();
2120 const elBtnActions = target.closest('.button-actions');
2121 const elCreateCourseAIWrap = elBtnActions.closest(GenerateWithOpenai.selectors.elGenerateDataAiWrap);
2122 let step = parseInt(elBtnActions.dataset.step);
2123 const stepAction = target.dataset.action;
2124 if (stepAction === 'next') {
2125 step++;
2126 } else if (stepAction === 'prev') {
2127 step--;
2128 }
2129 elBtnActions.dataset.step = step;
2130 const elForm = target.closest('form');
2131 const elContentStep = elForm.querySelector(`.step-content[data-step="${step}"]`);
2132 const elItemStep = elCreateCourseAIWrap.querySelector(`.step-item[data-step="${step}"]`);
2133 elForm.querySelectorAll('.step-content').forEach(el => el.classList.remove('active'));
2134 elContentStep.classList.add('active');
2135 elCreateCourseAIWrap.querySelectorAll('.step-item').forEach(el => el.classList.remove('active'));
2136 elItemStep.classList.add('active');
2137
2138 // Get all buttons step to show/hide
2139 const form = target.closest('form');
2140 const elBtnSteps = form.querySelectorAll('button[data-step-show]');
2141 elBtnSteps.forEach(el => {
2142 const stepsShow = el.dataset.stepShow.split(',').map(s => parseInt(s.trim()));
2143 if (stepsShow.includes(step)) {
2144 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(el, 1);
2145 } else {
2146 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(el, 0);
2147 }
2148 });
2149 }
2150
2151 /**
2152 * Create prompt from data config
2153 * @param args
2154 */
2155 generatePrompt(args) {
2156 const {
2157 e,
2158 target
2159 } = args;
2160 e.preventDefault();
2161 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, true);
2162
2163 // Get dataSend
2164 const form = target.closest('form');
2165 let dataSend = JSON.parse(target.dataset.send);
2166 dataSend = _utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(form, dataSend);
2167
2168 // Ajax to generate prompt
2169 const callBack = {
2170 success: response => {
2171 const {
2172 message,
2173 status,
2174 data
2175 } = response;
2176 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(message, status);
2177 if (status === 'success') {
2178 const elPromptTextarea = form.querySelector('textarea[name=lp-openai-prompt-generated-field]');
2179 elPromptTextarea.value = data;
2180 const elBtnNext = form.querySelector('.lp-btn-step[data-action=next]');
2181 elBtnNext.click();
2182 }
2183 },
2184 error: error => {
2185 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(error, 'error');
2186 },
2187 completed: () => {
2188 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, false);
2189 }
2190 };
2191 window.lpAJAXG.fetchAJAX(dataSend, callBack);
2192 }
2193
2194 /**
2195 * Submit prompt to OpenAI to generate course data
2196 * @param args
2197 */
2198 generateData(args) {
2199 const {
2200 e,
2201 target
2202 } = args;
2203 e.preventDefault();
2204 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, true);
2205
2206 // Get dataSend
2207 const form = target.closest('form');
2208 let dataSend = JSON.parse(target.dataset.send);
2209 dataSend = _utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(form, dataSend);
2210 const btnPrev = form.querySelector('.lp-btn-step[data-action=prev]');
2211 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(btnPrev, 0);
2212
2213 // Ajax to generate prompt
2214 const callBack = {
2215 success: response => {
2216 const {
2217 message,
2218 status,
2219 data
2220 } = response;
2221 if (lp_is_generating_course_data) {
2222 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(message, status);
2223 }
2224 if (status === 'success') {
2225 // Save structure data
2226 lp_structure_course = data.lp_structure_course;
2227
2228 // Set preview HTML
2229 const elResults = form.querySelector('.lp-ai-generated-results');
2230 elResults.innerHTML = data.lp_html_preview;
2231 const elBtnNext = form.querySelector('.lp-btn-step[data-action=next]');
2232 elBtnNext.click();
2233 }
2234 },
2235 error: error => {
2236 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(error, 'error');
2237 },
2238 completed: () => {
2239 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, false);
2240 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(btnPrev, 1);
2241 lp_is_generating_course_data = false;
2242 }
2243 };
2244 lp_is_generating_course_data = true;
2245 window.lpAJAXG.fetchAJAX(dataSend, callBack);
2246 }
2247 applyGeneratedData(args) {
2248 const {
2249 e,
2250 target
2251 } = args;
2252 e.preventDefault();
2253 const dataApply = target.dataset.apply;
2254 const dataTarget = target.dataset.target;
2255 if (dataTarget) {
2256 if (!isLayoutGutenberg) {
2257 if (dataTarget === 'set-wp-editor-content') {
2258 this.setWPEditorContent(dataApply);
2259 } else if (dataTarget === 'set-wp-title') {
2260 const elTitleInput = document.querySelector(this.getTitleInputSelector());
2261 if (elTitleInput) {
2262 elTitleInput.value = dataApply;
2263 elTitleInput.dispatchEvent(new Event('input', {
2264 bubbles: true
2265 }));
2266 }
2267 }
2268 } else if (dataTarget === 'set-wp-editor-content') {
2269 dispatchGutenberg('core/editor').editPost({
2270 content: dataApply
2271 });
2272 } else if (dataTarget === 'set-wp-title') {
2273 dispatchGutenberg('core/editor').editPost({
2274 title: dataApply
2275 });
2276 }
2277 }
2278 if (popupSweetAlert) {
2279 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
2280 }
2281 }
2282 copyGeneratedData(args) {
2283 const {
2284 e,
2285 target
2286 } = args;
2287 e.preventDefault();
2288 const dataCopy = target.dataset.copy;
2289 if (navigator.clipboard) {
2290 navigator.clipboard.writeText(dataCopy).then(() => {
2291 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Copied to clipboard!', 'success');
2292 }).catch(err => {
2293 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Failed to copy text: ' + err, 'error');
2294 });
2295 } else {
2296 // Fallback when clipboard API is unavailable
2297 const textarea = document.createElement('textarea');
2298 textarea.value = dataCopy;
2299 textarea.style.position = 'fixed';
2300 textarea.style.left = '-9999px';
2301 document.body.appendChild(textarea);
2302 textarea.select();
2303 try {
2304 const successful = document.execCommand('copy');
2305 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(successful ? 'Copied to clipboard!' : 'Failed to copy text', successful ? 'success' : 'error');
2306 } catch (err) {
2307 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Failed to copy text: ' + err, 'error');
2308 }
2309 document.body.removeChild(textarea);
2310 }
2311
2312 /*navigator.clipboard.writeText( dataCopy ).then( () => {
2313 lpToastify.show( 'Copied to clipboard!', 'success' );
2314 } ).catch( ( err ) => {
2315 lpToastify.show( 'Failed to copy text: ' + err, 'error' );
2316 } );*/
2317 }
2318 setWPEditorContent(htmlContent) {
2319 const editorId = this.getEditorId();
2320 const editor = window.tinymce?.get(editorId);
2321 if (editor) {
2322 editor.setContent(htmlContent);
2323 return;
2324 }
2325 const editorElement = document.querySelector(`#${editorId}`);
2326 if (editorElement) {
2327 editorElement.value = htmlContent;
2328 editorElement.dispatchEvent(new Event('input', {
2329 bubbles: true
2330 }));
2331 }
2332 }
2333 applyImageData(args) {
2334 const {
2335 e,
2336 target
2337 } = args;
2338 let dataSend = JSON.parse(target.dataset.send);
2339 dataSend = _utils_js__WEBPACK_IMPORTED_MODULE_0__.mergeDataWithDatForm(target.closest('form'), dataSend);
2340 //e.preventDefault();
2341 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, true);
2342
2343 // Ajax to generate prompt
2344 const callBack = {
2345 success: response => {
2346 const {
2347 message,
2348 status,
2349 data
2350 } = response;
2351 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(message, status);
2352 if (status === 'success') {
2353 if (this.options.isCourseBuilder) {
2354 const attachmentId = parseInt(data?.attachment_id || 0, 10);
2355 const imageSrc = this.extractImageSourceFromHtml(data?.html_image || '');
2356 const applied = this.applyCourseBuilderFeaturedImage(attachmentId, imageSrc);
2357 if (!applied) {
2358 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show('Failed to apply image to course featured image.', 'error');
2359 return;
2360 }
2361 } else if (!isLayoutGutenberg) {
2362 // Set image
2363 const elImagePreview = document.querySelector('#postimagediv .inside');
2364 elImagePreview.outerHTML = data.html_image;
2365 } else {
2366 dispatchGutenberg('core/editor').editPost({
2367 featured_media: data.attachment_id
2368 });
2369 }
2370 if (popupSweetAlert) {
2371 sweetalert2__WEBPACK_IMPORTED_MODULE_1___default().close();
2372 }
2373 }
2374 },
2375 error: error => {
2376 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_2__.show(error, 'error');
2377 },
2378 completed: () => {
2379 _utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl(target, false);
2380 }
2381 };
2382 window.lpAJAXG.fetchAJAX(dataSend, callBack);
2383 }
2384 }
2385
2386 /***/ },
2387
2388 /***/ "./assets/src/js/lpPopupSelectItemToAdd.js"
2389 /*!*************************************************!*\
2390 !*** ./assets/src/js/lpPopupSelectItemToAdd.js ***!
2391 \*************************************************/
2392 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2393
2394 "use strict";
2395 __webpack_require__.r(__webpack_exports__);
2396 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2397 /* harmony export */ LpPopupSelectItemToAdd: () => (/* binding */ LpPopupSelectItemToAdd)
2398 /* harmony export */ });
2399 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
2400 /* harmony import */ var lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/lpToastify.js */ "./assets/src/js/lpToastify.js");
2401 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
2402 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_2__);
2403 /**
2404 * LearnPress Popup Select Item
2405 *
2406 * Handles load(search) item from API, show in popup and select item.
2407 */
2408
2409
2410
2411
2412 let itemsSelectedData = [];
2413 let elPopup;
2414 let timeSearchTitleItem;
2415 class LpPopupSelectItemToAdd {
2416 constructor() {
2417 this.init();
2418 }
2419 static selectors = {
2420 elBtnShowPopupItemsToSelect: '.lp-btn-show-popup-items-to-select',
2421 elBtnAddItemsSelected: '.lp-btn-add-items-selected',
2422 elBtnCountItemsSelected: '.lp-btn-count-items-selected',
2423 elHeaderCountItemSelected: '.header-count-items-selected',
2424 elSelectItem: '.lp-select-item',
2425 elListItems: '.list-items',
2426 elPopupItemsToSelect: '.lp-popup-items-to-select',
2427 elSearchTitleItem: '.lp-search-title-item',
2428 elBtnBackListItems: '.lp-btn-back-to-select-items',
2429 elListItemsWrap: '.list-items-wrap',
2430 elListItemsSelected: '.list-items-selected',
2431 elItemSelectedClone: '.li-item-selected.clone',
2432 elItemSelected: '.li-item-selected',
2433 LPTarget: '.lp-target'
2434 };
2435 init() {
2436 this.events();
2437 }
2438 events = () => {
2439 if (LpPopupSelectItemToAdd._loadedEvents) {
2440 return;
2441 }
2442 LpPopupSelectItemToAdd._loadedEvents = true;
2443 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('click', [{
2444 selector: LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect,
2445 callBack: this.showPopupItemsToSelect.name,
2446 class: this
2447 }, {
2448 selector: LpPopupSelectItemToAdd.selectors.elSelectItem,
2449 callBack: this.selectItemsFromList.name,
2450 class: this
2451 }, {
2452 selector: LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected,
2453 callBack: this.showItemsSelected.name,
2454 class: this
2455 }, {
2456 selector: LpPopupSelectItemToAdd.selectors.elBtnBackListItems,
2457 callBack: this.backToSelectItems.name,
2458 class: this
2459 }, {
2460 selector: LpPopupSelectItemToAdd.selectors.elItemSelected,
2461 callBack: this.removeItemSelected.name,
2462 class: this
2463 }, {
2464 selector: '.tabs .tab',
2465 callBack: this.chooseTabItemsType.name,
2466 class: this
2467 }]);
2468 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.eventHandlers('keyup', [{
2469 selector: LpPopupSelectItemToAdd.selectors.elSearchTitleItem,
2470 callBack: this.searchTitleItemToSelect.name,
2471 class: this
2472 }]);
2473 };
2474
2475 // Show popup items to select
2476 showPopupItemsToSelect = args => {
2477 const {
2478 e,
2479 target = false,
2480 callBack
2481 } = args;
2482 const elBtnShowPopupItemsToSelect = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnShowPopupItemsToSelect}`);
2483 if (!elBtnShowPopupItemsToSelect) {
2484 return;
2485 }
2486
2487 // Reset items selected data when opening popup
2488 itemsSelectedData = [];
2489 const templateId = target.dataset.template || '';
2490 const modalTemplate = document.querySelector(templateId);
2491 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().fire({
2492 html: modalTemplate.innerHTML,
2493 showConfirmButton: false,
2494 showCloseButton: true,
2495 width: '60%',
2496 customClass: {
2497 popup: 'lp-select-items-popup',
2498 htmlContainer: 'lp-select-items-html-container',
2499 container: 'lp-select-items-container'
2500 },
2501 willOpen: () => {
2502 elPopup = sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().getPopup();
2503 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2504 if (elLPTarget) {
2505 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2506 dataSend.args.paged = 1;
2507 dataSend.args.item_selecting = itemsSelectedData || [];
2508 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
2509 window.lpAJAXG.fetchAJAX(dataSend, {
2510 success: response => {
2511 const {
2512 data
2513 } = response;
2514 const elSkeleton = elPopup.querySelector('.lp-skeleton-animation');
2515 elSkeleton.remove();
2516 elLPTarget.innerHTML = data.content || '';
2517 this.watchItemsSelectedDataChange();
2518 }
2519 });
2520 }
2521 }
2522 }).then(result => {
2523 if (result.isDismissed) {}
2524 });
2525 };
2526
2527 // Choose tab items type
2528 chooseTabItemsType = args => {
2529 const {
2530 e,
2531 target,
2532 callBack
2533 } = args;
2534 const elTabType = target.closest('.tab');
2535 if (!elTabType) {
2536 return;
2537 }
2538 e.preventDefault();
2539 const elTabs = elTabType.closest('.tabs');
2540 if (!elTabs) {
2541 return;
2542 }
2543 const elSelectItemsToAdd = elTabs.closest(`${LpPopupSelectItemToAdd.selectors.elPopupItemsToSelect}`);
2544 const elInputSearch = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.elSearchTitleItem}`);
2545 const itemType = elTabType.dataset.type;
2546 const elTabLis = elTabs.querySelectorAll('.tab');
2547 elTabLis.forEach(elTabLi => {
2548 if (elTabLi.classList.contains('active')) {
2549 elTabLi.classList.remove('active');
2550 }
2551 });
2552 elTabType.classList.add('active');
2553 // Reset search input
2554 elInputSearch.value = '';
2555 const elLPTarget = elSelectItemsToAdd.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2556 const dataSend = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2557 dataSend.args.item_type = itemType;
2558 dataSend.args.paged = 1;
2559 dataSend.args.item_selecting = itemsSelectedData || [];
2560 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSend);
2561 window.lpAJAXG.showHideLoading(elLPTarget, 1);
2562 window.lpAJAXG.fetchAJAX(dataSend, {
2563 success: response => {
2564 const {
2565 data
2566 } = response;
2567 elLPTarget.innerHTML = data.content || '';
2568 },
2569 error: error => {
2570 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
2571 },
2572 completed: () => {
2573 window.lpAJAXG.showHideLoading(elLPTarget, 0);
2574 this.watchItemsSelectedDataChange();
2575 }
2576 });
2577 };
2578
2579 // Choice items to add list items selected before adding to section
2580 selectItemsFromList = args => {
2581 const {
2582 e,
2583 target
2584 } = args;
2585 const elItemAttend = target.closest(`${LpPopupSelectItemToAdd.selectors.elSelectItem}`);
2586 if (!elItemAttend) {
2587 return;
2588 }
2589 const elInput = elItemAttend.querySelector('input[type="checkbox"]');
2590 if (target.tagName !== 'INPUT') {
2591 elInput.click();
2592 return;
2593 }
2594 const elUl = elItemAttend.closest(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
2595 if (!elUl) {
2596 return;
2597 }
2598 const itemSelected = {
2599 ...elInput.dataset
2600 };
2601 //console.log( 'itemSelected', itemSelected );
2602
2603 if (elInput.checked) {
2604 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
2605 if (!exists) {
2606 itemsSelectedData.push(itemSelected);
2607 }
2608 } else {
2609 const index = itemsSelectedData.findIndex(item => item.id === itemSelected.id);
2610 if (index !== -1) {
2611 itemsSelectedData.splice(index, 1);
2612 }
2613 }
2614 this.watchItemsSelectedDataChange();
2615 };
2616
2617 // Search title item
2618 searchTitleItemToSelect = args => {
2619 const {
2620 e,
2621 target
2622 } = args;
2623 const elInputSearch = target.closest(LpPopupSelectItemToAdd.selectors.elSearchTitleItem);
2624 if (!elInputSearch) {
2625 return;
2626 }
2627 const elLPTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2628 clearTimeout(timeSearchTitleItem);
2629 timeSearchTitleItem = setTimeout(() => {
2630 const dataSet = window.lpAJAXG.getDataSetCurrent(elLPTarget);
2631 dataSet.args.search_title = elInputSearch.value.trim();
2632 dataSet.args.item_selecting = itemsSelectedData;
2633 dataSet.args.paged = 1;
2634 window.lpAJAXG.setDataSetCurrent(elLPTarget, dataSet);
2635
2636 // Show loading
2637 window.lpAJAXG.showHideLoading(elLPTarget, 1);
2638 window.lpAJAXG.fetchAJAX(dataSet, {
2639 success: response => {
2640 const {
2641 data
2642 } = response;
2643 elLPTarget.innerHTML = data.content || '';
2644 },
2645 error: error => {
2646 lpAssetsJsPath_lpToastify_js__WEBPACK_IMPORTED_MODULE_1__.show(error, 'error');
2647 },
2648 completed: () => {
2649 window.lpAJAXG.showHideLoading(elLPTarget, 0);
2650 }
2651 });
2652 }, 800);
2653 };
2654
2655 // Show list of items, to choose items to add to section
2656 showItemsSelected = args => {
2657 const {
2658 e,
2659 target
2660 } = args;
2661 const elBtnCountItemsSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
2662 if (!elBtnCountItemsSelected) {
2663 return;
2664 }
2665 const elBtnBack = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
2666 const elTabs = elPopup.querySelector('.tabs');
2667 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
2668 const elHeaderItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
2669 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
2670 const elItemClone = elListItemsSelected.querySelector(`${LpPopupSelectItemToAdd.selectors.elItemSelectedClone}`);
2671 elHeaderItemsSelected.innerHTML = elBtnCountItemsSelected.innerHTML;
2672 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 0);
2673 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 0);
2674 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 0);
2675 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 1);
2676 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderItemsSelected, 1);
2677 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 1);
2678 elListItemsSelected.querySelectorAll(`${LpPopupSelectItemToAdd.selectors.elItemSelected}:not(.clone)`).forEach(elItem => {
2679 elItem.remove();
2680 });
2681 itemsSelectedData.forEach(item => {
2682 const elItemSelected = elItemClone.cloneNode(true);
2683 elItemSelected.classList.remove('clone');
2684 Object.entries(item).forEach(([key, value]) => {
2685 elItemSelected.dataset[key] = value;
2686 });
2687 const elTitleDisplay = elItemSelected.querySelector('.title-display');
2688 elTitleDisplay.innerHTML = item.title;
2689 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elItemSelected, 1);
2690 elItemClone.insertAdjacentElement('beforebegin', elItemSelected);
2691 });
2692 };
2693
2694 // Back to list of items
2695 backToSelectItems = args => {
2696 const {
2697 e,
2698 target
2699 } = args;
2700 const elBtnBack = target.closest(`${LpPopupSelectItemToAdd.selectors.elBtnBackListItems}`);
2701 if (!elBtnBack) {
2702 return;
2703 }
2704 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
2705 const elTabs = elPopup.querySelector('.tabs');
2706 const elListItemsWrap = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsWrap}`);
2707 const elHeaderCountItemSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
2708 const elListItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItemsSelected}`);
2709 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnCountItemsSelected, 1);
2710 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsWrap, 1);
2711 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elTabs, 1);
2712 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elBtnBack, 0);
2713 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elHeaderCountItemSelected, 0);
2714 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpShowHideEl(elListItemsSelected, 0);
2715 };
2716
2717 // Remove item selected from list items selected
2718 removeItemSelected = args => {
2719 const {
2720 e,
2721 target
2722 } = args;
2723 const elRemoveItemSelected = target.closest(`${LpPopupSelectItemToAdd.selectors.elItemSelected}`);
2724 if (!elRemoveItemSelected) {
2725 return;
2726 }
2727 const itemRemove = elRemoveItemSelected.dataset;
2728 const index = itemsSelectedData.findIndex(item => item.id === itemRemove.id);
2729 if (index !== -1) {
2730 itemsSelectedData.splice(index, 1);
2731 }
2732 elRemoveItemSelected.remove();
2733 this.watchItemsSelectedDataChange();
2734 };
2735
2736 // Watch items selected when data change
2737 watchItemsSelectedDataChange = () => {
2738 // Update count items selected, disable/enable buttons
2739 const elBtnAddItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnAddItemsSelected}`);
2740 const elBtnCountItemsSelected = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elBtnCountItemsSelected}`);
2741 const elSpanCount = elBtnCountItemsSelected.querySelector('span');
2742 const elHeaderCount = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elHeaderCountItemSelected}`);
2743 const elTarget = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.LPTarget}`);
2744 if (itemsSelectedData.length !== 0) {
2745 elBtnCountItemsSelected.disabled = false;
2746 elBtnAddItemsSelected.disabled = false;
2747 elBtnAddItemsSelected.classList.add('active');
2748 elSpanCount.textContent = `(${itemsSelectedData.length})`;
2749 elHeaderCount.innerHTML = elBtnCountItemsSelected.innerHTML;
2750 } else {
2751 elBtnCountItemsSelected.disabled = true;
2752 elBtnAddItemsSelected.disabled = true;
2753 elBtnAddItemsSelected.classList.remove('active');
2754 elSpanCount.textContent = '';
2755 elHeaderCount.textContent = '';
2756 }
2757
2758 // Update list input checked, when items removed, or change tab type
2759 const elListItems = elPopup.querySelector(`${LpPopupSelectItemToAdd.selectors.elListItems}`);
2760 const elInputs = elListItems.querySelectorAll('input[type="checkbox"]');
2761 elInputs.forEach(elInputItem => {
2762 const itemSelected = elInputItem.dataset;
2763 const exists = itemsSelectedData.some(item => item.id === itemSelected.id);
2764 elInputItem.checked = exists;
2765 });
2766
2767 // Set item selecting data to dataset for query.
2768 const dataSet = window.lpAJAXG.getDataSetCurrent(elTarget);
2769 dataSet.args.item_selecting = itemsSelectedData;
2770 window.lpAJAXG.setDataSetCurrent(elTarget, dataSet);
2771 };
2772
2773 // Add items selected to section
2774 addItemsSelectedToSection = args => {
2775 const {
2776 e,
2777 target,
2778 callBackHandle
2779 } = args;
2780 if (!elPopup) {
2781 return;
2782 }
2783 sweetalert2__WEBPACK_IMPORTED_MODULE_2___default().close();
2784 if (typeof callBackHandle === 'function') {
2785 callBackHandle(itemsSelectedData);
2786 itemsSelectedData = [];
2787 }
2788 };
2789 }
2790
2791 /***/ },
2792
2793 /***/ "./assets/src/js/lpToastify.js"
2794 /*!*************************************!*\
2795 !*** ./assets/src/js/lpToastify.js ***!
2796 \*************************************/
2797 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2798
2799 "use strict";
2800 __webpack_require__.r(__webpack_exports__);
2801 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2802 /* harmony export */ show: () => (/* binding */ show)
2803 /* harmony export */ });
2804 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
2805 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
2806 /* 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");
2807 /**
2808 * Utils functions
2809 *
2810 * @param url
2811 * @param data
2812 * @param functions
2813 * @since 4.3.0
2814 * @version 1.0.0
2815 */
2816
2817
2818 const argsToastify = {
2819 text: '',
2820 gravity: lpData.toast.gravity,
2821 // `top` or `bottom`
2822 position: lpData.toast.position,
2823 // `left`, `center` or `right`
2824 className: `${lpData.toast.classPrefix}`,
2825 close: lpData.toast.close == 1,
2826 stopOnFocus: lpData.toast.stopOnFocus == 1,
2827 duration: lpData.toast.duration
2828 };
2829 const show = (message, status = 'success', argsCustom) => {
2830 let args = argsToastify;
2831 if (argsCustom) {
2832 args = {
2833 ...args,
2834 ...argsCustom
2835 };
2836 }
2837 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
2838 ...args,
2839 text: message,
2840 className: `${lpData.toast.classPrefix} ${status}`
2841 });
2842 toastify.showToast();
2843 };
2844
2845 /***/ },
2846
2847 /***/ "./assets/src/js/utils.js"
2848 /*!********************************!*\
2849 !*** ./assets/src/js/utils.js ***!
2850 \********************************/
2851 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
2852
2853 "use strict";
2854 __webpack_require__.r(__webpack_exports__);
2855 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2856 /* harmony export */ debounce: () => (/* binding */ debounce),
2857 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
2858 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
2859 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
2860 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
2861 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
2862 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
2863 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
2864 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
2865 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
2866 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
2867 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
2868 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
2869 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
2870 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
2871 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
2872 /* harmony export */ });
2873 /**
2874 * Utils functions
2875 *
2876 * @param url
2877 * @param data
2878 * @param functions
2879 * @since 4.2.5.1
2880 * @version 1.0.6
2881 */
2882 const lpClassName = {
2883 hidden: 'lp-hidden',
2884 loading: 'loading',
2885 elCollapse: 'lp-collapse',
2886 elSectionToggle: '.lp-section-toggle',
2887 elTriggerToggle: '.lp-trigger-toggle'
2888 };
2889 const lpFetchAPI = (url, data = {}, functions = {}) => {
2890 if ('function' === typeof functions.before) {
2891 functions.before();
2892 }
2893 fetch(url, {
2894 method: 'GET',
2895 ...data
2896 }).then(response => response.json()).then(response => {
2897 if ('function' === typeof functions.success) {
2898 functions.success(response);
2899 }
2900 }).catch(err => {
2901 if ('function' === typeof functions.error) {
2902 functions.error(err);
2903 }
2904 }).finally(() => {
2905 if ('function' === typeof functions.completed) {
2906 functions.completed();
2907 }
2908 });
2909 };
2910
2911 /**
2912 * Get current URL without params.
2913 *
2914 * @since 4.2.5.1
2915 */
2916 const lpGetCurrentURLNoParam = () => {
2917 let currentUrl = window.location.href;
2918 const hasParams = currentUrl.includes('?');
2919 if (hasParams) {
2920 currentUrl = currentUrl.split('?')[0];
2921 }
2922 return currentUrl;
2923 };
2924 const lpAddQueryArgs = (endpoint, args) => {
2925 const url = new URL(endpoint);
2926 Object.keys(args).forEach(arg => {
2927 url.searchParams.set(arg, args[arg]);
2928 });
2929 return url;
2930 };
2931
2932 /**
2933 * Listen element viewed.
2934 *
2935 * @param el
2936 * @param callback
2937 * @since 4.2.5.8
2938 */
2939 const listenElementViewed = (el, callback) => {
2940 const observerSeeItem = new IntersectionObserver(function (entries) {
2941 for (const entry of entries) {
2942 if (entry.isIntersecting) {
2943 callback(entry);
2944 }
2945 }
2946 });
2947 observerSeeItem.observe(el);
2948 };
2949
2950 /**
2951 * Listen element created.
2952 *
2953 * @param callback
2954 * @since 4.2.5.8
2955 */
2956 const listenElementCreated = callback => {
2957 const observerCreateItem = new MutationObserver(function (mutations) {
2958 mutations.forEach(function (mutation) {
2959 if (mutation.addedNodes) {
2960 mutation.addedNodes.forEach(function (node) {
2961 if (node.nodeType === 1) {
2962 callback(node);
2963 }
2964 });
2965 }
2966 });
2967 });
2968 observerCreateItem.observe(document, {
2969 childList: true,
2970 subtree: true
2971 });
2972 // End.
2973 };
2974
2975 /**
2976 * Listen element created.
2977 *
2978 * @param selector
2979 * @param callback
2980 * @since 4.2.7.1
2981 */
2982 const lpOnElementReady = (selector, callback) => {
2983 const element = document.querySelector(selector);
2984 if (element) {
2985 callback(element);
2986 return;
2987 }
2988 const observer = new MutationObserver((mutations, obs) => {
2989 const element = document.querySelector(selector);
2990 if (element) {
2991 obs.disconnect();
2992 callback(element);
2993 }
2994 });
2995 observer.observe(document.documentElement, {
2996 childList: true,
2997 subtree: true
2998 });
2999 };
3000
3001 // Parse JSON from string with content include LP_AJAX_START.
3002 const lpAjaxParseJsonOld = data => {
3003 if (typeof data !== 'string') {
3004 return data;
3005 }
3006 const m = String.raw({
3007 raw: data
3008 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
3009 try {
3010 if (m) {
3011 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
3012 } else {
3013 data = JSON.parse(data);
3014 }
3015 } catch (e) {
3016 data = {};
3017 }
3018 return data;
3019 };
3020
3021 // status 0: hide, 1: show
3022 const lpShowHideEl = (el, status = 0) => {
3023 if (!el) {
3024 return;
3025 }
3026 if (!status) {
3027 el.classList.add(lpClassName.hidden);
3028 } else {
3029 el.classList.remove(lpClassName.hidden);
3030 }
3031 };
3032
3033 // status 0: hide, 1: show
3034 const lpSetLoadingEl = (el, status) => {
3035 if (!el) {
3036 return;
3037 }
3038 if (!status) {
3039 el.classList.remove(lpClassName.loading);
3040 } else {
3041 el.classList.add(lpClassName.loading);
3042 }
3043 };
3044
3045 // Toggle collapse section
3046 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
3047 if (!elTriggerClassName) {
3048 elTriggerClassName = lpClassName.elTriggerToggle;
3049 }
3050
3051 // Exclude elements, which should not trigger the collapse toggle
3052 if (elsExclude && elsExclude.length > 0) {
3053 for (const elExclude of elsExclude) {
3054 if (target.closest(elExclude)) {
3055 return;
3056 }
3057 }
3058 }
3059 const elTrigger = target.closest(elTriggerClassName);
3060 if (!elTrigger) {
3061 return;
3062 }
3063
3064 //console.log( 'elTrigger', elTrigger );
3065
3066 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
3067 if (!elSectionToggle) {
3068 return;
3069 }
3070 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
3071 if ('function' === typeof callback) {
3072 callback(elSectionToggle);
3073 }
3074 };
3075
3076 // Get data of form
3077 const getDataOfForm = form => {
3078 const dataSend = {};
3079 const formData = new FormData(form);
3080 for (const pair of formData.entries()) {
3081 const key = pair[0];
3082 const value = formData.getAll(key);
3083 if (!dataSend.hasOwnProperty(key)) {
3084 // Convert value array to string.
3085 dataSend[key] = value.join(',');
3086 }
3087 }
3088 return dataSend;
3089 };
3090
3091 // Get field keys of form
3092 const getFieldKeysOfForm = form => {
3093 const keys = [];
3094 const elements = form.elements;
3095 for (let i = 0; i < elements.length; i++) {
3096 const name = elements[i].name;
3097 if (name && !keys.includes(name)) {
3098 keys.push(name);
3099 }
3100 }
3101 return keys;
3102 };
3103
3104 // Merge data handle with data form.
3105 const mergeDataWithDatForm = (elForm, dataHandle) => {
3106 const dataForm = getDataOfForm(elForm);
3107 const keys = getFieldKeysOfForm(elForm);
3108 keys.forEach(key => {
3109 if (!dataForm.hasOwnProperty(key)) {
3110 delete dataHandle[key];
3111 } else if (dataForm[key][0] === '') {
3112 delete dataForm[key];
3113 delete dataHandle[key];
3114 }
3115 });
3116 dataHandle = {
3117 ...dataHandle,
3118 ...dataForm
3119 };
3120 return dataHandle;
3121 };
3122
3123 /**
3124 * Event trigger
3125 * For each list of event handlers, listen event on document.
3126 *
3127 * eventName: 'click', 'change', ...
3128 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
3129 *
3130 * @param eventName
3131 * @param eventHandlers
3132 */
3133 const eventHandlers = (eventName, eventHandlers) => {
3134 document.addEventListener(eventName, e => {
3135 const target = e.target;
3136 let args = {
3137 e,
3138 target
3139 };
3140 eventHandlers.forEach(eventHandler => {
3141 args = {
3142 ...args,
3143 ...eventHandler
3144 };
3145
3146 //console.log( args );
3147
3148 // Check condition before call back
3149 if (eventHandler.conditionBeforeCallBack) {
3150 if (eventHandler.conditionBeforeCallBack(args) !== true) {
3151 return;
3152 }
3153 }
3154
3155 // Special check for keydown event with checkIsEventEnter = true
3156 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
3157 if (e.key !== 'Enter') {
3158 return;
3159 }
3160 }
3161 if (target.closest(eventHandler.selector)) {
3162 if (eventHandler.class) {
3163 // Call method of class, function callBack will understand exactly {this} is class object.
3164 eventHandler.class[eventHandler.callBack](args);
3165 } else {
3166 // For send args is objected, {this} is eventHandler object, not class object.
3167 eventHandler.callBack(args);
3168 }
3169 }
3170 });
3171 });
3172 };
3173
3174 /**
3175 * Debounce - delays function execution until after `wait` ms of inactivity.
3176 *
3177 * Each call resets the timer. Only the last call in a burst executes.
3178 *
3179 * USE CASES:
3180 * - Search inputs, form validation, window resize
3181 * - Multiple elements need independent timers
3182 * - When you need to call with different arguments
3183 *
3184 * EXAMPLES:
3185 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
3186 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
3187 *
3188 * const debouncedResize = debounce( recalculateLayout, 250 );
3189 * window.addEventListener('resize', debouncedResize);
3190 *
3191 * ⚠️ Create ONCE outside event handlers, not inside.
3192 *
3193 * @param {Function} func - Function to debounce (can be anonymous)
3194 * @param {number} wait - Milliseconds to wait (default: 500)
3195 * @return {Function} Debounced wrapper function
3196 * @since 4.3.7
3197 * @version 1.0.0
3198 */
3199 const debounce = (func, wait = 500) => {
3200 let timer;
3201 return args => {
3202 clearTimeout(timer);
3203 timer = setTimeout(() => func(args), wait);
3204 };
3205 };
3206
3207 /***/ },
3208
3209 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
3210 /*!*****************************************************************************************!*\
3211 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
3212 \*****************************************************************************************/
3213 (module, __webpack_exports__, __webpack_require__) {
3214
3215 "use strict";
3216 __webpack_require__.r(__webpack_exports__);
3217 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3218 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
3219 /* harmony export */ });
3220 /* 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");
3221 /* 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__);
3222 /* 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");
3223 /* 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__);
3224 // Imports
3225
3226
3227 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()));
3228 // Module
3229 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
3230 * Toastify js 1.12.0
3231 * https://github.com/apvarun/toastify-js
3232 * @license MIT licensed
3233 *
3234 * Copyright (C) 2018 Varun A P
3235 */
3236
3237 .toastify {
3238 padding: 12px 20px;
3239 color: #ffffff;
3240 display: inline-block;
3241 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
3242 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
3243 background: linear-gradient(135deg, #73a5ff, #5477f5);
3244 position: fixed;
3245 opacity: 0;
3246 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
3247 border-radius: 2px;
3248 cursor: pointer;
3249 text-decoration: none;
3250 max-width: calc(50% - 20px);
3251 z-index: 2147483647;
3252 }
3253
3254 .toastify.on {
3255 opacity: 1;
3256 }
3257
3258 .toast-close {
3259 background: transparent;
3260 border: 0;
3261 color: white;
3262 cursor: pointer;
3263 font-family: inherit;
3264 font-size: 1em;
3265 opacity: 0.4;
3266 padding: 0 5px;
3267 }
3268
3269 .toastify-right {
3270 right: 15px;
3271 }
3272
3273 .toastify-left {
3274 left: 15px;
3275 }
3276
3277 .toastify-top {
3278 top: -150px;
3279 }
3280
3281 .toastify-bottom {
3282 bottom: -150px;
3283 }
3284
3285 .toastify-rounded {
3286 border-radius: 25px;
3287 }
3288
3289 .toastify-avatar {
3290 width: 1.5em;
3291 height: 1.5em;
3292 margin: -7px 5px;
3293 border-radius: 2px;
3294 }
3295
3296 .toastify-center {
3297 margin-left: auto;
3298 margin-right: auto;
3299 left: 0;
3300 right: 0;
3301 max-width: fit-content;
3302 max-width: -moz-fit-content;
3303 }
3304
3305 @media only screen and (max-width: 360px) {
3306 .toastify-right, .toastify-left {
3307 margin-left: auto;
3308 margin-right: auto;
3309 left: 0;
3310 right: 0;
3311 max-width: fit-content;
3312 }
3313 }
3314 `, "",{"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":""}]);
3315 // Exports
3316 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
3317
3318
3319 /***/ },
3320
3321 /***/ "./node_modules/css-loader/dist/runtime/api.js"
3322 /*!*****************************************************!*\
3323 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
3324 \*****************************************************/
3325 (module) {
3326
3327 "use strict";
3328
3329
3330 /*
3331 MIT License http://www.opensource.org/licenses/mit-license.php
3332 Author Tobias Koppers @sokra
3333 */
3334 module.exports = function (cssWithMappingToString) {
3335 var list = [];
3336
3337 // return the list of modules as css string
3338 list.toString = function toString() {
3339 return this.map(function (item) {
3340 var content = "";
3341 var needLayer = typeof item[5] !== "undefined";
3342 if (item[4]) {
3343 content += "@supports (".concat(item[4], ") {");
3344 }
3345 if (item[2]) {
3346 content += "@media ".concat(item[2], " {");
3347 }
3348 if (needLayer) {
3349 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
3350 }
3351 content += cssWithMappingToString(item);
3352 if (needLayer) {
3353 content += "}";
3354 }
3355 if (item[2]) {
3356 content += "}";
3357 }
3358 if (item[4]) {
3359 content += "}";
3360 }
3361 return content;
3362 }).join("");
3363 };
3364
3365 // import a list of modules into the list
3366 list.i = function i(modules, media, dedupe, supports, layer) {
3367 if (typeof modules === "string") {
3368 modules = [[null, modules, undefined]];
3369 }
3370 var alreadyImportedModules = {};
3371 if (dedupe) {
3372 for (var k = 0; k < this.length; k++) {
3373 var id = this[k][0];
3374 if (id != null) {
3375 alreadyImportedModules[id] = true;
3376 }
3377 }
3378 }
3379 for (var _k = 0; _k < modules.length; _k++) {
3380 var item = [].concat(modules[_k]);
3381 if (dedupe && alreadyImportedModules[item[0]]) {
3382 continue;
3383 }
3384 if (typeof layer !== "undefined") {
3385 if (typeof item[5] === "undefined") {
3386 item[5] = layer;
3387 } else {
3388 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
3389 item[5] = layer;
3390 }
3391 }
3392 if (media) {
3393 if (!item[2]) {
3394 item[2] = media;
3395 } else {
3396 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
3397 item[2] = media;
3398 }
3399 }
3400 if (supports) {
3401 if (!item[4]) {
3402 item[4] = "".concat(supports);
3403 } else {
3404 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
3405 item[4] = supports;
3406 }
3407 }
3408 list.push(item);
3409 }
3410 };
3411 return list;
3412 };
3413
3414 /***/ },
3415
3416 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
3417 /*!************************************************************!*\
3418 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
3419 \************************************************************/
3420 (module) {
3421
3422 "use strict";
3423
3424
3425 module.exports = function (item) {
3426 var content = item[1];
3427 var cssMapping = item[3];
3428 if (!cssMapping) {
3429 return content;
3430 }
3431 if (typeof btoa === "function") {
3432 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
3433 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
3434 var sourceMapping = "/*# ".concat(data, " */");
3435 return [content].concat([sourceMapping]).join("\n");
3436 }
3437 return [content].join("\n");
3438 };
3439
3440 /***/ },
3441
3442 /***/ "./node_modules/sortablejs/modular/sortable.esm.js"
3443 /*!*********************************************************!*\
3444 !*** ./node_modules/sortablejs/modular/sortable.esm.js ***!
3445 \*********************************************************/
3446 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3447
3448 "use strict";
3449 __webpack_require__.r(__webpack_exports__);
3450 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3451 /* harmony export */ MultiDrag: () => (/* binding */ MultiDragPlugin),
3452 /* harmony export */ Sortable: () => (/* binding */ Sortable),
3453 /* harmony export */ Swap: () => (/* binding */ SwapPlugin),
3454 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
3455 /* harmony export */ });
3456 /**!
3457 * Sortable 1.15.7
3458 * @author RubaXa <[email protected]>
3459 * @author owenm <[email protected]>
3460 * @license MIT
3461 */
3462 function _arrayLikeToArray(r, a) {
3463 (null == a || a > r.length) && (a = r.length);
3464 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
3465 return n;
3466 }
3467 function _arrayWithoutHoles(r) {
3468 if (Array.isArray(r)) return _arrayLikeToArray(r);
3469 }
3470 function _defineProperty(e, r, t) {
3471 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
3472 value: t,
3473 enumerable: !0,
3474 configurable: !0,
3475 writable: !0
3476 }) : e[r] = t, e;
3477 }
3478 function _extends() {
3479 return _extends = Object.assign ? Object.assign.bind() : function (n) {
3480 for (var e = 1; e < arguments.length; e++) {
3481 var t = arguments[e];
3482 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
3483 }
3484 return n;
3485 }, _extends.apply(null, arguments);
3486 }
3487 function _iterableToArray(r) {
3488 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
3489 }
3490 function _nonIterableSpread() {
3491 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3492 }
3493 function ownKeys(e, r) {
3494 var t = Object.keys(e);
3495 if (Object.getOwnPropertySymbols) {
3496 var o = Object.getOwnPropertySymbols(e);
3497 r && (o = o.filter(function (r) {
3498 return Object.getOwnPropertyDescriptor(e, r).enumerable;
3499 })), t.push.apply(t, o);
3500 }
3501 return t;
3502 }
3503 function _objectSpread2(e) {
3504 for (var r = 1; r < arguments.length; r++) {
3505 var t = null != arguments[r] ? arguments[r] : {};
3506 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
3507 _defineProperty(e, r, t[r]);
3508 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
3509 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
3510 });
3511 }
3512 return e;
3513 }
3514 function _objectWithoutProperties(e, t) {
3515 if (null == e) return {};
3516 var o,
3517 r,
3518 i = _objectWithoutPropertiesLoose(e, t);
3519 if (Object.getOwnPropertySymbols) {
3520 var n = Object.getOwnPropertySymbols(e);
3521 for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
3522 }
3523 return i;
3524 }
3525 function _objectWithoutPropertiesLoose(r, e) {
3526 if (null == r) return {};
3527 var t = {};
3528 for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
3529 if (-1 !== e.indexOf(n)) continue;
3530 t[n] = r[n];
3531 }
3532 return t;
3533 }
3534 function _toConsumableArray(r) {
3535 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
3536 }
3537 function _toPrimitive(t, r) {
3538 if ("object" != typeof t || !t) return t;
3539 var e = t[Symbol.toPrimitive];
3540 if (void 0 !== e) {
3541 var i = e.call(t, r || "default");
3542 if ("object" != typeof i) return i;
3543 throw new TypeError("@@toPrimitive must return a primitive value.");
3544 }
3545 return ("string" === r ? String : Number)(t);
3546 }
3547 function _toPropertyKey(t) {
3548 var i = _toPrimitive(t, "string");
3549 return "symbol" == typeof i ? i : i + "";
3550 }
3551 function _typeof(o) {
3552 "@babel/helpers - typeof";
3553
3554 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
3555 return typeof o;
3556 } : function (o) {
3557 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
3558 }, _typeof(o);
3559 }
3560 function _unsupportedIterableToArray(r, a) {
3561 if (r) {
3562 if ("string" == typeof r) return _arrayLikeToArray(r, a);
3563 var t = {}.toString.call(r).slice(8, -1);
3564 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;
3565 }
3566 }
3567
3568 var version = "1.15.7";
3569
3570 function userAgent(pattern) {
3571 if (typeof window !== 'undefined' && window.navigator) {
3572 return !! /*@__PURE__*/navigator.userAgent.match(pattern);
3573 }
3574 }
3575 var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i);
3576 var Edge = userAgent(/Edge/i);
3577 var FireFox = userAgent(/firefox/i);
3578 var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i);
3579 var IOS = userAgent(/iP(ad|od|hone)/i);
3580 var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i);
3581
3582 var captureMode = {
3583 capture: false,
3584 passive: false
3585 };
3586 function on(el, event, fn) {
3587 el.addEventListener(event, fn, !IE11OrLess && captureMode);
3588 }
3589 function off(el, event, fn) {
3590 el.removeEventListener(event, fn, !IE11OrLess && captureMode);
3591 }
3592 function matches( /**HTMLElement*/el, /**String*/selector) {
3593 if (!selector) return;
3594 selector[0] === '>' && (selector = selector.substring(1));
3595 if (el) {
3596 try {
3597 if (el.matches) {
3598 return el.matches(selector);
3599 } else if (el.msMatchesSelector) {
3600 return el.msMatchesSelector(selector);
3601 } else if (el.webkitMatchesSelector) {
3602 return el.webkitMatchesSelector(selector);
3603 }
3604 } catch (_) {
3605 return false;
3606 }
3607 }
3608 return false;
3609 }
3610 function getParentOrHost(el) {
3611 return el.host && el !== document && el.host.nodeType && el.host !== el ? el.host : el.parentNode;
3612 }
3613 function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) {
3614 if (el) {
3615 ctx = ctx || document;
3616 do {
3617 if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) {
3618 return el;
3619 }
3620 if (el === ctx) break;
3621 /* jshint boss:true */
3622 } while (el = getParentOrHost(el));
3623 }
3624 return null;
3625 }
3626 var R_SPACE = /\s+/g;
3627 function toggleClass(el, name, state) {
3628 if (el && name) {
3629 if (el.classList) {
3630 el.classList[state ? 'add' : 'remove'](name);
3631 } else {
3632 var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' ');
3633 el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' ');
3634 }
3635 }
3636 }
3637 function css(el, prop, val) {
3638 var style = el && el.style;
3639 if (style) {
3640 if (val === void 0) {
3641 if (document.defaultView && document.defaultView.getComputedStyle) {
3642 val = document.defaultView.getComputedStyle(el, '');
3643 } else if (el.currentStyle) {
3644 val = el.currentStyle;
3645 }
3646 return prop === void 0 ? val : val[prop];
3647 } else {
3648 if (!(prop in style) && prop.indexOf('webkit') === -1) {
3649 prop = '-webkit-' + prop;
3650 }
3651 style[prop] = val + (typeof val === 'string' ? '' : 'px');
3652 }
3653 }
3654 }
3655 function matrix(el, selfOnly) {
3656 var appliedTransforms = '';
3657 if (typeof el === 'string') {
3658 appliedTransforms = el;
3659 } else {
3660 do {
3661 var transform = css(el, 'transform');
3662 if (transform && transform !== 'none') {
3663 appliedTransforms = transform + ' ' + appliedTransforms;
3664 }
3665 /* jshint boss:true */
3666 } while (!selfOnly && (el = el.parentNode));
3667 }
3668 var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix;
3669 /*jshint -W056 */
3670 return matrixFn && new matrixFn(appliedTransforms);
3671 }
3672 function find(ctx, tagName, iterator) {
3673 if (ctx) {
3674 var list = ctx.getElementsByTagName(tagName),
3675 i = 0,
3676 n = list.length;
3677 if (iterator) {
3678 for (; i < n; i++) {
3679 iterator(list[i], i);
3680 }
3681 }
3682 return list;
3683 }
3684 return [];
3685 }
3686 function getWindowScrollingElement() {
3687 var scrollingElement = document.scrollingElement;
3688 if (scrollingElement) {
3689 return scrollingElement;
3690 } else {
3691 return document.documentElement;
3692 }
3693 }
3694
3695 /**
3696 * Returns the "bounding client rect" of given element
3697 * @param {HTMLElement} el The element whose boundingClientRect is wanted
3698 * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container
3699 * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr
3700 * @param {[Boolean]} undoScale Whether the container's scale() should be undone
3701 * @param {[HTMLElement]} container The parent the element will be placed in
3702 * @return {Object} The boundingClientRect of el, with specified adjustments
3703 */
3704 function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) {
3705 if (!el.getBoundingClientRect && el !== window) return;
3706 var elRect, top, left, bottom, right, height, width;
3707 if (el !== window && el.parentNode && el !== getWindowScrollingElement()) {
3708 elRect = el.getBoundingClientRect();
3709 top = elRect.top;
3710 left = elRect.left;
3711 bottom = elRect.bottom;
3712 right = elRect.right;
3713 height = elRect.height;
3714 width = elRect.width;
3715 } else {
3716 top = 0;
3717 left = 0;
3718 bottom = window.innerHeight;
3719 right = window.innerWidth;
3720 height = window.innerHeight;
3721 width = window.innerWidth;
3722 }
3723 if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) {
3724 // Adjust for translate()
3725 container = container || el.parentNode;
3726
3727 // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312)
3728 // Not needed on <= IE11
3729 if (!IE11OrLess) {
3730 do {
3731 if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) {
3732 var containerRect = container.getBoundingClientRect();
3733
3734 // Set relative to edges of padding box of container
3735 top -= containerRect.top + parseInt(css(container, 'border-top-width'));
3736 left -= containerRect.left + parseInt(css(container, 'border-left-width'));
3737 bottom = top + elRect.height;
3738 right = left + elRect.width;
3739 break;
3740 }
3741 /* jshint boss:true */
3742 } while (container = container.parentNode);
3743 }
3744 }
3745 if (undoScale && el !== window) {
3746 // Adjust for scale()
3747 var elMatrix = matrix(container || el),
3748 scaleX = elMatrix && elMatrix.a,
3749 scaleY = elMatrix && elMatrix.d;
3750 if (elMatrix) {
3751 top /= scaleY;
3752 left /= scaleX;
3753 width /= scaleX;
3754 height /= scaleY;
3755 bottom = top + height;
3756 right = left + width;
3757 }
3758 }
3759 return {
3760 top: top,
3761 left: left,
3762 bottom: bottom,
3763 right: right,
3764 width: width,
3765 height: height
3766 };
3767 }
3768
3769 /**
3770 * Checks if a side of an element is scrolled past a side of its parents
3771 * @param {HTMLElement} el The element who's side being scrolled out of view is in question
3772 * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom')
3773 * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom')
3774 * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element
3775 */
3776 function isScrolledPast(el, elSide, parentSide) {
3777 var parent = getParentAutoScrollElement(el, true),
3778 elSideVal = getRect(el)[elSide];
3779
3780 /* jshint boss:true */
3781 while (parent) {
3782 var parentSideVal = getRect(parent)[parentSide],
3783 visible = void 0;
3784 if (parentSide === 'top' || parentSide === 'left') {
3785 visible = elSideVal >= parentSideVal;
3786 } else {
3787 visible = elSideVal <= parentSideVal;
3788 }
3789 if (!visible) return parent;
3790 if (parent === getWindowScrollingElement()) break;
3791 parent = getParentAutoScrollElement(parent, false);
3792 }
3793 return false;
3794 }
3795
3796 /**
3797 * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible)
3798 * and non-draggable elements
3799 * @param {HTMLElement} el The parent element
3800 * @param {Number} childNum The index of the child
3801 * @param {Object} options Parent Sortable's options
3802 * @return {HTMLElement} The child at index childNum, or null if not found
3803 */
3804 function getChild(el, childNum, options, includeDragEl) {
3805 var currentChild = 0,
3806 i = 0,
3807 children = el.children;
3808 while (i < children.length) {
3809 if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) {
3810 if (currentChild === childNum) {
3811 return children[i];
3812 }
3813 currentChild++;
3814 }
3815 i++;
3816 }
3817 return null;
3818 }
3819
3820 /**
3821 * Gets the last child in the el, ignoring ghostEl or invisible elements (clones)
3822 * @param {HTMLElement} el Parent element
3823 * @param {selector} selector Any other elements that should be ignored
3824 * @return {HTMLElement} The last child, ignoring ghostEl
3825 */
3826 function lastChild(el, selector) {
3827 var last = el.lastElementChild;
3828 while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) {
3829 last = last.previousElementSibling;
3830 }
3831 return last || null;
3832 }
3833
3834 /**
3835 * Returns the index of an element within its parent for a selected set of
3836 * elements
3837 * @param {HTMLElement} el
3838 * @param {selector} selector
3839 * @return {number}
3840 */
3841 function index(el, selector) {
3842 var index = 0;
3843 if (!el || !el.parentNode) {
3844 return -1;
3845 }
3846
3847 /* jshint boss:true */
3848 while (el = el.previousElementSibling) {
3849 if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) {
3850 index++;
3851 }
3852 }
3853 return index;
3854 }
3855
3856 /**
3857 * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements.
3858 * The value is returned in real pixels.
3859 * @param {HTMLElement} el
3860 * @return {Array} Offsets in the format of [left, top]
3861 */
3862 function getRelativeScrollOffset(el) {
3863 var offsetLeft = 0,
3864 offsetTop = 0,
3865 winScroller = getWindowScrollingElement();
3866 if (el) {
3867 do {
3868 var elMatrix = matrix(el),
3869 scaleX = elMatrix.a,
3870 scaleY = elMatrix.d;
3871 offsetLeft += el.scrollLeft * scaleX;
3872 offsetTop += el.scrollTop * scaleY;
3873 } while (el !== winScroller && (el = el.parentNode));
3874 }
3875 return [offsetLeft, offsetTop];
3876 }
3877
3878 /**
3879 * Returns the index of the object within the given array
3880 * @param {Array} arr Array that may or may not hold the object
3881 * @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
3882 * @return {Number} The index of the object in the array, or -1
3883 */
3884 function indexOfObject(arr, obj) {
3885 for (var i in arr) {
3886 if (!arr.hasOwnProperty(i)) continue;
3887 for (var key in obj) {
3888 if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i);
3889 }
3890 }
3891 return -1;
3892 }
3893 function getParentAutoScrollElement(el, includeSelf) {
3894 // skip to window
3895 if (!el || !el.getBoundingClientRect) return getWindowScrollingElement();
3896 var elem = el;
3897 var gotSelf = false;
3898 do {
3899 // we don't need to get elem css if it isn't even overflowing in the first place (performance)
3900 if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) {
3901 var elemCSS = css(elem);
3902 if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) {
3903 if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement();
3904 if (gotSelf || includeSelf) return elem;
3905 gotSelf = true;
3906 }
3907 }
3908 /* jshint boss:true */
3909 } while (elem = elem.parentNode);
3910 return getWindowScrollingElement();
3911 }
3912 function extend(dst, src) {
3913 if (dst && src) {
3914 for (var key in src) {
3915 if (src.hasOwnProperty(key)) {
3916 dst[key] = src[key];
3917 }
3918 }
3919 }
3920 return dst;
3921 }
3922 function isRectEqual(rect1, rect2) {
3923 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);
3924 }
3925 var _throttleTimeout;
3926 function throttle(callback, ms) {
3927 return function () {
3928 if (!_throttleTimeout) {
3929 var args = arguments,
3930 _this = this;
3931 if (args.length === 1) {
3932 callback.call(_this, args[0]);
3933 } else {
3934 callback.apply(_this, args);
3935 }
3936 _throttleTimeout = setTimeout(function () {
3937 _throttleTimeout = void 0;
3938 }, ms);
3939 }
3940 };
3941 }
3942 function cancelThrottle() {
3943 clearTimeout(_throttleTimeout);
3944 _throttleTimeout = void 0;
3945 }
3946 function scrollBy(el, x, y) {
3947 el.scrollLeft += x;
3948 el.scrollTop += y;
3949 }
3950 function clone(el) {
3951 var Polymer = window.Polymer;
3952 var $ = window.jQuery || window.Zepto;
3953 if (Polymer && Polymer.dom) {
3954 return Polymer.dom(el).cloneNode(true);
3955 } else if ($) {
3956 return $(el).clone(true)[0];
3957 } else {
3958 return el.cloneNode(true);
3959 }
3960 }
3961 function setRect(el, rect) {
3962 css(el, 'position', 'absolute');
3963 css(el, 'top', rect.top);
3964 css(el, 'left', rect.left);
3965 css(el, 'width', rect.width);
3966 css(el, 'height', rect.height);
3967 }
3968 function unsetRect(el) {
3969 css(el, 'position', '');
3970 css(el, 'top', '');
3971 css(el, 'left', '');
3972 css(el, 'width', '');
3973 css(el, 'height', '');
3974 }
3975 function getChildContainingRectFromElement(container, options, ghostEl) {
3976 var rect = {};
3977 Array.from(container.children).forEach(function (child) {
3978 var _rect$left, _rect$top, _rect$right, _rect$bottom;
3979 if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return;
3980 var childRect = getRect(child);
3981 rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left);
3982 rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top);
3983 rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right);
3984 rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom);
3985 });
3986 rect.width = rect.right - rect.left;
3987 rect.height = rect.bottom - rect.top;
3988 rect.x = rect.left;
3989 rect.y = rect.top;
3990 return rect;
3991 }
3992 var expando = 'Sortable' + new Date().getTime();
3993
3994 function AnimationStateManager() {
3995 var animationStates = [],
3996 animationCallbackId;
3997 return {
3998 captureAnimationState: function captureAnimationState() {
3999 animationStates = [];
4000 if (!this.options.animation) return;
4001 var children = [].slice.call(this.el.children);
4002 children.forEach(function (child) {
4003 if (css(child, 'display') === 'none' || child === Sortable.ghost) return;
4004 animationStates.push({
4005 target: child,
4006 rect: getRect(child)
4007 });
4008 var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect);
4009
4010 // If animating: compensate for current animation
4011 if (child.thisAnimationDuration) {
4012 var childMatrix = matrix(child, true);
4013 if (childMatrix) {
4014 fromRect.top -= childMatrix.f;
4015 fromRect.left -= childMatrix.e;
4016 }
4017 }
4018 child.fromRect = fromRect;
4019 });
4020 },
4021 addAnimationState: function addAnimationState(state) {
4022 animationStates.push(state);
4023 },
4024 removeAnimationState: function removeAnimationState(target) {
4025 animationStates.splice(indexOfObject(animationStates, {
4026 target: target
4027 }), 1);
4028 },
4029 animateAll: function animateAll(callback) {
4030 var _this = this;
4031 if (!this.options.animation) {
4032 clearTimeout(animationCallbackId);
4033 if (typeof callback === 'function') callback();
4034 return;
4035 }
4036 var animating = false,
4037 animationTime = 0;
4038 animationStates.forEach(function (state) {
4039 var time = 0,
4040 target = state.target,
4041 fromRect = target.fromRect,
4042 toRect = getRect(target),
4043 prevFromRect = target.prevFromRect,
4044 prevToRect = target.prevToRect,
4045 animatingRect = state.rect,
4046 targetMatrix = matrix(target, true);
4047 if (targetMatrix) {
4048 // Compensate for current animation
4049 toRect.top -= targetMatrix.f;
4050 toRect.left -= targetMatrix.e;
4051 }
4052 target.toRect = toRect;
4053 if (target.thisAnimationDuration) {
4054 // Could also check if animatingRect is between fromRect and toRect
4055 if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) &&
4056 // Make sure animatingRect is on line between toRect & fromRect
4057 (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) {
4058 // If returning to same place as started from animation and on same axis
4059 time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options);
4060 }
4061 }
4062
4063 // if fromRect != toRect: animate
4064 if (!isRectEqual(toRect, fromRect)) {
4065 target.prevFromRect = fromRect;
4066 target.prevToRect = toRect;
4067 if (!time) {
4068 time = _this.options.animation;
4069 }
4070 _this.animate(target, animatingRect, toRect, time);
4071 }
4072 if (time) {
4073 animating = true;
4074 animationTime = Math.max(animationTime, time);
4075 clearTimeout(target.animationResetTimer);
4076 target.animationResetTimer = setTimeout(function () {
4077 target.animationTime = 0;
4078 target.prevFromRect = null;
4079 target.fromRect = null;
4080 target.prevToRect = null;
4081 target.thisAnimationDuration = null;
4082 }, time);
4083 target.thisAnimationDuration = time;
4084 }
4085 });
4086 clearTimeout(animationCallbackId);
4087 if (!animating) {
4088 if (typeof callback === 'function') callback();
4089 } else {
4090 animationCallbackId = setTimeout(function () {
4091 if (typeof callback === 'function') callback();
4092 }, animationTime);
4093 }
4094 animationStates = [];
4095 },
4096 animate: function animate(target, currentRect, toRect, duration) {
4097 if (duration) {
4098 css(target, 'transition', '');
4099 css(target, 'transform', '');
4100 var elMatrix = matrix(this.el),
4101 scaleX = elMatrix && elMatrix.a,
4102 scaleY = elMatrix && elMatrix.d,
4103 translateX = (currentRect.left - toRect.left) / (scaleX || 1),
4104 translateY = (currentRect.top - toRect.top) / (scaleY || 1);
4105 target.animatingX = !!translateX;
4106 target.animatingY = !!translateY;
4107 css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)');
4108 this.forRepaintDummy = repaint(target); // repaint
4109
4110 css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : ''));
4111 css(target, 'transform', 'translate3d(0,0,0)');
4112 typeof target.animated === 'number' && clearTimeout(target.animated);
4113 target.animated = setTimeout(function () {
4114 css(target, 'transition', '');
4115 css(target, 'transform', '');
4116 target.animated = false;
4117 target.animatingX = false;
4118 target.animatingY = false;
4119 }, duration);
4120 }
4121 }
4122 };
4123 }
4124 function repaint(target) {
4125 return target.offsetWidth;
4126 }
4127 function calculateRealTime(animatingRect, fromRect, toRect, options) {
4128 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;
4129 }
4130
4131 var plugins = [];
4132 var defaults = {
4133 initializeByDefault: true
4134 };
4135 var PluginManager = {
4136 mount: function mount(plugin) {
4137 // Set default static properties
4138 for (var option in defaults) {
4139 if (defaults.hasOwnProperty(option) && !(option in plugin)) {
4140 plugin[option] = defaults[option];
4141 }
4142 }
4143 plugins.forEach(function (p) {
4144 if (p.pluginName === plugin.pluginName) {
4145 throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once");
4146 }
4147 });
4148 plugins.push(plugin);
4149 },
4150 pluginEvent: function pluginEvent(eventName, sortable, evt) {
4151 var _this = this;
4152 this.eventCanceled = false;
4153 evt.cancel = function () {
4154 _this.eventCanceled = true;
4155 };
4156 var eventNameGlobal = eventName + 'Global';
4157 plugins.forEach(function (plugin) {
4158 if (!sortable[plugin.pluginName]) return;
4159 // Fire global events if it exists in this sortable
4160 if (sortable[plugin.pluginName][eventNameGlobal]) {
4161 sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({
4162 sortable: sortable
4163 }, evt));
4164 }
4165
4166 // Only fire plugin event if plugin is enabled in this sortable,
4167 // and plugin has event defined
4168 if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) {
4169 sortable[plugin.pluginName][eventName](_objectSpread2({
4170 sortable: sortable
4171 }, evt));
4172 }
4173 });
4174 },
4175 initializePlugins: function initializePlugins(sortable, el, defaults, options) {
4176 plugins.forEach(function (plugin) {
4177 var pluginName = plugin.pluginName;
4178 if (!sortable.options[pluginName] && !plugin.initializeByDefault) return;
4179 var initialized = new plugin(sortable, el, sortable.options);
4180 initialized.sortable = sortable;
4181 initialized.options = sortable.options;
4182 sortable[pluginName] = initialized;
4183
4184 // Add default options from plugin
4185 _extends(defaults, initialized.defaults);
4186 });
4187 for (var option in sortable.options) {
4188 if (!sortable.options.hasOwnProperty(option)) continue;
4189 var modified = this.modifyOption(sortable, option, sortable.options[option]);
4190 if (typeof modified !== 'undefined') {
4191 sortable.options[option] = modified;
4192 }
4193 }
4194 },
4195 getEventProperties: function getEventProperties(name, sortable) {
4196 var eventProperties = {};
4197 plugins.forEach(function (plugin) {
4198 if (typeof plugin.eventProperties !== 'function') return;
4199 _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name));
4200 });
4201 return eventProperties;
4202 },
4203 modifyOption: function modifyOption(sortable, name, value) {
4204 var modifiedValue;
4205 plugins.forEach(function (plugin) {
4206 // Plugin must exist on the Sortable
4207 if (!sortable[plugin.pluginName]) return;
4208
4209 // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin
4210 if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') {
4211 modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value);
4212 }
4213 });
4214 return modifiedValue;
4215 }
4216 };
4217
4218 function dispatchEvent(_ref) {
4219 var sortable = _ref.sortable,
4220 rootEl = _ref.rootEl,
4221 name = _ref.name,
4222 targetEl = _ref.targetEl,
4223 cloneEl = _ref.cloneEl,
4224 toEl = _ref.toEl,
4225 fromEl = _ref.fromEl,
4226 oldIndex = _ref.oldIndex,
4227 newIndex = _ref.newIndex,
4228 oldDraggableIndex = _ref.oldDraggableIndex,
4229 newDraggableIndex = _ref.newDraggableIndex,
4230 originalEvent = _ref.originalEvent,
4231 putSortable = _ref.putSortable,
4232 extraEventProperties = _ref.extraEventProperties;
4233 sortable = sortable || rootEl && rootEl[expando];
4234 if (!sortable) return;
4235 var evt,
4236 options = sortable.options,
4237 onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
4238 // Support for new CustomEvent feature
4239 if (window.CustomEvent && !IE11OrLess && !Edge) {
4240 evt = new CustomEvent(name, {
4241 bubbles: true,
4242 cancelable: true
4243 });
4244 } else {
4245 evt = document.createEvent('Event');
4246 evt.initEvent(name, true, true);
4247 }
4248 evt.to = toEl || rootEl;
4249 evt.from = fromEl || rootEl;
4250 evt.item = targetEl || rootEl;
4251 evt.clone = cloneEl;
4252 evt.oldIndex = oldIndex;
4253 evt.newIndex = newIndex;
4254 evt.oldDraggableIndex = oldDraggableIndex;
4255 evt.newDraggableIndex = newDraggableIndex;
4256 evt.originalEvent = originalEvent;
4257 evt.pullMode = putSortable ? putSortable.lastPutMode : undefined;
4258 var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable));
4259 for (var option in allEventProperties) {
4260 evt[option] = allEventProperties[option];
4261 }
4262 if (rootEl) {
4263 rootEl.dispatchEvent(evt);
4264 }
4265 if (options[onName]) {
4266 options[onName].call(sortable, evt);
4267 }
4268 }
4269
4270 var _excluded = ["evt"];
4271 var pluginEvent = function pluginEvent(eventName, sortable) {
4272 var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
4273 originalEvent = _ref.evt,
4274 data = _objectWithoutProperties(_ref, _excluded);
4275 PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({
4276 dragEl: dragEl,
4277 parentEl: parentEl,
4278 ghostEl: ghostEl,
4279 rootEl: rootEl,
4280 nextEl: nextEl,
4281 lastDownEl: lastDownEl,
4282 cloneEl: cloneEl,
4283 cloneHidden: cloneHidden,
4284 dragStarted: moved,
4285 putSortable: putSortable,
4286 activeSortable: Sortable.active,
4287 originalEvent: originalEvent,
4288 oldIndex: oldIndex,
4289 oldDraggableIndex: oldDraggableIndex,
4290 newIndex: newIndex,
4291 newDraggableIndex: newDraggableIndex,
4292 hideGhostForTarget: _hideGhostForTarget,
4293 unhideGhostForTarget: _unhideGhostForTarget,
4294 cloneNowHidden: function cloneNowHidden() {
4295 cloneHidden = true;
4296 },
4297 cloneNowShown: function cloneNowShown() {
4298 cloneHidden = false;
4299 },
4300 dispatchSortableEvent: function dispatchSortableEvent(name) {
4301 _dispatchEvent({
4302 sortable: sortable,
4303 name: name,
4304 originalEvent: originalEvent
4305 });
4306 }
4307 }, data));
4308 };
4309 function _dispatchEvent(info) {
4310 dispatchEvent(_objectSpread2({
4311 putSortable: putSortable,
4312 cloneEl: cloneEl,
4313 targetEl: dragEl,
4314 rootEl: rootEl,
4315 oldIndex: oldIndex,
4316 oldDraggableIndex: oldDraggableIndex,
4317 newIndex: newIndex,
4318 newDraggableIndex: newDraggableIndex
4319 }, info));
4320 }
4321 var dragEl,
4322 parentEl,
4323 ghostEl,
4324 rootEl,
4325 nextEl,
4326 lastDownEl,
4327 cloneEl,
4328 cloneHidden,
4329 oldIndex,
4330 newIndex,
4331 oldDraggableIndex,
4332 newDraggableIndex,
4333 activeGroup,
4334 putSortable,
4335 awaitingDragStarted = false,
4336 ignoreNextClick = false,
4337 sortables = [],
4338 tapEvt,
4339 touchEvt,
4340 lastDx,
4341 lastDy,
4342 tapDistanceLeft,
4343 tapDistanceTop,
4344 moved,
4345 lastTarget,
4346 lastDirection,
4347 pastFirstInvertThresh = false,
4348 isCircumstantialInvert = false,
4349 targetMoveDistance,
4350 // For positioning ghost absolutely
4351 ghostRelativeParent,
4352 ghostRelativeParentInitialScroll = [],
4353 // (left, top)
4354
4355 _silent = false,
4356 savedInputChecked = [];
4357
4358 /** @const */
4359 var documentExists = typeof document !== 'undefined',
4360 PositionGhostAbsolutely = IOS,
4361 CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float',
4362 // This will not pass for IE9, because IE9 DnD only works on anchors
4363 supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'),
4364 supportCssPointerEvents = function () {
4365 if (!documentExists) return;
4366 // false when <= IE11
4367 if (IE11OrLess) {
4368 return false;
4369 }
4370 var el = document.createElement('x');
4371 el.style.cssText = 'pointer-events:auto';
4372 return el.style.pointerEvents === 'auto';
4373 }(),
4374 _detectDirection = function _detectDirection(el, options) {
4375 var elCSS = css(el),
4376 elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth),
4377 child1 = getChild(el, 0, options),
4378 child2 = getChild(el, 1, options),
4379 firstChildCSS = child1 && css(child1),
4380 secondChildCSS = child2 && css(child2),
4381 firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width,
4382 secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width;
4383 if (elCSS.display === 'flex') {
4384 return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal';
4385 }
4386 if (elCSS.display === 'grid') {
4387 return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
4388 }
4389 if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') {
4390 var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right';
4391 return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal';
4392 }
4393 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';
4394 },
4395 _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) {
4396 var dragElS1Opp = vertical ? dragRect.left : dragRect.top,
4397 dragElS2Opp = vertical ? dragRect.right : dragRect.bottom,
4398 dragElOppLength = vertical ? dragRect.width : dragRect.height,
4399 targetS1Opp = vertical ? targetRect.left : targetRect.top,
4400 targetS2Opp = vertical ? targetRect.right : targetRect.bottom,
4401 targetOppLength = vertical ? targetRect.width : targetRect.height;
4402 return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2;
4403 },
4404 /**
4405 * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold.
4406 * @param {Number} x X position
4407 * @param {Number} y Y position
4408 * @return {HTMLElement} Element of the first found nearest Sortable
4409 */
4410 _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) {
4411 var ret;
4412 sortables.some(function (sortable) {
4413 var threshold = sortable[expando].options.emptyInsertThreshold;
4414 if (!threshold || lastChild(sortable)) return;
4415 var rect = getRect(sortable),
4416 insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold,
4417 insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold;
4418 if (insideHorizontally && insideVertically) {
4419 return ret = sortable;
4420 }
4421 });
4422 return ret;
4423 },
4424 _prepareGroup = function _prepareGroup(options) {
4425 function toFn(value, pull) {
4426 return function (to, from, dragEl, evt) {
4427 var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name;
4428 if (value == null && (pull || sameGroup)) {
4429 // Default pull value
4430 // Default pull and put value if same group
4431 return true;
4432 } else if (value == null || value === false) {
4433 return false;
4434 } else if (pull && value === 'clone') {
4435 return value;
4436 } else if (typeof value === 'function') {
4437 return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt);
4438 } else {
4439 var otherGroup = (pull ? to : from).options.group.name;
4440 return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1;
4441 }
4442 };
4443 }
4444 var group = {};
4445 var originalGroup = options.group;
4446 if (!originalGroup || _typeof(originalGroup) != 'object') {
4447 originalGroup = {
4448 name: originalGroup
4449 };
4450 }
4451 group.name = originalGroup.name;
4452 group.checkPull = toFn(originalGroup.pull, true);
4453 group.checkPut = toFn(originalGroup.put);
4454 group.revertClone = originalGroup.revertClone;
4455 options.group = group;
4456 },
4457 _hideGhostForTarget = function _hideGhostForTarget() {
4458 if (!supportCssPointerEvents && ghostEl) {
4459 css(ghostEl, 'display', 'none');
4460 }
4461 },
4462 _unhideGhostForTarget = function _unhideGhostForTarget() {
4463 if (!supportCssPointerEvents && ghostEl) {
4464 css(ghostEl, 'display', '');
4465 }
4466 };
4467
4468 // #1184 fix - Prevent click event on fallback if dragged but item not changed position
4469 if (documentExists && !ChromeForAndroid) {
4470 document.addEventListener('click', function (evt) {
4471 if (ignoreNextClick) {
4472 evt.preventDefault();
4473 evt.stopPropagation && evt.stopPropagation();
4474 evt.stopImmediatePropagation && evt.stopImmediatePropagation();
4475 ignoreNextClick = false;
4476 return false;
4477 }
4478 }, true);
4479 }
4480 var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) {
4481 if (dragEl) {
4482 evt = evt.touches ? evt.touches[0] : evt;
4483 var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY);
4484 if (nearest) {
4485 // Create imitation event
4486 var event = {};
4487 for (var i in evt) {
4488 if (evt.hasOwnProperty(i)) {
4489 event[i] = evt[i];
4490 }
4491 }
4492 event.target = event.rootEl = nearest;
4493 event.preventDefault = void 0;
4494 event.stopPropagation = void 0;
4495 nearest[expando]._onDragOver(event);
4496 }
4497 }
4498 };
4499 var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) {
4500 if (dragEl) {
4501 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
4502 }
4503 };
4504
4505 /**
4506 * @class Sortable
4507 * @param {HTMLElement} el
4508 * @param {Object} [options]
4509 */
4510 function Sortable(el, options) {
4511 if (!(el && el.nodeType && el.nodeType === 1)) {
4512 throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el));
4513 }
4514 this.el = el; // root element
4515 this.options = options = _extends({}, options);
4516
4517 // Export instance
4518 el[expando] = this;
4519 var defaults = {
4520 group: null,
4521 sort: true,
4522 disabled: false,
4523 store: null,
4524 handle: null,
4525 draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*',
4526 swapThreshold: 1,
4527 // percentage; 0 <= x <= 1
4528 invertSwap: false,
4529 // invert always
4530 invertedSwapThreshold: null,
4531 // will be set to same as swapThreshold if default
4532 removeCloneOnHide: true,
4533 direction: function direction() {
4534 return _detectDirection(el, this.options);
4535 },
4536 ghostClass: 'sortable-ghost',
4537 chosenClass: 'sortable-chosen',
4538 dragClass: 'sortable-drag',
4539 ignore: 'a, img',
4540 filter: null,
4541 preventOnFilter: true,
4542 animation: 0,
4543 easing: null,
4544 setData: function setData(dataTransfer, dragEl) {
4545 dataTransfer.setData('Text', dragEl.textContent);
4546 },
4547 dropBubble: false,
4548 dragoverBubble: false,
4549 dataIdAttr: 'data-id',
4550 delay: 0,
4551 delayOnTouchOnly: false,
4552 touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1,
4553 forceFallback: false,
4554 fallbackClass: 'sortable-fallback',
4555 fallbackOnBody: false,
4556 fallbackTolerance: 0,
4557 fallbackOffset: {
4558 x: 0,
4559 y: 0
4560 },
4561 // Disabled on Safari: #1571; Enabled on Safari IOS: #2244
4562 supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS),
4563 emptyInsertThreshold: 5
4564 };
4565 PluginManager.initializePlugins(this, el, defaults);
4566
4567 // Set default options
4568 for (var name in defaults) {
4569 !(name in options) && (options[name] = defaults[name]);
4570 }
4571 _prepareGroup(options);
4572
4573 // Bind all private methods
4574 for (var fn in this) {
4575 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
4576 this[fn] = this[fn].bind(this);
4577 }
4578 }
4579
4580 // Setup drag mode
4581 this.nativeDraggable = options.forceFallback ? false : supportDraggable;
4582 if (this.nativeDraggable) {
4583 // Touch start threshold cannot be greater than the native dragstart threshold
4584 this.options.touchStartThreshold = 1;
4585 }
4586
4587 // Bind events
4588 if (options.supportPointer) {
4589 on(el, 'pointerdown', this._onTapStart);
4590 } else {
4591 on(el, 'mousedown', this._onTapStart);
4592 on(el, 'touchstart', this._onTapStart);
4593 }
4594 if (this.nativeDraggable) {
4595 on(el, 'dragover', this);
4596 on(el, 'dragenter', this);
4597 }
4598 sortables.push(this.el);
4599
4600 // Restore sorting
4601 options.store && options.store.get && this.sort(options.store.get(this) || []);
4602
4603 // Add animation state manager
4604 _extends(this, AnimationStateManager());
4605 }
4606 Sortable.prototype = /** @lends Sortable.prototype */{
4607 constructor: Sortable,
4608 _isOutsideThisEl: function _isOutsideThisEl(target) {
4609 if (!this.el.contains(target) && target !== this.el) {
4610 lastTarget = null;
4611 }
4612 },
4613 _getDirection: function _getDirection(evt, target) {
4614 return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction;
4615 },
4616 _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) {
4617 if (!evt.cancelable) return;
4618 var _this = this,
4619 el = this.el,
4620 options = this.options,
4621 preventOnFilter = options.preventOnFilter,
4622 type = evt.type,
4623 touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt,
4624 target = (touch || evt).target,
4625 originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target,
4626 filter = options.filter;
4627 _saveInputCheckedState(el);
4628
4629 // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
4630 if (dragEl) {
4631 return;
4632 }
4633 if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) {
4634 return; // only left button and enabled
4635 }
4636
4637 // cancel dnd if original target is content editable
4638 if (originalTarget.isContentEditable) {
4639 return;
4640 }
4641
4642 // Safari ignores further event handling after mousedown
4643 if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') {
4644 return;
4645 }
4646 target = closest(target, options.draggable, el, false);
4647 if (target && target.animated) {
4648 return;
4649 }
4650 if (lastDownEl === target) {
4651 // Ignoring duplicate `down`
4652 return;
4653 }
4654
4655 // Get the index of the dragged element within its parent
4656 oldIndex = index(target);
4657 oldDraggableIndex = index(target, options.draggable);
4658
4659 // Check filter
4660 if (typeof filter === 'function') {
4661 if (filter.call(this, evt, target, this)) {
4662 _dispatchEvent({
4663 sortable: _this,
4664 rootEl: originalTarget,
4665 name: 'filter',
4666 targetEl: target,
4667 toEl: el,
4668 fromEl: el
4669 });
4670 pluginEvent('filter', _this, {
4671 evt: evt
4672 });
4673 preventOnFilter && evt.preventDefault();
4674 return; // cancel dnd
4675 }
4676 } else if (filter) {
4677 filter = filter.split(',').some(function (criteria) {
4678 criteria = closest(originalTarget, criteria.trim(), el, false);
4679 if (criteria) {
4680 _dispatchEvent({
4681 sortable: _this,
4682 rootEl: criteria,
4683 name: 'filter',
4684 targetEl: target,
4685 fromEl: el,
4686 toEl: el
4687 });
4688 pluginEvent('filter', _this, {
4689 evt: evt
4690 });
4691 return true;
4692 }
4693 });
4694 if (filter) {
4695 preventOnFilter && evt.preventDefault();
4696 return; // cancel dnd
4697 }
4698 }
4699 if (options.handle && !closest(originalTarget, options.handle, el, false)) {
4700 return;
4701 }
4702
4703 // Prepare `dragstart`
4704 this._prepareDragStart(evt, touch, target);
4705 },
4706 _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) {
4707 var _this = this,
4708 el = _this.el,
4709 options = _this.options,
4710 ownerDocument = el.ownerDocument,
4711 dragStartFn;
4712 if (target && !dragEl && target.parentNode === el) {
4713 var dragRect = getRect(target);
4714 rootEl = el;
4715 dragEl = target;
4716 parentEl = dragEl.parentNode;
4717 nextEl = dragEl.nextSibling;
4718 lastDownEl = target;
4719 activeGroup = options.group;
4720 Sortable.dragged = dragEl;
4721 tapEvt = {
4722 target: dragEl,
4723 clientX: (touch || evt).clientX,
4724 clientY: (touch || evt).clientY
4725 };
4726 tapDistanceLeft = tapEvt.clientX - dragRect.left;
4727 tapDistanceTop = tapEvt.clientY - dragRect.top;
4728 this._lastX = (touch || evt).clientX;
4729 this._lastY = (touch || evt).clientY;
4730 dragEl.style['will-change'] = 'all';
4731 dragStartFn = function dragStartFn() {
4732 pluginEvent('delayEnded', _this, {
4733 evt: evt
4734 });
4735 if (Sortable.eventCanceled) {
4736 _this._onDrop();
4737 return;
4738 }
4739 // Delayed drag has been triggered
4740 // we can re-enable the events: touchmove/mousemove
4741 _this._disableDelayedDragEvents();
4742 if (!FireFox && _this.nativeDraggable) {
4743 dragEl.draggable = true;
4744 }
4745
4746 // Bind the events: dragstart/dragend
4747 _this._triggerDragStart(evt, touch);
4748
4749 // Drag start event
4750 _dispatchEvent({
4751 sortable: _this,
4752 name: 'choose',
4753 originalEvent: evt
4754 });
4755
4756 // Chosen item
4757 toggleClass(dragEl, options.chosenClass, true);
4758 };
4759
4760 // Disable "draggable"
4761 options.ignore.split(',').forEach(function (criteria) {
4762 find(dragEl, criteria.trim(), _disableDraggable);
4763 });
4764 on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent);
4765 on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent);
4766 on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent);
4767 if (options.supportPointer) {
4768 on(ownerDocument, 'pointerup', _this._onDrop);
4769 // Native D&D triggers pointercancel
4770 !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop);
4771 } else {
4772 on(ownerDocument, 'mouseup', _this._onDrop);
4773 on(ownerDocument, 'touchend', _this._onDrop);
4774 on(ownerDocument, 'touchcancel', _this._onDrop);
4775 }
4776
4777 // Make dragEl draggable (must be before delay for FireFox)
4778 if (FireFox && this.nativeDraggable) {
4779 this.options.touchStartThreshold = 4;
4780 dragEl.draggable = true;
4781 }
4782 pluginEvent('delayStart', this, {
4783 evt: evt
4784 });
4785
4786 // Delay is impossible for native DnD in Edge or IE
4787 if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) {
4788 if (Sortable.eventCanceled) {
4789 this._onDrop();
4790 return;
4791 }
4792 // If the user moves the pointer or let go the click or touch
4793 // before the delay has been reached:
4794 // disable the delayed drag
4795 if (options.supportPointer) {
4796 on(ownerDocument, 'pointerup', _this._disableDelayedDrag);
4797 on(ownerDocument, 'pointercancel', _this._disableDelayedDrag);
4798 } else {
4799 on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
4800 on(ownerDocument, 'touchend', _this._disableDelayedDrag);
4801 on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
4802 }
4803 on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler);
4804 on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler);
4805 options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler);
4806 _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
4807 } else {
4808 dragStartFn();
4809 }
4810 }
4811 },
4812 _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) {
4813 var touch = e.touches ? e.touches[0] : e;
4814 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))) {
4815 this._disableDelayedDrag();
4816 }
4817 },
4818 _disableDelayedDrag: function _disableDelayedDrag() {
4819 dragEl && _disableDraggable(dragEl);
4820 clearTimeout(this._dragStartTimer);
4821 this._disableDelayedDragEvents();
4822 },
4823 _disableDelayedDragEvents: function _disableDelayedDragEvents() {
4824 var ownerDocument = this.el.ownerDocument;
4825 off(ownerDocument, 'mouseup', this._disableDelayedDrag);
4826 off(ownerDocument, 'touchend', this._disableDelayedDrag);
4827 off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
4828 off(ownerDocument, 'pointerup', this._disableDelayedDrag);
4829 off(ownerDocument, 'pointercancel', this._disableDelayedDrag);
4830 off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler);
4831 off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler);
4832 off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler);
4833 },
4834 _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) {
4835 touch = touch || evt.pointerType == 'touch' && evt;
4836 if (!this.nativeDraggable || touch) {
4837 if (this.options.supportPointer) {
4838 on(document, 'pointermove', this._onTouchMove);
4839 } else if (touch) {
4840 on(document, 'touchmove', this._onTouchMove);
4841 } else {
4842 on(document, 'mousemove', this._onTouchMove);
4843 }
4844 } else {
4845 on(dragEl, 'dragend', this);
4846 on(rootEl, 'dragstart', this._onDragStart);
4847 }
4848 try {
4849 if (document.selection) {
4850 _nextTick(function () {
4851 document.selection.empty();
4852 });
4853 } else {
4854 window.getSelection().removeAllRanges();
4855 }
4856 } catch (err) {}
4857 },
4858 _dragStarted: function _dragStarted(fallback, evt) {
4859 awaitingDragStarted = false;
4860 if (rootEl && dragEl) {
4861 pluginEvent('dragStarted', this, {
4862 evt: evt
4863 });
4864 if (this.nativeDraggable) {
4865 on(document, 'dragover', _checkOutsideTargetEl);
4866 }
4867 var options = this.options;
4868
4869 // Apply effect
4870 !fallback && toggleClass(dragEl, options.dragClass, false);
4871 toggleClass(dragEl, options.ghostClass, true);
4872 Sortable.active = this;
4873 fallback && this._appendGhost();
4874
4875 // Drag start event
4876 _dispatchEvent({
4877 sortable: this,
4878 name: 'start',
4879 originalEvent: evt
4880 });
4881 } else {
4882 this._nulling();
4883 }
4884 },
4885 _emulateDragOver: function _emulateDragOver() {
4886 if (touchEvt) {
4887 this._lastX = touchEvt.clientX;
4888 this._lastY = touchEvt.clientY;
4889 _hideGhostForTarget();
4890 var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
4891 var parent = target;
4892 while (target && target.shadowRoot) {
4893 target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY);
4894 if (target === parent) break;
4895 parent = target;
4896 }
4897 dragEl.parentNode[expando]._isOutsideThisEl(target);
4898 if (parent) {
4899 do {
4900 if (parent[expando]) {
4901 var inserted = void 0;
4902 inserted = parent[expando]._onDragOver({
4903 clientX: touchEvt.clientX,
4904 clientY: touchEvt.clientY,
4905 target: target,
4906 rootEl: parent
4907 });
4908 if (inserted && !this.options.dragoverBubble) {
4909 break;
4910 }
4911 }
4912 target = parent; // store last element
4913 }
4914 /* jshint boss:true */ while (parent = getParentOrHost(parent));
4915 }
4916 _unhideGhostForTarget();
4917 }
4918 },
4919 _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) {
4920 if (tapEvt) {
4921 var options = this.options,
4922 fallbackTolerance = options.fallbackTolerance,
4923 fallbackOffset = options.fallbackOffset,
4924 touch = evt.touches ? evt.touches[0] : evt,
4925 ghostMatrix = ghostEl && matrix(ghostEl, true),
4926 scaleX = ghostEl && ghostMatrix && ghostMatrix.a,
4927 scaleY = ghostEl && ghostMatrix && ghostMatrix.d,
4928 relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent),
4929 dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1),
4930 dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1);
4931
4932 // only set the status to dragging, when we are actually dragging
4933 if (!Sortable.active && !awaitingDragStarted) {
4934 if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) {
4935 return;
4936 }
4937 this._onDragStart(evt, true);
4938 }
4939 if (ghostEl) {
4940 if (ghostMatrix) {
4941 ghostMatrix.e += dx - (lastDx || 0);
4942 ghostMatrix.f += dy - (lastDy || 0);
4943 } else {
4944 ghostMatrix = {
4945 a: 1,
4946 b: 0,
4947 c: 0,
4948 d: 1,
4949 e: dx,
4950 f: dy
4951 };
4952 }
4953 var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")");
4954 css(ghostEl, 'webkitTransform', cssMatrix);
4955 css(ghostEl, 'mozTransform', cssMatrix);
4956 css(ghostEl, 'msTransform', cssMatrix);
4957 css(ghostEl, 'transform', cssMatrix);
4958 lastDx = dx;
4959 lastDy = dy;
4960 touchEvt = touch;
4961 }
4962 evt.cancelable && evt.preventDefault();
4963 }
4964 },
4965 _appendGhost: function _appendGhost() {
4966 // Bug if using scale(): https://stackoverflow.com/questions/2637058
4967 // Not being adjusted for
4968 if (!ghostEl) {
4969 var container = this.options.fallbackOnBody ? document.body : rootEl,
4970 rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container),
4971 options = this.options;
4972
4973 // Position absolutely
4974 if (PositionGhostAbsolutely) {
4975 // Get relatively positioned parent
4976 ghostRelativeParent = container;
4977 while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) {
4978 ghostRelativeParent = ghostRelativeParent.parentNode;
4979 }
4980 if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) {
4981 if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement();
4982 rect.top += ghostRelativeParent.scrollTop;
4983 rect.left += ghostRelativeParent.scrollLeft;
4984 } else {
4985 ghostRelativeParent = getWindowScrollingElement();
4986 }
4987 ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent);
4988 }
4989 ghostEl = dragEl.cloneNode(true);
4990 toggleClass(ghostEl, options.ghostClass, false);
4991 toggleClass(ghostEl, options.fallbackClass, true);
4992 toggleClass(ghostEl, options.dragClass, true);
4993 css(ghostEl, 'transition', '');
4994 css(ghostEl, 'transform', '');
4995 css(ghostEl, 'box-sizing', 'border-box');
4996 css(ghostEl, 'margin', 0);
4997 css(ghostEl, 'top', rect.top);
4998 css(ghostEl, 'left', rect.left);
4999 css(ghostEl, 'width', rect.width);
5000 css(ghostEl, 'height', rect.height);
5001 css(ghostEl, 'opacity', '0.8');
5002 css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed');
5003 css(ghostEl, 'zIndex', '100000');
5004 css(ghostEl, 'pointerEvents', 'none');
5005 Sortable.ghost = ghostEl;
5006 container.appendChild(ghostEl);
5007
5008 // Set transform-origin
5009 css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%');
5010 }
5011 },
5012 _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) {
5013 var _this = this;
5014 var dataTransfer = evt.dataTransfer;
5015 var options = _this.options;
5016 pluginEvent('dragStart', this, {
5017 evt: evt
5018 });
5019 if (Sortable.eventCanceled) {
5020 this._onDrop();
5021 return;
5022 }
5023 pluginEvent('setupClone', this);
5024 if (!Sortable.eventCanceled) {
5025 cloneEl = clone(dragEl);
5026 cloneEl.removeAttribute("id");
5027 cloneEl.draggable = false;
5028 cloneEl.style['will-change'] = '';
5029 this._hideClone();
5030 toggleClass(cloneEl, this.options.chosenClass, false);
5031 Sortable.clone = cloneEl;
5032 }
5033
5034 // #1143: IFrame support workaround
5035 _this.cloneId = _nextTick(function () {
5036 pluginEvent('clone', _this);
5037 if (Sortable.eventCanceled) return;
5038 if (!_this.options.removeCloneOnHide) {
5039 rootEl.insertBefore(cloneEl, dragEl);
5040 }
5041 _this._hideClone();
5042 _dispatchEvent({
5043 sortable: _this,
5044 name: 'clone'
5045 });
5046 });
5047 !fallback && toggleClass(dragEl, options.dragClass, true);
5048
5049 // Set proper drop events
5050 if (fallback) {
5051 ignoreNextClick = true;
5052 _this._loopId = setInterval(_this._emulateDragOver, 50);
5053 } else {
5054 // Undo what was set in _prepareDragStart before drag started
5055 off(document, 'mouseup', _this._onDrop);
5056 off(document, 'touchend', _this._onDrop);
5057 off(document, 'touchcancel', _this._onDrop);
5058 if (dataTransfer) {
5059 dataTransfer.effectAllowed = 'move';
5060 options.setData && options.setData.call(_this, dataTransfer, dragEl);
5061 }
5062 on(document, 'drop', _this);
5063
5064 // #1276 fix:
5065 css(dragEl, 'transform', 'translateZ(0)');
5066 }
5067 awaitingDragStarted = true;
5068 _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt));
5069 on(document, 'selectstart', _this);
5070 moved = true;
5071 window.getSelection().removeAllRanges();
5072 if (Safari) {
5073 css(document.body, 'user-select', 'none');
5074 }
5075 },
5076 // Returns true - if no further action is needed (either inserted or another condition)
5077 _onDragOver: function _onDragOver( /**Event*/evt) {
5078 var el = this.el,
5079 target = evt.target,
5080 dragRect,
5081 targetRect,
5082 revert,
5083 options = this.options,
5084 group = options.group,
5085 activeSortable = Sortable.active,
5086 isOwner = activeGroup === group,
5087 canSort = options.sort,
5088 fromSortable = putSortable || activeSortable,
5089 vertical,
5090 _this = this,
5091 completedFired = false;
5092 if (_silent) return;
5093 function dragOverEvent(name, extra) {
5094 pluginEvent(name, _this, _objectSpread2({
5095 evt: evt,
5096 isOwner: isOwner,
5097 axis: vertical ? 'vertical' : 'horizontal',
5098 revert: revert,
5099 dragRect: dragRect,
5100 targetRect: targetRect,
5101 canSort: canSort,
5102 fromSortable: fromSortable,
5103 target: target,
5104 completed: completed,
5105 onMove: function onMove(target, after) {
5106 return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after);
5107 },
5108 changed: changed
5109 }, extra));
5110 }
5111
5112 // Capture animation state
5113 function capture() {
5114 dragOverEvent('dragOverAnimationCapture');
5115 _this.captureAnimationState();
5116 if (_this !== fromSortable) {
5117 fromSortable.captureAnimationState();
5118 }
5119 }
5120
5121 // Return invocation when dragEl is inserted (or completed)
5122 function completed(insertion) {
5123 dragOverEvent('dragOverCompleted', {
5124 insertion: insertion
5125 });
5126 if (insertion) {
5127 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
5128 if (isOwner) {
5129 activeSortable._hideClone();
5130 } else {
5131 activeSortable._showClone(_this);
5132 }
5133 if (_this !== fromSortable) {
5134 // Set ghost class to new sortable's ghost class
5135 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false);
5136 toggleClass(dragEl, options.ghostClass, true);
5137 }
5138 if (putSortable !== _this && _this !== Sortable.active) {
5139 putSortable = _this;
5140 } else if (_this === Sortable.active && putSortable) {
5141 putSortable = null;
5142 }
5143
5144 // Animation
5145 if (fromSortable === _this) {
5146 _this._ignoreWhileAnimating = target;
5147 }
5148 _this.animateAll(function () {
5149 dragOverEvent('dragOverAnimationComplete');
5150 _this._ignoreWhileAnimating = null;
5151 });
5152 if (_this !== fromSortable) {
5153 fromSortable.animateAll();
5154 fromSortable._ignoreWhileAnimating = null;
5155 }
5156 }
5157
5158 // Null lastTarget if it is not inside a previously swapped element
5159 if (target === dragEl && !dragEl.animated || target === el && !target.animated) {
5160 lastTarget = null;
5161 }
5162
5163 // no bubbling and not fallback
5164 if (!options.dragoverBubble && !evt.rootEl && target !== document) {
5165 dragEl.parentNode[expando]._isOutsideThisEl(evt.target);
5166
5167 // Do not detect for empty insert if already inserted
5168 !insertion && nearestEmptyInsertDetectEvent(evt);
5169 }
5170 !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation();
5171 return completedFired = true;
5172 }
5173
5174 // Call when dragEl has been inserted
5175 function changed() {
5176 newIndex = index(dragEl);
5177 newDraggableIndex = index(dragEl, options.draggable);
5178 _dispatchEvent({
5179 sortable: _this,
5180 name: 'change',
5181 toEl: el,
5182 newIndex: newIndex,
5183 newDraggableIndex: newDraggableIndex,
5184 originalEvent: evt
5185 });
5186 }
5187 if (evt.preventDefault !== void 0) {
5188 evt.cancelable && evt.preventDefault();
5189 }
5190 target = closest(target, options.draggable, el, true);
5191 dragOverEvent('dragOver');
5192 if (Sortable.eventCanceled) return completedFired;
5193 if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) {
5194 return completed(false);
5195 }
5196 ignoreNextClick = false;
5197 if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list
5198 : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) {
5199 vertical = this._getDirection(evt, target) === 'vertical';
5200 dragRect = getRect(dragEl);
5201 dragOverEvent('dragOverValid');
5202 if (Sortable.eventCanceled) return completedFired;
5203 if (revert) {
5204 parentEl = rootEl; // actualization
5205 capture();
5206 this._hideClone();
5207 dragOverEvent('revert');
5208 if (!Sortable.eventCanceled) {
5209 if (nextEl) {
5210 rootEl.insertBefore(dragEl, nextEl);
5211 } else {
5212 rootEl.appendChild(dragEl);
5213 }
5214 }
5215 return completed(true);
5216 }
5217 var elLastChild = lastChild(el, options.draggable);
5218 if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) {
5219 // Insert to end of list
5220
5221 // If already at end of list: Do not insert
5222 if (elLastChild === dragEl) {
5223 return completed(false);
5224 }
5225
5226 // if there is a last element, it is the target
5227 if (elLastChild && el === evt.target) {
5228 target = elLastChild;
5229 }
5230 if (target) {
5231 targetRect = getRect(target);
5232 }
5233 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) {
5234 capture();
5235 if (elLastChild && elLastChild.nextSibling) {
5236 // the last draggable element is not the last node
5237 el.insertBefore(dragEl, elLastChild.nextSibling);
5238 } else {
5239 el.appendChild(dragEl);
5240 }
5241 parentEl = el; // actualization
5242
5243 changed();
5244 return completed(true);
5245 }
5246 } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) {
5247 // Insert to start of list
5248 var firstChild = getChild(el, 0, options, true);
5249 if (firstChild === dragEl) {
5250 return completed(false);
5251 }
5252 target = firstChild;
5253 targetRect = getRect(target);
5254 if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) {
5255 capture();
5256 el.insertBefore(dragEl, firstChild);
5257 parentEl = el; // actualization
5258
5259 changed();
5260 return completed(true);
5261 }
5262 } else if (target.parentNode === el) {
5263 targetRect = getRect(target);
5264 var direction = 0,
5265 targetBeforeFirstSwap,
5266 differentLevel = dragEl.parentNode !== el,
5267 differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical),
5268 side1 = vertical ? 'top' : 'left',
5269 scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'),
5270 scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0;
5271 if (lastTarget !== target) {
5272 targetBeforeFirstSwap = targetRect[side1];
5273 pastFirstInvertThresh = false;
5274 isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel;
5275 }
5276 direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target);
5277 var sibling;
5278 if (direction !== 0) {
5279 // Check if target is beside dragEl in respective direction (ignoring hidden elements)
5280 var dragIndex = index(dragEl);
5281 do {
5282 dragIndex -= direction;
5283 sibling = parentEl.children[dragIndex];
5284 } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl));
5285 }
5286 // If dragEl is already beside target: Do not insert
5287 if (direction === 0 || sibling === target) {
5288 return completed(false);
5289 }
5290 lastTarget = target;
5291 lastDirection = direction;
5292 var nextSibling = target.nextElementSibling,
5293 after = false;
5294 after = direction === 1;
5295 var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after);
5296 if (moveVector !== false) {
5297 if (moveVector === 1 || moveVector === -1) {
5298 after = moveVector === 1;
5299 }
5300 _silent = true;
5301 setTimeout(_unsilent, 30);
5302 capture();
5303 if (after && !nextSibling) {
5304 el.appendChild(dragEl);
5305 } else {
5306 target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
5307 }
5308
5309 // Undo chrome's scroll adjustment (has no effect on other browsers)
5310 if (scrolledPastTop) {
5311 scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop);
5312 }
5313 parentEl = dragEl.parentNode; // actualization
5314
5315 // must be done before animation
5316 if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) {
5317 targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]);
5318 }
5319 changed();
5320 return completed(true);
5321 }
5322 }
5323 if (el.contains(dragEl)) {
5324 return completed(false);
5325 }
5326 }
5327 return false;
5328 },
5329 _ignoreWhileAnimating: null,
5330 _offMoveEvents: function _offMoveEvents() {
5331 off(document, 'mousemove', this._onTouchMove);
5332 off(document, 'touchmove', this._onTouchMove);
5333 off(document, 'pointermove', this._onTouchMove);
5334 off(document, 'dragover', nearestEmptyInsertDetectEvent);
5335 off(document, 'mousemove', nearestEmptyInsertDetectEvent);
5336 off(document, 'touchmove', nearestEmptyInsertDetectEvent);
5337 },
5338 _offUpEvents: function _offUpEvents() {
5339 var ownerDocument = this.el.ownerDocument;
5340 off(ownerDocument, 'mouseup', this._onDrop);
5341 off(ownerDocument, 'touchend', this._onDrop);
5342 off(ownerDocument, 'pointerup', this._onDrop);
5343 off(ownerDocument, 'pointercancel', this._onDrop);
5344 off(ownerDocument, 'touchcancel', this._onDrop);
5345 off(document, 'selectstart', this);
5346 },
5347 _onDrop: function _onDrop( /**Event*/evt) {
5348 var el = this.el,
5349 options = this.options;
5350
5351 // Get the index of the dragged element within its parent
5352 newIndex = index(dragEl);
5353 newDraggableIndex = index(dragEl, options.draggable);
5354 pluginEvent('drop', this, {
5355 evt: evt
5356 });
5357 parentEl = dragEl && dragEl.parentNode;
5358
5359 // Get again after plugin event
5360 newIndex = index(dragEl);
5361 newDraggableIndex = index(dragEl, options.draggable);
5362 if (Sortable.eventCanceled) {
5363 this._nulling();
5364 return;
5365 }
5366 awaitingDragStarted = false;
5367 isCircumstantialInvert = false;
5368 pastFirstInvertThresh = false;
5369 clearInterval(this._loopId);
5370 clearTimeout(this._dragStartTimer);
5371 _cancelNextTick(this.cloneId);
5372 _cancelNextTick(this._dragStartId);
5373
5374 // Unbind events
5375 if (this.nativeDraggable) {
5376 off(document, 'drop', this);
5377 off(el, 'dragstart', this._onDragStart);
5378 }
5379 this._offMoveEvents();
5380 this._offUpEvents();
5381 if (Safari) {
5382 css(document.body, 'user-select', '');
5383 }
5384 css(dragEl, 'transform', '');
5385 if (evt) {
5386 if (moved) {
5387 evt.cancelable && evt.preventDefault();
5388 !options.dropBubble && evt.stopPropagation();
5389 }
5390 ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl);
5391 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
5392 // Remove clone(s)
5393 cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl);
5394 }
5395 if (dragEl) {
5396 if (this.nativeDraggable) {
5397 off(dragEl, 'dragend', this);
5398 }
5399 _disableDraggable(dragEl);
5400 dragEl.style['will-change'] = '';
5401
5402 // Remove classes
5403 // ghostClass is added in dragStarted
5404 if (moved && !awaitingDragStarted) {
5405 toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false);
5406 }
5407 toggleClass(dragEl, this.options.chosenClass, false);
5408
5409 // Drag stop event
5410 _dispatchEvent({
5411 sortable: this,
5412 name: 'unchoose',
5413 toEl: parentEl,
5414 newIndex: null,
5415 newDraggableIndex: null,
5416 originalEvent: evt
5417 });
5418 if (rootEl !== parentEl) {
5419 if (newIndex >= 0) {
5420 // Add event
5421 _dispatchEvent({
5422 rootEl: parentEl,
5423 name: 'add',
5424 toEl: parentEl,
5425 fromEl: rootEl,
5426 originalEvent: evt
5427 });
5428
5429 // Remove event
5430 _dispatchEvent({
5431 sortable: this,
5432 name: 'remove',
5433 toEl: parentEl,
5434 originalEvent: evt
5435 });
5436
5437 // drag from one list and drop into another
5438 _dispatchEvent({
5439 rootEl: parentEl,
5440 name: 'sort',
5441 toEl: parentEl,
5442 fromEl: rootEl,
5443 originalEvent: evt
5444 });
5445 _dispatchEvent({
5446 sortable: this,
5447 name: 'sort',
5448 toEl: parentEl,
5449 originalEvent: evt
5450 });
5451 }
5452 putSortable && putSortable.save();
5453 } else {
5454 if (newIndex !== oldIndex) {
5455 if (newIndex >= 0) {
5456 // drag & drop within the same list
5457 _dispatchEvent({
5458 sortable: this,
5459 name: 'update',
5460 toEl: parentEl,
5461 originalEvent: evt
5462 });
5463 _dispatchEvent({
5464 sortable: this,
5465 name: 'sort',
5466 toEl: parentEl,
5467 originalEvent: evt
5468 });
5469 }
5470 }
5471 }
5472 if (Sortable.active) {
5473 /* jshint eqnull:true */
5474 if (newIndex == null || newIndex === -1) {
5475 newIndex = oldIndex;
5476 newDraggableIndex = oldDraggableIndex;
5477 }
5478 _dispatchEvent({
5479 sortable: this,
5480 name: 'end',
5481 toEl: parentEl,
5482 originalEvent: evt
5483 });
5484
5485 // Save sorting
5486 this.save();
5487 }
5488 }
5489 }
5490 this._nulling();
5491 },
5492 _nulling: function _nulling() {
5493 pluginEvent('nulling', this);
5494 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;
5495 var el = this.el;
5496 savedInputChecked.forEach(function (checkEl) {
5497 if (el.contains(checkEl)) {
5498 checkEl.checked = true;
5499 }
5500 });
5501 savedInputChecked.length = lastDx = lastDy = 0;
5502 },
5503 handleEvent: function handleEvent( /**Event*/evt) {
5504 switch (evt.type) {
5505 case 'drop':
5506 case 'dragend':
5507 this._onDrop(evt);
5508 break;
5509 case 'dragenter':
5510 case 'dragover':
5511 if (dragEl) {
5512 this._onDragOver(evt);
5513 _globalDragOver(evt);
5514 }
5515 break;
5516 case 'selectstart':
5517 evt.preventDefault();
5518 break;
5519 }
5520 },
5521 /**
5522 * Serializes the item into an array of string.
5523 * @returns {String[]}
5524 */
5525 toArray: function toArray() {
5526 var order = [],
5527 el,
5528 children = this.el.children,
5529 i = 0,
5530 n = children.length,
5531 options = this.options;
5532 for (; i < n; i++) {
5533 el = children[i];
5534 if (closest(el, options.draggable, this.el, false)) {
5535 order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
5536 }
5537 }
5538 return order;
5539 },
5540 /**
5541 * Sorts the elements according to the array.
5542 * @param {String[]} order order of the items
5543 */
5544 sort: function sort(order, useAnimation) {
5545 var items = {},
5546 rootEl = this.el;
5547 this.toArray().forEach(function (id, i) {
5548 var el = rootEl.children[i];
5549 if (closest(el, this.options.draggable, rootEl, false)) {
5550 items[id] = el;
5551 }
5552 }, this);
5553 useAnimation && this.captureAnimationState();
5554 order.forEach(function (id) {
5555 if (items[id]) {
5556 rootEl.removeChild(items[id]);
5557 rootEl.appendChild(items[id]);
5558 }
5559 });
5560 useAnimation && this.animateAll();
5561 },
5562 /**
5563 * Save the current sorting
5564 */
5565 save: function save() {
5566 var store = this.options.store;
5567 store && store.set && store.set(this);
5568 },
5569 /**
5570 * 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.
5571 * @param {HTMLElement} el
5572 * @param {String} [selector] default: `options.draggable`
5573 * @returns {HTMLElement|null}
5574 */
5575 closest: function closest$1(el, selector) {
5576 return closest(el, selector || this.options.draggable, this.el, false);
5577 },
5578 /**
5579 * Set/get option
5580 * @param {string} name
5581 * @param {*} [value]
5582 * @returns {*}
5583 */
5584 option: function option(name, value) {
5585 var options = this.options;
5586 if (value === void 0) {
5587 return options[name];
5588 } else {
5589 var modifiedValue = PluginManager.modifyOption(this, name, value);
5590 if (typeof modifiedValue !== 'undefined') {
5591 options[name] = modifiedValue;
5592 } else {
5593 options[name] = value;
5594 }
5595 if (name === 'group') {
5596 _prepareGroup(options);
5597 }
5598 }
5599 },
5600 /**
5601 * Destroy
5602 */
5603 destroy: function destroy() {
5604 pluginEvent('destroy', this);
5605 var el = this.el;
5606 el[expando] = null;
5607 off(el, 'mousedown', this._onTapStart);
5608 off(el, 'touchstart', this._onTapStart);
5609 off(el, 'pointerdown', this._onTapStart);
5610 if (this.nativeDraggable) {
5611 off(el, 'dragover', this);
5612 off(el, 'dragenter', this);
5613 }
5614 // Remove draggable attributes
5615 Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
5616 el.removeAttribute('draggable');
5617 });
5618 this._onDrop();
5619 this._disableDelayedDragEvents();
5620 sortables.splice(sortables.indexOf(this.el), 1);
5621 this.el = el = null;
5622 },
5623 _hideClone: function _hideClone() {
5624 if (!cloneHidden) {
5625 pluginEvent('hideClone', this);
5626 if (Sortable.eventCanceled) return;
5627 css(cloneEl, 'display', 'none');
5628 if (this.options.removeCloneOnHide && cloneEl.parentNode) {
5629 cloneEl.parentNode.removeChild(cloneEl);
5630 }
5631 cloneHidden = true;
5632 }
5633 },
5634 _showClone: function _showClone(putSortable) {
5635 if (putSortable.lastPutMode !== 'clone') {
5636 this._hideClone();
5637 return;
5638 }
5639 if (cloneHidden) {
5640 pluginEvent('showClone', this);
5641 if (Sortable.eventCanceled) return;
5642
5643 // show clone at dragEl or original position
5644 if (dragEl.parentNode == rootEl && !this.options.group.revertClone) {
5645 rootEl.insertBefore(cloneEl, dragEl);
5646 } else if (nextEl) {
5647 rootEl.insertBefore(cloneEl, nextEl);
5648 } else {
5649 rootEl.appendChild(cloneEl);
5650 }
5651 if (this.options.group.revertClone) {
5652 this.animate(dragEl, cloneEl);
5653 }
5654 css(cloneEl, 'display', '');
5655 cloneHidden = false;
5656 }
5657 }
5658 };
5659 function _globalDragOver( /**Event*/evt) {
5660 if (evt.dataTransfer) {
5661 evt.dataTransfer.dropEffect = 'move';
5662 }
5663 evt.cancelable && evt.preventDefault();
5664 }
5665 function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) {
5666 var evt,
5667 sortable = fromEl[expando],
5668 onMoveFn = sortable.options.onMove,
5669 retVal;
5670 // Support for new CustomEvent feature
5671 if (window.CustomEvent && !IE11OrLess && !Edge) {
5672 evt = new CustomEvent('move', {
5673 bubbles: true,
5674 cancelable: true
5675 });
5676 } else {
5677 evt = document.createEvent('Event');
5678 evt.initEvent('move', true, true);
5679 }
5680 evt.to = toEl;
5681 evt.from = fromEl;
5682 evt.dragged = dragEl;
5683 evt.draggedRect = dragRect;
5684 evt.related = targetEl || toEl;
5685 evt.relatedRect = targetRect || getRect(toEl);
5686 evt.willInsertAfter = willInsertAfter;
5687 evt.originalEvent = originalEvent;
5688 fromEl.dispatchEvent(evt);
5689 if (onMoveFn) {
5690 retVal = onMoveFn.call(sortable, evt, originalEvent);
5691 }
5692 return retVal;
5693 }
5694 function _disableDraggable(el) {
5695 el.draggable = false;
5696 }
5697 function _unsilent() {
5698 _silent = false;
5699 }
5700 function _ghostIsFirst(evt, vertical, sortable) {
5701 var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true));
5702 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
5703 var spacer = 10;
5704 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;
5705 }
5706 function _ghostIsLast(evt, vertical, sortable) {
5707 var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable));
5708 var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl);
5709 var spacer = 10;
5710 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;
5711 }
5712 function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) {
5713 var mouseOnAxis = vertical ? evt.clientY : evt.clientX,
5714 targetLength = vertical ? targetRect.height : targetRect.width,
5715 targetS1 = vertical ? targetRect.top : targetRect.left,
5716 targetS2 = vertical ? targetRect.bottom : targetRect.right,
5717 invert = false;
5718 if (!invertSwap) {
5719 // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold
5720 if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) {
5721 // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2
5722 // check if past first invert threshold on side opposite of lastDirection
5723 if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) {
5724 // past first invert threshold, do not restrict inverted threshold to dragEl shadow
5725 pastFirstInvertThresh = true;
5726 }
5727 if (!pastFirstInvertThresh) {
5728 // dragEl shadow (target move distance shadow)
5729 if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow
5730 : mouseOnAxis > targetS2 - targetMoveDistance) {
5731 return -lastDirection;
5732 }
5733 } else {
5734 invert = true;
5735 }
5736 } else {
5737 // Regular
5738 if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) {
5739 return _getInsertDirection(target);
5740 }
5741 }
5742 }
5743 invert = invert || invertSwap;
5744 if (invert) {
5745 // Invert of regular
5746 if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) {
5747 return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1;
5748 }
5749 }
5750 return 0;
5751 }
5752
5753 /**
5754 * Gets the direction dragEl must be swapped relative to target in order to make it
5755 * seem that dragEl has been "inserted" into that element's position
5756 * @param {HTMLElement} target The target whose position dragEl is being inserted at
5757 * @return {Number} Direction dragEl must be swapped
5758 */
5759 function _getInsertDirection(target) {
5760 if (index(dragEl) < index(target)) {
5761 return 1;
5762 } else {
5763 return -1;
5764 }
5765 }
5766
5767 /**
5768 * Generate id
5769 * @param {HTMLElement} el
5770 * @returns {String}
5771 * @private
5772 */
5773 function _generateId(el) {
5774 var str = el.tagName + el.className + el.src + el.href + el.textContent,
5775 i = str.length,
5776 sum = 0;
5777 while (i--) {
5778 sum += str.charCodeAt(i);
5779 }
5780 return sum.toString(36);
5781 }
5782 function _saveInputCheckedState(root) {
5783 savedInputChecked.length = 0;
5784 var inputs = root.getElementsByTagName('input');
5785 var idx = inputs.length;
5786 while (idx--) {
5787 var el = inputs[idx];
5788 el.checked && savedInputChecked.push(el);
5789 }
5790 }
5791 function _nextTick(fn) {
5792 return setTimeout(fn, 0);
5793 }
5794 function _cancelNextTick(id) {
5795 return clearTimeout(id);
5796 }
5797
5798 // Fixed #973:
5799 if (documentExists) {
5800 on(document, 'touchmove', function (evt) {
5801 if ((Sortable.active || awaitingDragStarted) && evt.cancelable) {
5802 evt.preventDefault();
5803 }
5804 });
5805 }
5806
5807 // Export utils
5808 Sortable.utils = {
5809 on: on,
5810 off: off,
5811 css: css,
5812 find: find,
5813 is: function is(el, selector) {
5814 return !!closest(el, selector, el, false);
5815 },
5816 extend: extend,
5817 throttle: throttle,
5818 closest: closest,
5819 toggleClass: toggleClass,
5820 clone: clone,
5821 index: index,
5822 nextTick: _nextTick,
5823 cancelNextTick: _cancelNextTick,
5824 detectDirection: _detectDirection,
5825 getChild: getChild,
5826 expando: expando
5827 };
5828
5829 /**
5830 * Get the Sortable instance of an element
5831 * @param {HTMLElement} element The element
5832 * @return {Sortable|undefined} The instance of Sortable
5833 */
5834 Sortable.get = function (element) {
5835 return element[expando];
5836 };
5837
5838 /**
5839 * Mount a plugin to Sortable
5840 * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
5841 */
5842 Sortable.mount = function () {
5843 for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) {
5844 plugins[_key] = arguments[_key];
5845 }
5846 if (plugins[0].constructor === Array) plugins = plugins[0];
5847 plugins.forEach(function (plugin) {
5848 if (!plugin.prototype || !plugin.prototype.constructor) {
5849 throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin));
5850 }
5851 if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils);
5852 PluginManager.mount(plugin);
5853 });
5854 };
5855
5856 /**
5857 * Create sortable instance
5858 * @param {HTMLElement} el
5859 * @param {Object} [options]
5860 */
5861 Sortable.create = function (el, options) {
5862 return new Sortable(el, options);
5863 };
5864
5865 // Export
5866 Sortable.version = version;
5867
5868 var autoScrolls = [],
5869 scrollEl,
5870 scrollRootEl,
5871 scrolling = false,
5872 lastAutoScrollX,
5873 lastAutoScrollY,
5874 touchEvt$1,
5875 pointerElemChangedInterval;
5876 function AutoScrollPlugin() {
5877 function AutoScroll() {
5878 this.defaults = {
5879 scroll: true,
5880 forceAutoScrollFallback: false,
5881 scrollSensitivity: 30,
5882 scrollSpeed: 10,
5883 bubbleScroll: true
5884 };
5885
5886 // Bind all private methods
5887 for (var fn in this) {
5888 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
5889 this[fn] = this[fn].bind(this);
5890 }
5891 }
5892 }
5893 AutoScroll.prototype = {
5894 dragStarted: function dragStarted(_ref) {
5895 var originalEvent = _ref.originalEvent;
5896 if (this.sortable.nativeDraggable) {
5897 on(document, 'dragover', this._handleAutoScroll);
5898 } else {
5899 if (this.options.supportPointer) {
5900 on(document, 'pointermove', this._handleFallbackAutoScroll);
5901 } else if (originalEvent.touches) {
5902 on(document, 'touchmove', this._handleFallbackAutoScroll);
5903 } else {
5904 on(document, 'mousemove', this._handleFallbackAutoScroll);
5905 }
5906 }
5907 },
5908 dragOverCompleted: function dragOverCompleted(_ref2) {
5909 var originalEvent = _ref2.originalEvent;
5910 // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached)
5911 if (!this.options.dragOverBubble && !originalEvent.rootEl) {
5912 this._handleAutoScroll(originalEvent);
5913 }
5914 },
5915 drop: function drop() {
5916 if (this.sortable.nativeDraggable) {
5917 off(document, 'dragover', this._handleAutoScroll);
5918 } else {
5919 off(document, 'pointermove', this._handleFallbackAutoScroll);
5920 off(document, 'touchmove', this._handleFallbackAutoScroll);
5921 off(document, 'mousemove', this._handleFallbackAutoScroll);
5922 }
5923 clearPointerElemChangedInterval();
5924 clearAutoScrolls();
5925 cancelThrottle();
5926 },
5927 nulling: function nulling() {
5928 touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null;
5929 autoScrolls.length = 0;
5930 },
5931 _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) {
5932 this._handleAutoScroll(evt, true);
5933 },
5934 _handleAutoScroll: function _handleAutoScroll(evt, fallback) {
5935 var _this = this;
5936 var x = (evt.touches ? evt.touches[0] : evt).clientX,
5937 y = (evt.touches ? evt.touches[0] : evt).clientY,
5938 elem = document.elementFromPoint(x, y);
5939 touchEvt$1 = evt;
5940
5941 // IE does not seem to have native autoscroll,
5942 // Edge's autoscroll seems too conditional,
5943 // MACOS Safari does not have autoscroll,
5944 // Firefox and Chrome are good
5945 if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) {
5946 autoScroll(evt, this.options, elem, fallback);
5947
5948 // Listener for pointer element change
5949 var ogElemScroller = getParentAutoScrollElement(elem, true);
5950 if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) {
5951 pointerElemChangedInterval && clearPointerElemChangedInterval();
5952 // Detect for pointer elem change, emulating native DnD behaviour
5953 pointerElemChangedInterval = setInterval(function () {
5954 var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true);
5955 if (newElem !== ogElemScroller) {
5956 ogElemScroller = newElem;
5957 clearAutoScrolls();
5958 }
5959 autoScroll(evt, _this.options, newElem, fallback);
5960 }, 10);
5961 lastAutoScrollX = x;
5962 lastAutoScrollY = y;
5963 }
5964 } else {
5965 // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll
5966 if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) {
5967 clearAutoScrolls();
5968 return;
5969 }
5970 autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false);
5971 }
5972 }
5973 };
5974 return _extends(AutoScroll, {
5975 pluginName: 'scroll',
5976 initializeByDefault: true
5977 });
5978 }
5979 function clearAutoScrolls() {
5980 autoScrolls.forEach(function (autoScroll) {
5981 clearInterval(autoScroll.pid);
5982 });
5983 autoScrolls = [];
5984 }
5985 function clearPointerElemChangedInterval() {
5986 clearInterval(pointerElemChangedInterval);
5987 }
5988 var autoScroll = throttle(function (evt, options, rootEl, isFallback) {
5989 // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
5990 if (!options.scroll) return;
5991 var x = (evt.touches ? evt.touches[0] : evt).clientX,
5992 y = (evt.touches ? evt.touches[0] : evt).clientY,
5993 sens = options.scrollSensitivity,
5994 speed = options.scrollSpeed,
5995 winScroller = getWindowScrollingElement();
5996 var scrollThisInstance = false,
5997 scrollCustomFn;
5998
5999 // New scroll root, set scrollEl
6000 if (scrollRootEl !== rootEl) {
6001 scrollRootEl = rootEl;
6002 clearAutoScrolls();
6003 scrollEl = options.scroll;
6004 scrollCustomFn = options.scrollFn;
6005 if (scrollEl === true) {
6006 scrollEl = getParentAutoScrollElement(rootEl, true);
6007 }
6008 }
6009 var layersOut = 0;
6010 var currentParent = scrollEl;
6011 do {
6012 var el = currentParent,
6013 rect = getRect(el),
6014 top = rect.top,
6015 bottom = rect.bottom,
6016 left = rect.left,
6017 right = rect.right,
6018 width = rect.width,
6019 height = rect.height,
6020 canScrollX = void 0,
6021 canScrollY = void 0,
6022 scrollWidth = el.scrollWidth,
6023 scrollHeight = el.scrollHeight,
6024 elCSS = css(el),
6025 scrollPosX = el.scrollLeft,
6026 scrollPosY = el.scrollTop;
6027 if (el === winScroller) {
6028 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible');
6029 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible');
6030 } else {
6031 canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll');
6032 canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
6033 }
6034 var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
6035 var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
6036 if (!autoScrolls[layersOut]) {
6037 for (var i = 0; i <= layersOut; i++) {
6038 if (!autoScrolls[i]) {
6039 autoScrolls[i] = {};
6040 }
6041 }
6042 }
6043 if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) {
6044 autoScrolls[layersOut].el = el;
6045 autoScrolls[layersOut].vx = vx;
6046 autoScrolls[layersOut].vy = vy;
6047 clearInterval(autoScrolls[layersOut].pid);
6048 if (vx != 0 || vy != 0) {
6049 scrollThisInstance = true;
6050 /* jshint loopfunc:true */
6051 autoScrolls[layersOut].pid = setInterval(function () {
6052 // emulate drag over during autoscroll (fallback), emulating native DnD behaviour
6053 if (isFallback && this.layer === 0) {
6054 Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely
6055 }
6056 var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0;
6057 var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0;
6058 if (typeof scrollCustomFn === 'function') {
6059 if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') {
6060 return;
6061 }
6062 }
6063 scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY);
6064 }.bind({
6065 layer: layersOut
6066 }), 24);
6067 }
6068 }
6069 layersOut++;
6070 } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false)));
6071 scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not
6072 }, 30);
6073
6074 var drop = function drop(_ref) {
6075 var originalEvent = _ref.originalEvent,
6076 putSortable = _ref.putSortable,
6077 dragEl = _ref.dragEl,
6078 activeSortable = _ref.activeSortable,
6079 dispatchSortableEvent = _ref.dispatchSortableEvent,
6080 hideGhostForTarget = _ref.hideGhostForTarget,
6081 unhideGhostForTarget = _ref.unhideGhostForTarget;
6082 if (!originalEvent) return;
6083 var toSortable = putSortable || activeSortable;
6084 hideGhostForTarget();
6085 var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent;
6086 var target = document.elementFromPoint(touch.clientX, touch.clientY);
6087 unhideGhostForTarget();
6088 if (toSortable && !toSortable.el.contains(target)) {
6089 dispatchSortableEvent('spill');
6090 this.onSpill({
6091 dragEl: dragEl,
6092 putSortable: putSortable
6093 });
6094 }
6095 };
6096 function Revert() {}
6097 Revert.prototype = {
6098 startIndex: null,
6099 dragStart: function dragStart(_ref2) {
6100 var oldDraggableIndex = _ref2.oldDraggableIndex;
6101 this.startIndex = oldDraggableIndex;
6102 },
6103 onSpill: function onSpill(_ref3) {
6104 var dragEl = _ref3.dragEl,
6105 putSortable = _ref3.putSortable;
6106 this.sortable.captureAnimationState();
6107 if (putSortable) {
6108 putSortable.captureAnimationState();
6109 }
6110 var nextSibling = getChild(this.sortable.el, this.startIndex, this.options);
6111 if (nextSibling) {
6112 this.sortable.el.insertBefore(dragEl, nextSibling);
6113 } else {
6114 this.sortable.el.appendChild(dragEl);
6115 }
6116 this.sortable.animateAll();
6117 if (putSortable) {
6118 putSortable.animateAll();
6119 }
6120 },
6121 drop: drop
6122 };
6123 _extends(Revert, {
6124 pluginName: 'revertOnSpill'
6125 });
6126 function Remove() {}
6127 Remove.prototype = {
6128 onSpill: function onSpill(_ref4) {
6129 var dragEl = _ref4.dragEl,
6130 putSortable = _ref4.putSortable;
6131 var parentSortable = putSortable || this.sortable;
6132 parentSortable.captureAnimationState();
6133 dragEl.parentNode && dragEl.parentNode.removeChild(dragEl);
6134 parentSortable.animateAll();
6135 },
6136 drop: drop
6137 };
6138 _extends(Remove, {
6139 pluginName: 'removeOnSpill'
6140 });
6141
6142 var lastSwapEl;
6143 function SwapPlugin() {
6144 function Swap() {
6145 this.defaults = {
6146 swapClass: 'sortable-swap-highlight'
6147 };
6148 }
6149 Swap.prototype = {
6150 dragStart: function dragStart(_ref) {
6151 var dragEl = _ref.dragEl;
6152 lastSwapEl = dragEl;
6153 },
6154 dragOverValid: function dragOverValid(_ref2) {
6155 var completed = _ref2.completed,
6156 target = _ref2.target,
6157 onMove = _ref2.onMove,
6158 activeSortable = _ref2.activeSortable,
6159 changed = _ref2.changed,
6160 cancel = _ref2.cancel;
6161 if (!activeSortable.options.swap) return;
6162 var el = this.sortable.el,
6163 options = this.options;
6164 if (target && target !== el) {
6165 var prevSwapEl = lastSwapEl;
6166 if (onMove(target) !== false) {
6167 toggleClass(target, options.swapClass, true);
6168 lastSwapEl = target;
6169 } else {
6170 lastSwapEl = null;
6171 }
6172 if (prevSwapEl && prevSwapEl !== lastSwapEl) {
6173 toggleClass(prevSwapEl, options.swapClass, false);
6174 }
6175 }
6176 changed();
6177 completed(true);
6178 cancel();
6179 },
6180 drop: function drop(_ref3) {
6181 var activeSortable = _ref3.activeSortable,
6182 putSortable = _ref3.putSortable,
6183 dragEl = _ref3.dragEl;
6184 var toSortable = putSortable || this.sortable;
6185 var options = this.options;
6186 lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false);
6187 if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) {
6188 if (dragEl !== lastSwapEl) {
6189 toSortable.captureAnimationState();
6190 if (toSortable !== activeSortable) activeSortable.captureAnimationState();
6191 swapNodes(dragEl, lastSwapEl);
6192 toSortable.animateAll();
6193 if (toSortable !== activeSortable) activeSortable.animateAll();
6194 }
6195 }
6196 },
6197 nulling: function nulling() {
6198 lastSwapEl = null;
6199 }
6200 };
6201 return _extends(Swap, {
6202 pluginName: 'swap',
6203 eventProperties: function eventProperties() {
6204 return {
6205 swapItem: lastSwapEl
6206 };
6207 }
6208 });
6209 }
6210 function swapNodes(n1, n2) {
6211 var p1 = n1.parentNode,
6212 p2 = n2.parentNode,
6213 i1,
6214 i2;
6215 if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;
6216 i1 = index(n1);
6217 i2 = index(n2);
6218 if (p1.isEqualNode(p2) && i1 < i2) {
6219 i2++;
6220 }
6221 p1.insertBefore(n2, p1.children[i1]);
6222 p2.insertBefore(n1, p2.children[i2]);
6223 }
6224
6225 var multiDragElements = [],
6226 multiDragClones = [],
6227 lastMultiDragSelect,
6228 // for selection with modifier key down (SHIFT)
6229 multiDragSortable,
6230 initialFolding = false,
6231 // Initial multi-drag fold when drag started
6232 folding = false,
6233 // Folding any other time
6234 dragStarted = false,
6235 dragEl$1,
6236 clonesFromRect,
6237 clonesHidden;
6238 function MultiDragPlugin() {
6239 function MultiDrag(sortable) {
6240 // Bind all private methods
6241 for (var fn in this) {
6242 if (fn.charAt(0) === '_' && typeof this[fn] === 'function') {
6243 this[fn] = this[fn].bind(this);
6244 }
6245 }
6246 if (!sortable.options.avoidImplicitDeselect) {
6247 if (sortable.options.supportPointer) {
6248 on(document, 'pointerup', this._deselectMultiDrag);
6249 } else {
6250 on(document, 'mouseup', this._deselectMultiDrag);
6251 on(document, 'touchend', this._deselectMultiDrag);
6252 }
6253 }
6254 on(document, 'keydown', this._checkKeyDown);
6255 on(document, 'keyup', this._checkKeyUp);
6256 this.defaults = {
6257 selectedClass: 'sortable-selected',
6258 multiDragKey: null,
6259 avoidImplicitDeselect: false,
6260 setData: function setData(dataTransfer, dragEl) {
6261 var data = '';
6262 if (multiDragElements.length && multiDragSortable === sortable) {
6263 multiDragElements.forEach(function (multiDragElement, i) {
6264 data += (!i ? '' : ', ') + multiDragElement.textContent;
6265 });
6266 } else {
6267 data = dragEl.textContent;
6268 }
6269 dataTransfer.setData('Text', data);
6270 }
6271 };
6272 }
6273 MultiDrag.prototype = {
6274 multiDragKeyDown: false,
6275 isMultiDrag: false,
6276 delayStartGlobal: function delayStartGlobal(_ref) {
6277 var dragged = _ref.dragEl;
6278 dragEl$1 = dragged;
6279 },
6280 delayEnded: function delayEnded() {
6281 this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1);
6282 },
6283 setupClone: function setupClone(_ref2) {
6284 var sortable = _ref2.sortable,
6285 cancel = _ref2.cancel;
6286 if (!this.isMultiDrag) return;
6287 for (var i = 0; i < multiDragElements.length; i++) {
6288 multiDragClones.push(clone(multiDragElements[i]));
6289 multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex;
6290 multiDragClones[i].draggable = false;
6291 multiDragClones[i].style['will-change'] = '';
6292 toggleClass(multiDragClones[i], this.options.selectedClass, false);
6293 multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false);
6294 }
6295 sortable._hideClone();
6296 cancel();
6297 },
6298 clone: function clone(_ref3) {
6299 var sortable = _ref3.sortable,
6300 rootEl = _ref3.rootEl,
6301 dispatchSortableEvent = _ref3.dispatchSortableEvent,
6302 cancel = _ref3.cancel;
6303 if (!this.isMultiDrag) return;
6304 if (!this.options.removeCloneOnHide) {
6305 if (multiDragElements.length && multiDragSortable === sortable) {
6306 insertMultiDragClones(true, rootEl);
6307 dispatchSortableEvent('clone');
6308 cancel();
6309 }
6310 }
6311 },
6312 showClone: function showClone(_ref4) {
6313 var cloneNowShown = _ref4.cloneNowShown,
6314 rootEl = _ref4.rootEl,
6315 cancel = _ref4.cancel;
6316 if (!this.isMultiDrag) return;
6317 insertMultiDragClones(false, rootEl);
6318 multiDragClones.forEach(function (clone) {
6319 css(clone, 'display', '');
6320 });
6321 cloneNowShown();
6322 clonesHidden = false;
6323 cancel();
6324 },
6325 hideClone: function hideClone(_ref5) {
6326 var _this = this;
6327 var sortable = _ref5.sortable,
6328 cloneNowHidden = _ref5.cloneNowHidden,
6329 cancel = _ref5.cancel;
6330 if (!this.isMultiDrag) return;
6331 multiDragClones.forEach(function (clone) {
6332 css(clone, 'display', 'none');
6333 if (_this.options.removeCloneOnHide && clone.parentNode) {
6334 clone.parentNode.removeChild(clone);
6335 }
6336 });
6337 cloneNowHidden();
6338 clonesHidden = true;
6339 cancel();
6340 },
6341 dragStartGlobal: function dragStartGlobal(_ref6) {
6342 var sortable = _ref6.sortable;
6343 if (!this.isMultiDrag && multiDragSortable) {
6344 multiDragSortable.multiDrag._deselectMultiDrag();
6345 }
6346 multiDragElements.forEach(function (multiDragElement) {
6347 multiDragElement.sortableIndex = index(multiDragElement);
6348 });
6349
6350 // Sort multi-drag elements
6351 multiDragElements = multiDragElements.sort(function (a, b) {
6352 return a.sortableIndex - b.sortableIndex;
6353 });
6354 dragStarted = true;
6355 },
6356 dragStarted: function dragStarted(_ref7) {
6357 var _this2 = this;
6358 var sortable = _ref7.sortable;
6359 if (!this.isMultiDrag) return;
6360 if (this.options.sort) {
6361 // Capture rects,
6362 // hide multi drag elements (by positioning them absolute),
6363 // set multi drag elements rects to dragRect,
6364 // show multi drag elements,
6365 // animate to rects,
6366 // unset rects & remove from DOM
6367
6368 sortable.captureAnimationState();
6369 if (this.options.animation) {
6370 multiDragElements.forEach(function (multiDragElement) {
6371 if (multiDragElement === dragEl$1) return;
6372 css(multiDragElement, 'position', 'absolute');
6373 });
6374 var dragRect = getRect(dragEl$1, false, true, true);
6375 multiDragElements.forEach(function (multiDragElement) {
6376 if (multiDragElement === dragEl$1) return;
6377 setRect(multiDragElement, dragRect);
6378 });
6379 folding = true;
6380 initialFolding = true;
6381 }
6382 }
6383 sortable.animateAll(function () {
6384 folding = false;
6385 initialFolding = false;
6386 if (_this2.options.animation) {
6387 multiDragElements.forEach(function (multiDragElement) {
6388 unsetRect(multiDragElement);
6389 });
6390 }
6391
6392 // Remove all auxiliary multidrag items from el, if sorting enabled
6393 if (_this2.options.sort) {
6394 removeMultiDragElements();
6395 }
6396 });
6397 },
6398 dragOver: function dragOver(_ref8) {
6399 var target = _ref8.target,
6400 completed = _ref8.completed,
6401 cancel = _ref8.cancel;
6402 if (folding && ~multiDragElements.indexOf(target)) {
6403 completed(false);
6404 cancel();
6405 }
6406 },
6407 revert: function revert(_ref9) {
6408 var fromSortable = _ref9.fromSortable,
6409 rootEl = _ref9.rootEl,
6410 sortable = _ref9.sortable,
6411 dragRect = _ref9.dragRect;
6412 if (multiDragElements.length > 1) {
6413 // Setup unfold animation
6414 multiDragElements.forEach(function (multiDragElement) {
6415 sortable.addAnimationState({
6416 target: multiDragElement,
6417 rect: folding ? getRect(multiDragElement) : dragRect
6418 });
6419 unsetRect(multiDragElement);
6420 multiDragElement.fromRect = dragRect;
6421 fromSortable.removeAnimationState(multiDragElement);
6422 });
6423 folding = false;
6424 insertMultiDragElements(!this.options.removeCloneOnHide, rootEl);
6425 }
6426 },
6427 dragOverCompleted: function dragOverCompleted(_ref10) {
6428 var sortable = _ref10.sortable,
6429 isOwner = _ref10.isOwner,
6430 insertion = _ref10.insertion,
6431 activeSortable = _ref10.activeSortable,
6432 parentEl = _ref10.parentEl,
6433 putSortable = _ref10.putSortable;
6434 var options = this.options;
6435 if (insertion) {
6436 // Clones must be hidden before folding animation to capture dragRectAbsolute properly
6437 if (isOwner) {
6438 activeSortable._hideClone();
6439 }
6440 initialFolding = false;
6441 // If leaving sort:false root, or already folding - Fold to new location
6442 if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) {
6443 // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible
6444 var dragRectAbsolute = getRect(dragEl$1, false, true, true);
6445 multiDragElements.forEach(function (multiDragElement) {
6446 if (multiDragElement === dragEl$1) return;
6447 setRect(multiDragElement, dragRectAbsolute);
6448
6449 // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted
6450 // while folding, and so that we can capture them again because old sortable will no longer be fromSortable
6451 parentEl.appendChild(multiDragElement);
6452 });
6453 folding = true;
6454 }
6455
6456 // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out
6457 if (!isOwner) {
6458 // Only remove if not folding (folding will remove them anyways)
6459 if (!folding) {
6460 removeMultiDragElements();
6461 }
6462 if (multiDragElements.length > 1) {
6463 var clonesHiddenBefore = clonesHidden;
6464 activeSortable._showClone(sortable);
6465
6466 // Unfold animation for clones if showing from hidden
6467 if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) {
6468 multiDragClones.forEach(function (clone) {
6469 activeSortable.addAnimationState({
6470 target: clone,
6471 rect: clonesFromRect
6472 });
6473 clone.fromRect = clonesFromRect;
6474 clone.thisAnimationDuration = null;
6475 });
6476 }
6477 } else {
6478 activeSortable._showClone(sortable);
6479 }
6480 }
6481 }
6482 },
6483 dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) {
6484 var dragRect = _ref11.dragRect,
6485 isOwner = _ref11.isOwner,
6486 activeSortable = _ref11.activeSortable;
6487 multiDragElements.forEach(function (multiDragElement) {
6488 multiDragElement.thisAnimationDuration = null;
6489 });
6490 if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) {
6491 clonesFromRect = _extends({}, dragRect);
6492 var dragMatrix = matrix(dragEl$1, true);
6493 clonesFromRect.top -= dragMatrix.f;
6494 clonesFromRect.left -= dragMatrix.e;
6495 }
6496 },
6497 dragOverAnimationComplete: function dragOverAnimationComplete() {
6498 if (folding) {
6499 folding = false;
6500 removeMultiDragElements();
6501 }
6502 },
6503 drop: function drop(_ref12) {
6504 var evt = _ref12.originalEvent,
6505 rootEl = _ref12.rootEl,
6506 parentEl = _ref12.parentEl,
6507 sortable = _ref12.sortable,
6508 dispatchSortableEvent = _ref12.dispatchSortableEvent,
6509 oldIndex = _ref12.oldIndex,
6510 putSortable = _ref12.putSortable;
6511 var toSortable = putSortable || this.sortable;
6512 if (!evt) return;
6513 var options = this.options,
6514 children = parentEl.children;
6515
6516 // Multi-drag selection
6517 if (!dragStarted) {
6518 if (options.multiDragKey && !this.multiDragKeyDown) {
6519 this._deselectMultiDrag();
6520 }
6521 toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1));
6522 if (!~multiDragElements.indexOf(dragEl$1)) {
6523 multiDragElements.push(dragEl$1);
6524 dispatchEvent({
6525 sortable: sortable,
6526 rootEl: rootEl,
6527 name: 'select',
6528 targetEl: dragEl$1,
6529 originalEvent: evt
6530 });
6531
6532 // Modifier activated, select from last to dragEl
6533 if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) {
6534 var lastIndex = index(lastMultiDragSelect),
6535 currentIndex = index(dragEl$1);
6536 if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) {
6537 (function () {
6538 // Must include lastMultiDragSelect (select it), in case modified selection from no selection
6539 // (but previous selection existed)
6540 var n, i;
6541 if (currentIndex > lastIndex) {
6542 i = lastIndex;
6543 n = currentIndex;
6544 } else {
6545 i = currentIndex;
6546 n = lastIndex + 1;
6547 }
6548 var filter = options.filter;
6549 for (; i < n; i++) {
6550 if (~multiDragElements.indexOf(children[i])) continue;
6551 // Check if element is draggable
6552 if (!closest(children[i], options.draggable, parentEl, false)) continue;
6553 // Check if element is filtered
6554 var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) {
6555 return closest(children[i], criteria.trim(), parentEl, false);
6556 }));
6557 if (filtered) continue;
6558 toggleClass(children[i], options.selectedClass, true);
6559 multiDragElements.push(children[i]);
6560 dispatchEvent({
6561 sortable: sortable,
6562 rootEl: rootEl,
6563 name: 'select',
6564 targetEl: children[i],
6565 originalEvent: evt
6566 });
6567 }
6568 })();
6569 }
6570 } else {
6571 lastMultiDragSelect = dragEl$1;
6572 }
6573 multiDragSortable = toSortable;
6574 } else {
6575 multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1);
6576 lastMultiDragSelect = null;
6577 dispatchEvent({
6578 sortable: sortable,
6579 rootEl: rootEl,
6580 name: 'deselect',
6581 targetEl: dragEl$1,
6582 originalEvent: evt
6583 });
6584 }
6585 }
6586
6587 // Multi-drag drop
6588 if (dragStarted && this.isMultiDrag) {
6589 folding = false;
6590 // Do not "unfold" after around dragEl if reverted
6591 if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) {
6592 var dragRect = getRect(dragEl$1),
6593 multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')');
6594 if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null;
6595 toSortable.captureAnimationState();
6596 if (!initialFolding) {
6597 if (options.animation) {
6598 dragEl$1.fromRect = dragRect;
6599 multiDragElements.forEach(function (multiDragElement) {
6600 multiDragElement.thisAnimationDuration = null;
6601 if (multiDragElement !== dragEl$1) {
6602 var rect = folding ? getRect(multiDragElement) : dragRect;
6603 multiDragElement.fromRect = rect;
6604
6605 // Prepare unfold animation
6606 toSortable.addAnimationState({
6607 target: multiDragElement,
6608 rect: rect
6609 });
6610 }
6611 });
6612 }
6613
6614 // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert
6615 // properly they must all be removed
6616 removeMultiDragElements();
6617 multiDragElements.forEach(function (multiDragElement) {
6618 if (children[multiDragIndex]) {
6619 parentEl.insertBefore(multiDragElement, children[multiDragIndex]);
6620 } else {
6621 parentEl.appendChild(multiDragElement);
6622 }
6623 multiDragIndex++;
6624 });
6625
6626 // If initial folding is done, the elements may have changed position because they are now
6627 // unfolding around dragEl, even though dragEl may not have his index changed, so update event
6628 // must be fired here as Sortable will not.
6629 if (oldIndex === index(dragEl$1)) {
6630 var update = false;
6631 multiDragElements.forEach(function (multiDragElement) {
6632 if (multiDragElement.sortableIndex !== index(multiDragElement)) {
6633 update = true;
6634 return;
6635 }
6636 });
6637 if (update) {
6638 dispatchSortableEvent('update');
6639 dispatchSortableEvent('sort');
6640 }
6641 }
6642 }
6643
6644 // Must be done after capturing individual rects (scroll bar)
6645 multiDragElements.forEach(function (multiDragElement) {
6646 unsetRect(multiDragElement);
6647 });
6648 toSortable.animateAll();
6649 }
6650 multiDragSortable = toSortable;
6651 }
6652
6653 // Remove clones if necessary
6654 if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') {
6655 multiDragClones.forEach(function (clone) {
6656 clone.parentNode && clone.parentNode.removeChild(clone);
6657 });
6658 }
6659 },
6660 nullingGlobal: function nullingGlobal() {
6661 this.isMultiDrag = dragStarted = false;
6662 multiDragClones.length = 0;
6663 },
6664 destroyGlobal: function destroyGlobal() {
6665 this._deselectMultiDrag();
6666 off(document, 'pointerup', this._deselectMultiDrag);
6667 off(document, 'mouseup', this._deselectMultiDrag);
6668 off(document, 'touchend', this._deselectMultiDrag);
6669 off(document, 'keydown', this._checkKeyDown);
6670 off(document, 'keyup', this._checkKeyUp);
6671 },
6672 _deselectMultiDrag: function _deselectMultiDrag(evt) {
6673 if (typeof dragStarted !== "undefined" && dragStarted) return;
6674
6675 // Only deselect if selection is in this sortable
6676 if (multiDragSortable !== this.sortable) return;
6677
6678 // Only deselect if target is not item in this sortable
6679 if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return;
6680
6681 // Only deselect if left click
6682 if (evt && evt.button !== 0) return;
6683 while (multiDragElements.length) {
6684 var el = multiDragElements[0];
6685 toggleClass(el, this.options.selectedClass, false);
6686 multiDragElements.shift();
6687 dispatchEvent({
6688 sortable: this.sortable,
6689 rootEl: this.sortable.el,
6690 name: 'deselect',
6691 targetEl: el,
6692 originalEvent: evt
6693 });
6694 }
6695 },
6696 _checkKeyDown: function _checkKeyDown(evt) {
6697 if (evt.key === this.options.multiDragKey) {
6698 this.multiDragKeyDown = true;
6699 }
6700 },
6701 _checkKeyUp: function _checkKeyUp(evt) {
6702 if (evt.key === this.options.multiDragKey) {
6703 this.multiDragKeyDown = false;
6704 }
6705 }
6706 };
6707 return _extends(MultiDrag, {
6708 // Static methods & properties
6709 pluginName: 'multiDrag',
6710 utils: {
6711 /**
6712 * Selects the provided multi-drag item
6713 * @param {HTMLElement} el The element to be selected
6714 */
6715 select: function select(el) {
6716 var sortable = el.parentNode[expando];
6717 if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return;
6718 if (multiDragSortable && multiDragSortable !== sortable) {
6719 multiDragSortable.multiDrag._deselectMultiDrag();
6720 multiDragSortable = sortable;
6721 }
6722 toggleClass(el, sortable.options.selectedClass, true);
6723 multiDragElements.push(el);
6724 },
6725 /**
6726 * Deselects the provided multi-drag item
6727 * @param {HTMLElement} el The element to be deselected
6728 */
6729 deselect: function deselect(el) {
6730 var sortable = el.parentNode[expando],
6731 index = multiDragElements.indexOf(el);
6732 if (!sortable || !sortable.options.multiDrag || !~index) return;
6733 toggleClass(el, sortable.options.selectedClass, false);
6734 multiDragElements.splice(index, 1);
6735 }
6736 },
6737 eventProperties: function eventProperties() {
6738 var _this3 = this;
6739 var oldIndicies = [],
6740 newIndicies = [];
6741 multiDragElements.forEach(function (multiDragElement) {
6742 oldIndicies.push({
6743 multiDragElement: multiDragElement,
6744 index: multiDragElement.sortableIndex
6745 });
6746
6747 // multiDragElements will already be sorted if folding
6748 var newIndex;
6749 if (folding && multiDragElement !== dragEl$1) {
6750 newIndex = -1;
6751 } else if (folding) {
6752 newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')');
6753 } else {
6754 newIndex = index(multiDragElement);
6755 }
6756 newIndicies.push({
6757 multiDragElement: multiDragElement,
6758 index: newIndex
6759 });
6760 });
6761 return {
6762 items: _toConsumableArray(multiDragElements),
6763 clones: [].concat(multiDragClones),
6764 oldIndicies: oldIndicies,
6765 newIndicies: newIndicies
6766 };
6767 },
6768 optionListeners: {
6769 multiDragKey: function multiDragKey(key) {
6770 key = key.toLowerCase();
6771 if (key === 'ctrl') {
6772 key = 'Control';
6773 } else if (key.length > 1) {
6774 key = key.charAt(0).toUpperCase() + key.substr(1);
6775 }
6776 return key;
6777 }
6778 }
6779 });
6780 }
6781 function insertMultiDragElements(clonesInserted, rootEl) {
6782 multiDragElements.forEach(function (multiDragElement, i) {
6783 var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)];
6784 if (target) {
6785 rootEl.insertBefore(multiDragElement, target);
6786 } else {
6787 rootEl.appendChild(multiDragElement);
6788 }
6789 });
6790 }
6791
6792 /**
6793 * Insert multi-drag clones
6794 * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted
6795 * @param {HTMLElement} rootEl
6796 */
6797 function insertMultiDragClones(elementsInserted, rootEl) {
6798 multiDragClones.forEach(function (clone, i) {
6799 var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)];
6800 if (target) {
6801 rootEl.insertBefore(clone, target);
6802 } else {
6803 rootEl.appendChild(clone);
6804 }
6805 });
6806 }
6807 function removeMultiDragElements() {
6808 multiDragElements.forEach(function (multiDragElement) {
6809 if (multiDragElement === dragEl$1) return;
6810 multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement);
6811 });
6812 }
6813
6814 Sortable.mount(new AutoScrollPlugin());
6815 Sortable.mount(Remove, Revert);
6816
6817 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Sortable);
6818
6819
6820
6821 /***/ },
6822
6823 /***/ "./node_modules/toastify-js/src/toastify.css"
6824 /*!***************************************************!*\
6825 !*** ./node_modules/toastify-js/src/toastify.css ***!
6826 \***************************************************/
6827 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
6828
6829 "use strict";
6830 __webpack_require__.r(__webpack_exports__);
6831 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6832 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
6833 /* harmony export */ });
6834 /* 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");
6835 /* 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__);
6836 /* 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");
6837 /* 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__);
6838 /* 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");
6839 /* 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__);
6840 /* 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");
6841 /* 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__);
6842 /* 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");
6843 /* 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__);
6844 /* 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");
6845 /* 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__);
6846 /* 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");
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858 var options = {};
6859
6860 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
6861 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
6862
6863 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
6864
6865 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
6866 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
6867
6868 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);
6869
6870
6871
6872
6873 /* 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);
6874
6875
6876 /***/ },
6877
6878 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
6879 /*!****************************************************************************!*\
6880 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
6881 \****************************************************************************/
6882 (module) {
6883
6884 "use strict";
6885
6886
6887 var stylesInDOM = [];
6888 function getIndexByIdentifier(identifier) {
6889 var result = -1;
6890 for (var i = 0; i < stylesInDOM.length; i++) {
6891 if (stylesInDOM[i].identifier === identifier) {
6892 result = i;
6893 break;
6894 }
6895 }
6896 return result;
6897 }
6898 function modulesToDom(list, options) {
6899 var idCountMap = {};
6900 var identifiers = [];
6901 for (var i = 0; i < list.length; i++) {
6902 var item = list[i];
6903 var id = options.base ? item[0] + options.base : item[0];
6904 var count = idCountMap[id] || 0;
6905 var identifier = "".concat(id, " ").concat(count);
6906 idCountMap[id] = count + 1;
6907 var indexByIdentifier = getIndexByIdentifier(identifier);
6908 var obj = {
6909 css: item[1],
6910 media: item[2],
6911 sourceMap: item[3],
6912 supports: item[4],
6913 layer: item[5]
6914 };
6915 if (indexByIdentifier !== -1) {
6916 stylesInDOM[indexByIdentifier].references++;
6917 stylesInDOM[indexByIdentifier].updater(obj);
6918 } else {
6919 var updater = addElementStyle(obj, options);
6920 options.byIndex = i;
6921 stylesInDOM.splice(i, 0, {
6922 identifier: identifier,
6923 updater: updater,
6924 references: 1
6925 });
6926 }
6927 identifiers.push(identifier);
6928 }
6929 return identifiers;
6930 }
6931 function addElementStyle(obj, options) {
6932 var api = options.domAPI(options);
6933 api.update(obj);
6934 var updater = function updater(newObj) {
6935 if (newObj) {
6936 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
6937 return;
6938 }
6939 api.update(obj = newObj);
6940 } else {
6941 api.remove();
6942 }
6943 };
6944 return updater;
6945 }
6946 module.exports = function (list, options) {
6947 options = options || {};
6948 list = list || [];
6949 var lastIdentifiers = modulesToDom(list, options);
6950 return function update(newList) {
6951 newList = newList || [];
6952 for (var i = 0; i < lastIdentifiers.length; i++) {
6953 var identifier = lastIdentifiers[i];
6954 var index = getIndexByIdentifier(identifier);
6955 stylesInDOM[index].references--;
6956 }
6957 var newLastIdentifiers = modulesToDom(newList, options);
6958 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
6959 var _identifier = lastIdentifiers[_i];
6960 var _index = getIndexByIdentifier(_identifier);
6961 if (stylesInDOM[_index].references === 0) {
6962 stylesInDOM[_index].updater();
6963 stylesInDOM.splice(_index, 1);
6964 }
6965 }
6966 lastIdentifiers = newLastIdentifiers;
6967 };
6968 };
6969
6970 /***/ },
6971
6972 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
6973 /*!********************************************************************!*\
6974 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
6975 \********************************************************************/
6976 (module) {
6977
6978 "use strict";
6979
6980
6981 var memo = {};
6982
6983 /* istanbul ignore next */
6984 function getTarget(target) {
6985 if (typeof memo[target] === "undefined") {
6986 var styleTarget = document.querySelector(target);
6987
6988 // Special case to return head of iframe instead of iframe itself
6989 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
6990 try {
6991 // This will throw an exception if access to iframe is blocked
6992 // due to cross-origin restrictions
6993 styleTarget = styleTarget.contentDocument.head;
6994 } catch (e) {
6995 // istanbul ignore next
6996 styleTarget = null;
6997 }
6998 }
6999 memo[target] = styleTarget;
7000 }
7001 return memo[target];
7002 }
7003
7004 /* istanbul ignore next */
7005 function insertBySelector(insert, style) {
7006 var target = getTarget(insert);
7007 if (!target) {
7008 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
7009 }
7010 target.appendChild(style);
7011 }
7012 module.exports = insertBySelector;
7013
7014 /***/ },
7015
7016 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
7017 /*!**********************************************************************!*\
7018 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
7019 \**********************************************************************/
7020 (module) {
7021
7022 "use strict";
7023
7024
7025 /* istanbul ignore next */
7026 function insertStyleElement(options) {
7027 var element = document.createElement("style");
7028 options.setAttributes(element, options.attributes);
7029 options.insert(element, options.options);
7030 return element;
7031 }
7032 module.exports = insertStyleElement;
7033
7034 /***/ },
7035
7036 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
7037 /*!**********************************************************************************!*\
7038 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
7039 \**********************************************************************************/
7040 (module, __unused_webpack_exports, __webpack_require__) {
7041
7042 "use strict";
7043
7044
7045 /* istanbul ignore next */
7046 function setAttributesWithoutAttributes(styleElement) {
7047 var nonce = true ? __webpack_require__.nc : 0;
7048 if (nonce) {
7049 styleElement.setAttribute("nonce", nonce);
7050 }
7051 }
7052 module.exports = setAttributesWithoutAttributes;
7053
7054 /***/ },
7055
7056 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
7057 /*!***************************************************************!*\
7058 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
7059 \***************************************************************/
7060 (module) {
7061
7062 "use strict";
7063
7064
7065 /* istanbul ignore next */
7066 function apply(styleElement, options, obj) {
7067 var css = "";
7068 if (obj.supports) {
7069 css += "@supports (".concat(obj.supports, ") {");
7070 }
7071 if (obj.media) {
7072 css += "@media ".concat(obj.media, " {");
7073 }
7074 var needLayer = typeof obj.layer !== "undefined";
7075 if (needLayer) {
7076 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
7077 }
7078 css += obj.css;
7079 if (needLayer) {
7080 css += "}";
7081 }
7082 if (obj.media) {
7083 css += "}";
7084 }
7085 if (obj.supports) {
7086 css += "}";
7087 }
7088 var sourceMap = obj.sourceMap;
7089 if (sourceMap && typeof btoa !== "undefined") {
7090 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
7091 }
7092
7093 // For old IE
7094 /* istanbul ignore if */
7095 options.styleTagTransform(css, styleElement, options.options);
7096 }
7097 function removeStyleElement(styleElement) {
7098 // istanbul ignore if
7099 if (styleElement.parentNode === null) {
7100 return false;
7101 }
7102 styleElement.parentNode.removeChild(styleElement);
7103 }
7104
7105 /* istanbul ignore next */
7106 function domAPI(options) {
7107 if (typeof document === "undefined") {
7108 return {
7109 update: function update() {},
7110 remove: function remove() {}
7111 };
7112 }
7113 var styleElement = options.insertStyleElement(options);
7114 return {
7115 update: function update(obj) {
7116 apply(styleElement, options, obj);
7117 },
7118 remove: function remove() {
7119 removeStyleElement(styleElement);
7120 }
7121 };
7122 }
7123 module.exports = domAPI;
7124
7125 /***/ },
7126
7127 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
7128 /*!*********************************************************************!*\
7129 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
7130 \*********************************************************************/
7131 (module) {
7132
7133 "use strict";
7134
7135
7136 /* istanbul ignore next */
7137 function styleTagTransform(css, styleElement) {
7138 if (styleElement.styleSheet) {
7139 styleElement.styleSheet.cssText = css;
7140 } else {
7141 while (styleElement.firstChild) {
7142 styleElement.removeChild(styleElement.firstChild);
7143 }
7144 styleElement.appendChild(document.createTextNode(css));
7145 }
7146 }
7147 module.exports = styleTagTransform;
7148
7149 /***/ },
7150
7151 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
7152 /*!**********************************************************!*\
7153 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
7154 \**********************************************************/
7155 (module) {
7156
7157 /*!
7158 * sweetalert2 v11.26.25
7159 * Released under the MIT License.
7160 */
7161 (function (global, factory) {
7162 true ? module.exports = factory() :
7163 0;
7164 })(this, (function () { 'use strict';
7165
7166 function _assertClassBrand(e, t, n) {
7167 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
7168 throw new TypeError("Private element is not present on this object");
7169 }
7170 function _checkPrivateRedeclaration(e, t) {
7171 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
7172 }
7173 function _classPrivateFieldGet2(s, a) {
7174 return s.get(_assertClassBrand(s, a));
7175 }
7176 function _classPrivateFieldInitSpec(e, t, a) {
7177 _checkPrivateRedeclaration(e, t), t.set(e, a);
7178 }
7179 function _classPrivateFieldSet2(s, a, r) {
7180 return s.set(_assertClassBrand(s, a), r), r;
7181 }
7182
7183 const RESTORE_FOCUS_TIMEOUT = 100;
7184
7185 /** @type {GlobalState} */
7186 const globalState = {};
7187 const focusPreviousActiveElement = () => {
7188 if (globalState.previousActiveElement instanceof HTMLElement) {
7189 globalState.previousActiveElement.focus();
7190 globalState.previousActiveElement = null;
7191 } else if (document.body) {
7192 document.body.focus();
7193 }
7194 };
7195
7196 /**
7197 * Restore previous active (focused) element
7198 *
7199 * @param {boolean} returnFocus
7200 * @returns {Promise<void>}
7201 */
7202 const restoreActiveElement = returnFocus => {
7203 return new Promise(resolve => {
7204 if (!returnFocus) {
7205 return resolve();
7206 }
7207 const x = window.scrollX;
7208 const y = window.scrollY;
7209 globalState.restoreFocusTimeout = setTimeout(() => {
7210 focusPreviousActiveElement();
7211 resolve();
7212 }, RESTORE_FOCUS_TIMEOUT); // issues/900
7213
7214 window.scrollTo(x, y);
7215 });
7216 };
7217
7218 const swalPrefix = 'swal2-';
7219
7220 /**
7221 * @typedef {Record<SwalClass, string>} SwalClasses
7222 */
7223
7224 /**
7225 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
7226 * @typedef {Record<SwalIcon, string>} SwalIcons
7227 */
7228
7229 /** @type {SwalClass[]} */
7230 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'];
7231 const swalClasses = classNames.reduce((acc, className) => {
7232 acc[className] = swalPrefix + className;
7233 return acc;
7234 }, /** @type {SwalClasses} */{});
7235
7236 /** @type {SwalIcon[]} */
7237 const icons = ['success', 'warning', 'info', 'question', 'error'];
7238 const iconTypes = icons.reduce((acc, icon) => {
7239 acc[icon] = swalPrefix + icon;
7240 return acc;
7241 }, /** @type {SwalIcons} */{});
7242
7243 const consolePrefix = 'SweetAlert2:';
7244
7245 /**
7246 * Capitalize the first letter of a string
7247 *
7248 * @param {string} str
7249 * @returns {string}
7250 */
7251 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
7252
7253 /**
7254 * Standardize console warnings
7255 *
7256 * @param {string | string[]} message
7257 */
7258 const warn = message => {
7259 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
7260 };
7261
7262 /**
7263 * Standardize console errors
7264 *
7265 * @param {string} message
7266 */
7267 const error = message => {
7268 console.error(`${consolePrefix} ${message}`);
7269 };
7270
7271 /**
7272 * Private global state for `warnOnce`
7273 *
7274 * @type {string[]}
7275 * @private
7276 */
7277 const previousWarnOnceMessages = [];
7278
7279 /**
7280 * Show a console warning, but only if it hasn't already been shown
7281 *
7282 * @param {string} message
7283 */
7284 const warnOnce = message => {
7285 if (!previousWarnOnceMessages.includes(message)) {
7286 previousWarnOnceMessages.push(message);
7287 warn(message);
7288 }
7289 };
7290
7291 /**
7292 * Show a one-time console warning about deprecated params/methods
7293 *
7294 * @param {string} deprecatedParam
7295 * @param {string?} useInstead
7296 */
7297 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
7298 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
7299 };
7300
7301 /**
7302 * If `arg` is a function, call it (with no arguments or context) and return the result.
7303 * Otherwise, just pass the value through
7304 *
7305 * @param {(() => *) | *} arg
7306 * @returns {*}
7307 */
7308 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
7309
7310 /**
7311 * @param {*} arg
7312 * @returns {boolean}
7313 */
7314 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
7315
7316 /**
7317 * @param {*} arg
7318 * @returns {Promise<*>}
7319 */
7320 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
7321
7322 /**
7323 * @param {*} arg
7324 * @returns {boolean}
7325 */
7326 const isPromise = arg => arg && Promise.resolve(arg) === arg;
7327
7328 /**
7329 * @returns {boolean}
7330 */
7331 const isFirefox = () => navigator.userAgent.includes('Firefox');
7332
7333 /**
7334 * Gets the popup container which contains the backdrop and the popup itself.
7335 *
7336 * @returns {HTMLElement | null}
7337 */
7338 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
7339
7340 /**
7341 * @param {string} selectorString
7342 * @returns {HTMLElement | null}
7343 */
7344 const elementBySelector = selectorString => {
7345 const container = getContainer();
7346 return container ? container.querySelector(selectorString) : null;
7347 };
7348
7349 /**
7350 * @param {string} className
7351 * @returns {HTMLElement | null}
7352 */
7353 const elementByClass = className => {
7354 return elementBySelector(`.${className}`);
7355 };
7356
7357 /**
7358 * @returns {HTMLElement | null}
7359 */
7360 const getPopup = () => elementByClass(swalClasses.popup);
7361
7362 /**
7363 * @returns {HTMLElement | null}
7364 */
7365 const getIcon = () => elementByClass(swalClasses.icon);
7366
7367 /**
7368 * @returns {HTMLElement | null}
7369 */
7370 const getIconContent = () => elementByClass(swalClasses['icon-content']);
7371
7372 /**
7373 * @returns {HTMLElement | null}
7374 */
7375 const getTitle = () => elementByClass(swalClasses.title);
7376
7377 /**
7378 * @returns {HTMLElement | null}
7379 */
7380 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
7381
7382 /**
7383 * @returns {HTMLElement | null}
7384 */
7385 const getImage = () => elementByClass(swalClasses.image);
7386
7387 /**
7388 * @returns {HTMLElement | null}
7389 */
7390 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
7391
7392 /**
7393 * @returns {HTMLElement | null}
7394 */
7395 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
7396
7397 /**
7398 * @returns {HTMLButtonElement | null}
7399 */
7400 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
7401
7402 /**
7403 * @returns {HTMLButtonElement | null}
7404 */
7405 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
7406
7407 /**
7408 * @returns {HTMLButtonElement | null}
7409 */
7410 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
7411
7412 /**
7413 * @returns {HTMLElement | null}
7414 */
7415 const getInputLabel = () => elementByClass(swalClasses['input-label']);
7416
7417 /**
7418 * @returns {HTMLElement | null}
7419 */
7420 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
7421
7422 /**
7423 * @returns {HTMLElement | null}
7424 */
7425 const getActions = () => elementByClass(swalClasses.actions);
7426
7427 /**
7428 * @returns {HTMLElement | null}
7429 */
7430 const getFooter = () => elementByClass(swalClasses.footer);
7431
7432 /**
7433 * @returns {HTMLElement | null}
7434 */
7435 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
7436
7437 /**
7438 * @returns {HTMLElement | null}
7439 */
7440 const getCloseButton = () => elementByClass(swalClasses.close);
7441
7442 // https://github.com/jkup/focusable/blob/master/index.js
7443 const focusable = `
7444 a[href],
7445 area[href],
7446 input:not([disabled]),
7447 select:not([disabled]),
7448 textarea:not([disabled]),
7449 button:not([disabled]),
7450 iframe,
7451 object,
7452 embed,
7453 [tabindex="0"],
7454 [contenteditable],
7455 audio[controls],
7456 video[controls],
7457 summary
7458 `;
7459 /**
7460 * @returns {HTMLElement[]}
7461 */
7462 const getFocusableElements = () => {
7463 const popup = getPopup();
7464 if (!popup) {
7465 return [];
7466 }
7467 /** @type {NodeListOf<HTMLElement>} */
7468 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
7469 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
7470 // sort according to tabindex
7471 .sort((a, b) => {
7472 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
7473 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
7474 if (tabindexA > tabindexB) {
7475 return 1;
7476 } else if (tabindexA < tabindexB) {
7477 return -1;
7478 }
7479 return 0;
7480 });
7481
7482 /** @type {NodeListOf<HTMLElement>} */
7483 const otherFocusableElements = popup.querySelectorAll(focusable);
7484 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
7485 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
7486 };
7487
7488 /**
7489 * @returns {boolean}
7490 */
7491 const isModal = () => {
7492 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
7493 };
7494
7495 /**
7496 * @returns {boolean}
7497 */
7498 const isToast = () => {
7499 const popup = getPopup();
7500 if (!popup) {
7501 return false;
7502 }
7503 return hasClass(popup, swalClasses.toast);
7504 };
7505
7506 /**
7507 * @returns {boolean}
7508 */
7509 const isLoading = () => {
7510 const popup = getPopup();
7511 if (!popup) {
7512 return false;
7513 }
7514 return popup.hasAttribute('data-loading');
7515 };
7516
7517 /**
7518 * Securely set innerHTML of an element
7519 * https://github.com/sweetalert2/sweetalert2/issues/1926
7520 *
7521 * @param {HTMLElement} elem
7522 * @param {string} html
7523 */
7524 const setInnerHtml = (elem, html) => {
7525 elem.textContent = '';
7526 if (html) {
7527 const parser = new DOMParser();
7528 const parsed = parser.parseFromString(html, `text/html`);
7529 const head = parsed.querySelector('head');
7530 if (head) {
7531 Array.from(head.childNodes).forEach(child => {
7532 elem.appendChild(child);
7533 });
7534 }
7535 const body = parsed.querySelector('body');
7536 if (body) {
7537 Array.from(body.childNodes).forEach(child => {
7538 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
7539 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
7540 } else {
7541 elem.appendChild(child);
7542 }
7543 });
7544 }
7545 }
7546 };
7547
7548 /**
7549 * @param {HTMLElement} elem
7550 * @param {string} className
7551 * @returns {boolean}
7552 */
7553 const hasClass = (elem, className) => {
7554 if (!className) {
7555 return false;
7556 }
7557 return className.split(/\s+/).every(cls => elem.classList.contains(cls));
7558 };
7559
7560 /**
7561 * @param {HTMLElement} elem
7562 * @param {SweetAlertOptions} params
7563 */
7564 const removeCustomClasses = (elem, params) => {
7565 Array.from(elem.classList).forEach(className => {
7566 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
7567 elem.classList.remove(className);
7568 }
7569 });
7570 };
7571
7572 /**
7573 * @param {HTMLElement} elem
7574 * @param {SweetAlertOptions} params
7575 * @param {string} className
7576 */
7577 const applyCustomClass = (elem, params, className) => {
7578 removeCustomClasses(elem, params);
7579 if (!params.customClass) {
7580 return;
7581 }
7582 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
7583 if (!customClass) {
7584 return;
7585 }
7586 if (typeof customClass !== 'string' && !customClass.forEach) {
7587 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
7588 return;
7589 }
7590 addClass(elem, customClass);
7591 };
7592
7593 /**
7594 * @param {HTMLElement} popup
7595 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
7596 * @returns {HTMLInputElement | null}
7597 */
7598 const getInput$1 = (popup, inputClass) => {
7599 if (!inputClass) {
7600 return null;
7601 }
7602 switch (inputClass) {
7603 case 'select':
7604 case 'textarea':
7605 case 'file':
7606 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
7607 case 'checkbox':
7608 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
7609 case 'radio':
7610 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
7611 case 'range':
7612 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
7613 default:
7614 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
7615 }
7616 };
7617
7618 /**
7619 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
7620 */
7621 const focusInput = input => {
7622 input.focus();
7623
7624 // place cursor at end of text in text input
7625 if (input.type !== 'file') {
7626 // http://stackoverflow.com/a/2345915
7627 const val = input.value;
7628 input.value = '';
7629 input.value = val;
7630 }
7631 };
7632
7633 /**
7634 * @param {HTMLElement | HTMLElement[] | null} target
7635 * @param {string | string[] | readonly string[] | undefined} classList
7636 * @param {boolean} condition
7637 */
7638 const toggleClass = (target, classList, condition) => {
7639 if (!target || !classList) {
7640 return;
7641 }
7642 const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
7643 const targets = Array.isArray(target) ? target : [target];
7644 targets.forEach(elem => {
7645 classes.forEach(className => {
7646 if (condition) {
7647 elem.classList.add(className);
7648 } else {
7649 elem.classList.remove(className);
7650 }
7651 });
7652 });
7653 };
7654
7655 /**
7656 * @param {HTMLElement | HTMLElement[] | null} target
7657 * @param {string | string[] | readonly string[] | undefined} classList
7658 */
7659 const addClass = (target, classList) => {
7660 toggleClass(target, classList, true);
7661 };
7662
7663 /**
7664 * @param {HTMLElement | HTMLElement[] | null} target
7665 * @param {string | string[] | readonly string[] | undefined} classList
7666 */
7667 const removeClass = (target, classList) => {
7668 toggleClass(target, classList, false);
7669 };
7670
7671 /**
7672 * Get direct child of an element by class name
7673 *
7674 * @param {HTMLElement} elem
7675 * @param {string} className
7676 * @returns {HTMLElement | undefined}
7677 */
7678 const getDirectChildByClass = (elem, className) => (/** @type {HTMLElement | undefined} */
7679 Array.from(elem.children).find(child => child instanceof HTMLElement && hasClass(child, className)));
7680
7681 /**
7682 * @param {HTMLElement} elem
7683 * @param {string} property
7684 * @param {string | number | null | undefined} value
7685 */
7686 const applyNumericalStyle = (elem, property, value) => {
7687 if (value === `${parseInt(`${value}`)}`) {
7688 value = parseInt(value);
7689 }
7690 if (value || value === 0) {
7691 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
7692 } else {
7693 elem.style.removeProperty(property);
7694 }
7695 };
7696
7697 /**
7698 * @param {HTMLElement | null} elem
7699 * @param {string} display
7700 */
7701 const show = (elem, display = 'flex') => {
7702 if (!elem) {
7703 return;
7704 }
7705 elem.style.display = display;
7706 };
7707
7708 /**
7709 * @param {HTMLElement | null} elem
7710 */
7711 const hide = elem => {
7712 if (!elem) {
7713 return;
7714 }
7715 elem.style.display = 'none';
7716 };
7717
7718 /**
7719 * @param {HTMLElement | null} elem
7720 * @param {string} display
7721 */
7722 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
7723 if (!elem) {
7724 return;
7725 }
7726 new MutationObserver(() => {
7727 toggle(elem, elem.innerHTML, display);
7728 }).observe(elem, {
7729 childList: true,
7730 subtree: true
7731 });
7732 };
7733
7734 /**
7735 * @param {HTMLElement} parent
7736 * @param {string} selector
7737 * @param {string} property
7738 * @param {string} value
7739 */
7740 const setStyle = (parent, selector, property, value) => {
7741 /** @type {HTMLElement | null} */
7742 const el = parent.querySelector(selector);
7743 if (el) {
7744 el.style.setProperty(property, value);
7745 }
7746 };
7747
7748 /**
7749 * @param {HTMLElement} elem
7750 * @param {boolean | string | null | undefined} condition
7751 * @param {string} display
7752 */
7753 const toggle = (elem, condition, display = 'flex') => {
7754 if (condition) {
7755 show(elem, display);
7756 } else {
7757 hide(elem);
7758 }
7759 };
7760
7761 /**
7762 * borrowed from jquery $(elem).is(':visible') implementation
7763 *
7764 * @param {HTMLElement | null} elem
7765 * @returns {boolean}
7766 */
7767 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
7768
7769 /**
7770 * @returns {boolean}
7771 */
7772 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
7773
7774 /**
7775 * @param {HTMLElement} elem
7776 * @returns {boolean}
7777 */
7778 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
7779
7780 /**
7781 * @param {HTMLElement} element
7782 * @param {HTMLElement} stopElement
7783 * @returns {boolean}
7784 */
7785 const selfOrParentIsScrollable = (element, stopElement) => {
7786 let parent = /** @type {HTMLElement | null} */element;
7787 while (parent && parent !== stopElement) {
7788 if (isScrollable(parent)) {
7789 return true;
7790 }
7791 parent = parent.parentElement;
7792 }
7793 return false;
7794 };
7795
7796 /**
7797 * borrowed from https://stackoverflow.com/a/46352119
7798 *
7799 * @param {HTMLElement} elem
7800 * @returns {boolean}
7801 */
7802 const hasCssAnimation = elem => {
7803 const style = window.getComputedStyle(elem);
7804 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
7805 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
7806 return animDuration > 0 || transDuration > 0;
7807 };
7808
7809 /**
7810 * @param {number} timer
7811 * @param {boolean} reset
7812 */
7813 const animateTimerProgressBar = (timer, reset = false) => {
7814 const timerProgressBar = getTimerProgressBar();
7815 if (!timerProgressBar) {
7816 return;
7817 }
7818 if (isVisible$1(timerProgressBar)) {
7819 if (reset) {
7820 timerProgressBar.style.transition = 'none';
7821 timerProgressBar.style.width = '100%';
7822 }
7823 setTimeout(() => {
7824 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
7825 timerProgressBar.style.width = '0%';
7826 }, 10);
7827 }
7828 };
7829 const stopTimerProgressBar = () => {
7830 const timerProgressBar = getTimerProgressBar();
7831 if (!timerProgressBar) {
7832 return;
7833 }
7834 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
7835 timerProgressBar.style.removeProperty('transition');
7836 timerProgressBar.style.width = '100%';
7837 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
7838 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
7839 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
7840 };
7841
7842 /**
7843 * Detect Node env
7844 *
7845 * @returns {boolean}
7846 */
7847 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
7848
7849 const sweetHTML = `
7850 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
7851 <button type="button" class="${swalClasses.close}"></button>
7852 <ul class="${swalClasses['progress-steps']}"></ul>
7853 <div class="${swalClasses.icon}"></div>
7854 <img class="${swalClasses.image}" />
7855 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
7856 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
7857 <input class="${swalClasses.input}" id="${swalClasses.input}" />
7858 <input type="file" class="${swalClasses.file}" />
7859 <div class="${swalClasses.range}">
7860 <input type="range" />
7861 <output></output>
7862 </div>
7863 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
7864 <div class="${swalClasses.radio}"></div>
7865 <label class="${swalClasses.checkbox}">
7866 <input type="checkbox" id="${swalClasses.checkbox}" />
7867 <span class="${swalClasses.label}"></span>
7868 </label>
7869 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
7870 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
7871 <div class="${swalClasses.actions}">
7872 <div class="${swalClasses.loader}"></div>
7873 <button type="button" class="${swalClasses.confirm}"></button>
7874 <button type="button" class="${swalClasses.deny}"></button>
7875 <button type="button" class="${swalClasses.cancel}"></button>
7876 </div>
7877 <div class="${swalClasses.footer}"></div>
7878 <div class="${swalClasses['timer-progress-bar-container']}">
7879 <div class="${swalClasses['timer-progress-bar']}"></div>
7880 </div>
7881 </div>
7882 `.replace(/(^|\n)\s*/g, '');
7883
7884 /**
7885 * @returns {boolean}
7886 */
7887 const resetOldContainer = () => {
7888 const oldContainer = getContainer();
7889 if (!oldContainer) {
7890 return false;
7891 }
7892 oldContainer.remove();
7893 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
7894 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
7895 swalClasses['has-column']]);
7896 return true;
7897 };
7898 const resetValidationMessage$1 = () => {
7899 if (globalState.currentInstance) {
7900 globalState.currentInstance.resetValidationMessage();
7901 }
7902 };
7903 const addInputChangeListeners = () => {
7904 const popup = getPopup();
7905 if (!popup) {
7906 return;
7907 }
7908 const input = getDirectChildByClass(popup, swalClasses.input);
7909 const file = getDirectChildByClass(popup, swalClasses.file);
7910 /** @type {HTMLInputElement | null} */
7911 const range = popup.querySelector(`.${swalClasses.range} input`);
7912 /** @type {HTMLOutputElement | null} */
7913 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
7914 const select = getDirectChildByClass(popup, swalClasses.select);
7915 /** @type {HTMLInputElement | null} */
7916 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
7917 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
7918 if (input) {
7919 input.oninput = resetValidationMessage$1;
7920 }
7921 if (file) {
7922 file.onchange = resetValidationMessage$1;
7923 }
7924 if (select) {
7925 select.onchange = resetValidationMessage$1;
7926 }
7927 if (checkbox) {
7928 checkbox.onchange = resetValidationMessage$1;
7929 }
7930 if (textarea) {
7931 textarea.oninput = resetValidationMessage$1;
7932 }
7933 if (range && rangeOutput) {
7934 range.oninput = () => {
7935 resetValidationMessage$1();
7936 rangeOutput.value = range.value;
7937 };
7938 range.onchange = () => {
7939 resetValidationMessage$1();
7940 rangeOutput.value = range.value;
7941 };
7942 }
7943 };
7944
7945 /**
7946 * @param {string | HTMLElement} target
7947 * @returns {HTMLElement}
7948 */
7949 const getTarget = target => {
7950 if (typeof target === 'string') {
7951 const element = document.querySelector(target);
7952 if (!element) {
7953 throw new Error(`Target element "${target}" not found`);
7954 }
7955 return /** @type {HTMLElement} */element;
7956 }
7957 return target;
7958 };
7959
7960 /**
7961 * @param {SweetAlertOptions} params
7962 */
7963 const setupAccessibility = params => {
7964 const popup = getPopup();
7965 if (!popup) {
7966 return;
7967 }
7968 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
7969 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
7970 if (!params.toast) {
7971 popup.setAttribute('aria-modal', 'true');
7972 }
7973 };
7974
7975 /**
7976 * @param {HTMLElement} targetElement
7977 */
7978 const setupRTL = targetElement => {
7979 if (window.getComputedStyle(targetElement).direction === 'rtl') {
7980 addClass(getContainer(), swalClasses.rtl);
7981 globalState.isRTL = true;
7982 }
7983 };
7984
7985 /**
7986 * Add modal + backdrop to DOM
7987 *
7988 * @param {SweetAlertOptions} params
7989 */
7990 const init = params => {
7991 // Clean up the old popup container if it exists
7992 const oldContainerExisted = resetOldContainer();
7993 if (isNodeEnv()) {
7994 error('SweetAlert2 requires document to initialize');
7995 return;
7996 }
7997 const container = document.createElement('div');
7998 container.className = swalClasses.container;
7999 if (oldContainerExisted) {
8000 addClass(container, swalClasses['no-transition']);
8001 }
8002 setInnerHtml(container, sweetHTML);
8003 container.dataset['swal2Theme'] = params.theme;
8004 const targetElement = getTarget(params.target || 'body');
8005 targetElement.appendChild(container);
8006 if (params.topLayer) {
8007 container.setAttribute('popover', '');
8008 container.showPopover();
8009 }
8010 setupAccessibility(params);
8011 setupRTL(targetElement);
8012 addInputChangeListeners();
8013 };
8014
8015 /**
8016 * @param {HTMLElement | object | string} param
8017 * @param {HTMLElement} target
8018 */
8019 const parseHtmlToContainer = (param, target) => {
8020 // DOM element
8021 if (param instanceof HTMLElement) {
8022 target.appendChild(param);
8023 }
8024
8025 // Object
8026 else if (typeof param === 'object') {
8027 handleObject(param, target);
8028 }
8029
8030 // Plain string
8031 else if (param) {
8032 setInnerHtml(target, param);
8033 }
8034 };
8035
8036 /**
8037 * @param {object} param
8038 * @param {HTMLElement} target
8039 */
8040 const handleObject = (param, target) => {
8041 // JQuery element(s)
8042 if ('jquery' in param) {
8043 handleJqueryElem(target, param);
8044 }
8045
8046 // For other objects use their string representation
8047 else {
8048 setInnerHtml(target, param.toString());
8049 }
8050 };
8051
8052 /**
8053 * @param {HTMLElement} target
8054 * @param {any} elem
8055 */
8056 const handleJqueryElem = (target, elem) => {
8057 target.textContent = '';
8058 if (0 in elem) {
8059 for (let i = 0; i in elem; i++) {
8060 target.appendChild(elem[i].cloneNode(true));
8061 }
8062 } else {
8063 target.appendChild(elem.cloneNode(true));
8064 }
8065 };
8066
8067 /**
8068 * @param {SweetAlert} instance
8069 * @param {SweetAlertOptions} params
8070 */
8071 const renderActions = (instance, params) => {
8072 const actions = getActions();
8073 const loader = getLoader();
8074 if (!actions || !loader) {
8075 return;
8076 }
8077
8078 // Actions (buttons) wrapper
8079 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
8080 hide(actions);
8081 } else {
8082 show(actions);
8083 }
8084
8085 // Custom class
8086 applyCustomClass(actions, params, 'actions');
8087
8088 // Render all the buttons
8089 renderButtons(actions, loader, params);
8090
8091 // Loader
8092 setInnerHtml(loader, params.loaderHtml || '');
8093 applyCustomClass(loader, params, 'loader');
8094 };
8095
8096 /**
8097 * @param {HTMLElement} actions
8098 * @param {HTMLElement} loader
8099 * @param {SweetAlertOptions} params
8100 */
8101 function renderButtons(actions, loader, params) {
8102 const confirmButton = getConfirmButton();
8103 const denyButton = getDenyButton();
8104 const cancelButton = getCancelButton();
8105 if (!confirmButton || !denyButton || !cancelButton) {
8106 return;
8107 }
8108
8109 // Render buttons
8110 renderButton(confirmButton, 'confirm', params);
8111 renderButton(denyButton, 'deny', params);
8112 renderButton(cancelButton, 'cancel', params);
8113 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
8114 if (params.reverseButtons) {
8115 if (params.toast) {
8116 actions.insertBefore(cancelButton, confirmButton);
8117 actions.insertBefore(denyButton, confirmButton);
8118 } else {
8119 actions.insertBefore(cancelButton, loader);
8120 actions.insertBefore(denyButton, loader);
8121 actions.insertBefore(confirmButton, loader);
8122 }
8123 }
8124 }
8125
8126 /**
8127 * @param {HTMLElement} confirmButton
8128 * @param {HTMLElement} denyButton
8129 * @param {HTMLElement} cancelButton
8130 * @param {SweetAlertOptions} params
8131 */
8132 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
8133 if (!params.buttonsStyling) {
8134 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
8135 return;
8136 }
8137 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
8138
8139 // Apply custom background colors and outline colors to action buttons
8140 /** @type {[HTMLElement, string, string | undefined][]} */
8141 const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
8142 buttons.forEach(([button, type, color]) => {
8143 if (color) {
8144 button.style.setProperty(`--swal2-${type}-button-background-color`, color);
8145 }
8146 applyOutlineColor(button);
8147 });
8148 }
8149
8150 /**
8151 * @param {HTMLElement} button
8152 */
8153 function applyOutlineColor(button) {
8154 const buttonStyle = window.getComputedStyle(button);
8155 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
8156 // If the button already has a custom outline color, no need to change it
8157 return;
8158 }
8159 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
8160 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
8161 }
8162
8163 /**
8164 * @param {HTMLElement} button
8165 * @param {'confirm' | 'deny' | 'cancel'} buttonType
8166 * @param {SweetAlertOptions} params
8167 */
8168 function renderButton(button, buttonType, params) {
8169 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
8170 toggle(button, params[`show${buttonName}Button`], 'inline-block');
8171 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
8172 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
8173
8174 // Add buttons custom classes
8175 button.className = swalClasses[buttonType];
8176 applyCustomClass(button, params, `${buttonType}Button`);
8177 }
8178
8179 /**
8180 * @param {SweetAlert} instance
8181 * @param {SweetAlertOptions} params
8182 */
8183 const renderCloseButton = (instance, params) => {
8184 const closeButton = getCloseButton();
8185 if (!closeButton) {
8186 return;
8187 }
8188 setInnerHtml(closeButton, params.closeButtonHtml || '');
8189
8190 // Custom class
8191 applyCustomClass(closeButton, params, 'closeButton');
8192 toggle(closeButton, params.showCloseButton);
8193 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
8194 };
8195
8196 /**
8197 * @param {SweetAlert} instance
8198 * @param {SweetAlertOptions} params
8199 */
8200 const renderContainer = (instance, params) => {
8201 const container = getContainer();
8202 if (!container) {
8203 return;
8204 }
8205 handleBackdropParam(container, params.backdrop);
8206 handlePositionParam(container, params.position);
8207 handleGrowParam(container, params.grow);
8208
8209 // Custom class
8210 applyCustomClass(container, params, 'container');
8211 };
8212
8213 /**
8214 * @param {HTMLElement} container
8215 * @param {SweetAlertOptions['backdrop']} backdrop
8216 */
8217 function handleBackdropParam(container, backdrop) {
8218 if (typeof backdrop === 'string') {
8219 container.style.background = backdrop;
8220 } else if (!backdrop) {
8221 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
8222 }
8223 }
8224
8225 /**
8226 * @param {HTMLElement} container
8227 * @param {SweetAlertOptions['position']} position
8228 */
8229 function handlePositionParam(container, position) {
8230 if (!position) {
8231 return;
8232 }
8233 if (position in swalClasses) {
8234 addClass(container, swalClasses[position]);
8235 } else {
8236 warn('The "position" parameter is not valid, defaulting to "center"');
8237 addClass(container, swalClasses.center);
8238 }
8239 }
8240
8241 /**
8242 * @param {HTMLElement} container
8243 * @param {SweetAlertOptions['grow']} grow
8244 */
8245 function handleGrowParam(container, grow) {
8246 if (!grow) {
8247 return;
8248 }
8249 addClass(container, swalClasses[`grow-${grow}`]);
8250 }
8251
8252 /**
8253 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8254 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8255 * This is the approach that Babel will probably take to implement private methods/fields
8256 * https://github.com/tc39/proposal-private-methods
8257 * https://github.com/babel/babel/pull/7555
8258 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8259 * then we can use that language feature.
8260 */
8261
8262 var privateProps = {
8263 innerParams: new WeakMap(),
8264 domCache: new WeakMap(),
8265 focusedElement: new WeakMap()
8266 };
8267
8268 /// <reference path="../../../../sweetalert2.d.ts"/>
8269
8270
8271 /** @type {InputClass[]} */
8272 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
8273
8274 /**
8275 * @param {SweetAlert} instance
8276 * @param {SweetAlertOptions} params
8277 */
8278 const renderInput = (instance, params) => {
8279 const popup = getPopup();
8280 if (!popup) {
8281 return;
8282 }
8283 const innerParams = privateProps.innerParams.get(instance);
8284 const rerender = !innerParams || params.input !== innerParams.input;
8285 inputClasses.forEach(inputClass => {
8286 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
8287 if (!inputContainer) {
8288 return;
8289 }
8290
8291 // set attributes
8292 setAttributes(inputClass, params.inputAttributes);
8293
8294 // set class
8295 inputContainer.className = swalClasses[inputClass];
8296 if (rerender) {
8297 hide(inputContainer);
8298 }
8299 });
8300 if (params.input) {
8301 if (rerender) {
8302 showInput(params);
8303 }
8304 // set custom class
8305 setCustomClass(params);
8306 }
8307 };
8308
8309 /**
8310 * @param {SweetAlertOptions} params
8311 */
8312 const showInput = params => {
8313 if (!params.input) {
8314 return;
8315 }
8316 if (!renderInputType[params.input]) {
8317 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
8318 return;
8319 }
8320 const inputContainer = getInputContainer(params.input);
8321 if (!inputContainer) {
8322 return;
8323 }
8324 const input = renderInputType[params.input](inputContainer, params);
8325 show(inputContainer);
8326
8327 // input autofocus
8328 if (params.inputAutoFocus) {
8329 setTimeout(() => {
8330 focusInput(input);
8331 });
8332 }
8333 };
8334
8335 /**
8336 * @param {HTMLInputElement} input
8337 */
8338 const removeAttributes = input => {
8339 for (const {
8340 name
8341 } of Array.from(input.attributes)) {
8342 if (!['id', 'type', 'value', 'style'].includes(name)) {
8343 input.removeAttribute(name);
8344 }
8345 }
8346 };
8347
8348 /**
8349 * @param {InputClass} inputClass
8350 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
8351 */
8352 const setAttributes = (inputClass, inputAttributes) => {
8353 const popup = getPopup();
8354 if (!popup) {
8355 return;
8356 }
8357 const input = getInput$1(popup, inputClass);
8358 if (!input) {
8359 return;
8360 }
8361 removeAttributes(input);
8362 for (const attr in inputAttributes) {
8363 input.setAttribute(attr, inputAttributes[attr]);
8364 }
8365 };
8366
8367 /**
8368 * @param {SweetAlertOptions} params
8369 */
8370 const setCustomClass = params => {
8371 if (!params.input) {
8372 return;
8373 }
8374 const inputContainer = getInputContainer(params.input);
8375 if (inputContainer) {
8376 applyCustomClass(inputContainer, params, 'input');
8377 }
8378 };
8379
8380 /**
8381 * @param {HTMLInputElement | HTMLTextAreaElement} input
8382 * @param {SweetAlertOptions} params
8383 */
8384 const setInputPlaceholder = (input, params) => {
8385 if (!input.placeholder && params.inputPlaceholder) {
8386 input.placeholder = params.inputPlaceholder;
8387 }
8388 };
8389
8390 /**
8391 * @param {Input} input
8392 * @param {Input} prependTo
8393 * @param {SweetAlertOptions} params
8394 */
8395 const setInputLabel = (input, prependTo, params) => {
8396 if (params.inputLabel) {
8397 const label = document.createElement('label');
8398 const labelClass = swalClasses['input-label'];
8399 label.setAttribute('for', input.id);
8400 label.className = labelClass;
8401 if (typeof params.customClass === 'object') {
8402 addClass(label, params.customClass.inputLabel);
8403 }
8404 label.innerText = params.inputLabel;
8405 prependTo.insertAdjacentElement('beforebegin', label);
8406 }
8407 };
8408
8409 /**
8410 * @param {SweetAlertInput} inputType
8411 * @returns {HTMLElement | undefined}
8412 */
8413 const getInputContainer = inputType => {
8414 const popup = getPopup();
8415 if (!popup) {
8416 return;
8417 }
8418 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
8419 };
8420
8421 /**
8422 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
8423 * @param {SweetAlertOptions['inputValue']} inputValue
8424 */
8425 const checkAndSetInputValue = (input, inputValue) => {
8426 if (['string', 'number'].includes(typeof inputValue)) {
8427 input.value = `${inputValue}`;
8428 } else if (!isPromise(inputValue)) {
8429 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
8430 }
8431 };
8432
8433 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
8434 const renderInputType = {};
8435
8436 /**
8437 * @param {Input | HTMLElement} input
8438 * @param {SweetAlertOptions} params
8439 * @returns {Input}
8440 */
8441 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} */
8442 (input, params) => {
8443 // oxfmt-ignore
8444 const inputElement = /** @type {HTMLInputElement} */input;
8445 checkAndSetInputValue(inputElement, params.inputValue);
8446 setInputLabel(inputElement, inputElement, params);
8447 setInputPlaceholder(inputElement, params);
8448 // oxfmt-ignore
8449 inputElement.type = /** @type {string} */params.input;
8450 return inputElement;
8451 };
8452
8453 /**
8454 * @param {Input | HTMLElement} input
8455 * @param {SweetAlertOptions} params
8456 * @returns {Input}
8457 */
8458 renderInputType.file = (input, params) => {
8459 const inputElement = /** @type {HTMLInputElement} */input;
8460 setInputLabel(inputElement, inputElement, params);
8461 setInputPlaceholder(inputElement, params);
8462 return inputElement;
8463 };
8464
8465 /**
8466 * @param {Input | HTMLElement} range
8467 * @param {SweetAlertOptions} params
8468 * @returns {Input}
8469 */
8470 renderInputType.range = (range, params) => {
8471 const rangeContainer = /** @type {HTMLElement} */range;
8472 const rangeInput = rangeContainer.querySelector('input');
8473 const rangeOutput = rangeContainer.querySelector('output');
8474 if (rangeInput) {
8475 checkAndSetInputValue(rangeInput, params.inputValue);
8476 rangeInput.type = /** @type {string} */params.input;
8477 setInputLabel(rangeInput, /** @type {Input} */range, params);
8478 }
8479 if (rangeOutput) {
8480 checkAndSetInputValue(rangeOutput, params.inputValue);
8481 }
8482 return /** @type {Input} */range;
8483 };
8484
8485 /**
8486 * @param {Input | HTMLElement} select
8487 * @param {SweetAlertOptions} params
8488 * @returns {Input}
8489 */
8490 renderInputType.select = (select, params) => {
8491 const selectElement = /** @type {HTMLSelectElement} */select;
8492 selectElement.textContent = '';
8493 if (params.inputPlaceholder) {
8494 const placeholder = document.createElement('option');
8495 setInnerHtml(placeholder, params.inputPlaceholder);
8496 placeholder.value = '';
8497 placeholder.disabled = true;
8498 placeholder.selected = true;
8499 selectElement.appendChild(placeholder);
8500 }
8501 setInputLabel(selectElement, selectElement, params);
8502 return selectElement;
8503 };
8504
8505 /**
8506 * @param {Input | HTMLElement} radio
8507 * @returns {Input}
8508 */
8509 renderInputType.radio = radio => {
8510 const radioElement = /** @type {HTMLElement} */radio;
8511 radioElement.textContent = '';
8512 return /** @type {Input} */radio;
8513 };
8514
8515 /**
8516 * @param {Input | HTMLElement} checkboxContainer
8517 * @param {SweetAlertOptions} params
8518 * @returns {Input}
8519 */
8520 renderInputType.checkbox = (checkboxContainer, params) => {
8521 const popup = getPopup();
8522 if (!popup) {
8523 throw new Error('Popup not found');
8524 }
8525 const checkbox = getInput$1(popup, 'checkbox');
8526 if (!checkbox) {
8527 throw new Error('Checkbox input not found');
8528 }
8529 checkbox.value = '1';
8530 checkbox.checked = Boolean(params.inputValue);
8531 const containerElement = /** @type {HTMLElement} */checkboxContainer;
8532 const label = containerElement.querySelector('span');
8533 if (label) {
8534 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
8535 if (placeholderOrLabel) {
8536 setInnerHtml(label, placeholderOrLabel);
8537 }
8538 }
8539 return checkbox;
8540 };
8541
8542 /**
8543 * @param {Input | HTMLElement} textarea
8544 * @param {SweetAlertOptions} params
8545 * @returns {Input}
8546 */
8547 renderInputType.textarea = (textarea, params) => {
8548 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
8549 checkAndSetInputValue(textareaElement, params.inputValue);
8550 setInputPlaceholder(textareaElement, params);
8551 setInputLabel(textareaElement, textareaElement, params);
8552
8553 /**
8554 * @param {HTMLElement} el
8555 * @returns {number}
8556 */
8557 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
8558
8559 // https://github.com/sweetalert2/sweetalert2/issues/2291
8560 setTimeout(() => {
8561 // https://github.com/sweetalert2/sweetalert2/issues/1699
8562 if ('MutationObserver' in window) {
8563 const popup = getPopup();
8564 if (!popup) {
8565 return;
8566 }
8567 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
8568 const textareaResizeHandler = () => {
8569 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
8570 if (!document.body.contains(textareaElement)) {
8571 return;
8572 }
8573 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
8574 const popupElement = getPopup();
8575 if (popupElement) {
8576 if (textareaWidth > initialPopupWidth) {
8577 popupElement.style.width = `${textareaWidth}px`;
8578 } else {
8579 applyNumericalStyle(popupElement, 'width', params.width);
8580 }
8581 }
8582 };
8583 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
8584 attributes: true,
8585 attributeFilter: ['style']
8586 });
8587 }
8588 });
8589 return textareaElement;
8590 };
8591
8592 /**
8593 * @param {SweetAlert} instance
8594 * @param {SweetAlertOptions} params
8595 */
8596 const renderContent = (instance, params) => {
8597 const htmlContainer = getHtmlContainer();
8598 if (!htmlContainer) {
8599 return;
8600 }
8601 showWhenInnerHtmlPresent(htmlContainer);
8602 applyCustomClass(htmlContainer, params, 'htmlContainer');
8603
8604 // Content as HTML
8605 if (params.html) {
8606 parseHtmlToContainer(params.html, htmlContainer);
8607 show(htmlContainer, 'block');
8608 }
8609
8610 // Content as plain text
8611 else if (params.text) {
8612 htmlContainer.textContent = params.text;
8613 show(htmlContainer, 'block');
8614 }
8615
8616 // No content
8617 else {
8618 hide(htmlContainer);
8619 }
8620 renderInput(instance, params);
8621 };
8622
8623 /**
8624 * @param {SweetAlert} instance
8625 * @param {SweetAlertOptions} params
8626 */
8627 const renderFooter = (instance, params) => {
8628 const footer = getFooter();
8629 if (!footer) {
8630 return;
8631 }
8632 showWhenInnerHtmlPresent(footer);
8633 toggle(footer, Boolean(params.footer), 'block');
8634 if (params.footer) {
8635 parseHtmlToContainer(params.footer, footer);
8636 }
8637
8638 // Custom class
8639 applyCustomClass(footer, params, 'footer');
8640 };
8641
8642 /**
8643 * @param {SweetAlert} instance
8644 * @param {SweetAlertOptions} params
8645 */
8646 const renderIcon = (instance, params) => {
8647 const innerParams = privateProps.innerParams.get(instance);
8648 const icon = getIcon();
8649 if (!icon) {
8650 return;
8651 }
8652
8653 // if the given icon already rendered, apply the styling without re-rendering the icon
8654 if (innerParams && params.icon === innerParams.icon) {
8655 // Custom or default content
8656 setContent(icon, params);
8657 applyStyles(icon, params);
8658 return;
8659 }
8660 if (!params.icon && !params.iconHtml) {
8661 hide(icon);
8662 return;
8663 }
8664 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
8665 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
8666 hide(icon);
8667 return;
8668 }
8669 show(icon);
8670
8671 // Custom or default content
8672 setContent(icon, params);
8673 applyStyles(icon, params);
8674
8675 // Animate icon
8676 addClass(icon, params.showClass && params.showClass.icon);
8677
8678 // Re-adjust the success icon on system theme change
8679 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
8680 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
8681 };
8682
8683 /**
8684 * @param {HTMLElement} icon
8685 * @param {SweetAlertOptions} params
8686 */
8687 const applyStyles = (icon, params) => {
8688 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
8689 if (params.icon !== iconType) {
8690 removeClass(icon, iconClassName);
8691 }
8692 }
8693 addClass(icon, params.icon && iconTypes[params.icon]);
8694
8695 // Icon color
8696 setColor(icon, params);
8697
8698 // Success icon background color
8699 adjustSuccessIconBackgroundColor();
8700
8701 // Custom class
8702 applyCustomClass(icon, params, 'icon');
8703 };
8704
8705 // Adjust success icon background color to match the popup background color
8706 const adjustSuccessIconBackgroundColor = () => {
8707 const popup = getPopup();
8708 if (!popup) {
8709 return;
8710 }
8711 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
8712 /** @type {NodeListOf<HTMLElement>} */
8713 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
8714 successIconParts.forEach(part => {
8715 part.style.backgroundColor = popupBackgroundColor;
8716 });
8717 };
8718
8719 /**
8720 *
8721 * @param {SweetAlertOptions} params
8722 * @returns {string}
8723 */
8724 const successIconHtml = params => `
8725 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
8726 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
8727 <div class="swal2-success-ring"></div>
8728 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
8729 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
8730 `;
8731 const errorIconHtml = `
8732 <span class="swal2-x-mark">
8733 <span class="swal2-x-mark-line-left"></span>
8734 <span class="swal2-x-mark-line-right"></span>
8735 </span>
8736 `;
8737
8738 /**
8739 * @param {HTMLElement} icon
8740 * @param {SweetAlertOptions} params
8741 */
8742 const setContent = (icon, params) => {
8743 if (!params.icon && !params.iconHtml) {
8744 return;
8745 }
8746 let oldContent = icon.innerHTML;
8747 let newContent = '';
8748 if (params.iconHtml) {
8749 newContent = iconContent(params.iconHtml);
8750 } else if (params.icon === 'success') {
8751 newContent = successIconHtml(params);
8752 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
8753 } else if (params.icon === 'error') {
8754 newContent = errorIconHtml;
8755 } else if (params.icon) {
8756 const defaultIconHtml = {
8757 question: '?',
8758 warning: '!',
8759 info: 'i'
8760 };
8761 newContent = iconContent(defaultIconHtml[params.icon]);
8762 }
8763 if (oldContent.trim() !== newContent.trim()) {
8764 setInnerHtml(icon, newContent);
8765 }
8766 };
8767
8768 /**
8769 * @param {HTMLElement} icon
8770 * @param {SweetAlertOptions} params
8771 */
8772 const setColor = (icon, params) => {
8773 if (!params.iconColor) {
8774 return;
8775 }
8776 icon.style.color = params.iconColor;
8777 icon.style.borderColor = params.iconColor;
8778 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
8779 setStyle(icon, sel, 'background-color', params.iconColor);
8780 }
8781 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
8782 };
8783
8784 /**
8785 * @param {string} content
8786 * @returns {string}
8787 */
8788 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
8789
8790 /**
8791 * @param {SweetAlert} instance
8792 * @param {SweetAlertOptions} params
8793 */
8794 const renderImage = (instance, params) => {
8795 const image = getImage();
8796 if (!image) {
8797 return;
8798 }
8799 if (!params.imageUrl) {
8800 hide(image);
8801 return;
8802 }
8803 show(image, '');
8804
8805 // Src, alt
8806 image.setAttribute('src', params.imageUrl);
8807 image.setAttribute('alt', params.imageAlt || '');
8808
8809 // Width, height
8810 applyNumericalStyle(image, 'width', params.imageWidth);
8811 applyNumericalStyle(image, 'height', params.imageHeight);
8812
8813 // Class
8814 image.className = swalClasses.image;
8815 applyCustomClass(image, params, 'image');
8816 };
8817
8818 let dragging = false;
8819 let mousedownX = 0;
8820 let mousedownY = 0;
8821 let initialX = 0;
8822 let initialY = 0;
8823
8824 /**
8825 * @param {HTMLElement} popup
8826 */
8827 const addDraggableListeners = popup => {
8828 popup.addEventListener('mousedown', down);
8829 document.body.addEventListener('mousemove', move);
8830 popup.addEventListener('mouseup', up);
8831 popup.addEventListener('touchstart', down);
8832 document.body.addEventListener('touchmove', move);
8833 popup.addEventListener('touchend', up);
8834 };
8835
8836 /**
8837 * @param {HTMLElement} popup
8838 */
8839 const removeDraggableListeners = popup => {
8840 popup.removeEventListener('mousedown', down);
8841 document.body.removeEventListener('mousemove', move);
8842 popup.removeEventListener('mouseup', up);
8843 popup.removeEventListener('touchstart', down);
8844 document.body.removeEventListener('touchmove', move);
8845 popup.removeEventListener('touchend', up);
8846 };
8847
8848 /**
8849 * @param {MouseEvent | TouchEvent} event
8850 */
8851 const down = event => {
8852 const popup = getPopup();
8853 if (!popup) {
8854 return;
8855 }
8856 const icon = getIcon();
8857 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
8858 dragging = true;
8859 const clientXY = getClientXY(event);
8860 mousedownX = clientXY.clientX;
8861 mousedownY = clientXY.clientY;
8862 initialX = parseInt(popup.style.insetInlineStart) || 0;
8863 initialY = parseInt(popup.style.insetBlockStart) || 0;
8864 addClass(popup, 'swal2-dragging');
8865 }
8866 };
8867
8868 /**
8869 * @param {MouseEvent | TouchEvent} event
8870 */
8871 const move = event => {
8872 const popup = getPopup();
8873 if (!popup) {
8874 return;
8875 }
8876 if (dragging) {
8877 let {
8878 clientX,
8879 clientY
8880 } = getClientXY(event);
8881 const deltaX = clientX - mousedownX;
8882 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
8883 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
8884 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
8885 }
8886 };
8887 const up = () => {
8888 const popup = getPopup();
8889 dragging = false;
8890 removeClass(popup, 'swal2-dragging');
8891 };
8892
8893 /**
8894 * @param {MouseEvent | TouchEvent} event
8895 * @returns {{ clientX: number, clientY: number }}
8896 */
8897 const getClientXY = event => {
8898 const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
8899 return {
8900 clientX: source.clientX,
8901 clientY: source.clientY
8902 };
8903 };
8904
8905 /**
8906 * @param {SweetAlert} instance
8907 * @param {SweetAlertOptions} params
8908 */
8909 const renderPopup = (instance, params) => {
8910 const container = getContainer();
8911 const popup = getPopup();
8912 if (!container || !popup) {
8913 return;
8914 }
8915
8916 // Width
8917 // https://github.com/sweetalert2/sweetalert2/issues/2170
8918 if (params.toast) {
8919 applyNumericalStyle(container, 'width', params.width);
8920 popup.style.width = '100%';
8921 const loader = getLoader();
8922 if (loader) {
8923 popup.insertBefore(loader, getIcon());
8924 }
8925 } else {
8926 applyNumericalStyle(popup, 'width', params.width);
8927 }
8928
8929 // Padding
8930 applyNumericalStyle(popup, 'padding', params.padding);
8931
8932 // Color
8933 if (params.color) {
8934 popup.style.color = params.color;
8935 }
8936
8937 // Background
8938 if (params.background) {
8939 popup.style.background = params.background;
8940 }
8941 hide(getValidationMessage());
8942
8943 // Classes
8944 addClasses$1(popup, params);
8945 if (params.draggable && !params.toast) {
8946 addClass(popup, swalClasses.draggable);
8947 addDraggableListeners(popup);
8948 } else {
8949 removeClass(popup, swalClasses.draggable);
8950 removeDraggableListeners(popup);
8951 }
8952 };
8953
8954 /**
8955 * @param {HTMLElement} popup
8956 * @param {SweetAlertOptions} params
8957 */
8958 const addClasses$1 = (popup, params) => {
8959 const showClass = params.showClass || {};
8960 // Default Class + showClass when updating Swal.update({})
8961 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
8962 if (params.toast) {
8963 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
8964 addClass(popup, swalClasses.toast);
8965 } else {
8966 addClass(popup, swalClasses.modal);
8967 }
8968
8969 // Custom class
8970 applyCustomClass(popup, params, 'popup');
8971 // TODO: remove in the next major
8972 if (typeof params.customClass === 'string') {
8973 addClass(popup, params.customClass);
8974 }
8975
8976 // Icon class (#1842)
8977 if (params.icon) {
8978 addClass(popup, swalClasses[`icon-${params.icon}`]);
8979 }
8980 };
8981
8982 /**
8983 * @param {SweetAlert} instance
8984 * @param {SweetAlertOptions} params
8985 */
8986 const renderProgressSteps = (instance, params) => {
8987 const progressStepsContainer = getProgressSteps();
8988 if (!progressStepsContainer) {
8989 return;
8990 }
8991 const {
8992 progressSteps,
8993 currentProgressStep
8994 } = params;
8995 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
8996 hide(progressStepsContainer);
8997 return;
8998 }
8999 show(progressStepsContainer);
9000 progressStepsContainer.textContent = '';
9001 if (currentProgressStep >= progressSteps.length) {
9002 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
9003 }
9004 progressSteps.forEach((step, index) => {
9005 const stepEl = createStepElement(step);
9006 progressStepsContainer.appendChild(stepEl);
9007 if (index === currentProgressStep) {
9008 addClass(stepEl, swalClasses['active-progress-step']);
9009 }
9010 if (index !== progressSteps.length - 1) {
9011 const lineEl = createLineElement(params);
9012 progressStepsContainer.appendChild(lineEl);
9013 }
9014 });
9015 };
9016
9017 /**
9018 * @param {string} step
9019 * @returns {HTMLLIElement}
9020 */
9021 const createStepElement = step => {
9022 const stepEl = document.createElement('li');
9023 addClass(stepEl, swalClasses['progress-step']);
9024 setInnerHtml(stepEl, step);
9025 return stepEl;
9026 };
9027
9028 /**
9029 * @param {SweetAlertOptions} params
9030 * @returns {HTMLLIElement}
9031 */
9032 const createLineElement = params => {
9033 const lineEl = document.createElement('li');
9034 addClass(lineEl, swalClasses['progress-step-line']);
9035 if (params.progressStepsDistance) {
9036 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
9037 }
9038 return lineEl;
9039 };
9040
9041 /**
9042 * @param {SweetAlert} instance
9043 * @param {SweetAlertOptions} params
9044 */
9045 const renderTitle = (instance, params) => {
9046 const title = getTitle();
9047 if (!title) {
9048 return;
9049 }
9050 showWhenInnerHtmlPresent(title);
9051 toggle(title, Boolean(params.title || params.titleText), 'block');
9052 if (params.title) {
9053 parseHtmlToContainer(params.title, title);
9054 }
9055 if (params.titleText) {
9056 title.innerText = params.titleText;
9057 }
9058
9059 // Custom class
9060 applyCustomClass(title, params, 'title');
9061 };
9062
9063 /**
9064 * @param {SweetAlert} instance
9065 * @param {SweetAlertOptions} params
9066 */
9067 const render = (instance, params) => {
9068 var _globalState$eventEmi;
9069 renderPopup(instance, params);
9070 renderContainer(instance, params);
9071 renderProgressSteps(instance, params);
9072 renderIcon(instance, params);
9073 renderImage(instance, params);
9074 renderTitle(instance, params);
9075 renderCloseButton(instance, params);
9076 renderContent(instance, params);
9077 renderActions(instance, params);
9078 renderFooter(instance, params);
9079 const popup = getPopup();
9080 if (typeof params.didRender === 'function' && popup) {
9081 params.didRender(popup);
9082 }
9083 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
9084 };
9085
9086 /*
9087 * Global function to determine if SweetAlert2 popup is shown
9088 */
9089 const isVisible = () => {
9090 return isVisible$1(getPopup());
9091 };
9092
9093 /*
9094 * Global function to click 'Confirm' button
9095 */
9096 const clickConfirm = () => {
9097 var _dom$getConfirmButton;
9098 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
9099 };
9100
9101 /*
9102 * Global function to click 'Deny' button
9103 */
9104 const clickDeny = () => {
9105 var _dom$getDenyButton;
9106 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
9107 };
9108
9109 /*
9110 * Global function to click 'Cancel' button
9111 */
9112 const clickCancel = () => {
9113 var _dom$getCancelButton;
9114 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
9115 };
9116
9117 /** @type {Record<DismissReason, DismissReason>} */
9118 const DismissReason = Object.freeze({
9119 cancel: 'cancel',
9120 backdrop: 'backdrop',
9121 close: 'close',
9122 esc: 'esc',
9123 timer: 'timer'
9124 });
9125
9126 /**
9127 * @param {GlobalState} globalState
9128 */
9129 const removeKeydownHandler = globalState => {
9130 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
9131 const handler = /** @type {EventListenerOrEventListenerObject} */
9132 /** @type {unknown} */globalState.keydownHandler;
9133 globalState.keydownTarget.removeEventListener('keydown', handler, {
9134 capture: globalState.keydownListenerCapture
9135 });
9136 globalState.keydownHandlerAdded = false;
9137 }
9138 };
9139
9140 /**
9141 * @param {GlobalState} globalState
9142 * @param {SweetAlertOptions} innerParams
9143 * @param {(dismiss: DismissReason) => void} dismissWith
9144 */
9145 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
9146 removeKeydownHandler(globalState);
9147 if (!innerParams.toast) {
9148 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
9149 const handler = e => keydownHandler(innerParams, e, dismissWith);
9150 globalState.keydownHandler = handler;
9151 const target = innerParams.keydownListenerCapture ? window : getPopup();
9152 if (target) {
9153 globalState.keydownTarget = target;
9154 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
9155 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
9156 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
9157 capture: globalState.keydownListenerCapture
9158 });
9159 globalState.keydownHandlerAdded = true;
9160 }
9161 }
9162 };
9163
9164 /**
9165 * @param {number} index
9166 * @param {number} increment
9167 * @returns {boolean} shouldPreventDefault
9168 */
9169 const setFocus = (index, increment) => {
9170 var _dom$getPopup;
9171 const focusableElements = getFocusableElements();
9172 // search for visible elements and select the next possible match
9173 if (focusableElements.length) {
9174 index = index + increment;
9175
9176 // shift + tab when .swal2-popup is focused
9177 if (index === -2) {
9178 index = focusableElements.length - 1;
9179 }
9180
9181 // rollover to first item
9182 if (index === focusableElements.length) {
9183 index = 0;
9184
9185 // go to last item
9186 } else if (index === -1) {
9187 index = focusableElements.length - 1;
9188 }
9189 focusableElements[index].focus();
9190
9191 // don't prevent default for iframes (Firefox fix)
9192 // https://github.com/sweetalert2/sweetalert2/issues/2931
9193 if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
9194 return false;
9195 }
9196 return true;
9197 }
9198 // no visible focusable elements, focus the popup
9199 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
9200 return true;
9201 };
9202 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
9203 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
9204
9205 /**
9206 * @param {SweetAlertOptions} innerParams
9207 * @param {KeyboardEvent} event
9208 * @param {(dismiss: DismissReason) => void} dismissWith
9209 */
9210 const keydownHandler = (innerParams, event, dismissWith) => {
9211 if (!innerParams) {
9212 return; // This instance has already been destroyed
9213 }
9214
9215 // Ignore keydown during IME composition
9216 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
9217 // https://github.com/sweetalert2/sweetalert2/issues/720
9218 // https://github.com/sweetalert2/sweetalert2/issues/2406
9219 if (event.isComposing || event.keyCode === 229) {
9220 return;
9221 }
9222 if (innerParams.stopKeydownPropagation) {
9223 event.stopPropagation();
9224 }
9225
9226 // ENTER
9227 if (event.key === 'Enter') {
9228 handleEnter(event, innerParams);
9229 }
9230
9231 // TAB
9232 else if (event.key === 'Tab') {
9233 handleTab(event);
9234 }
9235
9236 // ARROWS - switch focus between buttons
9237 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
9238 handleArrows(event.key);
9239 }
9240
9241 // ESC
9242 else if (event.key === 'Escape') {
9243 handleEsc(event, innerParams, dismissWith);
9244 }
9245 };
9246
9247 /**
9248 * @param {KeyboardEvent} event
9249 * @param {SweetAlertOptions} innerParams
9250 */
9251 const handleEnter = (event, innerParams) => {
9252 // https://github.com/sweetalert2/sweetalert2/issues/2386
9253 if (!callIfFunction(innerParams.allowEnterKey)) {
9254 return;
9255 }
9256 const popup = getPopup();
9257 if (!popup || !innerParams.input) {
9258 return;
9259 }
9260 const input = getInput$1(popup, innerParams.input);
9261 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
9262 if (['textarea', 'file'].includes(innerParams.input)) {
9263 return; // do not submit
9264 }
9265 clickConfirm();
9266 event.preventDefault();
9267 }
9268 };
9269
9270 /**
9271 * @param {KeyboardEvent} event
9272 */
9273 const handleTab = event => {
9274 const targetElement = event.target;
9275 const focusableElements = getFocusableElements();
9276 const btnIndex = focusableElements.findIndex(el => el === targetElement);
9277
9278 // don't prevent default for iframes (Firefox fix)
9279 // https://github.com/sweetalert2/sweetalert2/issues/2931
9280 let shouldPreventDefault = true;
9281
9282 // Cycle to the next button
9283 if (!event.shiftKey) {
9284 shouldPreventDefault = setFocus(btnIndex, 1);
9285 }
9286
9287 // Cycle to the prev button
9288 else {
9289 shouldPreventDefault = setFocus(btnIndex, -1);
9290 }
9291 event.stopPropagation();
9292 if (shouldPreventDefault) {
9293 event.preventDefault();
9294 }
9295 };
9296
9297 /**
9298 * @param {string} key
9299 */
9300 const handleArrows = key => {
9301 const actions = getActions();
9302 const confirmButton = getConfirmButton();
9303 const denyButton = getDenyButton();
9304 const cancelButton = getCancelButton();
9305 if (!actions || !confirmButton || !denyButton || !cancelButton) {
9306 return;
9307 }
9308 /** @type HTMLElement[] */
9309 const buttons = [confirmButton, denyButton, cancelButton];
9310 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
9311 return;
9312 }
9313 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
9314 let buttonToFocus = document.activeElement;
9315 if (!buttonToFocus) {
9316 return;
9317 }
9318 for (let i = 0; i < actions.children.length; i++) {
9319 buttonToFocus = buttonToFocus[sibling];
9320 if (!buttonToFocus) {
9321 return;
9322 }
9323 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
9324 break;
9325 }
9326 }
9327 if (buttonToFocus instanceof HTMLButtonElement) {
9328 buttonToFocus.focus();
9329 }
9330 };
9331
9332 /**
9333 * @param {KeyboardEvent} event
9334 * @param {SweetAlertOptions} innerParams
9335 * @param {(dismiss: DismissReason) => void} dismissWith
9336 */
9337 const handleEsc = (event, innerParams, dismissWith) => {
9338 event.preventDefault();
9339 if (callIfFunction(innerParams.allowEscapeKey)) {
9340 dismissWith(DismissReason.esc);
9341 }
9342 };
9343
9344 /**
9345 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
9346 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
9347 * This is the approach that Babel will probably take to implement private methods/fields
9348 * https://github.com/tc39/proposal-private-methods
9349 * https://github.com/babel/babel/pull/7555
9350 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
9351 * then we can use that language feature.
9352 */
9353
9354 var privateMethods = {
9355 swalPromiseResolve: new WeakMap(),
9356 swalPromiseReject: new WeakMap()
9357 };
9358
9359 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
9360 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
9361 // elements not within the active modal dialog will not be surfaced if a user opens a screen
9362 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
9363
9364 const setAriaHidden = () => {
9365 const container = getContainer();
9366 const bodyChildren = Array.from(document.body.children);
9367 bodyChildren.forEach(el => {
9368 if (el.contains(container)) {
9369 return;
9370 }
9371 if (el.hasAttribute('aria-hidden')) {
9372 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
9373 }
9374 el.setAttribute('aria-hidden', 'true');
9375 });
9376 };
9377 const unsetAriaHidden = () => {
9378 const bodyChildren = Array.from(document.body.children);
9379 bodyChildren.forEach(el => {
9380 if (el.hasAttribute('data-previous-aria-hidden')) {
9381 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
9382 el.removeAttribute('data-previous-aria-hidden');
9383 } else {
9384 el.removeAttribute('aria-hidden');
9385 }
9386 });
9387 };
9388
9389 // @ts-ignore
9390 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
9391
9392 // @ts-ignore
9393 const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
9394
9395 /**
9396 * Fix iOS scrolling
9397 * http://stackoverflow.com/q/39626302
9398 */
9399 const iOSfix = () => {
9400 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
9401 const offset = document.body.scrollTop;
9402 document.body.style.top = `${offset * -1}px`;
9403 addClass(document.body, swalClasses.iosfix);
9404 lockBodyScroll();
9405 }
9406 };
9407
9408 /**
9409 * https://github.com/sweetalert2/sweetalert2/issues/1246
9410 */
9411 const lockBodyScroll = () => {
9412 const container = getContainer();
9413 if (!container) {
9414 return;
9415 }
9416 /** @type {boolean} */
9417 let preventTouchMove;
9418 /**
9419 * @param {TouchEvent} event
9420 */
9421 container.ontouchstart = event => {
9422 preventTouchMove = shouldPreventTouchMove(event);
9423 };
9424 /**
9425 * @param {TouchEvent} event
9426 */
9427 container.ontouchmove = event => {
9428 if (preventTouchMove) {
9429 event.preventDefault();
9430 event.stopPropagation();
9431 }
9432 };
9433 };
9434
9435 /**
9436 * @param {TouchEvent} event
9437 * @returns {boolean}
9438 */
9439 const shouldPreventTouchMove = event => {
9440 const target = event.target;
9441 const container = getContainer();
9442 const htmlContainer = getHtmlContainer();
9443 if (!container || !htmlContainer) {
9444 return false;
9445 }
9446 if (isStylus(event) || isZoom(event)) {
9447 return false;
9448 }
9449 if (target === container) {
9450 return true;
9451 }
9452 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
9453 // #2823
9454 target.tagName !== 'INPUT' &&
9455 // #1603
9456 target.tagName !== 'TEXTAREA' &&
9457 // #2266
9458 !(isScrollable(htmlContainer) &&
9459 // #1944
9460 htmlContainer.contains(target))) {
9461 return true;
9462 }
9463 return false;
9464 };
9465
9466 /**
9467 * https://github.com/sweetalert2/sweetalert2/issues/1786
9468 *
9469 * @param {TouchEvent} event
9470 * @returns {boolean}
9471 */
9472 const isStylus = event => {
9473 return Boolean(event.touches && event.touches.length &&
9474 // @ts-ignore - touchType is not a standard property
9475 event.touches[0].touchType === 'stylus');
9476 };
9477
9478 /**
9479 * https://github.com/sweetalert2/sweetalert2/issues/1891
9480 *
9481 * @param {TouchEvent} event
9482 * @returns {boolean}
9483 */
9484 const isZoom = event => {
9485 return event.touches && event.touches.length > 1;
9486 };
9487 const undoIOSfix = () => {
9488 if (hasClass(document.body, swalClasses.iosfix)) {
9489 const offset = parseInt(document.body.style.top, 10);
9490 removeClass(document.body, swalClasses.iosfix);
9491 document.body.style.top = '';
9492 document.body.scrollTop = offset * -1;
9493 }
9494 };
9495
9496 /**
9497 * Measure scrollbar width for padding body during modal show/hide
9498 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
9499 *
9500 * @returns {number}
9501 */
9502 const measureScrollbar = () => {
9503 const scrollDiv = document.createElement('div');
9504 scrollDiv.className = swalClasses['scrollbar-measure'];
9505 document.body.appendChild(scrollDiv);
9506 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
9507 document.body.removeChild(scrollDiv);
9508 return scrollbarWidth;
9509 };
9510
9511 /**
9512 * Remember state in cases where opening and handling a modal will fiddle with it.
9513 * @type {number | null}
9514 */
9515 let previousBodyPadding = null;
9516
9517 /**
9518 * @param {string} initialBodyOverflow
9519 */
9520 const replaceScrollbarWithPadding = initialBodyOverflow => {
9521 // for queues, do not do this more than once
9522 if (previousBodyPadding !== null) {
9523 return;
9524 }
9525 // if the body has overflow
9526 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
9527 ) {
9528 // add padding so the content doesn't shift after removal of scrollbar
9529 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
9530 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
9531 }
9532 };
9533 const undoReplaceScrollbarWithPadding = () => {
9534 if (previousBodyPadding !== null) {
9535 document.body.style.paddingRight = `${previousBodyPadding}px`;
9536 previousBodyPadding = null;
9537 }
9538 };
9539
9540 /**
9541 * @param {SweetAlert} instance
9542 * @param {HTMLElement} container
9543 * @param {boolean} returnFocus
9544 * @param {(() => void) | undefined} didClose
9545 */
9546 function removePopupAndResetState(instance, container, returnFocus, didClose) {
9547 if (isToast()) {
9548 triggerDidCloseAndDispose(instance, didClose);
9549 } else {
9550 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
9551 removeKeydownHandler(globalState);
9552 }
9553
9554 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
9555 // for some reason removing the container in Safari will scroll the document to bottom
9556 if (isSafariOrIOS) {
9557 container.setAttribute('style', 'display:none !important');
9558 container.removeAttribute('class');
9559 container.innerHTML = '';
9560 } else {
9561 container.remove();
9562 }
9563 if (isModal()) {
9564 undoReplaceScrollbarWithPadding();
9565 undoIOSfix();
9566 unsetAriaHidden();
9567 }
9568 removeBodyClasses();
9569 }
9570
9571 /**
9572 * Remove SweetAlert2 classes from body
9573 */
9574 function removeBodyClasses() {
9575 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
9576 }
9577
9578 /**
9579 * Instance method to close sweetAlert
9580 *
9581 * @param {SweetAlertResult | undefined} resolveValue
9582 * @this {SweetAlert}
9583 */
9584 function close(resolveValue) {
9585 resolveValue = prepareResolveValue(resolveValue);
9586 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
9587 const didClose = triggerClosePopup(this);
9588 if (this.isAwaitingPromise) {
9589 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
9590 if (!resolveValue.isDismissed) {
9591 handleAwaitingPromise(this);
9592 swalPromiseResolve(resolveValue);
9593 }
9594 } else if (didClose) {
9595 // Resolve Swal promise
9596 swalPromiseResolve(resolveValue);
9597 }
9598 }
9599
9600 /**
9601 * @param {SweetAlert} instance
9602 * @returns {boolean}
9603 */
9604 const triggerClosePopup = instance => {
9605 const popup = getPopup();
9606 if (!popup) {
9607 return false;
9608 }
9609 const innerParams = privateProps.innerParams.get(instance);
9610 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
9611 return false;
9612 }
9613 removeClass(popup, innerParams.showClass.popup);
9614 addClass(popup, innerParams.hideClass.popup);
9615 const backdrop = getContainer();
9616 removeClass(backdrop, innerParams.showClass.backdrop);
9617 addClass(backdrop, innerParams.hideClass.backdrop);
9618 handlePopupAnimation(instance, popup, innerParams);
9619 return true;
9620 };
9621
9622 /**
9623 * @param {Error | string} error
9624 * @this {SweetAlert}
9625 */
9626 function rejectPromise(error) {
9627 const rejectPromise = privateMethods.swalPromiseReject.get(this);
9628 handleAwaitingPromise(this);
9629 if (rejectPromise) {
9630 // Reject Swal promise
9631 rejectPromise(error);
9632 }
9633 }
9634
9635 /**
9636 * @param {SweetAlert} instance
9637 */
9638 const handleAwaitingPromise = instance => {
9639 if (instance.isAwaitingPromise) {
9640 // @ts-ignore
9641 delete instance.isAwaitingPromise;
9642 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
9643 if (!privateProps.innerParams.get(instance)) {
9644 instance._destroy();
9645 }
9646 }
9647 };
9648
9649 /**
9650 * @param {SweetAlertResult | undefined} resolveValue
9651 * @returns {SweetAlertResult}
9652 */
9653 const prepareResolveValue = resolveValue => {
9654 // When user calls Swal.close()
9655 if (typeof resolveValue === 'undefined') {
9656 return {
9657 isConfirmed: false,
9658 isDenied: false,
9659 isDismissed: true
9660 };
9661 }
9662 return Object.assign({
9663 isConfirmed: false,
9664 isDenied: false,
9665 isDismissed: false
9666 }, resolveValue);
9667 };
9668
9669 /**
9670 * @param {SweetAlert} instance
9671 * @param {HTMLElement} popup
9672 * @param {SweetAlertOptions} innerParams
9673 */
9674 const handlePopupAnimation = (instance, popup, innerParams) => {
9675 var _globalState$eventEmi;
9676 const container = getContainer();
9677 // If animation is supported, animate
9678 const animationIsSupported = hasCssAnimation(popup);
9679 if (typeof innerParams.willClose === 'function') {
9680 innerParams.willClose(popup);
9681 }
9682 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
9683 if (animationIsSupported && container) {
9684 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
9685 } else if (container) {
9686 // Otherwise, remove immediately
9687 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
9688 }
9689 };
9690
9691 /**
9692 * @param {SweetAlert} instance
9693 * @param {HTMLElement} popup
9694 * @param {HTMLElement} container
9695 * @param {boolean} returnFocus
9696 * @param {(() => void) | undefined} didClose
9697 */
9698 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
9699 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
9700 /**
9701 * @param {AnimationEvent | TransitionEvent} e
9702 */
9703 const swalCloseAnimationFinished = function (e) {
9704 if (e.target === popup) {
9705 var _globalState$swalClos;
9706 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
9707 delete globalState.swalCloseEventFinishedCallback;
9708 popup.removeEventListener('animationend', swalCloseAnimationFinished);
9709 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
9710 }
9711 };
9712 popup.addEventListener('animationend', swalCloseAnimationFinished);
9713 popup.addEventListener('transitionend', swalCloseAnimationFinished);
9714 };
9715
9716 /**
9717 * @param {SweetAlert} instance
9718 * @param {(() => void) | undefined} didClose
9719 */
9720 const triggerDidCloseAndDispose = (instance, didClose) => {
9721 setTimeout(() => {
9722 var _globalState$eventEmi2;
9723 if (typeof didClose === 'function') {
9724 didClose.bind(instance.params)();
9725 }
9726 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
9727 // instance might have been destroyed already
9728 if (instance._destroy) {
9729 instance._destroy();
9730 }
9731 });
9732 };
9733
9734 /**
9735 * Shows loader (spinner), this is useful with AJAX requests.
9736 * By default the loader be shown instead of the "Confirm" button.
9737 *
9738 * @param {HTMLButtonElement | null} [buttonToReplace]
9739 */
9740 const showLoading = buttonToReplace => {
9741 let popup = getPopup();
9742 if (!popup) {
9743 new Swal();
9744 }
9745 popup = getPopup();
9746 if (!popup) {
9747 return;
9748 }
9749 const loader = getLoader();
9750 if (isToast()) {
9751 hide(getIcon());
9752 } else {
9753 replaceButton(popup, buttonToReplace);
9754 }
9755 show(loader);
9756 popup.setAttribute('data-loading', 'true');
9757 popup.setAttribute('aria-busy', 'true');
9758 popup.focus();
9759 };
9760
9761 /**
9762 * @param {HTMLElement} popup
9763 * @param {HTMLButtonElement | null} [buttonToReplace]
9764 */
9765 const replaceButton = (popup, buttonToReplace) => {
9766 const actions = getActions();
9767 const loader = getLoader();
9768 if (!actions || !loader) {
9769 return;
9770 }
9771 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
9772 buttonToReplace = getConfirmButton();
9773 }
9774 show(actions);
9775 if (buttonToReplace) {
9776 hide(buttonToReplace);
9777 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
9778 actions.insertBefore(loader, buttonToReplace);
9779 }
9780 addClass([popup, actions], swalClasses.loading);
9781 };
9782
9783 /**
9784 * @param {SweetAlert} instance
9785 * @param {SweetAlertOptions} params
9786 */
9787 const handleInputOptionsAndValue = (instance, params) => {
9788 if (params.input === 'select' || params.input === 'radio') {
9789 handleInputOptions(instance, params);
9790 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
9791 showLoading(getConfirmButton());
9792 handleInputValue(instance, params);
9793 }
9794 };
9795
9796 /**
9797 * @param {SweetAlert} instance
9798 * @param {SweetAlertOptions} innerParams
9799 * @returns {SweetAlertInputValue}
9800 */
9801 const getInputValue = (instance, innerParams) => {
9802 const input = instance.getInput();
9803 if (!input) {
9804 return null;
9805 }
9806 switch (innerParams.input) {
9807 case 'checkbox':
9808 return getCheckboxValue(input);
9809 case 'radio':
9810 return getRadioValue(input);
9811 case 'file':
9812 return getFileValue(input);
9813 default:
9814 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
9815 }
9816 };
9817
9818 /**
9819 * @param {HTMLInputElement} input
9820 * @returns {number}
9821 */
9822 const getCheckboxValue = input => input.checked ? 1 : 0;
9823
9824 /**
9825 * @param {HTMLInputElement} input
9826 * @returns {string | null}
9827 */
9828 const getRadioValue = input => input.checked ? input.value : null;
9829
9830 /**
9831 * @param {HTMLInputElement} input
9832 * @returns {FileList | File | null}
9833 */
9834 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
9835
9836 /**
9837 * @param {SweetAlert} instance
9838 * @param {SweetAlertOptions} params
9839 */
9840 const handleInputOptions = (instance, params) => {
9841 const popup = getPopup();
9842 if (!popup) {
9843 return;
9844 }
9845 /**
9846 * @param {*} inputOptions
9847 */
9848 const processInputOptions = inputOptions => {
9849 if (params.input === 'select') {
9850 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
9851 } else if (params.input === 'radio') {
9852 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
9853 }
9854 };
9855 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
9856 showLoading(getConfirmButton());
9857 asPromise(params.inputOptions).then(inputOptions => {
9858 instance.hideLoading();
9859 processInputOptions(inputOptions);
9860 });
9861 } else if (typeof params.inputOptions === 'object') {
9862 processInputOptions(params.inputOptions);
9863 } else {
9864 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
9865 }
9866 };
9867
9868 /**
9869 * @param {SweetAlert} instance
9870 * @param {SweetAlertOptions} params
9871 */
9872 const handleInputValue = (instance, params) => {
9873 const input = instance.getInput();
9874 if (!input) {
9875 return;
9876 }
9877 hide(input);
9878 asPromise(params.inputValue).then(inputValue => {
9879 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
9880 show(input);
9881 input.focus();
9882 instance.hideLoading();
9883 }).catch(err => {
9884 error(`Error in inputValue promise: ${err}`);
9885 input.value = '';
9886 show(input);
9887 input.focus();
9888 instance.hideLoading();
9889 });
9890 };
9891
9892 /**
9893 * @param {HTMLElement} popup
9894 * @param {InputOptionFlattened[]} inputOptions
9895 * @param {SweetAlertOptions} params
9896 */
9897 function populateSelectOptions(popup, inputOptions, params) {
9898 const select = getDirectChildByClass(popup, swalClasses.select);
9899 if (!select) {
9900 return;
9901 }
9902 /**
9903 * @param {HTMLElement} parent
9904 * @param {string} optionLabel
9905 * @param {string} optionValue
9906 */
9907 const renderOption = (parent, optionLabel, optionValue) => {
9908 const option = document.createElement('option');
9909 option.value = optionValue;
9910 setInnerHtml(option, optionLabel);
9911 option.selected = isSelected(optionValue, params.inputValue);
9912 parent.appendChild(option);
9913 };
9914 inputOptions.forEach(inputOption => {
9915 const optionValue = inputOption[0];
9916 const optionLabel = inputOption[1];
9917 // <optgroup> spec:
9918 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
9919 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
9920 // check whether this is a <optgroup>
9921 if (Array.isArray(optionLabel)) {
9922 // if it is an array, then it is an <optgroup>
9923 const optgroup = document.createElement('optgroup');
9924 optgroup.label = optionValue;
9925 optgroup.disabled = false; // not configurable for now
9926 select.appendChild(optgroup);
9927 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
9928 } else {
9929 // case of <option>
9930 renderOption(select, optionLabel, optionValue);
9931 }
9932 });
9933 select.focus();
9934 }
9935
9936 /**
9937 * @param {HTMLElement} popup
9938 * @param {InputOptionFlattened[]} inputOptions
9939 * @param {SweetAlertOptions} params
9940 */
9941 function populateRadioOptions(popup, inputOptions, params) {
9942 const radio = getDirectChildByClass(popup, swalClasses.radio);
9943 if (!radio) {
9944 return;
9945 }
9946 inputOptions.forEach(inputOption => {
9947 const radioValue = inputOption[0];
9948 const radioLabel = inputOption[1];
9949 const radioInput = document.createElement('input');
9950 const radioLabelElement = document.createElement('label');
9951 radioInput.type = 'radio';
9952 radioInput.name = swalClasses.radio;
9953 radioInput.value = radioValue;
9954 if (isSelected(radioValue, params.inputValue)) {
9955 radioInput.checked = true;
9956 }
9957 const label = document.createElement('span');
9958 setInnerHtml(label, radioLabel);
9959 label.className = swalClasses.label;
9960 radioLabelElement.appendChild(radioInput);
9961 radioLabelElement.appendChild(label);
9962 radio.appendChild(radioLabelElement);
9963 });
9964 const radios = radio.querySelectorAll('input');
9965 if (radios.length) {
9966 radios[0].focus();
9967 }
9968 }
9969
9970 /**
9971 * Converts `inputOptions` into an array of `[value, label]`s
9972 *
9973 * @param {*} inputOptions
9974 * @typedef {string[]} InputOptionFlattened
9975 * @returns {InputOptionFlattened[]}
9976 */
9977 const formatInputOptions = inputOptions => {
9978 const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
9979 return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
9980 };
9981
9982 /**
9983 * @param {string} optionValue
9984 * @param {SweetAlertInputValue} inputValue
9985 * @returns {boolean}
9986 */
9987 const isSelected = (optionValue, inputValue) => Boolean(inputValue) && inputValue != null && inputValue.toString() === optionValue.toString();
9988
9989 /**
9990 * @param {SweetAlert} instance
9991 */
9992 const handleConfirmButtonClick = instance => {
9993 const innerParams = privateProps.innerParams.get(instance);
9994 instance.disableButtons();
9995 if (innerParams.input) {
9996 handleConfirmOrDenyWithInput(instance, 'confirm');
9997 } else {
9998 confirm(instance, true);
9999 }
10000 };
10001
10002 /**
10003 * @param {SweetAlert} instance
10004 */
10005 const handleDenyButtonClick = instance => {
10006 const innerParams = privateProps.innerParams.get(instance);
10007 instance.disableButtons();
10008 if (innerParams.returnInputValueOnDeny) {
10009 handleConfirmOrDenyWithInput(instance, 'deny');
10010 } else {
10011 deny(instance, false);
10012 }
10013 };
10014
10015 /**
10016 * @param {SweetAlert} instance
10017 * @param {(dismiss: DismissReason) => void} dismissWith
10018 */
10019 const handleCancelButtonClick = (instance, dismissWith) => {
10020 instance.disableButtons();
10021 dismissWith(DismissReason.cancel);
10022 };
10023
10024 /**
10025 * @param {SweetAlert} instance
10026 * @param {'confirm' | 'deny'} type
10027 */
10028 const handleConfirmOrDenyWithInput = (instance, type) => {
10029 const innerParams = privateProps.innerParams.get(instance);
10030 if (!innerParams.input) {
10031 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
10032 return;
10033 }
10034 const input = instance.getInput();
10035 const inputValue = getInputValue(instance, innerParams);
10036 if (innerParams.inputValidator) {
10037 handleInputValidator(instance, inputValue, type);
10038 } else if (input && !input.checkValidity()) {
10039 instance.enableButtons();
10040 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
10041 } else if (type === 'deny') {
10042 deny(instance, inputValue);
10043 } else {
10044 confirm(instance, inputValue);
10045 }
10046 };
10047
10048 /**
10049 * @param {SweetAlert} instance
10050 * @param {SweetAlertInputValue} inputValue
10051 * @param {'confirm' | 'deny'} type
10052 */
10053 const handleInputValidator = (instance, inputValue, type) => {
10054 const innerParams = privateProps.innerParams.get(instance);
10055 instance.disableInput();
10056 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
10057 validationPromise.then(validationMessage => {
10058 instance.enableButtons();
10059 instance.enableInput();
10060 if (validationMessage) {
10061 instance.showValidationMessage(validationMessage);
10062 } else if (type === 'deny') {
10063 deny(instance, inputValue);
10064 } else {
10065 confirm(instance, inputValue);
10066 }
10067 });
10068 };
10069
10070 /**
10071 * @param {SweetAlert} instance
10072 * @param {*} value
10073 */
10074 const deny = (instance, value) => {
10075 const innerParams = privateProps.innerParams.get(instance);
10076 if (innerParams.showLoaderOnDeny) {
10077 showLoading(getDenyButton());
10078 }
10079 if (innerParams.preDeny) {
10080 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
10081 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
10082 preDenyPromise.then(preDenyValue => {
10083 if (preDenyValue === false) {
10084 instance.hideLoading();
10085 handleAwaitingPromise(instance);
10086 } else {
10087 instance.close(/** @type SweetAlertResult */{
10088 isDenied: true,
10089 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
10090 });
10091 }
10092 }).catch(error => rejectWith(instance, error));
10093 } else {
10094 instance.close(/** @type SweetAlertResult */{
10095 isDenied: true,
10096 value
10097 });
10098 }
10099 };
10100
10101 /**
10102 * @param {SweetAlert} instance
10103 * @param {*} value
10104 */
10105 const succeedWith = (instance, value) => {
10106 instance.close(/** @type SweetAlertResult */{
10107 isConfirmed: true,
10108 value
10109 });
10110 };
10111
10112 /**
10113 *
10114 * @param {SweetAlert} instance
10115 * @param {string} error
10116 */
10117 const rejectWith = (instance, error) => {
10118 instance.rejectPromise(error);
10119 };
10120
10121 /**
10122 *
10123 * @param {SweetAlert} instance
10124 * @param {*} value
10125 */
10126 const confirm = (instance, value) => {
10127 const innerParams = privateProps.innerParams.get(instance);
10128 if (innerParams.showLoaderOnConfirm) {
10129 showLoading();
10130 }
10131 if (innerParams.preConfirm) {
10132 instance.resetValidationMessage();
10133 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
10134 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
10135 preConfirmPromise.then(preConfirmValue => {
10136 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
10137 instance.hideLoading();
10138 handleAwaitingPromise(instance);
10139 } else {
10140 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
10141 }
10142 }).catch(error => rejectWith(instance, error));
10143 } else {
10144 succeedWith(instance, value);
10145 }
10146 };
10147
10148 /**
10149 * Hides loader and shows back the button which was hidden by .showLoading()
10150 * @this {SweetAlert}
10151 */
10152 function hideLoading() {
10153 // do nothing if popup is closed
10154 const innerParams = privateProps.innerParams.get(this);
10155 if (!innerParams) {
10156 return;
10157 }
10158 const domCache = privateProps.domCache.get(this);
10159 hide(domCache.loader);
10160 if (isToast()) {
10161 if (innerParams.icon) {
10162 show(getIcon());
10163 }
10164 } else {
10165 showRelatedButton(domCache);
10166 }
10167 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
10168 domCache.popup.removeAttribute('aria-busy');
10169 domCache.popup.removeAttribute('data-loading');
10170 this.enableButtons();
10171 }
10172
10173 /**
10174 * @param {DomCache} domCache
10175 */
10176 const showRelatedButton = domCache => {
10177 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
10178 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
10179 if (buttonToReplace.length) {
10180 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
10181 } else if (allButtonsAreHidden()) {
10182 hide(domCache.actions);
10183 }
10184 };
10185
10186 /**
10187 * Gets the input DOM node, this method works with input parameter.
10188 *
10189 * @returns {HTMLInputElement | null}
10190 * @this {SweetAlert}
10191 */
10192 function getInput() {
10193 const innerParams = privateProps.innerParams.get(this);
10194 const domCache = privateProps.domCache.get(this);
10195 if (!domCache) {
10196 return null;
10197 }
10198 return getInput$1(domCache.popup, innerParams.input);
10199 }
10200
10201 /**
10202 * @param {SweetAlert} instance
10203 * @param {string[]} buttons
10204 * @param {boolean} disabled
10205 */
10206 function setButtonsDisabled(instance, buttons, disabled) {
10207 const domCache = privateProps.domCache.get(instance);
10208 buttons.forEach(button => {
10209 domCache[button].disabled = disabled;
10210 });
10211 }
10212
10213 /**
10214 * @param {HTMLInputElement | null} input
10215 * @param {boolean} disabled
10216 */
10217 function setInputDisabled(input, disabled) {
10218 const popup = getPopup();
10219 if (!popup || !input) {
10220 return;
10221 }
10222 if (input.type === 'radio') {
10223 /** @type {NodeListOf<HTMLInputElement>} */
10224 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
10225 radios.forEach(radio => {
10226 radio.disabled = disabled;
10227 });
10228 } else {
10229 input.disabled = disabled;
10230 }
10231 }
10232
10233 /**
10234 * Enable all the buttons
10235 * @this {SweetAlert}
10236 */
10237 function enableButtons() {
10238 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
10239 const focusedElement = privateProps.focusedElement.get(this);
10240 if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
10241 focusedElement.focus();
10242 }
10243 privateProps.focusedElement.delete(this);
10244 }
10245
10246 /**
10247 * Disable all the buttons
10248 * @this {SweetAlert}
10249 */
10250 function disableButtons() {
10251 privateProps.focusedElement.set(this, document.activeElement);
10252 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
10253 }
10254
10255 /**
10256 * Enable the input field
10257 * @this {SweetAlert}
10258 */
10259 function enableInput() {
10260 setInputDisabled(this.getInput(), false);
10261 }
10262
10263 /**
10264 * Disable the input field
10265 * @this {SweetAlert}
10266 */
10267 function disableInput() {
10268 setInputDisabled(this.getInput(), true);
10269 }
10270
10271 /**
10272 * Show block with validation message
10273 *
10274 * @param {string} error
10275 * @this {SweetAlert}
10276 */
10277 function showValidationMessage(error) {
10278 const domCache = privateProps.domCache.get(this);
10279 const params = privateProps.innerParams.get(this);
10280 setInnerHtml(domCache.validationMessage, error);
10281 domCache.validationMessage.className = swalClasses['validation-message'];
10282 if (params.customClass && params.customClass.validationMessage) {
10283 addClass(domCache.validationMessage, params.customClass.validationMessage);
10284 }
10285 show(domCache.validationMessage);
10286 const input = this.getInput();
10287 if (input) {
10288 input.setAttribute('aria-invalid', 'true');
10289 input.setAttribute('aria-describedby', swalClasses['validation-message']);
10290 focusInput(input);
10291 addClass(input, swalClasses.inputerror);
10292 }
10293 }
10294
10295 /**
10296 * Hide block with validation message
10297 *
10298 * @this {SweetAlert}
10299 */
10300 function resetValidationMessage() {
10301 const domCache = privateProps.domCache.get(this);
10302 if (domCache.validationMessage) {
10303 hide(domCache.validationMessage);
10304 }
10305 const input = this.getInput();
10306 if (input) {
10307 input.removeAttribute('aria-invalid');
10308 input.removeAttribute('aria-describedby');
10309 removeClass(input, swalClasses.inputerror);
10310 }
10311 }
10312
10313 const defaultParams = {
10314 title: '',
10315 titleText: '',
10316 text: '',
10317 html: '',
10318 footer: '',
10319 icon: undefined,
10320 iconColor: undefined,
10321 iconHtml: undefined,
10322 template: undefined,
10323 toast: false,
10324 draggable: false,
10325 animation: true,
10326 theme: 'light',
10327 showClass: {
10328 popup: 'swal2-show',
10329 backdrop: 'swal2-backdrop-show',
10330 icon: 'swal2-icon-show'
10331 },
10332 hideClass: {
10333 popup: 'swal2-hide',
10334 backdrop: 'swal2-backdrop-hide',
10335 icon: 'swal2-icon-hide'
10336 },
10337 customClass: {},
10338 target: 'body',
10339 color: undefined,
10340 backdrop: true,
10341 heightAuto: true,
10342 allowOutsideClick: true,
10343 allowEscapeKey: true,
10344 allowEnterKey: true,
10345 stopKeydownPropagation: true,
10346 keydownListenerCapture: false,
10347 showConfirmButton: true,
10348 showDenyButton: false,
10349 showCancelButton: false,
10350 preConfirm: undefined,
10351 preDeny: undefined,
10352 confirmButtonText: 'OK',
10353 confirmButtonAriaLabel: '',
10354 confirmButtonColor: undefined,
10355 denyButtonText: 'No',
10356 denyButtonAriaLabel: '',
10357 denyButtonColor: undefined,
10358 cancelButtonText: 'Cancel',
10359 cancelButtonAriaLabel: '',
10360 cancelButtonColor: undefined,
10361 buttonsStyling: true,
10362 reverseButtons: false,
10363 focusConfirm: true,
10364 focusDeny: false,
10365 focusCancel: false,
10366 returnFocus: true,
10367 showCloseButton: false,
10368 closeButtonHtml: '&times;',
10369 closeButtonAriaLabel: 'Close this dialog',
10370 loaderHtml: '',
10371 showLoaderOnConfirm: false,
10372 showLoaderOnDeny: false,
10373 imageUrl: undefined,
10374 imageWidth: undefined,
10375 imageHeight: undefined,
10376 imageAlt: '',
10377 timer: undefined,
10378 timerProgressBar: false,
10379 width: undefined,
10380 padding: undefined,
10381 background: undefined,
10382 input: undefined,
10383 inputPlaceholder: '',
10384 inputLabel: '',
10385 inputValue: '',
10386 inputOptions: {},
10387 inputAutoFocus: true,
10388 inputAutoTrim: true,
10389 inputAttributes: {},
10390 inputValidator: undefined,
10391 returnInputValueOnDeny: false,
10392 validationMessage: undefined,
10393 grow: false,
10394 position: 'center',
10395 progressSteps: [],
10396 currentProgressStep: undefined,
10397 progressStepsDistance: undefined,
10398 willOpen: undefined,
10399 didOpen: undefined,
10400 didRender: undefined,
10401 willClose: undefined,
10402 didClose: undefined,
10403 didDestroy: undefined,
10404 scrollbarPadding: true,
10405 topLayer: false
10406 };
10407 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'];
10408
10409 /** @type {Record<string, string | undefined>} */
10410 const deprecatedParams = {
10411 allowEnterKey: undefined
10412 };
10413 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
10414
10415 /**
10416 * Is valid parameter
10417 *
10418 * @param {string} paramName
10419 * @returns {boolean}
10420 */
10421 const isValidParameter = paramName => {
10422 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
10423 };
10424
10425 /**
10426 * Is valid parameter for Swal.update() method
10427 *
10428 * @param {string} paramName
10429 * @returns {boolean}
10430 */
10431 const isUpdatableParameter = paramName => {
10432 return updatableParams.indexOf(paramName) !== -1;
10433 };
10434
10435 /**
10436 * Is deprecated parameter
10437 *
10438 * @param {string} paramName
10439 * @returns {string | undefined}
10440 */
10441 const isDeprecatedParameter = paramName => {
10442 return deprecatedParams[paramName];
10443 };
10444
10445 /**
10446 * @param {string} param
10447 */
10448 const checkIfParamIsValid = param => {
10449 if (!isValidParameter(param)) {
10450 warn(`Unknown parameter "${param}"`);
10451 }
10452 };
10453
10454 /**
10455 * @param {string} param
10456 */
10457 const checkIfToastParamIsValid = param => {
10458 if (toastIncompatibleParams.includes(param)) {
10459 warn(`The parameter "${param}" is incompatible with toasts`);
10460 }
10461 };
10462
10463 /**
10464 * @param {string} param
10465 */
10466 const checkIfParamIsDeprecated = param => {
10467 const isDeprecated = isDeprecatedParameter(param);
10468 if (isDeprecated) {
10469 warnAboutDeprecation(param, isDeprecated);
10470 }
10471 };
10472
10473 /**
10474 * Show relevant warnings for given params
10475 *
10476 * @param {SweetAlertOptions} params
10477 */
10478 const showWarningsForParams = params => {
10479 if (params.backdrop === false && params.allowOutsideClick) {
10480 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
10481 }
10482 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)) {
10483 warn(`Invalid theme "${params.theme}"`);
10484 }
10485 for (const param in params) {
10486 checkIfParamIsValid(param);
10487 if (params.toast) {
10488 checkIfToastParamIsValid(param);
10489 }
10490 checkIfParamIsDeprecated(param);
10491 }
10492 };
10493
10494 /**
10495 * Updates popup parameters.
10496 *
10497 * @this {any}
10498 * @param {SweetAlertOptions} params
10499 */
10500 function update(params) {
10501 const container = getContainer();
10502 const popup = getPopup();
10503 const innerParams = privateProps.innerParams.get(this);
10504 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
10505 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.`);
10506 return;
10507 }
10508 const validUpdatableParams = filterValidParams(params);
10509 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
10510 showWarningsForParams(updatedParams);
10511 if (container) {
10512 container.dataset['swal2Theme'] = updatedParams.theme;
10513 }
10514 render(this, updatedParams);
10515 privateProps.innerParams.set(this, updatedParams);
10516 Object.defineProperties(this, {
10517 params: {
10518 value: Object.assign({}, this.params, params),
10519 writable: false,
10520 enumerable: true
10521 }
10522 });
10523 }
10524
10525 /**
10526 * @param {SweetAlertOptions} params
10527 * @returns {SweetAlertOptions}
10528 */
10529 const filterValidParams = params => {
10530 /** @type {Record<string, any>} */
10531 const validUpdatableParams = {};
10532 Object.keys(params).forEach(param => {
10533 if (isUpdatableParameter(param)) {
10534 const typedParams = /** @type {Record<string, any>} */params;
10535 validUpdatableParams[param] = typedParams[param];
10536 } else {
10537 warn(`Invalid parameter to update: ${param}`);
10538 }
10539 });
10540 return validUpdatableParams;
10541 };
10542
10543 /**
10544 * Dispose the current SweetAlert2 instance
10545 * @this {SweetAlert}
10546 */
10547 function _destroy() {
10548 var _globalState$eventEmi;
10549 const domCache = privateProps.domCache.get(this);
10550 const innerParams = privateProps.innerParams.get(this);
10551 if (!innerParams) {
10552 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
10553 return; // This instance has already been destroyed
10554 }
10555
10556 // Check if there is another Swal closing
10557 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
10558 globalState.swalCloseEventFinishedCallback();
10559 delete globalState.swalCloseEventFinishedCallback;
10560 }
10561 if (typeof innerParams.didDestroy === 'function') {
10562 innerParams.didDestroy();
10563 }
10564 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
10565 disposeSwal(this);
10566 }
10567
10568 /**
10569 * @param {SweetAlert} instance
10570 */
10571 const disposeSwal = instance => {
10572 disposeWeakMaps(instance);
10573 // Unset this.params so GC will dispose it (#1569)
10574 // @ts-ignore
10575 delete instance.params;
10576 // Unset globalState props so GC will dispose globalState (#1569)
10577 delete globalState.keydownHandler;
10578 delete globalState.keydownTarget;
10579 // Unset currentInstance
10580 delete globalState.currentInstance;
10581 };
10582
10583 /**
10584 * @param {SweetAlert} instance
10585 */
10586 const disposeWeakMaps = instance => {
10587 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
10588 if (instance.isAwaitingPromise) {
10589 unsetWeakMaps(privateProps, instance);
10590 instance.isAwaitingPromise = true;
10591 } else {
10592 unsetWeakMaps(privateMethods, instance);
10593 unsetWeakMaps(privateProps, instance);
10594
10595 // @ts-ignore
10596 delete instance.isAwaitingPromise;
10597 // Unset instance methods
10598 // @ts-ignore
10599 delete instance.disableButtons;
10600 // @ts-ignore
10601 delete instance.enableButtons;
10602 // @ts-ignore
10603 delete instance.getInput;
10604 // @ts-ignore
10605 delete instance.disableInput;
10606 // @ts-ignore
10607 delete instance.enableInput;
10608 // @ts-ignore
10609 delete instance.hideLoading;
10610 // @ts-ignore
10611 delete instance.disableLoading;
10612 // @ts-ignore
10613 delete instance.showValidationMessage;
10614 // @ts-ignore
10615 delete instance.resetValidationMessage;
10616 // @ts-ignore
10617 delete instance.close;
10618 // @ts-ignore
10619 delete instance.closePopup;
10620 // @ts-ignore
10621 delete instance.closeModal;
10622 // @ts-ignore
10623 delete instance.closeToast;
10624 // @ts-ignore
10625 delete instance.rejectPromise;
10626 // @ts-ignore
10627 delete instance.update;
10628 // @ts-ignore
10629 delete instance._destroy;
10630 }
10631 };
10632
10633 /**
10634 * @param {Record<string, WeakMap<any, any>>} obj
10635 * @param {SweetAlert} instance
10636 */
10637 const unsetWeakMaps = (obj, instance) => {
10638 for (const i in obj) {
10639 obj[i].delete(instance);
10640 }
10641 };
10642
10643 var instanceMethods = /*#__PURE__*/Object.freeze({
10644 __proto__: null,
10645 _destroy: _destroy,
10646 close: close,
10647 closeModal: close,
10648 closePopup: close,
10649 closeToast: close,
10650 disableButtons: disableButtons,
10651 disableInput: disableInput,
10652 disableLoading: hideLoading,
10653 enableButtons: enableButtons,
10654 enableInput: enableInput,
10655 getInput: getInput,
10656 handleAwaitingPromise: handleAwaitingPromise,
10657 hideLoading: hideLoading,
10658 rejectPromise: rejectPromise,
10659 resetValidationMessage: resetValidationMessage,
10660 showValidationMessage: showValidationMessage,
10661 update: update
10662 });
10663
10664 /**
10665 * @param {SweetAlertOptions} innerParams
10666 * @param {DomCache} domCache
10667 * @param {(dismiss: DismissReason) => void} dismissWith
10668 */
10669 const handlePopupClick = (innerParams, domCache, dismissWith) => {
10670 if (innerParams.toast) {
10671 handleToastClick(innerParams, domCache, dismissWith);
10672 } else {
10673 // Ignore click events that had mousedown on the popup but mouseup on the container
10674 // This can happen when the user drags a slider
10675 handleModalMousedown(domCache);
10676
10677 // Ignore click events that had mousedown on the container but mouseup on the popup
10678 handleContainerMousedown(domCache);
10679 handleModalClick(innerParams, domCache, dismissWith);
10680 }
10681 };
10682
10683 /**
10684 * @param {SweetAlertOptions} innerParams
10685 * @param {DomCache} domCache
10686 * @param {(dismiss: DismissReason) => void} dismissWith
10687 */
10688 const handleToastClick = (innerParams, domCache, dismissWith) => {
10689 // Closing toast by internal click
10690 domCache.popup.onclick = () => {
10691 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
10692 return;
10693 }
10694 dismissWith(DismissReason.close);
10695 };
10696 };
10697
10698 /**
10699 * @param {SweetAlertOptions} innerParams
10700 * @returns {boolean}
10701 */
10702 const isAnyButtonShown = innerParams => {
10703 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
10704 };
10705 let ignoreOutsideClick = false;
10706
10707 /**
10708 * @param {DomCache} domCache
10709 */
10710 const handleModalMousedown = domCache => {
10711 domCache.popup.onmousedown = () => {
10712 domCache.container.onmouseup = function (e) {
10713 domCache.container.onmouseup = () => {};
10714 // We only check if the mouseup target is the container because usually it doesn't
10715 // have any other direct children aside of the popup
10716 if (e.target === domCache.container) {
10717 ignoreOutsideClick = true;
10718 }
10719 };
10720 };
10721 };
10722
10723 /**
10724 * @param {DomCache} domCache
10725 */
10726 const handleContainerMousedown = domCache => {
10727 domCache.container.onmousedown = e => {
10728 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
10729 if (e.target === domCache.container) {
10730 e.preventDefault();
10731 }
10732 domCache.popup.onmouseup = function (e) {
10733 domCache.popup.onmouseup = () => {};
10734 // We also need to check if the mouseup target is a child of the popup
10735 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
10736 ignoreOutsideClick = true;
10737 }
10738 };
10739 };
10740 };
10741
10742 /**
10743 * @param {SweetAlertOptions} innerParams
10744 * @param {DomCache} domCache
10745 * @param {(dismiss: DismissReason) => void} dismissWith
10746 */
10747 const handleModalClick = (innerParams, domCache, dismissWith) => {
10748 domCache.container.onclick = e => {
10749 if (ignoreOutsideClick) {
10750 ignoreOutsideClick = false;
10751 return;
10752 }
10753 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
10754 dismissWith(DismissReason.backdrop);
10755 }
10756 };
10757 };
10758
10759 /**
10760 * @param {unknown} elem
10761 * @returns {boolean}
10762 */
10763 const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
10764
10765 /**
10766 * @param {unknown} elem
10767 * @returns {boolean}
10768 */
10769 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
10770
10771 /**
10772 * @param {ReadonlyArray<unknown>} args
10773 * @returns {SweetAlertOptions}
10774 */
10775 const argsToParams = args => {
10776 /** @type {Record<string, unknown>} */
10777 const params = {};
10778 if (typeof args[0] === 'object' && !isElement(args[0])) {
10779 Object.assign(params, args[0]);
10780 } else {
10781 ['title', 'html', 'icon'].forEach((name, index) => {
10782 const arg = args[index];
10783 if (typeof arg === 'string' || isElement(arg)) {
10784 params[name] = arg;
10785 } else if (arg !== undefined) {
10786 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
10787 }
10788 });
10789 }
10790 return /** @type {SweetAlertOptions} */params;
10791 };
10792
10793 /**
10794 * Main method to create a new SweetAlert2 popup
10795 *
10796 * @this {new (...args: any[]) => any}
10797 * @param {...SweetAlertOptions} args
10798 * @returns {Promise<SweetAlertResult>}
10799 */
10800 function fire(...args) {
10801 return new this(...args);
10802 }
10803
10804 /**
10805 * Returns an extended version of `Swal` containing `params` as defaults.
10806 * Useful for reusing Swal configuration.
10807 *
10808 * For example:
10809 *
10810 * Before:
10811 * const textPromptOptions = { input: 'text', showCancelButton: true }
10812 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
10813 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
10814 *
10815 * After:
10816 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
10817 * const {value: firstName} = await TextPrompt('What is your first name?')
10818 * const {value: lastName} = await TextPrompt('What is your last name?')
10819 *
10820 * @param {SweetAlertOptions} mixinParams
10821 * @returns {SweetAlert}
10822 * @this {typeof import('../SweetAlert.js').SweetAlert}
10823 */
10824 function mixin(mixinParams) {
10825 // @ts-ignore: 'this' refers to the SweetAlert constructor
10826 class MixinSwal extends this {
10827 /**
10828 * @param {any} params
10829 * @param {any} priorityMixinParams
10830 */
10831 _main(params, priorityMixinParams) {
10832 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
10833 }
10834 }
10835 // @ts-ignore
10836 return MixinSwal;
10837 }
10838
10839 /**
10840 * If `timer` parameter is set, returns number of milliseconds of timer remained.
10841 * Otherwise, returns undefined.
10842 *
10843 * @returns {number | undefined}
10844 */
10845 const getTimerLeft = () => {
10846 return globalState.timeout && globalState.timeout.getTimerLeft();
10847 };
10848
10849 /**
10850 * Stop timer. Returns number of milliseconds of timer remained.
10851 * If `timer` parameter isn't set, returns undefined.
10852 *
10853 * @returns {number | undefined}
10854 */
10855 const stopTimer = () => {
10856 if (globalState.timeout) {
10857 stopTimerProgressBar();
10858 return globalState.timeout.stop();
10859 }
10860 };
10861
10862 /**
10863 * Resume timer. Returns number of milliseconds of timer remained.
10864 * If `timer` parameter isn't set, returns undefined.
10865 *
10866 * @returns {number | undefined}
10867 */
10868 const resumeTimer = () => {
10869 if (globalState.timeout) {
10870 const remaining = globalState.timeout.start();
10871 animateTimerProgressBar(remaining);
10872 return remaining;
10873 }
10874 };
10875
10876 /**
10877 * Resume timer. Returns number of milliseconds of timer remained.
10878 * If `timer` parameter isn't set, returns undefined.
10879 *
10880 * @returns {number | undefined}
10881 */
10882 const toggleTimer = () => {
10883 const timer = globalState.timeout;
10884 return timer && (timer.running ? stopTimer() : resumeTimer());
10885 };
10886
10887 /**
10888 * Increase timer. Returns number of milliseconds of an updated timer.
10889 * If `timer` parameter isn't set, returns undefined.
10890 *
10891 * @param {number} ms
10892 * @returns {number | undefined}
10893 */
10894 const increaseTimer = ms => {
10895 if (globalState.timeout) {
10896 const remaining = globalState.timeout.increase(ms);
10897 animateTimerProgressBar(remaining, true);
10898 return remaining;
10899 }
10900 };
10901
10902 /**
10903 * Check if timer is running. Returns true if timer is running
10904 * or false if timer is paused or stopped.
10905 * If `timer` parameter isn't set, returns undefined
10906 *
10907 * @returns {boolean}
10908 */
10909 const isTimerRunning = () => {
10910 return Boolean(globalState.timeout && globalState.timeout.isRunning());
10911 };
10912
10913 let bodyClickListenerAdded = false;
10914 /** @type {Record<string, any>} */
10915 const clickHandlers = {};
10916
10917 /**
10918 * @this {any}
10919 * @param {string} attr
10920 */
10921 function bindClickHandler(attr = 'data-swal-template') {
10922 clickHandlers[attr] = this;
10923 if (!bodyClickListenerAdded) {
10924 document.body.addEventListener('click', bodyClickListener);
10925 bodyClickListenerAdded = true;
10926 }
10927 }
10928
10929 /**
10930 * @param {MouseEvent} event
10931 */
10932 const bodyClickListener = event => {
10933 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
10934 for (const attr in clickHandlers) {
10935 const template = el.getAttribute && el.getAttribute(attr);
10936 if (template) {
10937 clickHandlers[attr].fire({
10938 template
10939 });
10940 return;
10941 }
10942 }
10943 }
10944 };
10945
10946 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
10947
10948 class EventEmitter {
10949 constructor() {
10950 /** @type {Events} */
10951 this.events = {};
10952 }
10953
10954 /**
10955 * @param {string} eventName
10956 * @returns {EventHandlers}
10957 */
10958 _getHandlersByEventName(eventName) {
10959 if (typeof this.events[eventName] === 'undefined') {
10960 // not Set because we need to keep the FIFO order
10961 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
10962 this.events[eventName] = [];
10963 }
10964 return this.events[eventName];
10965 }
10966
10967 /**
10968 * @param {string} eventName
10969 * @param {EventHandler} eventHandler
10970 */
10971 on(eventName, eventHandler) {
10972 const currentHandlers = this._getHandlersByEventName(eventName);
10973 if (!currentHandlers.includes(eventHandler)) {
10974 currentHandlers.push(eventHandler);
10975 }
10976 }
10977
10978 /**
10979 * @param {string} eventName
10980 * @param {EventHandler} eventHandler
10981 */
10982 once(eventName, eventHandler) {
10983 /**
10984 * @param {...any} args
10985 */
10986 const onceFn = (...args) => {
10987 this.removeListener(eventName, onceFn);
10988 // @ts-ignore
10989 eventHandler.apply(this, args);
10990 };
10991 this.on(eventName, onceFn);
10992 }
10993
10994 /**
10995 * @param {string} eventName
10996 * @param {...any} args
10997 */
10998 emit(eventName, ...args) {
10999 this._getHandlersByEventName(eventName).forEach(
11000 /**
11001 * @param {EventHandler} eventHandler
11002 */
11003 eventHandler => {
11004 try {
11005 // @ts-ignore
11006 eventHandler.apply(this, args);
11007 } catch (error) {
11008 console.error(error);
11009 }
11010 });
11011 }
11012
11013 /**
11014 * @param {string} eventName
11015 * @param {EventHandler} eventHandler
11016 */
11017 removeListener(eventName, eventHandler) {
11018 const currentHandlers = this._getHandlersByEventName(eventName);
11019 const index = currentHandlers.indexOf(eventHandler);
11020 if (index > -1) {
11021 currentHandlers.splice(index, 1);
11022 }
11023 }
11024
11025 /**
11026 * @param {string} eventName
11027 */
11028 removeAllListeners(eventName) {
11029 if (this.events[eventName] !== undefined) {
11030 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
11031 this.events[eventName].length = 0;
11032 }
11033 }
11034 reset() {
11035 this.events = {};
11036 }
11037 }
11038
11039 globalState.eventEmitter = new EventEmitter();
11040
11041 /**
11042 * @param {string} eventName
11043 * @param {EventHandler} eventHandler
11044 */
11045 const on = (eventName, eventHandler) => {
11046 if (globalState.eventEmitter) {
11047 globalState.eventEmitter.on(eventName, eventHandler);
11048 }
11049 };
11050
11051 /**
11052 * @param {string} eventName
11053 * @param {EventHandler} eventHandler
11054 */
11055 const once = (eventName, eventHandler) => {
11056 if (globalState.eventEmitter) {
11057 globalState.eventEmitter.once(eventName, eventHandler);
11058 }
11059 };
11060
11061 /**
11062 * @param {string} [eventName]
11063 * @param {EventHandler} [eventHandler]
11064 */
11065 const off = (eventName, eventHandler) => {
11066 if (!globalState.eventEmitter) {
11067 return;
11068 }
11069
11070 // Remove all handlers for all events
11071 if (!eventName) {
11072 globalState.eventEmitter.reset();
11073 return;
11074 }
11075 if (eventHandler) {
11076 // Remove a specific handler
11077 globalState.eventEmitter.removeListener(eventName, eventHandler);
11078 } else {
11079 // Remove all handlers for a specific event
11080 globalState.eventEmitter.removeAllListeners(eventName);
11081 }
11082 };
11083
11084 var staticMethods = /*#__PURE__*/Object.freeze({
11085 __proto__: null,
11086 argsToParams: argsToParams,
11087 bindClickHandler: bindClickHandler,
11088 clickCancel: clickCancel,
11089 clickConfirm: clickConfirm,
11090 clickDeny: clickDeny,
11091 enableLoading: showLoading,
11092 fire: fire,
11093 getActions: getActions,
11094 getCancelButton: getCancelButton,
11095 getCloseButton: getCloseButton,
11096 getConfirmButton: getConfirmButton,
11097 getContainer: getContainer,
11098 getDenyButton: getDenyButton,
11099 getFocusableElements: getFocusableElements,
11100 getFooter: getFooter,
11101 getHtmlContainer: getHtmlContainer,
11102 getIcon: getIcon,
11103 getIconContent: getIconContent,
11104 getImage: getImage,
11105 getInputLabel: getInputLabel,
11106 getLoader: getLoader,
11107 getPopup: getPopup,
11108 getProgressSteps: getProgressSteps,
11109 getTimerLeft: getTimerLeft,
11110 getTimerProgressBar: getTimerProgressBar,
11111 getTitle: getTitle,
11112 getValidationMessage: getValidationMessage,
11113 increaseTimer: increaseTimer,
11114 isDeprecatedParameter: isDeprecatedParameter,
11115 isLoading: isLoading,
11116 isTimerRunning: isTimerRunning,
11117 isUpdatableParameter: isUpdatableParameter,
11118 isValidParameter: isValidParameter,
11119 isVisible: isVisible,
11120 mixin: mixin,
11121 off: off,
11122 on: on,
11123 once: once,
11124 resumeTimer: resumeTimer,
11125 showLoading: showLoading,
11126 stopTimer: stopTimer,
11127 toggleTimer: toggleTimer
11128 });
11129
11130 class Timer {
11131 /**
11132 * @param {() => void} callback
11133 * @param {number} delay
11134 */
11135 constructor(callback, delay) {
11136 this.callback = callback;
11137 this.remaining = delay;
11138 this.running = false;
11139 this.start();
11140 }
11141
11142 /**
11143 * @returns {number}
11144 */
11145 start() {
11146 if (!this.running) {
11147 this.running = true;
11148 this.started = new Date();
11149 this.id = setTimeout(this.callback, this.remaining);
11150 }
11151 return this.remaining;
11152 }
11153
11154 /**
11155 * @returns {number}
11156 */
11157 stop() {
11158 if (this.started && this.running) {
11159 this.running = false;
11160 clearTimeout(this.id);
11161 this.remaining -= new Date().getTime() - this.started.getTime();
11162 }
11163 return this.remaining;
11164 }
11165
11166 /**
11167 * @param {number} n
11168 * @returns {number}
11169 */
11170 increase(n) {
11171 const running = this.running;
11172 if (running) {
11173 this.stop();
11174 }
11175 this.remaining += n;
11176 if (running) {
11177 this.start();
11178 }
11179 return this.remaining;
11180 }
11181
11182 /**
11183 * @returns {number}
11184 */
11185 getTimerLeft() {
11186 if (this.running) {
11187 this.stop();
11188 this.start();
11189 }
11190 return this.remaining;
11191 }
11192
11193 /**
11194 * @returns {boolean}
11195 */
11196 isRunning() {
11197 return this.running;
11198 }
11199 }
11200
11201 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
11202
11203 /**
11204 * @param {SweetAlertOptions} params
11205 * @returns {SweetAlertOptions}
11206 */
11207 const getTemplateParams = params => {
11208 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
11209 if (!template) {
11210 return {};
11211 }
11212 /** @type {DocumentFragment} */
11213 const templateContent = template.content;
11214 showWarningsForElements(templateContent);
11215 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
11216 return result;
11217 };
11218
11219 /**
11220 * @param {DocumentFragment} templateContent
11221 * @returns {Record<string, string | boolean | number>}
11222 */
11223 const getSwalParams = templateContent => {
11224 /** @type {Record<string, string | boolean | number>} */
11225 const result = {};
11226 /** @type {HTMLElement[]} */
11227 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
11228 swalParams.forEach(param => {
11229 showWarningsForAttributes(param, ['name', 'value']);
11230 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
11231 const value = param.getAttribute('value');
11232 if (!paramName || !value) {
11233 return;
11234 }
11235 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
11236 result[paramName] = value !== 'false';
11237 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
11238 result[paramName] = JSON.parse(value);
11239 } else {
11240 result[paramName] = value;
11241 }
11242 });
11243 return result;
11244 };
11245
11246 /**
11247 * @param {DocumentFragment} templateContent
11248 * @returns {Record<string, () => void>}
11249 */
11250 const getSwalFunctionParams = templateContent => {
11251 /** @type {Record<string, () => void>} */
11252 const result = {};
11253 /** @type {HTMLElement[]} */
11254 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
11255 swalFunctions.forEach(param => {
11256 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
11257 const value = param.getAttribute('value');
11258 if (!paramName || !value) {
11259 return;
11260 }
11261 result[paramName] = new Function(`return ${value}`)();
11262 });
11263 return result;
11264 };
11265
11266 /**
11267 * @param {DocumentFragment} templateContent
11268 * @returns {Record<string, string | boolean>}
11269 */
11270 const getSwalButtons = templateContent => {
11271 /** @type {Record<string, string | boolean>} */
11272 const result = {};
11273 /** @type {HTMLElement[]} */
11274 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
11275 swalButtons.forEach(button => {
11276 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
11277 const type = button.getAttribute('type');
11278 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
11279 return;
11280 }
11281 result[`${type}ButtonText`] = button.innerHTML;
11282 result[`show${capitalizeFirstLetter(type)}Button`] = true;
11283 const color = button.getAttribute('color');
11284 if (color !== null) {
11285 result[`${type}ButtonColor`] = color;
11286 }
11287 const ariaLabel = button.getAttribute('aria-label');
11288 if (ariaLabel !== null) {
11289 result[`${type}ButtonAriaLabel`] = ariaLabel;
11290 }
11291 });
11292 return result;
11293 };
11294
11295 /**
11296 * @param {DocumentFragment} templateContent
11297 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
11298 */
11299 const getSwalImage = templateContent => {
11300 const result = {};
11301 /** @type {HTMLElement | null} */
11302 const image = templateContent.querySelector('swal-image');
11303 if (image) {
11304 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
11305 // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
11306 const src = image.getAttribute('src');
11307 if (src !== null) result.imageUrl = src || undefined;
11308 const width = image.getAttribute('width');
11309 if (width !== null) result.imageWidth = width || undefined;
11310 const height = image.getAttribute('height');
11311 if (height !== null) result.imageHeight = height || undefined;
11312 const alt = image.getAttribute('alt');
11313 if (alt !== null) result.imageAlt = alt || undefined;
11314 }
11315 return result;
11316 };
11317
11318 /**
11319 * @param {DocumentFragment} templateContent
11320 * @returns {object}
11321 */
11322 const getSwalIcon = templateContent => {
11323 const result = {};
11324 /** @type {HTMLElement | null} */
11325 const icon = templateContent.querySelector('swal-icon');
11326 if (icon) {
11327 showWarningsForAttributes(icon, ['type', 'color']);
11328 if (icon.hasAttribute('type')) {
11329 result.icon = icon.getAttribute('type');
11330 }
11331 if (icon.hasAttribute('color')) {
11332 result.iconColor = icon.getAttribute('color');
11333 }
11334 result.iconHtml = icon.innerHTML;
11335 }
11336 return result;
11337 };
11338
11339 /**
11340 * @param {DocumentFragment} templateContent
11341 * @returns {object}
11342 */
11343 const getSwalInput = templateContent => {
11344 /** @type {Record<string, any>} */
11345 const result = {};
11346 /** @type {HTMLElement | null} */
11347 const input = templateContent.querySelector('swal-input');
11348 if (input) {
11349 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
11350 result.input = input.getAttribute('type') || 'text';
11351 if (input.hasAttribute('label')) {
11352 result.inputLabel = input.getAttribute('label');
11353 }
11354 if (input.hasAttribute('placeholder')) {
11355 result.inputPlaceholder = input.getAttribute('placeholder');
11356 }
11357 if (input.hasAttribute('value')) {
11358 result.inputValue = input.getAttribute('value');
11359 }
11360 }
11361 /** @type {HTMLElement[]} */
11362 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
11363 if (inputOptions.length) {
11364 result.inputOptions = {};
11365 inputOptions.forEach(option => {
11366 showWarningsForAttributes(option, ['value']);
11367 const optionValue = option.getAttribute('value');
11368 if (!optionValue) {
11369 return;
11370 }
11371 const optionName = option.innerHTML;
11372 result.inputOptions[optionValue] = optionName;
11373 });
11374 }
11375 return result;
11376 };
11377
11378 /**
11379 * @param {DocumentFragment} templateContent
11380 * @param {string[]} paramNames
11381 * @returns {Record<string, string>}
11382 */
11383 const getSwalStringParams = (templateContent, paramNames) => {
11384 /** @type {Record<string, string>} */
11385 const result = {};
11386 for (const i in paramNames) {
11387 const paramName = paramNames[i];
11388 /** @type {HTMLElement | null} */
11389 const tag = templateContent.querySelector(paramName);
11390 if (tag) {
11391 showWarningsForAttributes(tag, []);
11392 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
11393 }
11394 }
11395 return result;
11396 };
11397
11398 /**
11399 * @param {DocumentFragment} templateContent
11400 */
11401 const showWarningsForElements = templateContent => {
11402 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
11403 Array.from(templateContent.children).forEach(el => {
11404 const tagName = el.tagName.toLowerCase();
11405 if (!allowedElements.includes(tagName)) {
11406 warn(`Unrecognized element <${tagName}>`);
11407 }
11408 });
11409 };
11410
11411 /**
11412 * @param {HTMLElement} el
11413 * @param {string[]} allowedAttributes
11414 */
11415 const showWarningsForAttributes = (el, allowedAttributes) => {
11416 Array.from(el.attributes).forEach(attribute => {
11417 if (allowedAttributes.indexOf(attribute.name) === -1) {
11418 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.'}`]);
11419 }
11420 });
11421 };
11422
11423 const SHOW_CLASS_TIMEOUT = 10;
11424
11425 /**
11426 * Open popup, add necessary classes and styles, fix scrollbar
11427 *
11428 * @param {SweetAlertOptions} params
11429 */
11430 const openPopup = params => {
11431 var _globalState$eventEmi, _globalState$eventEmi2;
11432 const container = getContainer();
11433 const popup = getPopup();
11434 if (!container || !popup) {
11435 return;
11436 }
11437 if (typeof params.willOpen === 'function') {
11438 params.willOpen(popup);
11439 }
11440 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
11441 const bodyStyles = window.getComputedStyle(document.body);
11442 const initialBodyOverflow = bodyStyles.overflowY;
11443 addClasses(container, popup, params);
11444
11445 // scrolling is 'hidden' until animation is done, after that 'auto'
11446 setTimeout(() => {
11447 setScrollingVisibility(container, popup);
11448 }, SHOW_CLASS_TIMEOUT);
11449 if (isModal()) {
11450 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
11451 setAriaHidden();
11452 }
11453
11454 // https://github.com/sweetalert2/sweetalert2/issues/2923
11455 if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
11456 // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
11457 container.style.pointerEvents = 'auto';
11458 }
11459 if (!isToast() && !globalState.previousActiveElement) {
11460 globalState.previousActiveElement = document.activeElement;
11461 }
11462 if (typeof params.didOpen === 'function') {
11463 const didOpen = params.didOpen;
11464 setTimeout(() => didOpen(popup));
11465 }
11466 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
11467 };
11468
11469 /**
11470 * @param {Event} event
11471 */
11472 const swalOpenAnimationFinished = event => {
11473 const popup = getPopup();
11474 if (!popup || event.target !== popup) {
11475 return;
11476 }
11477 const container = getContainer();
11478 if (!container) {
11479 return;
11480 }
11481 popup.removeEventListener('animationend', swalOpenAnimationFinished);
11482 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
11483 container.style.overflowY = 'auto';
11484
11485 // no-transition is added in init() in case one swal is opened right after another
11486 removeClass(container, swalClasses['no-transition']);
11487 };
11488
11489 /**
11490 * @param {HTMLElement} container
11491 * @param {HTMLElement} popup
11492 */
11493 const setScrollingVisibility = (container, popup) => {
11494 if (hasCssAnimation(popup)) {
11495 container.style.overflowY = 'hidden';
11496 popup.addEventListener('animationend', swalOpenAnimationFinished);
11497 popup.addEventListener('transitionend', swalOpenAnimationFinished);
11498 } else {
11499 container.style.overflowY = 'auto';
11500 }
11501 };
11502
11503 /**
11504 * @param {HTMLElement} container
11505 * @param {boolean} scrollbarPadding
11506 * @param {string} initialBodyOverflow
11507 */
11508 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
11509 iOSfix();
11510 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
11511 replaceScrollbarWithPadding(initialBodyOverflow);
11512 }
11513
11514 // sweetalert2/issues/1247
11515 setTimeout(() => {
11516 container.scrollTop = 0;
11517 });
11518 };
11519
11520 /**
11521 * @param {HTMLElement} container
11522 * @param {HTMLElement} popup
11523 * @param {SweetAlertOptions} params
11524 */
11525 const addClasses = (container, popup, params) => {
11526 var _params$showClass;
11527 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
11528 addClass(container, params.showClass.backdrop);
11529 }
11530 if (params.animation) {
11531 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
11532 popup.style.setProperty('opacity', '0', 'important');
11533 show(popup, 'grid');
11534 setTimeout(() => {
11535 var _params$showClass2;
11536 // Animate popup right after showing it
11537 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
11538 addClass(popup, params.showClass.popup);
11539 }
11540 // and remove the opacity workaround
11541 popup.style.removeProperty('opacity');
11542 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
11543 } else {
11544 show(popup, 'grid');
11545 }
11546 addClass([document.documentElement, document.body], swalClasses.shown);
11547 if (params.heightAuto && params.backdrop && !params.toast) {
11548 addClass([document.documentElement, document.body], swalClasses['height-auto']);
11549 }
11550 };
11551
11552 var defaultInputValidators = {
11553 /**
11554 * @param {string} string
11555 * @param {string} [validationMessage]
11556 * @returns {Promise<string | void>}
11557 */
11558 email: (string, validationMessage) => {
11559 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
11560 },
11561 /**
11562 * @param {string} string
11563 * @param {string} [validationMessage]
11564 * @returns {Promise<string | void>}
11565 */
11566 url: (string, validationMessage) => {
11567 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
11568 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');
11569 }
11570 };
11571
11572 /**
11573 * @param {SweetAlertOptions} params
11574 */
11575 function setDefaultInputValidators(params) {
11576 // Use default `inputValidator` for supported input types if not provided
11577 if (params.inputValidator) {
11578 return;
11579 }
11580 if (params.input === 'email') {
11581 params.inputValidator = defaultInputValidators['email'];
11582 }
11583 if (params.input === 'url') {
11584 params.inputValidator = defaultInputValidators['url'];
11585 }
11586 }
11587
11588 /**
11589 * @param {SweetAlertOptions} params
11590 */
11591 function validateCustomTargetElement(params) {
11592 // Determine if the custom target element is valid
11593 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
11594 warn('Target parameter is not valid, defaulting to "body"');
11595 params.target = 'body';
11596 }
11597 }
11598
11599 /**
11600 * Set type, text and actions on popup
11601 *
11602 * @param {SweetAlertOptions} params
11603 */
11604 function setParameters(params) {
11605 setDefaultInputValidators(params);
11606
11607 // showLoaderOnConfirm && preConfirm
11608 if (params.showLoaderOnConfirm && !params.preConfirm) {
11609 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');
11610 }
11611 validateCustomTargetElement(params);
11612
11613 // Replace newlines with <br> in title
11614 if (typeof params.title === 'string') {
11615 params.title = params.title.split('\n').join('<br />');
11616 }
11617 init(params);
11618 }
11619
11620 /** @type {SweetAlert} */
11621 let currentInstance;
11622 var _promise = /*#__PURE__*/new WeakMap();
11623 class SweetAlert {
11624 /**
11625 * @param {...(SweetAlertOptions | string)} args
11626 * @this {SweetAlert}
11627 */
11628 constructor(...args) {
11629 /**
11630 * @type {Promise<SweetAlertResult>}
11631 */
11632 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
11633 Promise.resolve({
11634 isConfirmed: false,
11635 isDenied: false,
11636 isDismissed: true
11637 }));
11638 // Prevent run in Node env
11639 if (typeof window === 'undefined') {
11640 return;
11641 }
11642 currentInstance = this;
11643
11644 // @ts-ignore
11645 const outerParams = Object.freeze(this.constructor.argsToParams(args));
11646
11647 /** @type {Readonly<SweetAlertOptions>} */
11648 this.params = outerParams;
11649
11650 /** @type {boolean} */
11651 this.isAwaitingPromise = false;
11652 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
11653 }
11654
11655 /**
11656 * @param {any} userParams
11657 * @param {any} mixinParams
11658 */
11659 _main(userParams, mixinParams = {}) {
11660 showWarningsForParams(Object.assign({}, mixinParams, userParams));
11661 if (globalState.currentInstance) {
11662 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
11663 const {
11664 isAwaitingPromise
11665 } = globalState.currentInstance;
11666 globalState.currentInstance._destroy();
11667 if (!isAwaitingPromise) {
11668 swalPromiseResolve({
11669 isDismissed: true
11670 });
11671 }
11672 if (isModal()) {
11673 unsetAriaHidden();
11674 }
11675 }
11676 globalState.currentInstance = currentInstance;
11677 const innerParams = prepareParams(userParams, mixinParams);
11678 setParameters(innerParams);
11679 Object.freeze(innerParams);
11680
11681 // clear the previous timer
11682 if (globalState.timeout) {
11683 globalState.timeout.stop();
11684 delete globalState.timeout;
11685 }
11686
11687 // clear the restore focus timeout
11688 clearTimeout(globalState.restoreFocusTimeout);
11689 const domCache = populateDomCache(currentInstance);
11690 render(currentInstance, innerParams);
11691 privateProps.innerParams.set(currentInstance, innerParams);
11692 return swalPromise(currentInstance, domCache, innerParams);
11693 }
11694
11695 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
11696 /**
11697 * @param {any} onFulfilled
11698 */
11699 // oxlint-disable-next-line unicorn/no-thenable
11700 then(onFulfilled) {
11701 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
11702 }
11703
11704 /**
11705 * @param {any} onFinally
11706 */
11707 finally(onFinally) {
11708 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
11709 }
11710 }
11711
11712 /**
11713 * @param {SweetAlert} instance
11714 * @param {DomCache} domCache
11715 * @param {SweetAlertOptions} innerParams
11716 * @returns {Promise<SweetAlertResult>}
11717 */
11718 const swalPromise = (instance, domCache, innerParams) => {
11719 return new Promise((resolve, reject) => {
11720 // functions to handle all closings/dismissals
11721 /**
11722 * @param {DismissReason} dismiss
11723 */
11724 const dismissWith = dismiss => {
11725 instance.close({
11726 isDismissed: true,
11727 dismiss,
11728 isConfirmed: false,
11729 isDenied: false
11730 });
11731 };
11732 privateMethods.swalPromiseResolve.set(instance, resolve);
11733 privateMethods.swalPromiseReject.set(instance, reject);
11734 domCache.confirmButton.onclick = () => {
11735 handleConfirmButtonClick(instance);
11736 };
11737 domCache.denyButton.onclick = () => {
11738 handleDenyButtonClick(instance);
11739 };
11740 domCache.cancelButton.onclick = () => {
11741 handleCancelButtonClick(instance, dismissWith);
11742 };
11743 domCache.closeButton.onclick = () => {
11744 dismissWith(DismissReason.close);
11745 };
11746 handlePopupClick(innerParams, domCache, dismissWith);
11747 addKeydownHandler(globalState, innerParams, dismissWith);
11748 handleInputOptionsAndValue(instance, innerParams);
11749 openPopup(innerParams);
11750 setupTimer(globalState, innerParams, dismissWith);
11751 initFocus(domCache, innerParams);
11752
11753 // Scroll container to top on open (#1247, #1946)
11754 setTimeout(() => {
11755 domCache.container.scrollTop = 0;
11756 });
11757 });
11758 };
11759
11760 /**
11761 * @param {SweetAlertOptions} userParams
11762 * @param {SweetAlertOptions} mixinParams
11763 * @returns {SweetAlertOptions}
11764 */
11765 const prepareParams = (userParams, mixinParams) => {
11766 const templateParams = getTemplateParams(userParams);
11767 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
11768 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
11769 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
11770 if (params.animation === false) {
11771 params.showClass = {
11772 backdrop: 'swal2-noanimation'
11773 };
11774 params.hideClass = {};
11775 }
11776 return params;
11777 };
11778
11779 /**
11780 * @param {SweetAlert} instance
11781 * @returns {DomCache}
11782 */
11783 const populateDomCache = instance => {
11784 const domCache = /** @type {DomCache} */{
11785 popup: (/** @type {HTMLElement} */getPopup()),
11786 container: (/** @type {HTMLElement} */getContainer()),
11787 actions: (/** @type {HTMLElement} */getActions()),
11788 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
11789 denyButton: (/** @type {HTMLElement} */getDenyButton()),
11790 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
11791 loader: (/** @type {HTMLElement} */getLoader()),
11792 closeButton: (/** @type {HTMLElement} */getCloseButton()),
11793 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
11794 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
11795 };
11796 privateProps.domCache.set(instance, domCache);
11797 return domCache;
11798 };
11799
11800 /**
11801 * @param {GlobalState} globalState
11802 * @param {SweetAlertOptions} innerParams
11803 * @param {(dismiss: DismissReason) => void} dismissWith
11804 */
11805 const setupTimer = (globalState, innerParams, dismissWith) => {
11806 const timerProgressBar = getTimerProgressBar();
11807 hide(timerProgressBar);
11808 if (innerParams.timer) {
11809 globalState.timeout = new Timer(() => {
11810 dismissWith('timer');
11811 delete globalState.timeout;
11812 }, innerParams.timer);
11813 if (innerParams.timerProgressBar && timerProgressBar) {
11814 show(timerProgressBar);
11815 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
11816 setTimeout(() => {
11817 if (globalState.timeout && globalState.timeout.running) {
11818 // timer can be already stopped or unset at this point
11819 animateTimerProgressBar(/** @type {number} */innerParams.timer);
11820 }
11821 });
11822 }
11823 }
11824 };
11825
11826 /**
11827 * Initialize focus in the popup:
11828 *
11829 * 1. If `toast` is `true`, don't steal focus from the document.
11830 * 2. Else if there is an [autofocus] element, focus it.
11831 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
11832 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
11833 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
11834 * 6. Else focus the first focusable element in a popup (if any).
11835 *
11836 * @param {DomCache} domCache
11837 * @param {SweetAlertOptions} innerParams
11838 */
11839 const initFocus = (domCache, innerParams) => {
11840 if (innerParams.toast) {
11841 return;
11842 }
11843 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
11844 if (!callIfFunction(innerParams.allowEnterKey)) {
11845 warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
11846 domCache.popup.focus();
11847 return;
11848 }
11849 if (focusAutofocus(domCache)) {
11850 return;
11851 }
11852 if (focusButton(domCache, innerParams)) {
11853 return;
11854 }
11855 setFocus(-1, 1);
11856 };
11857
11858 /**
11859 * @param {DomCache} domCache
11860 * @returns {boolean}
11861 */
11862 const focusAutofocus = domCache => {
11863 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
11864 for (const autofocusElement of autofocusElements) {
11865 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
11866 autofocusElement.focus();
11867 return true;
11868 }
11869 }
11870 return false;
11871 };
11872
11873 /**
11874 * @param {DomCache} domCache
11875 * @param {SweetAlertOptions} innerParams
11876 * @returns {boolean}
11877 */
11878 const focusButton = (domCache, innerParams) => {
11879 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
11880 domCache.denyButton.focus();
11881 return true;
11882 }
11883 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
11884 domCache.cancelButton.focus();
11885 return true;
11886 }
11887 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
11888 domCache.confirmButton.focus();
11889 return true;
11890 }
11891 return false;
11892 };
11893
11894 // Assign instance methods from src/instanceMethods/*.js to prototype
11895 SweetAlert.prototype.disableButtons = disableButtons;
11896 SweetAlert.prototype.enableButtons = enableButtons;
11897 SweetAlert.prototype.getInput = getInput;
11898 SweetAlert.prototype.disableInput = disableInput;
11899 SweetAlert.prototype.enableInput = enableInput;
11900 SweetAlert.prototype.hideLoading = hideLoading;
11901 SweetAlert.prototype.disableLoading = hideLoading;
11902 SweetAlert.prototype.showValidationMessage = showValidationMessage;
11903 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
11904 SweetAlert.prototype.close = close;
11905 SweetAlert.prototype.closePopup = close;
11906 SweetAlert.prototype.closeModal = close;
11907 SweetAlert.prototype.closeToast = close;
11908 SweetAlert.prototype.rejectPromise = rejectPromise;
11909 SweetAlert.prototype.update = update;
11910 SweetAlert.prototype._destroy = _destroy;
11911
11912 // Assign static methods from src/staticMethods/*.js to constructor
11913 Object.assign(SweetAlert, staticMethods);
11914
11915 // Proxy to instance methods to constructor, for now, for backwards compatibility
11916 Object.keys(instanceMethods).forEach(key => {
11917 /**
11918 * @param {...(SweetAlertOptions | string | undefined)} args
11919 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
11920 */
11921 // @ts-ignore: Dynamic property assignment for backwards compatibility
11922 SweetAlert[key] = function (...args) {
11923 // @ts-ignore
11924 if (currentInstance && currentInstance[key]) {
11925 // @ts-ignore
11926 return currentInstance[key](...args);
11927 }
11928 return undefined;
11929 };
11930 });
11931 SweetAlert.DismissReason = DismissReason;
11932 SweetAlert.version = '11.26.25';
11933
11934 const Swal = SweetAlert;
11935 // @ts-ignore
11936 Swal.default = Swal;
11937
11938 return Swal;
11939
11940 }));
11941 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
11942 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:auto}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:auto}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
11943
11944 /***/ },
11945
11946 /***/ "./node_modules/toastify-js/src/toastify.js"
11947 /*!**************************************************!*\
11948 !*** ./node_modules/toastify-js/src/toastify.js ***!
11949 \**************************************************/
11950 (module) {
11951
11952 /*!
11953 * Toastify js 1.12.0
11954 * https://github.com/apvarun/toastify-js
11955 * @license MIT licensed
11956 *
11957 * Copyright (C) 2018 Varun A P
11958 */
11959 (function(root, factory) {
11960 if ( true && module.exports) {
11961 module.exports = factory();
11962 } else {
11963 root.Toastify = factory();
11964 }
11965 })(this, function(global) {
11966 // Object initialization
11967 var Toastify = function(options) {
11968 // Returning a new init object
11969 return new Toastify.lib.init(options);
11970 },
11971 // Library version
11972 version = "1.12.0";
11973
11974 // Set the default global options
11975 Toastify.defaults = {
11976 oldestFirst: true,
11977 text: "Toastify is awesome!",
11978 node: undefined,
11979 duration: 3000,
11980 selector: undefined,
11981 callback: function () {
11982 },
11983 destination: undefined,
11984 newWindow: false,
11985 close: false,
11986 gravity: "toastify-top",
11987 positionLeft: false,
11988 position: '',
11989 backgroundColor: '',
11990 avatar: "",
11991 className: "",
11992 stopOnFocus: true,
11993 onClick: function () {
11994 },
11995 offset: {x: 0, y: 0},
11996 escapeMarkup: true,
11997 ariaLive: 'polite',
11998 style: {background: ''}
11999 };
12000
12001 // Defining the prototype of the object
12002 Toastify.lib = Toastify.prototype = {
12003 toastify: version,
12004
12005 constructor: Toastify,
12006
12007 // Initializing the object with required parameters
12008 init: function(options) {
12009 // Verifying and validating the input object
12010 if (!options) {
12011 options = {};
12012 }
12013
12014 // Creating the options object
12015 this.options = {};
12016
12017 this.toastElement = null;
12018
12019 // Validating the options
12020 this.options.text = options.text || Toastify.defaults.text; // Display message
12021 this.options.node = options.node || Toastify.defaults.node; // Display content as node
12022 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
12023 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
12024 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
12025 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
12026 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
12027 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
12028 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
12029 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
12030 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
12031 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
12032 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
12033 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
12034 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
12035 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
12036 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
12037 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
12038 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
12039 this.options.style = options.style || Toastify.defaults.style;
12040 if(options.backgroundColor) {
12041 this.options.style.background = options.backgroundColor;
12042 }
12043
12044 // Returning the current object for chaining functions
12045 return this;
12046 },
12047
12048 // Building the DOM element
12049 buildToast: function() {
12050 // Validating if the options are defined
12051 if (!this.options) {
12052 throw "Toastify is not initialized";
12053 }
12054
12055 // Creating the DOM object
12056 var divElement = document.createElement("div");
12057 divElement.className = "toastify on " + this.options.className;
12058
12059 // Positioning toast to left or right or center
12060 if (!!this.options.position) {
12061 divElement.className += " toastify-" + this.options.position;
12062 } else {
12063 // To be depreciated in further versions
12064 if (this.options.positionLeft === true) {
12065 divElement.className += " toastify-left";
12066 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
12067 } else {
12068 // Default position
12069 divElement.className += " toastify-right";
12070 }
12071 }
12072
12073 // Assigning gravity of element
12074 divElement.className += " " + this.options.gravity;
12075
12076 if (this.options.backgroundColor) {
12077 // This is being deprecated in favor of using the style HTML DOM property
12078 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
12079 }
12080
12081 // Loop through our style object and apply styles to divElement
12082 for (var property in this.options.style) {
12083 divElement.style[property] = this.options.style[property];
12084 }
12085
12086 // Announce the toast to screen readers
12087 if (this.options.ariaLive) {
12088 divElement.setAttribute('aria-live', this.options.ariaLive)
12089 }
12090
12091 // Adding the toast message/node
12092 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
12093 // If we have a valid node, we insert it
12094 divElement.appendChild(this.options.node)
12095 } else {
12096 if (this.options.escapeMarkup) {
12097 divElement.innerText = this.options.text;
12098 } else {
12099 divElement.innerHTML = this.options.text;
12100 }
12101
12102 if (this.options.avatar !== "") {
12103 var avatarElement = document.createElement("img");
12104 avatarElement.src = this.options.avatar;
12105
12106 avatarElement.className = "toastify-avatar";
12107
12108 if (this.options.position == "left" || this.options.positionLeft === true) {
12109 // Adding close icon on the left of content
12110 divElement.appendChild(avatarElement);
12111 } else {
12112 // Adding close icon on the right of content
12113 divElement.insertAdjacentElement("afterbegin", avatarElement);
12114 }
12115 }
12116 }
12117
12118 // Adding a close icon to the toast
12119 if (this.options.close === true) {
12120 // Create a span for close element
12121 var closeElement = document.createElement("button");
12122 closeElement.type = "button";
12123 closeElement.setAttribute("aria-label", "Close");
12124 closeElement.className = "toast-close";
12125 closeElement.innerHTML = "&#10006;";
12126
12127 // Triggering the removal of toast from DOM on close click
12128 closeElement.addEventListener(
12129 "click",
12130 function(event) {
12131 event.stopPropagation();
12132 this.removeElement(this.toastElement);
12133 window.clearTimeout(this.toastElement.timeOutValue);
12134 }.bind(this)
12135 );
12136
12137 //Calculating screen width
12138 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
12139
12140 // Adding the close icon to the toast element
12141 // Display on the right if screen width is less than or equal to 360px
12142 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
12143 // Adding close icon on the left of content
12144 divElement.insertAdjacentElement("afterbegin", closeElement);
12145 } else {
12146 // Adding close icon on the right of content
12147 divElement.appendChild(closeElement);
12148 }
12149 }
12150
12151 // Clear timeout while toast is focused
12152 if (this.options.stopOnFocus && this.options.duration > 0) {
12153 var self = this;
12154 // stop countdown
12155 divElement.addEventListener(
12156 "mouseover",
12157 function(event) {
12158 window.clearTimeout(divElement.timeOutValue);
12159 }
12160 )
12161 // add back the timeout
12162 divElement.addEventListener(
12163 "mouseleave",
12164 function() {
12165 divElement.timeOutValue = window.setTimeout(
12166 function() {
12167 // Remove the toast from DOM
12168 self.removeElement(divElement);
12169 },
12170 self.options.duration
12171 )
12172 }
12173 )
12174 }
12175
12176 // Adding an on-click destination path
12177 if (typeof this.options.destination !== "undefined") {
12178 divElement.addEventListener(
12179 "click",
12180 function(event) {
12181 event.stopPropagation();
12182 if (this.options.newWindow === true) {
12183 window.open(this.options.destination, "_blank");
12184 } else {
12185 window.location = this.options.destination;
12186 }
12187 }.bind(this)
12188 );
12189 }
12190
12191 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
12192 divElement.addEventListener(
12193 "click",
12194 function(event) {
12195 event.stopPropagation();
12196 this.options.onClick();
12197 }.bind(this)
12198 );
12199 }
12200
12201 // Adding offset
12202 if(typeof this.options.offset === "object") {
12203
12204 var x = getAxisOffsetAValue("x", this.options);
12205 var y = getAxisOffsetAValue("y", this.options);
12206
12207 var xOffset = this.options.position == "left" ? x : "-" + x;
12208 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
12209
12210 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
12211
12212 }
12213
12214 // Returning the generated element
12215 return divElement;
12216 },
12217
12218 // Displaying the toast
12219 showToast: function() {
12220 // Creating the DOM object for the toast
12221 this.toastElement = this.buildToast();
12222
12223 // Getting the root element to with the toast needs to be added
12224 var rootElement;
12225 if (typeof this.options.selector === "string") {
12226 rootElement = document.getElementById(this.options.selector);
12227 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
12228 rootElement = this.options.selector;
12229 } else {
12230 rootElement = document.body;
12231 }
12232
12233 // Validating if root element is present in DOM
12234 if (!rootElement) {
12235 throw "Root element is not defined";
12236 }
12237
12238 // Adding the DOM element
12239 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
12240 rootElement.insertBefore(this.toastElement, elementToInsert);
12241
12242 // Repositioning the toasts in case multiple toasts are present
12243 Toastify.reposition();
12244
12245 if (this.options.duration > 0) {
12246 this.toastElement.timeOutValue = window.setTimeout(
12247 function() {
12248 // Remove the toast from DOM
12249 this.removeElement(this.toastElement);
12250 }.bind(this),
12251 this.options.duration
12252 ); // Binding `this` for function invocation
12253 }
12254
12255 // Supporting function chaining
12256 return this;
12257 },
12258
12259 hideToast: function() {
12260 if (this.toastElement.timeOutValue) {
12261 clearTimeout(this.toastElement.timeOutValue);
12262 }
12263 this.removeElement(this.toastElement);
12264 },
12265
12266 // Removing the element from the DOM
12267 removeElement: function(toastElement) {
12268 // Hiding the element
12269 // toastElement.classList.remove("on");
12270 toastElement.className = toastElement.className.replace(" on", "");
12271
12272 // Removing the element from DOM after transition end
12273 window.setTimeout(
12274 function() {
12275 // remove options node if any
12276 if (this.options.node && this.options.node.parentNode) {
12277 this.options.node.parentNode.removeChild(this.options.node);
12278 }
12279
12280 // Remove the element from the DOM, only when the parent node was not removed before.
12281 if (toastElement.parentNode) {
12282 toastElement.parentNode.removeChild(toastElement);
12283 }
12284
12285 // Calling the callback function
12286 this.options.callback.call(toastElement);
12287
12288 // Repositioning the toasts again
12289 Toastify.reposition();
12290 }.bind(this),
12291 400
12292 ); // Binding `this` for function invocation
12293 },
12294 };
12295
12296 // Positioning the toasts on the DOM
12297 Toastify.reposition = function() {
12298
12299 // Top margins with gravity
12300 var topLeftOffsetSize = {
12301 top: 15,
12302 bottom: 15,
12303 };
12304 var topRightOffsetSize = {
12305 top: 15,
12306 bottom: 15,
12307 };
12308 var offsetSize = {
12309 top: 15,
12310 bottom: 15,
12311 };
12312
12313 // Get all toast messages on the DOM
12314 var allToasts = document.getElementsByClassName("toastify");
12315
12316 var classUsed;
12317
12318 // Modifying the position of each toast element
12319 for (var i = 0; i < allToasts.length; i++) {
12320 // Getting the applied gravity
12321 if (containsClass(allToasts[i], "toastify-top") === true) {
12322 classUsed = "toastify-top";
12323 } else {
12324 classUsed = "toastify-bottom";
12325 }
12326
12327 var height = allToasts[i].offsetHeight;
12328 classUsed = classUsed.substr(9, classUsed.length-1)
12329 // Spacing between toasts
12330 var offset = 15;
12331
12332 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
12333
12334 // Show toast in center if screen with less than or equal to 360px
12335 if (width <= 360) {
12336 // Setting the position
12337 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
12338
12339 offsetSize[classUsed] += height + offset;
12340 } else {
12341 if (containsClass(allToasts[i], "toastify-left") === true) {
12342 // Setting the position
12343 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
12344
12345 topLeftOffsetSize[classUsed] += height + offset;
12346 } else {
12347 // Setting the position
12348 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
12349
12350 topRightOffsetSize[classUsed] += height + offset;
12351 }
12352 }
12353 }
12354
12355 // Supporting function chaining
12356 return this;
12357 };
12358
12359 // Helper function to get offset.
12360 function getAxisOffsetAValue(axis, options) {
12361
12362 if(options.offset[axis]) {
12363 if(isNaN(options.offset[axis])) {
12364 return options.offset[axis];
12365 }
12366 else {
12367 return options.offset[axis] + 'px';
12368 }
12369 }
12370
12371 return '0px';
12372
12373 }
12374
12375 function containsClass(elem, yourClass) {
12376 if (!elem || typeof yourClass !== "string") {
12377 return false;
12378 } else if (
12379 elem.className &&
12380 elem.className
12381 .trim()
12382 .split(/\s+/gi)
12383 .indexOf(yourClass) > -1
12384 ) {
12385 return true;
12386 } else {
12387 return false;
12388 }
12389 }
12390
12391 // Setting up the prototype for the init object
12392 Toastify.lib.init.prototype = Toastify.lib;
12393
12394 // Returning the Toastify function to be assigned to the window object/module
12395 return Toastify;
12396 });
12397
12398
12399 /***/ }
12400
12401 /******/ });
12402 /************************************************************************/
12403 /******/ // The module cache
12404 /******/ const __webpack_module_cache__ = {};
12405 /******/
12406 /******/ // The require function
12407 /******/ function __webpack_require__(moduleId) {
12408 /******/ // Check if module is in cache
12409 /******/ const cachedModule = __webpack_module_cache__[moduleId];
12410 /******/ if (cachedModule !== undefined) {
12411 /******/ return cachedModule.exports;
12412 /******/ }
12413 /******/ // Create a new module (and put it into the cache)
12414 /******/ const module = __webpack_module_cache__[moduleId] = {
12415 /******/ id: moduleId,
12416 /******/ // no module.loaded needed
12417 /******/ exports: {}
12418 /******/ };
12419 /******/
12420 /******/ // Execute the module function
12421 /******/ if (!(moduleId in __webpack_modules__)) {
12422 /******/ delete __webpack_module_cache__[moduleId];
12423 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
12424 /******/ e.code = 'MODULE_NOT_FOUND';
12425 /******/ throw e;
12426 /******/ }
12427 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
12428 /******/
12429 /******/ // Return the exports of the module
12430 /******/ return module.exports;
12431 /******/ }
12432 /******/
12433 /************************************************************************/
12434 /******/ /* webpack/runtime/compat get default export */
12435 /******/ (() => {
12436 /******/ // getDefaultExport function for compatibility with non-harmony modules
12437 /******/ __webpack_require__.n = (module) => {
12438 /******/ const getter = module && module.__esModule ?
12439 /******/ () => (module['default']) :
12440 /******/ () => (module);
12441 /******/ __webpack_require__.d(getter, { a: getter });
12442 /******/ return getter;
12443 /******/ };
12444 /******/ })();
12445 /******/
12446 /******/ /* webpack/runtime/define property getters */
12447 /******/ (() => {
12448 /******/ // define getter/value functions for harmony exports
12449 /******/ __webpack_require__.d = (exports, definition) => {
12450 /******/ if(Array.isArray(definition)) {
12451 /******/ var i = 0;
12452 /******/ while(i < definition.length) {
12453 /******/ var key = definition[i++];
12454 /******/ var binding = definition[i++];
12455 /******/ if(!__webpack_require__.o(exports, key)) {
12456 /******/ if(binding === 0) {
12457 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
12458 /******/ } else {
12459 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
12460 /******/ }
12461 /******/ } else if(binding === 0) { i++; }
12462 /******/ }
12463 /******/ } else {
12464 /******/ for(var key in definition) {
12465 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
12466 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
12467 /******/ }
12468 /******/ }
12469 /******/ }
12470 /******/ };
12471 /******/ })();
12472 /******/
12473 /******/ /* webpack/runtime/hasOwnProperty shorthand */
12474 /******/ (() => {
12475 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
12476 /******/ })();
12477 /******/
12478 /******/ /* webpack/runtime/make namespace object */
12479 /******/ (() => {
12480 /******/ // define __esModule on exports
12481 /******/ __webpack_require__.r = (exports) => {
12482 /******/ if(Symbol.toStringTag) {
12483 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
12484 /******/ }
12485 /******/ Object.defineProperty(exports, '__esModule', { value: true });
12486 /******/ };
12487 /******/ })();
12488 /******/
12489 /******/ /* webpack/runtime/nonce */
12490 /******/ (() => {
12491 /******/ __webpack_require__.nc = undefined;
12492 /******/ })();
12493 /******/
12494 /************************************************************************/
12495 let __webpack_exports__ = {};
12496 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
12497 (() => {
12498 "use strict";
12499 /*!********************************************!*\
12500 !*** ./assets/src/js/admin/edit-course.js ***!
12501 \********************************************/
12502 __webpack_require__.r(__webpack_exports__);
12503 /* 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");
12504 /* 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");
12505 /* 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");
12506 /**
12507 * Edit course JS handler.
12508 *
12509 * @since 4.3.0
12510 * @version 1.0.0
12511 */
12512
12513
12514
12515 new _edit_course_edit_curriculum_js__WEBPACK_IMPORTED_MODULE_0__.EditCourseCurriculum();
12516 new _generate_with_openai_js__WEBPACK_IMPORTED_MODULE_1__.GenerateWithOpenai();
12517 new _edit_course_edit_curriculum_edit_curriculum_ai_js__WEBPACK_IMPORTED_MODULE_2__.EditCurriculumAi();
12518 })();
12519
12520 /******/ })()
12521 ;
12522 //# sourceMappingURL=edit-course.js.map