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

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

11,605 lines 416.7 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.17
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 * Gets the popup container which contains the backdrop and the popup itself.
6337 *
6338 * @returns {HTMLElement | null}
6339 */
6340 const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);
6341
6342 /**
6343 * @param {string} selectorString
6344 * @returns {HTMLElement | null}
6345 */
6346 const elementBySelector = selectorString => {
6347 const container = getContainer();
6348 return container ? container.querySelector(selectorString) : null;
6349 };
6350
6351 /**
6352 * @param {string} className
6353 * @returns {HTMLElement | null}
6354 */
6355 const elementByClass = className => {
6356 return elementBySelector(`.${className}`);
6357 };
6358
6359 /**
6360 * @returns {HTMLElement | null}
6361 */
6362 const getPopup = () => elementByClass(swalClasses.popup);
6363
6364 /**
6365 * @returns {HTMLElement | null}
6366 */
6367 const getIcon = () => elementByClass(swalClasses.icon);
6368
6369 /**
6370 * @returns {HTMLElement | null}
6371 */
6372 const getIconContent = () => elementByClass(swalClasses['icon-content']);
6373
6374 /**
6375 * @returns {HTMLElement | null}
6376 */
6377 const getTitle = () => elementByClass(swalClasses.title);
6378
6379 /**
6380 * @returns {HTMLElement | null}
6381 */
6382 const getHtmlContainer = () => elementByClass(swalClasses['html-container']);
6383
6384 /**
6385 * @returns {HTMLElement | null}
6386 */
6387 const getImage = () => elementByClass(swalClasses.image);
6388
6389 /**
6390 * @returns {HTMLElement | null}
6391 */
6392 const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);
6393
6394 /**
6395 * @returns {HTMLElement | null}
6396 */
6397 const getValidationMessage = () => elementByClass(swalClasses['validation-message']);
6398
6399 /**
6400 * @returns {HTMLButtonElement | null}
6401 */
6402 const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));
6403
6404 /**
6405 * @returns {HTMLButtonElement | null}
6406 */
6407 const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));
6408
6409 /**
6410 * @returns {HTMLButtonElement | null}
6411 */
6412 const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));
6413
6414 /**
6415 * @returns {HTMLElement | null}
6416 */
6417 const getInputLabel = () => elementByClass(swalClasses['input-label']);
6418
6419 /**
6420 * @returns {HTMLElement | null}
6421 */
6422 const getLoader = () => elementBySelector(`.${swalClasses.loader}`);
6423
6424 /**
6425 * @returns {HTMLElement | null}
6426 */
6427 const getActions = () => elementByClass(swalClasses.actions);
6428
6429 /**
6430 * @returns {HTMLElement | null}
6431 */
6432 const getFooter = () => elementByClass(swalClasses.footer);
6433
6434 /**
6435 * @returns {HTMLElement | null}
6436 */
6437 const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);
6438
6439 /**
6440 * @returns {HTMLElement | null}
6441 */
6442 const getCloseButton = () => elementByClass(swalClasses.close);
6443
6444 // https://github.com/jkup/focusable/blob/master/index.js
6445 const focusable = `
6446 a[href],
6447 area[href],
6448 input:not([disabled]),
6449 select:not([disabled]),
6450 textarea:not([disabled]),
6451 button:not([disabled]),
6452 iframe,
6453 object,
6454 embed,
6455 [tabindex="0"],
6456 [contenteditable],
6457 audio[controls],
6458 video[controls],
6459 summary
6460 `;
6461 /**
6462 * @returns {HTMLElement[]}
6463 */
6464 const getFocusableElements = () => {
6465 const popup = getPopup();
6466 if (!popup) {
6467 return [];
6468 }
6469 /** @type {NodeListOf<HTMLElement>} */
6470 const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
6471 const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
6472 // sort according to tabindex
6473 .sort((a, b) => {
6474 const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
6475 const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
6476 if (tabindexA > tabindexB) {
6477 return 1;
6478 } else if (tabindexA < tabindexB) {
6479 return -1;
6480 }
6481 return 0;
6482 });
6483
6484 /** @type {NodeListOf<HTMLElement>} */
6485 const otherFocusableElements = popup.querySelectorAll(focusable);
6486 const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
6487 return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
6488 };
6489
6490 /**
6491 * @returns {boolean}
6492 */
6493 const isModal = () => {
6494 return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
6495 };
6496
6497 /**
6498 * @returns {boolean}
6499 */
6500 const isToast = () => {
6501 const popup = getPopup();
6502 if (!popup) {
6503 return false;
6504 }
6505 return hasClass(popup, swalClasses.toast);
6506 };
6507
6508 /**
6509 * @returns {boolean}
6510 */
6511 const isLoading = () => {
6512 const popup = getPopup();
6513 if (!popup) {
6514 return false;
6515 }
6516 return popup.hasAttribute('data-loading');
6517 };
6518
6519 /**
6520 * Securely set innerHTML of an element
6521 * https://github.com/sweetalert2/sweetalert2/issues/1926
6522 *
6523 * @param {HTMLElement} elem
6524 * @param {string} html
6525 */
6526 const setInnerHtml = (elem, html) => {
6527 elem.textContent = '';
6528 if (html) {
6529 const parser = new DOMParser();
6530 const parsed = parser.parseFromString(html, `text/html`);
6531 const head = parsed.querySelector('head');
6532 if (head) {
6533 Array.from(head.childNodes).forEach(child => {
6534 elem.appendChild(child);
6535 });
6536 }
6537 const body = parsed.querySelector('body');
6538 if (body) {
6539 Array.from(body.childNodes).forEach(child => {
6540 if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
6541 elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
6542 } else {
6543 elem.appendChild(child);
6544 }
6545 });
6546 }
6547 }
6548 };
6549
6550 /**
6551 * @param {HTMLElement} elem
6552 * @param {string} className
6553 * @returns {boolean}
6554 */
6555 const hasClass = (elem, className) => {
6556 if (!className) {
6557 return false;
6558 }
6559 const classList = className.split(/\s+/);
6560 for (let i = 0; i < classList.length; i++) {
6561 if (!elem.classList.contains(classList[i])) {
6562 return false;
6563 }
6564 }
6565 return true;
6566 };
6567
6568 /**
6569 * @param {HTMLElement} elem
6570 * @param {SweetAlertOptions} params
6571 */
6572 const removeCustomClasses = (elem, params) => {
6573 Array.from(elem.classList).forEach(className => {
6574 if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
6575 elem.classList.remove(className);
6576 }
6577 });
6578 };
6579
6580 /**
6581 * @param {HTMLElement} elem
6582 * @param {SweetAlertOptions} params
6583 * @param {string} className
6584 */
6585 const applyCustomClass = (elem, params, className) => {
6586 removeCustomClasses(elem, params);
6587 if (!params.customClass) {
6588 return;
6589 }
6590 const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
6591 if (!customClass) {
6592 return;
6593 }
6594 if (typeof customClass !== 'string' && !customClass.forEach) {
6595 warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
6596 return;
6597 }
6598 addClass(elem, customClass);
6599 };
6600
6601 /**
6602 * @param {HTMLElement} popup
6603 * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
6604 * @returns {HTMLInputElement | null}
6605 */
6606 const getInput$1 = (popup, inputClass) => {
6607 if (!inputClass) {
6608 return null;
6609 }
6610 switch (inputClass) {
6611 case 'select':
6612 case 'textarea':
6613 case 'file':
6614 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
6615 case 'checkbox':
6616 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
6617 case 'radio':
6618 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
6619 case 'range':
6620 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
6621 default:
6622 return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
6623 }
6624 };
6625
6626 /**
6627 * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
6628 */
6629 const focusInput = input => {
6630 input.focus();
6631
6632 // place cursor at end of text in text input
6633 if (input.type !== 'file') {
6634 // http://stackoverflow.com/a/2345915
6635 const val = input.value;
6636 input.value = '';
6637 input.value = val;
6638 }
6639 };
6640
6641 /**
6642 * @param {HTMLElement | HTMLElement[] | null} target
6643 * @param {string | string[] | readonly string[] | undefined} classList
6644 * @param {boolean} condition
6645 */
6646 const toggleClass = (target, classList, condition) => {
6647 if (!target || !classList) {
6648 return;
6649 }
6650 if (typeof classList === 'string') {
6651 classList = classList.split(/\s+/).filter(Boolean);
6652 }
6653 classList.forEach(className => {
6654 if (Array.isArray(target)) {
6655 target.forEach(elem => {
6656 if (condition) {
6657 elem.classList.add(className);
6658 } else {
6659 elem.classList.remove(className);
6660 }
6661 });
6662 } else {
6663 if (condition) {
6664 target.classList.add(className);
6665 } else {
6666 target.classList.remove(className);
6667 }
6668 }
6669 });
6670 };
6671
6672 /**
6673 * @param {HTMLElement | HTMLElement[] | null} target
6674 * @param {string | string[] | readonly string[] | undefined} classList
6675 */
6676 const addClass = (target, classList) => {
6677 toggleClass(target, classList, true);
6678 };
6679
6680 /**
6681 * @param {HTMLElement | HTMLElement[] | null} target
6682 * @param {string | string[] | readonly string[] | undefined} classList
6683 */
6684 const removeClass = (target, classList) => {
6685 toggleClass(target, classList, false);
6686 };
6687
6688 /**
6689 * Get direct child of an element by class name
6690 *
6691 * @param {HTMLElement} elem
6692 * @param {string} className
6693 * @returns {HTMLElement | undefined}
6694 */
6695 const getDirectChildByClass = (elem, className) => {
6696 const children = Array.from(elem.children);
6697 for (let i = 0; i < children.length; i++) {
6698 const child = children[i];
6699 if (child instanceof HTMLElement && hasClass(child, className)) {
6700 return child;
6701 }
6702 }
6703 };
6704
6705 /**
6706 * @param {HTMLElement} elem
6707 * @param {string} property
6708 * @param {string | number | null | undefined} value
6709 */
6710 const applyNumericalStyle = (elem, property, value) => {
6711 if (value === `${parseInt(`${value}`)}`) {
6712 value = parseInt(value);
6713 }
6714 if (value || parseInt(`${value}`) === 0) {
6715 elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : (/** @type {string} */value));
6716 } else {
6717 elem.style.removeProperty(property);
6718 }
6719 };
6720
6721 /**
6722 * @param {HTMLElement | null} elem
6723 * @param {string} display
6724 */
6725 const show = (elem, display = 'flex') => {
6726 if (!elem) {
6727 return;
6728 }
6729 elem.style.display = display;
6730 };
6731
6732 /**
6733 * @param {HTMLElement | null} elem
6734 */
6735 const hide = elem => {
6736 if (!elem) {
6737 return;
6738 }
6739 elem.style.display = 'none';
6740 };
6741
6742 /**
6743 * @param {HTMLElement | null} elem
6744 * @param {string} display
6745 */
6746 const showWhenInnerHtmlPresent = (elem, display = 'block') => {
6747 if (!elem) {
6748 return;
6749 }
6750 new MutationObserver(() => {
6751 toggle(elem, elem.innerHTML, display);
6752 }).observe(elem, {
6753 childList: true,
6754 subtree: true
6755 });
6756 };
6757
6758 /**
6759 * @param {HTMLElement} parent
6760 * @param {string} selector
6761 * @param {string} property
6762 * @param {string} value
6763 */
6764 const setStyle = (parent, selector, property, value) => {
6765 /** @type {HTMLElement | null} */
6766 const el = parent.querySelector(selector);
6767 if (el) {
6768 el.style.setProperty(property, value);
6769 }
6770 };
6771
6772 /**
6773 * @param {HTMLElement} elem
6774 * @param {boolean | string | null | undefined} condition
6775 * @param {string} display
6776 */
6777 const toggle = (elem, condition, display = 'flex') => {
6778 if (condition) {
6779 show(elem, display);
6780 } else {
6781 hide(elem);
6782 }
6783 };
6784
6785 /**
6786 * borrowed from jquery $(elem).is(':visible') implementation
6787 *
6788 * @param {HTMLElement | null} elem
6789 * @returns {boolean}
6790 */
6791 const isVisible$1 = elem => Boolean(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));
6792
6793 /**
6794 * @returns {boolean}
6795 */
6796 const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());
6797
6798 /**
6799 * @param {HTMLElement} elem
6800 * @returns {boolean}
6801 */
6802 const isScrollable = elem => Boolean(elem.scrollHeight > elem.clientHeight);
6803
6804 /**
6805 * @param {HTMLElement} element
6806 * @param {HTMLElement} stopElement
6807 * @returns {boolean}
6808 */
6809 const selfOrParentIsScrollable = (element, stopElement) => {
6810 let parent = /** @type {HTMLElement | null} */element;
6811 while (parent && parent !== stopElement) {
6812 if (isScrollable(parent)) {
6813 return true;
6814 }
6815 parent = parent.parentElement;
6816 }
6817 return false;
6818 };
6819
6820 /**
6821 * borrowed from https://stackoverflow.com/a/46352119
6822 *
6823 * @param {HTMLElement} elem
6824 * @returns {boolean}
6825 */
6826 const hasCssAnimation = elem => {
6827 const style = window.getComputedStyle(elem);
6828 const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
6829 const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
6830 return animDuration > 0 || transDuration > 0;
6831 };
6832
6833 /**
6834 * @param {number} timer
6835 * @param {boolean} reset
6836 */
6837 const animateTimerProgressBar = (timer, reset = false) => {
6838 const timerProgressBar = getTimerProgressBar();
6839 if (!timerProgressBar) {
6840 return;
6841 }
6842 if (isVisible$1(timerProgressBar)) {
6843 if (reset) {
6844 timerProgressBar.style.transition = 'none';
6845 timerProgressBar.style.width = '100%';
6846 }
6847 setTimeout(() => {
6848 timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
6849 timerProgressBar.style.width = '0%';
6850 }, 10);
6851 }
6852 };
6853 const stopTimerProgressBar = () => {
6854 const timerProgressBar = getTimerProgressBar();
6855 if (!timerProgressBar) {
6856 return;
6857 }
6858 const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6859 timerProgressBar.style.removeProperty('transition');
6860 timerProgressBar.style.width = '100%';
6861 const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
6862 const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
6863 timerProgressBar.style.width = `${timerProgressBarPercent}%`;
6864 };
6865
6866 /**
6867 * Detect Node env
6868 *
6869 * @returns {boolean}
6870 */
6871 const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
6872
6873 const sweetHTML = `
6874 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
6875 <button type="button" class="${swalClasses.close}"></button>
6876 <ul class="${swalClasses['progress-steps']}"></ul>
6877 <div class="${swalClasses.icon}"></div>
6878 <img class="${swalClasses.image}" />
6879 <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
6880 <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
6881 <input class="${swalClasses.input}" id="${swalClasses.input}" />
6882 <input type="file" class="${swalClasses.file}" />
6883 <div class="${swalClasses.range}">
6884 <input type="range" />
6885 <output></output>
6886 </div>
6887 <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
6888 <div class="${swalClasses.radio}"></div>
6889 <label class="${swalClasses.checkbox}">
6890 <input type="checkbox" id="${swalClasses.checkbox}" />
6891 <span class="${swalClasses.label}"></span>
6892 </label>
6893 <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
6894 <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
6895 <div class="${swalClasses.actions}">
6896 <div class="${swalClasses.loader}"></div>
6897 <button type="button" class="${swalClasses.confirm}"></button>
6898 <button type="button" class="${swalClasses.deny}"></button>
6899 <button type="button" class="${swalClasses.cancel}"></button>
6900 </div>
6901 <div class="${swalClasses.footer}"></div>
6902 <div class="${swalClasses['timer-progress-bar-container']}">
6903 <div class="${swalClasses['timer-progress-bar']}"></div>
6904 </div>
6905 </div>
6906 `.replace(/(^|\n)\s*/g, '');
6907
6908 /**
6909 * @returns {boolean}
6910 */
6911 const resetOldContainer = () => {
6912 const oldContainer = getContainer();
6913 if (!oldContainer) {
6914 return false;
6915 }
6916 oldContainer.remove();
6917 removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'],
6918 // @ts-ignore: 'has-column' is not defined in swalClasses but may be set dynamically
6919 swalClasses['has-column']]);
6920 return true;
6921 };
6922 const resetValidationMessage$1 = () => {
6923 if (globalState.currentInstance) {
6924 globalState.currentInstance.resetValidationMessage();
6925 }
6926 };
6927 const addInputChangeListeners = () => {
6928 const popup = getPopup();
6929 if (!popup) {
6930 return;
6931 }
6932 const input = getDirectChildByClass(popup, swalClasses.input);
6933 const file = getDirectChildByClass(popup, swalClasses.file);
6934 /** @type {HTMLInputElement | null} */
6935 const range = popup.querySelector(`.${swalClasses.range} input`);
6936 /** @type {HTMLOutputElement | null} */
6937 const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
6938 const select = getDirectChildByClass(popup, swalClasses.select);
6939 /** @type {HTMLInputElement | null} */
6940 const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
6941 const textarea = getDirectChildByClass(popup, swalClasses.textarea);
6942 if (input) {
6943 input.oninput = resetValidationMessage$1;
6944 }
6945 if (file) {
6946 file.onchange = resetValidationMessage$1;
6947 }
6948 if (select) {
6949 select.onchange = resetValidationMessage$1;
6950 }
6951 if (checkbox) {
6952 checkbox.onchange = resetValidationMessage$1;
6953 }
6954 if (textarea) {
6955 textarea.oninput = resetValidationMessage$1;
6956 }
6957 if (range && rangeOutput) {
6958 range.oninput = () => {
6959 resetValidationMessage$1();
6960 rangeOutput.value = range.value;
6961 };
6962 range.onchange = () => {
6963 resetValidationMessage$1();
6964 rangeOutput.value = range.value;
6965 };
6966 }
6967 };
6968
6969 /**
6970 * @param {string | HTMLElement} target
6971 * @returns {HTMLElement}
6972 */
6973 const getTarget = target => {
6974 if (typeof target === 'string') {
6975 const element = document.querySelector(target);
6976 if (!element) {
6977 throw new Error(`Target element "${target}" not found`);
6978 }
6979 return /** @type {HTMLElement} */element;
6980 }
6981 return target;
6982 };
6983
6984 /**
6985 * @param {SweetAlertOptions} params
6986 */
6987 const setupAccessibility = params => {
6988 const popup = getPopup();
6989 if (!popup) {
6990 return;
6991 }
6992 popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
6993 popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
6994 if (!params.toast) {
6995 popup.setAttribute('aria-modal', 'true');
6996 }
6997 };
6998
6999 /**
7000 * @param {HTMLElement} targetElement
7001 */
7002 const setupRTL = targetElement => {
7003 if (window.getComputedStyle(targetElement).direction === 'rtl') {
7004 addClass(getContainer(), swalClasses.rtl);
7005 globalState.isRTL = true;
7006 }
7007 };
7008
7009 /**
7010 * Add modal + backdrop to DOM
7011 *
7012 * @param {SweetAlertOptions} params
7013 */
7014 const init = params => {
7015 // Clean up the old popup container if it exists
7016 const oldContainerExisted = resetOldContainer();
7017 if (isNodeEnv()) {
7018 error('SweetAlert2 requires document to initialize');
7019 return;
7020 }
7021 const container = document.createElement('div');
7022 container.className = swalClasses.container;
7023 if (oldContainerExisted) {
7024 addClass(container, swalClasses['no-transition']);
7025 }
7026 setInnerHtml(container, sweetHTML);
7027 container.dataset['swal2Theme'] = params.theme;
7028 const targetElement = getTarget(params.target || 'body');
7029 targetElement.appendChild(container);
7030 if (params.topLayer) {
7031 container.setAttribute('popover', '');
7032 container.showPopover();
7033 }
7034 setupAccessibility(params);
7035 setupRTL(targetElement);
7036 addInputChangeListeners();
7037 };
7038
7039 /**
7040 * @param {HTMLElement | object | string} param
7041 * @param {HTMLElement} target
7042 */
7043 const parseHtmlToContainer = (param, target) => {
7044 // DOM element
7045 if (param instanceof HTMLElement) {
7046 target.appendChild(param);
7047 }
7048
7049 // Object
7050 else if (typeof param === 'object') {
7051 handleObject(param, target);
7052 }
7053
7054 // Plain string
7055 else if (param) {
7056 setInnerHtml(target, param);
7057 }
7058 };
7059
7060 /**
7061 * @param {object} param
7062 * @param {HTMLElement} target
7063 */
7064 const handleObject = (param, target) => {
7065 // JQuery element(s)
7066 if ('jquery' in param) {
7067 handleJqueryElem(target, param);
7068 }
7069
7070 // For other objects use their string representation
7071 else {
7072 setInnerHtml(target, param.toString());
7073 }
7074 };
7075
7076 /**
7077 * @param {HTMLElement} target
7078 * @param {any} elem
7079 */
7080 const handleJqueryElem = (target, elem) => {
7081 target.textContent = '';
7082 if (0 in elem) {
7083 for (let i = 0; i in elem; i++) {
7084 target.appendChild(elem[i].cloneNode(true));
7085 }
7086 } else {
7087 target.appendChild(elem.cloneNode(true));
7088 }
7089 };
7090
7091 /**
7092 * @param {SweetAlert} instance
7093 * @param {SweetAlertOptions} params
7094 */
7095 const renderActions = (instance, params) => {
7096 const actions = getActions();
7097 const loader = getLoader();
7098 if (!actions || !loader) {
7099 return;
7100 }
7101
7102 // Actions (buttons) wrapper
7103 if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
7104 hide(actions);
7105 } else {
7106 show(actions);
7107 }
7108
7109 // Custom class
7110 applyCustomClass(actions, params, 'actions');
7111
7112 // Render all the buttons
7113 renderButtons(actions, loader, params);
7114
7115 // Loader
7116 setInnerHtml(loader, params.loaderHtml || '');
7117 applyCustomClass(loader, params, 'loader');
7118 };
7119
7120 /**
7121 * @param {HTMLElement} actions
7122 * @param {HTMLElement} loader
7123 * @param {SweetAlertOptions} params
7124 */
7125 function renderButtons(actions, loader, params) {
7126 const confirmButton = getConfirmButton();
7127 const denyButton = getDenyButton();
7128 const cancelButton = getCancelButton();
7129 if (!confirmButton || !denyButton || !cancelButton) {
7130 return;
7131 }
7132
7133 // Render buttons
7134 renderButton(confirmButton, 'confirm', params);
7135 renderButton(denyButton, 'deny', params);
7136 renderButton(cancelButton, 'cancel', params);
7137 handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
7138 if (params.reverseButtons) {
7139 if (params.toast) {
7140 actions.insertBefore(cancelButton, confirmButton);
7141 actions.insertBefore(denyButton, confirmButton);
7142 } else {
7143 actions.insertBefore(cancelButton, loader);
7144 actions.insertBefore(denyButton, loader);
7145 actions.insertBefore(confirmButton, loader);
7146 }
7147 }
7148 }
7149
7150 /**
7151 * @param {HTMLElement} confirmButton
7152 * @param {HTMLElement} denyButton
7153 * @param {HTMLElement} cancelButton
7154 * @param {SweetAlertOptions} params
7155 */
7156 function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
7157 if (!params.buttonsStyling) {
7158 removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7159 return;
7160 }
7161 addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
7162
7163 // Apply custom background colors to action buttons
7164 if (params.confirmButtonColor) {
7165 confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
7166 }
7167 if (params.denyButtonColor) {
7168 denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
7169 }
7170 if (params.cancelButtonColor) {
7171 cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
7172 }
7173
7174 // Apply the outline color to action buttons
7175 applyOutlineColor(confirmButton);
7176 applyOutlineColor(denyButton);
7177 applyOutlineColor(cancelButton);
7178 }
7179
7180 /**
7181 * @param {HTMLElement} button
7182 */
7183 function applyOutlineColor(button) {
7184 const buttonStyle = window.getComputedStyle(button);
7185 if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
7186 // If the button already has a custom outline color, no need to change it
7187 return;
7188 }
7189 const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
7190 button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
7191 }
7192
7193 /**
7194 * @param {HTMLElement} button
7195 * @param {'confirm' | 'deny' | 'cancel'} buttonType
7196 * @param {SweetAlertOptions} params
7197 */
7198 function renderButton(button, buttonType, params) {
7199 const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
7200 toggle(button, params[`show${buttonName}Button`], 'inline-block');
7201 setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
7202 button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label
7203
7204 // Add buttons custom classes
7205 button.className = swalClasses[buttonType];
7206 applyCustomClass(button, params, `${buttonType}Button`);
7207 }
7208
7209 /**
7210 * @param {SweetAlert} instance
7211 * @param {SweetAlertOptions} params
7212 */
7213 const renderCloseButton = (instance, params) => {
7214 const closeButton = getCloseButton();
7215 if (!closeButton) {
7216 return;
7217 }
7218 setInnerHtml(closeButton, params.closeButtonHtml || '');
7219
7220 // Custom class
7221 applyCustomClass(closeButton, params, 'closeButton');
7222 toggle(closeButton, params.showCloseButton);
7223 closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
7224 };
7225
7226 /**
7227 * @param {SweetAlert} instance
7228 * @param {SweetAlertOptions} params
7229 */
7230 const renderContainer = (instance, params) => {
7231 const container = getContainer();
7232 if (!container) {
7233 return;
7234 }
7235 handleBackdropParam(container, params.backdrop);
7236 handlePositionParam(container, params.position);
7237 handleGrowParam(container, params.grow);
7238
7239 // Custom class
7240 applyCustomClass(container, params, 'container');
7241 };
7242
7243 /**
7244 * @param {HTMLElement} container
7245 * @param {SweetAlertOptions['backdrop']} backdrop
7246 */
7247 function handleBackdropParam(container, backdrop) {
7248 if (typeof backdrop === 'string') {
7249 container.style.background = backdrop;
7250 } else if (!backdrop) {
7251 addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
7252 }
7253 }
7254
7255 /**
7256 * @param {HTMLElement} container
7257 * @param {SweetAlertOptions['position']} position
7258 */
7259 function handlePositionParam(container, position) {
7260 if (!position) {
7261 return;
7262 }
7263 if (position in swalClasses) {
7264 addClass(container, swalClasses[position]);
7265 } else {
7266 warn('The "position" parameter is not valid, defaulting to "center"');
7267 addClass(container, swalClasses.center);
7268 }
7269 }
7270
7271 /**
7272 * @param {HTMLElement} container
7273 * @param {SweetAlertOptions['grow']} grow
7274 */
7275 function handleGrowParam(container, grow) {
7276 if (!grow) {
7277 return;
7278 }
7279 addClass(container, swalClasses[`grow-${grow}`]);
7280 }
7281
7282 /**
7283 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
7284 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
7285 * This is the approach that Babel will probably take to implement private methods/fields
7286 * https://github.com/tc39/proposal-private-methods
7287 * https://github.com/babel/babel/pull/7555
7288 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
7289 * then we can use that language feature.
7290 */
7291
7292 var privateProps = {
7293 innerParams: new WeakMap(),
7294 domCache: new WeakMap()
7295 };
7296
7297 /// <reference path="../../../../sweetalert2.d.ts"/>
7298
7299
7300 /** @type {InputClass[]} */
7301 const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];
7302
7303 /**
7304 * @param {SweetAlert} instance
7305 * @param {SweetAlertOptions} params
7306 */
7307 const renderInput = (instance, params) => {
7308 const popup = getPopup();
7309 if (!popup) {
7310 return;
7311 }
7312 const innerParams = privateProps.innerParams.get(instance);
7313 const rerender = !innerParams || params.input !== innerParams.input;
7314 inputClasses.forEach(inputClass => {
7315 const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
7316 if (!inputContainer) {
7317 return;
7318 }
7319
7320 // set attributes
7321 setAttributes(inputClass, params.inputAttributes);
7322
7323 // set class
7324 inputContainer.className = swalClasses[inputClass];
7325 if (rerender) {
7326 hide(inputContainer);
7327 }
7328 });
7329 if (params.input) {
7330 if (rerender) {
7331 showInput(params);
7332 }
7333 // set custom class
7334 setCustomClass(params);
7335 }
7336 };
7337
7338 /**
7339 * @param {SweetAlertOptions} params
7340 */
7341 const showInput = params => {
7342 if (!params.input) {
7343 return;
7344 }
7345 if (!renderInputType[params.input]) {
7346 error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
7347 return;
7348 }
7349 const inputContainer = getInputContainer(params.input);
7350 if (!inputContainer) {
7351 return;
7352 }
7353 const input = renderInputType[params.input](inputContainer, params);
7354 show(inputContainer);
7355
7356 // input autofocus
7357 if (params.inputAutoFocus) {
7358 setTimeout(() => {
7359 focusInput(input);
7360 });
7361 }
7362 };
7363
7364 /**
7365 * @param {HTMLInputElement} input
7366 */
7367 const removeAttributes = input => {
7368 for (let i = 0; i < input.attributes.length; i++) {
7369 const attrName = input.attributes[i].name;
7370 if (!['id', 'type', 'value', 'style'].includes(attrName)) {
7371 input.removeAttribute(attrName);
7372 }
7373 }
7374 };
7375
7376 /**
7377 * @param {InputClass} inputClass
7378 * @param {SweetAlertOptions['inputAttributes']} inputAttributes
7379 */
7380 const setAttributes = (inputClass, inputAttributes) => {
7381 const popup = getPopup();
7382 if (!popup) {
7383 return;
7384 }
7385 const input = getInput$1(popup, inputClass);
7386 if (!input) {
7387 return;
7388 }
7389 removeAttributes(input);
7390 for (const attr in inputAttributes) {
7391 input.setAttribute(attr, inputAttributes[attr]);
7392 }
7393 };
7394
7395 /**
7396 * @param {SweetAlertOptions} params
7397 */
7398 const setCustomClass = params => {
7399 if (!params.input) {
7400 return;
7401 }
7402 const inputContainer = getInputContainer(params.input);
7403 if (inputContainer) {
7404 applyCustomClass(inputContainer, params, 'input');
7405 }
7406 };
7407
7408 /**
7409 * @param {HTMLInputElement | HTMLTextAreaElement} input
7410 * @param {SweetAlertOptions} params
7411 */
7412 const setInputPlaceholder = (input, params) => {
7413 if (!input.placeholder && params.inputPlaceholder) {
7414 input.placeholder = params.inputPlaceholder;
7415 }
7416 };
7417
7418 /**
7419 * @param {Input} input
7420 * @param {Input} prependTo
7421 * @param {SweetAlertOptions} params
7422 */
7423 const setInputLabel = (input, prependTo, params) => {
7424 if (params.inputLabel) {
7425 const label = document.createElement('label');
7426 const labelClass = swalClasses['input-label'];
7427 label.setAttribute('for', input.id);
7428 label.className = labelClass;
7429 if (typeof params.customClass === 'object') {
7430 addClass(label, params.customClass.inputLabel);
7431 }
7432 label.innerText = params.inputLabel;
7433 prependTo.insertAdjacentElement('beforebegin', label);
7434 }
7435 };
7436
7437 /**
7438 * @param {SweetAlertInput} inputType
7439 * @returns {HTMLElement | undefined}
7440 */
7441 const getInputContainer = inputType => {
7442 const popup = getPopup();
7443 if (!popup) {
7444 return;
7445 }
7446 return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
7447 };
7448
7449 /**
7450 * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
7451 * @param {SweetAlertOptions['inputValue']} inputValue
7452 */
7453 const checkAndSetInputValue = (input, inputValue) => {
7454 if (['string', 'number'].includes(typeof inputValue)) {
7455 input.value = `${inputValue}`;
7456 } else if (!isPromise(inputValue)) {
7457 warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
7458 }
7459 };
7460
7461 /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
7462 const renderInputType = {};
7463
7464 /**
7465 * @param {Input | HTMLElement} input
7466 * @param {SweetAlertOptions} params
7467 * @returns {Input}
7468 */
7469 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} */
7470 (input, params) => {
7471 const inputElement = /** @type {HTMLInputElement} */input;
7472 checkAndSetInputValue(inputElement, params.inputValue);
7473 setInputLabel(inputElement, inputElement, params);
7474 setInputPlaceholder(inputElement, params);
7475 inputElement.type = /** @type {string} */params.input;
7476 return inputElement;
7477 };
7478
7479 /**
7480 * @param {Input | HTMLElement} input
7481 * @param {SweetAlertOptions} params
7482 * @returns {Input}
7483 */
7484 renderInputType.file = (input, params) => {
7485 const inputElement = /** @type {HTMLInputElement} */input;
7486 setInputLabel(inputElement, inputElement, params);
7487 setInputPlaceholder(inputElement, params);
7488 return inputElement;
7489 };
7490
7491 /**
7492 * @param {Input | HTMLElement} range
7493 * @param {SweetAlertOptions} params
7494 * @returns {Input}
7495 */
7496 renderInputType.range = (range, params) => {
7497 const rangeContainer = /** @type {HTMLElement} */range;
7498 const rangeInput = rangeContainer.querySelector('input');
7499 const rangeOutput = rangeContainer.querySelector('output');
7500 if (rangeInput) {
7501 checkAndSetInputValue(rangeInput, params.inputValue);
7502 rangeInput.type = /** @type {string} */params.input;
7503 setInputLabel(rangeInput, /** @type {Input} */range, params);
7504 }
7505 if (rangeOutput) {
7506 checkAndSetInputValue(rangeOutput, params.inputValue);
7507 }
7508 return /** @type {Input} */range;
7509 };
7510
7511 /**
7512 * @param {Input | HTMLElement} select
7513 * @param {SweetAlertOptions} params
7514 * @returns {Input}
7515 */
7516 renderInputType.select = (select, params) => {
7517 const selectElement = /** @type {HTMLSelectElement} */select;
7518 selectElement.textContent = '';
7519 if (params.inputPlaceholder) {
7520 const placeholder = document.createElement('option');
7521 setInnerHtml(placeholder, params.inputPlaceholder);
7522 placeholder.value = '';
7523 placeholder.disabled = true;
7524 placeholder.selected = true;
7525 selectElement.appendChild(placeholder);
7526 }
7527 setInputLabel(selectElement, selectElement, params);
7528 return selectElement;
7529 };
7530
7531 /**
7532 * @param {Input | HTMLElement} radio
7533 * @returns {Input}
7534 */
7535 renderInputType.radio = radio => {
7536 const radioElement = /** @type {HTMLElement} */radio;
7537 radioElement.textContent = '';
7538 return /** @type {Input} */radio;
7539 };
7540
7541 /**
7542 * @param {Input | HTMLElement} checkboxContainer
7543 * @param {SweetAlertOptions} params
7544 * @returns {Input}
7545 */
7546 renderInputType.checkbox = (checkboxContainer, params) => {
7547 const popup = getPopup();
7548 if (!popup) {
7549 throw new Error('Popup not found');
7550 }
7551 const checkbox = getInput$1(popup, 'checkbox');
7552 if (!checkbox) {
7553 throw new Error('Checkbox input not found');
7554 }
7555 checkbox.value = '1';
7556 checkbox.checked = Boolean(params.inputValue);
7557 const containerElement = /** @type {HTMLElement} */checkboxContainer;
7558 const label = containerElement.querySelector('span');
7559 if (label) {
7560 const placeholderOrLabel = params.inputPlaceholder || params.inputLabel;
7561 if (placeholderOrLabel) {
7562 setInnerHtml(label, placeholderOrLabel);
7563 }
7564 }
7565 return checkbox;
7566 };
7567
7568 /**
7569 * @param {Input | HTMLElement} textarea
7570 * @param {SweetAlertOptions} params
7571 * @returns {Input}
7572 */
7573 renderInputType.textarea = (textarea, params) => {
7574 const textareaElement = /** @type {HTMLTextAreaElement} */textarea;
7575 checkAndSetInputValue(textareaElement, params.inputValue);
7576 setInputPlaceholder(textareaElement, params);
7577 setInputLabel(textareaElement, textareaElement, params);
7578
7579 /**
7580 * @param {HTMLElement} el
7581 * @returns {number}
7582 */
7583 const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);
7584
7585 // https://github.com/sweetalert2/sweetalert2/issues/2291
7586 setTimeout(() => {
7587 // https://github.com/sweetalert2/sweetalert2/issues/1699
7588 if ('MutationObserver' in window) {
7589 const popup = getPopup();
7590 if (!popup) {
7591 return;
7592 }
7593 const initialPopupWidth = parseInt(window.getComputedStyle(popup).width);
7594 const textareaResizeHandler = () => {
7595 // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
7596 if (!document.body.contains(textareaElement)) {
7597 return;
7598 }
7599 const textareaWidth = textareaElement.offsetWidth + getMargin(textareaElement);
7600 const popupElement = getPopup();
7601 if (popupElement) {
7602 if (textareaWidth > initialPopupWidth) {
7603 popupElement.style.width = `${textareaWidth}px`;
7604 } else {
7605 applyNumericalStyle(popupElement, 'width', params.width);
7606 }
7607 }
7608 };
7609 new MutationObserver(textareaResizeHandler).observe(textareaElement, {
7610 attributes: true,
7611 attributeFilter: ['style']
7612 });
7613 }
7614 });
7615 return textareaElement;
7616 };
7617
7618 /**
7619 * @param {SweetAlert} instance
7620 * @param {SweetAlertOptions} params
7621 */
7622 const renderContent = (instance, params) => {
7623 const htmlContainer = getHtmlContainer();
7624 if (!htmlContainer) {
7625 return;
7626 }
7627 showWhenInnerHtmlPresent(htmlContainer);
7628 applyCustomClass(htmlContainer, params, 'htmlContainer');
7629
7630 // Content as HTML
7631 if (params.html) {
7632 parseHtmlToContainer(params.html, htmlContainer);
7633 show(htmlContainer, 'block');
7634 }
7635
7636 // Content as plain text
7637 else if (params.text) {
7638 htmlContainer.textContent = params.text;
7639 show(htmlContainer, 'block');
7640 }
7641
7642 // No content
7643 else {
7644 hide(htmlContainer);
7645 }
7646 renderInput(instance, params);
7647 };
7648
7649 /**
7650 * @param {SweetAlert} instance
7651 * @param {SweetAlertOptions} params
7652 */
7653 const renderFooter = (instance, params) => {
7654 const footer = getFooter();
7655 if (!footer) {
7656 return;
7657 }
7658 showWhenInnerHtmlPresent(footer);
7659 toggle(footer, Boolean(params.footer), 'block');
7660 if (params.footer) {
7661 parseHtmlToContainer(params.footer, footer);
7662 }
7663
7664 // Custom class
7665 applyCustomClass(footer, params, 'footer');
7666 };
7667
7668 /**
7669 * @param {SweetAlert} instance
7670 * @param {SweetAlertOptions} params
7671 */
7672 const renderIcon = (instance, params) => {
7673 const innerParams = privateProps.innerParams.get(instance);
7674 const icon = getIcon();
7675 if (!icon) {
7676 return;
7677 }
7678
7679 // if the given icon already rendered, apply the styling without re-rendering the icon
7680 if (innerParams && params.icon === innerParams.icon) {
7681 // Custom or default content
7682 setContent(icon, params);
7683 applyStyles(icon, params);
7684 return;
7685 }
7686 if (!params.icon && !params.iconHtml) {
7687 hide(icon);
7688 return;
7689 }
7690 if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
7691 error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
7692 hide(icon);
7693 return;
7694 }
7695 show(icon);
7696
7697 // Custom or default content
7698 setContent(icon, params);
7699 applyStyles(icon, params);
7700
7701 // Animate icon
7702 addClass(icon, params.showClass && params.showClass.icon);
7703
7704 // Re-adjust the success icon on system theme change
7705 const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
7706 colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
7707 };
7708
7709 /**
7710 * @param {HTMLElement} icon
7711 * @param {SweetAlertOptions} params
7712 */
7713 const applyStyles = (icon, params) => {
7714 for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
7715 if (params.icon !== iconType) {
7716 removeClass(icon, iconClassName);
7717 }
7718 }
7719 addClass(icon, params.icon && iconTypes[params.icon]);
7720
7721 // Icon color
7722 setColor(icon, params);
7723
7724 // Success icon background color
7725 adjustSuccessIconBackgroundColor();
7726
7727 // Custom class
7728 applyCustomClass(icon, params, 'icon');
7729 };
7730
7731 // Adjust success icon background color to match the popup background color
7732 const adjustSuccessIconBackgroundColor = () => {
7733 const popup = getPopup();
7734 if (!popup) {
7735 return;
7736 }
7737 const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
7738 /** @type {NodeListOf<HTMLElement>} */
7739 const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
7740 for (let i = 0; i < successIconParts.length; i++) {
7741 successIconParts[i].style.backgroundColor = popupBackgroundColor;
7742 }
7743 };
7744
7745 /**
7746 *
7747 * @param {SweetAlertOptions} params
7748 * @returns {string}
7749 */
7750 const successIconHtml = params => `
7751 ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
7752 <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
7753 <div class="swal2-success-ring"></div>
7754 ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
7755 ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
7756 `;
7757 const errorIconHtml = `
7758 <span class="swal2-x-mark">
7759 <span class="swal2-x-mark-line-left"></span>
7760 <span class="swal2-x-mark-line-right"></span>
7761 </span>
7762 `;
7763
7764 /**
7765 * @param {HTMLElement} icon
7766 * @param {SweetAlertOptions} params
7767 */
7768 const setContent = (icon, params) => {
7769 if (!params.icon && !params.iconHtml) {
7770 return;
7771 }
7772 let oldContent = icon.innerHTML;
7773 let newContent = '';
7774 if (params.iconHtml) {
7775 newContent = iconContent(params.iconHtml);
7776 } else if (params.icon === 'success') {
7777 newContent = successIconHtml(params);
7778 oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
7779 } else if (params.icon === 'error') {
7780 newContent = errorIconHtml;
7781 } else if (params.icon) {
7782 const defaultIconHtml = {
7783 question: '?',
7784 warning: '!',
7785 info: 'i'
7786 };
7787 newContent = iconContent(defaultIconHtml[params.icon]);
7788 }
7789 if (oldContent.trim() !== newContent.trim()) {
7790 setInnerHtml(icon, newContent);
7791 }
7792 };
7793
7794 /**
7795 * @param {HTMLElement} icon
7796 * @param {SweetAlertOptions} params
7797 */
7798 const setColor = (icon, params) => {
7799 if (!params.iconColor) {
7800 return;
7801 }
7802 icon.style.color = params.iconColor;
7803 icon.style.borderColor = params.iconColor;
7804 for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
7805 setStyle(icon, sel, 'background-color', params.iconColor);
7806 }
7807 setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
7808 };
7809
7810 /**
7811 * @param {string} content
7812 * @returns {string}
7813 */
7814 const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;
7815
7816 /**
7817 * @param {SweetAlert} instance
7818 * @param {SweetAlertOptions} params
7819 */
7820 const renderImage = (instance, params) => {
7821 const image = getImage();
7822 if (!image) {
7823 return;
7824 }
7825 if (!params.imageUrl) {
7826 hide(image);
7827 return;
7828 }
7829 show(image, '');
7830
7831 // Src, alt
7832 image.setAttribute('src', params.imageUrl);
7833 image.setAttribute('alt', params.imageAlt || '');
7834
7835 // Width, height
7836 applyNumericalStyle(image, 'width', params.imageWidth);
7837 applyNumericalStyle(image, 'height', params.imageHeight);
7838
7839 // Class
7840 image.className = swalClasses.image;
7841 applyCustomClass(image, params, 'image');
7842 };
7843
7844 let dragging = false;
7845 let mousedownX = 0;
7846 let mousedownY = 0;
7847 let initialX = 0;
7848 let initialY = 0;
7849
7850 /**
7851 * @param {HTMLElement} popup
7852 */
7853 const addDraggableListeners = popup => {
7854 popup.addEventListener('mousedown', down);
7855 document.body.addEventListener('mousemove', move);
7856 popup.addEventListener('mouseup', up);
7857 popup.addEventListener('touchstart', down);
7858 document.body.addEventListener('touchmove', move);
7859 popup.addEventListener('touchend', up);
7860 };
7861
7862 /**
7863 * @param {HTMLElement} popup
7864 */
7865 const removeDraggableListeners = popup => {
7866 popup.removeEventListener('mousedown', down);
7867 document.body.removeEventListener('mousemove', move);
7868 popup.removeEventListener('mouseup', up);
7869 popup.removeEventListener('touchstart', down);
7870 document.body.removeEventListener('touchmove', move);
7871 popup.removeEventListener('touchend', up);
7872 };
7873
7874 /**
7875 * @param {MouseEvent | TouchEvent} event
7876 */
7877 const down = event => {
7878 const popup = getPopup();
7879 if (!popup) {
7880 return;
7881 }
7882 const icon = getIcon();
7883 if (event.target === popup || icon && icon.contains(/** @type {HTMLElement} */event.target)) {
7884 dragging = true;
7885 const clientXY = getClientXY(event);
7886 mousedownX = clientXY.clientX;
7887 mousedownY = clientXY.clientY;
7888 initialX = parseInt(popup.style.insetInlineStart) || 0;
7889 initialY = parseInt(popup.style.insetBlockStart) || 0;
7890 addClass(popup, 'swal2-dragging');
7891 }
7892 };
7893
7894 /**
7895 * @param {MouseEvent | TouchEvent} event
7896 */
7897 const move = event => {
7898 const popup = getPopup();
7899 if (!popup) {
7900 return;
7901 }
7902 if (dragging) {
7903 let {
7904 clientX,
7905 clientY
7906 } = getClientXY(event);
7907 const deltaX = clientX - mousedownX;
7908 // In RTL mode, negate the horizontal delta since insetInlineStart refers to the right edge
7909 popup.style.insetInlineStart = `${initialX + (globalState.isRTL ? -deltaX : deltaX)}px`;
7910 popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
7911 }
7912 };
7913 const up = () => {
7914 const popup = getPopup();
7915 dragging = false;
7916 removeClass(popup, 'swal2-dragging');
7917 };
7918
7919 /**
7920 * @param {MouseEvent | TouchEvent} event
7921 * @returns {{ clientX: number, clientY: number }}
7922 */
7923 const getClientXY = event => {
7924 let clientX = 0,
7925 clientY = 0;
7926 if (event.type.startsWith('mouse')) {
7927 clientX = /** @type {MouseEvent} */event.clientX;
7928 clientY = /** @type {MouseEvent} */event.clientY;
7929 } else if (event.type.startsWith('touch')) {
7930 clientX = /** @type {TouchEvent} */event.touches[0].clientX;
7931 clientY = /** @type {TouchEvent} */event.touches[0].clientY;
7932 }
7933 return {
7934 clientX,
7935 clientY
7936 };
7937 };
7938
7939 /**
7940 * @param {SweetAlert} instance
7941 * @param {SweetAlertOptions} params
7942 */
7943 const renderPopup = (instance, params) => {
7944 const container = getContainer();
7945 const popup = getPopup();
7946 if (!container || !popup) {
7947 return;
7948 }
7949
7950 // Width
7951 // https://github.com/sweetalert2/sweetalert2/issues/2170
7952 if (params.toast) {
7953 applyNumericalStyle(container, 'width', params.width);
7954 popup.style.width = '100%';
7955 const loader = getLoader();
7956 if (loader) {
7957 popup.insertBefore(loader, getIcon());
7958 }
7959 } else {
7960 applyNumericalStyle(popup, 'width', params.width);
7961 }
7962
7963 // Padding
7964 applyNumericalStyle(popup, 'padding', params.padding);
7965
7966 // Color
7967 if (params.color) {
7968 popup.style.color = params.color;
7969 }
7970
7971 // Background
7972 if (params.background) {
7973 popup.style.background = params.background;
7974 }
7975 hide(getValidationMessage());
7976
7977 // Classes
7978 addClasses$1(popup, params);
7979 if (params.draggable && !params.toast) {
7980 addClass(popup, swalClasses.draggable);
7981 addDraggableListeners(popup);
7982 } else {
7983 removeClass(popup, swalClasses.draggable);
7984 removeDraggableListeners(popup);
7985 }
7986 };
7987
7988 /**
7989 * @param {HTMLElement} popup
7990 * @param {SweetAlertOptions} params
7991 */
7992 const addClasses$1 = (popup, params) => {
7993 const showClass = params.showClass || {};
7994 // Default Class + showClass when updating Swal.update({})
7995 popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
7996 if (params.toast) {
7997 addClass([document.documentElement, document.body], swalClasses['toast-shown']);
7998 addClass(popup, swalClasses.toast);
7999 } else {
8000 addClass(popup, swalClasses.modal);
8001 }
8002
8003 // Custom class
8004 applyCustomClass(popup, params, 'popup');
8005 // TODO: remove in the next major
8006 if (typeof params.customClass === 'string') {
8007 addClass(popup, params.customClass);
8008 }
8009
8010 // Icon class (#1842)
8011 if (params.icon) {
8012 addClass(popup, swalClasses[`icon-${params.icon}`]);
8013 }
8014 };
8015
8016 /**
8017 * @param {SweetAlert} instance
8018 * @param {SweetAlertOptions} params
8019 */
8020 const renderProgressSteps = (instance, params) => {
8021 const progressStepsContainer = getProgressSteps();
8022 if (!progressStepsContainer) {
8023 return;
8024 }
8025 const {
8026 progressSteps,
8027 currentProgressStep
8028 } = params;
8029 if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
8030 hide(progressStepsContainer);
8031 return;
8032 }
8033 show(progressStepsContainer);
8034 progressStepsContainer.textContent = '';
8035 if (currentProgressStep >= progressSteps.length) {
8036 warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
8037 }
8038 progressSteps.forEach((step, index) => {
8039 const stepEl = createStepElement(step);
8040 progressStepsContainer.appendChild(stepEl);
8041 if (index === currentProgressStep) {
8042 addClass(stepEl, swalClasses['active-progress-step']);
8043 }
8044 if (index !== progressSteps.length - 1) {
8045 const lineEl = createLineElement(params);
8046 progressStepsContainer.appendChild(lineEl);
8047 }
8048 });
8049 };
8050
8051 /**
8052 * @param {string} step
8053 * @returns {HTMLLIElement}
8054 */
8055 const createStepElement = step => {
8056 const stepEl = document.createElement('li');
8057 addClass(stepEl, swalClasses['progress-step']);
8058 setInnerHtml(stepEl, step);
8059 return stepEl;
8060 };
8061
8062 /**
8063 * @param {SweetAlertOptions} params
8064 * @returns {HTMLLIElement}
8065 */
8066 const createLineElement = params => {
8067 const lineEl = document.createElement('li');
8068 addClass(lineEl, swalClasses['progress-step-line']);
8069 if (params.progressStepsDistance) {
8070 applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
8071 }
8072 return lineEl;
8073 };
8074
8075 /**
8076 * @param {SweetAlert} instance
8077 * @param {SweetAlertOptions} params
8078 */
8079 const renderTitle = (instance, params) => {
8080 const title = getTitle();
8081 if (!title) {
8082 return;
8083 }
8084 showWhenInnerHtmlPresent(title);
8085 toggle(title, Boolean(params.title || params.titleText), 'block');
8086 if (params.title) {
8087 parseHtmlToContainer(params.title, title);
8088 }
8089 if (params.titleText) {
8090 title.innerText = params.titleText;
8091 }
8092
8093 // Custom class
8094 applyCustomClass(title, params, 'title');
8095 };
8096
8097 /**
8098 * @param {SweetAlert} instance
8099 * @param {SweetAlertOptions} params
8100 */
8101 const render = (instance, params) => {
8102 var _globalState$eventEmi;
8103 renderPopup(instance, params);
8104 renderContainer(instance, params);
8105 renderProgressSteps(instance, params);
8106 renderIcon(instance, params);
8107 renderImage(instance, params);
8108 renderTitle(instance, params);
8109 renderCloseButton(instance, params);
8110 renderContent(instance, params);
8111 renderActions(instance, params);
8112 renderFooter(instance, params);
8113 const popup = getPopup();
8114 if (typeof params.didRender === 'function' && popup) {
8115 params.didRender(popup);
8116 }
8117 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didRender', popup);
8118 };
8119
8120 /*
8121 * Global function to determine if SweetAlert2 popup is shown
8122 */
8123 const isVisible = () => {
8124 return isVisible$1(getPopup());
8125 };
8126
8127 /*
8128 * Global function to click 'Confirm' button
8129 */
8130 const clickConfirm = () => {
8131 var _dom$getConfirmButton;
8132 return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
8133 };
8134
8135 /*
8136 * Global function to click 'Deny' button
8137 */
8138 const clickDeny = () => {
8139 var _dom$getDenyButton;
8140 return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
8141 };
8142
8143 /*
8144 * Global function to click 'Cancel' button
8145 */
8146 const clickCancel = () => {
8147 var _dom$getCancelButton;
8148 return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
8149 };
8150
8151 /** @type {Record<DismissReason, DismissReason>} */
8152 const DismissReason = Object.freeze({
8153 cancel: 'cancel',
8154 backdrop: 'backdrop',
8155 close: 'close',
8156 esc: 'esc',
8157 timer: 'timer'
8158 });
8159
8160 /**
8161 * @param {GlobalState} globalState
8162 */
8163 const removeKeydownHandler = globalState => {
8164 if (globalState.keydownTarget && globalState.keydownHandlerAdded && globalState.keydownHandler) {
8165 const handler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */globalState.keydownHandler;
8166 globalState.keydownTarget.removeEventListener('keydown', handler, {
8167 capture: globalState.keydownListenerCapture
8168 });
8169 globalState.keydownHandlerAdded = false;
8170 }
8171 };
8172
8173 /**
8174 * @param {GlobalState} globalState
8175 * @param {SweetAlertOptions} innerParams
8176 * @param {(dismiss: DismissReason) => void} dismissWith
8177 */
8178 const addKeydownHandler = (globalState, innerParams, dismissWith) => {
8179 removeKeydownHandler(globalState);
8180 if (!innerParams.toast) {
8181 /** @type {(this: HTMLElement, event: KeyboardEvent) => void} */
8182 const handler = e => keydownHandler(innerParams, e, dismissWith);
8183 globalState.keydownHandler = handler;
8184 const target = innerParams.keydownListenerCapture ? window : getPopup();
8185 if (target) {
8186 globalState.keydownTarget = target;
8187 globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
8188 const eventHandler = /** @type {EventListenerOrEventListenerObject} */ /** @type {unknown} */handler;
8189 globalState.keydownTarget.addEventListener('keydown', eventHandler, {
8190 capture: globalState.keydownListenerCapture
8191 });
8192 globalState.keydownHandlerAdded = true;
8193 }
8194 }
8195 };
8196
8197 /**
8198 * @param {number} index
8199 * @param {number} increment
8200 */
8201 const setFocus = (index, increment) => {
8202 var _dom$getPopup;
8203 const focusableElements = getFocusableElements();
8204 // search for visible elements and select the next possible match
8205 if (focusableElements.length) {
8206 index = index + increment;
8207
8208 // shift + tab when .swal2-popup is focused
8209 if (index === -2) {
8210 index = focusableElements.length - 1;
8211 }
8212
8213 // rollover to first item
8214 if (index === focusableElements.length) {
8215 index = 0;
8216
8217 // go to last item
8218 } else if (index === -1) {
8219 index = focusableElements.length - 1;
8220 }
8221 focusableElements[index].focus();
8222 return;
8223 }
8224 // no visible focusable elements, focus the popup
8225 (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
8226 };
8227 const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
8228 const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];
8229
8230 /**
8231 * @param {SweetAlertOptions} innerParams
8232 * @param {KeyboardEvent} event
8233 * @param {(dismiss: DismissReason) => void} dismissWith
8234 */
8235 const keydownHandler = (innerParams, event, dismissWith) => {
8236 if (!innerParams) {
8237 return; // This instance has already been destroyed
8238 }
8239
8240 // Ignore keydown during IME composition
8241 // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
8242 // https://github.com/sweetalert2/sweetalert2/issues/720
8243 // https://github.com/sweetalert2/sweetalert2/issues/2406
8244 if (event.isComposing || event.keyCode === 229) {
8245 return;
8246 }
8247 if (innerParams.stopKeydownPropagation) {
8248 event.stopPropagation();
8249 }
8250
8251 // ENTER
8252 if (event.key === 'Enter') {
8253 handleEnter(event, innerParams);
8254 }
8255
8256 // TAB
8257 else if (event.key === 'Tab') {
8258 handleTab(event);
8259 }
8260
8261 // ARROWS - switch focus between buttons
8262 else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
8263 handleArrows(event.key);
8264 }
8265
8266 // ESC
8267 else if (event.key === 'Escape') {
8268 handleEsc(event, innerParams, dismissWith);
8269 }
8270 };
8271
8272 /**
8273 * @param {KeyboardEvent} event
8274 * @param {SweetAlertOptions} innerParams
8275 */
8276 const handleEnter = (event, innerParams) => {
8277 // https://github.com/sweetalert2/sweetalert2/issues/2386
8278 if (!callIfFunction(innerParams.allowEnterKey)) {
8279 return;
8280 }
8281 const popup = getPopup();
8282 if (!popup || !innerParams.input) {
8283 return;
8284 }
8285 const input = getInput$1(popup, innerParams.input);
8286 if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
8287 if (['textarea', 'file'].includes(innerParams.input)) {
8288 return; // do not submit
8289 }
8290 clickConfirm();
8291 event.preventDefault();
8292 }
8293 };
8294
8295 /**
8296 * @param {KeyboardEvent} event
8297 */
8298 const handleTab = event => {
8299 const targetElement = event.target;
8300 const focusableElements = getFocusableElements();
8301 let btnIndex = -1;
8302 for (let i = 0; i < focusableElements.length; i++) {
8303 if (targetElement === focusableElements[i]) {
8304 btnIndex = i;
8305 break;
8306 }
8307 }
8308
8309 // Cycle to the next button
8310 if (!event.shiftKey) {
8311 setFocus(btnIndex, 1);
8312 }
8313
8314 // Cycle to the prev button
8315 else {
8316 setFocus(btnIndex, -1);
8317 }
8318 event.stopPropagation();
8319 event.preventDefault();
8320 };
8321
8322 /**
8323 * @param {string} key
8324 */
8325 const handleArrows = key => {
8326 const actions = getActions();
8327 const confirmButton = getConfirmButton();
8328 const denyButton = getDenyButton();
8329 const cancelButton = getCancelButton();
8330 if (!actions || !confirmButton || !denyButton || !cancelButton) {
8331 return;
8332 }
8333 /** @type HTMLElement[] */
8334 const buttons = [confirmButton, denyButton, cancelButton];
8335 if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
8336 return;
8337 }
8338 const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
8339 let buttonToFocus = document.activeElement;
8340 if (!buttonToFocus) {
8341 return;
8342 }
8343 for (let i = 0; i < actions.children.length; i++) {
8344 buttonToFocus = buttonToFocus[sibling];
8345 if (!buttonToFocus) {
8346 return;
8347 }
8348 if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
8349 break;
8350 }
8351 }
8352 if (buttonToFocus instanceof HTMLButtonElement) {
8353 buttonToFocus.focus();
8354 }
8355 };
8356
8357 /**
8358 * @param {KeyboardEvent} event
8359 * @param {SweetAlertOptions} innerParams
8360 * @param {(dismiss: DismissReason) => void} dismissWith
8361 */
8362 const handleEsc = (event, innerParams, dismissWith) => {
8363 event.preventDefault();
8364 if (callIfFunction(innerParams.allowEscapeKey)) {
8365 dismissWith(DismissReason.esc);
8366 }
8367 };
8368
8369 /**
8370 * This module contains `WeakMap`s for each effectively-"private property" that a `Swal` has.
8371 * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
8372 * This is the approach that Babel will probably take to implement private methods/fields
8373 * https://github.com/tc39/proposal-private-methods
8374 * https://github.com/babel/babel/pull/7555
8375 * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
8376 * then we can use that language feature.
8377 */
8378
8379 var privateMethods = {
8380 swalPromiseResolve: new WeakMap(),
8381 swalPromiseReject: new WeakMap()
8382 };
8383
8384 // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
8385 // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
8386 // elements not within the active modal dialog will not be surfaced if a user opens a screen
8387 // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.
8388
8389 const setAriaHidden = () => {
8390 const container = getContainer();
8391 const bodyChildren = Array.from(document.body.children);
8392 bodyChildren.forEach(el => {
8393 if (el.contains(container)) {
8394 return;
8395 }
8396 if (el.hasAttribute('aria-hidden')) {
8397 el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
8398 }
8399 el.setAttribute('aria-hidden', 'true');
8400 });
8401 };
8402 const unsetAriaHidden = () => {
8403 const bodyChildren = Array.from(document.body.children);
8404 bodyChildren.forEach(el => {
8405 if (el.hasAttribute('data-previous-aria-hidden')) {
8406 el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
8407 el.removeAttribute('data-previous-aria-hidden');
8408 } else {
8409 el.removeAttribute('aria-hidden');
8410 }
8411 });
8412 };
8413
8414 // @ts-ignore
8415 const isSafariOrIOS = typeof window !== 'undefined' && Boolean(window.GestureEvent); // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394
8416
8417 /**
8418 * Fix iOS scrolling
8419 * http://stackoverflow.com/q/39626302
8420 */
8421 const iOSfix = () => {
8422 if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
8423 const offset = document.body.scrollTop;
8424 document.body.style.top = `${offset * -1}px`;
8425 addClass(document.body, swalClasses.iosfix);
8426 lockBodyScroll();
8427 }
8428 };
8429
8430 /**
8431 * https://github.com/sweetalert2/sweetalert2/issues/1246
8432 */
8433 const lockBodyScroll = () => {
8434 const container = getContainer();
8435 if (!container) {
8436 return;
8437 }
8438 /** @type {boolean} */
8439 let preventTouchMove;
8440 /**
8441 * @param {TouchEvent} event
8442 */
8443 container.ontouchstart = event => {
8444 preventTouchMove = shouldPreventTouchMove(event);
8445 };
8446 /**
8447 * @param {TouchEvent} event
8448 */
8449 container.ontouchmove = event => {
8450 if (preventTouchMove) {
8451 event.preventDefault();
8452 event.stopPropagation();
8453 }
8454 };
8455 };
8456
8457 /**
8458 * @param {TouchEvent} event
8459 * @returns {boolean}
8460 */
8461 const shouldPreventTouchMove = event => {
8462 const target = event.target;
8463 const container = getContainer();
8464 const htmlContainer = getHtmlContainer();
8465 if (!container || !htmlContainer) {
8466 return false;
8467 }
8468 if (isStylus(event) || isZoom(event)) {
8469 return false;
8470 }
8471 if (target === container) {
8472 return true;
8473 }
8474 if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
8475 // #2823
8476 target.tagName !== 'INPUT' &&
8477 // #1603
8478 target.tagName !== 'TEXTAREA' &&
8479 // #2266
8480 !(isScrollable(htmlContainer) &&
8481 // #1944
8482 htmlContainer.contains(target))) {
8483 return true;
8484 }
8485 return false;
8486 };
8487
8488 /**
8489 * https://github.com/sweetalert2/sweetalert2/issues/1786
8490 *
8491 * @param {TouchEvent} event
8492 * @returns {boolean}
8493 */
8494 const isStylus = event => {
8495 return Boolean(event.touches && event.touches.length &&
8496 // @ts-ignore - touchType is not a standard property
8497 event.touches[0].touchType === 'stylus');
8498 };
8499
8500 /**
8501 * https://github.com/sweetalert2/sweetalert2/issues/1891
8502 *
8503 * @param {TouchEvent} event
8504 * @returns {boolean}
8505 */
8506 const isZoom = event => {
8507 return event.touches && event.touches.length > 1;
8508 };
8509 const undoIOSfix = () => {
8510 if (hasClass(document.body, swalClasses.iosfix)) {
8511 const offset = parseInt(document.body.style.top, 10);
8512 removeClass(document.body, swalClasses.iosfix);
8513 document.body.style.top = '';
8514 document.body.scrollTop = offset * -1;
8515 }
8516 };
8517
8518 /**
8519 * Measure scrollbar width for padding body during modal show/hide
8520 * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
8521 *
8522 * @returns {number}
8523 */
8524 const measureScrollbar = () => {
8525 const scrollDiv = document.createElement('div');
8526 scrollDiv.className = swalClasses['scrollbar-measure'];
8527 document.body.appendChild(scrollDiv);
8528 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
8529 document.body.removeChild(scrollDiv);
8530 return scrollbarWidth;
8531 };
8532
8533 /**
8534 * Remember state in cases where opening and handling a modal will fiddle with it.
8535 * @type {number | null}
8536 */
8537 let previousBodyPadding = null;
8538
8539 /**
8540 * @param {string} initialBodyOverflow
8541 */
8542 const replaceScrollbarWithPadding = initialBodyOverflow => {
8543 // for queues, do not do this more than once
8544 if (previousBodyPadding !== null) {
8545 return;
8546 }
8547 // if the body has overflow
8548 if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
8549 ) {
8550 // add padding so the content doesn't shift after removal of scrollbar
8551 previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
8552 document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
8553 }
8554 };
8555 const undoReplaceScrollbarWithPadding = () => {
8556 if (previousBodyPadding !== null) {
8557 document.body.style.paddingRight = `${previousBodyPadding}px`;
8558 previousBodyPadding = null;
8559 }
8560 };
8561
8562 /**
8563 * @param {SweetAlert} instance
8564 * @param {HTMLElement} container
8565 * @param {boolean} returnFocus
8566 * @param {(() => void) | undefined} didClose
8567 */
8568 function removePopupAndResetState(instance, container, returnFocus, didClose) {
8569 if (isToast()) {
8570 triggerDidCloseAndDispose(instance, didClose);
8571 } else {
8572 restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
8573 removeKeydownHandler(globalState);
8574 }
8575
8576 // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
8577 // for some reason removing the container in Safari will scroll the document to bottom
8578 if (isSafariOrIOS) {
8579 container.setAttribute('style', 'display:none !important');
8580 container.removeAttribute('class');
8581 container.innerHTML = '';
8582 } else {
8583 container.remove();
8584 }
8585 if (isModal()) {
8586 undoReplaceScrollbarWithPadding();
8587 undoIOSfix();
8588 unsetAriaHidden();
8589 }
8590 removeBodyClasses();
8591 }
8592
8593 /**
8594 * Remove SweetAlert2 classes from body
8595 */
8596 function removeBodyClasses() {
8597 removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
8598 }
8599
8600 /**
8601 * Instance method to close sweetAlert
8602 *
8603 * @param {SweetAlertResult | undefined} resolveValue
8604 * @this {SweetAlert}
8605 */
8606 function close(resolveValue) {
8607 resolveValue = prepareResolveValue(resolveValue);
8608 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
8609 const didClose = triggerClosePopup(this);
8610 if (this.isAwaitingPromise) {
8611 // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
8612 if (!resolveValue.isDismissed) {
8613 handleAwaitingPromise(this);
8614 swalPromiseResolve(resolveValue);
8615 }
8616 } else if (didClose) {
8617 // Resolve Swal promise
8618 swalPromiseResolve(resolveValue);
8619 }
8620 }
8621
8622 /**
8623 * @param {SweetAlert} instance
8624 * @returns {boolean}
8625 */
8626 const triggerClosePopup = instance => {
8627 const popup = getPopup();
8628 if (!popup) {
8629 return false;
8630 }
8631 const innerParams = privateProps.innerParams.get(instance);
8632 if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
8633 return false;
8634 }
8635 removeClass(popup, innerParams.showClass.popup);
8636 addClass(popup, innerParams.hideClass.popup);
8637 const backdrop = getContainer();
8638 removeClass(backdrop, innerParams.showClass.backdrop);
8639 addClass(backdrop, innerParams.hideClass.backdrop);
8640 handlePopupAnimation(instance, popup, innerParams);
8641 return true;
8642 };
8643
8644 /**
8645 * @param {Error | string} error
8646 * @this {SweetAlert}
8647 */
8648 function rejectPromise(error) {
8649 const rejectPromise = privateMethods.swalPromiseReject.get(this);
8650 handleAwaitingPromise(this);
8651 if (rejectPromise) {
8652 // Reject Swal promise
8653 rejectPromise(error);
8654 }
8655 }
8656
8657 /**
8658 * @param {SweetAlert} instance
8659 */
8660 const handleAwaitingPromise = instance => {
8661 if (instance.isAwaitingPromise) {
8662 // @ts-ignore
8663 delete instance.isAwaitingPromise;
8664 // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
8665 if (!privateProps.innerParams.get(instance)) {
8666 instance._destroy();
8667 }
8668 }
8669 };
8670
8671 /**
8672 * @param {SweetAlertResult | undefined} resolveValue
8673 * @returns {SweetAlertResult}
8674 */
8675 const prepareResolveValue = resolveValue => {
8676 // When user calls Swal.close()
8677 if (typeof resolveValue === 'undefined') {
8678 return {
8679 isConfirmed: false,
8680 isDenied: false,
8681 isDismissed: true
8682 };
8683 }
8684 return Object.assign({
8685 isConfirmed: false,
8686 isDenied: false,
8687 isDismissed: false
8688 }, resolveValue);
8689 };
8690
8691 /**
8692 * @param {SweetAlert} instance
8693 * @param {HTMLElement} popup
8694 * @param {SweetAlertOptions} innerParams
8695 */
8696 const handlePopupAnimation = (instance, popup, innerParams) => {
8697 var _globalState$eventEmi;
8698 const container = getContainer();
8699 // If animation is supported, animate
8700 const animationIsSupported = hasCssAnimation(popup);
8701 if (typeof innerParams.willClose === 'function') {
8702 innerParams.willClose(popup);
8703 }
8704 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
8705 if (animationIsSupported && container) {
8706 animatePopup(instance, popup, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8707 } else if (container) {
8708 // Otherwise, remove immediately
8709 removePopupAndResetState(instance, container, Boolean(innerParams.returnFocus), innerParams.didClose);
8710 }
8711 };
8712
8713 /**
8714 * @param {SweetAlert} instance
8715 * @param {HTMLElement} popup
8716 * @param {HTMLElement} container
8717 * @param {boolean} returnFocus
8718 * @param {(() => void) | undefined} didClose
8719 */
8720 const animatePopup = (instance, popup, container, returnFocus, didClose) => {
8721 globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
8722 /**
8723 * @param {AnimationEvent | TransitionEvent} e
8724 */
8725 const swalCloseAnimationFinished = function (e) {
8726 if (e.target === popup) {
8727 var _globalState$swalClos;
8728 (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
8729 delete globalState.swalCloseEventFinishedCallback;
8730 popup.removeEventListener('animationend', swalCloseAnimationFinished);
8731 popup.removeEventListener('transitionend', swalCloseAnimationFinished);
8732 }
8733 };
8734 popup.addEventListener('animationend', swalCloseAnimationFinished);
8735 popup.addEventListener('transitionend', swalCloseAnimationFinished);
8736 };
8737
8738 /**
8739 * @param {SweetAlert} instance
8740 * @param {(() => void) | undefined} didClose
8741 */
8742 const triggerDidCloseAndDispose = (instance, didClose) => {
8743 setTimeout(() => {
8744 var _globalState$eventEmi2;
8745 if (typeof didClose === 'function') {
8746 didClose.bind(instance.params)();
8747 }
8748 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
8749 // instance might have been destroyed already
8750 if (instance._destroy) {
8751 instance._destroy();
8752 }
8753 });
8754 };
8755
8756 /**
8757 * Shows loader (spinner), this is useful with AJAX requests.
8758 * By default the loader be shown instead of the "Confirm" button.
8759 *
8760 * @param {HTMLButtonElement | null} [buttonToReplace]
8761 */
8762 const showLoading = buttonToReplace => {
8763 let popup = getPopup();
8764 if (!popup) {
8765 new Swal();
8766 }
8767 popup = getPopup();
8768 if (!popup) {
8769 return;
8770 }
8771 const loader = getLoader();
8772 if (isToast()) {
8773 hide(getIcon());
8774 } else {
8775 replaceButton(popup, buttonToReplace);
8776 }
8777 show(loader);
8778 popup.setAttribute('data-loading', 'true');
8779 popup.setAttribute('aria-busy', 'true');
8780 popup.focus();
8781 };
8782
8783 /**
8784 * @param {HTMLElement} popup
8785 * @param {HTMLButtonElement | null} [buttonToReplace]
8786 */
8787 const replaceButton = (popup, buttonToReplace) => {
8788 const actions = getActions();
8789 const loader = getLoader();
8790 if (!actions || !loader) {
8791 return;
8792 }
8793 if (!buttonToReplace && isVisible$1(getConfirmButton())) {
8794 buttonToReplace = getConfirmButton();
8795 }
8796 show(actions);
8797 if (buttonToReplace) {
8798 hide(buttonToReplace);
8799 loader.setAttribute('data-button-to-replace', buttonToReplace.className);
8800 actions.insertBefore(loader, buttonToReplace);
8801 }
8802 addClass([popup, actions], swalClasses.loading);
8803 };
8804
8805 /**
8806 * @param {SweetAlert} instance
8807 * @param {SweetAlertOptions} params
8808 */
8809 const handleInputOptionsAndValue = (instance, params) => {
8810 if (params.input === 'select' || params.input === 'radio') {
8811 handleInputOptions(instance, params);
8812 } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
8813 showLoading(getConfirmButton());
8814 handleInputValue(instance, params);
8815 }
8816 };
8817
8818 /**
8819 * @param {SweetAlert} instance
8820 * @param {SweetAlertOptions} innerParams
8821 * @returns {SweetAlertInputValue}
8822 */
8823 const getInputValue = (instance, innerParams) => {
8824 const input = instance.getInput();
8825 if (!input) {
8826 return null;
8827 }
8828 switch (innerParams.input) {
8829 case 'checkbox':
8830 return getCheckboxValue(input);
8831 case 'radio':
8832 return getRadioValue(input);
8833 case 'file':
8834 return getFileValue(input);
8835 default:
8836 return innerParams.inputAutoTrim ? input.value.trim() : input.value;
8837 }
8838 };
8839
8840 /**
8841 * @param {HTMLInputElement} input
8842 * @returns {number}
8843 */
8844 const getCheckboxValue = input => input.checked ? 1 : 0;
8845
8846 /**
8847 * @param {HTMLInputElement} input
8848 * @returns {string | null}
8849 */
8850 const getRadioValue = input => input.checked ? input.value : null;
8851
8852 /**
8853 * @param {HTMLInputElement} input
8854 * @returns {FileList | File | null}
8855 */
8856 const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;
8857
8858 /**
8859 * @param {SweetAlert} instance
8860 * @param {SweetAlertOptions} params
8861 */
8862 const handleInputOptions = (instance, params) => {
8863 const popup = getPopup();
8864 if (!popup) {
8865 return;
8866 }
8867 /**
8868 * @param {*} inputOptions
8869 */
8870 const processInputOptions = inputOptions => {
8871 if (params.input === 'select') {
8872 populateSelectOptions(popup, formatInputOptions(inputOptions), params);
8873 } else if (params.input === 'radio') {
8874 populateRadioOptions(popup, formatInputOptions(inputOptions), params);
8875 }
8876 };
8877 if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
8878 showLoading(getConfirmButton());
8879 asPromise(params.inputOptions).then(inputOptions => {
8880 instance.hideLoading();
8881 processInputOptions(inputOptions);
8882 });
8883 } else if (typeof params.inputOptions === 'object') {
8884 processInputOptions(params.inputOptions);
8885 } else {
8886 error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
8887 }
8888 };
8889
8890 /**
8891 * @param {SweetAlert} instance
8892 * @param {SweetAlertOptions} params
8893 */
8894 const handleInputValue = (instance, params) => {
8895 const input = instance.getInput();
8896 if (!input) {
8897 return;
8898 }
8899 hide(input);
8900 asPromise(params.inputValue).then(inputValue => {
8901 input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
8902 show(input);
8903 input.focus();
8904 instance.hideLoading();
8905 }).catch(err => {
8906 error(`Error in inputValue promise: ${err}`);
8907 input.value = '';
8908 show(input);
8909 input.focus();
8910 instance.hideLoading();
8911 });
8912 };
8913
8914 /**
8915 * @param {HTMLElement} popup
8916 * @param {InputOptionFlattened[]} inputOptions
8917 * @param {SweetAlertOptions} params
8918 */
8919 function populateSelectOptions(popup, inputOptions, params) {
8920 const select = getDirectChildByClass(popup, swalClasses.select);
8921 if (!select) {
8922 return;
8923 }
8924 /**
8925 * @param {HTMLElement} parent
8926 * @param {string} optionLabel
8927 * @param {string} optionValue
8928 */
8929 const renderOption = (parent, optionLabel, optionValue) => {
8930 const option = document.createElement('option');
8931 option.value = optionValue;
8932 setInnerHtml(option, optionLabel);
8933 option.selected = isSelected(optionValue, params.inputValue);
8934 parent.appendChild(option);
8935 };
8936 inputOptions.forEach(inputOption => {
8937 const optionValue = inputOption[0];
8938 const optionLabel = inputOption[1];
8939 // <optgroup> spec:
8940 // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
8941 // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
8942 // check whether this is a <optgroup>
8943 if (Array.isArray(optionLabel)) {
8944 // if it is an array, then it is an <optgroup>
8945 const optgroup = document.createElement('optgroup');
8946 optgroup.label = optionValue;
8947 optgroup.disabled = false; // not configurable for now
8948 select.appendChild(optgroup);
8949 optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
8950 } else {
8951 // case of <option>
8952 renderOption(select, optionLabel, optionValue);
8953 }
8954 });
8955 select.focus();
8956 }
8957
8958 /**
8959 * @param {HTMLElement} popup
8960 * @param {InputOptionFlattened[]} inputOptions
8961 * @param {SweetAlertOptions} params
8962 */
8963 function populateRadioOptions(popup, inputOptions, params) {
8964 const radio = getDirectChildByClass(popup, swalClasses.radio);
8965 if (!radio) {
8966 return;
8967 }
8968 inputOptions.forEach(inputOption => {
8969 const radioValue = inputOption[0];
8970 const radioLabel = inputOption[1];
8971 const radioInput = document.createElement('input');
8972 const radioLabelElement = document.createElement('label');
8973 radioInput.type = 'radio';
8974 radioInput.name = swalClasses.radio;
8975 radioInput.value = radioValue;
8976 if (isSelected(radioValue, params.inputValue)) {
8977 radioInput.checked = true;
8978 }
8979 const label = document.createElement('span');
8980 setInnerHtml(label, radioLabel);
8981 label.className = swalClasses.label;
8982 radioLabelElement.appendChild(radioInput);
8983 radioLabelElement.appendChild(label);
8984 radio.appendChild(radioLabelElement);
8985 });
8986 const radios = radio.querySelectorAll('input');
8987 if (radios.length) {
8988 radios[0].focus();
8989 }
8990 }
8991
8992 /**
8993 * Converts `inputOptions` into an array of `[value, label]`s
8994 *
8995 * @param {*} inputOptions
8996 * @typedef {string[]} InputOptionFlattened
8997 * @returns {InputOptionFlattened[]}
8998 */
8999 const formatInputOptions = inputOptions => {
9000 /** @type {InputOptionFlattened[]} */
9001 const result = [];
9002 if (inputOptions instanceof Map) {
9003 inputOptions.forEach((value, key) => {
9004 let valueFormatted = value;
9005 if (typeof valueFormatted === 'object') {
9006 // case of <optgroup>
9007 valueFormatted = formatInputOptions(valueFormatted);
9008 }
9009 result.push([key, valueFormatted]);
9010 });
9011 } else {
9012 Object.keys(inputOptions).forEach(key => {
9013 let valueFormatted = inputOptions[key];
9014 if (typeof valueFormatted === 'object') {
9015 // case of <optgroup>
9016 valueFormatted = formatInputOptions(valueFormatted);
9017 }
9018 result.push([key, valueFormatted]);
9019 });
9020 }
9021 return result;
9022 };
9023
9024 /**
9025 * @param {string} optionValue
9026 * @param {SweetAlertInputValue} inputValue
9027 * @returns {boolean}
9028 */
9029 const isSelected = (optionValue, inputValue) => {
9030 return Boolean(inputValue) && inputValue !== null && inputValue !== undefined && inputValue.toString() === optionValue.toString();
9031 };
9032
9033 /**
9034 * @param {SweetAlert} instance
9035 */
9036 const handleConfirmButtonClick = instance => {
9037 const innerParams = privateProps.innerParams.get(instance);
9038 instance.disableButtons();
9039 if (innerParams.input) {
9040 handleConfirmOrDenyWithInput(instance, 'confirm');
9041 } else {
9042 confirm(instance, true);
9043 }
9044 };
9045
9046 /**
9047 * @param {SweetAlert} instance
9048 */
9049 const handleDenyButtonClick = instance => {
9050 const innerParams = privateProps.innerParams.get(instance);
9051 instance.disableButtons();
9052 if (innerParams.returnInputValueOnDeny) {
9053 handleConfirmOrDenyWithInput(instance, 'deny');
9054 } else {
9055 deny(instance, false);
9056 }
9057 };
9058
9059 /**
9060 * @param {SweetAlert} instance
9061 * @param {(dismiss: DismissReason) => void} dismissWith
9062 */
9063 const handleCancelButtonClick = (instance, dismissWith) => {
9064 instance.disableButtons();
9065 dismissWith(DismissReason.cancel);
9066 };
9067
9068 /**
9069 * @param {SweetAlert} instance
9070 * @param {'confirm' | 'deny'} type
9071 */
9072 const handleConfirmOrDenyWithInput = (instance, type) => {
9073 const innerParams = privateProps.innerParams.get(instance);
9074 if (!innerParams.input) {
9075 error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
9076 return;
9077 }
9078 const input = instance.getInput();
9079 const inputValue = getInputValue(instance, innerParams);
9080 if (innerParams.inputValidator) {
9081 handleInputValidator(instance, inputValue, type);
9082 } else if (input && !input.checkValidity()) {
9083 instance.enableButtons();
9084 instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
9085 } else if (type === 'deny') {
9086 deny(instance, inputValue);
9087 } else {
9088 confirm(instance, inputValue);
9089 }
9090 };
9091
9092 /**
9093 * @param {SweetAlert} instance
9094 * @param {SweetAlertInputValue} inputValue
9095 * @param {'confirm' | 'deny'} type
9096 */
9097 const handleInputValidator = (instance, inputValue, type) => {
9098 const innerParams = privateProps.innerParams.get(instance);
9099 instance.disableInput();
9100 const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
9101 validationPromise.then(validationMessage => {
9102 instance.enableButtons();
9103 instance.enableInput();
9104 if (validationMessage) {
9105 instance.showValidationMessage(validationMessage);
9106 } else if (type === 'deny') {
9107 deny(instance, inputValue);
9108 } else {
9109 confirm(instance, inputValue);
9110 }
9111 });
9112 };
9113
9114 /**
9115 * @param {SweetAlert} instance
9116 * @param {*} value
9117 */
9118 const deny = (instance, value) => {
9119 const innerParams = privateProps.innerParams.get(instance);
9120 if (innerParams.showLoaderOnDeny) {
9121 showLoading(getDenyButton());
9122 }
9123 if (innerParams.preDeny) {
9124 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
9125 const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
9126 preDenyPromise.then(preDenyValue => {
9127 if (preDenyValue === false) {
9128 instance.hideLoading();
9129 handleAwaitingPromise(instance);
9130 } else {
9131 instance.close(/** @type SweetAlertResult */{
9132 isDenied: true,
9133 value: typeof preDenyValue === 'undefined' ? value : preDenyValue
9134 });
9135 }
9136 }).catch(error => rejectWith(instance, error));
9137 } else {
9138 instance.close(/** @type SweetAlertResult */{
9139 isDenied: true,
9140 value
9141 });
9142 }
9143 };
9144
9145 /**
9146 * @param {SweetAlert} instance
9147 * @param {*} value
9148 */
9149 const succeedWith = (instance, value) => {
9150 instance.close(/** @type SweetAlertResult */{
9151 isConfirmed: true,
9152 value
9153 });
9154 };
9155
9156 /**
9157 *
9158 * @param {SweetAlert} instance
9159 * @param {string} error
9160 */
9161 const rejectWith = (instance, error) => {
9162 instance.rejectPromise(error);
9163 };
9164
9165 /**
9166 *
9167 * @param {SweetAlert} instance
9168 * @param {*} value
9169 */
9170 const confirm = (instance, value) => {
9171 const innerParams = privateProps.innerParams.get(instance);
9172 if (innerParams.showLoaderOnConfirm) {
9173 showLoading();
9174 }
9175 if (innerParams.preConfirm) {
9176 instance.resetValidationMessage();
9177 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
9178 const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
9179 preConfirmPromise.then(preConfirmValue => {
9180 if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
9181 instance.hideLoading();
9182 handleAwaitingPromise(instance);
9183 } else {
9184 succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
9185 }
9186 }).catch(error => rejectWith(instance, error));
9187 } else {
9188 succeedWith(instance, value);
9189 }
9190 };
9191
9192 /**
9193 * Hides loader and shows back the button which was hidden by .showLoading()
9194 * @this {SweetAlert}
9195 */
9196 function hideLoading() {
9197 // do nothing if popup is closed
9198 const innerParams = privateProps.innerParams.get(this);
9199 if (!innerParams) {
9200 return;
9201 }
9202 const domCache = privateProps.domCache.get(this);
9203 hide(domCache.loader);
9204 if (isToast()) {
9205 if (innerParams.icon) {
9206 show(getIcon());
9207 }
9208 } else {
9209 showRelatedButton(domCache);
9210 }
9211 removeClass([domCache.popup, domCache.actions], swalClasses.loading);
9212 domCache.popup.removeAttribute('aria-busy');
9213 domCache.popup.removeAttribute('data-loading');
9214 domCache.confirmButton.disabled = false;
9215 domCache.denyButton.disabled = false;
9216 domCache.cancelButton.disabled = false;
9217 }
9218
9219 /**
9220 * @param {DomCache} domCache
9221 */
9222 const showRelatedButton = domCache => {
9223 const dataButtonToReplace = domCache.loader.getAttribute('data-button-to-replace');
9224 const buttonToReplace = dataButtonToReplace ? domCache.popup.getElementsByClassName(dataButtonToReplace) : [];
9225 if (buttonToReplace.length) {
9226 show(/** @type {HTMLElement} */buttonToReplace[0], 'inline-block');
9227 } else if (allButtonsAreHidden()) {
9228 hide(domCache.actions);
9229 }
9230 };
9231
9232 /**
9233 * Gets the input DOM node, this method works with input parameter.
9234 *
9235 * @returns {HTMLInputElement | null}
9236 * @this {SweetAlert}
9237 */
9238 function getInput() {
9239 const innerParams = privateProps.innerParams.get(this);
9240 const domCache = privateProps.domCache.get(this);
9241 if (!domCache) {
9242 return null;
9243 }
9244 return getInput$1(domCache.popup, innerParams.input);
9245 }
9246
9247 /**
9248 * @param {SweetAlert} instance
9249 * @param {string[]} buttons
9250 * @param {boolean} disabled
9251 */
9252 function setButtonsDisabled(instance, buttons, disabled) {
9253 const domCache = privateProps.domCache.get(instance);
9254 buttons.forEach(button => {
9255 domCache[button].disabled = disabled;
9256 });
9257 }
9258
9259 /**
9260 * @param {HTMLInputElement | null} input
9261 * @param {boolean} disabled
9262 */
9263 function setInputDisabled(input, disabled) {
9264 const popup = getPopup();
9265 if (!popup || !input) {
9266 return;
9267 }
9268 if (input.type === 'radio') {
9269 /** @type {NodeListOf<HTMLInputElement>} */
9270 const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
9271 for (let i = 0; i < radios.length; i++) {
9272 radios[i].disabled = disabled;
9273 }
9274 } else {
9275 input.disabled = disabled;
9276 }
9277 }
9278
9279 /**
9280 * Enable all the buttons
9281 * @this {SweetAlert}
9282 */
9283 function enableButtons() {
9284 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
9285 }
9286
9287 /**
9288 * Disable all the buttons
9289 * @this {SweetAlert}
9290 */
9291 function disableButtons() {
9292 setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
9293 }
9294
9295 /**
9296 * Enable the input field
9297 * @this {SweetAlert}
9298 */
9299 function enableInput() {
9300 setInputDisabled(this.getInput(), false);
9301 }
9302
9303 /**
9304 * Disable the input field
9305 * @this {SweetAlert}
9306 */
9307 function disableInput() {
9308 setInputDisabled(this.getInput(), true);
9309 }
9310
9311 /**
9312 * Show block with validation message
9313 *
9314 * @param {string} error
9315 * @this {SweetAlert}
9316 */
9317 function showValidationMessage(error) {
9318 const domCache = privateProps.domCache.get(this);
9319 const params = privateProps.innerParams.get(this);
9320 setInnerHtml(domCache.validationMessage, error);
9321 domCache.validationMessage.className = swalClasses['validation-message'];
9322 if (params.customClass && params.customClass.validationMessage) {
9323 addClass(domCache.validationMessage, params.customClass.validationMessage);
9324 }
9325 show(domCache.validationMessage);
9326 const input = this.getInput();
9327 if (input) {
9328 input.setAttribute('aria-invalid', 'true');
9329 input.setAttribute('aria-describedby', swalClasses['validation-message']);
9330 focusInput(input);
9331 addClass(input, swalClasses.inputerror);
9332 }
9333 }
9334
9335 /**
9336 * Hide block with validation message
9337 *
9338 * @this {SweetAlert}
9339 */
9340 function resetValidationMessage() {
9341 const domCache = privateProps.domCache.get(this);
9342 if (domCache.validationMessage) {
9343 hide(domCache.validationMessage);
9344 }
9345 const input = this.getInput();
9346 if (input) {
9347 input.removeAttribute('aria-invalid');
9348 input.removeAttribute('aria-describedby');
9349 removeClass(input, swalClasses.inputerror);
9350 }
9351 }
9352
9353 const defaultParams = {
9354 title: '',
9355 titleText: '',
9356 text: '',
9357 html: '',
9358 footer: '',
9359 icon: undefined,
9360 iconColor: undefined,
9361 iconHtml: undefined,
9362 template: undefined,
9363 toast: false,
9364 draggable: false,
9365 animation: true,
9366 theme: 'light',
9367 showClass: {
9368 popup: 'swal2-show',
9369 backdrop: 'swal2-backdrop-show',
9370 icon: 'swal2-icon-show'
9371 },
9372 hideClass: {
9373 popup: 'swal2-hide',
9374 backdrop: 'swal2-backdrop-hide',
9375 icon: 'swal2-icon-hide'
9376 },
9377 customClass: {},
9378 target: 'body',
9379 color: undefined,
9380 backdrop: true,
9381 heightAuto: true,
9382 allowOutsideClick: true,
9383 allowEscapeKey: true,
9384 allowEnterKey: true,
9385 stopKeydownPropagation: true,
9386 keydownListenerCapture: false,
9387 showConfirmButton: true,
9388 showDenyButton: false,
9389 showCancelButton: false,
9390 preConfirm: undefined,
9391 preDeny: undefined,
9392 confirmButtonText: 'OK',
9393 confirmButtonAriaLabel: '',
9394 confirmButtonColor: undefined,
9395 denyButtonText: 'No',
9396 denyButtonAriaLabel: '',
9397 denyButtonColor: undefined,
9398 cancelButtonText: 'Cancel',
9399 cancelButtonAriaLabel: '',
9400 cancelButtonColor: undefined,
9401 buttonsStyling: true,
9402 reverseButtons: false,
9403 focusConfirm: true,
9404 focusDeny: false,
9405 focusCancel: false,
9406 returnFocus: true,
9407 showCloseButton: false,
9408 closeButtonHtml: '&times;',
9409 closeButtonAriaLabel: 'Close this dialog',
9410 loaderHtml: '',
9411 showLoaderOnConfirm: false,
9412 showLoaderOnDeny: false,
9413 imageUrl: undefined,
9414 imageWidth: undefined,
9415 imageHeight: undefined,
9416 imageAlt: '',
9417 timer: undefined,
9418 timerProgressBar: false,
9419 width: undefined,
9420 padding: undefined,
9421 background: undefined,
9422 input: undefined,
9423 inputPlaceholder: '',
9424 inputLabel: '',
9425 inputValue: '',
9426 inputOptions: {},
9427 inputAutoFocus: true,
9428 inputAutoTrim: true,
9429 inputAttributes: {},
9430 inputValidator: undefined,
9431 returnInputValueOnDeny: false,
9432 validationMessage: undefined,
9433 grow: false,
9434 position: 'center',
9435 progressSteps: [],
9436 currentProgressStep: undefined,
9437 progressStepsDistance: undefined,
9438 willOpen: undefined,
9439 didOpen: undefined,
9440 didRender: undefined,
9441 willClose: undefined,
9442 didClose: undefined,
9443 didDestroy: undefined,
9444 scrollbarPadding: true,
9445 topLayer: false
9446 };
9447 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'];
9448
9449 /** @type {Record<string, string | undefined>} */
9450 const deprecatedParams = {
9451 allowEnterKey: undefined
9452 };
9453 const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];
9454
9455 /**
9456 * Is valid parameter
9457 *
9458 * @param {string} paramName
9459 * @returns {boolean}
9460 */
9461 const isValidParameter = paramName => {
9462 return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
9463 };
9464
9465 /**
9466 * Is valid parameter for Swal.update() method
9467 *
9468 * @param {string} paramName
9469 * @returns {boolean}
9470 */
9471 const isUpdatableParameter = paramName => {
9472 return updatableParams.indexOf(paramName) !== -1;
9473 };
9474
9475 /**
9476 * Is deprecated parameter
9477 *
9478 * @param {string} paramName
9479 * @returns {string | undefined}
9480 */
9481 const isDeprecatedParameter = paramName => {
9482 return deprecatedParams[paramName];
9483 };
9484
9485 /**
9486 * @param {string} param
9487 */
9488 const checkIfParamIsValid = param => {
9489 if (!isValidParameter(param)) {
9490 warn(`Unknown parameter "${param}"`);
9491 }
9492 };
9493
9494 /**
9495 * @param {string} param
9496 */
9497 const checkIfToastParamIsValid = param => {
9498 if (toastIncompatibleParams.includes(param)) {
9499 warn(`The parameter "${param}" is incompatible with toasts`);
9500 }
9501 };
9502
9503 /**
9504 * @param {string} param
9505 */
9506 const checkIfParamIsDeprecated = param => {
9507 const isDeprecated = isDeprecatedParameter(param);
9508 if (isDeprecated) {
9509 warnAboutDeprecation(param, isDeprecated);
9510 }
9511 };
9512
9513 /**
9514 * Show relevant warnings for given params
9515 *
9516 * @param {SweetAlertOptions} params
9517 */
9518 const showWarningsForParams = params => {
9519 if (params.backdrop === false && params.allowOutsideClick) {
9520 warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
9521 }
9522 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)) {
9523 warn(`Invalid theme "${params.theme}"`);
9524 }
9525 for (const param in params) {
9526 checkIfParamIsValid(param);
9527 if (params.toast) {
9528 checkIfToastParamIsValid(param);
9529 }
9530 checkIfParamIsDeprecated(param);
9531 }
9532 };
9533
9534 /**
9535 * Updates popup parameters.
9536 *
9537 * @this {any}
9538 * @param {SweetAlertOptions} params
9539 */
9540 function update(params) {
9541 const container = getContainer();
9542 const popup = getPopup();
9543 const innerParams = privateProps.innerParams.get(this);
9544 if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
9545 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.`);
9546 return;
9547 }
9548 const validUpdatableParams = filterValidParams(params);
9549 const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
9550 showWarningsForParams(updatedParams);
9551 if (container) {
9552 container.dataset['swal2Theme'] = updatedParams.theme;
9553 }
9554 render(this, updatedParams);
9555 privateProps.innerParams.set(this, updatedParams);
9556 Object.defineProperties(this, {
9557 params: {
9558 value: Object.assign({}, this.params, params),
9559 writable: false,
9560 enumerable: true
9561 }
9562 });
9563 }
9564
9565 /**
9566 * @param {SweetAlertOptions} params
9567 * @returns {SweetAlertOptions}
9568 */
9569 const filterValidParams = params => {
9570 /** @type {Record<string, any>} */
9571 const validUpdatableParams = {};
9572 Object.keys(params).forEach(param => {
9573 if (isUpdatableParameter(param)) {
9574 const typedParams = /** @type {Record<string, any>} */params;
9575 validUpdatableParams[param] = typedParams[param];
9576 } else {
9577 warn(`Invalid parameter to update: ${param}`);
9578 }
9579 });
9580 return validUpdatableParams;
9581 };
9582
9583 /**
9584 * Dispose the current SweetAlert2 instance
9585 * @this {SweetAlert}
9586 */
9587 function _destroy() {
9588 var _globalState$eventEmi;
9589 const domCache = privateProps.domCache.get(this);
9590 const innerParams = privateProps.innerParams.get(this);
9591 if (!innerParams) {
9592 disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
9593 return; // This instance has already been destroyed
9594 }
9595
9596 // Check if there is another Swal closing
9597 if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
9598 globalState.swalCloseEventFinishedCallback();
9599 delete globalState.swalCloseEventFinishedCallback;
9600 }
9601 if (typeof innerParams.didDestroy === 'function') {
9602 innerParams.didDestroy();
9603 }
9604 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('didDestroy');
9605 disposeSwal(this);
9606 }
9607
9608 /**
9609 * @param {SweetAlert} instance
9610 */
9611 const disposeSwal = instance => {
9612 disposeWeakMaps(instance);
9613 // Unset this.params so GC will dispose it (#1569)
9614 // @ts-ignore
9615 delete instance.params;
9616 // Unset globalState props so GC will dispose globalState (#1569)
9617 delete globalState.keydownHandler;
9618 delete globalState.keydownTarget;
9619 // Unset currentInstance
9620 delete globalState.currentInstance;
9621 };
9622
9623 /**
9624 * @param {SweetAlert} instance
9625 */
9626 const disposeWeakMaps = instance => {
9627 // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
9628 if (instance.isAwaitingPromise) {
9629 unsetWeakMaps(privateProps, instance);
9630 instance.isAwaitingPromise = true;
9631 } else {
9632 unsetWeakMaps(privateMethods, instance);
9633 unsetWeakMaps(privateProps, instance);
9634
9635 // @ts-ignore
9636 delete instance.isAwaitingPromise;
9637 // Unset instance methods
9638 // @ts-ignore
9639 delete instance.disableButtons;
9640 // @ts-ignore
9641 delete instance.enableButtons;
9642 // @ts-ignore
9643 delete instance.getInput;
9644 // @ts-ignore
9645 delete instance.disableInput;
9646 // @ts-ignore
9647 delete instance.enableInput;
9648 // @ts-ignore
9649 delete instance.hideLoading;
9650 // @ts-ignore
9651 delete instance.disableLoading;
9652 // @ts-ignore
9653 delete instance.showValidationMessage;
9654 // @ts-ignore
9655 delete instance.resetValidationMessage;
9656 // @ts-ignore
9657 delete instance.close;
9658 // @ts-ignore
9659 delete instance.closePopup;
9660 // @ts-ignore
9661 delete instance.closeModal;
9662 // @ts-ignore
9663 delete instance.closeToast;
9664 // @ts-ignore
9665 delete instance.rejectPromise;
9666 // @ts-ignore
9667 delete instance.update;
9668 // @ts-ignore
9669 delete instance._destroy;
9670 }
9671 };
9672
9673 /**
9674 * @param {Record<string, WeakMap<any, any>>} obj
9675 * @param {SweetAlert} instance
9676 */
9677 const unsetWeakMaps = (obj, instance) => {
9678 for (const i in obj) {
9679 obj[i].delete(instance);
9680 }
9681 };
9682
9683 var instanceMethods = /*#__PURE__*/Object.freeze({
9684 __proto__: null,
9685 _destroy: _destroy,
9686 close: close,
9687 closeModal: close,
9688 closePopup: close,
9689 closeToast: close,
9690 disableButtons: disableButtons,
9691 disableInput: disableInput,
9692 disableLoading: hideLoading,
9693 enableButtons: enableButtons,
9694 enableInput: enableInput,
9695 getInput: getInput,
9696 handleAwaitingPromise: handleAwaitingPromise,
9697 hideLoading: hideLoading,
9698 rejectPromise: rejectPromise,
9699 resetValidationMessage: resetValidationMessage,
9700 showValidationMessage: showValidationMessage,
9701 update: update
9702 });
9703
9704 /**
9705 * @param {SweetAlertOptions} innerParams
9706 * @param {DomCache} domCache
9707 * @param {(dismiss: DismissReason) => void} dismissWith
9708 */
9709 const handlePopupClick = (innerParams, domCache, dismissWith) => {
9710 if (innerParams.toast) {
9711 handleToastClick(innerParams, domCache, dismissWith);
9712 } else {
9713 // Ignore click events that had mousedown on the popup but mouseup on the container
9714 // This can happen when the user drags a slider
9715 handleModalMousedown(domCache);
9716
9717 // Ignore click events that had mousedown on the container but mouseup on the popup
9718 handleContainerMousedown(domCache);
9719 handleModalClick(innerParams, domCache, dismissWith);
9720 }
9721 };
9722
9723 /**
9724 * @param {SweetAlertOptions} innerParams
9725 * @param {DomCache} domCache
9726 * @param {(dismiss: DismissReason) => void} dismissWith
9727 */
9728 const handleToastClick = (innerParams, domCache, dismissWith) => {
9729 // Closing toast by internal click
9730 domCache.popup.onclick = () => {
9731 if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
9732 return;
9733 }
9734 dismissWith(DismissReason.close);
9735 };
9736 };
9737
9738 /**
9739 * @param {SweetAlertOptions} innerParams
9740 * @returns {boolean}
9741 */
9742 const isAnyButtonShown = innerParams => {
9743 return Boolean(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
9744 };
9745 let ignoreOutsideClick = false;
9746
9747 /**
9748 * @param {DomCache} domCache
9749 */
9750 const handleModalMousedown = domCache => {
9751 domCache.popup.onmousedown = () => {
9752 domCache.container.onmouseup = function (e) {
9753 domCache.container.onmouseup = () => {};
9754 // We only check if the mouseup target is the container because usually it doesn't
9755 // have any other direct children aside of the popup
9756 if (e.target === domCache.container) {
9757 ignoreOutsideClick = true;
9758 }
9759 };
9760 };
9761 };
9762
9763 /**
9764 * @param {DomCache} domCache
9765 */
9766 const handleContainerMousedown = domCache => {
9767 domCache.container.onmousedown = e => {
9768 // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
9769 if (e.target === domCache.container) {
9770 e.preventDefault();
9771 }
9772 domCache.popup.onmouseup = function (e) {
9773 domCache.popup.onmouseup = () => {};
9774 // We also need to check if the mouseup target is a child of the popup
9775 if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
9776 ignoreOutsideClick = true;
9777 }
9778 };
9779 };
9780 };
9781
9782 /**
9783 * @param {SweetAlertOptions} innerParams
9784 * @param {DomCache} domCache
9785 * @param {(dismiss: DismissReason) => void} dismissWith
9786 */
9787 const handleModalClick = (innerParams, domCache, dismissWith) => {
9788 domCache.container.onclick = e => {
9789 if (ignoreOutsideClick) {
9790 ignoreOutsideClick = false;
9791 return;
9792 }
9793 if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
9794 dismissWith(DismissReason.backdrop);
9795 }
9796 };
9797 };
9798
9799 /**
9800 * @param {any} elem
9801 * @returns {boolean}
9802 */
9803 const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
9804
9805 /**
9806 * @param {any} elem
9807 * @returns {boolean}
9808 */
9809 const isElement = elem => elem instanceof Element || isJqueryElement(elem);
9810
9811 /**
9812 * @param {any[]} args
9813 * @returns {SweetAlertOptions}
9814 */
9815 const argsToParams = args => {
9816 /** @type {Record<string, any>} */
9817 const params = {};
9818 if (typeof args[0] === 'object' && !isElement(args[0])) {
9819 Object.assign(params, args[0]);
9820 } else {
9821 ['title', 'html', 'icon'].forEach((name, index) => {
9822 const arg = args[index];
9823 if (typeof arg === 'string' || isElement(arg)) {
9824 params[name] = arg;
9825 } else if (arg !== undefined) {
9826 error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
9827 }
9828 });
9829 }
9830 return params;
9831 };
9832
9833 /**
9834 * Main method to create a new SweetAlert2 popup
9835 *
9836 * @this {new (...args: any[]) => any}
9837 * @param {...SweetAlertOptions} args
9838 * @returns {Promise<SweetAlertResult>}
9839 */
9840 function fire(...args) {
9841 return new this(...args);
9842 }
9843
9844 /**
9845 * Returns an extended version of `Swal` containing `params` as defaults.
9846 * Useful for reusing Swal configuration.
9847 *
9848 * For example:
9849 *
9850 * Before:
9851 * const textPromptOptions = { input: 'text', showCancelButton: true }
9852 * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
9853 * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
9854 *
9855 * After:
9856 * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
9857 * const {value: firstName} = await TextPrompt('What is your first name?')
9858 * const {value: lastName} = await TextPrompt('What is your last name?')
9859 *
9860 * @param {SweetAlertOptions} mixinParams
9861 * @returns {SweetAlert}
9862 * @this {typeof import('../SweetAlert.js').SweetAlert}
9863 */
9864 function mixin(mixinParams) {
9865 // @ts-ignore: 'this' refers to the SweetAlert constructor
9866 class MixinSwal extends this {
9867 /**
9868 * @param {any} params
9869 * @param {any} priorityMixinParams
9870 */
9871 _main(params, priorityMixinParams) {
9872 return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
9873 }
9874 }
9875 // @ts-ignore
9876 return MixinSwal;
9877 }
9878
9879 /**
9880 * If `timer` parameter is set, returns number of milliseconds of timer remained.
9881 * Otherwise, returns undefined.
9882 *
9883 * @returns {number | undefined}
9884 */
9885 const getTimerLeft = () => {
9886 return globalState.timeout && globalState.timeout.getTimerLeft();
9887 };
9888
9889 /**
9890 * Stop timer. Returns number of milliseconds of timer remained.
9891 * If `timer` parameter isn't set, returns undefined.
9892 *
9893 * @returns {number | undefined}
9894 */
9895 const stopTimer = () => {
9896 if (globalState.timeout) {
9897 stopTimerProgressBar();
9898 return globalState.timeout.stop();
9899 }
9900 };
9901
9902 /**
9903 * Resume timer. Returns number of milliseconds of timer remained.
9904 * If `timer` parameter isn't set, returns undefined.
9905 *
9906 * @returns {number | undefined}
9907 */
9908 const resumeTimer = () => {
9909 if (globalState.timeout) {
9910 const remaining = globalState.timeout.start();
9911 animateTimerProgressBar(remaining);
9912 return remaining;
9913 }
9914 };
9915
9916 /**
9917 * Resume timer. Returns number of milliseconds of timer remained.
9918 * If `timer` parameter isn't set, returns undefined.
9919 *
9920 * @returns {number | undefined}
9921 */
9922 const toggleTimer = () => {
9923 const timer = globalState.timeout;
9924 return timer && (timer.running ? stopTimer() : resumeTimer());
9925 };
9926
9927 /**
9928 * Increase timer. Returns number of milliseconds of an updated timer.
9929 * If `timer` parameter isn't set, returns undefined.
9930 *
9931 * @param {number} ms
9932 * @returns {number | undefined}
9933 */
9934 const increaseTimer = ms => {
9935 if (globalState.timeout) {
9936 const remaining = globalState.timeout.increase(ms);
9937 animateTimerProgressBar(remaining, true);
9938 return remaining;
9939 }
9940 };
9941
9942 /**
9943 * Check if timer is running. Returns true if timer is running
9944 * or false if timer is paused or stopped.
9945 * If `timer` parameter isn't set, returns undefined
9946 *
9947 * @returns {boolean}
9948 */
9949 const isTimerRunning = () => {
9950 return Boolean(globalState.timeout && globalState.timeout.isRunning());
9951 };
9952
9953 let bodyClickListenerAdded = false;
9954 /** @type {Record<string, any>} */
9955 const clickHandlers = {};
9956
9957 /**
9958 * @this {any}
9959 * @param {string} attr
9960 */
9961 function bindClickHandler(attr = 'data-swal-template') {
9962 clickHandlers[attr] = this;
9963 if (!bodyClickListenerAdded) {
9964 document.body.addEventListener('click', bodyClickListener);
9965 bodyClickListenerAdded = true;
9966 }
9967 }
9968
9969 /**
9970 * @param {MouseEvent} event
9971 */
9972 const bodyClickListener = event => {
9973 for (let el = /** @type {any} */event.target; el && el !== document; el = el.parentNode) {
9974 for (const attr in clickHandlers) {
9975 const template = el.getAttribute && el.getAttribute(attr);
9976 if (template) {
9977 clickHandlers[attr].fire({
9978 template
9979 });
9980 return;
9981 }
9982 }
9983 }
9984 };
9985
9986 // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957
9987
9988 class EventEmitter {
9989 constructor() {
9990 /** @type {Events} */
9991 this.events = {};
9992 }
9993
9994 /**
9995 * @param {string} eventName
9996 * @returns {EventHandlers}
9997 */
9998 _getHandlersByEventName(eventName) {
9999 if (typeof this.events[eventName] === 'undefined') {
10000 // not Set because we need to keep the FIFO order
10001 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
10002 this.events[eventName] = [];
10003 }
10004 return this.events[eventName];
10005 }
10006
10007 /**
10008 * @param {string} eventName
10009 * @param {EventHandler} eventHandler
10010 */
10011 on(eventName, eventHandler) {
10012 const currentHandlers = this._getHandlersByEventName(eventName);
10013 if (!currentHandlers.includes(eventHandler)) {
10014 currentHandlers.push(eventHandler);
10015 }
10016 }
10017
10018 /**
10019 * @param {string} eventName
10020 * @param {EventHandler} eventHandler
10021 */
10022 once(eventName, eventHandler) {
10023 /**
10024 * @param {...any} args
10025 */
10026 const onceFn = (...args) => {
10027 this.removeListener(eventName, onceFn);
10028 // @ts-ignore
10029 eventHandler.apply(this, args);
10030 };
10031 this.on(eventName, onceFn);
10032 }
10033
10034 /**
10035 * @param {string} eventName
10036 * @param {...any} args
10037 */
10038 emit(eventName, ...args) {
10039 this._getHandlersByEventName(eventName).forEach(
10040 /**
10041 * @param {EventHandler} eventHandler
10042 */
10043 eventHandler => {
10044 try {
10045 // @ts-ignore
10046 eventHandler.apply(this, args);
10047 } catch (error) {
10048 console.error(error);
10049 }
10050 });
10051 }
10052
10053 /**
10054 * @param {string} eventName
10055 * @param {EventHandler} eventHandler
10056 */
10057 removeListener(eventName, eventHandler) {
10058 const currentHandlers = this._getHandlersByEventName(eventName);
10059 const index = currentHandlers.indexOf(eventHandler);
10060 if (index > -1) {
10061 currentHandlers.splice(index, 1);
10062 }
10063 }
10064
10065 /**
10066 * @param {string} eventName
10067 */
10068 removeAllListeners(eventName) {
10069 if (this.events[eventName] !== undefined) {
10070 // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
10071 this.events[eventName].length = 0;
10072 }
10073 }
10074 reset() {
10075 this.events = {};
10076 }
10077 }
10078
10079 globalState.eventEmitter = new EventEmitter();
10080
10081 /**
10082 * @param {string} eventName
10083 * @param {EventHandler} eventHandler
10084 */
10085 const on = (eventName, eventHandler) => {
10086 if (globalState.eventEmitter) {
10087 globalState.eventEmitter.on(eventName, eventHandler);
10088 }
10089 };
10090
10091 /**
10092 * @param {string} eventName
10093 * @param {EventHandler} eventHandler
10094 */
10095 const once = (eventName, eventHandler) => {
10096 if (globalState.eventEmitter) {
10097 globalState.eventEmitter.once(eventName, eventHandler);
10098 }
10099 };
10100
10101 /**
10102 * @param {string} [eventName]
10103 * @param {EventHandler} [eventHandler]
10104 */
10105 const off = (eventName, eventHandler) => {
10106 if (!globalState.eventEmitter) {
10107 return;
10108 }
10109
10110 // Remove all handlers for all events
10111 if (!eventName) {
10112 globalState.eventEmitter.reset();
10113 return;
10114 }
10115 if (eventHandler) {
10116 // Remove a specific handler
10117 globalState.eventEmitter.removeListener(eventName, eventHandler);
10118 } else {
10119 // Remove all handlers for a specific event
10120 globalState.eventEmitter.removeAllListeners(eventName);
10121 }
10122 };
10123
10124 var staticMethods = /*#__PURE__*/Object.freeze({
10125 __proto__: null,
10126 argsToParams: argsToParams,
10127 bindClickHandler: bindClickHandler,
10128 clickCancel: clickCancel,
10129 clickConfirm: clickConfirm,
10130 clickDeny: clickDeny,
10131 enableLoading: showLoading,
10132 fire: fire,
10133 getActions: getActions,
10134 getCancelButton: getCancelButton,
10135 getCloseButton: getCloseButton,
10136 getConfirmButton: getConfirmButton,
10137 getContainer: getContainer,
10138 getDenyButton: getDenyButton,
10139 getFocusableElements: getFocusableElements,
10140 getFooter: getFooter,
10141 getHtmlContainer: getHtmlContainer,
10142 getIcon: getIcon,
10143 getIconContent: getIconContent,
10144 getImage: getImage,
10145 getInputLabel: getInputLabel,
10146 getLoader: getLoader,
10147 getPopup: getPopup,
10148 getProgressSteps: getProgressSteps,
10149 getTimerLeft: getTimerLeft,
10150 getTimerProgressBar: getTimerProgressBar,
10151 getTitle: getTitle,
10152 getValidationMessage: getValidationMessage,
10153 increaseTimer: increaseTimer,
10154 isDeprecatedParameter: isDeprecatedParameter,
10155 isLoading: isLoading,
10156 isTimerRunning: isTimerRunning,
10157 isUpdatableParameter: isUpdatableParameter,
10158 isValidParameter: isValidParameter,
10159 isVisible: isVisible,
10160 mixin: mixin,
10161 off: off,
10162 on: on,
10163 once: once,
10164 resumeTimer: resumeTimer,
10165 showLoading: showLoading,
10166 stopTimer: stopTimer,
10167 toggleTimer: toggleTimer
10168 });
10169
10170 class Timer {
10171 /**
10172 * @param {() => void} callback
10173 * @param {number} delay
10174 */
10175 constructor(callback, delay) {
10176 this.callback = callback;
10177 this.remaining = delay;
10178 this.running = false;
10179 this.start();
10180 }
10181
10182 /**
10183 * @returns {number}
10184 */
10185 start() {
10186 if (!this.running) {
10187 this.running = true;
10188 this.started = new Date();
10189 this.id = setTimeout(this.callback, this.remaining);
10190 }
10191 return this.remaining;
10192 }
10193
10194 /**
10195 * @returns {number}
10196 */
10197 stop() {
10198 if (this.started && this.running) {
10199 this.running = false;
10200 clearTimeout(this.id);
10201 this.remaining -= new Date().getTime() - this.started.getTime();
10202 }
10203 return this.remaining;
10204 }
10205
10206 /**
10207 * @param {number} n
10208 * @returns {number}
10209 */
10210 increase(n) {
10211 const running = this.running;
10212 if (running) {
10213 this.stop();
10214 }
10215 this.remaining += n;
10216 if (running) {
10217 this.start();
10218 }
10219 return this.remaining;
10220 }
10221
10222 /**
10223 * @returns {number}
10224 */
10225 getTimerLeft() {
10226 if (this.running) {
10227 this.stop();
10228 this.start();
10229 }
10230 return this.remaining;
10231 }
10232
10233 /**
10234 * @returns {boolean}
10235 */
10236 isRunning() {
10237 return this.running;
10238 }
10239 }
10240
10241 const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];
10242
10243 /**
10244 * @param {SweetAlertOptions} params
10245 * @returns {SweetAlertOptions}
10246 */
10247 const getTemplateParams = params => {
10248 const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
10249 if (!template) {
10250 return {};
10251 }
10252 /** @type {DocumentFragment} */
10253 const templateContent = template.content;
10254 showWarningsForElements(templateContent);
10255 const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
10256 return result;
10257 };
10258
10259 /**
10260 * @param {DocumentFragment} templateContent
10261 * @returns {Record<string, string | boolean | number>}
10262 */
10263 const getSwalParams = templateContent => {
10264 /** @type {Record<string, string | boolean | number>} */
10265 const result = {};
10266 /** @type {HTMLElement[]} */
10267 const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
10268 swalParams.forEach(param => {
10269 showWarningsForAttributes(param, ['name', 'value']);
10270 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10271 const value = param.getAttribute('value');
10272 if (!paramName || !value) {
10273 return;
10274 }
10275 if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'boolean') {
10276 result[paramName] = value !== 'false';
10277 } else if (paramName in defaultParams && typeof defaultParams[(/** @type {keyof typeof defaultParams} */paramName)] === 'object') {
10278 result[paramName] = JSON.parse(value);
10279 } else {
10280 result[paramName] = value;
10281 }
10282 });
10283 return result;
10284 };
10285
10286 /**
10287 * @param {DocumentFragment} templateContent
10288 * @returns {Record<string, () => void>}
10289 */
10290 const getSwalFunctionParams = templateContent => {
10291 /** @type {Record<string, () => void>} */
10292 const result = {};
10293 /** @type {HTMLElement[]} */
10294 const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
10295 swalFunctions.forEach(param => {
10296 const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
10297 const value = param.getAttribute('value');
10298 if (!paramName || !value) {
10299 return;
10300 }
10301 result[paramName] = new Function(`return ${value}`)();
10302 });
10303 return result;
10304 };
10305
10306 /**
10307 * @param {DocumentFragment} templateContent
10308 * @returns {Record<string, string | boolean>}
10309 */
10310 const getSwalButtons = templateContent => {
10311 /** @type {Record<string, string | boolean>} */
10312 const result = {};
10313 /** @type {HTMLElement[]} */
10314 const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
10315 swalButtons.forEach(button => {
10316 showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
10317 const type = button.getAttribute('type');
10318 if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
10319 return;
10320 }
10321 result[`${type}ButtonText`] = button.innerHTML;
10322 result[`show${capitalizeFirstLetter(type)}Button`] = true;
10323 if (button.hasAttribute('color')) {
10324 const color = button.getAttribute('color');
10325 if (color !== null) {
10326 result[`${type}ButtonColor`] = color;
10327 }
10328 }
10329 if (button.hasAttribute('aria-label')) {
10330 const ariaLabel = button.getAttribute('aria-label');
10331 if (ariaLabel !== null) {
10332 result[`${type}ButtonAriaLabel`] = ariaLabel;
10333 }
10334 }
10335 });
10336 return result;
10337 };
10338
10339 /**
10340 * @param {DocumentFragment} templateContent
10341 * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
10342 */
10343 const getSwalImage = templateContent => {
10344 const result = {};
10345 /** @type {HTMLElement | null} */
10346 const image = templateContent.querySelector('swal-image');
10347 if (image) {
10348 showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
10349 if (image.hasAttribute('src')) {
10350 result.imageUrl = image.getAttribute('src') || undefined;
10351 }
10352 if (image.hasAttribute('width')) {
10353 result.imageWidth = image.getAttribute('width') || undefined;
10354 }
10355 if (image.hasAttribute('height')) {
10356 result.imageHeight = image.getAttribute('height') || undefined;
10357 }
10358 if (image.hasAttribute('alt')) {
10359 result.imageAlt = image.getAttribute('alt') || undefined;
10360 }
10361 }
10362 return result;
10363 };
10364
10365 /**
10366 * @param {DocumentFragment} templateContent
10367 * @returns {object}
10368 */
10369 const getSwalIcon = templateContent => {
10370 const result = {};
10371 /** @type {HTMLElement | null} */
10372 const icon = templateContent.querySelector('swal-icon');
10373 if (icon) {
10374 showWarningsForAttributes(icon, ['type', 'color']);
10375 if (icon.hasAttribute('type')) {
10376 result.icon = icon.getAttribute('type');
10377 }
10378 if (icon.hasAttribute('color')) {
10379 result.iconColor = icon.getAttribute('color');
10380 }
10381 result.iconHtml = icon.innerHTML;
10382 }
10383 return result;
10384 };
10385
10386 /**
10387 * @param {DocumentFragment} templateContent
10388 * @returns {object}
10389 */
10390 const getSwalInput = templateContent => {
10391 /** @type {Record<string, any>} */
10392 const result = {};
10393 /** @type {HTMLElement | null} */
10394 const input = templateContent.querySelector('swal-input');
10395 if (input) {
10396 showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
10397 result.input = input.getAttribute('type') || 'text';
10398 if (input.hasAttribute('label')) {
10399 result.inputLabel = input.getAttribute('label');
10400 }
10401 if (input.hasAttribute('placeholder')) {
10402 result.inputPlaceholder = input.getAttribute('placeholder');
10403 }
10404 if (input.hasAttribute('value')) {
10405 result.inputValue = input.getAttribute('value');
10406 }
10407 }
10408 /** @type {HTMLElement[]} */
10409 const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
10410 if (inputOptions.length) {
10411 result.inputOptions = {};
10412 inputOptions.forEach(option => {
10413 showWarningsForAttributes(option, ['value']);
10414 const optionValue = option.getAttribute('value');
10415 if (!optionValue) {
10416 return;
10417 }
10418 const optionName = option.innerHTML;
10419 result.inputOptions[optionValue] = optionName;
10420 });
10421 }
10422 return result;
10423 };
10424
10425 /**
10426 * @param {DocumentFragment} templateContent
10427 * @param {string[]} paramNames
10428 * @returns {Record<string, string>}
10429 */
10430 const getSwalStringParams = (templateContent, paramNames) => {
10431 /** @type {Record<string, string>} */
10432 const result = {};
10433 for (const i in paramNames) {
10434 const paramName = paramNames[i];
10435 /** @type {HTMLElement | null} */
10436 const tag = templateContent.querySelector(paramName);
10437 if (tag) {
10438 showWarningsForAttributes(tag, []);
10439 result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
10440 }
10441 }
10442 return result;
10443 };
10444
10445 /**
10446 * @param {DocumentFragment} templateContent
10447 */
10448 const showWarningsForElements = templateContent => {
10449 const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
10450 Array.from(templateContent.children).forEach(el => {
10451 const tagName = el.tagName.toLowerCase();
10452 if (!allowedElements.includes(tagName)) {
10453 warn(`Unrecognized element <${tagName}>`);
10454 }
10455 });
10456 };
10457
10458 /**
10459 * @param {HTMLElement} el
10460 * @param {string[]} allowedAttributes
10461 */
10462 const showWarningsForAttributes = (el, allowedAttributes) => {
10463 Array.from(el.attributes).forEach(attribute => {
10464 if (allowedAttributes.indexOf(attribute.name) === -1) {
10465 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.'}`]);
10466 }
10467 });
10468 };
10469
10470 const SHOW_CLASS_TIMEOUT = 10;
10471
10472 /**
10473 * Open popup, add necessary classes and styles, fix scrollbar
10474 *
10475 * @param {SweetAlertOptions} params
10476 */
10477 const openPopup = params => {
10478 var _globalState$eventEmi, _globalState$eventEmi2;
10479 const container = getContainer();
10480 const popup = getPopup();
10481 if (!container || !popup) {
10482 return;
10483 }
10484 if (typeof params.willOpen === 'function') {
10485 params.willOpen(popup);
10486 }
10487 (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willOpen', popup);
10488 const bodyStyles = window.getComputedStyle(document.body);
10489 const initialBodyOverflow = bodyStyles.overflowY;
10490 addClasses(container, popup, params);
10491
10492 // scrolling is 'hidden' until animation is done, after that 'auto'
10493 setTimeout(() => {
10494 setScrollingVisibility(container, popup);
10495 }, SHOW_CLASS_TIMEOUT);
10496 if (isModal()) {
10497 // Using ternary instead of ?? operator for Webpack 4 compatibility
10498 fixScrollContainer(container, params.scrollbarPadding !== undefined ? params.scrollbarPadding : false, initialBodyOverflow);
10499 setAriaHidden();
10500 }
10501 if (!isToast() && !globalState.previousActiveElement) {
10502 globalState.previousActiveElement = document.activeElement;
10503 }
10504 if (typeof params.didOpen === 'function') {
10505 const didOpen = params.didOpen;
10506 setTimeout(() => didOpen(popup));
10507 }
10508 (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didOpen', popup);
10509 };
10510
10511 /**
10512 * @param {Event} event
10513 */
10514 const swalOpenAnimationFinished = event => {
10515 const popup = getPopup();
10516 if (!popup || event.target !== popup) {
10517 return;
10518 }
10519 const container = getContainer();
10520 if (!container) {
10521 return;
10522 }
10523 popup.removeEventListener('animationend', swalOpenAnimationFinished);
10524 popup.removeEventListener('transitionend', swalOpenAnimationFinished);
10525 container.style.overflowY = 'auto';
10526
10527 // no-transition is added in init() in case one swal is opened right after another
10528 removeClass(container, swalClasses['no-transition']);
10529 };
10530
10531 /**
10532 * @param {HTMLElement} container
10533 * @param {HTMLElement} popup
10534 */
10535 const setScrollingVisibility = (container, popup) => {
10536 if (hasCssAnimation(popup)) {
10537 container.style.overflowY = 'hidden';
10538 popup.addEventListener('animationend', swalOpenAnimationFinished);
10539 popup.addEventListener('transitionend', swalOpenAnimationFinished);
10540 } else {
10541 container.style.overflowY = 'auto';
10542 }
10543 };
10544
10545 /**
10546 * @param {HTMLElement} container
10547 * @param {boolean} scrollbarPadding
10548 * @param {string} initialBodyOverflow
10549 */
10550 const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
10551 iOSfix();
10552 if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
10553 replaceScrollbarWithPadding(initialBodyOverflow);
10554 }
10555
10556 // sweetalert2/issues/1247
10557 setTimeout(() => {
10558 container.scrollTop = 0;
10559 });
10560 };
10561
10562 /**
10563 * @param {HTMLElement} container
10564 * @param {HTMLElement} popup
10565 * @param {SweetAlertOptions} params
10566 */
10567 const addClasses = (container, popup, params) => {
10568 var _params$showClass;
10569 if ((_params$showClass = params.showClass) !== null && _params$showClass !== void 0 && _params$showClass.backdrop) {
10570 addClass(container, params.showClass.backdrop);
10571 }
10572 if (params.animation) {
10573 // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
10574 popup.style.setProperty('opacity', '0', 'important');
10575 show(popup, 'grid');
10576 setTimeout(() => {
10577 var _params$showClass2;
10578 // Animate popup right after showing it
10579 if ((_params$showClass2 = params.showClass) !== null && _params$showClass2 !== void 0 && _params$showClass2.popup) {
10580 addClass(popup, params.showClass.popup);
10581 }
10582 // and remove the opacity workaround
10583 popup.style.removeProperty('opacity');
10584 }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
10585 } else {
10586 show(popup, 'grid');
10587 }
10588 addClass([document.documentElement, document.body], swalClasses.shown);
10589 if (params.heightAuto && params.backdrop && !params.toast) {
10590 addClass([document.documentElement, document.body], swalClasses['height-auto']);
10591 }
10592 };
10593
10594 var defaultInputValidators = {
10595 /**
10596 * @param {string} string
10597 * @param {string} [validationMessage]
10598 * @returns {Promise<string | void>}
10599 */
10600 email: (string, validationMessage) => {
10601 return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
10602 },
10603 /**
10604 * @param {string} string
10605 * @param {string} [validationMessage]
10606 * @returns {Promise<string | void>}
10607 */
10608 url: (string, validationMessage) => {
10609 // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
10610 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');
10611 }
10612 };
10613
10614 /**
10615 * @param {SweetAlertOptions} params
10616 */
10617 function setDefaultInputValidators(params) {
10618 // Use default `inputValidator` for supported input types if not provided
10619 if (params.inputValidator) {
10620 return;
10621 }
10622 if (params.input === 'email') {
10623 params.inputValidator = defaultInputValidators['email'];
10624 }
10625 if (params.input === 'url') {
10626 params.inputValidator = defaultInputValidators['url'];
10627 }
10628 }
10629
10630 /**
10631 * @param {SweetAlertOptions} params
10632 */
10633 function validateCustomTargetElement(params) {
10634 // Determine if the custom target element is valid
10635 if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
10636 warn('Target parameter is not valid, defaulting to "body"');
10637 params.target = 'body';
10638 }
10639 }
10640
10641 /**
10642 * Set type, text and actions on popup
10643 *
10644 * @param {SweetAlertOptions} params
10645 */
10646 function setParameters(params) {
10647 setDefaultInputValidators(params);
10648
10649 // showLoaderOnConfirm && preConfirm
10650 if (params.showLoaderOnConfirm && !params.preConfirm) {
10651 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');
10652 }
10653 validateCustomTargetElement(params);
10654
10655 // Replace newlines with <br> in title
10656 if (typeof params.title === 'string') {
10657 params.title = params.title.split('\n').join('<br />');
10658 }
10659 init(params);
10660 }
10661
10662 /** @type {SweetAlert} */
10663 let currentInstance;
10664 var _promise = /*#__PURE__*/new WeakMap();
10665 class SweetAlert {
10666 /**
10667 * @param {...(SweetAlertOptions | string)} args
10668 * @this {SweetAlert}
10669 */
10670 constructor(...args) {
10671 /**
10672 * @type {Promise<SweetAlertResult>}
10673 */
10674 _classPrivateFieldInitSpec(this, _promise, /** @type {Promise<SweetAlertResult>} */Promise.resolve({
10675 isConfirmed: false,
10676 isDenied: false,
10677 isDismissed: true
10678 }));
10679 // Prevent run in Node env
10680 if (typeof window === 'undefined') {
10681 return;
10682 }
10683 currentInstance = this;
10684
10685 // @ts-ignore
10686 const outerParams = Object.freeze(this.constructor.argsToParams(args));
10687
10688 /** @type {Readonly<SweetAlertOptions>} */
10689 this.params = outerParams;
10690
10691 /** @type {boolean} */
10692 this.isAwaitingPromise = false;
10693 _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
10694 }
10695
10696 /**
10697 * @param {any} userParams
10698 * @param {any} mixinParams
10699 */
10700 _main(userParams, mixinParams = {}) {
10701 showWarningsForParams(Object.assign({}, mixinParams, userParams));
10702 if (globalState.currentInstance) {
10703 const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
10704 const {
10705 isAwaitingPromise
10706 } = globalState.currentInstance;
10707 globalState.currentInstance._destroy();
10708 if (!isAwaitingPromise) {
10709 swalPromiseResolve({
10710 isDismissed: true
10711 });
10712 }
10713 if (isModal()) {
10714 unsetAriaHidden();
10715 }
10716 }
10717 globalState.currentInstance = currentInstance;
10718 const innerParams = prepareParams(userParams, mixinParams);
10719 setParameters(innerParams);
10720 Object.freeze(innerParams);
10721
10722 // clear the previous timer
10723 if (globalState.timeout) {
10724 globalState.timeout.stop();
10725 delete globalState.timeout;
10726 }
10727
10728 // clear the restore focus timeout
10729 clearTimeout(globalState.restoreFocusTimeout);
10730 const domCache = populateDomCache(currentInstance);
10731 render(currentInstance, innerParams);
10732 privateProps.innerParams.set(currentInstance, innerParams);
10733 return swalPromise(currentInstance, domCache, innerParams);
10734 }
10735
10736 // `catch` cannot be the name of a module export, so we define our thenable methods here instead
10737 /**
10738 * @param {any} onFulfilled
10739 */
10740 then(onFulfilled) {
10741 return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
10742 }
10743
10744 /**
10745 * @param {any} onFinally
10746 */
10747 finally(onFinally) {
10748 return _classPrivateFieldGet2(_promise, this).finally(onFinally);
10749 }
10750 }
10751
10752 /**
10753 * @param {SweetAlert} instance
10754 * @param {DomCache} domCache
10755 * @param {SweetAlertOptions} innerParams
10756 * @returns {Promise<SweetAlertResult>}
10757 */
10758 const swalPromise = (instance, domCache, innerParams) => {
10759 return new Promise((resolve, reject) => {
10760 // functions to handle all closings/dismissals
10761 /**
10762 * @param {DismissReason} dismiss
10763 */
10764 const dismissWith = dismiss => {
10765 instance.close({
10766 isDismissed: true,
10767 dismiss,
10768 isConfirmed: false,
10769 isDenied: false
10770 });
10771 };
10772 privateMethods.swalPromiseResolve.set(instance, resolve);
10773 privateMethods.swalPromiseReject.set(instance, reject);
10774 domCache.confirmButton.onclick = () => {
10775 handleConfirmButtonClick(instance);
10776 };
10777 domCache.denyButton.onclick = () => {
10778 handleDenyButtonClick(instance);
10779 };
10780 domCache.cancelButton.onclick = () => {
10781 handleCancelButtonClick(instance, dismissWith);
10782 };
10783 domCache.closeButton.onclick = () => {
10784 dismissWith(DismissReason.close);
10785 };
10786 handlePopupClick(innerParams, domCache, dismissWith);
10787 addKeydownHandler(globalState, innerParams, dismissWith);
10788 handleInputOptionsAndValue(instance, innerParams);
10789 openPopup(innerParams);
10790 setupTimer(globalState, innerParams, dismissWith);
10791 initFocus(domCache, innerParams);
10792
10793 // Scroll container to top on open (#1247, #1946)
10794 setTimeout(() => {
10795 domCache.container.scrollTop = 0;
10796 });
10797 });
10798 };
10799
10800 /**
10801 * @param {SweetAlertOptions} userParams
10802 * @param {SweetAlertOptions} mixinParams
10803 * @returns {SweetAlertOptions}
10804 */
10805 const prepareParams = (userParams, mixinParams) => {
10806 const templateParams = getTemplateParams(userParams);
10807 const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
10808 params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
10809 params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
10810 if (params.animation === false) {
10811 params.showClass = {
10812 backdrop: 'swal2-noanimation'
10813 };
10814 params.hideClass = {};
10815 }
10816 return params;
10817 };
10818
10819 /**
10820 * @param {SweetAlert} instance
10821 * @returns {DomCache}
10822 */
10823 const populateDomCache = instance => {
10824 const domCache = /** @type {DomCache} */{
10825 popup: (/** @type {HTMLElement} */getPopup()),
10826 container: (/** @type {HTMLElement} */getContainer()),
10827 actions: (/** @type {HTMLElement} */getActions()),
10828 confirmButton: (/** @type {HTMLElement} */getConfirmButton()),
10829 denyButton: (/** @type {HTMLElement} */getDenyButton()),
10830 cancelButton: (/** @type {HTMLElement} */getCancelButton()),
10831 loader: (/** @type {HTMLElement} */getLoader()),
10832 closeButton: (/** @type {HTMLElement} */getCloseButton()),
10833 validationMessage: (/** @type {HTMLElement} */getValidationMessage()),
10834 progressSteps: (/** @type {HTMLElement} */getProgressSteps())
10835 };
10836 privateProps.domCache.set(instance, domCache);
10837 return domCache;
10838 };
10839
10840 /**
10841 * @param {GlobalState} globalState
10842 * @param {SweetAlertOptions} innerParams
10843 * @param {(dismiss: DismissReason) => void} dismissWith
10844 */
10845 const setupTimer = (globalState, innerParams, dismissWith) => {
10846 const timerProgressBar = getTimerProgressBar();
10847 hide(timerProgressBar);
10848 if (innerParams.timer) {
10849 globalState.timeout = new Timer(() => {
10850 dismissWith('timer');
10851 delete globalState.timeout;
10852 }, innerParams.timer);
10853 if (innerParams.timerProgressBar && timerProgressBar) {
10854 show(timerProgressBar);
10855 applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
10856 setTimeout(() => {
10857 if (globalState.timeout && globalState.timeout.running) {
10858 // timer can be already stopped or unset at this point
10859 animateTimerProgressBar(/** @type {number} */innerParams.timer);
10860 }
10861 });
10862 }
10863 }
10864 };
10865
10866 /**
10867 * Initialize focus in the popup:
10868 *
10869 * 1. If `toast` is `true`, don't steal focus from the document.
10870 * 2. Else if there is an [autofocus] element, focus it.
10871 * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
10872 * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
10873 * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
10874 * 6. Else focus the first focusable element in a popup (if any).
10875 *
10876 * @param {DomCache} domCache
10877 * @param {SweetAlertOptions} innerParams
10878 */
10879 const initFocus = (domCache, innerParams) => {
10880 if (innerParams.toast) {
10881 return;
10882 }
10883 // TODO: this is dumb, remove `allowEnterKey` param in the next major version
10884 if (!callIfFunction(innerParams.allowEnterKey)) {
10885 warnAboutDeprecation('allowEnterKey');
10886 blurActiveElement();
10887 return;
10888 }
10889 if (focusAutofocus(domCache)) {
10890 return;
10891 }
10892 if (focusButton(domCache, innerParams)) {
10893 return;
10894 }
10895 setFocus(-1, 1);
10896 };
10897
10898 /**
10899 * @param {DomCache} domCache
10900 * @returns {boolean}
10901 */
10902 const focusAutofocus = domCache => {
10903 const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
10904 for (const autofocusElement of autofocusElements) {
10905 if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
10906 autofocusElement.focus();
10907 return true;
10908 }
10909 }
10910 return false;
10911 };
10912
10913 /**
10914 * @param {DomCache} domCache
10915 * @param {SweetAlertOptions} innerParams
10916 * @returns {boolean}
10917 */
10918 const focusButton = (domCache, innerParams) => {
10919 if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
10920 domCache.denyButton.focus();
10921 return true;
10922 }
10923 if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
10924 domCache.cancelButton.focus();
10925 return true;
10926 }
10927 if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
10928 domCache.confirmButton.focus();
10929 return true;
10930 }
10931 return false;
10932 };
10933 const blurActiveElement = () => {
10934 if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
10935 document.activeElement.blur();
10936 }
10937 };
10938
10939 // Assign instance methods from src/instanceMethods/*.js to prototype
10940 SweetAlert.prototype.disableButtons = disableButtons;
10941 SweetAlert.prototype.enableButtons = enableButtons;
10942 SweetAlert.prototype.getInput = getInput;
10943 SweetAlert.prototype.disableInput = disableInput;
10944 SweetAlert.prototype.enableInput = enableInput;
10945 SweetAlert.prototype.hideLoading = hideLoading;
10946 SweetAlert.prototype.disableLoading = hideLoading;
10947 SweetAlert.prototype.showValidationMessage = showValidationMessage;
10948 SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
10949 SweetAlert.prototype.close = close;
10950 SweetAlert.prototype.closePopup = close;
10951 SweetAlert.prototype.closeModal = close;
10952 SweetAlert.prototype.closeToast = close;
10953 SweetAlert.prototype.rejectPromise = rejectPromise;
10954 SweetAlert.prototype.update = update;
10955 SweetAlert.prototype._destroy = _destroy;
10956
10957 // Assign static methods from src/staticMethods/*.js to constructor
10958 Object.assign(SweetAlert, staticMethods);
10959
10960 // Proxy to instance methods to constructor, for now, for backwards compatibility
10961 Object.keys(instanceMethods).forEach(key => {
10962 /**
10963 * @param {...(SweetAlertOptions | string | undefined)} args
10964 * @returns {SweetAlertResult | Promise<SweetAlertResult> | undefined}
10965 */
10966 // @ts-ignore: Dynamic property assignment for backwards compatibility
10967 SweetAlert[key] = function (...args) {
10968 // @ts-ignore
10969 if (currentInstance && currentInstance[key]) {
10970 // @ts-ignore
10971 return currentInstance[key](...args);
10972 }
10973 return undefined;
10974 };
10975 });
10976 SweetAlert.DismissReason = DismissReason;
10977 SweetAlert.version = '11.26.17';
10978
10979 const Swal = SweetAlert;
10980 // @ts-ignore
10981 Swal.default = Swal;
10982
10983 return Swal;
10984
10985 }));
10986 if (typeof this !== 'undefined' && this.Sweetalert2){this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2}
10987 "undefined"!=typeof document&&function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch(e){n.innerText=t}}(document,":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.15s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-icon-animations: true;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start top top-end\" \"center-start center center-end\" \"bottom-start bottom-center bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem;container-name:swal2-popup}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}@container swal2-popup style(--swal2-icon-animations:true){.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}100%{transform:translate3d(0, 0, 0) scale(1);opacity:1}}@keyframes swal2-hide{0%{transform:translate3d(0, 0, 0) scale(1);opacity:1}100%{transform:translate3d(0, -50px, 0) scale(0.9);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");
10988
10989 /***/ },
10990
10991 /***/ "./node_modules/toastify-js/src/toastify.js"
10992 /*!**************************************************!*\
10993 !*** ./node_modules/toastify-js/src/toastify.js ***!
10994 \**************************************************/
10995 (module) {
10996
10997 /*!
10998 * Toastify js 1.12.0
10999 * https://github.com/apvarun/toastify-js
11000 * @license MIT licensed
11001 *
11002 * Copyright (C) 2018 Varun A P
11003 */
11004 (function(root, factory) {
11005 if ( true && module.exports) {
11006 module.exports = factory();
11007 } else {
11008 root.Toastify = factory();
11009 }
11010 })(this, function(global) {
11011 // Object initialization
11012 var Toastify = function(options) {
11013 // Returning a new init object
11014 return new Toastify.lib.init(options);
11015 },
11016 // Library version
11017 version = "1.12.0";
11018
11019 // Set the default global options
11020 Toastify.defaults = {
11021 oldestFirst: true,
11022 text: "Toastify is awesome!",
11023 node: undefined,
11024 duration: 3000,
11025 selector: undefined,
11026 callback: function () {
11027 },
11028 destination: undefined,
11029 newWindow: false,
11030 close: false,
11031 gravity: "toastify-top",
11032 positionLeft: false,
11033 position: '',
11034 backgroundColor: '',
11035 avatar: "",
11036 className: "",
11037 stopOnFocus: true,
11038 onClick: function () {
11039 },
11040 offset: {x: 0, y: 0},
11041 escapeMarkup: true,
11042 ariaLive: 'polite',
11043 style: {background: ''}
11044 };
11045
11046 // Defining the prototype of the object
11047 Toastify.lib = Toastify.prototype = {
11048 toastify: version,
11049
11050 constructor: Toastify,
11051
11052 // Initializing the object with required parameters
11053 init: function(options) {
11054 // Verifying and validating the input object
11055 if (!options) {
11056 options = {};
11057 }
11058
11059 // Creating the options object
11060 this.options = {};
11061
11062 this.toastElement = null;
11063
11064 // Validating the options
11065 this.options.text = options.text || Toastify.defaults.text; // Display message
11066 this.options.node = options.node || Toastify.defaults.node; // Display content as node
11067 this.options.duration = options.duration === 0 ? 0 : options.duration || Toastify.defaults.duration; // Display duration
11068 this.options.selector = options.selector || Toastify.defaults.selector; // Parent selector
11069 this.options.callback = options.callback || Toastify.defaults.callback; // Callback after display
11070 this.options.destination = options.destination || Toastify.defaults.destination; // On-click destination
11071 this.options.newWindow = options.newWindow || Toastify.defaults.newWindow; // Open destination in new window
11072 this.options.close = options.close || Toastify.defaults.close; // Show toast close icon
11073 this.options.gravity = options.gravity === "bottom" ? "toastify-bottom" : Toastify.defaults.gravity; // toast position - top or bottom
11074 this.options.positionLeft = options.positionLeft || Toastify.defaults.positionLeft; // toast position - left or right
11075 this.options.position = options.position || Toastify.defaults.position; // toast position - left or right
11076 this.options.backgroundColor = options.backgroundColor || Toastify.defaults.backgroundColor; // toast background color
11077 this.options.avatar = options.avatar || Toastify.defaults.avatar; // img element src - url or a path
11078 this.options.className = options.className || Toastify.defaults.className; // additional class names for the toast
11079 this.options.stopOnFocus = options.stopOnFocus === undefined ? Toastify.defaults.stopOnFocus : options.stopOnFocus; // stop timeout on focus
11080 this.options.onClick = options.onClick || Toastify.defaults.onClick; // Callback after click
11081 this.options.offset = options.offset || Toastify.defaults.offset; // toast offset
11082 this.options.escapeMarkup = options.escapeMarkup !== undefined ? options.escapeMarkup : Toastify.defaults.escapeMarkup;
11083 this.options.ariaLive = options.ariaLive || Toastify.defaults.ariaLive;
11084 this.options.style = options.style || Toastify.defaults.style;
11085 if(options.backgroundColor) {
11086 this.options.style.background = options.backgroundColor;
11087 }
11088
11089 // Returning the current object for chaining functions
11090 return this;
11091 },
11092
11093 // Building the DOM element
11094 buildToast: function() {
11095 // Validating if the options are defined
11096 if (!this.options) {
11097 throw "Toastify is not initialized";
11098 }
11099
11100 // Creating the DOM object
11101 var divElement = document.createElement("div");
11102 divElement.className = "toastify on " + this.options.className;
11103
11104 // Positioning toast to left or right or center
11105 if (!!this.options.position) {
11106 divElement.className += " toastify-" + this.options.position;
11107 } else {
11108 // To be depreciated in further versions
11109 if (this.options.positionLeft === true) {
11110 divElement.className += " toastify-left";
11111 console.warn('Property `positionLeft` will be depreciated in further versions. Please use `position` instead.')
11112 } else {
11113 // Default position
11114 divElement.className += " toastify-right";
11115 }
11116 }
11117
11118 // Assigning gravity of element
11119 divElement.className += " " + this.options.gravity;
11120
11121 if (this.options.backgroundColor) {
11122 // This is being deprecated in favor of using the style HTML DOM property
11123 console.warn('DEPRECATION NOTICE: "backgroundColor" is being deprecated. Please use the "style.background" property.');
11124 }
11125
11126 // Loop through our style object and apply styles to divElement
11127 for (var property in this.options.style) {
11128 divElement.style[property] = this.options.style[property];
11129 }
11130
11131 // Announce the toast to screen readers
11132 if (this.options.ariaLive) {
11133 divElement.setAttribute('aria-live', this.options.ariaLive)
11134 }
11135
11136 // Adding the toast message/node
11137 if (this.options.node && this.options.node.nodeType === Node.ELEMENT_NODE) {
11138 // If we have a valid node, we insert it
11139 divElement.appendChild(this.options.node)
11140 } else {
11141 if (this.options.escapeMarkup) {
11142 divElement.innerText = this.options.text;
11143 } else {
11144 divElement.innerHTML = this.options.text;
11145 }
11146
11147 if (this.options.avatar !== "") {
11148 var avatarElement = document.createElement("img");
11149 avatarElement.src = this.options.avatar;
11150
11151 avatarElement.className = "toastify-avatar";
11152
11153 if (this.options.position == "left" || this.options.positionLeft === true) {
11154 // Adding close icon on the left of content
11155 divElement.appendChild(avatarElement);
11156 } else {
11157 // Adding close icon on the right of content
11158 divElement.insertAdjacentElement("afterbegin", avatarElement);
11159 }
11160 }
11161 }
11162
11163 // Adding a close icon to the toast
11164 if (this.options.close === true) {
11165 // Create a span for close element
11166 var closeElement = document.createElement("button");
11167 closeElement.type = "button";
11168 closeElement.setAttribute("aria-label", "Close");
11169 closeElement.className = "toast-close";
11170 closeElement.innerHTML = "&#10006;";
11171
11172 // Triggering the removal of toast from DOM on close click
11173 closeElement.addEventListener(
11174 "click",
11175 function(event) {
11176 event.stopPropagation();
11177 this.removeElement(this.toastElement);
11178 window.clearTimeout(this.toastElement.timeOutValue);
11179 }.bind(this)
11180 );
11181
11182 //Calculating screen width
11183 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11184
11185 // Adding the close icon to the toast element
11186 // Display on the right if screen width is less than or equal to 360px
11187 if ((this.options.position == "left" || this.options.positionLeft === true) && width > 360) {
11188 // Adding close icon on the left of content
11189 divElement.insertAdjacentElement("afterbegin", closeElement);
11190 } else {
11191 // Adding close icon on the right of content
11192 divElement.appendChild(closeElement);
11193 }
11194 }
11195
11196 // Clear timeout while toast is focused
11197 if (this.options.stopOnFocus && this.options.duration > 0) {
11198 var self = this;
11199 // stop countdown
11200 divElement.addEventListener(
11201 "mouseover",
11202 function(event) {
11203 window.clearTimeout(divElement.timeOutValue);
11204 }
11205 )
11206 // add back the timeout
11207 divElement.addEventListener(
11208 "mouseleave",
11209 function() {
11210 divElement.timeOutValue = window.setTimeout(
11211 function() {
11212 // Remove the toast from DOM
11213 self.removeElement(divElement);
11214 },
11215 self.options.duration
11216 )
11217 }
11218 )
11219 }
11220
11221 // Adding an on-click destination path
11222 if (typeof this.options.destination !== "undefined") {
11223 divElement.addEventListener(
11224 "click",
11225 function(event) {
11226 event.stopPropagation();
11227 if (this.options.newWindow === true) {
11228 window.open(this.options.destination, "_blank");
11229 } else {
11230 window.location = this.options.destination;
11231 }
11232 }.bind(this)
11233 );
11234 }
11235
11236 if (typeof this.options.onClick === "function" && typeof this.options.destination === "undefined") {
11237 divElement.addEventListener(
11238 "click",
11239 function(event) {
11240 event.stopPropagation();
11241 this.options.onClick();
11242 }.bind(this)
11243 );
11244 }
11245
11246 // Adding offset
11247 if(typeof this.options.offset === "object") {
11248
11249 var x = getAxisOffsetAValue("x", this.options);
11250 var y = getAxisOffsetAValue("y", this.options);
11251
11252 var xOffset = this.options.position == "left" ? x : "-" + x;
11253 var yOffset = this.options.gravity == "toastify-top" ? y : "-" + y;
11254
11255 divElement.style.transform = "translate(" + xOffset + "," + yOffset + ")";
11256
11257 }
11258
11259 // Returning the generated element
11260 return divElement;
11261 },
11262
11263 // Displaying the toast
11264 showToast: function() {
11265 // Creating the DOM object for the toast
11266 this.toastElement = this.buildToast();
11267
11268 // Getting the root element to with the toast needs to be added
11269 var rootElement;
11270 if (typeof this.options.selector === "string") {
11271 rootElement = document.getElementById(this.options.selector);
11272 } else if (this.options.selector instanceof HTMLElement || (typeof ShadowRoot !== 'undefined' && this.options.selector instanceof ShadowRoot)) {
11273 rootElement = this.options.selector;
11274 } else {
11275 rootElement = document.body;
11276 }
11277
11278 // Validating if root element is present in DOM
11279 if (!rootElement) {
11280 throw "Root element is not defined";
11281 }
11282
11283 // Adding the DOM element
11284 var elementToInsert = Toastify.defaults.oldestFirst ? rootElement.firstChild : rootElement.lastChild;
11285 rootElement.insertBefore(this.toastElement, elementToInsert);
11286
11287 // Repositioning the toasts in case multiple toasts are present
11288 Toastify.reposition();
11289
11290 if (this.options.duration > 0) {
11291 this.toastElement.timeOutValue = window.setTimeout(
11292 function() {
11293 // Remove the toast from DOM
11294 this.removeElement(this.toastElement);
11295 }.bind(this),
11296 this.options.duration
11297 ); // Binding `this` for function invocation
11298 }
11299
11300 // Supporting function chaining
11301 return this;
11302 },
11303
11304 hideToast: function() {
11305 if (this.toastElement.timeOutValue) {
11306 clearTimeout(this.toastElement.timeOutValue);
11307 }
11308 this.removeElement(this.toastElement);
11309 },
11310
11311 // Removing the element from the DOM
11312 removeElement: function(toastElement) {
11313 // Hiding the element
11314 // toastElement.classList.remove("on");
11315 toastElement.className = toastElement.className.replace(" on", "");
11316
11317 // Removing the element from DOM after transition end
11318 window.setTimeout(
11319 function() {
11320 // remove options node if any
11321 if (this.options.node && this.options.node.parentNode) {
11322 this.options.node.parentNode.removeChild(this.options.node);
11323 }
11324
11325 // Remove the element from the DOM, only when the parent node was not removed before.
11326 if (toastElement.parentNode) {
11327 toastElement.parentNode.removeChild(toastElement);
11328 }
11329
11330 // Calling the callback function
11331 this.options.callback.call(toastElement);
11332
11333 // Repositioning the toasts again
11334 Toastify.reposition();
11335 }.bind(this),
11336 400
11337 ); // Binding `this` for function invocation
11338 },
11339 };
11340
11341 // Positioning the toasts on the DOM
11342 Toastify.reposition = function() {
11343
11344 // Top margins with gravity
11345 var topLeftOffsetSize = {
11346 top: 15,
11347 bottom: 15,
11348 };
11349 var topRightOffsetSize = {
11350 top: 15,
11351 bottom: 15,
11352 };
11353 var offsetSize = {
11354 top: 15,
11355 bottom: 15,
11356 };
11357
11358 // Get all toast messages on the DOM
11359 var allToasts = document.getElementsByClassName("toastify");
11360
11361 var classUsed;
11362
11363 // Modifying the position of each toast element
11364 for (var i = 0; i < allToasts.length; i++) {
11365 // Getting the applied gravity
11366 if (containsClass(allToasts[i], "toastify-top") === true) {
11367 classUsed = "toastify-top";
11368 } else {
11369 classUsed = "toastify-bottom";
11370 }
11371
11372 var height = allToasts[i].offsetHeight;
11373 classUsed = classUsed.substr(9, classUsed.length-1)
11374 // Spacing between toasts
11375 var offset = 15;
11376
11377 var width = window.innerWidth > 0 ? window.innerWidth : screen.width;
11378
11379 // Show toast in center if screen with less than or equal to 360px
11380 if (width <= 360) {
11381 // Setting the position
11382 allToasts[i].style[classUsed] = offsetSize[classUsed] + "px";
11383
11384 offsetSize[classUsed] += height + offset;
11385 } else {
11386 if (containsClass(allToasts[i], "toastify-left") === true) {
11387 // Setting the position
11388 allToasts[i].style[classUsed] = topLeftOffsetSize[classUsed] + "px";
11389
11390 topLeftOffsetSize[classUsed] += height + offset;
11391 } else {
11392 // Setting the position
11393 allToasts[i].style[classUsed] = topRightOffsetSize[classUsed] + "px";
11394
11395 topRightOffsetSize[classUsed] += height + offset;
11396 }
11397 }
11398 }
11399
11400 // Supporting function chaining
11401 return this;
11402 };
11403
11404 // Helper function to get offset.
11405 function getAxisOffsetAValue(axis, options) {
11406
11407 if(options.offset[axis]) {
11408 if(isNaN(options.offset[axis])) {
11409 return options.offset[axis];
11410 }
11411 else {
11412 return options.offset[axis] + 'px';
11413 }
11414 }
11415
11416 return '0px';
11417
11418 }
11419
11420 function containsClass(elem, yourClass) {
11421 if (!elem || typeof yourClass !== "string") {
11422 return false;
11423 } else if (
11424 elem.className &&
11425 elem.className
11426 .trim()
11427 .split(/\s+/gi)
11428 .indexOf(yourClass) > -1
11429 ) {
11430 return true;
11431 } else {
11432 return false;
11433 }
11434 }
11435
11436 // Setting up the prototype for the init object
11437 Toastify.lib.init.prototype = Toastify.lib;
11438
11439 // Returning the Toastify function to be assigned to the window object/module
11440 return Toastify;
11441 });
11442
11443
11444 /***/ },
11445
11446 /***/ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC"
11447 /*!**************************************************************************************************************************************************************************************************************************************************************!*\
11448 !*** data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC ***!
11449 \**************************************************************************************************************************************************************************************************************************************************************/
11450 (module) {
11451
11452 "use strict";
11453 module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC";
11454
11455 /***/ }
11456
11457 /******/ });
11458 /************************************************************************/
11459 /******/ // The module cache
11460 /******/ var __webpack_module_cache__ = {};
11461 /******/
11462 /******/ // The require function
11463 /******/ function __webpack_require__(moduleId) {
11464 /******/ // Check if module is in cache
11465 /******/ var cachedModule = __webpack_module_cache__[moduleId];
11466 /******/ if (cachedModule !== undefined) {
11467 /******/ return cachedModule.exports;
11468 /******/ }
11469 /******/ // Create a new module (and put it into the cache)
11470 /******/ var module = __webpack_module_cache__[moduleId] = {
11471 /******/ id: moduleId,
11472 /******/ // no module.loaded needed
11473 /******/ exports: {}
11474 /******/ };
11475 /******/
11476 /******/ // Execute the module function
11477 /******/ if (!(moduleId in __webpack_modules__)) {
11478 /******/ delete __webpack_module_cache__[moduleId];
11479 /******/ var e = new Error("Cannot find module '" + moduleId + "'");
11480 /******/ e.code = 'MODULE_NOT_FOUND';
11481 /******/ throw e;
11482 /******/ }
11483 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
11484 /******/
11485 /******/ // Return the exports of the module
11486 /******/ return module.exports;
11487 /******/ }
11488 /******/
11489 /******/ // expose the modules object (__webpack_modules__)
11490 /******/ __webpack_require__.m = __webpack_modules__;
11491 /******/
11492 /************************************************************************/
11493 /******/ /* webpack/runtime/compat get default export */
11494 /******/ (() => {
11495 /******/ // getDefaultExport function for compatibility with non-harmony modules
11496 /******/ __webpack_require__.n = (module) => {
11497 /******/ var getter = module && module.__esModule ?
11498 /******/ () => (module['default']) :
11499 /******/ () => (module);
11500 /******/ __webpack_require__.d(getter, { a: getter });
11501 /******/ return getter;
11502 /******/ };
11503 /******/ })();
11504 /******/
11505 /******/ /* webpack/runtime/define property getters */
11506 /******/ (() => {
11507 /******/ // define getter functions for harmony exports
11508 /******/ __webpack_require__.d = (exports, definition) => {
11509 /******/ for(var key in definition) {
11510 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
11511 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
11512 /******/ }
11513 /******/ }
11514 /******/ };
11515 /******/ })();
11516 /******/
11517 /******/ /* webpack/runtime/hasOwnProperty shorthand */
11518 /******/ (() => {
11519 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
11520 /******/ })();
11521 /******/
11522 /******/ /* webpack/runtime/make namespace object */
11523 /******/ (() => {
11524 /******/ // define __esModule on exports
11525 /******/ __webpack_require__.r = (exports) => {
11526 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
11527 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
11528 /******/ }
11529 /******/ Object.defineProperty(exports, '__esModule', { value: true });
11530 /******/ };
11531 /******/ })();
11532 /******/
11533 /******/ /* webpack/runtime/jsonp chunk loading */
11534 /******/ (() => {
11535 /******/ __webpack_require__.b = (typeof document !== 'undefined' && document.baseURI) || self.location.href;
11536 /******/
11537 /******/ // object to store loaded and loading chunks
11538 /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
11539 /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
11540 /******/ var installedChunks = {
11541 /******/ "./assets/js/dist/frontend/profile": 0
11542 /******/ };
11543 /******/
11544 /******/ // no chunk on demand loading
11545 /******/
11546 /******/ // no prefetching
11547 /******/
11548 /******/ // no preloaded
11549 /******/
11550 /******/ // no HMR
11551 /******/
11552 /******/ // no HMR manifest
11553 /******/
11554 /******/ // no on chunks loaded
11555 /******/
11556 /******/ // no jsonp function
11557 /******/ })();
11558 /******/
11559 /******/ /* webpack/runtime/nonce */
11560 /******/ (() => {
11561 /******/ __webpack_require__.nc = undefined;
11562 /******/ })();
11563 /******/
11564 /************************************************************************/
11565 var __webpack_exports__ = {};
11566 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
11567 (() => {
11568 "use strict";
11569 /*!*******************************************!*\
11570 !*** ./assets/src/js/frontend/profile.js ***!
11571 \*******************************************/
11572 __webpack_require__.r(__webpack_exports__);
11573 /* harmony import */ var _profile_course_tab__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./profile/course-tab */ "./assets/src/js/frontend/profile/course-tab.js");
11574 /* harmony import */ var _profile_statistic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./profile/statistic */ "./assets/src/js/frontend/profile/statistic.js");
11575 /* harmony import */ var _profile_order_recover__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./profile/order-recover */ "./assets/src/js/frontend/profile/order-recover.js");
11576 /* harmony import */ var _profile_cover_image__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./profile/cover-image */ "./assets/src/js/frontend/profile/cover-image.js");
11577 /* harmony import */ var _profile_avatar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./profile/avatar */ "./assets/src/js/frontend/profile/avatar.js");
11578 /* harmony import */ var _profile_quiz__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./profile/quiz */ "./assets/src/js/frontend/profile/quiz.js");
11579 /* harmony import */ var _profile_order_refund__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./profile/order-refund */ "./assets/src/js/frontend/profile/order-refund.js");
11580 /* 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");
11581
11582
11583
11584
11585
11586
11587
11588
11589 (0,_profile_cover_image__WEBPACK_IMPORTED_MODULE_3__["default"])();
11590 (0,_profile_quiz__WEBPACK_IMPORTED_MODULE_5__["default"])();
11591 (0,_profile_statistic__WEBPACK_IMPORTED_MODULE_1__["default"])();
11592 (0,_profile_order_recover__WEBPACK_IMPORTED_MODULE_2__["default"])();
11593 (0,_profile_order_refund__WEBPACK_IMPORTED_MODULE_6__["default"])();
11594 new _admin_courses_view_students_modal__WEBPACK_IMPORTED_MODULE_7__.ViewStudentsModal();
11595 document.addEventListener('DOMContentLoaded', function (event) {
11596 (0,_profile_course_tab__WEBPACK_IMPORTED_MODULE_0__["default"])();
11597 });
11598 if (document.getElementById('learnpress-avatar-upload')) {
11599 (0,_profile_avatar__WEBPACK_IMPORTED_MODULE_4__["default"])();
11600 }
11601 })();
11602
11603 /******/ })()
11604 ;
11605 //# sourceMappingURL=profile.js.map