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

profile.js in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.5, at assets/js/dist/frontend/profile.js

11,582 lines 416.6 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/courses/view-students-modal.js"
5 /*!************************************************************!*\
6 !*** ./assets/src/js/admin/courses/view-students-modal.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 */ ViewStudentsModal: () => (/* binding */ ViewStudentsModal)
14 /* harmony export */ });
15 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
16 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_0__);
17 /* harmony import */ var lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lpAssetsJsPath/utils.js */ "./assets/src/js/utils.js");
18
19
20 class ViewStudentsModal {
21 constructor() {
22 this.isRequesting = false;
23 this.activeCourseId = 0;
24 this.init();
25 }
26 static selectors = {
27 wrap: '#lp-modal-enrolled-wrap',
28 form: '#lp-modal-enrolled-form',
29 toolbarTemplate: '#lp-tmpl-enrolled-students-toolbar-modal',
30 targetTemplate: '#lp-tmpl-enrolled-students-target-modal',
31 toolbar: '.lp-enrolled-students-table-toolbar--modal',
32 courseTrigger: '.lp-btn-view-students',
33 searchInput: '#lp-modal-enrolled-search-input',
34 startDateInput: '#lp-modal-enrolled-filter-start-date',
35 endDateInput: '#lp-modal-enrolled-filter-end-date',
36 searchBtn: '.lp-enrolled-btn-search-modal',
37 clearBtn: '.lp-enrolled-btn-clear-modal',
38 modalSearchFields: '#lp-modal-enrolled-search-input, #lp-modal-enrolled-filter-start-date, #lp-modal-enrolled-filter-end-date'
39 };
40 setButtonLoadingState(btn, isLoading) {
41 if (!btn) {
42 return;
43 }
44 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.lpSetLoadingEl(btn, isLoading ? 1 : 0);
45 btn.disabled = !!isLoading;
46 }
47 init() {
48 if (ViewStudentsModal._loadedEvents) {
49 return;
50 }
51 ViewStudentsModal._loadedEvents = true;
52 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('click', [{
53 selector: ViewStudentsModal.selectors.courseTrigger,
54 class: this,
55 callBack: this.handleOpenModal.name
56 }, {
57 selector: ViewStudentsModal.selectors.searchBtn,
58 class: this,
59 callBack: this.handleModalSearch.name
60 }, {
61 selector: ViewStudentsModal.selectors.clearBtn,
62 class: this,
63 callBack: this.handleModalClear.name
64 }]);
65 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('keydown', [{
66 selector: ViewStudentsModal.selectors.modalSearchFields,
67 class: this,
68 callBack: this.handleModalSearchOnEnter.name,
69 checkIsEventEnter: true
70 }]);
71 lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.eventHandlers('change', [{
72 selector: ViewStudentsModal.selectors.startDateInput,
73 class: this,
74 callBack: this.checkDatesRange.name
75 }, {
76 selector: ViewStudentsModal.selectors.endDateInput,
77 class: this,
78 callBack: this.checkDatesRange.name
79 }]);
80 }
81 handleOpenModal(args) {
82 const btn = args?.target?.closest(ViewStudentsModal.selectors.courseTrigger);
83 if (!btn || this.isRequesting || btn.classList.contains('loading') || btn.disabled) {
84 return;
85 }
86 const courseId = parseInt(btn.dataset.courseId, 10) || 0;
87 if (!courseId) {
88 return;
89 }
90 const courseTitle = btn.dataset.courseTitle || '';
91 this.activeCourseId = courseId;
92 this.setButtonLoadingState(btn, true);
93 this.openModal(courseId, courseTitle, btn);
94 }
95 handleModalSearch(args) {
96 const btn = args?.target?.closest(ViewStudentsModal.selectors.searchBtn);
97 if (!btn || !this.activeCourseId) {
98 return;
99 }
100 if (args?.e) {
101 args.e.preventDefault();
102 }
103 if (this.isRequesting || btn.classList.contains('loading') || btn.disabled) {
104 return;
105 }
106 this.setButtonLoadingState(btn, true);
107 this.loadEnrolledStudents(this.activeCourseId, 1, btn);
108 }
109 handleModalSearchOnEnter(args) {
110 if (args?.e) {
111 args.e.preventDefault();
112 }
113 const form = this.getModalForm();
114 if (!form) {
115 return;
116 }
117 const btn = form.querySelector(ViewStudentsModal.selectors.searchBtn);
118 if (!btn) {
119 return;
120 }
121 this.handleModalSearch({
122 ...args,
123 target: btn
124 });
125 }
126 handleModalClear(args) {
127 const btn = args?.target?.closest(ViewStudentsModal.selectors.clearBtn);
128 const form = this.getModalForm();
129 if (!btn || !form || !this.activeCourseId) {
130 return;
131 }
132 if (args?.e) {
133 args.e.preventDefault();
134 }
135 if (this.isRequesting || btn.classList.contains('loading') || btn.disabled) {
136 return;
137 }
138 form.reset();
139 this.setButtonLoadingState(btn, true);
140 this.loadEnrolledStudents(this.activeCourseId, 1, btn);
141 }
142 getModalPopup() {
143 return (sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().getPopup) ? sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().getPopup() : null;
144 }
145 getModalToolbarHtml() {
146 const template = document.querySelector(ViewStudentsModal.selectors.toolbarTemplate);
147 return template ? template.innerHTML : '';
148 }
149 getModalTargetHtml() {
150 const template = document.querySelector(ViewStudentsModal.selectors.targetTemplate);
151 return template ? template.innerHTML : '';
152 }
153 getAjaxHandle() {
154 const ajaxHandle = window.lpAJAXG;
155 if (!ajaxHandle || typeof ajaxHandle.getDataSetCurrent !== 'function' || typeof ajaxHandle.setDataSetCurrent !== 'function' || typeof ajaxHandle.showHideLoading !== 'function' || typeof ajaxHandle.fetchAJAX !== 'function') {
156 return null;
157 }
158 return ajaxHandle;
159 }
160 getModalForm() {
161 const popup = this.getModalPopup();
162 if (!popup) {
163 return null;
164 }
165 return popup.querySelector(ViewStudentsModal.selectors.form);
166 }
167 getModalFilterArgs(dataArgs = {}) {
168 const form = this.getModalForm();
169 if (!form) {
170 return dataArgs;
171 }
172 return lpAssetsJsPath_utils_js__WEBPACK_IMPORTED_MODULE_1__.mergeDataWithDatForm(form, dataArgs);
173 }
174 loadEnrolledStudents(courseId, paged, elLoading = null) {
175 const wrap = document.querySelector(ViewStudentsModal.selectors.wrap);
176 const elTarget = wrap?.querySelector('.lp-target');
177 const ajaxHandle = this.getAjaxHandle();
178 if (!wrap || !elTarget || !ajaxHandle || this.isRequesting) {
179 return;
180 }
181 this.isRequesting = true;
182 if (elLoading) {
183 this.setButtonLoadingState(elLoading, true);
184 }
185 const dataSend = ajaxHandle.getDataSetCurrent(elTarget);
186 dataSend.args = this.getModalFilterArgs(dataSend.args || {});
187 dataSend.args.course_id = parseInt(courseId, 10) || 0;
188 dataSend.args.paged = paged;
189 ajaxHandle.setDataSetCurrent(elTarget, dataSend);
190 ajaxHandle.showHideLoading(elTarget, 1);
191 const callBack = {
192 success: response => {
193 elTarget.innerHTML = response.data.content;
194 },
195 error: err => {
196 console.error(err);
197 },
198 completed: () => {
199 this.isRequesting = false;
200 ajaxHandle.showHideLoading(elTarget, 0);
201 if (elLoading) {
202 this.setButtonLoadingState(elLoading, false);
203 }
204 }
205 };
206 ajaxHandle.fetchAJAX(dataSend, callBack);
207 }
208 openModal(courseId, courseTitle, elTrigger = null) {
209 const modalToolbarHtml = this.getModalToolbarHtml();
210 const modalTargetHtml = this.getModalTargetHtml();
211 if (!modalToolbarHtml || !modalTargetHtml) {
212 if (elTrigger) {
213 this.setButtonLoadingState(elTrigger, false);
214 }
215 return;
216 }
217 this.activeCourseId = parseInt(courseId, 10) || 0;
218 sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
219 title: `${courseTitle}`,
220 html: modalToolbarHtml + modalTargetHtml,
221 width: '80%',
222 showConfirmButton: false,
223 showCloseButton: true,
224 didOpen: () => {
225 this.loadEnrolledStudents(this.activeCourseId, 1, elTrigger);
226 },
227 didClose: () => {
228 this.activeCourseId = 0;
229 if (elTrigger) {
230 this.setButtonLoadingState(elTrigger, false);
231 }
232 }
233 });
234 }
235
236 // Ensure start date is not after end date and vice versa. If invalid, adjust the other date to match.
237 checkDatesRange(args) {
238 const {
239 e
240 } = args;
241 const elInput = e?.target;
242 if (!elInput) {
243 return;
244 }
245 const elForm = elInput.closest(ViewStudentsModal.selectors.form);
246 if (!elForm) {
247 return;
248 }
249 const startDateInput = elForm.querySelector(ViewStudentsModal.selectors.startDateInput);
250 const endDateInput = elForm.querySelector(ViewStudentsModal.selectors.endDateInput);
251 if (elInput === startDateInput) {
252 if (startDateInput.value) {
253 endDateInput.min = startDateInput.value;
254 if (endDateInput.value && endDateInput.value < startDateInput.value) {
255 endDateInput.value = startDateInput.value;
256 }
257 } else {
258 endDateInput.min = '';
259 }
260 } else if (elInput === endDateInput) {
261 if (endDateInput.value) {
262 startDateInput.max = endDateInput.value;
263 if (startDateInput.value && startDateInput.value > endDateInput.value) {
264 startDateInput.value = endDateInput.value;
265 }
266 } else {
267 startDateInput.max = '';
268 }
269 }
270 }
271 }
272
273 /***/ },
274
275 /***/ "./assets/src/js/api.js"
276 /*!******************************!*\
277 !*** ./assets/src/js/api.js ***!
278 \******************************/
279 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
280
281 "use strict";
282 __webpack_require__.r(__webpack_exports__);
283 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
284 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
285 /* harmony export */ });
286 /**
287 * List API on backend
288 *
289 * @since 4.2.6
290 * @version 1.0.2
291 */
292
293 const lplistAPI = {};
294 let lp_rest_url;
295 if ('undefined' !== typeof lpDataAdmin) {
296 lp_rest_url = lpDataAdmin.lp_rest_url;
297 lplistAPI.admin = {
298 apiAdminNotice: lp_rest_url + 'lp/v1/admin/tools/admin-notices',
299 apiAddons: lp_rest_url + 'lp/v1/addon/all',
300 apiAddonAction: lp_rest_url + 'lp/v1/addon/action-n',
301 apiAddonsPurchase: lp_rest_url + 'lp/v1/addon/info-addons-purchase',
302 apiSearchCourses: lp_rest_url + 'lp/v1/admin/tools/search-course',
303 apiSearchUsers: lp_rest_url + 'lp/v1/admin/tools/search-user',
304 apiAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/assign-user-course',
305 apiUnAssignUserCourse: lp_rest_url + 'lp/v1/admin/tools/unassign-user-course'
306 };
307 }
308 if ('undefined' !== typeof lpData) {
309 lp_rest_url = lpData.lp_rest_url;
310 lplistAPI.frontend = {
311 apiWidgets: lp_rest_url + 'lp/v1/widgets/api',
312 apiCourses: lp_rest_url + 'lp/v1/courses/archive-course',
313 // Deprecated API, don't load from v4.3.7
314 apiAJAX: lp_rest_url + 'lp/v1/load_content_via_ajax/',
315 // Deprecated since 4.3.0
316 apiProfileCoverImage: lp_rest_url + 'lp/v1/profile/cover-image'
317 };
318 }
319 if (lp_rest_url) {
320 lplistAPI.apiCourses = lp_rest_url + 'lp/v1/courses/';
321 lplistAPI.apiEditCoursesArchiveBlock = lp_rest_url + 'lp/v1/courses/edit-archive-block';
322 lplistAPI.apiCoursesSuggest = lp_rest_url + 'lp/v1/courses/courses-suggest';
323 }
324 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (lplistAPI);
325
326 /***/ },
327
328 /***/ "./assets/src/js/frontend/profile/avatar.js"
329 /*!**************************************************!*\
330 !*** ./assets/src/js/frontend/profile/avatar.js ***!
331 \**************************************************/
332 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
333
334 "use strict";
335 __webpack_require__.r(__webpack_exports__);
336 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
337 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
338 /* harmony export */ });
339 /* harmony import */ var cropperjs_dist_cropper_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! cropperjs/dist/cropper.css */ "./node_modules/cropperjs/dist/cropper.css");
340 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! cropperjs */ "./node_modules/cropperjs/dist/cropper.js");
341 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(cropperjs__WEBPACK_IMPORTED_MODULE_1__);
342 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
343 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
344 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_3__);
345 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
346
347
348
349 // import API from '../../api.js';
350
351
352 const profileAvatarImage = () => {
353 const lpAvatarWrapper = document.querySelector('#learnpress-avatar-upload');
354 if (!lpAvatarWrapper) {
355 return;
356 }
357 let cropper, avatarPreviewSrc, imgUrlOriginal;
358 let avatarForm = lpAvatarWrapper.querySelector('.lp_avatar__form');
359 const btnRemove = lpAvatarWrapper.querySelector('.lp-btn-remove-avatar'),
360 btnReplace = lpAvatarWrapper.querySelector('.lp-btn-choose-avatar'),
361 btnSave = lpAvatarWrapper.querySelector('.lp-btn-save-avatar'),
362 btnCancel = lpAvatarWrapper.querySelector('.lp-btn-cancel-avatar'),
363 avatarPreviewImage = lpAvatarWrapper.querySelector('.lp-avatar-image'),
364 avatarInputFile = lpAvatarWrapper.querySelector('#avatar-file'),
365 profileAvatar = document.querySelector('.wrapper-profile-header .user-avatar img');
366 const avatarRatio = parseFloat((lpProfileSettings.avatar_dimensions.width / lpProfileSettings.avatar_dimensions.height).toFixed(2));
367 lpAvatarWrapper.addEventListener('click', e => {
368 const target = e.target;
369 if (target === btnReplace) {
370 e.preventDefault();
371 avatarInputFile.click();
372 } else if (target === btnSave) {
373 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnSave, 1);
374 btnSave.disabled = true;
375 if (undefined !== cropper) {
376 const canvas = cropper.getCroppedCanvas({
377 width: lpProfileSettings.avatar_dimensions.width,
378 height: lpProfileSettings.avatar_dimensions.height
379 });
380 const newCropSrc = canvas.toDataURL('image/png');
381 if (profileAvatar) {
382 profileAvatar.src = newCropSrc;
383 }
384 avatarPreviewImage.src = newCropSrc;
385 const formData = new FormData();
386 formData.append('file', newCropSrc);
387 uploadAvatar(formData);
388 }
389 } else if (target === btnCancel) {
390 e.preventDefault();
391 cropper.destroy();
392 avatarPreviewImage.src = imgUrlOriginal;
393 if (imgUrlOriginal === window.location.href) {
394 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarForm, 1);
395 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnReplace, 0);
396 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 0);
397 } else {
398 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 1);
399 }
400 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnSave, 0);
401 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnCancel, 0);
402 } else if (target === btnRemove) {
403 btnRemove.disabled = true;
404 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnRemove, 1);
405 removeAvatar();
406 }
407 });
408 lpAvatarWrapper.addEventListener('change', e => {
409 const target = e.target;
410 if (target === avatarInputFile) {
411 const file = avatarInputFile.files[0];
412 if (!file) {
413 return;
414 }
415 const allowType = ['image/png', 'image/jpeg', 'image/webp'];
416 if (allowType.indexOf(file.type) < 0) {
417 return;
418 }
419 const reader = new FileReader();
420 reader.onload = function (e) {
421 avatarPreviewImage.src = e.target.result;
422 // Destroy previous cropper instance if any
423 if (cropper) {
424 cropper.destroy();
425 }
426 // Initialize cropper
427 cropper = new (cropperjs__WEBPACK_IMPORTED_MODULE_1___default())(avatarPreviewImage, {
428 aspectRatio: avatarRatio,
429 viewMode: 1,
430 zoomOnWheel: false
431 });
432 };
433 reader.readAsDataURL(file);
434 if (!avatarPreviewImage.classList.contains('lp-hidden')) {
435 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 1);
436 }
437 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarForm, 0);
438 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnSave, 1);
439 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnReplace, 1);
440 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnCancel, 1);
441 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 0);
442 }
443 });
444 const uploadAvatar = formData => {
445 fetch(`${lpData.lp_rest_url}lp/v1/profile/upload-avatar`, {
446 method: 'POST',
447 headers: {
448 'X-WP-Nonce': lpData.nonce
449 },
450 body: formData
451 }) // wrapped
452 .then(res => res.json()).then(res => {
453 if (res.status === 'error') {
454 throw new Error(res.message);
455 }
456 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 1);
457 showMessage('success', res.message);
458 if (undefined !== cropper) {
459 cropper.destroy();
460 }
461 imgUrlOriginal = avatarPreviewImage.src;
462 }).finally(() => {
463 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnSave, 0);
464 btnSave.disabled = false;
465 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnSave, 0);
466 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnCancel, 0);
467 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 1);
468 }).catch(err => console.log(err));
469 };
470 const removeAvatar = () => {
471 fetch(`${lpData.lp_rest_url}lp/v1/profile/remove-avatar`, {
472 method: 'POST',
473 headers: {
474 'X-WP-Nonce': lpData.nonce
475 }
476 }) // wrapped
477 .then(res => res.json()).then(res => {
478 if (res.status === 'error') {
479 throw new Error(res.message);
480 }
481 showMessage('success', res.message);
482 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarPreviewImage, 0);
483 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(avatarForm, 1);
484 imgUrlOriginal = avatarPreviewSrc = '';
485 profileAvatar.src = lpProfileSettings.default_avatar;
486 // window.location.href = window.location.href;
487 }).finally(() => {
488 btnRemove.disabled = false;
489 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnRemove, 0);
490 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(btnRemove, 0);
491 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(btnReplace, 0);
492 }).catch(err => console.log(err));
493 };
494 const showMessage = (status, message) => {
495 toastify_js__WEBPACK_IMPORTED_MODULE_3___default()({
496 text: message,
497 gravity: lpData.toast.gravity,
498 // `top` or `bottom`
499 position: lpData.toast.position,
500 // `left`, `center` or `right`
501 className: `${lpData.toast.classPrefix} ${status}`,
502 close: lpData.toast.close == 1,
503 stopOnFocus: lpData.toast.stopOnFocus == 1,
504 duration: lpData.toast.duration
505 }).showToast();
506 };
507 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpOnElementReady('.lp-avatar-image', () => {
508 imgUrlOriginal = avatarPreviewImage.src;
509 });
510 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpOnElementReady('#learnpress-avatar-upload', e => {
511 e.scrollIntoView({
512 behavior: 'smooth',
513 block: 'center'
514 });
515 });
516 };
517 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (profileAvatarImage);
518
519 /***/ },
520
521 /***/ "./assets/src/js/frontend/profile/course-tab.js"
522 /*!******************************************************!*\
523 !*** ./assets/src/js/frontend/profile/course-tab.js ***!
524 \******************************************************/
525 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
526
527 "use strict";
528 __webpack_require__.r(__webpack_exports__);
529 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
530 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
531 /* harmony export */ });
532 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
533
534
535 // Rest API load content course enrolled, created - Nhamdv.
536 const courseTab = () => {
537 const elements = document.querySelectorAll('.learn-press-course-tab__filter__content');
538 const getResponse = (ele, dataset, append = false, viewMoreEle = false) => {
539 let url = lpData.lp_rest_url + 'lp/v1/profile/course-tab';
540 url = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpAddQueryArgs)(url, dataset);
541 const callBack = {
542 success: response => {
543 const skeleton = ele.querySelector('.lp-skeleton-animation');
544 skeleton && skeleton.remove();
545 if (response.status === 'success' && response.data) {
546 if (append) {
547 ele.innerHTML += response.data;
548 } else {
549 ele.innerHTML = response.data;
550 }
551 } else if (append) {
552 ele.innerHTML += `<div class="lp-ajax-message" style="display:block">${response.message && response.message}</div>`;
553 } else {
554 ele.innerHTML = `<div class="lp-ajax-message" style="display:block">${response.message && response.message}</div>`;
555 }
556 if (viewMoreEle) {
557 viewMoreEle.classList.remove('loading');
558 const paged = parseInt(viewMoreEle.dataset.paged);
559 const numberPage = parseInt(viewMoreEle.dataset.number);
560 if (numberPage <= paged) {
561 viewMoreEle.remove();
562 }
563 viewMoreEle.dataset.paged = paged + 1;
564 }
565 viewMore(ele, dataset);
566 },
567 error: error => {
568 console.log(error);
569 },
570 completed: () => {}
571 };
572 let paramsFetch = {};
573 if (0 !== parseInt(lpData.user_id)) {
574 paramsFetch = {
575 headers: {
576 'X-WP-Nonce': lpData.nonce
577 }
578 };
579 }
580 ;(0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpFetchAPI)(url, paramsFetch, callBack);
581 };
582 if ('IntersectionObserver' in window) {
583 const eleObserver = new IntersectionObserver((entries, observer) => {
584 entries.forEach(entry => {
585 if (entry.isIntersecting) {
586 const ele = entry.target;
587 const params = ele.parentNode.querySelector('.lp_profile_tab_input_param');
588 const data = {
589 ...JSON.parse(params.value),
590 status: ele.dataset.tab || ''
591 };
592 getResponse(ele, data);
593 eleObserver.unobserve(ele);
594 }
595 });
596 });
597 [...elements].map(ele => {
598 if (ele.dataset.tab !== 'all') {
599 eleObserver.observe(ele);
600 } else {
601 const params = ele.parentNode.querySelector('.lp_profile_tab_input_param');
602 const data = {
603 ...JSON.parse(params.value),
604 status: ele.dataset.tab === 'all' ? '' : ele.dataset.tab || ''
605 };
606 getResponse(ele, data);
607 }
608 });
609 }
610 const changeFilter = () => {
611 const tabs = document.querySelectorAll('.learn-press-course-tab-filters');
612 tabs.forEach(tab => {
613 const filters = tab.querySelectorAll('.learn-press-filters a');
614 filters.forEach(filter => {
615 filter.addEventListener('click', e => {
616 e.preventDefault();
617 const tabName = filter.dataset.tab;
618 [...filters].map(ele => {
619 ele.classList.remove('active');
620 });
621 filter.classList.add('active');
622 [...tab.querySelectorAll('.learn-press-course-tab__filter__content')].map(ele => {
623 ele.style.display = 'none';
624 if (ele.dataset.tab === tabName) {
625 ele.style.display = '';
626 }
627 });
628 });
629 });
630 });
631 };
632 changeFilter();
633 const viewMore = (ele, dataset) => {
634 const viewMoreEle = ele.querySelector('button[data-paged]');
635 if (viewMoreEle) {
636 viewMoreEle.addEventListener('click', e => {
637 e.preventDefault();
638 const paged = viewMoreEle && viewMoreEle.dataset.paged;
639 viewMoreEle.classList.add('loading');
640 const element = dataset.layout === 'list' ? '.lp_profile_course_progress' : '.learn-press-courses';
641 getResponse(ele.querySelector(element), {
642 ...dataset,
643 ...{
644 paged
645 }
646 }, true, viewMoreEle);
647 });
648 }
649 };
650 };
651 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (courseTab);
652
653 /***/ },
654
655 /***/ "./assets/src/js/frontend/profile/cover-image.js"
656 /*!*******************************************************!*\
657 !*** ./assets/src/js/frontend/profile/cover-image.js ***!
658 \*******************************************************/
659 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
660
661 "use strict";
662 __webpack_require__.r(__webpack_exports__);
663 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
664 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
665 /* harmony export */ });
666 /* harmony import */ var cropperjs_dist_cropper_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! cropperjs/dist/cropper.css */ "./node_modules/cropperjs/dist/cropper.css");
667 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! cropperjs */ "./node_modules/cropperjs/dist/cropper.js");
668 /* harmony import */ var cropperjs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(cropperjs__WEBPACK_IMPORTED_MODULE_1__);
669 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
670 /* harmony import */ var _api_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../api.js */ "./assets/src/js/api.js");
671 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
672 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_4__);
673 /* harmony import */ var toastify_js_src_toastify_css__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! toastify-js/src/toastify.css */ "./node_modules/toastify-js/src/toastify.css");
674
675
676
677
678
679
680 const profileCoverImage = () => {
681 const lpSet = new Set();
682 let cropper;
683 let elBtnSave, elBtnRemove, elBtnChoose, elBtnCancel, elImagePreview, elCoverImageBackground, elImgCoverImageBackground, elImageEmpty, formCoverImage, elInputFile, elAction, imgUrlOriginal;
684 const className = {
685 formCoverImage: 'lp-user-cover-image',
686 BtnChooseCoverImage: 'lp-btn-choose-cover-image',
687 BtnSaveCoverImage: 'lp-btn-save-cover-image',
688 BtnRemoveCoverImage: 'lp-btn-remove-cover-image',
689 BtnCancelCoverImage: 'lp-btn-cancel-cover-image',
690 BtnToEditCoverImage: 'lp-btn-to-edit-cover-image',
691 CoverImagePreview: 'lp-cover-image-preview',
692 CoverImageEmpty: 'lp-cover-image-empty',
693 CoverImageBackground: 'lp-user-cover-image_background',
694 InputFile: 'lp-cover-image-file',
695 loading: 'loading',
696 hidden: 'lp-hidden'
697 };
698
699 /**
700 * Get elements to use.
701 */
702 const getElements = () => {
703 elBtnSave = formCoverImage.querySelector(`.${className.BtnSaveCoverImage}`);
704 elBtnChoose = formCoverImage.querySelector(`.${className.BtnChooseCoverImage}`);
705 elBtnRemove = formCoverImage.querySelector(`.${className.BtnRemoveCoverImage}`);
706 elBtnCancel = formCoverImage.querySelector(`.${className.BtnCancelCoverImage}`);
707 elImagePreview = formCoverImage.querySelector(`.${className.CoverImagePreview}`);
708 elCoverImageBackground = document.querySelector(`.${className.CoverImageBackground}`);
709 elImgCoverImageBackground = elCoverImageBackground.querySelector(`img`);
710 elImageEmpty = formCoverImage.querySelector(`.${className.CoverImageEmpty}`);
711 elAction = formCoverImage.querySelector('input[name=action]');
712 elInputFile = formCoverImage.querySelector('input[name=lp-cover-image-file]');
713 if (!lpSet.has('everClick')) {
714 imgUrlOriginal = elImagePreview.src;
715 lpSet.add('everClick');
716 }
717 };
718 const fetchAPI = formData => {
719 const callBack = {
720 success: response => {
721 const {
722 status,
723 message,
724 data
725 } = response;
726 toastify_js__WEBPACK_IMPORTED_MODULE_4___default()({
727 text: message,
728 gravity: lpData.toast.gravity,
729 // `top` or `bottom`
730 position: lpData.toast.position,
731 // `left`, `center` or `right`
732 className: `${lpData.toast.classPrefix} ${status}`,
733 close: lpData.toast.close == 1,
734 stopOnFocus: lpData.toast.stopOnFocus == 1,
735 duration: lpData.toast.duration
736 }).showToast();
737 if ('remove' === data.action) {
738 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 0);
739 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnChoose, 0);
740 elImagePreview.src = '';
741 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 0);
742 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImageEmpty, 1);
743 if (elCoverImageBackground) {
744 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elCoverImageBackground, 0);
745 }
746 } else if ('upload' === data.action) {
747 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 1);
748 elImagePreview.src = data.url;
749 imgUrlOriginal = data.url;
750 cropper.destroy();
751 }
752 imgUrlOriginal = elImagePreview.src;
753 },
754 error: error => {
755 console.log(error);
756 },
757 completed: () => {
758 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnSave, 0);
759 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elBtnSave, 0);
760 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elBtnRemove, 0);
761 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnCancel, 0);
762 if (!elImagePreview.src || elImagePreview.src === window.location.href) {
763 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 0);
764 } else {
765 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 1);
766 }
767 }
768 };
769 const url = _api_js__WEBPACK_IMPORTED_MODULE_3__["default"].frontend.apiProfileCoverImage;
770 const option = {
771 headers: {}
772 };
773 if (0 !== parseInt(lpData.user_id)) {
774 option.headers['X-WP-Nonce'] = lpData.nonce;
775 }
776 option.method = 'POST';
777 option.body = formData;
778 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpFetchAPI(url, option, callBack);
779 };
780
781 // Events
782 document.addEventListener('click', e => {
783 const target = e.target;
784 if (target.classList.contains(className.BtnToEditCoverImage)) {
785 formCoverImage = document.querySelector(`.${className.formCoverImage}`);
786 if (!formCoverImage) {
787 return;
788 }
789 const isCorrectSection = target.dataset.sectionCorrect == 1;
790 if (isCorrectSection) {
791 e.preventDefault();
792 formCoverImage.scrollIntoView({
793 behavior: 'smooth',
794 block: 'center'
795 });
796 }
797 }
798 formCoverImage = target.closest(`.${className.formCoverImage}`);
799 if (!formCoverImage) {
800 return;
801 }
802 getElements();
803 if (target.classList.contains(className.BtnChooseCoverImage)) {
804 e.preventDefault();
805 elInputFile.click();
806 }
807 if (target.classList.contains(className.BtnSaveCoverImage)) {
808 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(elBtnSave, 1);
809 }
810 if (target.classList.contains(className.BtnCancelCoverImage)) {
811 e.preventDefault();
812 cropper.destroy();
813 elImagePreview.src = imgUrlOriginal;
814 if (imgUrlOriginal === window.location.href) {
815 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImageEmpty, 1);
816 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnChoose, 0);
817 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 0);
818 } else {
819 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 1);
820 }
821 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnSave, 0);
822 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnCancel, 0);
823 }
824 if (target.classList.contains(className.BtnRemoveCoverImage)) {
825 e.preventDefault();
826 target.classList.add('loading');
827 if (cropper) {
828 cropper.destroy();
829 cropper = undefined;
830 }
831 elAction.value = 'remove';
832 elBtnSave.click();
833 }
834 if (target.classList.contains(className.CoverImageEmpty)) {
835 e.preventDefault();
836 elInputFile.click();
837 }
838 });
839 document.addEventListener('change', e => {
840 const target = e.target;
841 formCoverImage = target.closest(`.${className.formCoverImage}`);
842 if (!formCoverImage) {
843 return;
844 }
845 getElements();
846 if (target.classList.contains(className.InputFile)) {
847 e.preventDefault();
848 const file = target.files[0];
849 if (!file) {
850 return;
851 }
852 const allowType = ['image/png', 'image/jpeg', 'image/webp'];
853 if (allowType.indexOf(file.type) < 0) {
854 return;
855 }
856 elAction.value = 'upload';
857 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImagePreview, 1);
858 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elImageEmpty, 0);
859 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnRemove, 0);
860 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnSave, 1);
861 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnChoose, 1);
862 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elBtnCancel, 1);
863 const reader = new FileReader();
864 reader.onload = function (e) {
865 elImagePreview.src = e.target.result;
866 // Destroy previous cropper instance if any
867 if (cropper) {
868 cropper.destroy();
869 }
870 // Initialize cropper
871 cropper = new (cropperjs__WEBPACK_IMPORTED_MODULE_1___default())(elImagePreview, {
872 aspectRatio: lpData.coverImageRatio,
873 viewMode: 1,
874 zoomOnWheel: false
875 });
876 };
877 reader.readAsDataURL(file);
878 }
879 });
880 document.addEventListener('submit', e => {
881 const target = e.target;
882 if (target.classList.contains(className.formCoverImage)) {
883 e.preventDefault();
884 const formData = new FormData(target);
885 if (undefined !== cropper) {
886 const canvas = cropper.getCroppedCanvas({});
887 if (elCoverImageBackground) {
888 const dataUrl = canvas.toDataURL('image/png');
889 elCoverImageBackground.style.backgroundImage = `url(${dataUrl})`;
890 elImgCoverImageBackground.src = dataUrl;
891 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpShowHideEl(elCoverImageBackground, 1);
892 }
893 canvas.toBlob(blob => {
894 formData.append('image', blob, 'cover.png');
895 fetchAPI(formData);
896 }, 'image/png');
897 } else {
898 fetchAPI(formData);
899 }
900 }
901 });
902 document.addEventListener('DOMContentLoaded', e => {
903 const elBtnToEditCoverImage = document.querySelector(`.${className.BtnToEditCoverImage}`);
904 const formCoverImage = document.querySelector(`.${className.formCoverImage}`);
905 if (elBtnToEditCoverImage && formCoverImage) {
906 const isCorrectSection = elBtnToEditCoverImage.dataset.sectionCorrect == 1;
907 if (isCorrectSection) {
908 formCoverImage.scrollIntoView({
909 behavior: 'smooth',
910 block: 'center'
911 });
912 }
913 }
914 });
915 };
916 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (profileCoverImage);
917
918 /***/ },
919
920 /***/ "./assets/src/js/frontend/profile/order-recover.js"
921 /*!*********************************************************!*\
922 !*** ./assets/src/js/frontend/profile/order-recover.js ***!
923 \*********************************************************/
924 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
925
926 "use strict";
927 __webpack_require__.r(__webpack_exports__);
928 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
929 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
930 /* harmony export */ });
931 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
932 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
933 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_1__);
934
935
936
937 /**
938 * JS Recover order
939 *
940 * @since 4.0.0
941 * @version 1.0.1
942 */
943 const recoverOrder = () => {
944 const toastify = toastify_js__WEBPACK_IMPORTED_MODULE_1___default()({
945 gravity: lpData.toast.gravity,
946 // `top` or `bottom`
947 position: lpData.toast.position,
948 // `left`, `center` or `right`
949 close: lpData.toast.close == 1,
950 className: `${lpData.toast.classPrefix}`,
951 stopOnFocus: lpData.toast.stopOnFocus == 1,
952 duration: lpData.toast.duration
953 });
954
955 // Events
956 document.addEventListener('submit', e => {
957 const target = e.target;
958 if (target.classList.contains('lp-order-recover')) {
959 e.preventDefault();
960 ajaxRecover(target);
961 }
962 });
963 const ajaxRecover = form => {
964 const status = 'error';
965 const btnSubmit = form.querySelector('.button-recover-order');
966 if (!btnSubmit) {
967 return;
968 }
969 ;(0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl)(btnSubmit, 1);
970 const url = new URL(window.location.href);
971 fetch(url, {
972 method: 'POST',
973 body: new FormData(form)
974 }).then(response => {
975 return response.json();
976 }).then(res => {
977 const {
978 status,
979 data: {
980 redirect
981 },
982 message
983 } = res;
984 if (status === 'success') {
985 toastify.options.text = message;
986 toastify.options.className += ` ${status}`;
987 toastify.showToast();
988 if (redirect) {
989 window.location.href = redirect;
990 }
991 btnSubmit.remove();
992 } else {
993 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpSetLoadingEl)(btnSubmit, 0);
994 throw new Error(message);
995 }
996 }).finally(() => {}).catch(err => {
997 toastify.options.text = err.message;
998 toastify.options.className += ` ${status}`;
999 toastify.showToast();
1000 });
1001 };
1002 };
1003 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (recoverOrder);
1004
1005 /***/ },
1006
1007 /***/ "./assets/src/js/frontend/profile/order-refund.js"
1008 /*!********************************************************!*\
1009 !*** ./assets/src/js/frontend/profile/order-refund.js ***!
1010 \********************************************************/
1011 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1012
1013 "use strict";
1014 __webpack_require__.r(__webpack_exports__);
1015 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1016 /* harmony export */ OrderRefund: () => (/* binding */ OrderRefund),
1017 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
1018 /* harmony export */ });
1019 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sweetalert2 */ "./node_modules/sweetalert2/dist/sweetalert2.all.js");
1020 /* harmony import */ var sweetalert2__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sweetalert2__WEBPACK_IMPORTED_MODULE_0__);
1021 /* harmony import */ var _lpToastify__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../lpToastify */ "./assets/src/js/lpToastify.js");
1022 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
1023
1024
1025
1026
1027 /**
1028 * Order Refund Script
1029 *
1030 * Handle refund action on profile orders list.
1031 *
1032 * @since 4.3.5
1033 * @version 1.0.0
1034 */
1035 class OrderRefund {
1036 constructor() {
1037 this.isRequesting = false;
1038 }
1039 static selectors = {
1040 actionRefund: '.lp-refund-order-action'
1041 };
1042 init() {
1043 this.events();
1044 }
1045 events() {
1046 if (OrderRefund._loadedEvents) {
1047 return;
1048 }
1049 OrderRefund._loadedEvents = this;
1050 _utils_js__WEBPACK_IMPORTED_MODULE_2__.eventHandlers('click', [{
1051 selector: OrderRefund.selectors.actionRefund,
1052 class: this,
1053 callBack: this.handleRefundClick.name
1054 }]);
1055 }
1056 getAjaxHandle() {
1057 const ajaxHandle = window.lpAJAXG;
1058 if (!ajaxHandle || typeof ajaxHandle.fetchAJAX !== 'function') {
1059 return null;
1060 }
1061 return ajaxHandle;
1062 }
1063 setActionLoadingState(actionLink, isLoading) {
1064 if (!actionLink) {
1065 return;
1066 }
1067 if (isLoading) {
1068 actionLink.dataset.refundSubmitting = 'yes';
1069 } else {
1070 delete actionLink.dataset.refundSubmitting;
1071 }
1072 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpSetLoadingEl(actionLink, isLoading ? 1 : 0);
1073 }
1074 getActionData(actionLink) {
1075 const reasonMin = parseInt(actionLink.dataset.reasonMin || '10', 10);
1076 return {
1077 orderId: parseInt(actionLink.dataset.orderId || '0', 10),
1078 requireReason: actionLink.dataset.requireReason === 'yes',
1079 reasonMin: Number.isNaN(reasonMin) ? 10 : reasonMin,
1080 reasonPrompt: actionLink.dataset.reasonPrompt || '',
1081 reasonPlaceholder: actionLink.dataset.reasonPlaceholder || '',
1082 reasonRequired: actionLink.dataset.reasonRequired || '',
1083 confirmTitle: actionLink.dataset.confirmTitle || '',
1084 confirmText: actionLink.dataset.confirmText || '',
1085 confirmButton: actionLink.dataset.confirmButton || '',
1086 cancelButton: actionLink.dataset.cancelButton || ''
1087 };
1088 }
1089 openReasonModal(data) {
1090 return sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
1091 title: data.reasonPrompt,
1092 input: 'textarea',
1093 inputPlaceholder: data.reasonPlaceholder,
1094 inputAutoTrim: true,
1095 showCancelButton: true,
1096 confirmButtonText: data.confirmButton,
1097 cancelButtonText: data.cancelButton,
1098 inputValidator: value => {
1099 const reason = (value || '').trim();
1100 if (!reason.length) {
1101 return data.reasonRequired;
1102 }
1103 return undefined;
1104 }
1105 });
1106 }
1107 openConfirmModal(data) {
1108 return sweetalert2__WEBPACK_IMPORTED_MODULE_0___default().fire({
1109 icon: 'warning',
1110 title: data.confirmTitle,
1111 text: data.confirmText,
1112 showCancelButton: true,
1113 confirmButtonText: data.confirmButton,
1114 cancelButtonText: data.cancelButton
1115 });
1116 }
1117 sendRefundRequest(actionLink, data, reason = '') {
1118 const ajaxHandle = this.getAjaxHandle();
1119 if (!ajaxHandle) {
1120 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Refund action is unavailable right now.', 'error');
1121 return;
1122 }
1123 if (!data.orderId) {
1124 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show('Invalid order.', 'error');
1125 return;
1126 }
1127 this.isRequesting = true;
1128 this.setActionLoadingState(actionLink, true);
1129 const dataSend = {
1130 action: 'request_refund_order',
1131 order_id: data.orderId,
1132 reason
1133 };
1134 ajaxHandle.fetchAJAX(dataSend, {
1135 success: response => {
1136 const {
1137 status,
1138 message,
1139 data
1140 } = response;
1141 if (status !== 'success') {
1142 throw new Error(message);
1143 }
1144 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'success');
1145 setTimeout(() => {
1146 window.location.reload();
1147 }, 1200);
1148 },
1149 error: error => {
1150 const message = error?.message || error || 'Refund request failed.';
1151 _lpToastify__WEBPACK_IMPORTED_MODULE_1__.show(message, 'error');
1152 },
1153 completed: () => {
1154 this.isRequesting = false;
1155 this.setActionLoadingState(actionLink, false);
1156 }
1157 });
1158 }
1159 async handleRefundClick(args) {
1160 const {
1161 e,
1162 target
1163 } = args;
1164 e.preventDefault();
1165 const actionLink = target.closest(OrderRefund.selectors.actionRefund);
1166 if (!actionLink) {
1167 return;
1168 }
1169 if (this.isRequesting || actionLink.dataset.refundSubmitting === 'yes' || actionLink.classList.contains('loading')) {
1170 return;
1171 }
1172 const actionData = this.getActionData(actionLink);
1173 let reason = '';
1174 if (actionData.requireReason) {
1175 const reasonResult = await this.openReasonModal(actionData);
1176 if (!reasonResult.isConfirmed) {
1177 return;
1178 }
1179 reason = (reasonResult.value || '').trim();
1180 }
1181 const confirmResult = await this.openConfirmModal(actionData);
1182 if (!confirmResult.isConfirmed) {
1183 return;
1184 }
1185 this.sendRefundRequest(actionLink, actionData, reason);
1186 }
1187 }
1188 const orderRefund = () => {
1189 const orderRefundHandle = new OrderRefund();
1190 _utils_js__WEBPACK_IMPORTED_MODULE_2__.lpOnElementReady(OrderRefund.selectors.actionRefund, () => {
1191 orderRefundHandle.init();
1192 });
1193 };
1194 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (orderRefund);
1195
1196 /***/ },
1197
1198 /***/ "./assets/src/js/frontend/profile/quiz.js"
1199 /*!************************************************!*\
1200 !*** ./assets/src/js/frontend/profile/quiz.js ***!
1201 \************************************************/
1202 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1203
1204 "use strict";
1205 __webpack_require__.r(__webpack_exports__);
1206 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1207 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
1208 /* harmony export */ });
1209 /**
1210 * Handle click tab call API
1211 *
1212 * @since 4.2.8.2
1213 * @version 1.0.0
1214 */
1215 const profileQuizTab = () => {
1216 const handleClickTab = (e, target) => {
1217 if (target.closest('span')) {
1218 const elParent = target.closest('#profile-content-quizzes');
1219 if (!elParent) {
1220 return;
1221 }
1222 const elLPTarget = target.closest('.lp-target');
1223 if (!elLPTarget) {
1224 return;
1225 }
1226 window.lpAJAXG.showHideLoading(elLPTarget, 1);
1227 const dataSendJson = elLPTarget?.dataset?.send || {};
1228 const dataSend = JSON.parse(dataSendJson);
1229 const elTabChoice = target?.dataset?.filter || 'all';
1230 const liActive = elParent.querySelector('li.active');
1231 if (liActive.classList.contains(elTabChoice)) {
1232 return;
1233 }
1234 liActive.classList.remove('active');
1235 const liTarget = target.closest('li');
1236 liTarget.classList.add('active');
1237 dataSend.args.type = elTabChoice;
1238
1239 // Load list courses by AJAX.
1240 const callBack = {
1241 success: response => {
1242 const {
1243 data,
1244 message,
1245 status
1246 } = response;
1247 if ('success' === status) {
1248 elLPTarget.innerHTML = data.content || '';
1249 }
1250 },
1251 error: error => {
1252 console.log(error);
1253 },
1254 completed: () => {
1255 window.lpAJAXG.showHideLoading(elLPTarget, 0);
1256 }
1257 };
1258 window.lpAJAXG.fetchAJAX(dataSend, callBack);
1259 }
1260 };
1261 document.addEventListener('click', e => {
1262 const target = e.target;
1263 handleClickTab(e, target);
1264 });
1265 };
1266 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (profileQuizTab);
1267
1268 /***/ },
1269
1270 /***/ "./assets/src/js/frontend/profile/statistic.js"
1271 /*!*****************************************************!*\
1272 !*** ./assets/src/js/frontend/profile/statistic.js ***!
1273 \*****************************************************/
1274 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1275
1276 "use strict";
1277 __webpack_require__.r(__webpack_exports__);
1278 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1279 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
1280 /* harmony export */ });
1281 /* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils.js */ "./assets/src/js/utils.js");
1282
1283
1284 // Rest API load content course progress - Nhamdv.
1285 const courseStatistics = () => {
1286 const loadAPICourseStatistic = elCourseStatistic => {
1287 let apiUrl = 'lp/v1/profile/student/statistic';
1288 const tabActive = document.querySelector('.lp-profile-nav-tabs li.active');
1289 if (!tabActive) {
1290 return;
1291 }
1292 if (tabActive.classList.contains('courses')) {
1293 apiUrl = 'lp/v1/profile/instructor/statistic';
1294 }
1295 const elArgStatistic = elCourseStatistic.querySelector('[name="args_query_user_courses_statistic"]');
1296 if (!elArgStatistic) {
1297 return;
1298 }
1299 const data = JSON.parse(elArgStatistic.value);
1300 const callBack = {
1301 success: response => {
1302 if (response.status === 'success' && response.data) {
1303 elCourseStatistic.innerHTML = response.data;
1304 } else {
1305 elCourseStatistic.innerHTML = `<div class="lp-ajax-message error" style="display:block">${response.message && response.message}</div>`;
1306 }
1307 },
1308 error: error => {
1309 console.log(error);
1310 },
1311 completed: () => {}
1312 };
1313 apiUrl = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpAddQueryArgs)(lpData.lp_rest_url + apiUrl, data);
1314 if (0 !== parseInt(lpData.user_id)) {
1315 data.headers = {
1316 'X-WP-Nonce': lpData.nonce
1317 };
1318 }
1319 ;(0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpFetchAPI)(apiUrl, data, callBack);
1320 };
1321 (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.lpOnElementReady)('.learn-press-profile-course__statistic', elCourseStatistic => {
1322 loadAPICourseStatistic(elCourseStatistic);
1323 });
1324 };
1325 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (courseStatistics);
1326
1327 /***/ },
1328
1329 /***/ "./assets/src/js/lpToastify.js"
1330 /*!*************************************!*\
1331 !*** ./assets/src/js/lpToastify.js ***!
1332 \*************************************/
1333 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1334
1335 "use strict";
1336 __webpack_require__.r(__webpack_exports__);
1337 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1338 /* harmony export */ show: () => (/* binding */ show)
1339 /* harmony export */ });
1340 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
1341 /* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_0__);
1342 /* 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");
1343 /**
1344 * Utils functions
1345 *
1346 * @param url
1347 * @param data
1348 * @param functions
1349 * @since 4.3.0
1350 * @version 1.0.0
1351 */
1352
1353
1354 const argsToastify = {
1355 text: '',
1356 gravity: lpData.toast.gravity,
1357 // `top` or `bottom`
1358 position: lpData.toast.position,
1359 // `left`, `center` or `right`
1360 className: `${lpData.toast.classPrefix}`,
1361 close: lpData.toast.close == 1,
1362 stopOnFocus: lpData.toast.stopOnFocus == 1,
1363 duration: lpData.toast.duration
1364 };
1365 const show = (message, status = 'success', argsCustom) => {
1366 let args = argsToastify;
1367 if (argsCustom) {
1368 args = {
1369 ...args,
1370 ...argsCustom
1371 };
1372 }
1373 const toastify = new (toastify_js__WEBPACK_IMPORTED_MODULE_0___default())({
1374 ...args,
1375 text: message,
1376 className: `${lpData.toast.classPrefix} ${status}`
1377 });
1378 toastify.showToast();
1379 };
1380
1381 /***/ },
1382
1383 /***/ "./assets/src/js/utils.js"
1384 /*!********************************!*\
1385 !*** ./assets/src/js/utils.js ***!
1386 \********************************/
1387 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
1388
1389 "use strict";
1390 __webpack_require__.r(__webpack_exports__);
1391 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
1392 /* harmony export */ debounce: () => (/* binding */ debounce),
1393 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
1394 /* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
1395 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
1396 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
1397 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
1398 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
1399 /* harmony export */ lpAddQueryArgs: () => (/* binding */ lpAddQueryArgs),
1400 /* harmony export */ lpAjaxParseJsonOld: () => (/* binding */ lpAjaxParseJsonOld),
1401 /* harmony export */ lpClassName: () => (/* binding */ lpClassName),
1402 /* harmony export */ lpFetchAPI: () => (/* binding */ lpFetchAPI),
1403 /* harmony export */ lpGetCurrentURLNoParam: () => (/* binding */ lpGetCurrentURLNoParam),
1404 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
1405 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
1406 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
1407 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
1408 /* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
1409 /* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
1410 /* harmony export */ });
1411 /**
1412 * Utils functions
1413 *
1414 * @param url
1415 * @param data
1416 * @param functions
1417 * @since 4.2.5.1
1418 * @version 1.0.7
1419 */
1420 const lpClassName = {
1421 hidden: 'lp-hidden',
1422 loading: 'loading',
1423 elCollapse: 'lp-collapse',
1424 elSectionToggle: '.lp-section-toggle',
1425 elTriggerToggle: '.lp-trigger-toggle',
1426 elBtnFullScreen: '.lp-btn-full-screen-view',
1427 elFullScreen: 'lp-full-screen-view',
1428 elBtnFullScreenClose: 'lp-full-screen-view__close'
1429 };
1430 const lpFetchAPI = (url, data = {}, functions = {}) => {
1431 if ('function' === typeof functions.before) {
1432 functions.before();
1433 }
1434 fetch(url, {
1435 method: 'GET',
1436 ...data
1437 }).then(response => response.json()).then(response => {
1438 if ('function' === typeof functions.success) {
1439 functions.success(response);
1440 }
1441 }).catch(err => {
1442 if ('function' === typeof functions.error) {
1443 functions.error(err);
1444 }
1445 }).finally(() => {
1446 if ('function' === typeof functions.completed) {
1447 functions.completed();
1448 }
1449 });
1450 };
1451
1452 /**
1453 * Get current URL without params.
1454 *
1455 * @since 4.2.5.1
1456 */
1457 const lpGetCurrentURLNoParam = () => {
1458 let currentUrl = window.location.href;
1459 const hasParams = currentUrl.includes('?');
1460 if (hasParams) {
1461 currentUrl = currentUrl.split('?')[0];
1462 }
1463 return currentUrl;
1464 };
1465 const lpAddQueryArgs = (endpoint, args) => {
1466 const url = new URL(endpoint);
1467 Object.keys(args).forEach(arg => {
1468 url.searchParams.set(arg, args[arg]);
1469 });
1470 return url;
1471 };
1472
1473 /**
1474 * Listen element viewed.
1475 *
1476 * @param el
1477 * @param callback
1478 * @since 4.2.5.8
1479 */
1480 const listenElementViewed = (el, callback) => {
1481 const observerSeeItem = new IntersectionObserver(function (entries) {
1482 for (const entry of entries) {
1483 if (entry.isIntersecting) {
1484 callback(entry);
1485 }
1486 }
1487 });
1488 observerSeeItem.observe(el);
1489 };
1490
1491 /**
1492 * Listen element created.
1493 *
1494 * @param callback
1495 * @since 4.2.5.8
1496 */
1497 const listenElementCreated = callback => {
1498 const observerCreateItem = new MutationObserver(function (mutations) {
1499 mutations.forEach(function (mutation) {
1500 if (mutation.addedNodes) {
1501 mutation.addedNodes.forEach(function (node) {
1502 if (node.nodeType === 1) {
1503 callback(node);
1504 }
1505 });
1506 }
1507 });
1508 });
1509 observerCreateItem.observe(document, {
1510 childList: true,
1511 subtree: true
1512 });
1513 // End.
1514 };
1515
1516 /**
1517 * Listen element created.
1518 *
1519 * @param selector
1520 * @param callback
1521 * @since 4.2.7.1
1522 */
1523 const lpOnElementReady = (selector, callback) => {
1524 const element = document.querySelector(selector);
1525 if (element) {
1526 callback(element);
1527 return;
1528 }
1529 const observer = new MutationObserver((mutations, obs) => {
1530 const element = document.querySelector(selector);
1531 if (element) {
1532 obs.disconnect();
1533 callback(element);
1534 }
1535 });
1536 observer.observe(document.documentElement, {
1537 childList: true,
1538 subtree: true
1539 });
1540 };
1541
1542 // Parse JSON from string with content include LP_AJAX_START.
1543 const lpAjaxParseJsonOld = data => {
1544 if (typeof data !== 'string') {
1545 return data;
1546 }
1547 const m = String.raw({
1548 raw: data
1549 }).match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/s);
1550 try {
1551 if (m) {
1552 data = JSON.parse(m[1].replace(/(?:\r\n|\r|\n)/g, ''));
1553 } else {
1554 data = JSON.parse(data);
1555 }
1556 } catch (e) {
1557 data = {};
1558 }
1559 return data;
1560 };
1561
1562 // status 0: hide, 1: show
1563 const lpShowHideEl = (el, status = 0) => {
1564 if (!el) {
1565 return;
1566 }
1567 if (!status) {
1568 el.classList.add(lpClassName.hidden);
1569 } else {
1570 el.classList.remove(lpClassName.hidden);
1571 }
1572 };
1573
1574 // status 0: hide, 1: show
1575 const lpSetLoadingEl = (el, status) => {
1576 if (!el) {
1577 return;
1578 }
1579 if (!status) {
1580 el.classList.remove(lpClassName.loading);
1581 } else {
1582 el.classList.add(lpClassName.loading);
1583 }
1584 };
1585
1586 // Toggle collapse section
1587 const toggleCollapse = (e, target, elTriggerClassName = '', elsExclude = [], callback) => {
1588 if (!elTriggerClassName) {
1589 elTriggerClassName = lpClassName.elTriggerToggle;
1590 }
1591
1592 // Exclude elements, which should not trigger the collapse toggle
1593 if (elsExclude && elsExclude.length > 0) {
1594 for (const elExclude of elsExclude) {
1595 if (target.closest(elExclude)) {
1596 return;
1597 }
1598 }
1599 }
1600 const elTrigger = target.closest(elTriggerClassName);
1601 if (!elTrigger) {
1602 return;
1603 }
1604
1605 //console.log( 'elTrigger', elTrigger );
1606
1607 const elSectionToggle = elTrigger.closest(`${lpClassName.elSectionToggle}`);
1608 if (!elSectionToggle) {
1609 return;
1610 }
1611 elSectionToggle.classList.toggle(`${lpClassName.elCollapse}`);
1612 if ('function' === typeof callback) {
1613 callback(elSectionToggle);
1614 }
1615 };
1616
1617 // Get data of form
1618 const getDataOfForm = form => {
1619 const dataSend = {};
1620 const formData = new FormData(form);
1621 for (const pair of formData.entries()) {
1622 const key = pair[0];
1623 const value = formData.getAll(key);
1624 if (!dataSend.hasOwnProperty(key)) {
1625 // Convert value array to string.
1626 dataSend[key] = value.join(',');
1627 }
1628 }
1629 return dataSend;
1630 };
1631
1632 // Get field keys of form
1633 const getFieldKeysOfForm = form => {
1634 const keys = [];
1635 const elements = form.elements;
1636 for (let i = 0; i < elements.length; i++) {
1637 const name = elements[i].name;
1638 if (name && !keys.includes(name)) {
1639 keys.push(name);
1640 }
1641 }
1642 return keys;
1643 };
1644
1645 // Merge data handle with data form.
1646 const mergeDataWithDatForm = (elForm, dataHandle) => {
1647 const dataForm = getDataOfForm(elForm);
1648 const keys = getFieldKeysOfForm(elForm);
1649 keys.forEach(key => {
1650 if (!dataForm.hasOwnProperty(key)) {
1651 delete dataHandle[key];
1652 } else if (dataForm[key][0] === '') {
1653 delete dataForm[key];
1654 delete dataHandle[key];
1655 }
1656 });
1657 dataHandle = {
1658 ...dataHandle,
1659 ...dataForm
1660 };
1661 return dataHandle;
1662 };
1663
1664 /**
1665 * Event trigger
1666 * For each list of event handlers, listen event on document.
1667 *
1668 * eventName: 'click', 'change', ...
1669 * eventHandlers = [ { selector: '.lp-button', callBack: function(){}, class: object } ]
1670 *
1671 * @param eventName
1672 * @param eventHandlers
1673 */
1674 const eventHandlers = (eventName, eventHandlers) => {
1675 document.addEventListener(eventName, e => {
1676 const target = e.target;
1677 let args = {
1678 e,
1679 target
1680 };
1681 eventHandlers.forEach(eventHandler => {
1682 args = {
1683 ...args,
1684 ...eventHandler
1685 };
1686
1687 //console.log( args );
1688
1689 // Check condition before call back
1690 if (eventHandler.conditionBeforeCallBack) {
1691 if (eventHandler.conditionBeforeCallBack(args) !== true) {
1692 return;
1693 }
1694 }
1695
1696 // Special check for keydown event with checkIsEventEnter = true
1697 if (eventName === 'keydown' && eventHandler.checkIsEventEnter) {
1698 if (e.key !== 'Enter') {
1699 return;
1700 }
1701 }
1702 if (target.closest(eventHandler.selector)) {
1703 if (eventHandler.class) {
1704 // Call method of class, function callBack will understand exactly {this} is class object.
1705 eventHandler.class[eventHandler.callBack](args);
1706 } else {
1707 // For send args is objected, {this} is eventHandler object, not class object.
1708 eventHandler.callBack(args);
1709 }
1710 }
1711 });
1712 });
1713 };
1714
1715 /**
1716 * Debounce - delays function execution until after `wait` ms of inactivity.
1717 *
1718 * Each call resets the timer. Only the last call in a burst executes.
1719 *
1720 * USE CASES:
1721 * - Search inputs, form validation, window resize
1722 * - Multiple elements need independent timers
1723 * - When you need to call with different arguments
1724 *
1725 * EXAMPLES:
1726 * const debouncedSearch = debounce( (query) => fetchResults(query), 300 );
1727 * searchInput.addEventListener('input', (e) => debouncedSearch(e.target.value));
1728 *
1729 * const debouncedResize = debounce( recalculateLayout, 250 );
1730 * window.addEventListener('resize', debouncedResize);
1731 *
1732 * ⚠️ Create ONCE outside event handlers, not inside.
1733 *
1734 * @param {Function} func - Function to debounce (can be anonymous)
1735 * @param {number} wait - Milliseconds to wait (default: 500)
1736 * @return {Function} Debounced wrapper function
1737 * @since 4.3.7
1738 * @version 1.0.0
1739 */
1740 const debounce = (func, wait = 500) => {
1741 let timer;
1742 return args => {
1743 clearTimeout(timer);
1744 timer = setTimeout(() => func(args), wait);
1745 };
1746 };
1747
1748 /**
1749 * Initialize lp-toggle-enable components.
1750 *
1751 * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
1752 * Reads initial state from `data-enabled` attribute ("true"/"false").
1753 * Calls `data-on-toggle` callback (if provided via options) on state change.
1754 *
1755 * HTML structure:
1756 * <label class="lp-toggle-enable" data-enabled="true">
1757 * <input type="checkbox" class="lp-toggle-enable__input" />
1758 * <span class="lp-toggle-enable__track"></span>
1759 * </label>
1760 *
1761 * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
1762 * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
1763 * @since 4.4.5
1764 * @version 1.0.0
1765 */
1766 window.lpToggleEnableInit = 0;
1767 const toggleEnable = (onToggle = null) => {
1768 if (window.lpToggleEnableInit) {
1769 return;
1770 }
1771 window.lpToggleEnableInit = 1;
1772 const selector = '.lp-toggle-enable';
1773 const updateUI = (toggle, isEnabled) => {
1774 toggle.classList.toggle('is-enabled', isEnabled);
1775 const input = toggle.querySelector('.lp-toggle-enable__input');
1776 if (input) {
1777 input.checked = isEnabled;
1778 input.value = isEnabled ? '1' : '0';
1779 }
1780 };
1781
1782 // Delegate click handling via eventHandlers.
1783 eventHandlers('click', [{
1784 selector,
1785 callBack: args => {
1786 const {
1787 e,
1788 target
1789 } = args;
1790 const toggle = target.closest(selector);
1791 if (!toggle || toggle.classList.contains('is-disabled')) {
1792 return;
1793 }
1794 e.preventDefault();
1795 const isEnabled = !toggle.classList.contains('is-enabled');
1796 updateUI(toggle, isEnabled);
1797 if ('function' === typeof onToggle) {
1798 onToggle(toggle, isEnabled);
1799 }
1800 }
1801 }]);
1802 };
1803
1804 /**
1805 * Initialize custom fullscreen view buttons.
1806 *
1807 * Delegates clicks on `.lp-btn-full-screen-view` buttons to
1808 * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
1809 * target element. Falls back to the button's parent element when
1810 * `data-target` is not provided.
1811 *
1812 * @since 4.4.5
1813 * @version 1.0.0
1814 */
1815 window.lpFullScreenViewInit = 0;
1816 const fullScreenView = () => {
1817 if (window.lpFullScreenViewInit) {
1818 return;
1819 }
1820 window.lpFullScreenViewInit = 1;
1821 let lastScrollY = 0;
1822 const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
1823 const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
1824 if (isFullscreen) {
1825 elTarget.classList.remove(lpClassName.elFullScreen);
1826 document.documentElement.classList.remove('lp-full-screen-active');
1827 window.scrollTo(0, lastScrollY);
1828 } else {
1829 lastScrollY = window.scrollY;
1830 elTarget.classList.add(lpClassName.elFullScreen);
1831 document.documentElement.classList.add('lp-full-screen-active');
1832 }
1833 if (!isFullscreen) {
1834 if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
1835 const closeButton = document.createElement('button');
1836 closeButton.type = 'button';
1837 closeButton.className = lpClassName.elBtnFullScreenClose;
1838 closeButton.setAttribute('aria-label', 'Close');
1839 closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
1840 closeButton.addEventListener('click', e => {
1841 e.preventDefault();
1842 lpToggleFullscreenView(elTarget);
1843 });
1844 elTarget.appendChild(closeButton);
1845 }
1846 } else {
1847 const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
1848 if (closeButton) {
1849 closeButton.remove();
1850 }
1851 }
1852 };
1853 eventHandlers('click', [{
1854 selector: lpClassName.elBtnFullScreen,
1855 callBack: args => {
1856 const {
1857 e,
1858 target
1859 } = args;
1860 const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
1861 if (!elBtnFullScreen) {
1862 console.log('No full screen button found');
1863 return;
1864 }
1865 e.preventDefault();
1866 let elTarget = null;
1867 const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
1868 console.log(targetSelector);
1869 if (targetSelector) {
1870 elTarget = document.querySelector(targetSelector);
1871 }
1872 if (!elTarget) {
1873 console.log('No target element found');
1874 return;
1875 }
1876 lpToggleFullscreenView(elTarget, elBtnFullScreen);
1877 }
1878 }]);
1879 };
1880
1881 /***/ },
1882
1883 /***/ "./node_modules/cropperjs/dist/cropper.js"
1884 /*!************************************************!*\
1885 !*** ./node_modules/cropperjs/dist/cropper.js ***!
1886 \************************************************/
1887 (module) {
1888
1889 /*!
1890 * Cropper.js v1.6.2
1891 * https://fengyuanchen.github.io/cropperjs
1892 *
1893 * Copyright 2015-present Chen Fengyuan
1894 * Released under the MIT license
1895 *
1896 * Date: 2024-04-21T07:43:05.335Z
1897 */
1898
1899 (function (global, factory) {
1900 true ? module.exports = factory() :
1901 0;
1902 })(this, (function () { 'use strict';
1903
1904 function ownKeys(e, r) {
1905 var t = Object.keys(e);
1906 if (Object.getOwnPropertySymbols) {
1907 var o = Object.getOwnPropertySymbols(e);
1908 r && (o = o.filter(function (r) {
1909 return Object.getOwnPropertyDescriptor(e, r).enumerable;
1910 })), t.push.apply(t, o);
1911 }
1912 return t;
1913 }
1914 function _objectSpread2(e) {
1915 for (var r = 1; r < arguments.length; r++) {
1916 var t = null != arguments[r] ? arguments[r] : {};
1917 r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
1918 _defineProperty(e, r, t[r]);
1919 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
1920 Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
1921 });
1922 }
1923 return e;
1924 }
1925 function _toPrimitive(t, r) {
1926 if ("object" != typeof t || !t) return t;
1927 var e = t[Symbol.toPrimitive];
1928 if (void 0 !== e) {
1929 var i = e.call(t, r || "default");
1930 if ("object" != typeof i) return i;
1931 throw new TypeError("@@toPrimitive must return a primitive value.");
1932 }
1933 return ("string" === r ? String : Number)(t);
1934 }
1935 function _toPropertyKey(t) {
1936 var i = _toPrimitive(t, "string");
1937 return "symbol" == typeof i ? i : i + "";
1938 }
1939 function _typeof(o) {
1940 "@babel/helpers - typeof";
1941
1942 return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
1943 return typeof o;
1944 } : function (o) {
1945 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
1946 }, _typeof(o);
1947 }
1948 function _classCallCheck(instance, Constructor) {
1949 if (!(instance instanceof Constructor)) {
1950 throw new TypeError("Cannot call a class as a function");
1951 }
1952 }
1953 function _defineProperties(target, props) {
1954 for (var i = 0; i < props.length; i++) {
1955 var descriptor = props[i];
1956 descriptor.enumerable = descriptor.enumerable || false;
1957 descriptor.configurable = true;
1958 if ("value" in descriptor) descriptor.writable = true;
1959 Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
1960 }
1961 }
1962 function _createClass(Constructor, protoProps, staticProps) {
1963 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1964 if (staticProps) _defineProperties(Constructor, staticProps);
1965 Object.defineProperty(Constructor, "prototype", {
1966 writable: false
1967 });
1968 return Constructor;
1969 }
1970 function _defineProperty(obj, key, value) {
1971 key = _toPropertyKey(key);
1972 if (key in obj) {
1973 Object.defineProperty(obj, key, {
1974 value: value,
1975 enumerable: true,
1976 configurable: true,
1977 writable: true
1978 });
1979 } else {
1980 obj[key] = value;
1981 }
1982 return obj;
1983 }
1984 function _toConsumableArray(arr) {
1985 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
1986 }
1987 function _arrayWithoutHoles(arr) {
1988 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
1989 }
1990 function _iterableToArray(iter) {
1991 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
1992 }
1993 function _unsupportedIterableToArray(o, minLen) {
1994 if (!o) return;
1995 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
1996 var n = Object.prototype.toString.call(o).slice(8, -1);
1997 if (n === "Object" && o.constructor) n = o.constructor.name;
1998 if (n === "Map" || n === "Set") return Array.from(o);
1999 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
2000 }
2001 function _arrayLikeToArray(arr, len) {
2002 if (len == null || len > arr.length) len = arr.length;
2003 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
2004 return arr2;
2005 }
2006 function _nonIterableSpread() {
2007 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2008 }
2009
2010 var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
2011 var WINDOW = IS_BROWSER ? window : {};
2012 var IS_TOUCH_DEVICE = IS_BROWSER && WINDOW.document.documentElement ? 'ontouchstart' in WINDOW.document.documentElement : false;
2013 var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
2014 var NAMESPACE = 'cropper';
2015
2016 // Actions
2017 var ACTION_ALL = 'all';
2018 var ACTION_CROP = 'crop';
2019 var ACTION_MOVE = 'move';
2020 var ACTION_ZOOM = 'zoom';
2021 var ACTION_EAST = 'e';
2022 var ACTION_WEST = 'w';
2023 var ACTION_SOUTH = 's';
2024 var ACTION_NORTH = 'n';
2025 var ACTION_NORTH_EAST = 'ne';
2026 var ACTION_NORTH_WEST = 'nw';
2027 var ACTION_SOUTH_EAST = 'se';
2028 var ACTION_SOUTH_WEST = 'sw';
2029
2030 // Classes
2031 var CLASS_CROP = "".concat(NAMESPACE, "-crop");
2032 var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");
2033 var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");
2034 var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
2035 var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
2036 var CLASS_MODAL = "".concat(NAMESPACE, "-modal");
2037 var CLASS_MOVE = "".concat(NAMESPACE, "-move");
2038
2039 // Data keys
2040 var DATA_ACTION = "".concat(NAMESPACE, "Action");
2041 var DATA_PREVIEW = "".concat(NAMESPACE, "Preview");
2042
2043 // Drag modes
2044 var DRAG_MODE_CROP = 'crop';
2045 var DRAG_MODE_MOVE = 'move';
2046 var DRAG_MODE_NONE = 'none';
2047
2048 // Events
2049 var EVENT_CROP = 'crop';
2050 var EVENT_CROP_END = 'cropend';
2051 var EVENT_CROP_MOVE = 'cropmove';
2052 var EVENT_CROP_START = 'cropstart';
2053 var EVENT_DBLCLICK = 'dblclick';
2054 var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';
2055 var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';
2056 var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';
2057 var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;
2058 var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;
2059 var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;
2060 var EVENT_READY = 'ready';
2061 var EVENT_RESIZE = 'resize';
2062 var EVENT_WHEEL = 'wheel';
2063 var EVENT_ZOOM = 'zoom';
2064
2065 // Mime types
2066 var MIME_TYPE_JPEG = 'image/jpeg';
2067
2068 // RegExps
2069 var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;
2070 var REGEXP_DATA_URL = /^data:/;
2071 var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
2072 var REGEXP_TAG_NAME = /^img|canvas$/i;
2073
2074 // Misc
2075 // Inspired by the default width and height of a canvas element.
2076 var MIN_CONTAINER_WIDTH = 200;
2077 var MIN_CONTAINER_HEIGHT = 100;
2078
2079 var DEFAULTS = {
2080 // Define the view mode of the cropper
2081 viewMode: 0,
2082 // 0, 1, 2, 3
2083
2084 // Define the dragging mode of the cropper
2085 dragMode: DRAG_MODE_CROP,
2086 // 'crop', 'move' or 'none'
2087
2088 // Define the initial aspect ratio of the crop box
2089 initialAspectRatio: NaN,
2090 // Define the aspect ratio of the crop box
2091 aspectRatio: NaN,
2092 // An object with the previous cropping result data
2093 data: null,
2094 // A selector for adding extra containers to preview
2095 preview: '',
2096 // Re-render the cropper when resize the window
2097 responsive: true,
2098 // Restore the cropped area after resize the window
2099 restore: true,
2100 // Check if the current image is a cross-origin image
2101 checkCrossOrigin: true,
2102 // Check the current image's Exif Orientation information
2103 checkOrientation: true,
2104 // Show the black modal
2105 modal: true,
2106 // Show the dashed lines for guiding
2107 guides: true,
2108 // Show the center indicator for guiding
2109 center: true,
2110 // Show the white modal to highlight the crop box
2111 highlight: true,
2112 // Show the grid background
2113 background: true,
2114 // Enable to crop the image automatically when initialize
2115 autoCrop: true,
2116 // Define the percentage of automatic cropping area when initializes
2117 autoCropArea: 0.8,
2118 // Enable to move the image
2119 movable: true,
2120 // Enable to rotate the image
2121 rotatable: true,
2122 // Enable to scale the image
2123 scalable: true,
2124 // Enable to zoom the image
2125 zoomable: true,
2126 // Enable to zoom the image by dragging touch
2127 zoomOnTouch: true,
2128 // Enable to zoom the image by wheeling mouse
2129 zoomOnWheel: true,
2130 // Define zoom ratio when zoom the image by wheeling mouse
2131 wheelZoomRatio: 0.1,
2132 // Enable to move the crop box
2133 cropBoxMovable: true,
2134 // Enable to resize the crop box
2135 cropBoxResizable: true,
2136 // Toggle drag mode between "crop" and "move" when click twice on the cropper
2137 toggleDragModeOnDblclick: true,
2138 // Size limitation
2139 minCanvasWidth: 0,
2140 minCanvasHeight: 0,
2141 minCropBoxWidth: 0,
2142 minCropBoxHeight: 0,
2143 minContainerWidth: MIN_CONTAINER_WIDTH,
2144 minContainerHeight: MIN_CONTAINER_HEIGHT,
2145 // Shortcuts of events
2146 ready: null,
2147 cropstart: null,
2148 cropmove: null,
2149 cropend: null,
2150 crop: null,
2151 zoom: null
2152 };
2153
2154 var TEMPLATE = '<div class="cropper-container" touch-action="none">' + '<div class="cropper-wrap-box">' + '<div class="cropper-canvas"></div>' + '</div>' + '<div class="cropper-drag-box"></div>' + '<div class="cropper-crop-box">' + '<span class="cropper-view-box"></span>' + '<span class="cropper-dashed dashed-h"></span>' + '<span class="cropper-dashed dashed-v"></span>' + '<span class="cropper-center"></span>' + '<span class="cropper-face"></span>' + '<span class="cropper-line line-e" data-cropper-action="e"></span>' + '<span class="cropper-line line-n" data-cropper-action="n"></span>' + '<span class="cropper-line line-w" data-cropper-action="w"></span>' + '<span class="cropper-line line-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-e" data-cropper-action="e"></span>' + '<span class="cropper-point point-n" data-cropper-action="n"></span>' + '<span class="cropper-point point-w" data-cropper-action="w"></span>' + '<span class="cropper-point point-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-ne" data-cropper-action="ne"></span>' + '<span class="cropper-point point-nw" data-cropper-action="nw"></span>' + '<span class="cropper-point point-sw" data-cropper-action="sw"></span>' + '<span class="cropper-point point-se" data-cropper-action="se"></span>' + '</div>' + '</div>';
2155
2156 /**
2157 * Check if the given value is not a number.
2158 */
2159 var isNaN = Number.isNaN || WINDOW.isNaN;
2160
2161 /**
2162 * Check if the given value is a number.
2163 * @param {*} value - The value to check.
2164 * @returns {boolean} Returns `true` if the given value is a number, else `false`.
2165 */
2166 function isNumber(value) {
2167 return typeof value === 'number' && !isNaN(value);
2168 }
2169
2170 /**
2171 * Check if the given value is a positive number.
2172 * @param {*} value - The value to check.
2173 * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
2174 */
2175 var isPositiveNumber = function isPositiveNumber(value) {
2176 return value > 0 && value < Infinity;
2177 };
2178
2179 /**
2180 * Check if the given value is undefined.
2181 * @param {*} value - The value to check.
2182 * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
2183 */
2184 function isUndefined(value) {
2185 return typeof value === 'undefined';
2186 }
2187
2188 /**
2189 * Check if the given value is an object.
2190 * @param {*} value - The value to check.
2191 * @returns {boolean} Returns `true` if the given value is an object, else `false`.
2192 */
2193 function isObject(value) {
2194 return _typeof(value) === 'object' && value !== null;
2195 }
2196 var hasOwnProperty = Object.prototype.hasOwnProperty;
2197
2198 /**
2199 * Check if the given value is a plain object.
2200 * @param {*} value - The value to check.
2201 * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
2202 */
2203 function isPlainObject(value) {
2204 if (!isObject(value)) {
2205 return false;
2206 }
2207 try {
2208 var _constructor = value.constructor;
2209 var prototype = _constructor.prototype;
2210 return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
2211 } catch (error) {
2212 return false;
2213 }
2214 }
2215
2216 /**
2217 * Check if the given value is a function.
2218 * @param {*} value - The value to check.
2219 * @returns {boolean} Returns `true` if the given value is a function, else `false`.
2220 */
2221 function isFunction(value) {
2222 return typeof value === 'function';
2223 }
2224 var slice = Array.prototype.slice;
2225
2226 /**
2227 * Convert array-like or iterable object to an array.
2228 * @param {*} value - The value to convert.
2229 * @returns {Array} Returns a new array.
2230 */
2231 function toArray(value) {
2232 return Array.from ? Array.from(value) : slice.call(value);
2233 }
2234
2235 /**
2236 * Iterate the given data.
2237 * @param {*} data - The data to iterate.
2238 * @param {Function} callback - The process function for each element.
2239 * @returns {*} The original data.
2240 */
2241 function forEach(data, callback) {
2242 if (data && isFunction(callback)) {
2243 if (Array.isArray(data) || isNumber(data.length) /* array-like */) {
2244 toArray(data).forEach(function (value, key) {
2245 callback.call(data, value, key, data);
2246 });
2247 } else if (isObject(data)) {
2248 Object.keys(data).forEach(function (key) {
2249 callback.call(data, data[key], key, data);
2250 });
2251 }
2252 }
2253 return data;
2254 }
2255
2256 /**
2257 * Extend the given object.
2258 * @param {*} target - The target object to extend.
2259 * @param {*} args - The rest objects for merging to the target object.
2260 * @returns {Object} The extended object.
2261 */
2262 var assign = Object.assign || function assign(target) {
2263 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2264 args[_key - 1] = arguments[_key];
2265 }
2266 if (isObject(target) && args.length > 0) {
2267 args.forEach(function (arg) {
2268 if (isObject(arg)) {
2269 Object.keys(arg).forEach(function (key) {
2270 target[key] = arg[key];
2271 });
2272 }
2273 });
2274 }
2275 return target;
2276 };
2277 var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
2278
2279 /**
2280 * Normalize decimal number.
2281 * Check out {@link https://0.30000000000000004.com/}
2282 * @param {number} value - The value to normalize.
2283 * @param {number} [times=100000000000] - The times for normalizing.
2284 * @returns {number} Returns the normalized number.
2285 */
2286 function normalizeDecimalNumber(value) {
2287 var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
2288 return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
2289 }
2290 var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;
2291
2292 /**
2293 * Apply styles to the given element.
2294 * @param {Element} element - The target element.
2295 * @param {Object} styles - The styles for applying.
2296 */
2297 function setStyle(element, styles) {
2298 var style = element.style;
2299 forEach(styles, function (value, property) {
2300 if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
2301 value = "".concat(value, "px");
2302 }
2303 style[property] = value;
2304 });
2305 }
2306
2307 /**
2308 * Check if the given element has a special class.
2309 * @param {Element} element - The element to check.
2310 * @param {string} value - The class to search.
2311 * @returns {boolean} Returns `true` if the special class was found.
2312 */
2313 function hasClass(element, value) {
2314 return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
2315 }
2316
2317 /**
2318 * Add classes to the given element.
2319 * @param {Element} element - The target element.
2320 * @param {string} value - The classes to be added.
2321 */
2322 function addClass(element, value) {
2323 if (!value) {
2324 return;
2325 }
2326 if (isNumber(element.length)) {
2327 forEach(element, function (elem) {
2328 addClass(elem, value);
2329 });
2330 return;
2331 }
2332 if (element.classList) {
2333 element.classList.add(value);
2334 return;
2335 }
2336 var className = element.className.trim();
2337 if (!className) {
2338 element.className = value;
2339 } else if (className.indexOf(value) < 0) {
2340 element.className = "".concat(className, " ").concat(value);
2341 }
2342 }
2343
2344 /**
2345 * Remove classes from the given element.
2346 * @param {Element} element - The target element.
2347 * @param {string} value - The classes to be removed.
2348 */
2349 function removeClass(element, value) {
2350 if (!value) {
2351 return;
2352 }
2353 if (isNumber(element.length)) {
2354 forEach(element, function (elem) {
2355 removeClass(elem, value);
2356 });
2357 return;
2358 }
2359 if (element.classList) {
2360 element.classList.remove(value);
2361 return;
2362 }
2363 if (element.className.indexOf(value) >= 0) {
2364 element.className = element.className.replace(value, '');
2365 }
2366 }
2367
2368 /**
2369 * Add or remove classes from the given element.
2370 * @param {Element} element - The target element.
2371 * @param {string} value - The classes to be toggled.
2372 * @param {boolean} added - Add only.
2373 */
2374 function toggleClass(element, value, added) {
2375 if (!value) {
2376 return;
2377 }
2378 if (isNumber(element.length)) {
2379 forEach(element, function (elem) {
2380 toggleClass(elem, value, added);
2381 });
2382 return;
2383 }
2384
2385 // IE10-11 doesn't support the second parameter of `classList.toggle`
2386 if (added) {
2387 addClass(element, value);
2388 } else {
2389 removeClass(element, value);
2390 }
2391 }
2392 var REGEXP_CAMEL_CASE = /([a-z\d])([A-Z])/g;
2393
2394 /**
2395 * Transform the given string from camelCase to kebab-case
2396 * @param {string} value - The value to transform.
2397 * @returns {string} The transformed value.
2398 */
2399 function toParamCase(value) {
2400 return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();
2401 }
2402
2403 /**
2404 * Get data from the given element.
2405 * @param {Element} element - The target element.
2406 * @param {string} name - The data key to get.
2407 * @returns {string} The data value.
2408 */
2409 function getData(element, name) {
2410 if (isObject(element[name])) {
2411 return element[name];
2412 }
2413 if (element.dataset) {
2414 return element.dataset[name];
2415 }
2416 return element.getAttribute("data-".concat(toParamCase(name)));
2417 }
2418
2419 /**
2420 * Set data to the given element.
2421 * @param {Element} element - The target element.
2422 * @param {string} name - The data key to set.
2423 * @param {string} data - The data value.
2424 */
2425 function setData(element, name, data) {
2426 if (isObject(data)) {
2427 element[name] = data;
2428 } else if (element.dataset) {
2429 element.dataset[name] = data;
2430 } else {
2431 element.setAttribute("data-".concat(toParamCase(name)), data);
2432 }
2433 }
2434
2435 /**
2436 * Remove data from the given element.
2437 * @param {Element} element - The target element.
2438 * @param {string} name - The data key to remove.
2439 */
2440 function removeData(element, name) {
2441 if (isObject(element[name])) {
2442 try {
2443 delete element[name];
2444 } catch (error) {
2445 element[name] = undefined;
2446 }
2447 } else if (element.dataset) {
2448 // #128 Safari not allows to delete dataset property
2449 try {
2450 delete element.dataset[name];
2451 } catch (error) {
2452 element.dataset[name] = undefined;
2453 }
2454 } else {
2455 element.removeAttribute("data-".concat(toParamCase(name)));
2456 }
2457 }
2458 var REGEXP_SPACES = /\s\s*/;
2459 var onceSupported = function () {
2460 var supported = false;
2461 if (IS_BROWSER) {
2462 var once = false;
2463 var listener = function listener() {};
2464 var options = Object.defineProperty({}, 'once', {
2465 get: function get() {
2466 supported = true;
2467 return once;
2468 },
2469 /**
2470 * This setter can fix a `TypeError` in strict mode
2471 * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
2472 * @param {boolean} value - The value to set
2473 */
2474 set: function set(value) {
2475 once = value;
2476 }
2477 });
2478 WINDOW.addEventListener('test', listener, options);
2479 WINDOW.removeEventListener('test', listener, options);
2480 }
2481 return supported;
2482 }();
2483
2484 /**
2485 * Remove event listener from the target element.
2486 * @param {Element} element - The event target.
2487 * @param {string} type - The event type(s).
2488 * @param {Function} listener - The event listener.
2489 * @param {Object} options - The event options.
2490 */
2491 function removeListener(element, type, listener) {
2492 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
2493 var handler = listener;
2494 type.trim().split(REGEXP_SPACES).forEach(function (event) {
2495 if (!onceSupported) {
2496 var listeners = element.listeners;
2497 if (listeners && listeners[event] && listeners[event][listener]) {
2498 handler = listeners[event][listener];
2499 delete listeners[event][listener];
2500 if (Object.keys(listeners[event]).length === 0) {
2501 delete listeners[event];
2502 }
2503 if (Object.keys(listeners).length === 0) {
2504 delete element.listeners;
2505 }
2506 }
2507 }
2508 element.removeEventListener(event, handler, options);
2509 });
2510 }
2511
2512 /**
2513 * Add event listener to the target element.
2514 * @param {Element} element - The event target.
2515 * @param {string} type - The event type(s).
2516 * @param {Function} listener - The event listener.
2517 * @param {Object} options - The event options.
2518 */
2519 function addListener(element, type, listener) {
2520 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
2521 var _handler = listener;
2522 type.trim().split(REGEXP_SPACES).forEach(function (event) {
2523 if (options.once && !onceSupported) {
2524 var _element$listeners = element.listeners,
2525 listeners = _element$listeners === void 0 ? {} : _element$listeners;
2526 _handler = function handler() {
2527 delete listeners[event][listener];
2528 element.removeEventListener(event, _handler, options);
2529 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
2530 args[_key2] = arguments[_key2];
2531 }
2532 listener.apply(element, args);
2533 };
2534 if (!listeners[event]) {
2535 listeners[event] = {};
2536 }
2537 if (listeners[event][listener]) {
2538 element.removeEventListener(event, listeners[event][listener], options);
2539 }
2540 listeners[event][listener] = _handler;
2541 element.listeners = listeners;
2542 }
2543 element.addEventListener(event, _handler, options);
2544 });
2545 }
2546
2547 /**
2548 * Dispatch event on the target element.
2549 * @param {Element} element - The event target.
2550 * @param {string} type - The event type(s).
2551 * @param {Object} data - The additional event data.
2552 * @returns {boolean} Indicate if the event is default prevented or not.
2553 */
2554 function dispatchEvent(element, type, data) {
2555 var event;
2556
2557 // Event and CustomEvent on IE9-11 are global objects, not constructors
2558 if (isFunction(Event) && isFunction(CustomEvent)) {
2559 event = new CustomEvent(type, {
2560 detail: data,
2561 bubbles: true,
2562 cancelable: true
2563 });
2564 } else {
2565 event = document.createEvent('CustomEvent');
2566 event.initCustomEvent(type, true, true, data);
2567 }
2568 return element.dispatchEvent(event);
2569 }
2570
2571 /**
2572 * Get the offset base on the document.
2573 * @param {Element} element - The target element.
2574 * @returns {Object} The offset data.
2575 */
2576 function getOffset(element) {
2577 var box = element.getBoundingClientRect();
2578 return {
2579 left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
2580 top: box.top + (window.pageYOffset - document.documentElement.clientTop)
2581 };
2582 }
2583 var location = WINDOW.location;
2584 var REGEXP_ORIGINS = /^(\w+:)\/\/([^:/?#]*):?(\d*)/i;
2585
2586 /**
2587 * Check if the given URL is a cross origin URL.
2588 * @param {string} url - The target URL.
2589 * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
2590 */
2591 function isCrossOriginURL(url) {
2592 var parts = url.match(REGEXP_ORIGINS);
2593 return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
2594 }
2595
2596 /**
2597 * Add timestamp to the given URL.
2598 * @param {string} url - The target URL.
2599 * @returns {string} The result URL.
2600 */
2601 function addTimestamp(url) {
2602 var timestamp = "timestamp=".concat(new Date().getTime());
2603 return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
2604 }
2605
2606 /**
2607 * Get transforms base on the given object.
2608 * @param {Object} obj - The target object.
2609 * @returns {string} A string contains transform values.
2610 */
2611 function getTransforms(_ref) {
2612 var rotate = _ref.rotate,
2613 scaleX = _ref.scaleX,
2614 scaleY = _ref.scaleY,
2615 translateX = _ref.translateX,
2616 translateY = _ref.translateY;
2617 var values = [];
2618 if (isNumber(translateX) && translateX !== 0) {
2619 values.push("translateX(".concat(translateX, "px)"));
2620 }
2621 if (isNumber(translateY) && translateY !== 0) {
2622 values.push("translateY(".concat(translateY, "px)"));
2623 }
2624
2625 // Rotate should come first before scale to match orientation transform
2626 if (isNumber(rotate) && rotate !== 0) {
2627 values.push("rotate(".concat(rotate, "deg)"));
2628 }
2629 if (isNumber(scaleX) && scaleX !== 1) {
2630 values.push("scaleX(".concat(scaleX, ")"));
2631 }
2632 if (isNumber(scaleY) && scaleY !== 1) {
2633 values.push("scaleY(".concat(scaleY, ")"));
2634 }
2635 var transform = values.length ? values.join(' ') : 'none';
2636 return {
2637 WebkitTransform: transform,
2638 msTransform: transform,
2639 transform: transform
2640 };
2641 }
2642
2643 /**
2644 * Get the max ratio of a group of pointers.
2645 * @param {string} pointers - The target pointers.
2646 * @returns {number} The result ratio.
2647 */
2648 function getMaxZoomRatio(pointers) {
2649 var pointers2 = _objectSpread2({}, pointers);
2650 var maxRatio = 0;
2651 forEach(pointers, function (pointer, pointerId) {
2652 delete pointers2[pointerId];
2653 forEach(pointers2, function (pointer2) {
2654 var x1 = Math.abs(pointer.startX - pointer2.startX);
2655 var y1 = Math.abs(pointer.startY - pointer2.startY);
2656 var x2 = Math.abs(pointer.endX - pointer2.endX);
2657 var y2 = Math.abs(pointer.endY - pointer2.endY);
2658 var z1 = Math.sqrt(x1 * x1 + y1 * y1);
2659 var z2 = Math.sqrt(x2 * x2 + y2 * y2);
2660 var ratio = (z2 - z1) / z1;
2661 if (Math.abs(ratio) > Math.abs(maxRatio)) {
2662 maxRatio = ratio;
2663 }
2664 });
2665 });
2666 return maxRatio;
2667 }
2668
2669 /**
2670 * Get a pointer from an event object.
2671 * @param {Object} event - The target event object.
2672 * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
2673 * @returns {Object} The result pointer contains start and/or end point coordinates.
2674 */
2675 function getPointer(_ref2, endOnly) {
2676 var pageX = _ref2.pageX,
2677 pageY = _ref2.pageY;
2678 var end = {
2679 endX: pageX,
2680 endY: pageY
2681 };
2682 return endOnly ? end : _objectSpread2({
2683 startX: pageX,
2684 startY: pageY
2685 }, end);
2686 }
2687
2688 /**
2689 * Get the center point coordinate of a group of pointers.
2690 * @param {Object} pointers - The target pointers.
2691 * @returns {Object} The center point coordinate.
2692 */
2693 function getPointersCenter(pointers) {
2694 var pageX = 0;
2695 var pageY = 0;
2696 var count = 0;
2697 forEach(pointers, function (_ref3) {
2698 var startX = _ref3.startX,
2699 startY = _ref3.startY;
2700 pageX += startX;
2701 pageY += startY;
2702 count += 1;
2703 });
2704 pageX /= count;
2705 pageY /= count;
2706 return {
2707 pageX: pageX,
2708 pageY: pageY
2709 };
2710 }
2711
2712 /**
2713 * Get the max sizes in a rectangle under the given aspect ratio.
2714 * @param {Object} data - The original sizes.
2715 * @param {string} [type='contain'] - The adjust type.
2716 * @returns {Object} The result sizes.
2717 */
2718 function getAdjustedSizes(_ref4) {
2719 var aspectRatio = _ref4.aspectRatio,
2720 height = _ref4.height,
2721 width = _ref4.width;
2722 var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';
2723 var isValidWidth = isPositiveNumber(width);
2724 var isValidHeight = isPositiveNumber(height);
2725 if (isValidWidth && isValidHeight) {
2726 var adjustedWidth = height * aspectRatio;
2727 if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
2728 height = width / aspectRatio;
2729 } else {
2730 width = height * aspectRatio;
2731 }
2732 } else if (isValidWidth) {
2733 height = width / aspectRatio;
2734 } else if (isValidHeight) {
2735 width = height * aspectRatio;
2736 }
2737 return {
2738 width: width,
2739 height: height
2740 };
2741 }
2742
2743 /**
2744 * Get the new sizes of a rectangle after rotated.
2745 * @param {Object} data - The original sizes.
2746 * @returns {Object} The result sizes.
2747 */
2748 function getRotatedSizes(_ref5) {
2749 var width = _ref5.width,
2750 height = _ref5.height,
2751 degree = _ref5.degree;
2752 degree = Math.abs(degree) % 180;
2753 if (degree === 90) {
2754 return {
2755 width: height,
2756 height: width
2757 };
2758 }
2759 var arc = degree % 90 * Math.PI / 180;
2760 var sinArc = Math.sin(arc);
2761 var cosArc = Math.cos(arc);
2762 var newWidth = width * cosArc + height * sinArc;
2763 var newHeight = width * sinArc + height * cosArc;
2764 return degree > 90 ? {
2765 width: newHeight,
2766 height: newWidth
2767 } : {
2768 width: newWidth,
2769 height: newHeight
2770 };
2771 }
2772
2773 /**
2774 * Get a canvas which drew the given image.
2775 * @param {HTMLImageElement} image - The image for drawing.
2776 * @param {Object} imageData - The image data.
2777 * @param {Object} canvasData - The canvas data.
2778 * @param {Object} options - The options.
2779 * @returns {HTMLCanvasElement} The result canvas.
2780 */
2781 function getSourceCanvas(image, _ref6, _ref7, _ref8) {
2782 var imageAspectRatio = _ref6.aspectRatio,
2783 imageNaturalWidth = _ref6.naturalWidth,
2784 imageNaturalHeight = _ref6.naturalHeight,
2785 _ref6$rotate = _ref6.rotate,
2786 rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
2787 _ref6$scaleX = _ref6.scaleX,
2788 scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
2789 _ref6$scaleY = _ref6.scaleY,
2790 scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
2791 var aspectRatio = _ref7.aspectRatio,
2792 naturalWidth = _ref7.naturalWidth,
2793 naturalHeight = _ref7.naturalHeight;
2794 var _ref8$fillColor = _ref8.fillColor,
2795 fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
2796 _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
2797 imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
2798 _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
2799 imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
2800 _ref8$maxWidth = _ref8.maxWidth,
2801 maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
2802 _ref8$maxHeight = _ref8.maxHeight,
2803 maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
2804 _ref8$minWidth = _ref8.minWidth,
2805 minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
2806 _ref8$minHeight = _ref8.minHeight,
2807 minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
2808 var canvas = document.createElement('canvas');
2809 var context = canvas.getContext('2d');
2810 var maxSizes = getAdjustedSizes({
2811 aspectRatio: aspectRatio,
2812 width: maxWidth,
2813 height: maxHeight
2814 });
2815 var minSizes = getAdjustedSizes({
2816 aspectRatio: aspectRatio,
2817 width: minWidth,
2818 height: minHeight
2819 }, 'cover');
2820 var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
2821 var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight));
2822
2823 // Note: should always use image's natural sizes for drawing as
2824 // imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
2825 var destMaxSizes = getAdjustedSizes({
2826 aspectRatio: imageAspectRatio,
2827 width: maxWidth,
2828 height: maxHeight
2829 });
2830 var destMinSizes = getAdjustedSizes({
2831 aspectRatio: imageAspectRatio,
2832 width: minWidth,
2833 height: minHeight
2834 }, 'cover');
2835 var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));
2836 var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));
2837 var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];
2838 canvas.width = normalizeDecimalNumber(width);
2839 canvas.height = normalizeDecimalNumber(height);
2840 context.fillStyle = fillColor;
2841 context.fillRect(0, 0, width, height);
2842 context.save();
2843 context.translate(width / 2, height / 2);
2844 context.rotate(rotate * Math.PI / 180);
2845 context.scale(scaleX, scaleY);
2846 context.imageSmoothingEnabled = imageSmoothingEnabled;
2847 context.imageSmoothingQuality = imageSmoothingQuality;
2848 context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {
2849 return Math.floor(normalizeDecimalNumber(param));
2850 }))));
2851 context.restore();
2852 return canvas;
2853 }
2854 var fromCharCode = String.fromCharCode;
2855
2856 /**
2857 * Get string from char code in data view.
2858 * @param {DataView} dataView - The data view for read.
2859 * @param {number} start - The start index.
2860 * @param {number} length - The read length.
2861 * @returns {string} The read result.
2862 */
2863 function getStringFromCharCode(dataView, start, length) {
2864 var str = '';
2865 length += start;
2866 for (var i = start; i < length; i += 1) {
2867 str += fromCharCode(dataView.getUint8(i));
2868 }
2869 return str;
2870 }
2871 var REGEXP_DATA_URL_HEAD = /^data:.*,/;
2872
2873 /**
2874 * Transform Data URL to array buffer.
2875 * @param {string} dataURL - The Data URL to transform.
2876 * @returns {ArrayBuffer} The result array buffer.
2877 */
2878 function dataURLToArrayBuffer(dataURL) {
2879 var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
2880 var binary = atob(base64);
2881 var arrayBuffer = new ArrayBuffer(binary.length);
2882 var uint8 = new Uint8Array(arrayBuffer);
2883 forEach(uint8, function (value, i) {
2884 uint8[i] = binary.charCodeAt(i);
2885 });
2886 return arrayBuffer;
2887 }
2888
2889 /**
2890 * Transform array buffer to Data URL.
2891 * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
2892 * @param {string} mimeType - The mime type of the Data URL.
2893 * @returns {string} The result Data URL.
2894 */
2895 function arrayBufferToDataURL(arrayBuffer, mimeType) {
2896 var chunks = [];
2897
2898 // Chunk Typed Array for better performance (#435)
2899 var chunkSize = 8192;
2900 var uint8 = new Uint8Array(arrayBuffer);
2901 while (uint8.length > 0) {
2902 // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
2903 // eslint-disable-next-line prefer-spread
2904 chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
2905 uint8 = uint8.subarray(chunkSize);
2906 }
2907 return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
2908 }
2909
2910 /**
2911 * Get orientation value from given array buffer.
2912 * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
2913 * @returns {number} The read orientation value.
2914 */
2915 function resetAndGetOrientation(arrayBuffer) {
2916 var dataView = new DataView(arrayBuffer);
2917 var orientation;
2918
2919 // Ignores range error when the image does not have correct Exif information
2920 try {
2921 var littleEndian;
2922 var app1Start;
2923 var ifdStart;
2924
2925 // Only handle JPEG image (start by 0xFFD8)
2926 if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
2927 var length = dataView.byteLength;
2928 var offset = 2;
2929 while (offset + 1 < length) {
2930 if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
2931 app1Start = offset;
2932 break;
2933 }
2934 offset += 1;
2935 }
2936 }
2937 if (app1Start) {
2938 var exifIDCode = app1Start + 4;
2939 var tiffOffset = app1Start + 10;
2940 if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
2941 var endianness = dataView.getUint16(tiffOffset);
2942 littleEndian = endianness === 0x4949;
2943 if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
2944 if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
2945 var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
2946 if (firstIFDOffset >= 0x00000008) {
2947 ifdStart = tiffOffset + firstIFDOffset;
2948 }
2949 }
2950 }
2951 }
2952 }
2953 if (ifdStart) {
2954 var _length = dataView.getUint16(ifdStart, littleEndian);
2955 var _offset;
2956 var i;
2957 for (i = 0; i < _length; i += 1) {
2958 _offset = ifdStart + i * 12 + 2;
2959 if (dataView.getUint16(_offset, littleEndian) === 0x0112 /* Orientation */) {
2960 // 8 is the offset of the current tag's value
2961 _offset += 8;
2962
2963 // Get the original orientation value
2964 orientation = dataView.getUint16(_offset, littleEndian);
2965
2966 // Override the orientation with its default value
2967 dataView.setUint16(_offset, 1, littleEndian);
2968 break;
2969 }
2970 }
2971 }
2972 } catch (error) {
2973 orientation = 1;
2974 }
2975 return orientation;
2976 }
2977
2978 /**
2979 * Parse Exif Orientation value.
2980 * @param {number} orientation - The orientation to parse.
2981 * @returns {Object} The parsed result.
2982 */
2983 function parseOrientation(orientation) {
2984 var rotate = 0;
2985 var scaleX = 1;
2986 var scaleY = 1;
2987 switch (orientation) {
2988 // Flip horizontal
2989 case 2:
2990 scaleX = -1;
2991 break;
2992
2993 // Rotate left 180°
2994 case 3:
2995 rotate = -180;
2996 break;
2997
2998 // Flip vertical
2999 case 4:
3000 scaleY = -1;
3001 break;
3002
3003 // Flip vertical and rotate right 90°
3004 case 5:
3005 rotate = 90;
3006 scaleY = -1;
3007 break;
3008
3009 // Rotate right 90°
3010 case 6:
3011 rotate = 90;
3012 break;
3013
3014 // Flip horizontal and rotate right 90°
3015 case 7:
3016 rotate = 90;
3017 scaleX = -1;
3018 break;
3019
3020 // Rotate left 90°
3021 case 8:
3022 rotate = -90;
3023 break;
3024 }
3025 return {
3026 rotate: rotate,
3027 scaleX: scaleX,
3028 scaleY: scaleY
3029 };
3030 }
3031
3032 var render = {
3033 render: function render() {
3034 this.initContainer();
3035 this.initCanvas();
3036 this.initCropBox();
3037 this.renderCanvas();
3038 if (this.cropped) {
3039 this.renderCropBox();
3040 }
3041 },
3042 initContainer: function initContainer() {
3043 var element = this.element,
3044 options = this.options,
3045 container = this.container,
3046 cropper = this.cropper;
3047 var minWidth = Number(options.minContainerWidth);
3048 var minHeight = Number(options.minContainerHeight);
3049 addClass(cropper, CLASS_HIDDEN);
3050 removeClass(element, CLASS_HIDDEN);
3051 var containerData = {
3052 width: Math.max(container.offsetWidth, minWidth >= 0 ? minWidth : MIN_CONTAINER_WIDTH),
3053 height: Math.max(container.offsetHeight, minHeight >= 0 ? minHeight : MIN_CONTAINER_HEIGHT)
3054 };
3055 this.containerData = containerData;
3056 setStyle(cropper, {
3057 width: containerData.width,
3058 height: containerData.height
3059 });
3060 addClass(element, CLASS_HIDDEN);
3061 removeClass(cropper, CLASS_HIDDEN);
3062 },
3063 // Canvas (image wrapper)
3064 initCanvas: function initCanvas() {
3065 var containerData = this.containerData,
3066 imageData = this.imageData;
3067 var viewMode = this.options.viewMode;
3068 var rotated = Math.abs(imageData.rotate) % 180 === 90;
3069 var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
3070 var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
3071 var aspectRatio = naturalWidth / naturalHeight;
3072 var canvasWidth = containerData.width;
3073 var canvasHeight = containerData.height;
3074 if (containerData.height * aspectRatio > containerData.width) {
3075 if (viewMode === 3) {
3076 canvasWidth = containerData.height * aspectRatio;
3077 } else {
3078 canvasHeight = containerData.width / aspectRatio;
3079 }
3080 } else if (viewMode === 3) {
3081 canvasHeight = containerData.width / aspectRatio;
3082 } else {
3083 canvasWidth = containerData.height * aspectRatio;
3084 }
3085 var canvasData = {
3086 aspectRatio: aspectRatio,
3087 naturalWidth: naturalWidth,
3088 naturalHeight: naturalHeight,
3089 width: canvasWidth,
3090 height: canvasHeight
3091 };
3092 this.canvasData = canvasData;
3093 this.limited = viewMode === 1 || viewMode === 2;
3094 this.limitCanvas(true, true);
3095 canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
3096 canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
3097 canvasData.left = (containerData.width - canvasData.width) / 2;
3098 canvasData.top = (containerData.height - canvasData.height) / 2;
3099 canvasData.oldLeft = canvasData.left;
3100 canvasData.oldTop = canvasData.top;
3101 this.initialCanvasData = assign({}, canvasData);
3102 },
3103 limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
3104 var options = this.options,
3105 containerData = this.containerData,
3106 canvasData = this.canvasData,
3107 cropBoxData = this.cropBoxData;
3108 var viewMode = options.viewMode;
3109 var aspectRatio = canvasData.aspectRatio;
3110 var cropped = this.cropped && cropBoxData;
3111 if (sizeLimited) {
3112 var minCanvasWidth = Number(options.minCanvasWidth) || 0;
3113 var minCanvasHeight = Number(options.minCanvasHeight) || 0;
3114 if (viewMode > 1) {
3115 minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
3116 minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
3117 if (viewMode === 3) {
3118 if (minCanvasHeight * aspectRatio > minCanvasWidth) {
3119 minCanvasWidth = minCanvasHeight * aspectRatio;
3120 } else {
3121 minCanvasHeight = minCanvasWidth / aspectRatio;
3122 }
3123 }
3124 } else if (viewMode > 0) {
3125 if (minCanvasWidth) {
3126 minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);
3127 } else if (minCanvasHeight) {
3128 minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);
3129 } else if (cropped) {
3130 minCanvasWidth = cropBoxData.width;
3131 minCanvasHeight = cropBoxData.height;
3132 if (minCanvasHeight * aspectRatio > minCanvasWidth) {
3133 minCanvasWidth = minCanvasHeight * aspectRatio;
3134 } else {
3135 minCanvasHeight = minCanvasWidth / aspectRatio;
3136 }
3137 }
3138 }
3139 var _getAdjustedSizes = getAdjustedSizes({
3140 aspectRatio: aspectRatio,
3141 width: minCanvasWidth,
3142 height: minCanvasHeight
3143 });
3144 minCanvasWidth = _getAdjustedSizes.width;
3145 minCanvasHeight = _getAdjustedSizes.height;
3146 canvasData.minWidth = minCanvasWidth;
3147 canvasData.minHeight = minCanvasHeight;
3148 canvasData.maxWidth = Infinity;
3149 canvasData.maxHeight = Infinity;
3150 }
3151 if (positionLimited) {
3152 if (viewMode > (cropped ? 0 : 1)) {
3153 var newCanvasLeft = containerData.width - canvasData.width;
3154 var newCanvasTop = containerData.height - canvasData.height;
3155 canvasData.minLeft = Math.min(0, newCanvasLeft);
3156 canvasData.minTop = Math.min(0, newCanvasTop);
3157 canvasData.maxLeft = Math.max(0, newCanvasLeft);
3158 canvasData.maxTop = Math.max(0, newCanvasTop);
3159 if (cropped && this.limited) {
3160 canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
3161 canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
3162 canvasData.maxLeft = cropBoxData.left;
3163 canvasData.maxTop = cropBoxData.top;
3164 if (viewMode === 2) {
3165 if (canvasData.width >= containerData.width) {
3166 canvasData.minLeft = Math.min(0, newCanvasLeft);
3167 canvasData.maxLeft = Math.max(0, newCanvasLeft);
3168 }
3169 if (canvasData.height >= containerData.height) {
3170 canvasData.minTop = Math.min(0, newCanvasTop);
3171 canvasData.maxTop = Math.max(0, newCanvasTop);
3172 }
3173 }
3174 }
3175 } else {
3176 canvasData.minLeft = -canvasData.width;
3177 canvasData.minTop = -canvasData.height;
3178 canvasData.maxLeft = containerData.width;
3179 canvasData.maxTop = containerData.height;
3180 }
3181 }
3182 },
3183 renderCanvas: function renderCanvas(changed, transformed) {
3184 var canvasData = this.canvasData,
3185 imageData = this.imageData;
3186 if (transformed) {
3187 var _getRotatedSizes = getRotatedSizes({
3188 width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
3189 height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
3190 degree: imageData.rotate || 0
3191 }),
3192 naturalWidth = _getRotatedSizes.width,
3193 naturalHeight = _getRotatedSizes.height;
3194 var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
3195 var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
3196 canvasData.left -= (width - canvasData.width) / 2;
3197 canvasData.top -= (height - canvasData.height) / 2;
3198 canvasData.width = width;
3199 canvasData.height = height;
3200 canvasData.aspectRatio = naturalWidth / naturalHeight;
3201 canvasData.naturalWidth = naturalWidth;
3202 canvasData.naturalHeight = naturalHeight;
3203 this.limitCanvas(true, false);
3204 }
3205 if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
3206 canvasData.left = canvasData.oldLeft;
3207 }
3208 if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
3209 canvasData.top = canvasData.oldTop;
3210 }
3211 canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
3212 canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
3213 this.limitCanvas(false, true);
3214 canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);
3215 canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);
3216 canvasData.oldLeft = canvasData.left;
3217 canvasData.oldTop = canvasData.top;
3218 setStyle(this.canvas, assign({
3219 width: canvasData.width,
3220 height: canvasData.height
3221 }, getTransforms({
3222 translateX: canvasData.left,
3223 translateY: canvasData.top
3224 })));
3225 this.renderImage(changed);
3226 if (this.cropped && this.limited) {
3227 this.limitCropBox(true, true);
3228 }
3229 },
3230 renderImage: function renderImage(changed) {
3231 var canvasData = this.canvasData,
3232 imageData = this.imageData;
3233 var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
3234 var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
3235 assign(imageData, {
3236 width: width,
3237 height: height,
3238 left: (canvasData.width - width) / 2,
3239 top: (canvasData.height - height) / 2
3240 });
3241 setStyle(this.image, assign({
3242 width: imageData.width,
3243 height: imageData.height
3244 }, getTransforms(assign({
3245 translateX: imageData.left,
3246 translateY: imageData.top
3247 }, imageData))));
3248 if (changed) {
3249 this.output();
3250 }
3251 },
3252 initCropBox: function initCropBox() {
3253 var options = this.options,
3254 canvasData = this.canvasData;
3255 var aspectRatio = options.aspectRatio || options.initialAspectRatio;
3256 var autoCropArea = Number(options.autoCropArea) || 0.8;
3257 var cropBoxData = {
3258 width: canvasData.width,
3259 height: canvasData.height
3260 };
3261 if (aspectRatio) {
3262 if (canvasData.height * aspectRatio > canvasData.width) {
3263 cropBoxData.height = cropBoxData.width / aspectRatio;
3264 } else {
3265 cropBoxData.width = cropBoxData.height * aspectRatio;
3266 }
3267 }
3268 this.cropBoxData = cropBoxData;
3269 this.limitCropBox(true, true);
3270
3271 // Initialize auto crop area
3272 cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
3273 cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
3274
3275 // The width/height of auto crop area must large than "minWidth/Height"
3276 cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
3277 cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
3278 cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
3279 cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;
3280 cropBoxData.oldLeft = cropBoxData.left;
3281 cropBoxData.oldTop = cropBoxData.top;
3282 this.initialCropBoxData = assign({}, cropBoxData);
3283 },
3284 limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
3285 var options = this.options,
3286 containerData = this.containerData,
3287 canvasData = this.canvasData,
3288 cropBoxData = this.cropBoxData,
3289 limited = this.limited;
3290 var aspectRatio = options.aspectRatio;
3291 if (sizeLimited) {
3292 var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
3293 var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
3294 var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;
3295 var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height;
3296
3297 // The min/maxCropBoxWidth/Height must be less than container's width/height
3298 minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
3299 minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
3300 if (aspectRatio) {
3301 if (minCropBoxWidth && minCropBoxHeight) {
3302 if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
3303 minCropBoxHeight = minCropBoxWidth / aspectRatio;
3304 } else {
3305 minCropBoxWidth = minCropBoxHeight * aspectRatio;
3306 }
3307 } else if (minCropBoxWidth) {
3308 minCropBoxHeight = minCropBoxWidth / aspectRatio;
3309 } else if (minCropBoxHeight) {
3310 minCropBoxWidth = minCropBoxHeight * aspectRatio;
3311 }
3312 if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
3313 maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
3314 } else {
3315 maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
3316 }
3317 }
3318
3319 // The minWidth/Height must be less than maxWidth/Height
3320 cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
3321 cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
3322 cropBoxData.maxWidth = maxCropBoxWidth;
3323 cropBoxData.maxHeight = maxCropBoxHeight;
3324 }
3325 if (positionLimited) {
3326 if (limited) {
3327 cropBoxData.minLeft = Math.max(0, canvasData.left);
3328 cropBoxData.minTop = Math.max(0, canvasData.top);
3329 cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;
3330 cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;
3331 } else {
3332 cropBoxData.minLeft = 0;
3333 cropBoxData.minTop = 0;
3334 cropBoxData.maxLeft = containerData.width - cropBoxData.width;
3335 cropBoxData.maxTop = containerData.height - cropBoxData.height;
3336 }
3337 }
3338 },
3339 renderCropBox: function renderCropBox() {
3340 var options = this.options,
3341 containerData = this.containerData,
3342 cropBoxData = this.cropBoxData;
3343 if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
3344 cropBoxData.left = cropBoxData.oldLeft;
3345 }
3346 if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
3347 cropBoxData.top = cropBoxData.oldTop;
3348 }
3349 cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
3350 cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
3351 this.limitCropBox(false, true);
3352 cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);
3353 cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
3354 cropBoxData.oldLeft = cropBoxData.left;
3355 cropBoxData.oldTop = cropBoxData.top;
3356 if (options.movable && options.cropBoxMovable) {
3357 // Turn to move the canvas when the crop box is equal to the container
3358 setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
3359 }
3360 setStyle(this.cropBox, assign({
3361 width: cropBoxData.width,
3362 height: cropBoxData.height
3363 }, getTransforms({
3364 translateX: cropBoxData.left,
3365 translateY: cropBoxData.top
3366 })));
3367 if (this.cropped && this.limited) {
3368 this.limitCanvas(true, true);
3369 }
3370 if (!this.disabled) {
3371 this.output();
3372 }
3373 },
3374 output: function output() {
3375 this.preview();
3376 dispatchEvent(this.element, EVENT_CROP, this.getData());
3377 }
3378 };
3379
3380 var preview = {
3381 initPreview: function initPreview() {
3382 var element = this.element,
3383 crossOrigin = this.crossOrigin;
3384 var preview = this.options.preview;
3385 var url = crossOrigin ? this.crossOriginUrl : this.url;
3386 var alt = element.alt || 'The image to preview';
3387 var image = document.createElement('img');
3388 if (crossOrigin) {
3389 image.crossOrigin = crossOrigin;
3390 }
3391 image.src = url;
3392 image.alt = alt;
3393 this.viewBox.appendChild(image);
3394 this.viewBoxImage = image;
3395 if (!preview) {
3396 return;
3397 }
3398 var previews = preview;
3399 if (typeof preview === 'string') {
3400 previews = element.ownerDocument.querySelectorAll(preview);
3401 } else if (preview.querySelector) {
3402 previews = [preview];
3403 }
3404 this.previews = previews;
3405 forEach(previews, function (el) {
3406 var img = document.createElement('img');
3407
3408 // Save the original size for recover
3409 setData(el, DATA_PREVIEW, {
3410 width: el.offsetWidth,
3411 height: el.offsetHeight,
3412 html: el.innerHTML
3413 });
3414 if (crossOrigin) {
3415 img.crossOrigin = crossOrigin;
3416 }
3417 img.src = url;
3418 img.alt = alt;
3419
3420 /**
3421 * Override img element styles
3422 * Add `display:block` to avoid margin top issue
3423 * Add `height:auto` to override `height` attribute on IE8
3424 * (Occur only when margin-top <= -height)
3425 */
3426 img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
3427 el.innerHTML = '';
3428 el.appendChild(img);
3429 });
3430 },
3431 resetPreview: function resetPreview() {
3432 forEach(this.previews, function (element) {
3433 var data = getData(element, DATA_PREVIEW);
3434 setStyle(element, {
3435 width: data.width,
3436 height: data.height
3437 });
3438 element.innerHTML = data.html;
3439 removeData(element, DATA_PREVIEW);
3440 });
3441 },
3442 preview: function preview() {
3443 var imageData = this.imageData,
3444 canvasData = this.canvasData,
3445 cropBoxData = this.cropBoxData;
3446 var cropBoxWidth = cropBoxData.width,
3447 cropBoxHeight = cropBoxData.height;
3448 var width = imageData.width,
3449 height = imageData.height;
3450 var left = cropBoxData.left - canvasData.left - imageData.left;
3451 var top = cropBoxData.top - canvasData.top - imageData.top;
3452 if (!this.cropped || this.disabled) {
3453 return;
3454 }
3455 setStyle(this.viewBoxImage, assign({
3456 width: width,
3457 height: height
3458 }, getTransforms(assign({
3459 translateX: -left,
3460 translateY: -top
3461 }, imageData))));
3462 forEach(this.previews, function (element) {
3463 var data = getData(element, DATA_PREVIEW);
3464 var originalWidth = data.width;
3465 var originalHeight = data.height;
3466 var newWidth = originalWidth;
3467 var newHeight = originalHeight;
3468 var ratio = 1;
3469 if (cropBoxWidth) {
3470 ratio = originalWidth / cropBoxWidth;
3471 newHeight = cropBoxHeight * ratio;
3472 }
3473 if (cropBoxHeight && newHeight > originalHeight) {
3474 ratio = originalHeight / cropBoxHeight;
3475 newWidth = cropBoxWidth * ratio;
3476 newHeight = originalHeight;
3477 }
3478 setStyle(element, {
3479 width: newWidth,
3480 height: newHeight
3481 });
3482 setStyle(element.getElementsByTagName('img')[0], assign({
3483 width: width * ratio,
3484 height: height * ratio
3485 }, getTransforms(assign({
3486 translateX: -left * ratio,
3487 translateY: -top * ratio
3488 }, imageData))));
3489 });
3490 }
3491 };
3492
3493 var events = {
3494 bind: function bind() {
3495 var element = this.element,
3496 options = this.options,
3497 cropper = this.cropper;
3498 if (isFunction(options.cropstart)) {
3499 addListener(element, EVENT_CROP_START, options.cropstart);
3500 }
3501 if (isFunction(options.cropmove)) {
3502 addListener(element, EVENT_CROP_MOVE, options.cropmove);
3503 }
3504 if (isFunction(options.cropend)) {
3505 addListener(element, EVENT_CROP_END, options.cropend);
3506 }
3507 if (isFunction(options.crop)) {
3508 addListener(element, EVENT_CROP, options.crop);
3509 }
3510 if (isFunction(options.zoom)) {
3511 addListener(element, EVENT_ZOOM, options.zoom);
3512 }
3513 addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));
3514 if (options.zoomable && options.zoomOnWheel) {
3515 addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
3516 passive: false,
3517 capture: true
3518 });
3519 }
3520 if (options.toggleDragModeOnDblclick) {
3521 addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
3522 }
3523 addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));
3524 addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));
3525 if (options.responsive) {
3526 addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
3527 }
3528 },
3529 unbind: function unbind() {
3530 var element = this.element,
3531 options = this.options,
3532 cropper = this.cropper;
3533 if (isFunction(options.cropstart)) {
3534 removeListener(element, EVENT_CROP_START, options.cropstart);
3535 }
3536 if (isFunction(options.cropmove)) {
3537 removeListener(element, EVENT_CROP_MOVE, options.cropmove);
3538 }
3539 if (isFunction(options.cropend)) {
3540 removeListener(element, EVENT_CROP_END, options.cropend);
3541 }
3542 if (isFunction(options.crop)) {
3543 removeListener(element, EVENT_CROP, options.crop);
3544 }
3545 if (isFunction(options.zoom)) {
3546 removeListener(element, EVENT_ZOOM, options.zoom);
3547 }
3548 removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
3549 if (options.zoomable && options.zoomOnWheel) {
3550 removeListener(cropper, EVENT_WHEEL, this.onWheel, {
3551 passive: false,
3552 capture: true
3553 });
3554 }
3555 if (options.toggleDragModeOnDblclick) {
3556 removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
3557 }
3558 removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
3559 removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
3560 if (options.responsive) {
3561 removeListener(window, EVENT_RESIZE, this.onResize);
3562 }
3563 }
3564 };
3565
3566 var handlers = {
3567 resize: function resize() {
3568 if (this.disabled) {
3569 return;
3570 }
3571 var options = this.options,
3572 container = this.container,
3573 containerData = this.containerData;
3574 var ratioX = container.offsetWidth / containerData.width;
3575 var ratioY = container.offsetHeight / containerData.height;
3576 var ratio = Math.abs(ratioX - 1) > Math.abs(ratioY - 1) ? ratioX : ratioY;
3577
3578 // Resize when width changed or height changed
3579 if (ratio !== 1) {
3580 var canvasData;
3581 var cropBoxData;
3582 if (options.restore) {
3583 canvasData = this.getCanvasData();
3584 cropBoxData = this.getCropBoxData();
3585 }
3586 this.render();
3587 if (options.restore) {
3588 this.setCanvasData(forEach(canvasData, function (n, i) {
3589 canvasData[i] = n * ratio;
3590 }));
3591 this.setCropBoxData(forEach(cropBoxData, function (n, i) {
3592 cropBoxData[i] = n * ratio;
3593 }));
3594 }
3595 }
3596 },
3597 dblclick: function dblclick() {
3598 if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
3599 return;
3600 }
3601 this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
3602 },
3603 wheel: function wheel(event) {
3604 var _this = this;
3605 var ratio = Number(this.options.wheelZoomRatio) || 0.1;
3606 var delta = 1;
3607 if (this.disabled) {
3608 return;
3609 }
3610 event.preventDefault();
3611
3612 // Limit wheel speed to prevent zoom too fast (#21)
3613 if (this.wheeling) {
3614 return;
3615 }
3616 this.wheeling = true;
3617 setTimeout(function () {
3618 _this.wheeling = false;
3619 }, 50);
3620 if (event.deltaY) {
3621 delta = event.deltaY > 0 ? 1 : -1;
3622 } else if (event.wheelDelta) {
3623 delta = -event.wheelDelta / 120;
3624 } else if (event.detail) {
3625 delta = event.detail > 0 ? 1 : -1;
3626 }
3627 this.zoom(-delta * ratio, event);
3628 },
3629 cropStart: function cropStart(event) {
3630 var buttons = event.buttons,
3631 button = event.button;
3632 if (this.disabled
3633
3634 // Handle mouse event and pointer event and ignore touch event
3635 || (event.type === 'mousedown' || event.type === 'pointerdown' && event.pointerType === 'mouse') && (
3636 // No primary button (Usually the left button)
3637 isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0
3638
3639 // Open context menu
3640 || event.ctrlKey)) {
3641 return;
3642 }
3643 var options = this.options,
3644 pointers = this.pointers;
3645 var action;
3646 if (event.changedTouches) {
3647 // Handle touch event
3648 forEach(event.changedTouches, function (touch) {
3649 pointers[touch.identifier] = getPointer(touch);
3650 });
3651 } else {
3652 // Handle mouse event and pointer event
3653 pointers[event.pointerId || 0] = getPointer(event);
3654 }
3655 if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
3656 action = ACTION_ZOOM;
3657 } else {
3658 action = getData(event.target, DATA_ACTION);
3659 }
3660 if (!REGEXP_ACTIONS.test(action)) {
3661 return;
3662 }
3663 if (dispatchEvent(this.element, EVENT_CROP_START, {
3664 originalEvent: event,
3665 action: action
3666 }) === false) {
3667 return;
3668 }
3669
3670 // This line is required for preventing page zooming in iOS browsers
3671 event.preventDefault();
3672 this.action = action;
3673 this.cropping = false;
3674 if (action === ACTION_CROP) {
3675 this.cropping = true;
3676 addClass(this.dragBox, CLASS_MODAL);
3677 }
3678 },
3679 cropMove: function cropMove(event) {
3680 var action = this.action;
3681 if (this.disabled || !action) {
3682 return;
3683 }
3684 var pointers = this.pointers;
3685 event.preventDefault();
3686 if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
3687 originalEvent: event,
3688 action: action
3689 }) === false) {
3690 return;
3691 }
3692 if (event.changedTouches) {
3693 forEach(event.changedTouches, function (touch) {
3694 // The first parameter should not be undefined (#432)
3695 assign(pointers[touch.identifier] || {}, getPointer(touch, true));
3696 });
3697 } else {
3698 assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
3699 }
3700 this.change(event);
3701 },
3702 cropEnd: function cropEnd(event) {
3703 if (this.disabled) {
3704 return;
3705 }
3706 var action = this.action,
3707 pointers = this.pointers;
3708 if (event.changedTouches) {
3709 forEach(event.changedTouches, function (touch) {
3710 delete pointers[touch.identifier];
3711 });
3712 } else {
3713 delete pointers[event.pointerId || 0];
3714 }
3715 if (!action) {
3716 return;
3717 }
3718 event.preventDefault();
3719 if (!Object.keys(pointers).length) {
3720 this.action = '';
3721 }
3722 if (this.cropping) {
3723 this.cropping = false;
3724 toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
3725 }
3726 dispatchEvent(this.element, EVENT_CROP_END, {
3727 originalEvent: event,
3728 action: action
3729 });
3730 }
3731 };
3732
3733 var change = {
3734 change: function change(event) {
3735 var options = this.options,
3736 canvasData = this.canvasData,
3737 containerData = this.containerData,
3738 cropBoxData = this.cropBoxData,
3739 pointers = this.pointers;
3740 var action = this.action;
3741 var aspectRatio = options.aspectRatio;
3742 var left = cropBoxData.left,
3743 top = cropBoxData.top,
3744 width = cropBoxData.width,
3745 height = cropBoxData.height;
3746 var right = left + width;
3747 var bottom = top + height;
3748 var minLeft = 0;
3749 var minTop = 0;
3750 var maxWidth = containerData.width;
3751 var maxHeight = containerData.height;
3752 var renderable = true;
3753 var offset;
3754
3755 // Locking aspect ratio in "free mode" by holding shift key
3756 if (!aspectRatio && event.shiftKey) {
3757 aspectRatio = width && height ? width / height : 1;
3758 }
3759 if (this.limited) {
3760 minLeft = cropBoxData.minLeft;
3761 minTop = cropBoxData.minTop;
3762 maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
3763 maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
3764 }
3765 var pointer = pointers[Object.keys(pointers)[0]];
3766 var range = {
3767 x: pointer.endX - pointer.startX,
3768 y: pointer.endY - pointer.startY
3769 };
3770 var check = function check(side) {
3771 switch (side) {
3772 case ACTION_EAST:
3773 if (right + range.x > maxWidth) {
3774 range.x = maxWidth - right;
3775 }
3776 break;
3777 case ACTION_WEST:
3778 if (left + range.x < minLeft) {
3779 range.x = minLeft - left;
3780 }
3781 break;
3782 case ACTION_NORTH:
3783 if (top + range.y < minTop) {
3784 range.y = minTop - top;
3785 }
3786 break;
3787 case ACTION_SOUTH:
3788 if (bottom + range.y > maxHeight) {
3789 range.y = maxHeight - bottom;
3790 }
3791 break;
3792 }
3793 };
3794 switch (action) {
3795 // Move crop box
3796 case ACTION_ALL:
3797 left += range.x;
3798 top += range.y;
3799 break;
3800
3801 // Resize crop box
3802 case ACTION_EAST:
3803 if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
3804 renderable = false;
3805 break;
3806 }
3807 check(ACTION_EAST);
3808 width += range.x;
3809 if (width < 0) {
3810 action = ACTION_WEST;
3811 width = -width;
3812 left -= width;
3813 }
3814 if (aspectRatio) {
3815 height = width / aspectRatio;
3816 top += (cropBoxData.height - height) / 2;
3817 }
3818 break;
3819 case ACTION_NORTH:
3820 if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
3821 renderable = false;
3822 break;
3823 }
3824 check(ACTION_NORTH);
3825 height -= range.y;
3826 top += range.y;
3827 if (height < 0) {
3828 action = ACTION_SOUTH;
3829 height = -height;
3830 top -= height;
3831 }
3832 if (aspectRatio) {
3833 width = height * aspectRatio;
3834 left += (cropBoxData.width - width) / 2;
3835 }
3836 break;
3837 case ACTION_WEST:
3838 if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
3839 renderable = false;
3840 break;
3841 }
3842 check(ACTION_WEST);
3843 width -= range.x;
3844 left += range.x;
3845 if (width < 0) {
3846 action = ACTION_EAST;
3847 width = -width;
3848 left -= width;
3849 }
3850 if (aspectRatio) {
3851 height = width / aspectRatio;
3852 top += (cropBoxData.height - height) / 2;
3853 }
3854 break;
3855 case ACTION_SOUTH:
3856 if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
3857 renderable = false;
3858 break;
3859 }
3860 check(ACTION_SOUTH);
3861 height += range.y;
3862 if (height < 0) {
3863 action = ACTION_NORTH;
3864 height = -height;
3865 top -= height;
3866 }
3867 if (aspectRatio) {
3868 width = height * aspectRatio;
3869 left += (cropBoxData.width - width) / 2;
3870 }
3871 break;
3872 case ACTION_NORTH_EAST:
3873 if (aspectRatio) {
3874 if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
3875 renderable = false;
3876 break;
3877 }
3878 check(ACTION_NORTH);
3879 height -= range.y;
3880 top += range.y;
3881 width = height * aspectRatio;
3882 } else {
3883 check(ACTION_NORTH);
3884 check(ACTION_EAST);
3885 if (range.x >= 0) {
3886 if (right < maxWidth) {
3887 width += range.x;
3888 } else if (range.y <= 0 && top <= minTop) {
3889 renderable = false;
3890 }
3891 } else {
3892 width += range.x;
3893 }
3894 if (range.y <= 0) {
3895 if (top > minTop) {
3896 height -= range.y;
3897 top += range.y;
3898 }
3899 } else {
3900 height -= range.y;
3901 top += range.y;
3902 }
3903 }
3904 if (width < 0 && height < 0) {
3905 action = ACTION_SOUTH_WEST;
3906 height = -height;
3907 width = -width;
3908 top -= height;
3909 left -= width;
3910 } else if (width < 0) {
3911 action = ACTION_NORTH_WEST;
3912 width = -width;
3913 left -= width;
3914 } else if (height < 0) {
3915 action = ACTION_SOUTH_EAST;
3916 height = -height;
3917 top -= height;
3918 }
3919 break;
3920 case ACTION_NORTH_WEST:
3921 if (aspectRatio) {
3922 if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
3923 renderable = false;
3924 break;
3925 }
3926 check(ACTION_NORTH);
3927 height -= range.y;
3928 top += range.y;
3929 width = height * aspectRatio;
3930 left += cropBoxData.width - width;
3931 } else {
3932 check(ACTION_NORTH);
3933 check(ACTION_WEST);
3934 if (range.x <= 0) {
3935 if (left > minLeft) {
3936 width -= range.x;
3937 left += range.x;
3938 } else if (range.y <= 0 && top <= minTop) {
3939 renderable = false;
3940 }
3941 } else {
3942 width -= range.x;
3943 left += range.x;
3944 }
3945 if (range.y <= 0) {
3946 if (top > minTop) {
3947 height -= range.y;
3948 top += range.y;
3949 }
3950 } else {
3951 height -= range.y;
3952 top += range.y;
3953 }
3954 }
3955 if (width < 0 && height < 0) {
3956 action = ACTION_SOUTH_EAST;
3957 height = -height;
3958 width = -width;
3959 top -= height;
3960 left -= width;
3961 } else if (width < 0) {
3962 action = ACTION_NORTH_EAST;
3963 width = -width;
3964 left -= width;
3965 } else if (height < 0) {
3966 action = ACTION_SOUTH_WEST;
3967 height = -height;
3968 top -= height;
3969 }
3970 break;
3971 case ACTION_SOUTH_WEST:
3972 if (aspectRatio) {
3973 if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
3974 renderable = false;
3975 break;
3976 }
3977 check(ACTION_WEST);
3978 width -= range.x;
3979 left += range.x;
3980 height = width / aspectRatio;
3981 } else {
3982 check(ACTION_SOUTH);
3983 check(ACTION_WEST);
3984 if (range.x <= 0) {
3985 if (left > minLeft) {
3986 width -= range.x;
3987 left += range.x;
3988 } else if (range.y >= 0 && bottom >= maxHeight) {
3989 renderable = false;
3990 }
3991 } else {
3992 width -= range.x;
3993 left += range.x;
3994 }
3995 if (range.y >= 0) {
3996 if (bottom < maxHeight) {
3997 height += range.y;
3998 }
3999 } else {
4000 height += range.y;
4001 }
4002 }
4003 if (width < 0 && height < 0) {
4004 action = ACTION_NORTH_EAST;
4005 height = -height;
4006 width = -width;
4007 top -= height;
4008 left -= width;
4009 } else if (width < 0) {
4010 action = ACTION_SOUTH_EAST;
4011 width = -width;
4012 left -= width;
4013 } else if (height < 0) {
4014 action = ACTION_NORTH_WEST;
4015 height = -height;
4016 top -= height;
4017 }
4018 break;
4019 case ACTION_SOUTH_EAST:
4020 if (aspectRatio) {
4021 if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
4022 renderable = false;
4023 break;
4024 }
4025 check(ACTION_EAST);
4026 width += range.x;
4027 height = width / aspectRatio;
4028 } else {
4029 check(ACTION_SOUTH);
4030 check(ACTION_EAST);
4031 if (range.x >= 0) {
4032 if (right < maxWidth) {
4033 width += range.x;
4034 } else if (range.y >= 0 && bottom >= maxHeight) {
4035 renderable = false;
4036 }
4037 } else {
4038 width += range.x;
4039 }
4040 if (range.y >= 0) {
4041 if (bottom < maxHeight) {
4042 height += range.y;
4043 }
4044 } else {
4045 height += range.y;
4046 }
4047 }
4048 if (width < 0 && height < 0) {
4049 action = ACTION_NORTH_WEST;
4050 height = -height;
4051 width = -width;
4052 top -= height;
4053 left -= width;
4054 } else if (width < 0) {
4055 action = ACTION_SOUTH_WEST;
4056 width = -width;
4057 left -= width;
4058 } else if (height < 0) {
4059 action = ACTION_NORTH_EAST;
4060 height = -height;
4061 top -= height;
4062 }
4063 break;
4064
4065 // Move canvas
4066 case ACTION_MOVE:
4067 this.move(range.x, range.y);
4068 renderable = false;
4069 break;
4070
4071 // Zoom canvas
4072 case ACTION_ZOOM:
4073 this.zoom(getMaxZoomRatio(pointers), event);
4074 renderable = false;
4075 break;
4076
4077 // Create crop box
4078 case ACTION_CROP:
4079 if (!range.x || !range.y) {
4080 renderable = false;
4081 break;
4082 }
4083 offset = getOffset(this.cropper);
4084 left = pointer.startX - offset.left;
4085 top = pointer.startY - offset.top;
4086 width = cropBoxData.minWidth;
4087 height = cropBoxData.minHeight;
4088 if (range.x > 0) {
4089 action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
4090 } else if (range.x < 0) {
4091 left -= width;
4092 action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
4093 }
4094 if (range.y < 0) {
4095 top -= height;
4096 }
4097
4098 // Show the crop box if is hidden
4099 if (!this.cropped) {
4100 removeClass(this.cropBox, CLASS_HIDDEN);
4101 this.cropped = true;
4102 if (this.limited) {
4103 this.limitCropBox(true, true);
4104 }
4105 }
4106 break;
4107 }
4108 if (renderable) {
4109 cropBoxData.width = width;
4110 cropBoxData.height = height;
4111 cropBoxData.left = left;
4112 cropBoxData.top = top;
4113 this.action = action;
4114 this.renderCropBox();
4115 }
4116
4117 // Override
4118 forEach(pointers, function (p) {
4119 p.startX = p.endX;
4120 p.startY = p.endY;
4121 });
4122 }
4123 };
4124
4125 var methods = {
4126 // Show the crop box manually
4127 crop: function crop() {
4128 if (this.ready && !this.cropped && !this.disabled) {
4129 this.cropped = true;
4130 this.limitCropBox(true, true);
4131 if (this.options.modal) {
4132 addClass(this.dragBox, CLASS_MODAL);
4133 }
4134 removeClass(this.cropBox, CLASS_HIDDEN);
4135 this.setCropBoxData(this.initialCropBoxData);
4136 }
4137 return this;
4138 },
4139 // Reset the image and crop box to their initial states
4140 reset: function reset() {
4141 if (this.ready && !this.disabled) {
4142 this.imageData = assign({}, this.initialImageData);
4143 this.canvasData = assign({}, this.initialCanvasData);
4144 this.cropBoxData = assign({}, this.initialCropBoxData);
4145 this.renderCanvas();
4146 if (this.cropped) {
4147 this.renderCropBox();
4148 }
4149 }
4150 return this;
4151 },
4152 // Clear the crop box
4153 clear: function clear() {
4154 if (this.cropped && !this.disabled) {
4155 assign(this.cropBoxData, {
4156 left: 0,
4157 top: 0,
4158 width: 0,
4159 height: 0
4160 });
4161 this.cropped = false;
4162 this.renderCropBox();
4163 this.limitCanvas(true, true);
4164
4165 // Render canvas after crop box rendered
4166 this.renderCanvas();
4167 removeClass(this.dragBox, CLASS_MODAL);
4168 addClass(this.cropBox, CLASS_HIDDEN);
4169 }
4170 return this;
4171 },
4172 /**
4173 * Replace the image's src and rebuild the cropper
4174 * @param {string} url - The new URL.
4175 * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.
4176 * @returns {Cropper} this
4177 */
4178 replace: function replace(url) {
4179 var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
4180 if (!this.disabled && url) {
4181 if (this.isImg) {
4182 this.element.src = url;
4183 }
4184 if (hasSameSize) {
4185 this.url = url;
4186 this.image.src = url;
4187 if (this.ready) {
4188 this.viewBoxImage.src = url;
4189 forEach(this.previews, function (element) {
4190 element.getElementsByTagName('img')[0].src = url;
4191 });
4192 }
4193 } else {
4194 if (this.isImg) {
4195 this.replaced = true;
4196 }
4197 this.options.data = null;
4198 this.uncreate();
4199 this.load(url);
4200 }
4201 }
4202 return this;
4203 },
4204 // Enable (unfreeze) the cropper
4205 enable: function enable() {
4206 if (this.ready && this.disabled) {
4207 this.disabled = false;
4208 removeClass(this.cropper, CLASS_DISABLED);
4209 }
4210 return this;
4211 },
4212 // Disable (freeze) the cropper
4213 disable: function disable() {
4214 if (this.ready && !this.disabled) {
4215 this.disabled = true;
4216 addClass(this.cropper, CLASS_DISABLED);
4217 }
4218 return this;
4219 },
4220 /**
4221 * Destroy the cropper and remove the instance from the image
4222 * @returns {Cropper} this
4223 */
4224 destroy: function destroy() {
4225 var element = this.element;
4226 if (!element[NAMESPACE]) {
4227 return this;
4228 }
4229 element[NAMESPACE] = undefined;
4230 if (this.isImg && this.replaced) {
4231 element.src = this.originalUrl;
4232 }
4233 this.uncreate();
4234 return this;
4235 },
4236 /**
4237 * Move the canvas with relative offsets
4238 * @param {number} offsetX - The relative offset distance on the x-axis.
4239 * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.
4240 * @returns {Cropper} this
4241 */
4242 move: function move(offsetX) {
4243 var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;
4244 var _this$canvasData = this.canvasData,
4245 left = _this$canvasData.left,
4246 top = _this$canvasData.top;
4247 return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
4248 },
4249 /**
4250 * Move the canvas to an absolute point
4251 * @param {number} x - The x-axis coordinate.
4252 * @param {number} [y=x] - The y-axis coordinate.
4253 * @returns {Cropper} this
4254 */
4255 moveTo: function moveTo(x) {
4256 var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
4257 var canvasData = this.canvasData;
4258 var changed = false;
4259 x = Number(x);
4260 y = Number(y);
4261 if (this.ready && !this.disabled && this.options.movable) {
4262 if (isNumber(x)) {
4263 canvasData.left = x;
4264 changed = true;
4265 }
4266 if (isNumber(y)) {
4267 canvasData.top = y;
4268 changed = true;
4269 }
4270 if (changed) {
4271 this.renderCanvas(true);
4272 }
4273 }
4274 return this;
4275 },
4276 /**
4277 * Zoom the canvas with a relative ratio
4278 * @param {number} ratio - The target ratio.
4279 * @param {Event} _originalEvent - The original event if any.
4280 * @returns {Cropper} this
4281 */
4282 zoom: function zoom(ratio, _originalEvent) {
4283 var canvasData = this.canvasData;
4284 ratio = Number(ratio);
4285 if (ratio < 0) {
4286 ratio = 1 / (1 - ratio);
4287 } else {
4288 ratio = 1 + ratio;
4289 }
4290 return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
4291 },
4292 /**
4293 * Zoom the canvas to an absolute ratio
4294 * @param {number} ratio - The target ratio.
4295 * @param {Object} pivot - The zoom pivot point coordinate.
4296 * @param {Event} _originalEvent - The original event if any.
4297 * @returns {Cropper} this
4298 */
4299 zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
4300 var options = this.options,
4301 canvasData = this.canvasData;
4302 var width = canvasData.width,
4303 height = canvasData.height,
4304 naturalWidth = canvasData.naturalWidth,
4305 naturalHeight = canvasData.naturalHeight;
4306 ratio = Number(ratio);
4307 if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
4308 var newWidth = naturalWidth * ratio;
4309 var newHeight = naturalHeight * ratio;
4310 if (dispatchEvent(this.element, EVENT_ZOOM, {
4311 ratio: ratio,
4312 oldRatio: width / naturalWidth,
4313 originalEvent: _originalEvent
4314 }) === false) {
4315 return this;
4316 }
4317 if (_originalEvent) {
4318 var pointers = this.pointers;
4319 var offset = getOffset(this.cropper);
4320 var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
4321 pageX: _originalEvent.pageX,
4322 pageY: _originalEvent.pageY
4323 };
4324
4325 // Zoom from the triggering point of the event
4326 canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
4327 canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
4328 } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
4329 canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);
4330 canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);
4331 } else {
4332 // Zoom from the center of the canvas
4333 canvasData.left -= (newWidth - width) / 2;
4334 canvasData.top -= (newHeight - height) / 2;
4335 }
4336 canvasData.width = newWidth;
4337 canvasData.height = newHeight;
4338 this.renderCanvas(true);
4339 }
4340 return this;
4341 },
4342 /**
4343 * Rotate the canvas with a relative degree
4344 * @param {number} degree - The rotate degree.
4345 * @returns {Cropper} this
4346 */
4347 rotate: function rotate(degree) {
4348 return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
4349 },
4350 /**
4351 * Rotate the canvas to an absolute degree
4352 * @param {number} degree - The rotate degree.
4353 * @returns {Cropper} this
4354 */
4355 rotateTo: function rotateTo(degree) {
4356 degree = Number(degree);
4357 if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
4358 this.imageData.rotate = degree % 360;
4359 this.renderCanvas(true, true);
4360 }
4361 return this;
4362 },
4363 /**
4364 * Scale the image on the x-axis.
4365 * @param {number} scaleX - The scale ratio on the x-axis.
4366 * @returns {Cropper} this
4367 */
4368 scaleX: function scaleX(_scaleX) {
4369 var scaleY = this.imageData.scaleY;
4370 return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
4371 },
4372 /**
4373 * Scale the image on the y-axis.
4374 * @param {number} scaleY - The scale ratio on the y-axis.
4375 * @returns {Cropper} this
4376 */
4377 scaleY: function scaleY(_scaleY) {
4378 var scaleX = this.imageData.scaleX;
4379 return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
4380 },
4381 /**
4382 * Scale the image
4383 * @param {number} scaleX - The scale ratio on the x-axis.
4384 * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
4385 * @returns {Cropper} this
4386 */
4387 scale: function scale(scaleX) {
4388 var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
4389 var imageData = this.imageData;
4390 var transformed = false;
4391 scaleX = Number(scaleX);
4392 scaleY = Number(scaleY);
4393 if (this.ready && !this.disabled && this.options.scalable) {
4394 if (isNumber(scaleX)) {
4395 imageData.scaleX = scaleX;
4396 transformed = true;
4397 }
4398 if (isNumber(scaleY)) {
4399 imageData.scaleY = scaleY;
4400 transformed = true;
4401 }
4402 if (transformed) {
4403 this.renderCanvas(true, true);
4404 }
4405 }
4406 return this;
4407 },
4408 /**
4409 * Get the cropped area position and size data (base on the original image)
4410 * @param {boolean} [rounded=false] - Indicate if round the data values or not.
4411 * @returns {Object} The result cropped data.
4412 */
4413 getData: function getData() {
4414 var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
4415 var options = this.options,
4416 imageData = this.imageData,
4417 canvasData = this.canvasData,
4418 cropBoxData = this.cropBoxData;
4419 var data;
4420 if (this.ready && this.cropped) {
4421 data = {
4422 x: cropBoxData.left - canvasData.left,
4423 y: cropBoxData.top - canvasData.top,
4424 width: cropBoxData.width,
4425 height: cropBoxData.height
4426 };
4427 var ratio = imageData.width / imageData.naturalWidth;
4428 forEach(data, function (n, i) {
4429 data[i] = n / ratio;
4430 });
4431 if (rounded) {
4432 // In case rounding off leads to extra 1px in right or bottom border
4433 // we should round the top-left corner and the dimension (#343).
4434 var bottom = Math.round(data.y + data.height);
4435 var right = Math.round(data.x + data.width);
4436 data.x = Math.round(data.x);
4437 data.y = Math.round(data.y);
4438 data.width = right - data.x;
4439 data.height = bottom - data.y;
4440 }
4441 } else {
4442 data = {
4443 x: 0,
4444 y: 0,
4445 width: 0,
4446 height: 0
4447 };
4448 }
4449 if (options.rotatable) {
4450 data.rotate = imageData.rotate || 0;
4451 }
4452 if (options.scalable) {
4453 data.scaleX = imageData.scaleX || 1;
4454 data.scaleY = imageData.scaleY || 1;
4455 }
4456 return data;
4457 },
4458 /**
4459 * Set the cropped area position and size with new data
4460 * @param {Object} data - The new data.
4461 * @returns {Cropper} this
4462 */
4463 setData: function setData(data) {
4464 var options = this.options,
4465 imageData = this.imageData,
4466 canvasData = this.canvasData;
4467 var cropBoxData = {};
4468 if (this.ready && !this.disabled && isPlainObject(data)) {
4469 var transformed = false;
4470 if (options.rotatable) {
4471 if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
4472 imageData.rotate = data.rotate;
4473 transformed = true;
4474 }
4475 }
4476 if (options.scalable) {
4477 if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
4478 imageData.scaleX = data.scaleX;
4479 transformed = true;
4480 }
4481 if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
4482 imageData.scaleY = data.scaleY;
4483 transformed = true;
4484 }
4485 }
4486 if (transformed) {
4487 this.renderCanvas(true, true);
4488 }
4489 var ratio = imageData.width / imageData.naturalWidth;
4490 if (isNumber(data.x)) {
4491 cropBoxData.left = data.x * ratio + canvasData.left;
4492 }
4493 if (isNumber(data.y)) {
4494 cropBoxData.top = data.y * ratio + canvasData.top;
4495 }
4496 if (isNumber(data.width)) {
4497 cropBoxData.width = data.width * ratio;
4498 }
4499 if (isNumber(data.height)) {
4500 cropBoxData.height = data.height * ratio;
4501 }
4502 this.setCropBoxData(cropBoxData);
4503 }
4504 return this;
4505 },
4506 /**
4507 * Get the container size data.
4508 * @returns {Object} The result container data.
4509 */
4510 getContainerData: function getContainerData() {
4511 return this.ready ? assign({}, this.containerData) : {};
4512 },
4513 /**
4514 * Get the image position and size data.
4515 * @returns {Object} The result image data.
4516 */
4517 getImageData: function getImageData() {
4518 return this.sized ? assign({}, this.imageData) : {};
4519 },
4520 /**
4521 * Get the canvas position and size data.
4522 * @returns {Object} The result canvas data.
4523 */
4524 getCanvasData: function getCanvasData() {
4525 var canvasData = this.canvasData;
4526 var data = {};
4527 if (this.ready) {
4528 forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
4529 data[n] = canvasData[n];
4530 });
4531 }
4532 return data;
4533 },
4534 /**
4535 * Set the canvas position and size with new data.
4536 * @param {Object} data - The new canvas data.
4537 * @returns {Cropper} this
4538 */
4539 setCanvasData: function setCanvasData(data) {
4540 var canvasData = this.canvasData;
4541 var aspectRatio = canvasData.aspectRatio;
4542 if (this.ready && !this.disabled && isPlainObject(data)) {
4543 if (isNumber(data.left)) {
4544 canvasData.left = data.left;
4545 }
4546 if (isNumber(data.top)) {
4547 canvasData.top = data.top;
4548 }
4549 if (isNumber(data.width)) {
4550 canvasData.width = data.width;
4551 canvasData.height = data.width / aspectRatio;
4552 } else if (isNumber(data.height)) {
4553 canvasData.height = data.height;
4554 canvasData.width = data.height * aspectRatio;
4555 }
4556 this.renderCanvas(true);
4557 }
4558 return this;
4559 },
4560 /**
4561 * Get the crop box position and size data.
4562 * @returns {Object} The result crop box data.
4563 */
4564 getCropBoxData: function getCropBoxData() {
4565 var cropBoxData = this.cropBoxData;
4566 var data;
4567 if (this.ready && this.cropped) {
4568 data = {
4569 left: cropBoxData.left,
4570 top: cropBoxData.top,
4571 width: cropBoxData.width,
4572 height: cropBoxData.height
4573 };
4574 }
4575 return data || {};
4576 },
4577 /**
4578 * Set the crop box position and size with new data.
4579 * @param {Object} data - The new crop box data.
4580 * @returns {Cropper} this
4581 */
4582 setCropBoxData: function setCropBoxData(data) {
4583 var cropBoxData = this.cropBoxData;
4584 var aspectRatio = this.options.aspectRatio;
4585 var widthChanged;
4586 var heightChanged;
4587 if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
4588 if (isNumber(data.left)) {
4589 cropBoxData.left = data.left;
4590 }
4591 if (isNumber(data.top)) {
4592 cropBoxData.top = data.top;
4593 }
4594 if (isNumber(data.width) && data.width !== cropBoxData.width) {
4595 widthChanged = true;
4596 cropBoxData.width = data.width;
4597 }
4598 if (isNumber(data.height) && data.height !== cropBoxData.height) {
4599 heightChanged = true;
4600 cropBoxData.height = data.height;
4601 }
4602 if (aspectRatio) {
4603 if (widthChanged) {
4604 cropBoxData.height = cropBoxData.width / aspectRatio;
4605 } else if (heightChanged) {
4606 cropBoxData.width = cropBoxData.height * aspectRatio;
4607 }
4608 }
4609 this.renderCropBox();
4610 }
4611 return this;
4612 },
4613 /**
4614 * Get a canvas drawn the cropped image.
4615 * @param {Object} [options={}] - The config options.
4616 * @returns {HTMLCanvasElement} - The result canvas.
4617 */
4618 getCroppedCanvas: function getCroppedCanvas() {
4619 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
4620 if (!this.ready || !window.HTMLCanvasElement) {
4621 return null;
4622 }
4623 var canvasData = this.canvasData;
4624 var source = getSourceCanvas(this.image, this.imageData, canvasData, options);
4625
4626 // Returns the source canvas if it is not cropped.
4627 if (!this.cropped) {
4628 return source;
4629 }
4630 var _this$getData = this.getData(options.rounded),
4631 initialX = _this$getData.x,
4632 initialY = _this$getData.y,
4633 initialWidth = _this$getData.width,
4634 initialHeight = _this$getData.height;
4635 var ratio = source.width / Math.floor(canvasData.naturalWidth);
4636 if (ratio !== 1) {
4637 initialX *= ratio;
4638 initialY *= ratio;
4639 initialWidth *= ratio;
4640 initialHeight *= ratio;
4641 }
4642 var aspectRatio = initialWidth / initialHeight;
4643 var maxSizes = getAdjustedSizes({
4644 aspectRatio: aspectRatio,
4645 width: options.maxWidth || Infinity,
4646 height: options.maxHeight || Infinity
4647 });
4648 var minSizes = getAdjustedSizes({
4649 aspectRatio: aspectRatio,
4650 width: options.minWidth || 0,
4651 height: options.minHeight || 0
4652 }, 'cover');
4653 var _getAdjustedSizes = getAdjustedSizes({
4654 aspectRatio: aspectRatio,
4655 width: options.width || (ratio !== 1 ? source.width : initialWidth),
4656 height: options.height || (ratio !== 1 ? source.height : initialHeight)
4657 }),
4658 width = _getAdjustedSizes.width,
4659 height = _getAdjustedSizes.height;
4660 width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
4661 height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
4662 var canvas = document.createElement('canvas');
4663 var context = canvas.getContext('2d');
4664 canvas.width = normalizeDecimalNumber(width);
4665 canvas.height = normalizeDecimalNumber(height);
4666 context.fillStyle = options.fillColor || 'transparent';
4667 context.fillRect(0, 0, width, height);
4668 var _options$imageSmoothi = options.imageSmoothingEnabled,
4669 imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
4670 imageSmoothingQuality = options.imageSmoothingQuality;
4671 context.imageSmoothingEnabled = imageSmoothingEnabled;
4672 if (imageSmoothingQuality) {
4673 context.imageSmoothingQuality = imageSmoothingQuality;
4674 }
4675
4676 // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
4677 var sourceWidth = source.width;
4678 var sourceHeight = source.height;
4679
4680 // Source canvas parameters
4681 var srcX = initialX;
4682 var srcY = initialY;
4683 var srcWidth;
4684 var srcHeight;
4685
4686 // Destination canvas parameters
4687 var dstX;
4688 var dstY;
4689 var dstWidth;
4690 var dstHeight;
4691 if (srcX <= -initialWidth || srcX > sourceWidth) {
4692 srcX = 0;
4693 srcWidth = 0;
4694 dstX = 0;
4695 dstWidth = 0;
4696 } else if (srcX <= 0) {
4697 dstX = -srcX;
4698 srcX = 0;
4699 srcWidth = Math.min(sourceWidth, initialWidth + srcX);
4700 dstWidth = srcWidth;
4701 } else if (srcX <= sourceWidth) {
4702 dstX = 0;
4703 srcWidth = Math.min(initialWidth, sourceWidth - srcX);
4704 dstWidth = srcWidth;
4705 }
4706 if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
4707 srcY = 0;
4708 srcHeight = 0;
4709 dstY = 0;
4710 dstHeight = 0;
4711 } else if (srcY <= 0) {
4712 dstY = -srcY;
4713 srcY = 0;
4714 srcHeight = Math.min(sourceHeight, initialHeight + srcY);
4715 dstHeight = srcHeight;
4716 } else if (srcY <= sourceHeight) {
4717 dstY = 0;
4718 srcHeight = Math.min(initialHeight, sourceHeight - srcY);
4719 dstHeight = srcHeight;
4720 }
4721 var params = [srcX, srcY, srcWidth, srcHeight];
4722
4723 // Avoid "IndexSizeError"
4724 if (dstWidth > 0 && dstHeight > 0) {
4725 var scale = width / initialWidth;
4726 params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
4727 }
4728
4729 // All the numerical parameters should be integer for `drawImage`
4730 // https://github.com/fengyuanchen/cropper/issues/476
4731 context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {
4732 return Math.floor(normalizeDecimalNumber(param));
4733 }))));
4734 return canvas;
4735 },
4736 /**
4737 * Change the aspect ratio of the crop box.
4738 * @param {number} aspectRatio - The new aspect ratio.
4739 * @returns {Cropper} this
4740 */
4741 setAspectRatio: function setAspectRatio(aspectRatio) {
4742 var options = this.options;
4743 if (!this.disabled && !isUndefined(aspectRatio)) {
4744 // 0 -> NaN
4745 options.aspectRatio = Math.max(0, aspectRatio) || NaN;
4746 if (this.ready) {
4747 this.initCropBox();
4748 if (this.cropped) {
4749 this.renderCropBox();
4750 }
4751 }
4752 }
4753 return this;
4754 },
4755 /**
4756 * Change the drag mode.
4757 * @param {string} mode - The new drag mode.
4758 * @returns {Cropper} this
4759 */
4760 setDragMode: function setDragMode(mode) {
4761 var options = this.options,
4762 dragBox = this.dragBox,
4763 face = this.face;
4764 if (this.ready && !this.disabled) {
4765 var croppable = mode === DRAG_MODE_CROP;
4766 var movable = options.movable && mode === DRAG_MODE_MOVE;
4767 mode = croppable || movable ? mode : DRAG_MODE_NONE;
4768 options.dragMode = mode;
4769 setData(dragBox, DATA_ACTION, mode);
4770 toggleClass(dragBox, CLASS_CROP, croppable);
4771 toggleClass(dragBox, CLASS_MOVE, movable);
4772 if (!options.cropBoxMovable) {
4773 // Sync drag mode to crop box when it is not movable
4774 setData(face, DATA_ACTION, mode);
4775 toggleClass(face, CLASS_CROP, croppable);
4776 toggleClass(face, CLASS_MOVE, movable);
4777 }
4778 }
4779 return this;
4780 }
4781 };
4782
4783 var AnotherCropper = WINDOW.Cropper;
4784 var Cropper = /*#__PURE__*/function () {
4785 /**
4786 * Create a new Cropper.
4787 * @param {Element} element - The target element for cropping.
4788 * @param {Object} [options={}] - The configuration options.
4789 */
4790 function Cropper(element) {
4791 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
4792 _classCallCheck(this, Cropper);
4793 if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
4794 throw new Error('The first argument is required and must be an <img> or <canvas> element.');
4795 }
4796 this.element = element;
4797 this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
4798 this.cropped = false;
4799 this.disabled = false;
4800 this.pointers = {};
4801 this.ready = false;
4802 this.reloading = false;
4803 this.replaced = false;
4804 this.sized = false;
4805 this.sizing = false;
4806 this.init();
4807 }
4808 return _createClass(Cropper, [{
4809 key: "init",
4810 value: function init() {
4811 var element = this.element;
4812 var tagName = element.tagName.toLowerCase();
4813 var url;
4814 if (element[NAMESPACE]) {
4815 return;
4816 }
4817 element[NAMESPACE] = this;
4818 if (tagName === 'img') {
4819 this.isImg = true;
4820
4821 // e.g.: "img/picture.jpg"
4822 url = element.getAttribute('src') || '';
4823 this.originalUrl = url;
4824
4825 // Stop when it's a blank image
4826 if (!url) {
4827 return;
4828 }
4829
4830 // e.g.: "https://example.com/img/picture.jpg"
4831 url = element.src;
4832 } else if (tagName === 'canvas' && window.HTMLCanvasElement) {
4833 url = element.toDataURL();
4834 }
4835 this.load(url);
4836 }
4837 }, {
4838 key: "load",
4839 value: function load(url) {
4840 var _this = this;
4841 if (!url) {
4842 return;
4843 }
4844 this.url = url;
4845 this.imageData = {};
4846 var element = this.element,
4847 options = this.options;
4848 if (!options.rotatable && !options.scalable) {
4849 options.checkOrientation = false;
4850 }
4851
4852 // Only IE10+ supports Typed Arrays
4853 if (!options.checkOrientation || !window.ArrayBuffer) {
4854 this.clone();
4855 return;
4856 }
4857
4858 // Detect the mime type of the image directly if it is a Data URL
4859 if (REGEXP_DATA_URL.test(url)) {
4860 // Read ArrayBuffer from Data URL of JPEG images directly for better performance
4861 if (REGEXP_DATA_URL_JPEG.test(url)) {
4862 this.read(dataURLToArrayBuffer(url));
4863 } else {
4864 // Only a JPEG image may contains Exif Orientation information,
4865 // the rest types of Data URLs are not necessary to check orientation at all.
4866 this.clone();
4867 }
4868 return;
4869 }
4870
4871 // 1. Detect the mime type of the image by a XMLHttpRequest.
4872 // 2. Load the image as ArrayBuffer for reading orientation if its a JPEG image.
4873 var xhr = new XMLHttpRequest();
4874 var clone = this.clone.bind(this);
4875 this.reloading = true;
4876 this.xhr = xhr;
4877
4878 // 1. Cross origin requests are only supported for protocol schemes:
4879 // http, https, data, chrome, chrome-extension.
4880 // 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy
4881 // in some browsers as IE11 and Safari.
4882 xhr.onabort = clone;
4883 xhr.onerror = clone;
4884 xhr.ontimeout = clone;
4885 xhr.onprogress = function () {
4886 // Abort the request directly if it not a JPEG image for better performance
4887 if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {
4888 xhr.abort();
4889 }
4890 };
4891 xhr.onload = function () {
4892 _this.read(xhr.response);
4893 };
4894 xhr.onloadend = function () {
4895 _this.reloading = false;
4896 _this.xhr = null;
4897 };
4898
4899 // Bust cache when there is a "crossOrigin" property to avoid browser cache error
4900 if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
4901 url = addTimestamp(url);
4902 }
4903
4904 // The third parameter is required for avoiding side-effect (#682)
4905 xhr.open('GET', url, true);
4906 xhr.responseType = 'arraybuffer';
4907 xhr.withCredentials = element.crossOrigin === 'use-credentials';
4908 xhr.send();
4909 }
4910 }, {
4911 key: "read",
4912 value: function read(arrayBuffer) {
4913 var options = this.options,
4914 imageData = this.imageData;
4915
4916 // Reset the orientation value to its default value 1
4917 // as some iOS browsers will render image with its orientation
4918 var orientation = resetAndGetOrientation(arrayBuffer);
4919 var rotate = 0;
4920 var scaleX = 1;
4921 var scaleY = 1;
4922 if (orientation > 1) {
4923 // Generate a new URL which has the default orientation value
4924 this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);
4925 var _parseOrientation = parseOrientation(orientation);
4926 rotate = _parseOrientation.rotate;
4927 scaleX = _parseOrientation.scaleX;
4928 scaleY = _parseOrientation.scaleY;
4929 }
4930 if (options.rotatable) {
4931 imageData.rotate = rotate;
4932 }
4933 if (options.scalable) {
4934 imageData.scaleX = scaleX;
4935 imageData.scaleY = scaleY;
4936 }
4937 this.clone();
4938 }
4939 }, {
4940 key: "clone",
4941 value: function clone() {
4942 var element = this.element,
4943 url = this.url;
4944 var crossOrigin = element.crossOrigin;
4945 var crossOriginUrl = url;
4946 if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
4947 if (!crossOrigin) {
4948 crossOrigin = 'anonymous';
4949 }
4950
4951 // Bust cache when there is not a "crossOrigin" property (#519)
4952 crossOriginUrl = addTimestamp(url);
4953 }
4954 this.crossOrigin = crossOrigin;
4955 this.crossOriginUrl = crossOriginUrl;
4956 var image = document.createElement('img');
4957 if (crossOrigin) {
4958 image.crossOrigin = crossOrigin;
4959 }
4960 image.src = crossOriginUrl || url;
4961 image.alt = element.alt || 'The image to crop';
4962 this.image = image;
4963 image.onload = this.start.bind(this);
4964 image.onerror = this.stop.bind(this);
4965 addClass(image, CLASS_HIDE);
4966 element.parentNode.insertBefore(image, element.nextSibling);
4967 }
4968 }, {
4969 key: "start",
4970 value: function start() {
4971 var _this2 = this;
4972 var image = this.image;
4973 image.onload = null;
4974 image.onerror = null;
4975 this.sizing = true;
4976
4977 // Match all browsers that use WebKit as the layout engine in iOS devices,
4978 // such as Safari for iOS, Chrome for iOS, and in-app browsers.
4979 var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);
4980 var done = function done(naturalWidth, naturalHeight) {
4981 assign(_this2.imageData, {
4982 naturalWidth: naturalWidth,
4983 naturalHeight: naturalHeight,
4984 aspectRatio: naturalWidth / naturalHeight
4985 });
4986 _this2.initialImageData = assign({}, _this2.imageData);
4987 _this2.sizing = false;
4988 _this2.sized = true;
4989 _this2.build();
4990 };
4991
4992 // Most modern browsers (excepts iOS WebKit)
4993 if (image.naturalWidth && !isIOSWebKit) {
4994 done(image.naturalWidth, image.naturalHeight);
4995 return;
4996 }
4997 var sizingImage = document.createElement('img');
4998 var body = document.body || document.documentElement;
4999 this.sizingImage = sizingImage;
5000 sizingImage.onload = function () {
5001 done(sizingImage.width, sizingImage.height);
5002 if (!isIOSWebKit) {
5003 body.removeChild(sizingImage);
5004 }
5005 };
5006 sizingImage.src = image.src;
5007
5008 // iOS WebKit will convert the image automatically
5009 // with its orientation once append it into DOM (#279)
5010 if (!isIOSWebKit) {
5011 sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
5012 body.appendChild(sizingImage);
5013 }
5014 }
5015 }, {
5016 key: "stop",
5017 value: function stop() {
5018 var image = this.image;
5019 image.onload = null;
5020 image.onerror = null;
5021 image.parentNode.removeChild(image);
5022 this.image = null;
5023 }
5024 }, {
5025 key: "build",
5026 value: function build() {
5027 if (!this.sized || this.ready) {
5028 return;
5029 }
5030 var element = this.element,
5031 options = this.options,
5032 image = this.image;
5033
5034 // Create cropper elements
5035 var container = element.parentNode;
5036 var template = document.createElement('div');
5037 template.innerHTML = TEMPLATE;
5038 var cropper = template.querySelector(".".concat(NAMESPACE, "-container"));
5039 var canvas = cropper.querySelector(".".concat(NAMESPACE, "-canvas"));
5040 var dragBox = cropper.querySelector(".".concat(NAMESPACE, "-drag-box"));
5041 var cropBox = cropper.querySelector(".".concat(NAMESPACE, "-crop-box"));
5042 var face = cropBox.querySelector(".".concat(NAMESPACE, "-face"));
5043 this.container = container;
5044 this.cropper = cropper;
5045 this.canvas = canvas;
5046 this.dragBox = dragBox;
5047 this.cropBox = cropBox;
5048 this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));
5049 this.face = face;
5050 canvas.appendChild(image);
5051
5052 // Hide the original image
5053 addClass(element, CLASS_HIDDEN);
5054
5055 // Inserts the cropper after to the current image
5056 container.insertBefore(cropper, element.nextSibling);
5057
5058 // Show the hidden image
5059 removeClass(image, CLASS_HIDE);
5060 this.initPreview();
5061 this.bind();
5062 options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;
5063 options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
5064 options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
5065 addClass(cropBox, CLASS_HIDDEN);
5066 if (!options.guides) {
5067 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);
5068 }
5069 if (!options.center) {
5070 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);
5071 }
5072 if (options.background) {
5073 addClass(cropper, "".concat(NAMESPACE, "-bg"));
5074 }
5075 if (!options.highlight) {
5076 addClass(face, CLASS_INVISIBLE);
5077 }
5078 if (options.cropBoxMovable) {
5079 addClass(face, CLASS_MOVE);
5080 setData(face, DATA_ACTION, ACTION_ALL);
5081 }
5082 if (!options.cropBoxResizable) {
5083 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);
5084 addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);
5085 }
5086 this.render();
5087 this.ready = true;
5088 this.setDragMode(options.dragMode);
5089 if (options.autoCrop) {
5090 this.crop();
5091 }
5092 this.setData(options.data);
5093 if (isFunction(options.ready)) {
5094 addListener(element, EVENT_READY, options.ready, {
5095 once: true
5096 });
5097 }
5098 dispatchEvent(element, EVENT_READY);
5099 }
5100 }, {
5101 key: "unbuild",
5102 value: function unbuild() {
5103 if (!this.ready) {
5104 return;
5105 }
5106 this.ready = false;
5107 this.unbind();
5108 this.resetPreview();
5109 var parentNode = this.cropper.parentNode;
5110 if (parentNode) {
5111 parentNode.removeChild(this.cropper);
5112 }
5113 removeClass(this.element, CLASS_HIDDEN);
5114 }
5115 }, {
5116 key: "uncreate",
5117 value: function uncreate() {
5118 if (this.ready) {
5119 this.unbuild();
5120 this.ready = false;
5121 this.cropped = false;
5122 } else if (this.sizing) {
5123 this.sizingImage.onload = null;
5124 this.sizing = false;
5125 this.sized = false;
5126 } else if (this.reloading) {
5127 this.xhr.onabort = null;
5128 this.xhr.abort();
5129 } else if (this.image) {
5130 this.stop();
5131 }
5132 }
5133
5134 /**
5135 * Get the no conflict cropper class.
5136 * @returns {Cropper} The cropper class.
5137 */
5138 }], [{
5139 key: "noConflict",
5140 value: function noConflict() {
5141 window.Cropper = AnotherCropper;
5142 return Cropper;
5143 }
5144
5145 /**
5146 * Change the default options.
5147 * @param {Object} options - The new default options.
5148 */
5149 }, {
5150 key: "setDefaults",
5151 value: function setDefaults(options) {
5152 assign(DEFAULTS, isPlainObject(options) && options);
5153 }
5154 }]);
5155 }();
5156 assign(Cropper.prototype, render, preview, events, handlers, change, methods);
5157
5158 return Cropper;
5159
5160 }));
5161
5162
5163 /***/ },
5164
5165 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/cropperjs/dist/cropper.css"
5166 /*!***************************************************************************************!*\
5167 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/cropperjs/dist/cropper.css ***!
5168 \***************************************************************************************/
5169 (module, __webpack_exports__, __webpack_require__) {
5170
5171 "use strict";
5172 __webpack_require__.r(__webpack_exports__);
5173 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5174 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5175 /* harmony export */ });
5176 /* 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");
5177 /* 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__);
5178 /* 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");
5179 /* 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__);
5180 /* harmony import */ var _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../css-loader/dist/runtime/getUrl.js */ "./node_modules/css-loader/dist/runtime/getUrl.js");
5181 /* harmony import */ var _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__);
5182 // Imports
5183
5184
5185
5186 var ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ __webpack_require__(/*! data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC */ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"), __webpack_require__.b);
5187 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()));
5188 var ___CSS_LOADER_URL_REPLACEMENT_0___ = _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_0___);
5189 // Module
5190 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
5191 * Cropper.js v1.6.2
5192 * https://fengyuanchen.github.io/cropperjs
5193 *
5194 * Copyright 2015-present Chen Fengyuan
5195 * Released under the MIT license
5196 *
5197 * Date: 2024-04-21T07:43:02.731Z
5198 */
5199
5200 .cropper-container {
5201 direction: ltr;
5202 font-size: 0;
5203 line-height: 0;
5204 position: relative;
5205 -ms-touch-action: none;
5206 touch-action: none;
5207 -webkit-touch-callout: none;
5208 -webkit-user-select: none;
5209 -moz-user-select: none;
5210 -ms-user-select: none;
5211 user-select: none;
5212 }
5213
5214 .cropper-container img {
5215 backface-visibility: hidden;
5216 display: block;
5217 height: 100%;
5218 image-orientation: 0deg;
5219 max-height: none !important;
5220 max-width: none !important;
5221 min-height: 0 !important;
5222 min-width: 0 !important;
5223 width: 100%;
5224 }
5225
5226 .cropper-wrap-box,
5227 .cropper-canvas,
5228 .cropper-drag-box,
5229 .cropper-crop-box,
5230 .cropper-modal {
5231 bottom: 0;
5232 left: 0;
5233 position: absolute;
5234 right: 0;
5235 top: 0;
5236 }
5237
5238 .cropper-wrap-box,
5239 .cropper-canvas {
5240 overflow: hidden;
5241 }
5242
5243 .cropper-drag-box {
5244 background-color: #fff;
5245 opacity: 0;
5246 }
5247
5248 .cropper-modal {
5249 background-color: #000;
5250 opacity: 0.5;
5251 }
5252
5253 .cropper-view-box {
5254 display: block;
5255 height: 100%;
5256 outline: 1px solid #39f;
5257 outline-color: rgba(51, 153, 255, 0.75);
5258 overflow: hidden;
5259 width: 100%;
5260 }
5261
5262 .cropper-dashed {
5263 border: 0 dashed #eee;
5264 display: block;
5265 opacity: 0.5;
5266 position: absolute;
5267 }
5268
5269 .cropper-dashed.dashed-h {
5270 border-bottom-width: 1px;
5271 border-top-width: 1px;
5272 height: calc(100% / 3);
5273 left: 0;
5274 top: calc(100% / 3);
5275 width: 100%;
5276 }
5277
5278 .cropper-dashed.dashed-v {
5279 border-left-width: 1px;
5280 border-right-width: 1px;
5281 height: 100%;
5282 left: calc(100% / 3);
5283 top: 0;
5284 width: calc(100% / 3);
5285 }
5286
5287 .cropper-center {
5288 display: block;
5289 height: 0;
5290 left: 50%;
5291 opacity: 0.75;
5292 position: absolute;
5293 top: 50%;
5294 width: 0;
5295 }
5296
5297 .cropper-center::before,
5298 .cropper-center::after {
5299 background-color: #eee;
5300 content: ' ';
5301 display: block;
5302 position: absolute;
5303 }
5304
5305 .cropper-center::before {
5306 height: 1px;
5307 left: -3px;
5308 top: 0;
5309 width: 7px;
5310 }
5311
5312 .cropper-center::after {
5313 height: 7px;
5314 left: 0;
5315 top: -3px;
5316 width: 1px;
5317 }
5318
5319 .cropper-face,
5320 .cropper-line,
5321 .cropper-point {
5322 display: block;
5323 height: 100%;
5324 opacity: 0.1;
5325 position: absolute;
5326 width: 100%;
5327 }
5328
5329 .cropper-face {
5330 background-color: #fff;
5331 left: 0;
5332 top: 0;
5333 }
5334
5335 .cropper-line {
5336 background-color: #39f;
5337 }
5338
5339 .cropper-line.line-e {
5340 cursor: ew-resize;
5341 right: -3px;
5342 top: 0;
5343 width: 5px;
5344 }
5345
5346 .cropper-line.line-n {
5347 cursor: ns-resize;
5348 height: 5px;
5349 left: 0;
5350 top: -3px;
5351 }
5352
5353 .cropper-line.line-w {
5354 cursor: ew-resize;
5355 left: -3px;
5356 top: 0;
5357 width: 5px;
5358 }
5359
5360 .cropper-line.line-s {
5361 bottom: -3px;
5362 cursor: ns-resize;
5363 height: 5px;
5364 left: 0;
5365 }
5366
5367 .cropper-point {
5368 background-color: #39f;
5369 height: 5px;
5370 opacity: 0.75;
5371 width: 5px;
5372 }
5373
5374 .cropper-point.point-e {
5375 cursor: ew-resize;
5376 margin-top: -3px;
5377 right: -3px;
5378 top: 50%;
5379 }
5380
5381 .cropper-point.point-n {
5382 cursor: ns-resize;
5383 left: 50%;
5384 margin-left: -3px;
5385 top: -3px;
5386 }
5387
5388 .cropper-point.point-w {
5389 cursor: ew-resize;
5390 left: -3px;
5391 margin-top: -3px;
5392 top: 50%;
5393 }
5394
5395 .cropper-point.point-s {
5396 bottom: -3px;
5397 cursor: s-resize;
5398 left: 50%;
5399 margin-left: -3px;
5400 }
5401
5402 .cropper-point.point-ne {
5403 cursor: nesw-resize;
5404 right: -3px;
5405 top: -3px;
5406 }
5407
5408 .cropper-point.point-nw {
5409 cursor: nwse-resize;
5410 left: -3px;
5411 top: -3px;
5412 }
5413
5414 .cropper-point.point-sw {
5415 bottom: -3px;
5416 cursor: nesw-resize;
5417 left: -3px;
5418 }
5419
5420 .cropper-point.point-se {
5421 bottom: -3px;
5422 cursor: nwse-resize;
5423 height: 20px;
5424 opacity: 1;
5425 right: -3px;
5426 width: 20px;
5427 }
5428
5429 @media (min-width: 768px) {
5430
5431 .cropper-point.point-se {
5432 height: 15px;
5433 width: 15px;
5434 }
5435 }
5436
5437 @media (min-width: 992px) {
5438
5439 .cropper-point.point-se {
5440 height: 10px;
5441 width: 10px;
5442 }
5443 }
5444
5445 @media (min-width: 1200px) {
5446
5447 .cropper-point.point-se {
5448 height: 5px;
5449 opacity: 0.75;
5450 width: 5px;
5451 }
5452 }
5453
5454 .cropper-point.point-se::before {
5455 background-color: #39f;
5456 bottom: -50%;
5457 content: ' ';
5458 display: block;
5459 height: 200%;
5460 opacity: 0;
5461 position: absolute;
5462 right: -50%;
5463 width: 200%;
5464 }
5465
5466 .cropper-invisible {
5467 opacity: 0;
5468 }
5469
5470 .cropper-bg {
5471 background-image: url(${___CSS_LOADER_URL_REPLACEMENT_0___});
5472 }
5473
5474 .cropper-hide {
5475 display: block;
5476 height: 0;
5477 position: absolute;
5478 width: 0;
5479 }
5480
5481 .cropper-hidden {
5482 display: none !important;
5483 }
5484
5485 .cropper-move {
5486 cursor: move;
5487 }
5488
5489 .cropper-crop {
5490 cursor: crosshair;
5491 }
5492
5493 .cropper-disabled .cropper-drag-box,
5494 .cropper-disabled .cropper-face,
5495 .cropper-disabled .cropper-line,
5496 .cropper-disabled .cropper-point {
5497 cursor: not-allowed;
5498 }
5499 `, "",{"version":3,"sources":["webpack://./node_modules/cropperjs/dist/cropper.css"],"names":[],"mappings":"AAAA;;;;;;;;EAQE;;AAEF;EACE,cAAc;EACd,YAAY;EACZ,cAAc;EACd,kBAAkB;EAClB,sBAAsB;MAClB,kBAAkB;EACtB,2BAA2B;EAC3B,yBAAyB;KACtB,sBAAsB;MACrB,qBAAqB;UACjB,iBAAiB;AAC3B;;AAEA;IACI,2BAA2B;IAC3B,cAAc;IACd,YAAY;IACZ,uBAAuB;IACvB,2BAA2B;IAC3B,0BAA0B;IAC1B,wBAAwB;IACxB,uBAAuB;IACvB,WAAW;EACb;;AAEF;;;;;EAKE,SAAS;EACT,OAAO;EACP,kBAAkB;EAClB,QAAQ;EACR,MAAM;AACR;;AAEA;;EAEE,gBAAgB;AAClB;;AAEA;EACE,sBAAsB;EACtB,UAAU;AACZ;;AAEA;EACE,sBAAsB;EACtB,YAAY;AACd;;AAEA;EACE,cAAc;EACd,YAAY;EACZ,uBAAuB;EACvB,uCAAuC;EACvC,gBAAgB;EAChB,WAAW;AACb;;AAEA;EACE,qBAAqB;EACrB,cAAc;EACd,YAAY;EACZ,kBAAkB;AACpB;;AAEA;IACI,wBAAwB;IACxB,qBAAqB;IACrB,sBAAsB;IACtB,OAAO;IACP,mBAAmB;IACnB,WAAW;EACb;;AAEF;IACI,sBAAsB;IACtB,uBAAuB;IACvB,YAAY;IACZ,oBAAoB;IACpB,MAAM;IACN,qBAAqB;EACvB;;AAEF;EACE,cAAc;EACd,SAAS;EACT,SAAS;EACT,aAAa;EACb,kBAAkB;EAClB,QAAQ;EACR,QAAQ;AACV;;AAEA;;IAEI,sBAAsB;IACtB,YAAY;IACZ,cAAc;IACd,kBAAkB;EACpB;;AAEF;IACI,WAAW;IACX,UAAU;IACV,MAAM;IACN,UAAU;EACZ;;AAEF;IACI,WAAW;IACX,OAAO;IACP,SAAS;IACT,UAAU;EACZ;;AAEF;;;EAGE,cAAc;EACd,YAAY;EACZ,YAAY;EACZ,kBAAkB;EAClB,WAAW;AACb;;AAEA;EACE,sBAAsB;EACtB,OAAO;EACP,MAAM;AACR;;AAEA;EACE,sBAAsB;AACxB;;AAEA;IACI,iBAAiB;IACjB,WAAW;IACX,MAAM;IACN,UAAU;EACZ;;AAEF;IACI,iBAAiB;IACjB,WAAW;IACX,OAAO;IACP,SAAS;EACX;;AAEF;IACI,iBAAiB;IACjB,UAAU;IACV,MAAM;IACN,UAAU;EACZ;;AAEF;IACI,YAAY;IACZ,iBAAiB;IACjB,WAAW;IACX,OAAO;EACT;;AAEF;EACE,sBAAsB;EACtB,WAAW;EACX,aAAa;EACb,UAAU;AACZ;;AAEA;IACI,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,QAAQ;EACV;;AAEF;IACI,iBAAiB;IACjB,SAAS;IACT,iBAAiB;IACjB,SAAS;EACX;;AAEF;IACI,iBAAiB;IACjB,UAAU;IACV,gBAAgB;IAChB,QAAQ;EACV;;AAEF;IACI,YAAY;IACZ,gBAAgB;IAChB,SAAS;IACT,iBAAiB;EACnB;;AAEF;IACI,mBAAmB;IACnB,WAAW;IACX,SAAS;EACX;;AAEF;IACI,mBAAmB;IACnB,UAAU;IACV,SAAS;EACX;;AAEF;IACI,YAAY;IACZ,mBAAmB;IACnB,UAAU;EACZ;;AAEF;IACI,YAAY;IACZ,mBAAmB;IACnB,YAAY;IACZ,UAAU;IACV,WAAW;IACX,WAAW;EACb;;AAEF;;AAEA;MACM,YAAY;MACZ,WAAW;EACf;IACE;;AAEJ;;AAEA;MACM,YAAY;MACZ,WAAW;EACf;IACE;;AAEJ;;AAEA;MACM,WAAW;MACX,aAAa;MACb,UAAU;EACd;IACE;;AAEJ;IACI,sBAAsB;IACtB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,YAAY;IACZ,UAAU;IACV,kBAAkB;IAClB,WAAW;IACX,WAAW;EACb;;AAEF;EACE,UAAU;AACZ;;AAEA;EACE,yDAA+Q;AACjR;;AAEA;EACE,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;AACV;;AAEA;EACE,wBAAwB;AAC1B;;AAEA;EACE,YAAY;AACd;;AAEA;EACE,iBAAiB;AACnB;;AAEA;;;;EAIE,mBAAmB;AACrB","sourcesContent":["/*!\n * Cropper.js v1.6.2\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2024-04-21T07:43:02.731Z\n */\n\n.cropper-container {\n direction: ltr;\n font-size: 0;\n line-height: 0;\n position: relative;\n -ms-touch-action: none;\n touch-action: none;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.cropper-container img {\n backface-visibility: hidden;\n display: block;\n height: 100%;\n image-orientation: 0deg;\n max-height: none !important;\n max-width: none !important;\n min-height: 0 !important;\n min-width: 0 !important;\n width: 100%;\n }\n\n.cropper-wrap-box,\n.cropper-canvas,\n.cropper-drag-box,\n.cropper-crop-box,\n.cropper-modal {\n bottom: 0;\n left: 0;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.cropper-wrap-box,\n.cropper-canvas {\n overflow: hidden;\n}\n\n.cropper-drag-box {\n background-color: #fff;\n opacity: 0;\n}\n\n.cropper-modal {\n background-color: #000;\n opacity: 0.5;\n}\n\n.cropper-view-box {\n display: block;\n height: 100%;\n outline: 1px solid #39f;\n outline-color: rgba(51, 153, 255, 0.75);\n overflow: hidden;\n width: 100%;\n}\n\n.cropper-dashed {\n border: 0 dashed #eee;\n display: block;\n opacity: 0.5;\n position: absolute;\n}\n\n.cropper-dashed.dashed-h {\n border-bottom-width: 1px;\n border-top-width: 1px;\n height: calc(100% / 3);\n left: 0;\n top: calc(100% / 3);\n width: 100%;\n }\n\n.cropper-dashed.dashed-v {\n border-left-width: 1px;\n border-right-width: 1px;\n height: 100%;\n left: calc(100% / 3);\n top: 0;\n width: calc(100% / 3);\n }\n\n.cropper-center {\n display: block;\n height: 0;\n left: 50%;\n opacity: 0.75;\n position: absolute;\n top: 50%;\n width: 0;\n}\n\n.cropper-center::before,\n .cropper-center::after {\n background-color: #eee;\n content: ' ';\n display: block;\n position: absolute;\n }\n\n.cropper-center::before {\n height: 1px;\n left: -3px;\n top: 0;\n width: 7px;\n }\n\n.cropper-center::after {\n height: 7px;\n left: 0;\n top: -3px;\n width: 1px;\n }\n\n.cropper-face,\n.cropper-line,\n.cropper-point {\n display: block;\n height: 100%;\n opacity: 0.1;\n position: absolute;\n width: 100%;\n}\n\n.cropper-face {\n background-color: #fff;\n left: 0;\n top: 0;\n}\n\n.cropper-line {\n background-color: #39f;\n}\n\n.cropper-line.line-e {\n cursor: ew-resize;\n right: -3px;\n top: 0;\n width: 5px;\n }\n\n.cropper-line.line-n {\n cursor: ns-resize;\n height: 5px;\n left: 0;\n top: -3px;\n }\n\n.cropper-line.line-w {\n cursor: ew-resize;\n left: -3px;\n top: 0;\n width: 5px;\n }\n\n.cropper-line.line-s {\n bottom: -3px;\n cursor: ns-resize;\n height: 5px;\n left: 0;\n }\n\n.cropper-point {\n background-color: #39f;\n height: 5px;\n opacity: 0.75;\n width: 5px;\n}\n\n.cropper-point.point-e {\n cursor: ew-resize;\n margin-top: -3px;\n right: -3px;\n top: 50%;\n }\n\n.cropper-point.point-n {\n cursor: ns-resize;\n left: 50%;\n margin-left: -3px;\n top: -3px;\n }\n\n.cropper-point.point-w {\n cursor: ew-resize;\n left: -3px;\n margin-top: -3px;\n top: 50%;\n }\n\n.cropper-point.point-s {\n bottom: -3px;\n cursor: s-resize;\n left: 50%;\n margin-left: -3px;\n }\n\n.cropper-point.point-ne {\n cursor: nesw-resize;\n right: -3px;\n top: -3px;\n }\n\n.cropper-point.point-nw {\n cursor: nwse-resize;\n left: -3px;\n top: -3px;\n }\n\n.cropper-point.point-sw {\n bottom: -3px;\n cursor: nesw-resize;\n left: -3px;\n }\n\n.cropper-point.point-se {\n bottom: -3px;\n cursor: nwse-resize;\n height: 20px;\n opacity: 1;\n right: -3px;\n width: 20px;\n }\n\n@media (min-width: 768px) {\n\n.cropper-point.point-se {\n height: 15px;\n width: 15px;\n }\n }\n\n@media (min-width: 992px) {\n\n.cropper-point.point-se {\n height: 10px;\n width: 10px;\n }\n }\n\n@media (min-width: 1200px) {\n\n.cropper-point.point-se {\n height: 5px;\n opacity: 0.75;\n width: 5px;\n }\n }\n\n.cropper-point.point-se::before {\n background-color: #39f;\n bottom: -50%;\n content: ' ';\n display: block;\n height: 200%;\n opacity: 0;\n position: absolute;\n right: -50%;\n width: 200%;\n }\n\n.cropper-invisible {\n opacity: 0;\n}\n\n.cropper-bg {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');\n}\n\n.cropper-hide {\n display: block;\n height: 0;\n position: absolute;\n width: 0;\n}\n\n.cropper-hidden {\n display: none !important;\n}\n\n.cropper-move {\n cursor: move;\n}\n\n.cropper-crop {\n cursor: crosshair;\n}\n\n.cropper-disabled .cropper-drag-box,\n.cropper-disabled .cropper-face,\n.cropper-disabled .cropper-line,\n.cropper-disabled .cropper-point {\n cursor: not-allowed;\n}\n"],"sourceRoot":""}]);
5500 // Exports
5501 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
5502
5503
5504 /***/ },
5505
5506 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
5507 /*!*****************************************************************************************!*\
5508 !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css ***!
5509 \*****************************************************************************************/
5510 (module, __webpack_exports__, __webpack_require__) {
5511
5512 "use strict";
5513 __webpack_require__.r(__webpack_exports__);
5514 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5515 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5516 /* harmony export */ });
5517 /* 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");
5518 /* 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__);
5519 /* 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");
5520 /* 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__);
5521 // Imports
5522
5523
5524 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()));
5525 // Module
5526 ___CSS_LOADER_EXPORT___.push([module.id, `/*!
5527 * Toastify js 1.12.0
5528 * https://github.com/apvarun/toastify-js
5529 * @license MIT licensed
5530 *
5531 * Copyright (C) 2018 Varun A P
5532 */
5533
5534 .toastify {
5535 padding: 12px 20px;
5536 color: #ffffff;
5537 display: inline-block;
5538 box-shadow: 0 3px 6px -1px rgba(0, 0, 0, 0.12), 0 10px 36px -4px rgba(77, 96, 232, 0.3);
5539 background: -webkit-linear-gradient(315deg, #73a5ff, #5477f5);
5540 background: linear-gradient(135deg, #73a5ff, #5477f5);
5541 position: fixed;
5542 opacity: 0;
5543 transition: all 0.4s cubic-bezier(0.215, 0.61, 0.355, 1);
5544 border-radius: 2px;
5545 cursor: pointer;
5546 text-decoration: none;
5547 max-width: calc(50% - 20px);
5548 z-index: 2147483647;
5549 }
5550
5551 .toastify.on {
5552 opacity: 1;
5553 }
5554
5555 .toast-close {
5556 background: transparent;
5557 border: 0;
5558 color: white;
5559 cursor: pointer;
5560 font-family: inherit;
5561 font-size: 1em;
5562 opacity: 0.4;
5563 padding: 0 5px;
5564 }
5565
5566 .toastify-right {
5567 right: 15px;
5568 }
5569
5570 .toastify-left {
5571 left: 15px;
5572 }
5573
5574 .toastify-top {
5575 top: -150px;
5576 }
5577
5578 .toastify-bottom {
5579 bottom: -150px;
5580 }
5581
5582 .toastify-rounded {
5583 border-radius: 25px;
5584 }
5585
5586 .toastify-avatar {
5587 width: 1.5em;
5588 height: 1.5em;
5589 margin: -7px 5px;
5590 border-radius: 2px;
5591 }
5592
5593 .toastify-center {
5594 margin-left: auto;
5595 margin-right: auto;
5596 left: 0;
5597 right: 0;
5598 max-width: fit-content;
5599 max-width: -moz-fit-content;
5600 }
5601
5602 @media only screen and (max-width: 360px) {
5603 .toastify-right, .toastify-left {
5604 margin-left: auto;
5605 margin-right: auto;
5606 left: 0;
5607 right: 0;
5608 max-width: fit-content;
5609 }
5610 }
5611 `, "",{"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":""}]);
5612 // Exports
5613 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
5614
5615
5616 /***/ },
5617
5618 /***/ "./node_modules/css-loader/dist/runtime/api.js"
5619 /*!*****************************************************!*\
5620 !*** ./node_modules/css-loader/dist/runtime/api.js ***!
5621 \*****************************************************/
5622 (module) {
5623
5624 "use strict";
5625
5626
5627 /*
5628 MIT License http://www.opensource.org/licenses/mit-license.php
5629 Author Tobias Koppers @sokra
5630 */
5631 module.exports = function (cssWithMappingToString) {
5632 var list = [];
5633
5634 // return the list of modules as css string
5635 list.toString = function toString() {
5636 return this.map(function (item) {
5637 var content = "";
5638 var needLayer = typeof item[5] !== "undefined";
5639 if (item[4]) {
5640 content += "@supports (".concat(item[4], ") {");
5641 }
5642 if (item[2]) {
5643 content += "@media ".concat(item[2], " {");
5644 }
5645 if (needLayer) {
5646 content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");
5647 }
5648 content += cssWithMappingToString(item);
5649 if (needLayer) {
5650 content += "}";
5651 }
5652 if (item[2]) {
5653 content += "}";
5654 }
5655 if (item[4]) {
5656 content += "}";
5657 }
5658 return content;
5659 }).join("");
5660 };
5661
5662 // import a list of modules into the list
5663 list.i = function i(modules, media, dedupe, supports, layer) {
5664 if (typeof modules === "string") {
5665 modules = [[null, modules, undefined]];
5666 }
5667 var alreadyImportedModules = {};
5668 if (dedupe) {
5669 for (var k = 0; k < this.length; k++) {
5670 var id = this[k][0];
5671 if (id != null) {
5672 alreadyImportedModules[id] = true;
5673 }
5674 }
5675 }
5676 for (var _k = 0; _k < modules.length; _k++) {
5677 var item = [].concat(modules[_k]);
5678 if (dedupe && alreadyImportedModules[item[0]]) {
5679 continue;
5680 }
5681 if (typeof layer !== "undefined") {
5682 if (typeof item[5] === "undefined") {
5683 item[5] = layer;
5684 } else {
5685 item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");
5686 item[5] = layer;
5687 }
5688 }
5689 if (media) {
5690 if (!item[2]) {
5691 item[2] = media;
5692 } else {
5693 item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");
5694 item[2] = media;
5695 }
5696 }
5697 if (supports) {
5698 if (!item[4]) {
5699 item[4] = "".concat(supports);
5700 } else {
5701 item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");
5702 item[4] = supports;
5703 }
5704 }
5705 list.push(item);
5706 }
5707 };
5708 return list;
5709 };
5710
5711 /***/ },
5712
5713 /***/ "./node_modules/css-loader/dist/runtime/getUrl.js"
5714 /*!********************************************************!*\
5715 !*** ./node_modules/css-loader/dist/runtime/getUrl.js ***!
5716 \********************************************************/
5717 (module) {
5718
5719 "use strict";
5720
5721
5722 module.exports = function (url, options) {
5723 if (!options) {
5724 options = {};
5725 }
5726 if (!url) {
5727 return url;
5728 }
5729 url = String(url.__esModule ? url.default : url);
5730
5731 // If url is already wrapped in quotes, remove them
5732 if (/^['"].*['"]$/.test(url)) {
5733 url = url.slice(1, -1);
5734 }
5735 if (options.hash) {
5736 url += options.hash;
5737 }
5738
5739 // Should url be wrapped?
5740 // See https://drafts.csswg.org/css-values-3/#urls
5741 if (/["'() \t\n]|(%20)/.test(url) || options.needQuotes) {
5742 return "\"".concat(url.replace(/"/g, '\\"').replace(/\n/g, "\\n"), "\"");
5743 }
5744 return url;
5745 };
5746
5747 /***/ },
5748
5749 /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js"
5750 /*!************************************************************!*\
5751 !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***!
5752 \************************************************************/
5753 (module) {
5754
5755 "use strict";
5756
5757
5758 module.exports = function (item) {
5759 var content = item[1];
5760 var cssMapping = item[3];
5761 if (!cssMapping) {
5762 return content;
5763 }
5764 if (typeof btoa === "function") {
5765 var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));
5766 var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);
5767 var sourceMapping = "/*# ".concat(data, " */");
5768 return [content].concat([sourceMapping]).join("\n");
5769 }
5770 return [content].join("\n");
5771 };
5772
5773 /***/ },
5774
5775 /***/ "./node_modules/cropperjs/dist/cropper.css"
5776 /*!*************************************************!*\
5777 !*** ./node_modules/cropperjs/dist/cropper.css ***!
5778 \*************************************************/
5779 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5780
5781 "use strict";
5782 __webpack_require__.r(__webpack_exports__);
5783 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5784 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5785 /* harmony export */ });
5786 /* 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");
5787 /* 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__);
5788 /* 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");
5789 /* 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__);
5790 /* 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");
5791 /* 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__);
5792 /* 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");
5793 /* 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__);
5794 /* 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");
5795 /* 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__);
5796 /* 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");
5797 /* 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__);
5798 /* harmony import */ var _css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../../css-loader/dist/cjs.js!./cropper.css */ "./node_modules/css-loader/dist/cjs.js!./node_modules/cropperjs/dist/cropper.css");
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810 var options = {};
5811
5812 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5813 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5814
5815 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5816
5817 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5818 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5819
5820 var update = _style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"], options);
5821
5822
5823
5824
5825 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _css_loader_dist_cjs_js_cropper_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined);
5826
5827
5828 /***/ },
5829
5830 /***/ "./node_modules/toastify-js/src/toastify.css"
5831 /*!***************************************************!*\
5832 !*** ./node_modules/toastify-js/src/toastify.css ***!
5833 \***************************************************/
5834 (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5835
5836 "use strict";
5837 __webpack_require__.r(__webpack_exports__);
5838 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5839 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
5840 /* harmony export */ });
5841 /* 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");
5842 /* 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__);
5843 /* 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");
5844 /* 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__);
5845 /* 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");
5846 /* 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__);
5847 /* 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");
5848 /* 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__);
5849 /* 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");
5850 /* 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__);
5851 /* 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");
5852 /* 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__);
5853 /* 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");
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865 var options = {};
5866
5867 options.styleTagTransform = (_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());
5868 options.setAttributes = (_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());
5869
5870 options.insert = _style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head");
5871
5872 options.domAPI = (_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());
5873 options.insertStyleElement = (_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());
5874
5875 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);
5876
5877
5878
5879
5880 /* 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);
5881
5882
5883 /***/ },
5884
5885 /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"
5886 /*!****************************************************************************!*\
5887 !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***!
5888 \****************************************************************************/
5889 (module) {
5890
5891 "use strict";
5892
5893
5894 var stylesInDOM = [];
5895 function getIndexByIdentifier(identifier) {
5896 var result = -1;
5897 for (var i = 0; i < stylesInDOM.length; i++) {
5898 if (stylesInDOM[i].identifier === identifier) {
5899 result = i;
5900 break;
5901 }
5902 }
5903 return result;
5904 }
5905 function modulesToDom(list, options) {
5906 var idCountMap = {};
5907 var identifiers = [];
5908 for (var i = 0; i < list.length; i++) {
5909 var item = list[i];
5910 var id = options.base ? item[0] + options.base : item[0];
5911 var count = idCountMap[id] || 0;
5912 var identifier = "".concat(id, " ").concat(count);
5913 idCountMap[id] = count + 1;
5914 var indexByIdentifier = getIndexByIdentifier(identifier);
5915 var obj = {
5916 css: item[1],
5917 media: item[2],
5918 sourceMap: item[3],
5919 supports: item[4],
5920 layer: item[5]
5921 };
5922 if (indexByIdentifier !== -1) {
5923 stylesInDOM[indexByIdentifier].references++;
5924 stylesInDOM[indexByIdentifier].updater(obj);
5925 } else {
5926 var updater = addElementStyle(obj, options);
5927 options.byIndex = i;
5928 stylesInDOM.splice(i, 0, {
5929 identifier: identifier,
5930 updater: updater,
5931 references: 1
5932 });
5933 }
5934 identifiers.push(identifier);
5935 }
5936 return identifiers;
5937 }
5938 function addElementStyle(obj, options) {
5939 var api = options.domAPI(options);
5940 api.update(obj);
5941 var updater = function updater(newObj) {
5942 if (newObj) {
5943 if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {
5944 return;
5945 }
5946 api.update(obj = newObj);
5947 } else {
5948 api.remove();
5949 }
5950 };
5951 return updater;
5952 }
5953 module.exports = function (list, options) {
5954 options = options || {};
5955 list = list || [];
5956 var lastIdentifiers = modulesToDom(list, options);
5957 return function update(newList) {
5958 newList = newList || [];
5959 for (var i = 0; i < lastIdentifiers.length; i++) {
5960 var identifier = lastIdentifiers[i];
5961 var index = getIndexByIdentifier(identifier);
5962 stylesInDOM[index].references--;
5963 }
5964 var newLastIdentifiers = modulesToDom(newList, options);
5965 for (var _i = 0; _i < lastIdentifiers.length; _i++) {
5966 var _identifier = lastIdentifiers[_i];
5967 var _index = getIndexByIdentifier(_identifier);
5968 if (stylesInDOM[_index].references === 0) {
5969 stylesInDOM[_index].updater();
5970 stylesInDOM.splice(_index, 1);
5971 }
5972 }
5973 lastIdentifiers = newLastIdentifiers;
5974 };
5975 };
5976
5977 /***/ },
5978
5979 /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js"
5980 /*!********************************************************************!*\
5981 !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***!
5982 \********************************************************************/
5983 (module) {
5984
5985 "use strict";
5986
5987
5988 var memo = {};
5989
5990 /* istanbul ignore next */
5991 function getTarget(target) {
5992 if (typeof memo[target] === "undefined") {
5993 var styleTarget = document.querySelector(target);
5994
5995 // Special case to return head of iframe instead of iframe itself
5996 if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
5997 try {
5998 // This will throw an exception if access to iframe is blocked
5999 // due to cross-origin restrictions
6000 styleTarget = styleTarget.contentDocument.head;
6001 } catch (e) {
6002 // istanbul ignore next
6003 styleTarget = null;
6004 }
6005 }
6006 memo[target] = styleTarget;
6007 }
6008 return memo[target];
6009 }
6010
6011 /* istanbul ignore next */
6012 function insertBySelector(insert, style) {
6013 var target = getTarget(insert);
6014 if (!target) {
6015 throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");
6016 }
6017 target.appendChild(style);
6018 }
6019 module.exports = insertBySelector;
6020
6021 /***/ },
6022
6023 /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"
6024 /*!**********************************************************************!*\
6025 !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***!
6026 \**********************************************************************/
6027 (module) {
6028
6029 "use strict";
6030
6031
6032 /* istanbul ignore next */
6033 function insertStyleElement(options) {
6034 var element = document.createElement("style");
6035 options.setAttributes(element, options.attributes);
6036 options.insert(element, options.options);
6037 return element;
6038 }
6039 module.exports = insertStyleElement;
6040
6041 /***/ },
6042
6043 /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"
6044 /*!**********************************************************************************!*\
6045 !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***!
6046 \**********************************************************************************/
6047 (module, __unused_webpack_exports, __webpack_require__) {
6048
6049 "use strict";
6050
6051
6052 /* istanbul ignore next */
6053 function setAttributesWithoutAttributes(styleElement) {
6054 var nonce = true ? __webpack_require__.nc : 0;
6055 if (nonce) {
6056 styleElement.setAttribute("nonce", nonce);
6057 }
6058 }
6059 module.exports = setAttributesWithoutAttributes;
6060
6061 /***/ },
6062
6063 /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"
6064 /*!***************************************************************!*\
6065 !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***!
6066 \***************************************************************/
6067 (module) {
6068
6069 "use strict";
6070
6071
6072 /* istanbul ignore next */
6073 function apply(styleElement, options, obj) {
6074 var css = "";
6075 if (obj.supports) {
6076 css += "@supports (".concat(obj.supports, ") {");
6077 }
6078 if (obj.media) {
6079 css += "@media ".concat(obj.media, " {");
6080 }
6081 var needLayer = typeof obj.layer !== "undefined";
6082 if (needLayer) {
6083 css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");
6084 }
6085 css += obj.css;
6086 if (needLayer) {
6087 css += "}";
6088 }
6089 if (obj.media) {
6090 css += "}";
6091 }
6092 if (obj.supports) {
6093 css += "}";
6094 }
6095 var sourceMap = obj.sourceMap;
6096 if (sourceMap && typeof btoa !== "undefined") {
6097 css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");
6098 }
6099
6100 // For old IE
6101 /* istanbul ignore if */
6102 options.styleTagTransform(css, styleElement, options.options);
6103 }
6104 function removeStyleElement(styleElement) {
6105 // istanbul ignore if
6106 if (styleElement.parentNode === null) {
6107 return false;
6108 }
6109 styleElement.parentNode.removeChild(styleElement);
6110 }
6111
6112 /* istanbul ignore next */
6113 function domAPI(options) {
6114 if (typeof document === "undefined") {
6115 return {
6116 update: function update() {},
6117 remove: function remove() {}
6118 };
6119 }
6120 var styleElement = options.insertStyleElement(options);
6121 return {
6122 update: function update(obj) {
6123 apply(styleElement, options, obj);
6124 },
6125 remove: function remove() {
6126 removeStyleElement(styleElement);
6127 }
6128 };
6129 }
6130 module.exports = domAPI;
6131
6132 /***/ },
6133
6134 /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"
6135 /*!*********************************************************************!*\
6136 !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***!
6137 \*********************************************************************/
6138 (module) {
6139
6140 "use strict";
6141
6142
6143 /* istanbul ignore next */
6144 function styleTagTransform(css, styleElement) {
6145 if (styleElement.styleSheet) {
6146 styleElement.styleSheet.cssText = css;
6147 } else {
6148 while (styleElement.firstChild) {
6149 styleElement.removeChild(styleElement.firstChild);
6150 }
6151 styleElement.appendChild(document.createTextNode(css));
6152 }
6153 }
6154 module.exports = styleTagTransform;
6155
6156 /***/ },
6157
6158 /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js"
6159 /*!**********************************************************!*\
6160 !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
6161 \**********************************************************/
6162 (module) {
6163
6164 /*!
6165 * sweetalert2 v11.26.25
6166 * Released under the MIT License.
6167 */
6168 (function (global, factory) {
6169 true ? module.exports = factory() :
6170 0;
6171 })(this, (function () { 'use strict';
6172
6173 function _assertClassBrand(e, t, n) {
6174 if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
6175 throw new TypeError("Private element is not present on this object");
6176 }
6177 function _checkPrivateRedeclaration(e, t) {
6178 if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
6179 }
6180 function _classPrivateFieldGet2(s, a) {
6181 return s.get(_assertClassBrand(s, a));
6182 }
6183 function _classPrivateFieldInitSpec(e, t, a) {
6184 _checkPrivateRedeclaration(e, t), t.set(e, a);
6185 }
6186 function _classPrivateFieldSet2(s, a, r) {
6187 return s.set(_assertClassBrand(s, a), r), r;
6188 }
6189
6190 const RESTORE_FOCUS_TIMEOUT = 100;
6191
6192 /** @type {GlobalState} */
6193 const globalState = {};
6194 const focusPreviousActiveElement = () => {
6195 if (globalState.previousActiveElement instanceof HTMLElement) {
6196 globalState.previousActiveElement.focus();
6197 globalState.previousActiveElement = null;
6198 } else if (document.body) {
6199 document.body.focus();
6200 }
6201 };
6202
6203 /**
6204 * Restore previous active (focused) element
6205 *
6206 * @param {boolean} returnFocus
6207 * @returns {Promise<void>}
6208 */
6209 const restoreActiveElement = returnFocus => {
6210 return new Promise(resolve => {
6211 if (!returnFocus) {
6212 return resolve();
6213 }
6214 const x = window.scrollX;
6215 const y = window.scrollY;
6216 globalState.restoreFocusTimeout = setTimeout(() => {
6217 focusPreviousActiveElement();
6218 resolve();
6219 }, RESTORE_FOCUS_TIMEOUT); // issues/900
6220
6221 window.scrollTo(x, y);
6222 });
6223 };
6224
6225 const swalPrefix = 'swal2-';
6226
6227 /**
6228 * @typedef {Record<SwalClass, string>} SwalClasses
6229 */
6230
6231 /**
6232 * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
6233 * @typedef {Record<SwalIcon, string>} SwalIcons
6234 */
6235
6236 /** @type {SwalClass[]} */
6237 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'];
6238 const swalClasses = classNames.reduce((acc, className) => {
6239 acc[className] = swalPrefix + className;
6240 return acc;
6241 }, /** @type {SwalClasses} */{});
6242
6243 /** @type {SwalIcon[]} */
6244 const icons = ['success', 'warning', 'info', 'question', 'error'];
6245 const iconTypes = icons.reduce((acc, icon) => {
6246 acc[icon] = swalPrefix + icon;
6247 return acc;
6248 }, /** @type {SwalIcons} */{});
6249
6250 const consolePrefix = 'SweetAlert2:';
6251
6252 /**
6253 * Capitalize the first letter of a string
6254 *
6255 * @param {string} str
6256 * @returns {string}
6257 */
6258 const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);
6259
6260 /**
6261 * Standardize console warnings
6262 *
6263 * @param {string | string[]} message
6264 */
6265 const warn = message => {
6266 console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
6267 };
6268
6269 /**
6270 * Standardize console errors
6271 *
6272 * @param {string} message
6273 */
6274 const error = message => {
6275 console.error(`${consolePrefix} ${message}`);
6276 };
6277
6278 /**
6279 * Private global state for `warnOnce`
6280 *
6281 * @type {string[]}
6282 * @private
6283 */
6284 const previousWarnOnceMessages = [];
6285
6286 /**
6287 * Show a console warning, but only if it hasn't already been shown
6288 *
6289 * @param {string} message
6290 */
6291 const warnOnce = message => {
6292 if (!previousWarnOnceMessages.includes(message)) {
6293 previousWarnOnceMessages.push(message);
6294 warn(message);
6295 }
6296 };
6297
6298 /**
6299 * Show a one-time console warning about deprecated params/methods
6300 *
6301 * @param {string} deprecatedParam
6302 * @param {string?} useInstead
6303 */
6304 const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
6305 warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
6306 };
6307
6308 /**
6309 * If `arg` is a function, call it (with no arguments or context) and return the result.
6310 * Otherwise, just pass the value through
6311 *
6312 * @param {(() => *) | *} arg
6313 * @returns {*}
6314 */
6315 const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;
6316
6317 /**
6318 * @param {*} arg
6319 * @returns {boolean}
6320 */
6321 const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';
6322
6323 /**
6324 * @param {*} arg
6325 * @returns {Promise<*>}
6326 */
6327 const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);
6328
6329 /**
6330 * @param {*} arg
6331 * @returns {boolean}
6332 */
6333 const isPromise = arg => arg && Promise.resolve(arg) === arg;
6334
6335 /**
6336 * @returns {boolean}
6337 */
6338 const isFirefox = () => navigator.userAgent.includes('Firefox');
6339
6340 /**
6341 * Gets the popup container which contains the backdrop and the popup itself.
6342 *
6343 * @returns {HTMLElement | null}
6344 */
6345 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
6346
6347 /**
6348 * @param {string} selectorString
6349 * @returns {HTMLElement | null}
6350 */
6351 const elementBySelector = selectorString => {
6352 const container = getContainer();
6353 return container ? container.querySelector(selectorString) : null;
6354 };
6355
6356 /**
6357 * @param {string} className
6358 * @returns {HTMLElement | null}
6359 */
6360 const elementByClass = className => {
6361 return elementBySelector(`.${className}`);
6362 };
6363
6364 /**
6365 * @returns {HTMLElement | null}
6366 */
6367 const getPopup = () => elementByClass(swalClasses.popup);
6368
6369 /**
6370 * @returns {HTMLElement | null}
6371 */
6372 const getIcon = () => elementByClass(swalClasses.icon);
6373
6374 /**
6375 * @returns {HTMLElement | null}
6376 */
6377 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6378
6379 /**
6380 * @returns {HTMLElement | null}
6381 */
6382 const getTitle = () => elementByClass(swalClasses.title);
6383
6384 /**
6385 * @returns {HTMLElement | null}
6386 */
6387 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6388
6389 /**
6390 * @returns {HTMLElement | null}
6391 */
6392 const getImage = () => elementByClass(swalClasses.image);
6393
6394 /**
6395 * @returns {HTMLElement | null}
6396 */
6397 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6398
6399 /**
6400 * @returns {HTMLElement | null}
6401 */
6402 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6403
6404 /**
6405 * @returns {HTMLButtonElement | null}
6406 */
6407 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6408
6409 /**
6410 * @returns {HTMLButtonElement | null}
6411 */
6412 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6413
6414 /**
6415 * @returns {HTMLButtonElement | null}
6416 */
6417 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6418
6419 /**
6420 * @returns {HTMLElement | null}
6421 */
6422 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6423
6424 /**
6425 * @returns {HTMLElement | null}
6426 */
6427 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6428
6429 /**
6430 * @returns {HTMLElement | null}
6431 */
6432 const getActions = () => elementByClass(swalClasses.actions);
6433
6434 /**
6435 * @returns {HTMLElement | null}
6436 */
6437 const getFooter = () => elementByClass(swalClasses.footer);
6438
6439 /**
6440 * @returns {HTMLElement | null}
6441 */
6442 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6443
6444 /**
6445 * @returns {HTMLElement | null}
6446 */
6447 const getCloseButton = () => elementByClass(swalClasses.close);
6448
6449 // https://github.com/jkup/focusable/blob/master/index.js
6450 const focusable = `
6451 a[href],
6452 area[href],
6453 input:not([disabled]),
6454 select:not([disabled]),
6455 textarea:not([disabled]),
6456 button:not([disabled]),
6457 iframe,
6458 object,
6459 embed,
6460 [tabindex="0"],
6461 [contenteditable],
6462 audio[controls],
6463 video[controls],
6464 summary
6465 `;
6466 /**
6467 * @returns {HTMLElement[]}
6468 */
6469 const getFocusableElements = () => {
6470 const popup = getPopup();
6471 if (!popup) {
6472 return [];
6473 }
6474 /** @type {NodeListOf<HTMLElement>} */
6475 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6476 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6477 // sort according to tabindex
6478 .sort((a, b) => {
6479 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6480 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6481 if (tabindexA > tabindexB) {
6482 return 1;
6483 } else if (tabindexA < tabindexB) {
6484 return -1;
6485 }
6486 return 0;
6487 });
6488
6489 /** @type {NodeListOf<HTMLElement>} */
6490 const otherFocusableElements = popup.querySelectorAll(focusable);
6491 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6492 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6493 };
6494
6495 /**
6496 * @returns {boolean}
6497 */
6498 const isModal = () => {
6499 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6500 };
6501
6502 /**
6503 * @returns {boolean}
6504 */
6505 const isToast = () => {
6506 const popup = getPopup();
6507 if (!popup) {
6508 return false;
6509 }
6510 return hasClass(popup, swalClasses.toast);
6511 };
6512
6513 /**
6514 * @returns {boolean}
6515 */
6516 const isLoading = () => {
6517 const popup = getPopup();
6518 if (!popup) {
6519 return false;
6520 }
6521 return popup.hasAttribute('data-loading');
6522 };
6523
6524 /**
6525 * Securely set innerHTML of an element
6526 * https://github.com/sweetalert2/sweetalert2/issues/1926
6527 *
6528 * @param {HTMLElement} elem
6529 * @param {string} html
6530 */
6531 const setInnerHtml = (elem, html) => {
6532 elem.textContent = '';
6533 if (html) {
6534 const parser = new DOMParser();
6535 const parsed = parser.parseFromString(html, `text/html`);
6536 const head = parsed.querySelector('head');
6537 if (head) {
6538 Array.from(head.childNodes).forEach(child => {
6539 elem.appendChild(child);
6540 });
6541 }
6542 const body = parsed.querySelector('body');
6543 if (body) {
6544 Array.from(body.childNodes).forEach(child => {
6545 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6546 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6547 } else {
6548 elem.appendChild(child);
6549 }
6550 });
6551 }
6552 }
6553 };
6554
6555 /**
6556 * @param {HTMLElement} elem
6557 * @param {string} className
6558 * @returns {boolean}
6559 */
6560 const hasClass = (elem, className) => {
6561 if (!className) {
6562 return false;
6563 }
6564 return className.split(/\s+/).every(cls => elem.classList.contains(cls));
6565 };
6566
6567 /**
6568 * @param {HTMLElement} elem
6569 * @param {SweetAlertOptions} params
6570 */
6571 const removeCustomClasses = (elem, params) => {
6572 Array.from(elem.classList).forEach(className => {
6573 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6574 elem.classList.remove(className);
6575 }
6576 });
6577 };
6578
6579 /**
6580 * @param {HTMLElement} elem
6581 * @param {SweetAlertOptions} params
6582 * @param {string} className
6583 */
6584 const applyCustomClass = (elem, params, className) => {
6585 removeCustomClasses(elem, params);
6586 if (!params.customClass) {
6587 return;
6588 }
6589 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6590 if (!customClass) {
6591 return;
6592 }
6593 if (typeof customClass !== 'string' && !customClass.forEach) {
6594 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6595 return;
6596 }
6597 addClass(elem, customClass);
6598 };
6599
6600 /**
6601 * @param {HTMLElement} popup
6602 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6603 * @returns {HTMLInputElement | null}
6604 */
6605 const getInput$1 = (popup, inputClass) => {
6606 if (!inputClass) {
6607 return null;
6608 }
6609 switch (inputClass) {
6610 case 'select':
6611 case 'textarea':
6612 case 'file':
6613 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6614 case 'checkbox':
6615 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6616 case 'radio':
6617 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6618 case 'range':
6619 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6620 default:
6621 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6622 }
6623 };
6624
6625 /**
6626 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6627 */
6628 const focusInput = input => {
6629 input.focus();
6630
6631 // place cursor at end of text in text input
6632 if (input.type !== 'file') {
6633 // http://stackoverflow.com/a/2345915
6634 const val = input.value;
6635 input.value = '';
6636 input.value = val;
6637 }
6638 };
6639
6640 /**
6641 * @param {HTMLElement | HTMLElement[] | null} target
6642 * @param {string | string[] | readonly string[] | undefined} classList
6643 * @param {boolean} condition
6644 */
6645 const toggleClass = (target, classList, condition) => {
6646 if (!target || !classList) {
6647 return;
6648 }
6649 const classes = typeof classList === 'string' ? classList.split(/\s+/).filter(Boolean) : classList;
6650 const targets = Array.isArray(target) ? target : [target];
6651 targets.forEach(elem => {
6652 classes.forEach(className => {
6653 if (condition) {
6654 elem.classList.add(className);
6655 } else {
6656 elem.classList.remove(className);
6657 }
6658 });
6659 });
6660 };
6661
6662 /**
6663 * @param {HTMLElement | HTMLElement[] | null} target
6664 * @param {string | string[] | readonly string[] | undefined} classList
6665 */
6666 const addClass = (target, classList) => {
6667 toggleClass(target, classList, true);
6668 };
6669
6670 /**
6671 * @param {HTMLElement | HTMLElement[] | null} target
6672 * @param {string | string[] | readonly string[] | undefined} classList
6673 */
6674 const removeClass = (target, classList) => {
6675 toggleClass(target, classList, false);
6676 };
6677
6678 /**
6679 * Get direct child of an element by class name
6680 *
6681 * @param {HTMLElement} elem
6682 * @param {string} className
6683 * @returns {HTMLElement | undefined}
6684 */
6685 const getDirectChildByClass = (elem, className) => (/** @type {HTMLElement | undefined} */
6686 Array.from(elem.children).find(child => child instanceof HTMLElement && hasClass(child, className)));
6687
6688 /**
6689 * @param {HTMLElement} elem
6690 * @param {string} property
6691 * @param {string | number | null | undefined} value
6692 */
6693 const applyNumericalStyle = (elem, property, value) => {
6694 if (value === `${parseInt(`${value}`)}`) {
6695 value = parseInt(value);
6696 }
6697 if (value || value === 0) {
6698 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
6699 } else {
6700 elem.style.removeProperty(property);
6701 }
6702 };
6703
6704 /**
6705 * @param {HTMLElement | null} elem
6706 * @param {string} display
6707 */
6708 const show = (elem, display = 'flex') => {
6709 if (!elem) {
6710 return;
6711 }
6712 elem.style.display = display;
6713 };
6714
6715 /**
6716 * @param {HTMLElement | null} elem
6717 */
6718 const hide = elem => {
6719 if (!elem) {
6720 return;
6721 }
6722 elem.style.display = 'none';
6723 };
6724
6725 /**
6726 * @param {HTMLElement | null} elem
6727 * @param {string} display
6728 */
6729 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6730 if (!elem) {
6731 return;
6732 }
6733 new MutationObserver(() => {
6734 toggle(elem, elem.innerHTML, display);
6735 }).observe(elem, {
6736 childList: true,
6737 subtree: true
6738 });
6739 };
6740
6741 /**
6742 * @param {HTMLElement} parent
6743 * @param {string} selector
6744 * @param {string} property
6745 * @param {string} value
6746 */
6747 const setStyle = (parent, selector, property, value) => {
6748 /** @type {HTMLElement | null} */
6749 const el = parent.querySelector(selector);
6750 if (el) {
6751 el.style.setProperty(property, value);
6752 }
6753 };
6754
6755 /**
6756 * @param {HTMLElement} elem
6757 * @param {boolean | string | null | undefined} condition
6758 * @param {string} display
6759 */
6760 const toggle = (elem, condition, display = 'flex') => {
6761 if (condition) {
6762 show(elem, display);
6763 } else {
6764 hide(elem);
6765 }
6766 };
6767
6768 /**
6769 * borrowed from jquery $(elem).is(':visible') implementation
6770 *
6771 * @param {HTMLElement | null} elem
6772 * @returns {boolean}
6773 */
6774 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6775
6776 /**
6777 * @returns {boolean}
6778 */
6779 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6780
6781 /**
6782 * @param {HTMLElement} elem
6783 * @returns {boolean}
6784 */
6785 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
6786
6787 /**
6788 * @param {HTMLElement} element
6789 * @param {HTMLElement} stopElement
6790 * @returns {boolean}
6791 */
6792 const selfOrParentIsScrollable = (element, stopElement) => {
6793 let parent = /** @type {HTMLElement | null} */element;
6794 while (parent && parent !== stopElement) {
6795 if (isScrollable(parent)) {
6796 return true;
6797 }
6798 parent = parent.parentElement;
6799 }
6800 return false;
6801 };
6802
6803 /**
6804 * borrowed from https://stackoverflow.com/a/46352119
6805 *
6806 * @param {HTMLElement} elem
6807 * @returns {boolean}
6808 */
6809 const hasCssAnimation = elem => {
6810 const style = window.getComputedStyle(elem);
6811 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6812 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6813 return animDuration > 0 || transDuration > 0;
6814 };
6815
6816 /**
6817 * @param {number} timer
6818 * @param {boolean} reset
6819 */
6820 const animateTimerProgressBar = (timer, reset = false) => {
6821 const timerProgressBar = getTimerProgressBar();
6822 if (!timerProgressBar) {
6823 return;
6824 }
6825 if (isVisible$1(timerProgressBar)) {
6826 if (reset) {
6827 timerProgressBar.style.transition = 'none';
6828 timerProgressBar.style.width = '100%';
6829 }
6830 setTimeout(() => {
6831 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6832 timerProgressBar.style.width = '0%';
6833 }, 10);
6834 }
6835 };
6836 const stopTimerProgressBar = () => {
6837 const timerProgressBar = getTimerProgressBar();
6838 if (!timerProgressBar) {
6839 return;
6840 }
6841 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6842 timerProgressBar.style.removeProperty('transition');
6843 timerProgressBar.style.width = '100%';
6844 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6845 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6846 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6847 };
6848
6849 /**
6850 * Detect Node env
6851 *
6852 * @returns {boolean}
6853 */
6854 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6855
6856 const sweetHTML = `
6857 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6858 <button type="button" class="${swalClasses.close}"></button>
6859 <ul class="${swalClasses['progress-steps']}"></ul>
6860 <div class="${swalClasses.icon}"></div>
6861 <img class="${swalClasses.image}" />
6862 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6863 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6864 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6865 <input type="file" class="${swalClasses.file}" />
6866 <div class="${swalClasses.range}">
6867 <input type="range" />
6868 <output></output>
6869 </div>
6870 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6871 <div class="${swalClasses.radio}"></div>
6872 <label class="${swalClasses.checkbox}">
6873 <input type="checkbox" id="${swalClasses.checkbox}" />
6874 <span class="${swalClasses.label}"></span>
6875 </label>
6876 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6877 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6878 <div class="${swalClasses.actions}">
6879 <div class="${swalClasses.loader}"></div>
6880 <button type="button" class="${swalClasses.confirm}"></button>
6881 <button type="button" class="${swalClasses.deny}"></button>
6882 <button type="button" class="${swalClasses.cancel}"></button>
6883 </div>
6884 <div class="${swalClasses.footer}"></div>
6885 <div class="${swalClasses['timer-progress-bar-container']}">
6886 <div class="${swalClasses['timer-progress-bar']}"></div>
6887 </div>
6888 </div>
6889 `.replace(/(^|\n)\s*/g, '');
6890
6891 /**
6892 * @returns {boolean}
6893 */
6894 const resetOldContainer = () => {
6895 const oldContainer = getContainer();
6896 if (!oldContainer) {
6897 return false;
6898 }
6899 oldContainer.remove();
6900 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
6901 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
6902 swalClasses['has-column']]);
6903 return true;
6904 };
6905 const resetValidationMessage$1 = () => {
6906 if (globalState.currentInstance) {
6907 globalState.currentInstance.resetValidationMessage();
6908 }
6909 };
6910 const addInputChangeListeners = () => {
6911 const popup = getPopup();
6912 if (!popup) {
6913 return;
6914 }
6915 const input = getDirectChildByClass(popup, swalClasses.input);
6916 const file = getDirectChildByClass(popup, swalClasses.file);
6917 /** @type {HTMLInputElement | null} */
6918 const range = popup.querySelector(`.${swalClasses.range} input`);
6919 /** @type {HTMLOutputElement | null} */
6920 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6921 const select = getDirectChildByClass(popup, swalClasses.select);
6922 /** @type {HTMLInputElement | null} */
6923 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6924 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6925 if (input) {
6926 input.oninput = resetValidationMessage$1;
6927 }
6928 if (file) {
6929 file.onchange = resetValidationMessage$1;
6930 }
6931 if (select) {
6932 select.onchange = resetValidationMessage$1;
6933 }
6934 if (checkbox) {
6935 checkbox.onchange = resetValidationMessage$1;
6936 }
6937 if (textarea) {
6938 textarea.oninput = resetValidationMessage$1;
6939 }
6940 if (range && rangeOutput) {
6941 range.oninput = () => {
6942 resetValidationMessage$1();
6943 rangeOutput.value = range.value;
6944 };
6945 range.onchange = () => {
6946 resetValidationMessage$1();
6947 rangeOutput.value = range.value;
6948 };
6949 }
6950 };
6951
6952 /**
6953 * @param {string | HTMLElement} target
6954 * @returns {HTMLElement}
6955 */
6956 const getTarget = target => {
6957 if (typeof target === 'string') {
6958 const element = document.querySelector(target);
6959 if (!element) {
6960 throw new Error(`Target element "${target}" not found`);
6961 }
6962 return /** @type {HTMLElement} */element;
6963 }
6964 return target;
6965 };
6966
6967 /**
6968 * @param {SweetAlertOptions} params
6969 */
6970 const setupAccessibility = params => {
6971 const popup = getPopup();
6972 if (!popup) {
6973 return;
6974 }
6975 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6976 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6977 if (!params.toast) {
6978 popup.setAttribute('aria-modal', 'true');
6979 }
6980 };
6981
6982 /**
6983 * @param {HTMLElement} targetElement
6984 */
6985 const setupRTL = targetElement => {
6986 if (window.getComputedStyle(targetElement).direction === 'rtl') {
6987 addClass(getContainer(), swalClasses.rtl);
6988 globalState.isRTL = true;
6989 }
6990 };
6991
6992 /**
6993 * Add modal + backdrop to DOM
6994 *
6995 * @param {SweetAlertOptions} params
6996 */
6997 const init = params => {
6998 // Clean up the old popup container if it exists
6999 const oldContainerExisted = resetOldContainer();
7000 if (isNodeEnv()) {
7001 error('SweetAlert2 requires document to initialize');
7002 return;
7003 }
7004 const container = document.createElement('div');
7005 container.className = swalClasses.container;
7006 if (oldContainerExisted) {
7007 addClass(container, swalClasses['no-transition']);
7008 }
7009 setInnerHtml(container, sweetHTML);
7010 container.dataset['swal2Theme'] = params.theme;
7011 const targetElement = getTarget(params.target || 'body');
7012 targetElement.appendChild(container);
7013 if (params.topLayer) {
7014 container.setAttribute('popover', '');
7015 container.showPopover();
7016 }
7017 setupAccessibility(params);
7018 setupRTL(targetElement);
7019 addInputChangeListeners();
7020 };
7021
7022 /**
7023 * @param {HTMLElement | object | string} param
7024 * @param {HTMLElement} target
7025 */
7026 const parseHtmlToContainer = (param, target) => {
7027 // DOM element
7028 if (param instanceof HTMLElement) {
7029 target.appendChild(param);
7030 }
7031
7032 // Object
7033 else if (typeof param === 'object') {
7034 handleObject(param, target);
7035 }
7036
7037 // Plain string
7038 else if (param) {
7039 setInnerHtml(target, param);
7040 }
7041 };
7042
7043 /**
7044 * @param {object} param
7045 * @param {HTMLElement} target
7046 */
7047 const handleObject = (param, target) => {
7048 // JQuery element(s)
7049 if ('jquery' in param) {
7050 handleJqueryElem(target, param);
7051 }
7052
7053 // For other objects use their string representation
7054 else {
7055 setInnerHtml(target, param.toString());
7056 }
7057 };
7058
7059 /**
7060 * @param {HTMLElement} target
7061 * @param {any} elem
7062 */
7063 const handleJqueryElem = (target, elem) => {
7064 target.textContent = '';
7065 if (0 in elem) {
7066 for (let i = 0; i in elem; i++) {
7067 target.appendChild(elem[i].cloneNode(true));
7068 }
7069 } else {
7070 target.appendChild(elem.cloneNode(true));
7071 }
7072 };
7073
7074 /**
7075 * @param {SweetAlert} instance
7076 * @param {SweetAlertOptions} params
7077 */
7078 const renderActions = (instance, params) => {
7079 const actions = getActions();
7080 const loader = getLoader();
7081 if (!actions || !loader) {
7082 return;
7083 }
7084
7085 // Actions (buttons) wrapper
7086 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
7087 hide(actions);
7088 } else {
7089 show(actions);
7090 }
7091
7092 // Custom class
7093 applyCustomClass(actions, params, 'actions');
7094
7095 // Render all the buttons
7096 renderButtons(actions, loader, params);
7097
7098 // Loader
7099 setInnerHtml(loader, params.loaderHtml || '');
7100 applyCustomClass(loader, params, 'loader');
7101 };
7102
7103 /**
7104 * @param {HTMLElement} actions
7105 * @param {HTMLElement} loader
7106 * @param {SweetAlertOptions} params
7107 */
7108 function renderButtons(actions, loader, params) {
7109 const confirmButton = getConfirmButton();
7110 const denyButton = getDenyButton();
7111 const cancelButton = getCancelButton();
7112 if (!confirmButton || !denyButton || !cancelButton) {
7113 return;
7114 }
7115
7116 // Render buttons
7117 renderButton(confirmButton, 'confirm', params);
7118 renderButton(denyButton, 'deny', params);
7119 renderButton(cancelButton, 'cancel', params);
7120 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
7121 if (params.reverseButtons) {
7122 if (params.toast) {
7123 actions.insertBefore(cancelButton, confirmButton);
7124 actions.insertBefore(denyButton, confirmButton);
7125 } else {
7126 actions.insertBefore(cancelButton, loader);
7127 actions.insertBefore(denyButton, loader);
7128 actions.insertBefore(confirmButton, loader);
7129 }
7130 }
7131 }
7132
7133 /**
7134 * @param {HTMLElement} confirmButton
7135 * @param {HTMLElement} denyButton
7136 * @param {HTMLElement} cancelButton
7137 * @param {SweetAlertOptions} params
7138 */
7139 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
7140 if (!params.buttonsStyling) {
7141 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7142 return;
7143 }
7144 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7145
7146 // Apply custom background colors and outline colors to action buttons
7147 /** @type {[HTMLElement, string, string | undefined][]} */
7148 const buttons = [[confirmButton, 'confirm', params.confirmButtonColor], [denyButton, 'deny', params.denyButtonColor], [cancelButton, 'cancel', params.cancelButtonColor]];
7149 buttons.forEach(([button, type, color]) => {
7150 if (color) {
7151 button.style.setProperty(`--swal2-${type}-button-background-color`, color);
7152 }
7153 applyOutlineColor(button);
7154 });
7155 }
7156
7157 /**
7158 * @param {HTMLElement} button
7159 */
7160 function applyOutlineColor(button) {
7161 const buttonStyle = window.getComputedStyle(button);
7162 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
7163 // If the button already has a custom outline color, no need to change it
7164 return;
7165 }
7166 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
7167 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
7168 }
7169
7170 /**
7171 * @param {HTMLElement} button
7172 * @param {'confirm' | 'deny' | 'cancel'} buttonType
7173 * @param {SweetAlertOptions} params
7174 */
7175 function renderButton(button, buttonType, params) {
7176 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
7177 toggle(button, params[`show${buttonName}Button`], 'inline-block');
7178 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
7179 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
7180
7181 // Add buttons custom classes
7182 button.className = swalClasses[buttonType];
7183 applyCustomClass(button, params, `${buttonType}Button`);
7184 }
7185
7186 /**
7187 * @param {SweetAlert} instance
7188 * @param {SweetAlertOptions} params
7189 */
7190 const renderCloseButton = (instance, params) => {
7191 const closeButton = getCloseButton();
7192 if (!closeButton) {
7193 return;
7194 }
7195 setInnerHtml(closeButton, params.closeButtonHtml || '');
7196
7197 // Custom class
7198 applyCustomClass(closeButton, params, 'closeButton');
7199 toggle(closeButton, params.showCloseButton);
7200 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
7201 };
7202
7203 /**
7204 * @param {SweetAlert} instance
7205 * @param {SweetAlertOptions} params
7206 */
7207 const renderContainer = (instance, params) => {
7208 const container = getContainer();
7209 if (!container) {
7210 return;
7211 }
7212 handleBackdropParam(container, params.backdrop);
7213 handlePositionParam(container, params.position);
7214 handleGrowParam(container, params.grow);
7215
7216 // Custom class
7217 applyCustomClass(container, params, 'container');
7218 };
7219
7220 /**
7221 * @param {HTMLElement} container
7222 * @param {SweetAlertOptions['backdrop']} backdrop
7223 */
7224 function handleBackdropParam(container, backdrop) {
7225 if (typeof backdrop === 'string') {
7226 container.style.background = backdrop;
7227 } else if (!backdrop) {
7228 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
7229 }
7230 }
7231
7232 /**
7233 * @param {HTMLElement} container
7234 * @param {SweetAlertOptions['position']} position
7235 */
7236 function handlePositionParam(container, position) {
7237 if (!position) {
7238 return;
7239 }
7240 if (position in swalClasses) {
7241 addClass(container, swalClasses[position]);
7242 } else {
7243 warn('The "position" parameter is not valid, defaulting to "center"');
7244 addClass(container, swalClasses.center);
7245 }
7246 }
7247
7248 /**
7249 * @param {HTMLElement} container
7250 * @param {SweetAlertOptions['grow']} grow
7251 */
7252 function handleGrowParam(container, grow) {
7253 if (!grow) {
7254 return;
7255 }
7256 addClass(container, swalClasses[`grow-${grow}`]);
7257 }
7258
7259 /**
7260 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7261 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7262 * This is the approach that Babel will probably take to implement private methods/fields
7263 * https://github.com/tc39/proposal-private-methods
7264 * https://github.com/babel/babel/pull/7555
7265 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7266 * then we can use that language feature.
7267 */
7268
7269 var privateProps = {
7270 innerParams: new WeakMap(),
7271 domCache: new WeakMap(),
7272 focusedElement: new WeakMap()
7273 };
7274
7275 /// <reference path="../../../../sweetalert2.d.ts"/>
7276
7277
7278 /** @type {InputClass[]} */
7279 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
7280
7281 /**
7282 * @param {SweetAlert} instance
7283 * @param {SweetAlertOptions} params
7284 */
7285 const renderInput = (instance, params) => {
7286 const popup = getPopup();
7287 if (!popup) {
7288 return;
7289 }
7290 const innerParams = privateProps.innerParams.get(instance);
7291 const rerender = !innerParams || params.input !== innerParams.input;
7292 inputClasses.forEach(inputClass => {
7293 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
7294 if (!inputContainer) {
7295 return;
7296 }
7297
7298 // set attributes
7299 setAttributes(inputClass, params.inputAttributes);
7300
7301 // set class
7302 inputContainer.className = swalClasses[inputClass];
7303 if (rerender) {
7304 hide(inputContainer);
7305 }
7306 });
7307 if (params.input) {
7308 if (rerender) {
7309 showInput(params);
7310 }
7311 // set custom class
7312 setCustomClass(params);
7313 }
7314 };
7315
7316 /**
7317 * @param {SweetAlertOptions} params
7318 */
7319 const showInput = params => {
7320 if (!params.input) {
7321 return;
7322 }
7323 if (!renderInputType[params.input]) {
7324 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
7325 return;
7326 }
7327 const inputContainer = getInputContainer(params.input);
7328 if (!inputContainer) {
7329 return;
7330 }
7331 const input = renderInputType[params.input](inputContainer, params);
7332 show(inputContainer);
7333
7334 // input autofocus
7335 if (params.inputAutoFocus) {
7336 setTimeout(() => {
7337 focusInput(input);
7338 });
7339 }
7340 };
7341
7342 /**
7343 * @param {HTMLInputElement} input
7344 */
7345 const removeAttributes = input => {
7346 for (const {
7347 name
7348 } of Array.from(input.attributes)) {
7349 if (!['id', 'type', 'value', 'style'].includes(name)) {
7350 input.removeAttribute(name);
7351 }
7352 }
7353 };
7354
7355 /**
7356 * @param {InputClass} inputClass
7357 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
7358 */
7359 const setAttributes = (inputClass, inputAttributes) => {
7360 const popup = getPopup();
7361 if (!popup) {
7362 return;
7363 }
7364 const input = getInput$1(popup, inputClass);
7365 if (!input) {
7366 return;
7367 }
7368 removeAttributes(input);
7369 for (const attr in inputAttributes) {
7370 input.setAttribute(attr, inputAttributes[attr]);
7371 }
7372 };
7373
7374 /**
7375 * @param {SweetAlertOptions} params
7376 */
7377 const setCustomClass = params => {
7378 if (!params.input) {
7379 return;
7380 }
7381 const inputContainer = getInputContainer(params.input);
7382 if (inputContainer) {
7383 applyCustomClass(inputContainer, params, 'input');
7384 }
7385 };
7386
7387 /**
7388 * @param {HTMLInputElement | HTMLTextAreaElement} input
7389 * @param {SweetAlertOptions} params
7390 */
7391 const setInputPlaceholder = (input, params) => {
7392 if (!input.placeholder && params.inputPlaceholder) {
7393 input.placeholder = params.inputPlaceholder;
7394 }
7395 };
7396
7397 /**
7398 * @param {Input} input
7399 * @param {Input} prependTo
7400 * @param {SweetAlertOptions} params
7401 */
7402 const setInputLabel = (input, prependTo, params) => {
7403 if (params.inputLabel) {
7404 const label = document.createElement('label');
7405 const labelClass = swalClasses['input-label'];
7406 label.setAttribute('for', input.id);
7407 label.className = labelClass;
7408 if (typeof params.customClass === 'object') {
7409 addClass(label, params.customClass.inputLabel);
7410 }
7411 label.innerText = params.inputLabel;
7412 prependTo.insertAdjacentElement('beforebegin', label);
7413 }
7414 };
7415
7416 /**
7417 * @param {SweetAlertInput} inputType
7418 * @returns {HTMLElement | undefined}
7419 */
7420 const getInputContainer = inputType => {
7421 const popup = getPopup();
7422 if (!popup) {
7423 return;
7424 }
7425 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7426 };
7427
7428 /**
7429 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7430 * @param {SweetAlertOptions['inputValue']} inputValue
7431 */
7432 const checkAndSetInputValue = (input, inputValue) => {
7433 if (['string', 'number'].includes(typeof inputValue)) {
7434 input.value = `${inputValue}`;
7435 } else if (!isPromise(inputValue)) {
7436 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7437 }
7438 };
7439
7440 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7441 const renderInputType = {};
7442
7443 /**
7444 * @param {Input | HTMLElement} input
7445 * @param {SweetAlertOptions} params
7446 * @returns {Input}
7447 */
7448 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} */
7449 (input, params) => {
7450 // oxfmt-ignore
7451 const inputElement = /** @type {HTMLInputElement} */input;
7452 checkAndSetInputValue(inputElement, params.inputValue);
7453 setInputLabel(inputElement, inputElement, params);
7454 setInputPlaceholder(inputElement, params);
7455 // oxfmt-ignore
7456 inputElement.type = /** @type {string} */params.input;
7457 return inputElement;
7458 };
7459
7460 /**
7461 * @param {Input | HTMLElement} input
7462 * @param {SweetAlertOptions} params
7463 * @returns {Input}
7464 */
7465 renderInputType.file = (input, params) => {
7466 const inputElement = /** @type {HTMLInputElement} */input;
7467 setInputLabel(inputElement, inputElement, params);
7468 setInputPlaceholder(inputElement, params);
7469 return inputElement;
7470 };
7471
7472 /**
7473 * @param {Input | HTMLElement} range
7474 * @param {SweetAlertOptions} params
7475 * @returns {Input}
7476 */
7477 renderInputType.range = (range, params) => {
7478 const rangeContainer = /** @type {HTMLElement} */range;
7479 const rangeInput = rangeContainer.querySelector('input');
7480 const rangeOutput = rangeContainer.querySelector('output');
7481 if (rangeInput) {
7482 checkAndSetInputValue(rangeInput, params.inputValue);
7483 rangeInput.type = /** @type {string} */params.input;
7484 setInputLabel(rangeInput, /** @type {Input} */range, params);
7485 }
7486 if (rangeOutput) {
7487 checkAndSetInputValue(rangeOutput, params.inputValue);
7488 }
7489 return /** @type {Input} */range;
7490 };
7491
7492 /**
7493 * @param {Input | HTMLElement} select
7494 * @param {SweetAlertOptions} params
7495 * @returns {Input}
7496 */
7497 renderInputType.select = (select, params) => {
7498 const selectElement = /** @type {HTMLSelectElement} */select;
7499 selectElement.textContent = '';
7500 if (params.inputPlaceholder) {
7501 const placeholder = document.createElement('option');
7502 setInnerHtml(placeholder, params.inputPlaceholder);
7503 placeholder.value = '';
7504 placeholder.disabled = true;
7505 placeholder.selected = true;
7506 selectElement.appendChild(placeholder);
7507 }
7508 setInputLabel(selectElement, selectElement, params);
7509 return selectElement;
7510 };
7511
7512 /**
7513 * @param {Input | HTMLElement} radio
7514 * @returns {Input}
7515 */
7516 renderInputType.radio = radio => {
7517 const radioElement = /** @type {HTMLElement} */radio;
7518 radioElement.textContent = '';
7519 return /** @type {Input} */radio;
7520 };
7521
7522 /**
7523 * @param {Input | HTMLElement} checkboxContainer
7524 * @param {SweetAlertOptions} params
7525 * @returns {Input}
7526 */
7527 renderInputType.checkbox = (checkboxContainer, params) => {
7528 const popup = getPopup();
7529 if (!popup) {
7530 throw new Error('Popup not found');
7531 }
7532 const checkbox = getInput$1(popup, 'checkbox');
7533 if (!checkbox) {
7534 throw new Error('Checkbox input not found');
7535 }
7536 checkbox.value = '1';
7537 checkbox.checked = Boolean(params.inputValue);
7538 const containerElement = /** @type {HTMLElement} */checkboxContainer;
7539 const label = containerElement.querySelector('span');
7540 if (label) {
7541 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
7542 if (placeholderOrLabel) {
7543 setInnerHtml(label, placeholderOrLabel);
7544 }
7545 }
7546 return checkbox;
7547 };
7548
7549 /**
7550 * @param {Input | HTMLElement} textarea
7551 * @param {SweetAlertOptions} params
7552 * @returns {Input}
7553 */
7554 renderInputType.textarea = (textarea, params) => {
7555 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
7556 checkAndSetInputValue(textareaElement, params.inputValue);
7557 setInputPlaceholder(textareaElement, params);
7558 setInputLabel(textareaElement, textareaElement, params);
7559
7560 /**
7561 * @param {HTMLElement} el
7562 * @returns {number}
7563 */
7564 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7565
7566 // https://github.com/sweetalert2/sweetalert2/issues/2291
7567 setTimeout(() => {
7568 // https://github.com/sweetalert2/sweetalert2/issues/1699
7569 if ('MutationObserver' in window) {
7570 const popup = getPopup();
7571 if (!popup) {
7572 return;
7573 }
7574 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
7575 const textareaResizeHandler = () => {
7576 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7577 if (!document.body.contains(textareaElement)) {
7578 return;
7579 }
7580 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
7581 const popupElement = getPopup();
7582 if (popupElement) {
7583 if (textareaWidth > initialPopupWidth) {
7584 popupElement.style.width = `${textareaWidth}px`;
7585 } else {
7586 applyNumericalStyle(popupElement, 'width', params.width);
7587 }
7588 }
7589 };
7590 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
7591 attributes: true,
7592 attributeFilter: ['style']
7593 });
7594 }
7595 });
7596 return textareaElement;
7597 };
7598
7599 /**
7600 * @param {SweetAlert} instance
7601 * @param {SweetAlertOptions} params
7602 */
7603 const renderContent = (instance, params) => {
7604 const htmlContainer = getHtmlContainer();
7605 if (!htmlContainer) {
7606 return;
7607 }
7608 showWhenInnerHtmlPresent(htmlContainer);
7609 applyCustomClass(htmlContainer, params, 'htmlContainer');
7610
7611 // Content as HTML
7612 if (params.html) {
7613 parseHtmlToContainer(params.html, htmlContainer);
7614 show(htmlContainer, 'block');
7615 }
7616
7617 // Content as plain text
7618 else if (params.text) {
7619 htmlContainer.textContent = params.text;
7620 show(htmlContainer, 'block');
7621 }
7622
7623 // No content
7624 else {
7625 hide(htmlContainer);
7626 }
7627 renderInput(instance, params);
7628 };
7629
7630 /**
7631 * @param {SweetAlert} instance
7632 * @param {SweetAlertOptions} params
7633 */
7634 const renderFooter = (instance, params) => {
7635 const footer = getFooter();
7636 if (!footer) {
7637 return;
7638 }
7639 showWhenInnerHtmlPresent(footer);
7640 toggle(footer, Boolean(params.footer), 'block');
7641 if (params.footer) {
7642 parseHtmlToContainer(params.footer, footer);
7643 }
7644
7645 // Custom class
7646 applyCustomClass(footer, params, 'footer');
7647 };
7648
7649 /**
7650 * @param {SweetAlert} instance
7651 * @param {SweetAlertOptions} params
7652 */
7653 const renderIcon = (instance, params) => {
7654 const innerParams = privateProps.innerParams.get(instance);
7655 const icon = getIcon();
7656 if (!icon) {
7657 return;
7658 }
7659
7660 // if the given icon already rendered, apply the styling without re-rendering the icon
7661 if (innerParams && params.icon === innerParams.icon) {
7662 // Custom or default content
7663 setContent(icon, params);
7664 applyStyles(icon, params);
7665 return;
7666 }
7667 if (!params.icon && !params.iconHtml) {
7668 hide(icon);
7669 return;
7670 }
7671 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7672 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7673 hide(icon);
7674 return;
7675 }
7676 show(icon);
7677
7678 // Custom or default content
7679 setContent(icon, params);
7680 applyStyles(icon, params);
7681
7682 // Animate icon
7683 addClass(icon, params.showClass && params.showClass.icon);
7684
7685 // Re-adjust the success icon on system theme change
7686 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7687 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7688 };
7689
7690 /**
7691 * @param {HTMLElement} icon
7692 * @param {SweetAlertOptions} params
7693 */
7694 const applyStyles = (icon, params) => {
7695 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7696 if (params.icon !== iconType) {
7697 removeClass(icon, iconClassName);
7698 }
7699 }
7700 addClass(icon, params.icon && iconTypes[params.icon]);
7701
7702 // Icon color
7703 setColor(icon, params);
7704
7705 // Success icon background color
7706 adjustSuccessIconBackgroundColor();
7707
7708 // Custom class
7709 applyCustomClass(icon, params, 'icon');
7710 };
7711
7712 // Adjust success icon background color to match the popup background color
7713 const adjustSuccessIconBackgroundColor = () => {
7714 const popup = getPopup();
7715 if (!popup) {
7716 return;
7717 }
7718 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7719 /** @type {NodeListOf<HTMLElement>} */
7720 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7721 successIconParts.forEach(part => {
7722 part.style.backgroundColor = popupBackgroundColor;
7723 });
7724 };
7725
7726 /**
7727 *
7728 * @param {SweetAlertOptions} params
7729 * @returns {string}
7730 */
7731 const successIconHtml = params => `
7732 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7733 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7734 <div class="swal2-success-ring"></div>
7735 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7736 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7737 `;
7738 const errorIconHtml = `
7739 <span class="swal2-x-mark">
7740 <span class="swal2-x-mark-line-left"></span>
7741 <span class="swal2-x-mark-line-right"></span>
7742 </span>
7743 `;
7744
7745 /**
7746 * @param {HTMLElement} icon
7747 * @param {SweetAlertOptions} params
7748 */
7749 const setContent = (icon, params) => {
7750 if (!params.icon && !params.iconHtml) {
7751 return;
7752 }
7753 let oldContent = icon.innerHTML;
7754 let newContent = '';
7755 if (params.iconHtml) {
7756 newContent = iconContent(params.iconHtml);
7757 } else if (params.icon === 'success') {
7758 newContent = successIconHtml(params);
7759 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7760 } else if (params.icon === 'error') {
7761 newContent = errorIconHtml;
7762 } else if (params.icon) {
7763 const defaultIconHtml = {
7764 question: '?',
7765 warning: '!',
7766 info: 'i'
7767 };
7768 newContent = iconContent(defaultIconHtml[params.icon]);
7769 }
7770 if (oldContent.trim() !== newContent.trim()) {
7771 setInnerHtml(icon, newContent);
7772 }
7773 };
7774
7775 /**
7776 * @param {HTMLElement} icon
7777 * @param {SweetAlertOptions} params
7778 */
7779 const setColor = (icon, params) => {
7780 if (!params.iconColor) {
7781 return;
7782 }
7783 icon.style.color = params.iconColor;
7784 icon.style.borderColor = params.iconColor;
7785 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7786 setStyle(icon, sel, 'background-color', params.iconColor);
7787 }
7788 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7789 };
7790
7791 /**
7792 * @param {string} content
7793 * @returns {string}
7794 */
7795 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7796
7797 /**
7798 * @param {SweetAlert} instance
7799 * @param {SweetAlertOptions} params
7800 */
7801 const renderImage = (instance, params) => {
7802 const image = getImage();
7803 if (!image) {
7804 return;
7805 }
7806 if (!params.imageUrl) {
7807 hide(image);
7808 return;
7809 }
7810 show(image, '');
7811
7812 // Src, alt
7813 image.setAttribute('src', params.imageUrl);
7814 image.setAttribute('alt', params.imageAlt || '');
7815
7816 // Width, height
7817 applyNumericalStyle(image, 'width', params.imageWidth);
7818 applyNumericalStyle(image, 'height', params.imageHeight);
7819
7820 // Class
7821 image.className = swalClasses.image;
7822 applyCustomClass(image, params, 'image');
7823 };
7824
7825 let dragging = false;
7826 let mousedownX = 0;
7827 let mousedownY = 0;
7828 let initialX = 0;
7829 let initialY = 0;
7830
7831 /**
7832 * @param {HTMLElement} popup
7833 */
7834 const addDraggableListeners = popup => {
7835 popup.addEventListener('mousedown', down);
7836 document.body.addEventListener('mousemove', move);
7837 popup.addEventListener('mouseup', up);
7838 popup.addEventListener('touchstart', down);
7839 document.body.addEventListener('touchmove', move);
7840 popup.addEventListener('touchend', up);
7841 };
7842
7843 /**
7844 * @param {HTMLElement} popup
7845 */
7846 const removeDraggableListeners = popup => {
7847 popup.removeEventListener('mousedown', down);
7848 document.body.removeEventListener('mousemove', move);
7849 popup.removeEventListener('mouseup', up);
7850 popup.removeEventListener('touchstart', down);
7851 document.body.removeEventListener('touchmove', move);
7852 popup.removeEventListener('touchend', up);
7853 };
7854
7855 /**
7856 * @param {MouseEvent | TouchEvent} event
7857 */
7858 const down = event => {
7859 const popup = getPopup();
7860 if (!popup) {
7861 return;
7862 }
7863 const icon = getIcon();
7864 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
7865 dragging = true;
7866 const clientXY = getClientXY(event);
7867 mousedownX = clientXY.clientX;
7868 mousedownY = clientXY.clientY;
7869 initialX = parseInt(popup.style.insetInlineStart) || 0;
7870 initialY = parseInt(popup.style.insetBlockStart) || 0;
7871 addClass(popup, 'swal2-dragging');
7872 }
7873 };
7874
7875 /**
7876 * @param {MouseEvent | TouchEvent} event
7877 */
7878 const move = event => {
7879 const popup = getPopup();
7880 if (!popup) {
7881 return;
7882 }
7883 if (dragging) {
7884 let {
7885 clientX,
7886 clientY
7887 } = getClientXY(event);
7888 const deltaX = clientX - mousedownX;
7889 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
7890 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
7891 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7892 }
7893 };
7894 const up = () => {
7895 const popup = getPopup();
7896 dragging = false;
7897 removeClass(popup, 'swal2-dragging');
7898 };
7899
7900 /**
7901 * @param {MouseEvent | TouchEvent} event
7902 * @returns {{ clientX: number, clientY: number }}
7903 */
7904 const getClientXY = event => {
7905 const source = event.type.startsWith('touch') ? /** @type {TouchEvent} */event.touches[0] : (/** @type {MouseEvent} */event);
7906 return {
7907 clientX: source.clientX,
7908 clientY: source.clientY
7909 };
7910 };
7911
7912 /**
7913 * @param {SweetAlert} instance
7914 * @param {SweetAlertOptions} params
7915 */
7916 const renderPopup = (instance, params) => {
7917 const container = getContainer();
7918 const popup = getPopup();
7919 if (!container || !popup) {
7920 return;
7921 }
7922
7923 // Width
7924 // https://github.com/sweetalert2/sweetalert2/issues/2170
7925 if (params.toast) {
7926 applyNumericalStyle(container, 'width', params.width);
7927 popup.style.width = '100%';
7928 const loader = getLoader();
7929 if (loader) {
7930 popup.insertBefore(loader, getIcon());
7931 }
7932 } else {
7933 applyNumericalStyle(popup, 'width', params.width);
7934 }
7935
7936 // Padding
7937 applyNumericalStyle(popup, 'padding', params.padding);
7938
7939 // Color
7940 if (params.color) {
7941 popup.style.color = params.color;
7942 }
7943
7944 // Background
7945 if (params.background) {
7946 popup.style.background = params.background;
7947 }
7948 hide(getValidationMessage());
7949
7950 // Classes
7951 addClasses$1(popup, params);
7952 if (params.draggable && !params.toast) {
7953 addClass(popup, swalClasses.draggable);
7954 addDraggableListeners(popup);
7955 } else {
7956 removeClass(popup, swalClasses.draggable);
7957 removeDraggableListeners(popup);
7958 }
7959 };
7960
7961 /**
7962 * @param {HTMLElement} popup
7963 * @param {SweetAlertOptions} params
7964 */
7965 const addClasses$1 = (popup, params) => {
7966 const showClass = params.showClass || {};
7967 // Default Class + showClass when updating Swal.update({})
7968 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7969 if (params.toast) {
7970 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7971 addClass(popup, swalClasses.toast);
7972 } else {
7973 addClass(popup, swalClasses.modal);
7974 }
7975
7976 // Custom class
7977 applyCustomClass(popup, params, 'popup');
7978 // TODO: remove in the next major
7979 if (typeof params.customClass === 'string') {
7980 addClass(popup, params.customClass);
7981 }
7982
7983 // Icon class (#1842)
7984 if (params.icon) {
7985 addClass(popup, swalClasses[`icon-${params.icon}`]);
7986 }
7987 };
7988
7989 /**
7990 * @param {SweetAlert} instance
7991 * @param {SweetAlertOptions} params
7992 */
7993 const renderProgressSteps = (instance, params) => {
7994 const progressStepsContainer = getProgressSteps();
7995 if (!progressStepsContainer) {
7996 return;
7997 }
7998 const {
7999 progressSteps,
8000 currentProgressStep
8001 } = params;
8002 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
8003 hide(progressStepsContainer);
8004 return;
8005 }
8006 show(progressStepsContainer);
8007 progressStepsContainer.textContent = '';
8008 if (currentProgressStep >= progressSteps.length) {
8009 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
8010 }
8011 progressSteps.forEach((step, index) => {
8012 const stepEl = createStepElement(step);
8013 progressStepsContainer.appendChild(stepEl);
8014 if (index === currentProgressStep) {
8015 addClass(stepEl, swalClasses['active-progress-step']);
8016 }
8017 if (index !== progressSteps.length - 1) {
8018 const lineEl = createLineElement(params);
8019 progressStepsContainer.appendChild(lineEl);
8020 }
8021 });
8022 };
8023
8024 /**
8025 * @param {string} step
8026 * @returns {HTMLLIElement}
8027 */
8028 const createStepElement = step => {
8029 const stepEl = document.createElement('li');
8030 addClass(stepEl, swalClasses['progress-step']);
8031 setInnerHtml(stepEl, step);
8032 return stepEl;
8033 };
8034
8035 /**
8036 * @param {SweetAlertOptions} params
8037 * @returns {HTMLLIElement}
8038 */
8039 const createLineElement = params => {
8040 const lineEl = document.createElement('li');
8041 addClass(lineEl, swalClasses['progress-step-line']);
8042 if (params.progressStepsDistance) {
8043 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
8044 }
8045 return lineEl;
8046 };
8047
8048 /**
8049 * @param {SweetAlert} instance
8050 * @param {SweetAlertOptions} params
8051 */
8052 const renderTitle = (instance, params) => {
8053 const title = getTitle();
8054 if (!title) {
8055 return;
8056 }
8057 showWhenInnerHtmlPresent(title);
8058 toggle(title, Boolean(params.title || params.titleText), 'block');
8059 if (params.title) {
8060 parseHtmlToContainer(params.title, title);
8061 }
8062 if (params.titleText) {
8063 title.innerText = params.titleText;
8064 }
8065
8066 // Custom class
8067 applyCustomClass(title, params, 'title');
8068 };
8069
8070 /**
8071 * @param {SweetAlert} instance
8072 * @param {SweetAlertOptions} params
8073 */
8074 const render = (instance, params) => {
8075 var _globalState$eventEmi;
8076 renderPopup(instance, params);
8077 renderContainer(instance, params);
8078 renderProgressSteps(instance, params);
8079 renderIcon(instance, params);
8080 renderImage(instance, params);
8081 renderTitle(instance, params);
8082 renderCloseButton(instance, params);
8083 renderContent(instance, params);
8084 renderActions(instance, params);
8085 renderFooter(instance, params);
8086 const popup = getPopup();
8087 if (typeof params.didRender === 'function' && popup) {
8088 params.didRender(popup);
8089 }
8090 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
8091 };
8092
8093 /*
8094 * Global function to determine if SweetAlert2 popup is shown
8095 */
8096 const isVisible = () => {
8097 return isVisible$1(getPopup());
8098 };
8099
8100 /*
8101 * Global function to click 'Confirm' button
8102 */
8103 const clickConfirm = () => {
8104 var _dom$getConfirmButton;
8105 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
8106 };
8107
8108 /*
8109 * Global function to click 'Deny' button
8110 */
8111 const clickDeny = () => {
8112 var _dom$getDenyButton;
8113 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
8114 };
8115
8116 /*
8117 * Global function to click 'Cancel' button
8118 */
8119 const clickCancel = () => {
8120 var _dom$getCancelButton;
8121 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
8122 };
8123
8124 /** @type {Record<DismissReason, DismissReason>} */
8125 const DismissReason = Object.freeze({
8126 cancel: 'cancel',
8127 backdrop: 'backdrop',
8128 close: 'close',
8129 esc: 'esc',
8130 timer: 'timer'
8131 });
8132
8133 /**
8134 * @param {GlobalState} globalState
8135 */
8136 const removeKeydownHandler = globalState => {
8137 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
8138 const handler = /** @type {EventListenerOrEventListenerObject} */
8139 /** @type {unknown} */globalState.keydownHandler;
8140 globalState.keydownTarget.removeEventListener('keydown', handler, {
8141 capture: globalState.keydownListenerCapture
8142 });
8143 globalState.keydownHandlerAdded = false;
8144 }
8145 };
8146
8147 /**
8148 * @param {GlobalState} globalState
8149 * @param {SweetAlertOptions} innerParams
8150 * @param {(dismiss: DismissReason) => void} dismissWith
8151 */
8152 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
8153 removeKeydownHandler(globalState);
8154 if (!innerParams.toast) {
8155 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
8156 const handler = e => keydownHandler(innerParams, e, dismissWith);
8157 globalState.keydownHandler = handler;
8158 const target = innerParams.keydownListenerCapture ? window : getPopup();
8159 if (target) {
8160 globalState.keydownTarget = target;
8161 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
8162 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
8163 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
8164 capture: globalState.keydownListenerCapture
8165 });
8166 globalState.keydownHandlerAdded = true;
8167 }
8168 }
8169 };
8170
8171 /**
8172 * @param {number} index
8173 * @param {number} increment
8174 * @returns {boolean} shouldPreventDefault
8175 */
8176 const setFocus = (index, increment) => {
8177 var _dom$getPopup;
8178 const focusableElements = getFocusableElements();
8179 // search for visible elements and select the next possible match
8180 if (focusableElements.length) {
8181 index = index + increment;
8182
8183 // shift + tab when .swal2-popup is focused
8184 if (index === -2) {
8185 index = focusableElements.length - 1;
8186 }
8187
8188 // rollover to first item
8189 if (index === focusableElements.length) {
8190 index = 0;
8191
8192 // go to last item
8193 } else if (index === -1) {
8194 index = focusableElements.length - 1;
8195 }
8196 focusableElements[index].focus();
8197
8198 // don't prevent default for iframes (Firefox fix)
8199 // https://github.com/sweetalert2/sweetalert2/issues/2931
8200 if (isFirefox() && focusableElements[index] instanceof HTMLIFrameElement) {
8201 return false;
8202 }
8203 return true;
8204 }
8205 // no visible focusable elements, focus the popup
8206 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
8207 return true;
8208 };
8209 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
8210 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
8211
8212 /**
8213 * @param {SweetAlertOptions} innerParams
8214 * @param {KeyboardEvent} event
8215 * @param {(dismiss: DismissReason) => void} dismissWith
8216 */
8217 const keydownHandler = (innerParams, event, dismissWith) => {
8218 if (!innerParams) {
8219 return; // This instance has already been destroyed
8220 }
8221
8222 // Ignore keydown during IME composition
8223 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
8224 // https://github.com/sweetalert2/sweetalert2/issues/720
8225 // https://github.com/sweetalert2/sweetalert2/issues/2406
8226 if (event.isComposing || event.keyCode === 229) {
8227 return;
8228 }
8229 if (innerParams.stopKeydownPropagation) {
8230 event.stopPropagation();
8231 }
8232
8233 // ENTER
8234 if (event.key === 'Enter') {
8235 handleEnter(event, innerParams);
8236 }
8237
8238 // TAB
8239 else if (event.key === 'Tab') {
8240 handleTab(event);
8241 }
8242
8243 // ARROWS - switch focus between buttons
8244 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
8245 handleArrows(event.key);
8246 }
8247
8248 // ESC
8249 else if (event.key === 'Escape') {
8250 handleEsc(event, innerParams, dismissWith);
8251 }
8252 };
8253
8254 /**
8255 * @param {KeyboardEvent} event
8256 * @param {SweetAlertOptions} innerParams
8257 */
8258 const handleEnter = (event, innerParams) => {
8259 // https://github.com/sweetalert2/sweetalert2/issues/2386
8260 if (!callIfFunction(innerParams.allowEnterKey)) {
8261 return;
8262 }
8263 const popup = getPopup();
8264 if (!popup || !innerParams.input) {
8265 return;
8266 }
8267 const input = getInput$1(popup, innerParams.input);
8268 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
8269 if (['textarea', 'file'].includes(innerParams.input)) {
8270 return; // do not submit
8271 }
8272 clickConfirm();
8273 event.preventDefault();
8274 }
8275 };
8276
8277 /**
8278 * @param {KeyboardEvent} event
8279 */
8280 const handleTab = event => {
8281 const targetElement = event.target;
8282 const focusableElements = getFocusableElements();
8283 const btnIndex = focusableElements.findIndex(el => el === targetElement);
8284
8285 // don't prevent default for iframes (Firefox fix)
8286 // https://github.com/sweetalert2/sweetalert2/issues/2931
8287 let shouldPreventDefault = true;
8288
8289 // Cycle to the next button
8290 if (!event.shiftKey) {
8291 shouldPreventDefault = setFocus(btnIndex, 1);
8292 }
8293
8294 // Cycle to the prev button
8295 else {
8296 shouldPreventDefault = setFocus(btnIndex, -1);
8297 }
8298 event.stopPropagation();
8299 if (shouldPreventDefault) {
8300 event.preventDefault();
8301 }
8302 };
8303
8304 /**
8305 * @param {string} key
8306 */
8307 const handleArrows = key => {
8308 const actions = getActions();
8309 const confirmButton = getConfirmButton();
8310 const denyButton = getDenyButton();
8311 const cancelButton = getCancelButton();
8312 if (!actions || !confirmButton || !denyButton || !cancelButton) {
8313 return;
8314 }
8315 /** @type HTMLElement[] */
8316 const buttons = [confirmButton, denyButton, cancelButton];
8317 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
8318 return;
8319 }
8320 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
8321 let buttonToFocus = document.activeElement;
8322 if (!buttonToFocus) {
8323 return;
8324 }
8325 for (let i = 0; i < actions.children.length; i++) {
8326 buttonToFocus = buttonToFocus[sibling];
8327 if (!buttonToFocus) {
8328 return;
8329 }
8330 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
8331 break;
8332 }
8333 }
8334 if (buttonToFocus instanceof HTMLButtonElement) {
8335 buttonToFocus.focus();
8336 }
8337 };
8338
8339 /**
8340 * @param {KeyboardEvent} event
8341 * @param {SweetAlertOptions} innerParams
8342 * @param {(dismiss: DismissReason) => void} dismissWith
8343 */
8344 const handleEsc = (event, innerParams, dismissWith) => {
8345 event.preventDefault();
8346 if (callIfFunction(innerParams.allowEscapeKey)) {
8347 dismissWith(DismissReason.esc);
8348 }
8349 };
8350
8351 /**
8352 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8353 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8354 * This is the approach that Babel will probably take to implement private methods/fields
8355 * https://github.com/tc39/proposal-private-methods
8356 * https://github.com/babel/babel/pull/7555
8357 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8358 * then we can use that language feature.
8359 */
8360
8361 var privateMethods = {
8362 swalPromiseResolve: new WeakMap(),
8363 swalPromiseReject: new WeakMap()
8364 };
8365
8366 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
8367 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
8368 // elements not within the active modal dialog will not be surfaced if a user opens a screen
8369 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
8370
8371 const setAriaHidden = () => {
8372 const container = getContainer();
8373 const bodyChildren = Array.from(document.body.children);
8374 bodyChildren.forEach(el => {
8375 if (el.contains(container)) {
8376 return;
8377 }
8378 if (el.hasAttribute('aria-hidden')) {
8379 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
8380 }
8381 el.setAttribute('aria-hidden', 'true');
8382 });
8383 };
8384 const unsetAriaHidden = () => {
8385 const bodyChildren = Array.from(document.body.children);
8386 bodyChildren.forEach(el => {
8387 if (el.hasAttribute('data-previous-aria-hidden')) {
8388 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
8389 el.removeAttribute('data-previous-aria-hidden');
8390 } else {
8391 el.removeAttribute('aria-hidden');
8392 }
8393 });
8394 };
8395
8396 // @ts-ignore
8397 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
8398
8399 // @ts-ignore
8400 const isIOS = isSafariOrIOS && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
8401
8402 /**
8403 * Fix iOS scrolling
8404 * http://stackoverflow.com/q/39626302
8405 */
8406 const iOSfix = () => {
8407 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
8408 const offset = document.body.scrollTop;
8409 document.body.style.top = `${offset * -1}px`;
8410 addClass(document.body, swalClasses.iosfix);
8411 lockBodyScroll();
8412 }
8413 };
8414
8415 /**
8416 * https://github.com/sweetalert2/sweetalert2/issues/1246
8417 */
8418 const lockBodyScroll = () => {
8419 const container = getContainer();
8420 if (!container) {
8421 return;
8422 }
8423 /** @type {boolean} */
8424 let preventTouchMove;
8425 /**
8426 * @param {TouchEvent} event
8427 */
8428 container.ontouchstart = event => {
8429 preventTouchMove = shouldPreventTouchMove(event);
8430 };
8431 /**
8432 * @param {TouchEvent} event
8433 */
8434 container.ontouchmove = event => {
8435 if (preventTouchMove) {
8436 event.preventDefault();
8437 event.stopPropagation();
8438 }
8439 };
8440 };
8441
8442 /**
8443 * @param {TouchEvent} event
8444 * @returns {boolean}
8445 */
8446 const shouldPreventTouchMove = event => {
8447 const target = event.target;
8448 const container = getContainer();
8449 const htmlContainer = getHtmlContainer();
8450 if (!container || !htmlContainer) {
8451 return false;
8452 }
8453 if (isStylus(event) || isZoom(event)) {
8454 return false;
8455 }
8456 if (target === container) {
8457 return true;
8458 }
8459 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8460 // #2823
8461 target.tagName !== 'INPUT' &&
8462 // #1603
8463 target.tagName !== 'TEXTAREA' &&
8464 // #2266
8465 !(isScrollable(htmlContainer) &&
8466 // #1944
8467 htmlContainer.contains(target))) {
8468 return true;
8469 }
8470 return false;
8471 };
8472
8473 /**
8474 * https://github.com/sweetalert2/sweetalert2/issues/1786
8475 *
8476 * @param {TouchEvent} event
8477 * @returns {boolean}
8478 */
8479 const isStylus = event => {
8480 return Boolean(event.touches && event.touches.length &&
8481 // @ts-ignore - touchType is not a standard property
8482 event.touches[0].touchType === 'stylus');
8483 };
8484
8485 /**
8486 * https://github.com/sweetalert2/sweetalert2/issues/1891
8487 *
8488 * @param {TouchEvent} event
8489 * @returns {boolean}
8490 */
8491 const isZoom = event => {
8492 return event.touches && event.touches.length > 1;
8493 };
8494 const undoIOSfix = () => {
8495 if (hasClass(document.body, swalClasses.iosfix)) {
8496 const offset = parseInt(document.body.style.top, 10);
8497 removeClass(document.body, swalClasses.iosfix);
8498 document.body.style.top = '';
8499 document.body.scrollTop = offset * -1;
8500 }
8501 };
8502
8503 /**
8504 * Measure scrollbar width for padding body during modal show/hide
8505 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8506 *
8507 * @returns {number}
8508 */
8509 const measureScrollbar = () => {
8510 const scrollDiv = document.createElement('div');
8511 scrollDiv.className = swalClasses['scrollbar-measure'];
8512 document.body.appendChild(scrollDiv);
8513 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8514 document.body.removeChild(scrollDiv);
8515 return scrollbarWidth;
8516 };
8517
8518 /**
8519 * Remember state in cases where opening and handling a modal will fiddle with it.
8520 * @type {number | null}
8521 */
8522 let previousBodyPadding = null;
8523
8524 /**
8525 * @param {string} initialBodyOverflow
8526 */
8527 const replaceScrollbarWithPadding = initialBodyOverflow => {
8528 // for queues, do not do this more than once
8529 if (previousBodyPadding !== null) {
8530 return;
8531 }
8532 // if the body has overflow
8533 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8534 ) {
8535 // add padding so the content doesn't shift after removal of scrollbar
8536 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8537 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8538 }
8539 };
8540 const undoReplaceScrollbarWithPadding = () => {
8541 if (previousBodyPadding !== null) {
8542 document.body.style.paddingRight = `${previousBodyPadding}px`;
8543 previousBodyPadding = null;
8544 }
8545 };
8546
8547 /**
8548 * @param {SweetAlert} instance
8549 * @param {HTMLElement} container
8550 * @param {boolean} returnFocus
8551 * @param {(() => void) | undefined} didClose
8552 */
8553 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8554 if (isToast()) {
8555 triggerDidCloseAndDispose(instance, didClose);
8556 } else {
8557 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8558 removeKeydownHandler(globalState);
8559 }
8560
8561 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8562 // for some reason removing the container in Safari will scroll the document to bottom
8563 if (isSafariOrIOS) {
8564 container.setAttribute('style', 'display:none !important');
8565 container.removeAttribute('class');
8566 container.innerHTML = '';
8567 } else {
8568 container.remove();
8569 }
8570 if (isModal()) {
8571 undoReplaceScrollbarWithPadding();
8572 undoIOSfix();
8573 unsetAriaHidden();
8574 }
8575 removeBodyClasses();
8576 }
8577
8578 /**
8579 * Remove SweetAlert2 classes from body
8580 */
8581 function removeBodyClasses() {
8582 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8583 }
8584
8585 /**
8586 * Instance method to close sweetAlert
8587 *
8588 * @param {SweetAlertResult | undefined} resolveValue
8589 * @this {SweetAlert}
8590 */
8591 function close(resolveValue) {
8592 resolveValue = prepareResolveValue(resolveValue);
8593 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8594 const didClose = triggerClosePopup(this);
8595 if (this.isAwaitingPromise) {
8596 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8597 if (!resolveValue.isDismissed) {
8598 handleAwaitingPromise(this);
8599 swalPromiseResolve(resolveValue);
8600 }
8601 } else if (didClose) {
8602 // Resolve Swal promise
8603 swalPromiseResolve(resolveValue);
8604 }
8605 }
8606
8607 /**
8608 * @param {SweetAlert} instance
8609 * @returns {boolean}
8610 */
8611 const triggerClosePopup = instance => {
8612 const popup = getPopup();
8613 if (!popup) {
8614 return false;
8615 }
8616 const innerParams = privateProps.innerParams.get(instance);
8617 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8618 return false;
8619 }
8620 removeClass(popup, innerParams.showClass.popup);
8621 addClass(popup, innerParams.hideClass.popup);
8622 const backdrop = getContainer();
8623 removeClass(backdrop, innerParams.showClass.backdrop);
8624 addClass(backdrop, innerParams.hideClass.backdrop);
8625 handlePopupAnimation(instance, popup, innerParams);
8626 return true;
8627 };
8628
8629 /**
8630 * @param {Error | string} error
8631 * @this {SweetAlert}
8632 */
8633 function rejectPromise(error) {
8634 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8635 handleAwaitingPromise(this);
8636 if (rejectPromise) {
8637 // Reject Swal promise
8638 rejectPromise(error);
8639 }
8640 }
8641
8642 /**
8643 * @param {SweetAlert} instance
8644 */
8645 const handleAwaitingPromise = instance => {
8646 if (instance.isAwaitingPromise) {
8647 // @ts-ignore
8648 delete instance.isAwaitingPromise;
8649 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8650 if (!privateProps.innerParams.get(instance)) {
8651 instance._destroy();
8652 }
8653 }
8654 };
8655
8656 /**
8657 * @param {SweetAlertResult | undefined} resolveValue
8658 * @returns {SweetAlertResult}
8659 */
8660 const prepareResolveValue = resolveValue => {
8661 // When user calls Swal.close()
8662 if (typeof resolveValue === 'undefined') {
8663 return {
8664 isConfirmed: false,
8665 isDenied: false,
8666 isDismissed: true
8667 };
8668 }
8669 return Object.assign({
8670 isConfirmed: false,
8671 isDenied: false,
8672 isDismissed: false
8673 }, resolveValue);
8674 };
8675
8676 /**
8677 * @param {SweetAlert} instance
8678 * @param {HTMLElement} popup
8679 * @param {SweetAlertOptions} innerParams
8680 */
8681 const handlePopupAnimation = (instance, popup, innerParams) => {
8682 var _globalState$eventEmi;
8683 const container = getContainer();
8684 // If animation is supported, animate
8685 const animationIsSupported = hasCssAnimation(popup);
8686 if (typeof innerParams.willClose === 'function') {
8687 innerParams.willClose(popup);
8688 }
8689 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8690 if (animationIsSupported && container) {
8691 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8692 } else if (container) {
8693 // Otherwise, remove immediately
8694 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8695 }
8696 };
8697
8698 /**
8699 * @param {SweetAlert} instance
8700 * @param {HTMLElement} popup
8701 * @param {HTMLElement} container
8702 * @param {boolean} returnFocus
8703 * @param {(() => void) | undefined} didClose
8704 */
8705 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8706 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8707 /**
8708 * @param {AnimationEvent | TransitionEvent} e
8709 */
8710 const swalCloseAnimationFinished = function (e) {
8711 if (e.target === popup) {
8712 var _globalState$swalClos;
8713 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8714 delete globalState.swalCloseEventFinishedCallback;
8715 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8716 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8717 }
8718 };
8719 popup.addEventListener('animationend', swalCloseAnimationFinished);
8720 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8721 };
8722
8723 /**
8724 * @param {SweetAlert} instance
8725 * @param {(() => void) | undefined} didClose
8726 */
8727 const triggerDidCloseAndDispose = (instance, didClose) => {
8728 setTimeout(() => {
8729 var _globalState$eventEmi2;
8730 if (typeof didClose === 'function') {
8731 didClose.bind(instance.params)();
8732 }
8733 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8734 // instance might have been destroyed already
8735 if (instance._destroy) {
8736 instance._destroy();
8737 }
8738 });
8739 };
8740
8741 /**
8742 * Shows loader (spinner), this is useful with AJAX requests.
8743 * By default the loader be shown instead of the "Confirm" button.
8744 *
8745 * @param {HTMLButtonElement | null} [buttonToReplace]
8746 */
8747 const showLoading = buttonToReplace => {
8748 let popup = getPopup();
8749 if (!popup) {
8750 new Swal();
8751 }
8752 popup = getPopup();
8753 if (!popup) {
8754 return;
8755 }
8756 const loader = getLoader();
8757 if (isToast()) {
8758 hide(getIcon());
8759 } else {
8760 replaceButton(popup, buttonToReplace);
8761 }
8762 show(loader);
8763 popup.setAttribute('data-loading', 'true');
8764 popup.setAttribute('aria-busy', 'true');
8765 popup.focus();
8766 };
8767
8768 /**
8769 * @param {HTMLElement} popup
8770 * @param {HTMLButtonElement | null} [buttonToReplace]
8771 */
8772 const replaceButton = (popup, buttonToReplace) => {
8773 const actions = getActions();
8774 const loader = getLoader();
8775 if (!actions || !loader) {
8776 return;
8777 }
8778 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8779 buttonToReplace = getConfirmButton();
8780 }
8781 show(actions);
8782 if (buttonToReplace) {
8783 hide(buttonToReplace);
8784 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8785 actions.insertBefore(loader, buttonToReplace);
8786 }
8787 addClass([popup, actions], swalClasses.loading);
8788 };
8789
8790 /**
8791 * @param {SweetAlert} instance
8792 * @param {SweetAlertOptions} params
8793 */
8794 const handleInputOptionsAndValue = (instance, params) => {
8795 if (params.input === 'select' || params.input === 'radio') {
8796 handleInputOptions(instance, params);
8797 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8798 showLoading(getConfirmButton());
8799 handleInputValue(instance, params);
8800 }
8801 };
8802
8803 /**
8804 * @param {SweetAlert} instance
8805 * @param {SweetAlertOptions} innerParams
8806 * @returns {SweetAlertInputValue}
8807 */
8808 const getInputValue = (instance, innerParams) => {
8809 const input = instance.getInput();
8810 if (!input) {
8811 return null;
8812 }
8813 switch (innerParams.input) {
8814 case 'checkbox':
8815 return getCheckboxValue(input);
8816 case 'radio':
8817 return getRadioValue(input);
8818 case 'file':
8819 return getFileValue(input);
8820 default:
8821 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8822 }
8823 };
8824
8825 /**
8826 * @param {HTMLInputElement} input
8827 * @returns {number}
8828 */
8829 const getCheckboxValue = input => input.checked ? 1 : 0;
8830
8831 /**
8832 * @param {HTMLInputElement} input
8833 * @returns {string | null}
8834 */
8835 const getRadioValue = input => input.checked ? input.value : null;
8836
8837 /**
8838 * @param {HTMLInputElement} input
8839 * @returns {FileList | File | null}
8840 */
8841 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8842
8843 /**
8844 * @param {SweetAlert} instance
8845 * @param {SweetAlertOptions} params
8846 */
8847 const handleInputOptions = (instance, params) => {
8848 const popup = getPopup();
8849 if (!popup) {
8850 return;
8851 }
8852 /**
8853 * @param {*} inputOptions
8854 */
8855 const processInputOptions = inputOptions => {
8856 if (params.input === 'select') {
8857 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8858 } else if (params.input === 'radio') {
8859 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8860 }
8861 };
8862 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8863 showLoading(getConfirmButton());
8864 asPromise(params.inputOptions).then(inputOptions => {
8865 instance.hideLoading();
8866 processInputOptions(inputOptions);
8867 });
8868 } else if (typeof params.inputOptions === 'object') {
8869 processInputOptions(params.inputOptions);
8870 } else {
8871 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8872 }
8873 };
8874
8875 /**
8876 * @param {SweetAlert} instance
8877 * @param {SweetAlertOptions} params
8878 */
8879 const handleInputValue = (instance, params) => {
8880 const input = instance.getInput();
8881 if (!input) {
8882 return;
8883 }
8884 hide(input);
8885 asPromise(params.inputValue).then(inputValue => {
8886 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8887 show(input);
8888 input.focus();
8889 instance.hideLoading();
8890 }).catch(err => {
8891 error(`Error in inputValue promise: ${err}`);
8892 input.value = '';
8893 show(input);
8894 input.focus();
8895 instance.hideLoading();
8896 });
8897 };
8898
8899 /**
8900 * @param {HTMLElement} popup
8901 * @param {InputOptionFlattened[]} inputOptions
8902 * @param {SweetAlertOptions} params
8903 */
8904 function populateSelectOptions(popup, inputOptions, params) {
8905 const select = getDirectChildByClass(popup, swalClasses.select);
8906 if (!select) {
8907 return;
8908 }
8909 /**
8910 * @param {HTMLElement} parent
8911 * @param {string} optionLabel
8912 * @param {string} optionValue
8913 */
8914 const renderOption = (parent, optionLabel, optionValue) => {
8915 const option = document.createElement('option');
8916 option.value = optionValue;
8917 setInnerHtml(option, optionLabel);
8918 option.selected = isSelected(optionValue, params.inputValue);
8919 parent.appendChild(option);
8920 };
8921 inputOptions.forEach(inputOption => {
8922 const optionValue = inputOption[0];
8923 const optionLabel = inputOption[1];
8924 // <optgroup> spec:
8925 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8926 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8927 // check whether this is a <optgroup>
8928 if (Array.isArray(optionLabel)) {
8929 // if it is an array, then it is an <optgroup>
8930 const optgroup = document.createElement('optgroup');
8931 optgroup.label = optionValue;
8932 optgroup.disabled = false; // not configurable for now
8933 select.appendChild(optgroup);
8934 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8935 } else {
8936 // case of <option>
8937 renderOption(select, optionLabel, optionValue);
8938 }
8939 });
8940 select.focus();
8941 }
8942
8943 /**
8944 * @param {HTMLElement} popup
8945 * @param {InputOptionFlattened[]} inputOptions
8946 * @param {SweetAlertOptions} params
8947 */
8948 function populateRadioOptions(popup, inputOptions, params) {
8949 const radio = getDirectChildByClass(popup, swalClasses.radio);
8950 if (!radio) {
8951 return;
8952 }
8953 inputOptions.forEach(inputOption => {
8954 const radioValue = inputOption[0];
8955 const radioLabel = inputOption[1];
8956 const radioInput = document.createElement('input');
8957 const radioLabelElement = document.createElement('label');
8958 radioInput.type = 'radio';
8959 radioInput.name = swalClasses.radio;
8960 radioInput.value = radioValue;
8961 if (isSelected(radioValue, params.inputValue)) {
8962 radioInput.checked = true;
8963 }
8964 const label = document.createElement('span');
8965 setInnerHtml(label, radioLabel);
8966 label.className = swalClasses.label;
8967 radioLabelElement.appendChild(radioInput);
8968 radioLabelElement.appendChild(label);
8969 radio.appendChild(radioLabelElement);
8970 });
8971 const radios = radio.querySelectorAll('input');
8972 if (radios.length) {
8973 radios[0].focus();
8974 }
8975 }
8976
8977 /**
8978 * Converts `inputOptions` into an array of `[value, label]`s
8979 *
8980 * @param {*} inputOptions
8981 * @typedef {string[]} InputOptionFlattened
8982 * @returns {InputOptionFlattened[]}
8983 */
8984 const formatInputOptions = inputOptions => {
8985 const entries = inputOptions instanceof Map ? Array.from(inputOptions) : Object.entries(inputOptions);
8986 return entries.map(([key, value]) => [key, typeof value === 'object' ? formatInputOptions(value) : value]); // case of <optgroup>
8987 };
8988
8989 /**
8990 * @param {string} optionValue
8991 * @param {SweetAlertInputValue} inputValue
8992 * @returns {boolean}
8993 */
8994 const isSelected = (optionValue, inputValue) => Boolean(inputValue) && inputValue != null && inputValue.toString() === optionValue.toString();
8995
8996 /**
8997 * @param {SweetAlert} instance
8998 */
8999 const handleConfirmButtonClick = instance => {
9000 const innerParams = privateProps.innerParams.get(instance);
9001 instance.disableButtons();
9002 if (innerParams.input) {
9003 handleConfirmOrDenyWithInput(instance, 'confirm');
9004 } else {
9005 confirm(instance, true);
9006 }
9007 };
9008
9009 /**
9010 * @param {SweetAlert} instance
9011 */
9012 const handleDenyButtonClick = instance => {
9013 const innerParams = privateProps.innerParams.get(instance);
9014 instance.disableButtons();
9015 if (innerParams.returnInputValueOnDeny) {
9016 handleConfirmOrDenyWithInput(instance, 'deny');
9017 } else {
9018 deny(instance, false);
9019 }
9020 };
9021
9022 /**
9023 * @param {SweetAlert} instance
9024 * @param {(dismiss: DismissReason) => void} dismissWith
9025 */
9026 const handleCancelButtonClick = (instance, dismissWith) => {
9027 instance.disableButtons();
9028 dismissWith(DismissReason.cancel);
9029 };
9030
9031 /**
9032 * @param {SweetAlert} instance
9033 * @param {'confirm' | 'deny'} type
9034 */
9035 const handleConfirmOrDenyWithInput = (instance, type) => {
9036 const innerParams = privateProps.innerParams.get(instance);
9037 if (!innerParams.input) {
9038 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
9039 return;
9040 }
9041 const input = instance.getInput();
9042 const inputValue = getInputValue(instance, innerParams);
9043 if (innerParams.inputValidator) {
9044 handleInputValidator(instance, inputValue, type);
9045 } else if (input && !input.checkValidity()) {
9046 instance.enableButtons();
9047 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
9048 } else if (type === 'deny') {
9049 deny(instance, inputValue);
9050 } else {
9051 confirm(instance, inputValue);
9052 }
9053 };
9054
9055 /**
9056 * @param {SweetAlert} instance
9057 * @param {SweetAlertInputValue} inputValue
9058 * @param {'confirm' | 'deny'} type
9059 */
9060 const handleInputValidator = (instance, inputValue, type) => {
9061 const innerParams = privateProps.innerParams.get(instance);
9062 instance.disableInput();
9063 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
9064 validationPromise.then(validationMessage => {
9065 instance.enableButtons();
9066 instance.enableInput();
9067 if (validationMessage) {
9068 instance.showValidationMessage(validationMessage);
9069 } else if (type === 'deny') {
9070 deny(instance, inputValue);
9071 } else {
9072 confirm(instance, inputValue);
9073 }
9074 });
9075 };
9076
9077 /**
9078 * @param {SweetAlert} instance
9079 * @param {*} value
9080 */
9081 const deny = (instance, value) => {
9082 const innerParams = privateProps.innerParams.get(instance);
9083 if (innerParams.showLoaderOnDeny) {
9084 showLoading(getDenyButton());
9085 }
9086 if (innerParams.preDeny) {
9087 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
9088 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
9089 preDenyPromise.then(preDenyValue => {
9090 if (preDenyValue === false) {
9091 instance.hideLoading();
9092 handleAwaitingPromise(instance);
9093 } else {
9094 instance.close(/** @type SweetAlertResult */{
9095 isDenied: true,
9096 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
9097 });
9098 }
9099 }).catch(error => rejectWith(instance, error));
9100 } else {
9101 instance.close(/** @type SweetAlertResult */{
9102 isDenied: true,
9103 value
9104 });
9105 }
9106 };
9107
9108 /**
9109 * @param {SweetAlert} instance
9110 * @param {*} value
9111 */
9112 const succeedWith = (instance, value) => {
9113 instance.close(/** @type SweetAlertResult */{
9114 isConfirmed: true,
9115 value
9116 });
9117 };
9118
9119 /**
9120 *
9121 * @param {SweetAlert} instance
9122 * @param {string} error
9123 */
9124 const rejectWith = (instance, error) => {
9125 instance.rejectPromise(error);
9126 };
9127
9128 /**
9129 *
9130 * @param {SweetAlert} instance
9131 * @param {*} value
9132 */
9133 const confirm = (instance, value) => {
9134 const innerParams = privateProps.innerParams.get(instance);
9135 if (innerParams.showLoaderOnConfirm) {
9136 showLoading();
9137 }
9138 if (innerParams.preConfirm) {
9139 instance.resetValidationMessage();
9140 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
9141 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
9142 preConfirmPromise.then(preConfirmValue => {
9143 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
9144 instance.hideLoading();
9145 handleAwaitingPromise(instance);
9146 } else {
9147 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
9148 }
9149 }).catch(error => rejectWith(instance, error));
9150 } else {
9151 succeedWith(instance, value);
9152 }
9153 };
9154
9155 /**
9156 * Hides loader and shows back the button which was hidden by .showLoading()
9157 * @this {SweetAlert}
9158 */
9159 function hideLoading() {
9160 // do nothing if popup is closed
9161 const innerParams = privateProps.innerParams.get(this);
9162 if (!innerParams) {
9163 return;
9164 }
9165 const domCache = privateProps.domCache.get(this);
9166 hide(domCache.loader);
9167 if (isToast()) {
9168 if (innerParams.icon) {
9169 show(getIcon());
9170 }
9171 } else {
9172 showRelatedButton(domCache);
9173 }
9174 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
9175 domCache.popup.removeAttribute('aria-busy');
9176 domCache.popup.removeAttribute('data-loading');
9177 this.enableButtons();
9178 }
9179
9180 /**
9181 * @param {DomCache} domCache
9182 */
9183 const showRelatedButton = domCache => {
9184 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
9185 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
9186 if (buttonToReplace.length) {
9187 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
9188 } else if (allButtonsAreHidden()) {
9189 hide(domCache.actions);
9190 }
9191 };
9192
9193 /**
9194 * Gets the input DOM node, this method works with input parameter.
9195 *
9196 * @returns {HTMLInputElement | null}
9197 * @this {SweetAlert}
9198 */
9199 function getInput() {
9200 const innerParams = privateProps.innerParams.get(this);
9201 const domCache = privateProps.domCache.get(this);
9202 if (!domCache) {
9203 return null;
9204 }
9205 return getInput$1(domCache.popup, innerParams.input);
9206 }
9207
9208 /**
9209 * @param {SweetAlert} instance
9210 * @param {string[]} buttons
9211 * @param {boolean} disabled
9212 */
9213 function setButtonsDisabled(instance, buttons, disabled) {
9214 const domCache = privateProps.domCache.get(instance);
9215 buttons.forEach(button => {
9216 domCache[button].disabled = disabled;
9217 });
9218 }
9219
9220 /**
9221 * @param {HTMLInputElement | null} input
9222 * @param {boolean} disabled
9223 */
9224 function setInputDisabled(input, disabled) {
9225 const popup = getPopup();
9226 if (!popup || !input) {
9227 return;
9228 }
9229 if (input.type === 'radio') {
9230 /** @type {NodeListOf<HTMLInputElement>} */
9231 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
9232 radios.forEach(radio => {
9233 radio.disabled = disabled;
9234 });
9235 } else {
9236 input.disabled = disabled;
9237 }
9238 }
9239
9240 /**
9241 * Enable all the buttons
9242 * @this {SweetAlert}
9243 */
9244 function enableButtons() {
9245 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
9246 const focusedElement = privateProps.focusedElement.get(this);
9247 if (focusedElement instanceof HTMLElement && document.activeElement === document.body) {
9248 focusedElement.focus();
9249 }
9250 privateProps.focusedElement.delete(this);
9251 }
9252
9253 /**
9254 * Disable all the buttons
9255 * @this {SweetAlert}
9256 */
9257 function disableButtons() {
9258 privateProps.focusedElement.set(this, document.activeElement);
9259 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
9260 }
9261
9262 /**
9263 * Enable the input field
9264 * @this {SweetAlert}
9265 */
9266 function enableInput() {
9267 setInputDisabled(this.getInput(), false);
9268 }
9269
9270 /**
9271 * Disable the input field
9272 * @this {SweetAlert}
9273 */
9274 function disableInput() {
9275 setInputDisabled(this.getInput(), true);
9276 }
9277
9278 /**
9279 * Show block with validation message
9280 *
9281 * @param {string} error
9282 * @this {SweetAlert}
9283 */
9284 function showValidationMessage(error) {
9285 const domCache = privateProps.domCache.get(this);
9286 const params = privateProps.innerParams.get(this);
9287 setInnerHtml(domCache.validationMessage, error);
9288 domCache.validationMessage.className = swalClasses['validation-message'];
9289 if (params.customClass && params.customClass.validationMessage) {
9290 addClass(domCache.validationMessage, params.customClass.validationMessage);
9291 }
9292 show(domCache.validationMessage);
9293 const input = this.getInput();
9294 if (input) {
9295 input.setAttribute('aria-invalid', 'true');
9296 input.setAttribute('aria-describedby', swalClasses['validation-message']);
9297 focusInput(input);
9298 addClass(input, swalClasses.inputerror);
9299 }
9300 }
9301
9302 /**
9303 * Hide block with validation message
9304 *
9305 * @this {SweetAlert}
9306 */
9307 function resetValidationMessage() {
9308 const domCache = privateProps.domCache.get(this);
9309 if (domCache.validationMessage) {
9310 hide(domCache.validationMessage);
9311 }
9312 const input = this.getInput();
9313 if (input) {
9314 input.removeAttribute('aria-invalid');
9315 input.removeAttribute('aria-describedby');
9316 removeClass(input, swalClasses.inputerror);
9317 }
9318 }
9319
9320 const defaultParams = {
9321 title: '',
9322 titleText: '',
9323 text: '',
9324 html: '',
9325 footer: '',
9326 icon: undefined,
9327 iconColor: undefined,
9328 iconHtml: undefined,
9329 template: undefined,
9330 toast: false,
9331 draggable: false,
9332 animation: true,
9333 theme: 'light',
9334 showClass: {
9335 popup: 'swal2-show',
9336 backdrop: 'swal2-backdrop-show',
9337 icon: 'swal2-icon-show'
9338 },
9339 hideClass: {
9340 popup: 'swal2-hide',
9341 backdrop: 'swal2-backdrop-hide',
9342 icon: 'swal2-icon-hide'
9343 },
9344 customClass: {},
9345 target: 'body',
9346 color: undefined,
9347 backdrop: true,
9348 heightAuto: true,
9349 allowOutsideClick: true,
9350 allowEscapeKey: true,
9351 allowEnterKey: true,
9352 stopKeydownPropagation: true,
9353 keydownListenerCapture: false,
9354 showConfirmButton: true,
9355 showDenyButton: false,
9356 showCancelButton: false,
9357 preConfirm: undefined,
9358 preDeny: undefined,
9359 confirmButtonText: 'OK',
9360 confirmButtonAriaLabel: '',
9361 confirmButtonColor: undefined,
9362 denyButtonText: 'No',
9363 denyButtonAriaLabel: '',
9364 denyButtonColor: undefined,
9365 cancelButtonText: 'Cancel',
9366 cancelButtonAriaLabel: '',
9367 cancelButtonColor: undefined,
9368 buttonsStyling: true,
9369 reverseButtons: false,
9370 focusConfirm: true,
9371 focusDeny: false,
9372 focusCancel: false,
9373 returnFocus: true,
9374 showCloseButton: false,
9375 closeButtonHtml: '&times;',
9376 closeButtonAriaLabel: 'Close this dialog',
9377 loaderHtml: '',
9378 showLoaderOnConfirm: false,
9379 showLoaderOnDeny: false,
9380 imageUrl: undefined,
9381 imageWidth: undefined,
9382 imageHeight: undefined,
9383 imageAlt: '',
9384 timer: undefined,
9385 timerProgressBar: false,
9386 width: undefined,
9387 padding: undefined,
9388 background: undefined,
9389 input: undefined,
9390 inputPlaceholder: '',
9391 inputLabel: '',
9392 inputValue: '',
9393 inputOptions: {},
9394 inputAutoFocus: true,
9395 inputAutoTrim: true,
9396 inputAttributes: {},
9397 inputValidator: undefined,
9398 returnInputValueOnDeny: false,
9399 validationMessage: undefined,
9400 grow: false,
9401 position: 'center',
9402 progressSteps: [],
9403 currentProgressStep: undefined,
9404 progressStepsDistance: undefined,
9405 willOpen: undefined,
9406 didOpen: undefined,
9407 didRender: undefined,
9408 willClose: undefined,
9409 didClose: undefined,
9410 didDestroy: undefined,
9411 scrollbarPadding: true,
9412 topLayer: false
9413 };
9414 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'];
9415
9416 /** @type {Record<string, string | undefined>} */
9417 const deprecatedParams = {
9418 allowEnterKey: undefined
9419 };
9420 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9421
9422 /**
9423 * Is valid parameter
9424 *
9425 * @param {string} paramName
9426 * @returns {boolean}
9427 */
9428 const isValidParameter = paramName => {
9429 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9430 };
9431
9432 /**
9433 * Is valid parameter for Swal.update() method
9434 *
9435 * @param {string} paramName
9436 * @returns {boolean}
9437 */
9438 const isUpdatableParameter = paramName => {
9439 return updatableParams.indexOf(paramName) !== -1;
9440 };
9441
9442 /**
9443 * Is deprecated parameter
9444 *
9445 * @param {string} paramName
9446 * @returns {string | undefined}
9447 */
9448 const isDeprecatedParameter = paramName => {
9449 return deprecatedParams[paramName];
9450 };
9451
9452 /**
9453 * @param {string} param
9454 */
9455 const checkIfParamIsValid = param => {
9456 if (!isValidParameter(param)) {
9457 warn(`Unknown parameter "${param}"`);
9458 }
9459 };
9460
9461 /**
9462 * @param {string} param
9463 */
9464 const checkIfToastParamIsValid = param => {
9465 if (toastIncompatibleParams.includes(param)) {
9466 warn(`The parameter "${param}" is incompatible with toasts`);
9467 }
9468 };
9469
9470 /**
9471 * @param {string} param
9472 */
9473 const checkIfParamIsDeprecated = param => {
9474 const isDeprecated = isDeprecatedParameter(param);
9475 if (isDeprecated) {
9476 warnAboutDeprecation(param, isDeprecated);
9477 }
9478 };
9479
9480 /**
9481 * Show relevant warnings for given params
9482 *
9483 * @param {SweetAlertOptions} params
9484 */
9485 const showWarningsForParams = params => {
9486 if (params.backdrop === false && params.allowOutsideClick) {
9487 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9488 }
9489 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)) {
9490 warn(`Invalid theme "${params.theme}"`);
9491 }
9492 for (const param in params) {
9493 checkIfParamIsValid(param);
9494 if (params.toast) {
9495 checkIfToastParamIsValid(param);
9496 }
9497 checkIfParamIsDeprecated(param);
9498 }
9499 };
9500
9501 /**
9502 * Updates popup parameters.
9503 *
9504 * @this {any}
9505 * @param {SweetAlertOptions} params
9506 */
9507 function update(params) {
9508 const container = getContainer();
9509 const popup = getPopup();
9510 const innerParams = privateProps.innerParams.get(this);
9511 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9512 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.`);
9513 return;
9514 }
9515 const validUpdatableParams = filterValidParams(params);
9516 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9517 showWarningsForParams(updatedParams);
9518 if (container) {
9519 container.dataset['swal2Theme'] = updatedParams.theme;
9520 }
9521 render(this, updatedParams);
9522 privateProps.innerParams.set(this, updatedParams);
9523 Object.defineProperties(this, {
9524 params: {
9525 value: Object.assign({}, this.params, params),
9526 writable: false,
9527 enumerable: true
9528 }
9529 });
9530 }
9531
9532 /**
9533 * @param {SweetAlertOptions} params
9534 * @returns {SweetAlertOptions}
9535 */
9536 const filterValidParams = params => {
9537 /** @type {Record<string, any>} */
9538 const validUpdatableParams = {};
9539 Object.keys(params).forEach(param => {
9540 if (isUpdatableParameter(param)) {
9541 const typedParams = /** @type {Record<string, any>} */params;
9542 validUpdatableParams[param] = typedParams[param];
9543 } else {
9544 warn(`Invalid parameter to update: ${param}`);
9545 }
9546 });
9547 return validUpdatableParams;
9548 };
9549
9550 /**
9551 * Dispose the current SweetAlert2 instance
9552 * @this {SweetAlert}
9553 */
9554 function _destroy() {
9555 var _globalState$eventEmi;
9556 const domCache = privateProps.domCache.get(this);
9557 const innerParams = privateProps.innerParams.get(this);
9558 if (!innerParams) {
9559 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9560 return; // This instance has already been destroyed
9561 }
9562
9563 // Check if there is another Swal closing
9564 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9565 globalState.swalCloseEventFinishedCallback();
9566 delete globalState.swalCloseEventFinishedCallback;
9567 }
9568 if (typeof innerParams.didDestroy === 'function') {
9569 innerParams.didDestroy();
9570 }
9571 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
9572 disposeSwal(this);
9573 }
9574
9575 /**
9576 * @param {SweetAlert} instance
9577 */
9578 const disposeSwal = instance => {
9579 disposeWeakMaps(instance);
9580 // Unset this.params so GC will dispose it (#1569)
9581 // @ts-ignore
9582 delete instance.params;
9583 // Unset globalState props so GC will dispose globalState (#1569)
9584 delete globalState.keydownHandler;
9585 delete globalState.keydownTarget;
9586 // Unset currentInstance
9587 delete globalState.currentInstance;
9588 };
9589
9590 /**
9591 * @param {SweetAlert} instance
9592 */
9593 const disposeWeakMaps = instance => {
9594 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9595 if (instance.isAwaitingPromise) {
9596 unsetWeakMaps(privateProps, instance);
9597 instance.isAwaitingPromise = true;
9598 } else {
9599 unsetWeakMaps(privateMethods, instance);
9600 unsetWeakMaps(privateProps, instance);
9601
9602 // @ts-ignore
9603 delete instance.isAwaitingPromise;
9604 // Unset instance methods
9605 // @ts-ignore
9606 delete instance.disableButtons;
9607 // @ts-ignore
9608 delete instance.enableButtons;
9609 // @ts-ignore
9610 delete instance.getInput;
9611 // @ts-ignore
9612 delete instance.disableInput;
9613 // @ts-ignore
9614 delete instance.enableInput;
9615 // @ts-ignore
9616 delete instance.hideLoading;
9617 // @ts-ignore
9618 delete instance.disableLoading;
9619 // @ts-ignore
9620 delete instance.showValidationMessage;
9621 // @ts-ignore
9622 delete instance.resetValidationMessage;
9623 // @ts-ignore
9624 delete instance.close;
9625 // @ts-ignore
9626 delete instance.closePopup;
9627 // @ts-ignore
9628 delete instance.closeModal;
9629 // @ts-ignore
9630 delete instance.closeToast;
9631 // @ts-ignore
9632 delete instance.rejectPromise;
9633 // @ts-ignore
9634 delete instance.update;
9635 // @ts-ignore
9636 delete instance._destroy;
9637 }
9638 };
9639
9640 /**
9641 * @param {Record<string, WeakMap<any, any>>} obj
9642 * @param {SweetAlert} instance
9643 */
9644 const unsetWeakMaps = (obj, instance) => {
9645 for (const i in obj) {
9646 obj[i].delete(instance);
9647 }
9648 };
9649
9650 var instanceMethods = /*#__PURE__*/Object.freeze({
9651 __proto__: null,
9652 _destroy: _destroy,
9653 close: close,
9654 closeModal: close,
9655 closePopup: close,
9656 closeToast: close,
9657 disableButtons: disableButtons,
9658 disableInput: disableInput,
9659 disableLoading: hideLoading,
9660 enableButtons: enableButtons,
9661 enableInput: enableInput,
9662 getInput: getInput,
9663 handleAwaitingPromise: handleAwaitingPromise,
9664 hideLoading: hideLoading,
9665 rejectPromise: rejectPromise,
9666 resetValidationMessage: resetValidationMessage,
9667 showValidationMessage: showValidationMessage,
9668 update: update
9669 });
9670
9671 /**
9672 * @param {SweetAlertOptions} innerParams
9673 * @param {DomCache} domCache
9674 * @param {(dismiss: DismissReason) => void} dismissWith
9675 */
9676 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9677 if (innerParams.toast) {
9678 handleToastClick(innerParams, domCache, dismissWith);
9679 } else {
9680 // Ignore click events that had mousedown on the popup but mouseup on the container
9681 // This can happen when the user drags a slider
9682 handleModalMousedown(domCache);
9683
9684 // Ignore click events that had mousedown on the container but mouseup on the popup
9685 handleContainerMousedown(domCache);
9686 handleModalClick(innerParams, domCache, dismissWith);
9687 }
9688 };
9689
9690 /**
9691 * @param {SweetAlertOptions} innerParams
9692 * @param {DomCache} domCache
9693 * @param {(dismiss: DismissReason) => void} dismissWith
9694 */
9695 const handleToastClick = (innerParams, domCache, dismissWith) => {
9696 // Closing toast by internal click
9697 domCache.popup.onclick = () => {
9698 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9699 return;
9700 }
9701 dismissWith(DismissReason.close);
9702 };
9703 };
9704
9705 /**
9706 * @param {SweetAlertOptions} innerParams
9707 * @returns {boolean}
9708 */
9709 const isAnyButtonShown = innerParams => {
9710 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9711 };
9712 let ignoreOutsideClick = false;
9713
9714 /**
9715 * @param {DomCache} domCache
9716 */
9717 const handleModalMousedown = domCache => {
9718 domCache.popup.onmousedown = () => {
9719 domCache.container.onmouseup = function (e) {
9720 domCache.container.onmouseup = () => {};
9721 // We only check if the mouseup target is the container because usually it doesn't
9722 // have any other direct children aside of the popup
9723 if (e.target === domCache.container) {
9724 ignoreOutsideClick = true;
9725 }
9726 };
9727 };
9728 };
9729
9730 /**
9731 * @param {DomCache} domCache
9732 */
9733 const handleContainerMousedown = domCache => {
9734 domCache.container.onmousedown = e => {
9735 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9736 if (e.target === domCache.container) {
9737 e.preventDefault();
9738 }
9739 domCache.popup.onmouseup = function (e) {
9740 domCache.popup.onmouseup = () => {};
9741 // We also need to check if the mouseup target is a child of the popup
9742 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9743 ignoreOutsideClick = true;
9744 }
9745 };
9746 };
9747 };
9748
9749 /**
9750 * @param {SweetAlertOptions} innerParams
9751 * @param {DomCache} domCache
9752 * @param {(dismiss: DismissReason) => void} dismissWith
9753 */
9754 const handleModalClick = (innerParams, domCache, dismissWith) => {
9755 domCache.container.onclick = e => {
9756 if (ignoreOutsideClick) {
9757 ignoreOutsideClick = false;
9758 return;
9759 }
9760 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9761 dismissWith(DismissReason.backdrop);
9762 }
9763 };
9764 };
9765
9766 /**
9767 * @param {unknown} elem
9768 * @returns {boolean}
9769 */
9770 const isJqueryElement = elem => typeof elem === 'object' && elem !== null && 'jquery' in elem;
9771
9772 /**
9773 * @param {unknown} elem
9774 * @returns {boolean}
9775 */
9776 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9777
9778 /**
9779 * @param {ReadonlyArray<unknown>} args
9780 * @returns {SweetAlertOptions}
9781 */
9782 const argsToParams = args => {
9783 /** @type {Record<string, unknown>} */
9784 const params = {};
9785 if (typeof args[0] === 'object' && !isElement(args[0])) {
9786 Object.assign(params, args[0]);
9787 } else {
9788 ['title', 'html', 'icon'].forEach((name, index) => {
9789 const arg = args[index];
9790 if (typeof arg === 'string' || isElement(arg)) {
9791 params[name] = arg;
9792 } else if (arg !== undefined) {
9793 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9794 }
9795 });
9796 }
9797 return /** @type {SweetAlertOptions} */params;
9798 };
9799
9800 /**
9801 * Main method to create a new SweetAlert2 popup
9802 *
9803 * @this {new (...args: any[]) => any}
9804 * @param {...SweetAlertOptions} args
9805 * @returns {Promise<SweetAlertResult>}
9806 */
9807 function fire(...args) {
9808 return new this(...args);
9809 }
9810
9811 /**
9812 * Returns an extended version of `Swal` containing `params` as defaults.
9813 * Useful for reusing Swal configuration.
9814 *
9815 * For example:
9816 *
9817 * Before:
9818 * const textPromptOptions = { input: 'text', showCancelButton: true }
9819 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9820 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9821 *
9822 * After:
9823 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9824 * const {value: firstName} = await TextPrompt('What is your first name?')
9825 * const {value: lastName} = await TextPrompt('What is your last name?')
9826 *
9827 * @param {SweetAlertOptions} mixinParams
9828 * @returns {SweetAlert}
9829 * @this {typeof import('../SweetAlert.js').SweetAlert}
9830 */
9831 function mixin(mixinParams) {
9832 // @ts-ignore: 'this' refers to the SweetAlert constructor
9833 class MixinSwal extends this {
9834 /**
9835 * @param {any} params
9836 * @param {any} priorityMixinParams
9837 */
9838 _main(params, priorityMixinParams) {
9839 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9840 }
9841 }
9842 // @ts-ignore
9843 return MixinSwal;
9844 }
9845
9846 /**
9847 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9848 * Otherwise, returns undefined.
9849 *
9850 * @returns {number | undefined}
9851 */
9852 const getTimerLeft = () => {
9853 return globalState.timeout && globalState.timeout.getTimerLeft();
9854 };
9855
9856 /**
9857 * Stop timer. Returns number of milliseconds of timer remained.
9858 * If `timer` parameter isn't set, returns undefined.
9859 *
9860 * @returns {number | undefined}
9861 */
9862 const stopTimer = () => {
9863 if (globalState.timeout) {
9864 stopTimerProgressBar();
9865 return globalState.timeout.stop();
9866 }
9867 };
9868
9869 /**
9870 * Resume timer. Returns number of milliseconds of timer remained.
9871 * If `timer` parameter isn't set, returns undefined.
9872 *
9873 * @returns {number | undefined}
9874 */
9875 const resumeTimer = () => {
9876 if (globalState.timeout) {
9877 const remaining = globalState.timeout.start();
9878 animateTimerProgressBar(remaining);
9879 return remaining;
9880 }
9881 };
9882
9883 /**
9884 * Resume timer. Returns number of milliseconds of timer remained.
9885 * If `timer` parameter isn't set, returns undefined.
9886 *
9887 * @returns {number | undefined}
9888 */
9889 const toggleTimer = () => {
9890 const timer = globalState.timeout;
9891 return timer && (timer.running ? stopTimer() : resumeTimer());
9892 };
9893
9894 /**
9895 * Increase timer. Returns number of milliseconds of an updated timer.
9896 * If `timer` parameter isn't set, returns undefined.
9897 *
9898 * @param {number} ms
9899 * @returns {number | undefined}
9900 */
9901 const increaseTimer = ms => {
9902 if (globalState.timeout) {
9903 const remaining = globalState.timeout.increase(ms);
9904 animateTimerProgressBar(remaining, true);
9905 return remaining;
9906 }
9907 };
9908
9909 /**
9910 * Check if timer is running. Returns true if timer is running
9911 * or false if timer is paused or stopped.
9912 * If `timer` parameter isn't set, returns undefined
9913 *
9914 * @returns {boolean}
9915 */
9916 const isTimerRunning = () => {
9917 return Boolean(globalState.timeout && globalState.timeout.isRunning());
9918 };
9919
9920 let bodyClickListenerAdded = false;
9921 /** @type {Record<string, any>} */
9922 const clickHandlers = {};
9923
9924 /**
9925 * @this {any}
9926 * @param {string} attr
9927 */
9928 function bindClickHandler(attr = 'data-swal-template') {
9929 clickHandlers[attr] = this;
9930 if (!bodyClickListenerAdded) {
9931 document.body.addEventListener('click', bodyClickListener);
9932 bodyClickListenerAdded = true;
9933 }
9934 }
9935
9936 /**
9937 * @param {MouseEvent} event
9938 */
9939 const bodyClickListener = event => {
9940 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
9941 for (const attr in clickHandlers) {
9942 const template = el.getAttribute && el.getAttribute(attr);
9943 if (template) {
9944 clickHandlers[attr].fire({
9945 template
9946 });
9947 return;
9948 }
9949 }
9950 }
9951 };
9952
9953 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9954
9955 class EventEmitter {
9956 constructor() {
9957 /** @type {Events} */
9958 this.events = {};
9959 }
9960
9961 /**
9962 * @param {string} eventName
9963 * @returns {EventHandlers}
9964 */
9965 _getHandlersByEventName(eventName) {
9966 if (typeof this.events[eventName] === 'undefined') {
9967 // not Set because we need to keep the FIFO order
9968 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
9969 this.events[eventName] = [];
9970 }
9971 return this.events[eventName];
9972 }
9973
9974 /**
9975 * @param {string} eventName
9976 * @param {EventHandler} eventHandler
9977 */
9978 on(eventName, eventHandler) {
9979 const currentHandlers = this._getHandlersByEventName(eventName);
9980 if (!currentHandlers.includes(eventHandler)) {
9981 currentHandlers.push(eventHandler);
9982 }
9983 }
9984
9985 /**
9986 * @param {string} eventName
9987 * @param {EventHandler} eventHandler
9988 */
9989 once(eventName, eventHandler) {
9990 /**
9991 * @param {...any} args
9992 */
9993 const onceFn = (...args) => {
9994 this.removeListener(eventName, onceFn);
9995 // @ts-ignore
9996 eventHandler.apply(this, args);
9997 };
9998 this.on(eventName, onceFn);
9999 }
10000
10001 /**
10002 * @param {string} eventName
10003 * @param {...any} args
10004 */
10005 emit(eventName, ...args) {
10006 this._getHandlersByEventName(eventName).forEach(
10007 /**
10008 * @param {EventHandler} eventHandler
10009 */
10010 eventHandler => {
10011 try {
10012 // @ts-ignore
10013 eventHandler.apply(this, args);
10014 } catch (error) {
10015 console.error(error);
10016 }
10017 });
10018 }
10019
10020 /**
10021 * @param {string} eventName
10022 * @param {EventHandler} eventHandler
10023 */
10024 removeListener(eventName, eventHandler) {
10025 const currentHandlers = this._getHandlersByEventName(eventName);
10026 const index = currentHandlers.indexOf(eventHandler);
10027 if (index > -1) {
10028 currentHandlers.splice(index, 1);
10029 }
10030 }
10031
10032 /**
10033 * @param {string} eventName
10034 */
10035 removeAllListeners(eventName) {
10036 if (this.events[eventName] !== undefined) {
10037 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
10038 this.events[eventName].length = 0;
10039 }
10040 }
10041 reset() {
10042 this.events = {};
10043 }
10044 }
10045
10046 globalState.eventEmitter = new EventEmitter();
10047
10048 /**
10049 * @param {string} eventName
10050 * @param {EventHandler} eventHandler
10051 */
10052 const on = (eventName, eventHandler) => {
10053 if (globalState.eventEmitter) {
10054 globalState.eventEmitter.on(eventName, eventHandler);
10055 }
10056 };
10057
10058 /**
10059 * @param {string} eventName
10060 * @param {EventHandler} eventHandler
10061 */
10062 const once = (eventName, eventHandler) => {
10063 if (globalState.eventEmitter) {
10064 globalState.eventEmitter.once(eventName, eventHandler);
10065 }
10066 };
10067
10068 /**
10069 * @param {string} [eventName]
10070 * @param {EventHandler} [eventHandler]
10071 */
10072 const off = (eventName, eventHandler) => {
10073 if (!globalState.eventEmitter) {
10074 return;
10075 }
10076
10077 // Remove all handlers for all events
10078 if (!eventName) {
10079 globalState.eventEmitter.reset();
10080 return;
10081 }
10082 if (eventHandler) {
10083 // Remove a specific handler
10084 globalState.eventEmitter.removeListener(eventName, eventHandler);
10085 } else {
10086 // Remove all handlers for a specific event
10087 globalState.eventEmitter.removeAllListeners(eventName);
10088 }
10089 };
10090
10091 var staticMethods = /*#__PURE__*/Object.freeze({
10092 __proto__: null,
10093 argsToParams: argsToParams,
10094 bindClickHandler: bindClickHandler,
10095 clickCancel: clickCancel,
10096 clickConfirm: clickConfirm,
10097 clickDeny: clickDeny,
10098 enableLoading: showLoading,
10099 fire: fire,
10100 getActions: getActions,
10101 getCancelButton: getCancelButton,
10102 getCloseButton: getCloseButton,
10103 getConfirmButton: getConfirmButton,
10104 getContainer: getContainer,
10105 getDenyButton: getDenyButton,
10106 getFocusableElements: getFocusableElements,
10107 getFooter: getFooter,
10108 getHtmlContainer: getHtmlContainer,
10109 getIcon: getIcon,
10110 getIconContent: getIconContent,
10111 getImage: getImage,
10112 getInputLabel: getInputLabel,
10113 getLoader: getLoader,
10114 getPopup: getPopup,
10115 getProgressSteps: getProgressSteps,
10116 getTimerLeft: getTimerLeft,
10117 getTimerProgressBar: getTimerProgressBar,
10118 getTitle: getTitle,
10119 getValidationMessage: getValidationMessage,
10120 increaseTimer: increaseTimer,
10121 isDeprecatedParameter: isDeprecatedParameter,
10122 isLoading: isLoading,
10123 isTimerRunning: isTimerRunning,
10124 isUpdatableParameter: isUpdatableParameter,
10125 isValidParameter: isValidParameter,
10126 isVisible: isVisible,
10127 mixin: mixin,
10128 off: off,
10129 on: on,
10130 once: once,
10131 resumeTimer: resumeTimer,
10132 showLoading: showLoading,
10133 stopTimer: stopTimer,
10134 toggleTimer: toggleTimer
10135 });
10136
10137 class Timer {
10138 /**
10139 * @param {() => void} callback
10140 * @param {number} delay
10141 */
10142 constructor(callback, delay) {
10143 this.callback = callback;
10144 this.remaining = delay;
10145 this.running = false;
10146 this.start();
10147 }
10148
10149 /**
10150 * @returns {number}
10151 */
10152 start() {
10153 if (!this.running) {
10154 this.running = true;
10155 this.started = new Date();
10156 this.id = setTimeout(this.callback, this.remaining);
10157 }
10158 return this.remaining;
10159 }
10160
10161 /**
10162 * @returns {number}
10163 */
10164 stop() {
10165 if (this.started && this.running) {
10166 this.running = false;
10167 clearTimeout(this.id);
10168 this.remaining -= new Date().getTime() - this.started.getTime();
10169 }
10170 return this.remaining;
10171 }
10172
10173 /**
10174 * @param {number} n
10175 * @returns {number}
10176 */
10177 increase(n) {
10178 const running = this.running;
10179 if (running) {
10180 this.stop();
10181 }
10182 this.remaining += n;
10183 if (running) {
10184 this.start();
10185 }
10186 return this.remaining;
10187 }
10188
10189 /**
10190 * @returns {number}
10191 */
10192 getTimerLeft() {
10193 if (this.running) {
10194 this.stop();
10195 this.start();
10196 }
10197 return this.remaining;
10198 }
10199
10200 /**
10201 * @returns {boolean}
10202 */
10203 isRunning() {
10204 return this.running;
10205 }
10206 }
10207
10208 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
10209
10210 /**
10211 * @param {SweetAlertOptions} params
10212 * @returns {SweetAlertOptions}
10213 */
10214 const getTemplateParams = params => {
10215 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
10216 if (!template) {
10217 return {};
10218 }
10219 /** @type {DocumentFragment} */
10220 const templateContent = template.content;
10221 showWarningsForElements(templateContent);
10222 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
10223 return result;
10224 };
10225
10226 /**
10227 * @param {DocumentFragment} templateContent
10228 * @returns {Record<string, string | boolean | number>}
10229 */
10230 const getSwalParams = templateContent => {
10231 /** @type {Record<string, string | boolean | number>} */
10232 const result = {};
10233 /** @type {HTMLElement[]} */
10234 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
10235 swalParams.forEach(param => {
10236 showWarningsForAttributes(param, ['name', 'value']);
10237 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10238 const value = param.getAttribute('value');
10239 if (!paramName || !value) {
10240 return;
10241 }
10242 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
10243 result[paramName] = value !== 'false';
10244 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
10245 result[paramName] = JSON.parse(value);
10246 } else {
10247 result[paramName] = value;
10248 }
10249 });
10250 return result;
10251 };
10252
10253 /**
10254 * @param {DocumentFragment} templateContent
10255 * @returns {Record<string, () => void>}
10256 */
10257 const getSwalFunctionParams = templateContent => {
10258 /** @type {Record<string, () => void>} */
10259 const result = {};
10260 /** @type {HTMLElement[]} */
10261 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
10262 swalFunctions.forEach(param => {
10263 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10264 const value = param.getAttribute('value');
10265 if (!paramName || !value) {
10266 return;
10267 }
10268 result[paramName] = new Function(`return ${value}`)();
10269 });
10270 return result;
10271 };
10272
10273 /**
10274 * @param {DocumentFragment} templateContent
10275 * @returns {Record<string, string | boolean>}
10276 */
10277 const getSwalButtons = templateContent => {
10278 /** @type {Record<string, string | boolean>} */
10279 const result = {};
10280 /** @type {HTMLElement[]} */
10281 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
10282 swalButtons.forEach(button => {
10283 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
10284 const type = button.getAttribute('type');
10285 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
10286 return;
10287 }
10288 result[`${type}ButtonText`] = button.innerHTML;
10289 result[`show${capitalizeFirstLetter(type)}Button`] = true;
10290 const color = button.getAttribute('color');
10291 if (color !== null) {
10292 result[`${type}ButtonColor`] = color;
10293 }
10294 const ariaLabel = button.getAttribute('aria-label');
10295 if (ariaLabel !== null) {
10296 result[`${type}ButtonAriaLabel`] = ariaLabel;
10297 }
10298 });
10299 return result;
10300 };
10301
10302 /**
10303 * @param {DocumentFragment} templateContent
10304 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
10305 */
10306 const getSwalImage = templateContent => {
10307 const result = {};
10308 /** @type {HTMLElement | null} */
10309 const image = templateContent.querySelector('swal-image');
10310 if (image) {
10311 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
10312 // getAttribute returns null if attribute is absent; `|| undefined` converts empty string to undefined
10313 const src = image.getAttribute('src');
10314 if (src !== null) result.imageUrl = src || undefined;
10315 const width = image.getAttribute('width');
10316 if (width !== null) result.imageWidth = width || undefined;
10317 const height = image.getAttribute('height');
10318 if (height !== null) result.imageHeight = height || undefined;
10319 const alt = image.getAttribute('alt');
10320 if (alt !== null) result.imageAlt = alt || undefined;
10321 }
10322 return result;
10323 };
10324
10325 /**
10326 * @param {DocumentFragment} templateContent
10327 * @returns {object}
10328 */
10329 const getSwalIcon = templateContent => {
10330 const result = {};
10331 /** @type {HTMLElement | null} */
10332 const icon = templateContent.querySelector('swal-icon');
10333 if (icon) {
10334 showWarningsForAttributes(icon, ['type', 'color']);
10335 if (icon.hasAttribute('type')) {
10336 result.icon = icon.getAttribute('type');
10337 }
10338 if (icon.hasAttribute('color')) {
10339 result.iconColor = icon.getAttribute('color');
10340 }
10341 result.iconHtml = icon.innerHTML;
10342 }
10343 return result;
10344 };
10345
10346 /**
10347 * @param {DocumentFragment} templateContent
10348 * @returns {object}
10349 */
10350 const getSwalInput = templateContent => {
10351 /** @type {Record<string, any>} */
10352 const result = {};
10353 /** @type {HTMLElement | null} */
10354 const input = templateContent.querySelector('swal-input');
10355 if (input) {
10356 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
10357 result.input = input.getAttribute('type') || 'text';
10358 if (input.hasAttribute('label')) {
10359 result.inputLabel = input.getAttribute('label');
10360 }
10361 if (input.hasAttribute('placeholder')) {
10362 result.inputPlaceholder = input.getAttribute('placeholder');
10363 }
10364 if (input.hasAttribute('value')) {
10365 result.inputValue = input.getAttribute('value');
10366 }
10367 }
10368 /** @type {HTMLElement[]} */
10369 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
10370 if (inputOptions.length) {
10371 result.inputOptions = {};
10372 inputOptions.forEach(option => {
10373 showWarningsForAttributes(option, ['value']);
10374 const optionValue = option.getAttribute('value');
10375 if (!optionValue) {
10376 return;
10377 }
10378 const optionName = option.innerHTML;
10379 result.inputOptions[optionValue] = optionName;
10380 });
10381 }
10382 return result;
10383 };
10384
10385 /**
10386 * @param {DocumentFragment} templateContent
10387 * @param {string[]} paramNames
10388 * @returns {Record<string, string>}
10389 */
10390 const getSwalStringParams = (templateContent, paramNames) => {
10391 /** @type {Record<string, string>} */
10392 const result = {};
10393 for (const i in paramNames) {
10394 const paramName = paramNames[i];
10395 /** @type {HTMLElement | null} */
10396 const tag = templateContent.querySelector(paramName);
10397 if (tag) {
10398 showWarningsForAttributes(tag, []);
10399 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
10400 }
10401 }
10402 return result;
10403 };
10404
10405 /**
10406 * @param {DocumentFragment} templateContent
10407 */
10408 const showWarningsForElements = templateContent => {
10409 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
10410 Array.from(templateContent.children).forEach(el => {
10411 const tagName = el.tagName.toLowerCase();
10412 if (!allowedElements.includes(tagName)) {
10413 warn(`Unrecognized element <${tagName}>`);
10414 }
10415 });
10416 };
10417
10418 /**
10419 * @param {HTMLElement} el
10420 * @param {string[]} allowedAttributes
10421 */
10422 const showWarningsForAttributes = (el, allowedAttributes) => {
10423 Array.from(el.attributes).forEach(attribute => {
10424 if (allowedAttributes.indexOf(attribute.name) === -1) {
10425 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.'}`]);
10426 }
10427 });
10428 };
10429
10430 const SHOW_CLASS_TIMEOUT = 10;
10431
10432 /**
10433 * Open popup, add necessary classes and styles, fix scrollbar
10434 *
10435 * @param {SweetAlertOptions} params
10436 */
10437 const openPopup = params => {
10438 var _globalState$eventEmi, _globalState$eventEmi2;
10439 const container = getContainer();
10440 const popup = getPopup();
10441 if (!container || !popup) {
10442 return;
10443 }
10444 if (typeof params.willOpen === 'function') {
10445 params.willOpen(popup);
10446 }
10447 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
10448 const bodyStyles = window.getComputedStyle(document.body);
10449 const initialBodyOverflow = bodyStyles.overflowY;
10450 addClasses(container, popup, params);
10451
10452 // scrolling is 'hidden' until animation is done, after that 'auto'
10453 setTimeout(() => {
10454 setScrollingVisibility(container, popup);
10455 }, SHOW_CLASS_TIMEOUT);
10456 if (isModal()) {
10457 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
10458 setAriaHidden();
10459 }
10460
10461 // https://github.com/sweetalert2/sweetalert2/issues/2923
10462 if (isIOS && params.backdrop === false && popup.scrollHeight > container.clientHeight) {
10463 // remove pointer-events: none from container, it breaks scrolling tall popups in iOS
10464 container.style.pointerEvents = 'auto';
10465 }
10466 if (!isToast() && !globalState.previousActiveElement) {
10467 globalState.previousActiveElement = document.activeElement;
10468 }
10469 if (typeof params.didOpen === 'function') {
10470 const didOpen = params.didOpen;
10471 setTimeout(() => didOpen(popup));
10472 }
10473 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
10474 };
10475
10476 /**
10477 * @param {Event} event
10478 */
10479 const swalOpenAnimationFinished = event => {
10480 const popup = getPopup();
10481 if (!popup || event.target !== popup) {
10482 return;
10483 }
10484 const container = getContainer();
10485 if (!container) {
10486 return;
10487 }
10488 popup.removeEventListener('animationend', swalOpenAnimationFinished);
10489 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
10490 container.style.overflowY = 'auto';
10491
10492 // no-transition is added in init() in case one swal is opened right after another
10493 removeClass(container, swalClasses['no-transition']);
10494 };
10495
10496 /**
10497 * @param {HTMLElement} container
10498 * @param {HTMLElement} popup
10499 */
10500 const setScrollingVisibility = (container, popup) => {
10501 if (hasCssAnimation(popup)) {
10502 container.style.overflowY = 'hidden';
10503 popup.addEventListener('animationend', swalOpenAnimationFinished);
10504 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10505 } else {
10506 container.style.overflowY = 'auto';
10507 }
10508 };
10509
10510 /**
10511 * @param {HTMLElement} container
10512 * @param {boolean} scrollbarPadding
10513 * @param {string} initialBodyOverflow
10514 */
10515 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10516 iOSfix();
10517 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10518 replaceScrollbarWithPadding(initialBodyOverflow);
10519 }
10520
10521 // sweetalert2/issues/1247
10522 setTimeout(() => {
10523 container.scrollTop = 0;
10524 });
10525 };
10526
10527 /**
10528 * @param {HTMLElement} container
10529 * @param {HTMLElement} popup
10530 * @param {SweetAlertOptions} params
10531 */
10532 const addClasses = (container, popup, params) => {
10533 var _params$showClass;
10534 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
10535 addClass(container, params.showClass.backdrop);
10536 }
10537 if (params.animation) {
10538 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10539 popup.style.setProperty('opacity', '0', 'important');
10540 show(popup, 'grid');
10541 setTimeout(() => {
10542 var _params$showClass2;
10543 // Animate popup right after showing it
10544 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
10545 addClass(popup, params.showClass.popup);
10546 }
10547 // and remove the opacity workaround
10548 popup.style.removeProperty('opacity');
10549 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10550 } else {
10551 show(popup, 'grid');
10552 }
10553 addClass([document.documentElement, document.body], swalClasses.shown);
10554 if (params.heightAuto && params.backdrop && !params.toast) {
10555 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10556 }
10557 };
10558
10559 var defaultInputValidators = {
10560 /**
10561 * @param {string} string
10562 * @param {string} [validationMessage]
10563 * @returns {Promise<string | void>}
10564 */
10565 email: (string, validationMessage) => {
10566 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10567 },
10568 /**
10569 * @param {string} string
10570 * @param {string} [validationMessage]
10571 * @returns {Promise<string | void>}
10572 */
10573 url: (string, validationMessage) => {
10574 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10575 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');
10576 }
10577 };
10578
10579 /**
10580 * @param {SweetAlertOptions} params
10581 */
10582 function setDefaultInputValidators(params) {
10583 // Use default `inputValidator` for supported input types if not provided
10584 if (params.inputValidator) {
10585 return;
10586 }
10587 if (params.input === 'email') {
10588 params.inputValidator = defaultInputValidators['email'];
10589 }
10590 if (params.input === 'url') {
10591 params.inputValidator = defaultInputValidators['url'];
10592 }
10593 }
10594
10595 /**
10596 * @param {SweetAlertOptions} params
10597 */
10598 function validateCustomTargetElement(params) {
10599 // Determine if the custom target element is valid
10600 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10601 warn('Target parameter is not valid, defaulting to "body"');
10602 params.target = 'body';
10603 }
10604 }
10605
10606 /**
10607 * Set type, text and actions on popup
10608 *
10609 * @param {SweetAlertOptions} params
10610 */
10611 function setParameters(params) {
10612 setDefaultInputValidators(params);
10613
10614 // showLoaderOnConfirm && preConfirm
10615 if (params.showLoaderOnConfirm && !params.preConfirm) {
10616 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');
10617 }
10618 validateCustomTargetElement(params);
10619
10620 // Replace newlines with <br> in title
10621 if (typeof params.title === 'string') {
10622 params.title = params.title.split('\n').join('<br />');
10623 }
10624 init(params);
10625 }
10626
10627 /** @type {SweetAlert} */
10628 let currentInstance;
10629 var _promise = /*#__PURE__*/new WeakMap();
10630 class SweetAlert {
10631 /**
10632 * @param {...(SweetAlertOptions | string)} args
10633 * @this {SweetAlert}
10634 */
10635 constructor(...args) {
10636 /**
10637 * @type {Promise<SweetAlertResult>}
10638 */
10639 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */
10640 Promise.resolve({
10641 isConfirmed: false,
10642 isDenied: false,
10643 isDismissed: true
10644 }));
10645 // Prevent run in Node env
10646 if (typeof window === 'undefined') {
10647 return;
10648 }
10649 currentInstance = this;
10650
10651 // @ts-ignore
10652 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10653
10654 /** @type {Readonly<SweetAlertOptions>} */
10655 this.params = outerParams;
10656
10657 /** @type {boolean} */
10658 this.isAwaitingPromise = false;
10659 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10660 }
10661
10662 /**
10663 * @param {any} userParams
10664 * @param {any} mixinParams
10665 */
10666 _main(userParams, mixinParams = {}) {
10667 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10668 if (globalState.currentInstance) {
10669 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10670 const {
10671 isAwaitingPromise
10672 } = globalState.currentInstance;
10673 globalState.currentInstance._destroy();
10674 if (!isAwaitingPromise) {
10675 swalPromiseResolve({
10676 isDismissed: true
10677 });
10678 }
10679 if (isModal()) {
10680 unsetAriaHidden();
10681 }
10682 }
10683 globalState.currentInstance = currentInstance;
10684 const innerParams = prepareParams(userParams, mixinParams);
10685 setParameters(innerParams);
10686 Object.freeze(innerParams);
10687
10688 // clear the previous timer
10689 if (globalState.timeout) {
10690 globalState.timeout.stop();
10691 delete globalState.timeout;
10692 }
10693
10694 // clear the restore focus timeout
10695 clearTimeout(globalState.restoreFocusTimeout);
10696 const domCache = populateDomCache(currentInstance);
10697 render(currentInstance, innerParams);
10698 privateProps.innerParams.set(currentInstance, innerParams);
10699 return swalPromise(currentInstance, domCache, innerParams);
10700 }
10701
10702 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10703 /**
10704 * @param {any} onFulfilled
10705 */
10706 // oxlint-disable-next-line unicorn/no-thenable
10707 then(onFulfilled) {
10708 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10709 }
10710
10711 /**
10712 * @param {any} onFinally
10713 */
10714 finally(onFinally) {
10715 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10716 }
10717 }
10718
10719 /**
10720 * @param {SweetAlert} instance
10721 * @param {DomCache} domCache
10722 * @param {SweetAlertOptions} innerParams
10723 * @returns {Promise<SweetAlertResult>}
10724 */
10725 const swalPromise = (instance, domCache, innerParams) => {
10726 return new Promise((resolve, reject) => {
10727 // functions to handle all closings/dismissals
10728 /**
10729 * @param {DismissReason} dismiss
10730 */
10731 const dismissWith = dismiss => {
10732 instance.close({
10733 isDismissed: true,
10734 dismiss,
10735 isConfirmed: false,
10736 isDenied: false
10737 });
10738 };
10739 privateMethods.swalPromiseResolve.set(instance, resolve);
10740 privateMethods.swalPromiseReject.set(instance, reject);
10741 domCache.confirmButton.onclick = () => {
10742 handleConfirmButtonClick(instance);
10743 };
10744 domCache.denyButton.onclick = () => {
10745 handleDenyButtonClick(instance);
10746 };
10747 domCache.cancelButton.onclick = () => {
10748 handleCancelButtonClick(instance, dismissWith);
10749 };
10750 domCache.closeButton.onclick = () => {
10751 dismissWith(DismissReason.close);
10752 };
10753 handlePopupClick(innerParams, domCache, dismissWith);
10754 addKeydownHandler(globalState, innerParams, dismissWith);
10755 handleInputOptionsAndValue(instance, innerParams);
10756 openPopup(innerParams);
10757 setupTimer(globalState, innerParams, dismissWith);
10758 initFocus(domCache, innerParams);
10759
10760 // Scroll container to top on open (#1247, #1946)
10761 setTimeout(() => {
10762 domCache.container.scrollTop = 0;
10763 });
10764 });
10765 };
10766
10767 /**
10768 * @param {SweetAlertOptions} userParams
10769 * @param {SweetAlertOptions} mixinParams
10770 * @returns {SweetAlertOptions}
10771 */
10772 const prepareParams = (userParams, mixinParams) => {
10773 const templateParams = getTemplateParams(userParams);
10774 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10775 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10776 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10777 if (params.animation === false) {
10778 params.showClass = {
10779 backdrop: 'swal2-noanimation'
10780 };
10781 params.hideClass = {};
10782 }
10783 return params;
10784 };
10785
10786 /**
10787 * @param {SweetAlert} instance
10788 * @returns {DomCache}
10789 */
10790 const populateDomCache = instance => {
10791 const domCache = /** @type {DomCache} */{
10792 popup: (/** @type {HTMLElement} */getPopup()),
10793 container: (/** @type {HTMLElement} */getContainer()),
10794 actions: (/** @type {HTMLElement} */getActions()),
10795 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
10796 denyButton: (/** @type {HTMLElement} */getDenyButton()),
10797 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
10798 loader: (/** @type {HTMLElement} */getLoader()),
10799 closeButton: (/** @type {HTMLElement} */getCloseButton()),
10800 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
10801 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
10802 };
10803 privateProps.domCache.set(instance, domCache);
10804 return domCache;
10805 };
10806
10807 /**
10808 * @param {GlobalState} globalState
10809 * @param {SweetAlertOptions} innerParams
10810 * @param {(dismiss: DismissReason) => void} dismissWith
10811 */
10812 const setupTimer = (globalState, innerParams, dismissWith) => {
10813 const timerProgressBar = getTimerProgressBar();
10814 hide(timerProgressBar);
10815 if (innerParams.timer) {
10816 globalState.timeout = new Timer(() => {
10817 dismissWith('timer');
10818 delete globalState.timeout;
10819 }, innerParams.timer);
10820 if (innerParams.timerProgressBar && timerProgressBar) {
10821 show(timerProgressBar);
10822 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10823 setTimeout(() => {
10824 if (globalState.timeout && globalState.timeout.running) {
10825 // timer can be already stopped or unset at this point
10826 animateTimerProgressBar(/** @type {number} */innerParams.timer);
10827 }
10828 });
10829 }
10830 }
10831 };
10832
10833 /**
10834 * Initialize focus in the popup:
10835 *
10836 * 1. If `toast` is `true`, don't steal focus from the document.
10837 * 2. Else if there is an [autofocus] element, focus it.
10838 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10839 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10840 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10841 * 6. Else focus the first focusable element in a popup (if any).
10842 *
10843 * @param {DomCache} domCache
10844 * @param {SweetAlertOptions} innerParams
10845 */
10846 const initFocus = (domCache, innerParams) => {
10847 if (innerParams.toast) {
10848 return;
10849 }
10850 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10851 if (!callIfFunction(innerParams.allowEnterKey)) {
10852 warnAboutDeprecation('allowEnterKey', 'preConfirm: () => false');
10853 domCache.popup.focus();
10854 return;
10855 }
10856 if (focusAutofocus(domCache)) {
10857 return;
10858 }
10859 if (focusButton(domCache, innerParams)) {
10860 return;
10861 }
10862 setFocus(-1, 1);
10863 };
10864
10865 /**
10866 * @param {DomCache} domCache
10867 * @returns {boolean}
10868 */
10869 const focusAutofocus = domCache => {
10870 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10871 for (const autofocusElement of autofocusElements) {
10872 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10873 autofocusElement.focus();
10874 return true;
10875 }
10876 }
10877 return false;
10878 };
10879
10880 /**
10881 * @param {DomCache} domCache
10882 * @param {SweetAlertOptions} innerParams
10883 * @returns {boolean}
10884 */
10885 const focusButton = (domCache, innerParams) => {
10886 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10887 domCache.denyButton.focus();
10888 return true;
10889 }
10890 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10891 domCache.cancelButton.focus();
10892 return true;
10893 }
10894 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10895 domCache.confirmButton.focus();
10896 return true;
10897 }
10898 return false;
10899 };
10900
10901 // Assign instance methods from src/instanceMethods/*.js to prototype
10902 SweetAlert.prototype.disableButtons = disableButtons;
10903 SweetAlert.prototype.enableButtons = enableButtons;
10904 SweetAlert.prototype.getInput = getInput;
10905 SweetAlert.prototype.disableInput = disableInput;
10906 SweetAlert.prototype.enableInput = enableInput;
10907 SweetAlert.prototype.hideLoading = hideLoading;
10908 SweetAlert.prototype.disableLoading = hideLoading;
10909 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10910 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10911 SweetAlert.prototype.close = close;
10912 SweetAlert.prototype.closePopup = close;
10913 SweetAlert.prototype.closeModal = close;
10914 SweetAlert.prototype.closeToast = close;
10915 SweetAlert.prototype.rejectPromise = rejectPromise;
10916 SweetAlert.prototype.update = update;
10917 SweetAlert.prototype._destroy = _destroy;
10918
10919 // Assign static methods from src/staticMethods/*.js to constructor
10920 Object.assign(SweetAlert, staticMethods);
10921
10922 // Proxy to instance methods to constructor, for now, for backwards compatibility
10923 Object.keys(instanceMethods).forEach(key => {
10924 /**
10925 * @param {...(SweetAlertOptions | string | undefined)} args
10926 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
10927 */
10928 // @ts-ignore: Dynamic property assignment for backwards compatibility
10929 SweetAlert[key] = function (...args) {
10930 // @ts-ignore
10931 if (currentInstance && currentInstance[key]) {
10932 // @ts-ignore
10933 return currentInstance[key](...args);
10934 }
10935 return undefined;
10936 };
10937 });
10938 SweetAlert.DismissReason = DismissReason;
10939 SweetAlert.version = '11.26.25';
10940
10941 const Swal = SweetAlert;
10942 // @ts-ignore
10943 Swal.default = Swal;
10944
10945 return Swal;
10946
10947 }));
10948 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10949 "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}}");
10950
10951 /***/ },
10952
10953 /***/ "./node_modules/toastify-js/src/toastify.js"
10954 /*!**************************************************!*\
10955 !*** ./node_modules/toastify-js/src/toastify.js ***!
10956 \**************************************************/
10957 (module) {
10958
10959 /*!
10960 * Toastify js 1.12.0
10961 * https://github.com/apvarun/toastify-js
10962 * @license MIT licensed
10963 *
10964 * Copyright (C) 2018 Varun A P
10965 */
10966 (function(root, factory) {
10967 if ( true && module.exports) {
10968 module.exports = factory();
10969 } else {
10970 root.Toastify = factory();
10971 }
10972 })(this, function(global) {
10973 // Object initialization
10974 var Toastify = function(options) {
10975 // Returning a new init object
10976 return new Toastify.lib.init(options);
10977 },
10978 // Library version
10979 version = "1.12.0";
10980
10981 // Set the default global options
10982 Toastify.defaults = {
10983 oldestFirst: true,
10984 text: "Toastify is awesome!",
10985 node: undefined,
10986 duration: 3000,
10987 selector: undefined,
10988 callback: function () {
10989 },
10990 destination: undefined,
10991 newWindow: false,
10992 close: false,
10993 gravity: "toastify-top",
10994 positionLeft: false,
10995 position: '',
10996 backgroundColor: '',
10997 avatar: "",
10998 className: "",
10999 stopOnFocus: true,
11000 onClick: function () {
11001 },
11002 offset: {x: 0, y: 0},
11003 escapeMarkup: true,
11004 ariaLive: 'polite',
11005 style: {background: ''}
11006 };
11007
11008 // Defining the prototype of the object
11009 Toastify.lib = Toastify.prototype = {
11010 toastify: version,
11011
11012 constructor: Toastify,
11013
11014 // Initializing the object with required parameters
11015 init: function(options) {
11016 // Verifying and validating the input object
11017 if (!options) {
11018 options = {};
11019 }
11020
11021 // Creating the options object
11022 this.options = {};
11023
11024 this.toastElement = null;
11025
11026 // Validating the options
11027 this.options.text = options.text || Toastify.defaults.text; // Display message
11028 this.options.node = options.node || Toastify.defaults.node; // Display content as node
11029 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
11030 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
11031 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
11032 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
11033 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
11034 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
11035 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
11036 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
11037 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
11038 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
11039 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
11040 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
11041 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
11042 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
11043 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
11044 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
11045 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
11046 this.options.style = options.style || Toastify.defaults.style;
11047 if(options.backgroundColor) {
11048 this.options.style.background = options.backgroundColor;
11049 }
11050
11051 // Returning the current object for chaining functions
11052 return this;
11053 },
11054
11055 // Building the DOM element
11056 buildToast: function() {
11057 // Validating if the options are defined
11058 if (!this.options) {
11059 throw "Toastify is not initialized";
11060 }
11061
11062 // Creating the DOM object
11063 var divElement = document.createElement("div");
11064 divElement.className = "toastify on " + this.options.className;
11065
11066 // Positioning toast to left or right or center
11067 if (!!this.options.position) {
11068 divElement.className += " toastify-" + this.options.position;
11069 } else {
11070 // To be depreciated in further versions
11071 if (this.options.positionLeft === true) {
11072 divElement.className += " toastify-left";
11073 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
11074 } else {
11075 // Default position
11076 divElement.className += " toastify-right";
11077 }
11078 }
11079
11080 // Assigning gravity of element
11081 divElement.className += " " + this.options.gravity;
11082
11083 if (this.options.backgroundColor) {
11084 // This is being deprecated in favor of using the style HTML DOM property
11085 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
11086 }
11087
11088 // Loop through our style object and apply styles to divElement
11089 for (var property in this.options.style) {
11090 divElement.style[property] = this.options.style[property];
11091 }
11092
11093 // Announce the toast to screen readers
11094 if (this.options.ariaLive) {
11095 divElement.setAttribute('aria-live', this.options.ariaLive)
11096 }
11097
11098 // Adding the toast message/node
11099 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
11100 // If we have a valid node, we insert it
11101 divElement.appendChild(this.options.node)
11102 } else {
11103 if (this.options.escapeMarkup) {
11104 divElement.innerText = this.options.text;
11105 } else {
11106 divElement.innerHTML = this.options.text;
11107 }
11108
11109 if (this.options.avatar !== "") {
11110 var avatarElement = document.createElement("img");
11111 avatarElement.src = this.options.avatar;
11112
11113 avatarElement.className = "toastify-avatar";
11114
11115 if (this.options.position == "left" || this.options.positionLeft === true) {
11116 // Adding close icon on the left of content
11117 divElement.appendChild(avatarElement);
11118 } else {
11119 // Adding close icon on the right of content
11120 divElement.insertAdjacentElement("afterbegin", avatarElement);
11121 }
11122 }
11123 }
11124
11125 // Adding a close icon to the toast
11126 if (this.options.close === true) {
11127 // Create a span for close element
11128 var closeElement = document.createElement("button");
11129 closeElement.type = "button";
11130 closeElement.setAttribute("aria-label", "Close");
11131 closeElement.className = "toast-close";
11132 closeElement.innerHTML = "&#10006;";
11133
11134 // Triggering the removal of toast from DOM on close click
11135 closeElement.addEventListener(
11136 "click",
11137 function(event) {
11138 event.stopPropagation();
11139 this.removeElement(this.toastElement);
11140 window.clearTimeout(this.toastElement.timeOutValue);
11141 }.bind(this)
11142 );
11143
11144 //Calculating screen width
11145 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11146
11147 // Adding the close icon to the toast element
11148 // Display on the right if screen width is less than or equal to 360px
11149 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
11150 // Adding close icon on the left of content
11151 divElement.insertAdjacentElement("afterbegin", closeElement);
11152 } else {
11153 // Adding close icon on the right of content
11154 divElement.appendChild(closeElement);
11155 }
11156 }
11157
11158 // Clear timeout while toast is focused
11159 if (this.options.stopOnFocus && this.options.duration > 0) {
11160 var self = this;
11161 // stop countdown
11162 divElement.addEventListener(
11163 "mouseover",
11164 function(event) {
11165 window.clearTimeout(divElement.timeOutValue);
11166 }
11167 )
11168 // add back the timeout
11169 divElement.addEventListener(
11170 "mouseleave",
11171 function() {
11172 divElement.timeOutValue = window.setTimeout(
11173 function() {
11174 // Remove the toast from DOM
11175 self.removeElement(divElement);
11176 },
11177 self.options.duration
11178 )
11179 }
11180 )
11181 }
11182
11183 // Adding an on-click destination path
11184 if (typeof this.options.destination !== "undefined") {
11185 divElement.addEventListener(
11186 "click",
11187 function(event) {
11188 event.stopPropagation();
11189 if (this.options.newWindow === true) {
11190 window.open(this.options.destination, "_blank");
11191 } else {
11192 window.location = this.options.destination;
11193 }
11194 }.bind(this)
11195 );
11196 }
11197
11198 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
11199 divElement.addEventListener(
11200 "click",
11201 function(event) {
11202 event.stopPropagation();
11203 this.options.onClick();
11204 }.bind(this)
11205 );
11206 }
11207
11208 // Adding offset
11209 if(typeof this.options.offset === "object") {
11210
11211 var x = getAxisOffsetAValue("x", this.options);
11212 var y = getAxisOffsetAValue("y", this.options);
11213
11214 var xOffset = this.options.position == "left" ? x : "-" + x;
11215 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
11216
11217 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
11218
11219 }
11220
11221 // Returning the generated element
11222 return divElement;
11223 },
11224
11225 // Displaying the toast
11226 showToast: function() {
11227 // Creating the DOM object for the toast
11228 this.toastElement = this.buildToast();
11229
11230 // Getting the root element to with the toast needs to be added
11231 var rootElement;
11232 if (typeof this.options.selector === "string") {
11233 rootElement = document.getElementById(this.options.selector);
11234 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
11235 rootElement = this.options.selector;
11236 } else {
11237 rootElement = document.body;
11238 }
11239
11240 // Validating if root element is present in DOM
11241 if (!rootElement) {
11242 throw "Root element is not defined";
11243 }
11244
11245 // Adding the DOM element
11246 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
11247 rootElement.insertBefore(this.toastElement, elementToInsert);
11248
11249 // Repositioning the toasts in case multiple toasts are present
11250 Toastify.reposition();
11251
11252 if (this.options.duration > 0) {
11253 this.toastElement.timeOutValue = window.setTimeout(
11254 function() {
11255 // Remove the toast from DOM
11256 this.removeElement(this.toastElement);
11257 }.bind(this),
11258 this.options.duration
11259 ); // Binding `this` for function invocation
11260 }
11261
11262 // Supporting function chaining
11263 return this;
11264 },
11265
11266 hideToast: function() {
11267 if (this.toastElement.timeOutValue) {
11268 clearTimeout(this.toastElement.timeOutValue);
11269 }
11270 this.removeElement(this.toastElement);
11271 },
11272
11273 // Removing the element from the DOM
11274 removeElement: function(toastElement) {
11275 // Hiding the element
11276 // toastElement.classList.remove("on");
11277 toastElement.className = toastElement.className.replace(" on", "");
11278
11279 // Removing the element from DOM after transition end
11280 window.setTimeout(
11281 function() {
11282 // remove options node if any
11283 if (this.options.node && this.options.node.parentNode) {
11284 this.options.node.parentNode.removeChild(this.options.node);
11285 }
11286
11287 // Remove the element from the DOM, only when the parent node was not removed before.
11288 if (toastElement.parentNode) {
11289 toastElement.parentNode.removeChild(toastElement);
11290 }
11291
11292 // Calling the callback function
11293 this.options.callback.call(toastElement);
11294
11295 // Repositioning the toasts again
11296 Toastify.reposition();
11297 }.bind(this),
11298 400
11299 ); // Binding `this` for function invocation
11300 },
11301 };
11302
11303 // Positioning the toasts on the DOM
11304 Toastify.reposition = function() {
11305
11306 // Top margins with gravity
11307 var topLeftOffsetSize = {
11308 top: 15,
11309 bottom: 15,
11310 };
11311 var topRightOffsetSize = {
11312 top: 15,
11313 bottom: 15,
11314 };
11315 var offsetSize = {
11316 top: 15,
11317 bottom: 15,
11318 };
11319
11320 // Get all toast messages on the DOM
11321 var allToasts = document.getElementsByClassName("toastify");
11322
11323 var classUsed;
11324
11325 // Modifying the position of each toast element
11326 for (var i = 0; i < allToasts.length; i++) {
11327 // Getting the applied gravity
11328 if (containsClass(allToasts[i], "toastify-top") === true) {
11329 classUsed = "toastify-top";
11330 } else {
11331 classUsed = "toastify-bottom";
11332 }
11333
11334 var height = allToasts[i].offsetHeight;
11335 classUsed = classUsed.substr(9, classUsed.length-1)
11336 // Spacing between toasts
11337 var offset = 15;
11338
11339 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11340
11341 // Show toast in center if screen with less than or equal to 360px
11342 if (width <= 360) {
11343 // Setting the position
11344 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
11345
11346 offsetSize[classUsed] += height + offset;
11347 } else {
11348 if (containsClass(allToasts[i], "toastify-left") === true) {
11349 // Setting the position
11350 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
11351
11352 topLeftOffsetSize[classUsed] += height + offset;
11353 } else {
11354 // Setting the position
11355 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
11356
11357 topRightOffsetSize[classUsed] += height + offset;
11358 }
11359 }
11360 }
11361
11362 // Supporting function chaining
11363 return this;
11364 };
11365
11366 // Helper function to get offset.
11367 function getAxisOffsetAValue(axis, options) {
11368
11369 if(options.offset[axis]) {
11370 if(isNaN(options.offset[axis])) {
11371 return options.offset[axis];
11372 }
11373 else {
11374 return options.offset[axis] + 'px';
11375 }
11376 }
11377
11378 return '0px';
11379
11380 }
11381
11382 function containsClass(elem, yourClass) {
11383 if (!elem || typeof yourClass !== "string") {
11384 return false;
11385 } else if (
11386 elem.className &&
11387 elem.className
11388 .trim()
11389 .split(/\s+/gi)
11390 .indexOf(yourClass) > -1
11391 ) {
11392 return true;
11393 } else {
11394 return false;
11395 }
11396 }
11397
11398 // Setting up the prototype for the init object
11399 Toastify.lib.init.prototype = Toastify.lib;
11400
11401 // Returning the Toastify function to be assigned to the window object/module
11402 return Toastify;
11403 });
11404
11405
11406 /***/ },
11407
11408 /***/ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"
11409 /*!**************************************************************************************************************************************************************************************************************************************************************!*\
11410 !*** data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC ***!
11411 \**************************************************************************************************************************************************************************************************************************************************************/
11412 (module) {
11413
11414 "use strict";
11415 module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC";
11416
11417 /***/ }
11418
11419 /******/ });
11420 /************************************************************************/
11421 /******/ // The module cache
11422 /******/ const __webpack_module_cache__ = {};
11423 /******/
11424 /******/ // The require function
11425 /******/ function __webpack_require__(moduleId) {
11426 /******/ // Check if module is in cache
11427 /******/ const cachedModule = __webpack_module_cache__[moduleId];
11428 /******/ if (cachedModule !== undefined) {
11429 /******/ return cachedModule.exports;
11430 /******/ }
11431 /******/ // Create a new module (and put it into the cache)
11432 /******/ const module = __webpack_module_cache__[moduleId] = {
11433 /******/ id: moduleId,
11434 /******/ // no module.loaded needed
11435 /******/ exports: {}
11436 /******/ };
11437 /******/
11438 /******/ // Execute the module function
11439 /******/ if (!(moduleId in __webpack_modules__)) {
11440 /******/ delete __webpack_module_cache__[moduleId];
11441 /******/ const e = new Error("Cannot find module '" + moduleId + "'");
11442 /******/ e.code = 'MODULE_NOT_FOUND';
11443 /******/ throw e;
11444 /******/ }
11445 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11446 /******/
11447 /******/ // Return the exports of the module
11448 /******/ return module.exports;
11449 /******/ }
11450 /******/
11451 /******/ // expose the modules object (__webpack_modules__)
11452 /******/ __webpack_require__.m = __webpack_modules__;
11453 /******/
11454 /************************************************************************/
11455 /******/ /* webpack/runtime/compat get default export */
11456 /******/ (() => {
11457 /******/ // getDefaultExport function for compatibility with non-harmony modules
11458 /******/ __webpack_require__.n = (module) => {
11459 /******/ const getter = module && module.__esModule ?
11460 /******/ () => (module['default']) :
11461 /******/ () => (module);
11462 /******/ __webpack_require__.d(getter, { a: getter });
11463 /******/ return getter;
11464 /******/ };
11465 /******/ })();
11466 /******/
11467 /******/ /* webpack/runtime/define property getters */
11468 /******/ (() => {
11469 /******/ // define getter/value functions for harmony exports
11470 /******/ __webpack_require__.d = (exports, definition) => {
11471 /******/ if(Array.isArray(definition)) {
11472 /******/ var i = 0;
11473 /******/ while(i < definition.length) {
11474 /******/ var key = definition[i++];
11475 /******/ var binding = definition[i++];
11476 /******/ if(!__webpack_require__.o(exports, key)) {
11477 /******/ if(binding === 0) {
11478 /******/ Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
11479 /******/ } else {
11480 /******/ Object.defineProperty(exports, key, { enumerable: true, get: binding });
11481 /******/ }
11482 /******/ } else if(binding === 0) { i++; }
11483 /******/ }
11484 /******/ } else {
11485 /******/ for(var key in definition) {
11486 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11487 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11488 /******/ }
11489 /******/ }
11490 /******/ }
11491 /******/ };
11492 /******/ })();
11493 /******/
11494 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11495 /******/ (() => {
11496 /******/ __webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
11497 /******/ })();
11498 /******/
11499 /******/ /* webpack/runtime/make namespace object */
11500 /******/ (() => {
11501 /******/ // define __esModule on exports
11502 /******/ __webpack_require__.r = (exports) => {
11503 /******/ if(Symbol.toStringTag) {
11504 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11505 /******/ }
11506 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11507 /******/ };
11508 /******/ })();
11509 /******/
11510 /******/ /* webpack/runtime/jsonp chunk loading */
11511 /******/ (() => {
11512 /******/ __webpack_require__.b = (typeof document !== 'undefined' && document.baseURI) || self.location.href;
11513 /******/
11514 /******/ // object to store loaded and loading chunks
11515 /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
11516 /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
11517 /******/ const installedChunks = {
11518 /******/ "./assets/js/dist/frontend/profile": 0
11519 /******/ };
11520 /******/
11521 /******/ // no chunk on demand loading
11522 /******/
11523 /******/ // no prefetching
11524 /******/
11525 /******/ // no preloaded
11526 /******/
11527 /******/ // no HMR
11528 /******/
11529 /******/ // no HMR manifest
11530 /******/
11531 /******/ // no on chunks loaded
11532 /******/
11533 /******/ // no jsonp function
11534 /******/ })();
11535 /******/
11536 /******/ /* webpack/runtime/nonce */
11537 /******/ (() => {
11538 /******/ __webpack_require__.nc = undefined;
11539 /******/ })();
11540 /******/
11541 /************************************************************************/
11542 let __webpack_exports__ = {};
11543 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11544 (() => {
11545 "use strict";
11546 /*!*******************************************!*\
11547 !*** ./assets/src/js/frontend/profile.js ***!
11548 \*******************************************/
11549 __webpack_require__.r(__webpack_exports__);
11550 /* harmony import */ var _profile_course_tab__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./profile/course-tab */ "./assets/src/js/frontend/profile/course-tab.js");
11551 /* harmony import */ var _profile_statistic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./profile/statistic */ "./assets/src/js/frontend/profile/statistic.js");
11552 /* harmony import */ var _profile_order_recover__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./profile/order-recover */ "./assets/src/js/frontend/profile/order-recover.js");
11553 /* harmony import */ var _profile_cover_image__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./profile/cover-image */ "./assets/src/js/frontend/profile/cover-image.js");
11554 /* harmony import */ var _profile_avatar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./profile/avatar */ "./assets/src/js/frontend/profile/avatar.js");
11555 /* harmony import */ var _profile_quiz__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./profile/quiz */ "./assets/src/js/frontend/profile/quiz.js");
11556 /* harmony import */ var _profile_order_refund__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./profile/order-refund */ "./assets/src/js/frontend/profile/order-refund.js");
11557 /* harmony import */ var _admin_courses_view_students_modal__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../admin/courses/view-students-modal */ "./assets/src/js/admin/courses/view-students-modal.js");
11558
11559
11560
11561
11562
11563
11564
11565
11566 (0,_profile_cover_image__WEBPACK_IMPORTED_MODULE_3__["default"])();
11567 (0,_profile_quiz__WEBPACK_IMPORTED_MODULE_5__["default"])();
11568 (0,_profile_statistic__WEBPACK_IMPORTED_MODULE_1__["default"])();
11569 (0,_profile_order_recover__WEBPACK_IMPORTED_MODULE_2__["default"])();
11570 (0,_profile_order_refund__WEBPACK_IMPORTED_MODULE_6__["default"])();
11571 new _admin_courses_view_students_modal__WEBPACK_IMPORTED_MODULE_7__.ViewStudentsModal();
11572 document.addEventListener('DOMContentLoaded', function (event) {
11573 (0,_profile_course_tab__WEBPACK_IMPORTED_MODULE_0__["default"])();
11574 });
11575 if (document.getElementById('learnpress-avatar-upload')) {
11576 (0,_profile_avatar__WEBPACK_IMPORTED_MODULE_4__["default"])();
11577 }
11578 })();
11579
11580 /******/ })()
11581 ;
11582 //# sourceMappingURL=profile.js.map