{"ast":null,"code":"import { Injectable, ɵɵdefineInjectable, EventEmitter, isDevMode, Component, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, Input, HostBinding, Output, HostListener, NgModule } from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\nimport { __awaiter } from 'tslib';\nimport { CommonModule } from '@angular/common';\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/interfaces/cropper.settings.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\nimport * as ɵngcc0 from '@angular/core';\nimport * as ɵngcc1 from '@angular/platform-browser';\nimport * as ɵngcc2 from '@angular/common';\nconst _c0 = [\"wrapper\"];\nconst _c1 = [\"sourceImage\"];\nfunction ImageCropperComponent_img_2_Template(rf, ctx) {\n if (rf & 1) {\n const _r5 = ɵngcc0.ɵɵgetCurrentView();\n ɵngcc0.ɵɵelementStart(0, \"img\", 4, 5);\n ɵngcc0.ɵɵlistener(\"load\", function ImageCropperComponent_img_2_Template_img_load_0_listener() {\n ɵngcc0.ɵɵrestoreView(_r5);\n const ctx_r4 = ɵngcc0.ɵɵnextContext();\n return ɵngcc0.ɵɵresetView(ctx_r4.imageLoadedInView());\n });\n ɵngcc0.ɵɵelementEnd();\n }\n if (rf & 2) {\n const ctx_r1 = ɵngcc0.ɵɵnextContext();\n ɵngcc0.ɵɵstyleProp(\"visibility\", ctx_r1.imageVisible ? \"visible\" : \"hidden\")(\"transform\", ctx_r1.safeTransformStyle);\n ɵngcc0.ɵɵproperty(\"src\", ctx_r1.safeImgDataUrl, ɵngcc0.ɵɵsanitizeUrl);\n }\n}\nfunction ImageCropperComponent_div_4_ng_container_2_Template(rf, ctx) {\n if (rf & 1) {\n const _r8 = ɵngcc0.ɵɵgetCurrentView();\n ɵngcc0.ɵɵelementContainerStart(0);\n ɵngcc0.ɵɵelementStart(1, \"span\", 9);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_1_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r7 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r7.startMove($event, ctx_r7.moveTypes.Resize, \"topleft\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_1_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r9 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r9.startMove($event, ctx_r9.moveTypes.Resize, \"topleft\"));\n });\n ɵngcc0.ɵɵelement(2, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(3, \"span\", 11);\n ɵngcc0.ɵɵelement(4, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(5, \"span\", 12);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_5_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r10 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r10.startMove($event, ctx_r10.moveTypes.Resize, \"topright\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_5_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r11 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r11.startMove($event, ctx_r11.moveTypes.Resize, \"topright\"));\n });\n ɵngcc0.ɵɵelement(6, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(7, \"span\", 13);\n ɵngcc0.ɵɵelement(8, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(9, \"span\", 14);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_9_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r12 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r12.startMove($event, ctx_r12.moveTypes.Resize, \"bottomright\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_9_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r13 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r13.startMove($event, ctx_r13.moveTypes.Resize, \"bottomright\"));\n });\n ɵngcc0.ɵɵelement(10, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(11, \"span\", 15);\n ɵngcc0.ɵɵelement(12, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(13, \"span\", 16);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_13_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r14 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r14.startMove($event, ctx_r14.moveTypes.Resize, \"bottomleft\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_13_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r15 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r15.startMove($event, ctx_r15.moveTypes.Resize, \"bottomleft\"));\n });\n ɵngcc0.ɵɵelement(14, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(15, \"span\", 17);\n ɵngcc0.ɵɵelement(16, \"span\", 10);\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(17, \"span\", 18);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_17_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r16 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r16.startMove($event, ctx_r16.moveTypes.Resize, \"top\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_17_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r17 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r17.startMove($event, ctx_r17.moveTypes.Resize, \"top\"));\n });\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(18, \"span\", 19);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_18_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r18 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r18.startMove($event, ctx_r18.moveTypes.Resize, \"right\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_18_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r19 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r19.startMove($event, ctx_r19.moveTypes.Resize, \"right\"));\n });\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(19, \"span\", 20);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_19_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r20 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r20.startMove($event, ctx_r20.moveTypes.Resize, \"bottom\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_19_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r21 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r21.startMove($event, ctx_r21.moveTypes.Resize, \"bottom\"));\n });\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementStart(20, \"span\", 21);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_ng_container_2_Template_span_mousedown_20_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r22 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r22.startMove($event, ctx_r22.moveTypes.Resize, \"left\"));\n })(\"touchstart\", function ImageCropperComponent_div_4_ng_container_2_Template_span_touchstart_20_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r8);\n const ctx_r23 = ɵngcc0.ɵɵnextContext(2);\n return ɵngcc0.ɵɵresetView(ctx_r23.startMove($event, ctx_r23.moveTypes.Resize, \"left\"));\n });\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵelementContainerEnd();\n }\n}\nfunction ImageCropperComponent_div_4_Template(rf, ctx) {\n if (rf & 1) {\n const _r25 = ɵngcc0.ɵɵgetCurrentView();\n ɵngcc0.ɵɵelementStart(0, \"div\", 6);\n ɵngcc0.ɵɵlistener(\"keydown\", function ImageCropperComponent_div_4_Template_div_keydown_0_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r25);\n const ctx_r24 = ɵngcc0.ɵɵnextContext();\n return ɵngcc0.ɵɵresetView(ctx_r24.keyboardAccess($event));\n });\n ɵngcc0.ɵɵelementStart(1, \"div\", 7);\n ɵngcc0.ɵɵlistener(\"mousedown\", function ImageCropperComponent_div_4_Template_div_mousedown_1_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r25);\n const ctx_r26 = ɵngcc0.ɵɵnextContext();\n return ɵngcc0.ɵɵresetView(ctx_r26.startMove($event, ctx_r26.moveTypes.Move));\n })(\"touchstart\", function ImageCropperComponent_div_4_Template_div_touchstart_1_listener($event) {\n ɵngcc0.ɵɵrestoreView(_r25);\n const ctx_r27 = ɵngcc0.ɵɵnextContext();\n return ɵngcc0.ɵɵresetView(ctx_r27.startMove($event, ctx_r27.moveTypes.Move));\n });\n ɵngcc0.ɵɵelementEnd();\n ɵngcc0.ɵɵtemplate(2, ImageCropperComponent_div_4_ng_container_2_Template, 21, 0, \"ng-container\", 8);\n ɵngcc0.ɵɵelementEnd();\n }\n if (rf & 2) {\n const ctx_r2 = ɵngcc0.ɵɵnextContext();\n ɵngcc0.ɵɵstyleProp(\"top\", ctx_r2.cropper.y1, \"px\")(\"left\", ctx_r2.cropper.x1, \"px\")(\"width\", ctx_r2.cropper.x2 - ctx_r2.cropper.x1, \"px\")(\"height\", ctx_r2.cropper.y2 - ctx_r2.cropper.y1, \"px\")(\"margin-left\", ctx_r2.alignImage === \"center\" ? ctx_r2.marginLeft : null)(\"visibility\", ctx_r2.imageVisible ? \"visible\" : \"hidden\");\n ɵngcc0.ɵɵclassProp(\"ngx-ic-round\", ctx_r2.roundCropper);\n ɵngcc0.ɵɵadvance(2);\n ɵngcc0.ɵɵproperty(\"ngIf\", !ctx_r2.hideResizeSquares);\n }\n}\nclass CropperSettings {\n constructor() {\n // From options\n this.format = 'png';\n this.maintainAspectRatio = true;\n this.transform = {};\n this.aspectRatio = 1;\n this.resizeToWidth = 0;\n this.resizeToHeight = 0;\n this.cropperMinWidth = 0;\n this.cropperMinHeight = 0;\n this.cropperMaxHeight = 0;\n this.cropperMaxWidth = 0;\n this.cropperStaticWidth = 0;\n this.cropperStaticHeight = 0;\n this.canvasRotation = 0;\n this.initialStepSize = 3;\n this.roundCropper = false;\n this.onlyScaleDown = false;\n this.imageQuality = 92;\n this.autoCrop = true;\n this.backgroundColor = undefined;\n this.containWithinAspectRatio = false;\n this.hideResizeSquares = false;\n this.alignImage = 'center';\n // Internal\n this.cropperScaledMinWidth = 20;\n this.cropperScaledMinHeight = 20;\n this.cropperScaledMaxWidth = 20;\n this.cropperScaledMaxHeight = 20;\n this.stepSize = this.initialStepSize;\n }\n /**\n * @param {?} options\n * @return {?}\n */\n setOptions(options) {\n Object.keys(options).filter(\n /**\n * @param {?} k\n * @return {?}\n */\n k => k in this).forEach(\n /**\n * @param {?} k\n * @return {?}\n */\n k => this[k] = options[k]);\n this.validateOptions();\n }\n /**\n * @param {?} changes\n * @return {?}\n */\n setOptionsFromChanges(changes) {\n Object.keys(changes).filter(\n /**\n * @param {?} k\n * @return {?}\n */\n k => k in this).forEach(\n /**\n * @param {?} k\n * @return {?}\n */\n k => this[k] = changes[k].currentValue);\n this.validateOptions();\n }\n /**\n * @private\n * @return {?}\n */\n validateOptions() {\n if (this.maintainAspectRatio && !this.aspectRatio) {\n throw new Error('`aspectRatio` should > 0 when `maintainAspectRatio` is enabled');\n }\n }\n}\nif (false) {\n /** @type {?} */\n CropperSettings.prototype.format;\n /** @type {?} */\n CropperSettings.prototype.maintainAspectRatio;\n /** @type {?} */\n CropperSettings.prototype.transform;\n /** @type {?} */\n CropperSettings.prototype.aspectRatio;\n /** @type {?} */\n CropperSettings.prototype.resizeToWidth;\n /** @type {?} */\n CropperSettings.prototype.resizeToHeight;\n /** @type {?} */\n CropperSettings.prototype.cropperMinWidth;\n /** @type {?} */\n CropperSettings.prototype.cropperMinHeight;\n /** @type {?} */\n CropperSettings.prototype.cropperMaxHeight;\n /** @type {?} */\n CropperSettings.prototype.cropperMaxWidth;\n /** @type {?} */\n CropperSettings.prototype.cropperStaticWidth;\n /** @type {?} */\n CropperSettings.prototype.cropperStaticHeight;\n /** @type {?} */\n CropperSettings.prototype.canvasRotation;\n /** @type {?} */\n CropperSettings.prototype.initialStepSize;\n /** @type {?} */\n CropperSettings.prototype.roundCropper;\n /** @type {?} */\n CropperSettings.prototype.onlyScaleDown;\n /** @type {?} */\n CropperSettings.prototype.imageQuality;\n /** @type {?} */\n CropperSettings.prototype.autoCrop;\n /** @type {?} */\n CropperSettings.prototype.backgroundColor;\n /** @type {?} */\n CropperSettings.prototype.containWithinAspectRatio;\n /** @type {?} */\n CropperSettings.prototype.hideResizeSquares;\n /** @type {?} */\n CropperSettings.prototype.alignImage;\n /** @type {?} */\n CropperSettings.prototype.cropperScaledMinWidth;\n /** @type {?} */\n CropperSettings.prototype.cropperScaledMinHeight;\n /** @type {?} */\n CropperSettings.prototype.cropperScaledMaxWidth;\n /** @type {?} */\n CropperSettings.prototype.cropperScaledMaxHeight;\n /** @type {?} */\n CropperSettings.prototype.stepSize;\n}\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/interfaces/move-start.interface.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\n/**\n * @record\n */\nfunction MoveStart() {}\nif (false) {\n /** @type {?} */\n MoveStart.prototype.active;\n /** @type {?} */\n MoveStart.prototype.type;\n /** @type {?} */\n MoveStart.prototype.position;\n /** @type {?} */\n MoveStart.prototype.x1;\n /** @type {?} */\n MoveStart.prototype.y1;\n /** @type {?} */\n MoveStart.prototype.x2;\n /** @type {?} */\n MoveStart.prototype.y2;\n /** @type {?} */\n MoveStart.prototype.clientX;\n /** @type {?} */\n MoveStart.prototype.clientY;\n}\n/** @enum {string} */\nconst MoveTypes = {\n Move: \"move\",\n Resize: \"resize\",\n Pinch: \"pinch\"\n};\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/utils/resize.utils.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\n/*\n * Hermite resize - fast image resize/resample using Hermite filter.\n * https://github.com/viliusle/Hermite-resize\n */\n/**\n * @param {?} canvas\n * @param {?} width\n * @param {?} height\n * @return {?}\n */\nfunction resizeCanvas(canvas, width, height) {\n /** @type {?} */\n const width_source = canvas.width;\n /** @type {?} */\n const height_source = canvas.height;\n width = Math.round(width);\n height = Math.round(height);\n /** @type {?} */\n const ratio_w = width_source / width;\n /** @type {?} */\n const ratio_h = height_source / height;\n /** @type {?} */\n const ratio_w_half = Math.ceil(ratio_w / 2);\n /** @type {?} */\n const ratio_h_half = Math.ceil(ratio_h / 2);\n /** @type {?} */\n const ctx = canvas.getContext('2d');\n if (ctx) {\n /** @type {?} */\n const img = ctx.getImageData(0, 0, width_source, height_source);\n /** @type {?} */\n const img2 = ctx.createImageData(width, height);\n /** @type {?} */\n const data = img.data;\n /** @type {?} */\n const data2 = img2.data;\n for (let j = 0; j < height; j++) {\n for (let i = 0; i < width; i++) {\n /** @type {?} */\n const x2 = (i + j * width) * 4;\n /** @type {?} */\n const center_y = j * ratio_h;\n /** @type {?} */\n let weight = 0;\n /** @type {?} */\n let weights = 0;\n /** @type {?} */\n let weights_alpha = 0;\n /** @type {?} */\n let gx_r = 0;\n /** @type {?} */\n let gx_g = 0;\n /** @type {?} */\n let gx_b = 0;\n /** @type {?} */\n let gx_a = 0;\n /** @type {?} */\n const xx_start = Math.floor(i * ratio_w);\n /** @type {?} */\n const yy_start = Math.floor(j * ratio_h);\n /** @type {?} */\n let xx_stop = Math.ceil((i + 1) * ratio_w);\n /** @type {?} */\n let yy_stop = Math.ceil((j + 1) * ratio_h);\n xx_stop = Math.min(xx_stop, width_source);\n yy_stop = Math.min(yy_stop, height_source);\n for (let yy = yy_start; yy < yy_stop; yy++) {\n /** @type {?} */\n const dy = Math.abs(center_y - yy) / ratio_h_half;\n /** @type {?} */\n const center_x = i * ratio_w;\n /** @type {?} */\n const w0 = dy * dy;\n for (let xx = xx_start; xx < xx_stop; xx++) {\n /** @type {?} */\n const dx = Math.abs(center_x - xx) / ratio_w_half;\n /** @type {?} */\n const w = Math.sqrt(w0 + dx * dx);\n if (w >= 1) {\n //pixel too far\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n /** @type {?} */\n const pos_x = 4 * (xx + yy * width_source);\n //alpha\n gx_a += weight * data[pos_x + 3];\n weights_alpha += weight;\n //colors\n if (data[pos_x + 3] < 255) weight = weight * data[pos_x + 3] / 250;\n gx_r += weight * data[pos_x];\n gx_g += weight * data[pos_x + 1];\n gx_b += weight * data[pos_x + 2];\n weights += weight;\n }\n }\n data2[x2] = gx_r / weights;\n data2[x2 + 1] = gx_g / weights;\n data2[x2 + 2] = gx_b / weights;\n data2[x2 + 3] = gx_a / weights_alpha;\n }\n }\n canvas.width = width;\n canvas.height = height;\n //draw\n ctx.putImageData(img2, 0, 0);\n }\n}\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/services/crop.service.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\nclass CropService {\n /**\n * @param {?} sourceImage\n * @param {?} loadedImage\n * @param {?} cropper\n * @param {?} settings\n * @return {?}\n */\n crop(sourceImage, loadedImage, cropper, settings) {\n /** @type {?} */\n const imagePosition = this.getImagePosition(sourceImage, loadedImage, cropper, settings);\n /** @type {?} */\n const width = imagePosition.x2 - imagePosition.x1;\n /** @type {?} */\n const height = imagePosition.y2 - imagePosition.y1;\n /** @type {?} */\n const cropCanvas = /** @type {?} */document.createElement('canvas');\n cropCanvas.width = width;\n cropCanvas.height = height;\n /** @type {?} */\n const ctx = cropCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n if (settings.backgroundColor != null) {\n ctx.fillStyle = settings.backgroundColor;\n ctx.fillRect(0, 0, width, height);\n }\n /** @type {?} */\n const scaleX = (settings.transform.scale || 1) * (settings.transform.flipH ? -1 : 1);\n /** @type {?} */\n const scaleY = (settings.transform.scale || 1) * (settings.transform.flipV ? -1 : 1);\n /** @type {?} */\n const transformedImage = loadedImage.transformed;\n ctx.setTransform(scaleX, 0, 0, scaleY, transformedImage.size.width / 2, transformedImage.size.height / 2);\n ctx.translate(-imagePosition.x1 / scaleX, -imagePosition.y1 / scaleY);\n ctx.rotate((settings.transform.rotate || 0) * Math.PI / 180);\n ctx.drawImage(transformedImage.image, -transformedImage.size.width / 2, -transformedImage.size.height / 2);\n /** @type {?} */\n const output = {\n width,\n height,\n imagePosition,\n cropperPosition: Object.assign({}, cropper)\n };\n if (settings.containWithinAspectRatio) {\n output.offsetImagePosition = this.getOffsetImagePosition(sourceImage, loadedImage, cropper, settings);\n }\n /** @type {?} */\n const resizeRatio = this.getResizeRatio(width, height, settings);\n if (resizeRatio !== 1) {\n output.width = Math.round(width * resizeRatio);\n output.height = settings.maintainAspectRatio ? Math.round(output.width / settings.aspectRatio) : Math.round(height * resizeRatio);\n resizeCanvas(cropCanvas, output.width, output.height);\n }\n output.base64 = cropCanvas.toDataURL('image/' + settings.format, this.getQuality(settings));\n return output;\n }\n /**\n * @private\n * @param {?} sourceImage\n * @param {?} loadedImage\n * @param {?} cropper\n * @param {?} settings\n * @return {?}\n */\n getImagePosition(sourceImage, loadedImage, cropper, settings) {\n /** @type {?} */\n const sourceImageElement = sourceImage.nativeElement;\n /** @type {?} */\n const ratio = loadedImage.transformed.size.width / sourceImageElement.offsetWidth;\n /** @type {?} */\n const out = {\n x1: Math.round(cropper.x1 * ratio),\n y1: Math.round(cropper.y1 * ratio),\n x2: Math.round(cropper.x2 * ratio),\n y2: Math.round(cropper.y2 * ratio)\n };\n if (!settings.containWithinAspectRatio) {\n out.x1 = Math.max(out.x1, 0);\n out.y1 = Math.max(out.y1, 0);\n out.x2 = Math.min(out.x2, loadedImage.transformed.size.width);\n out.y2 = Math.min(out.y2, loadedImage.transformed.size.height);\n }\n return out;\n }\n /**\n * @private\n * @param {?} sourceImage\n * @param {?} loadedImage\n * @param {?} cropper\n * @param {?} settings\n * @return {?}\n */\n getOffsetImagePosition(sourceImage, loadedImage, cropper, settings) {\n /** @type {?} */\n const canvasRotation = settings.canvasRotation + loadedImage.exifTransform.rotate;\n /** @type {?} */\n const sourceImageElement = sourceImage.nativeElement;\n /** @type {?} */\n const ratio = loadedImage.transformed.size.width / sourceImageElement.offsetWidth;\n /** @type {?} */\n let offsetX;\n /** @type {?} */\n let offsetY;\n if (canvasRotation % 2) {\n offsetX = (loadedImage.transformed.size.width - loadedImage.original.size.height) / 2;\n offsetY = (loadedImage.transformed.size.height - loadedImage.original.size.width) / 2;\n } else {\n offsetX = (loadedImage.transformed.size.width - loadedImage.original.size.width) / 2;\n offsetY = (loadedImage.transformed.size.height - loadedImage.original.size.height) / 2;\n }\n /** @type {?} */\n const out = {\n x1: Math.round(cropper.x1 * ratio) - offsetX,\n y1: Math.round(cropper.y1 * ratio) - offsetY,\n x2: Math.round(cropper.x2 * ratio) - offsetX,\n y2: Math.round(cropper.y2 * ratio) - offsetY\n };\n if (!settings.containWithinAspectRatio) {\n out.x1 = Math.max(out.x1, 0);\n out.y1 = Math.max(out.y1, 0);\n out.x2 = Math.min(out.x2, loadedImage.transformed.size.width);\n out.y2 = Math.min(out.y2, loadedImage.transformed.size.height);\n }\n return out;\n }\n /**\n * @param {?} width\n * @param {?} height\n * @param {?} settings\n * @return {?}\n */\n getResizeRatio(width, height, settings) {\n /** @type {?} */\n const ratioWidth = settings.resizeToWidth / width;\n /** @type {?} */\n const ratioHeight = settings.resizeToHeight / height;\n /** @type {?} */\n const ratios = new Array();\n if (settings.resizeToWidth > 0) {\n ratios.push(ratioWidth);\n }\n if (settings.resizeToHeight > 0) {\n ratios.push(ratioHeight);\n }\n /** @type {?} */\n const result = ratios.length === 0 ? 1 : Math.min(...ratios);\n if (result > 1 && !settings.onlyScaleDown) {\n return result;\n }\n return Math.min(result, 1);\n }\n /**\n * @param {?} settings\n * @return {?}\n */\n getQuality(settings) {\n return Math.min(1, Math.max(0, settings.imageQuality / 100));\n }\n}\nCropService.ɵfac = function CropService_Factory(t) {\n return new (t || CropService)();\n};\n/** @nocollapse */\nCropService.ɵprov = ɵɵdefineInjectable({\n factory: function CropService_Factory() {\n return new CropService();\n },\n token: CropService,\n providedIn: \"root\"\n});\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(CropService, [{\n type: Injectable,\n args: [{\n providedIn: 'root'\n }]\n }], null, null);\n})();\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/services/cropper-position.service.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\nclass CropperPositionService {\n /**\n * @param {?} sourceImage\n * @param {?} cropperPosition\n * @param {?} settings\n * @return {?}\n */\n resetCropperPosition(sourceImage, cropperPosition, settings) {\n if (!(sourceImage === null || sourceImage === void 0 ? void 0 : sourceImage.nativeElement)) {\n return;\n }\n /** @type {?} */\n const sourceImageElement = sourceImage.nativeElement;\n if (settings.cropperStaticHeight && settings.cropperStaticWidth) {\n cropperPosition.x1 = 0;\n cropperPosition.x2 = sourceImageElement.offsetWidth > settings.cropperStaticWidth ? settings.cropperStaticWidth : sourceImageElement.offsetWidth;\n cropperPosition.y1 = 0;\n cropperPosition.y2 = sourceImageElement.offsetHeight > settings.cropperStaticHeight ? settings.cropperStaticHeight : sourceImageElement.offsetHeight;\n } else {\n /** @type {?} */\n const cropperWidth = Math.min(settings.cropperScaledMaxWidth, sourceImageElement.offsetWidth);\n /** @type {?} */\n const cropperHeight = Math.min(settings.cropperScaledMaxHeight, sourceImageElement.offsetHeight);\n if (!settings.maintainAspectRatio) {\n cropperPosition.x1 = 0;\n cropperPosition.x2 = cropperWidth;\n cropperPosition.y1 = 0;\n cropperPosition.y2 = cropperHeight;\n } else if (sourceImageElement.offsetWidth / settings.aspectRatio < sourceImageElement.offsetHeight) {\n cropperPosition.x1 = 0;\n cropperPosition.x2 = cropperWidth;\n /** @type {?} */\n const cropperHeightWithAspectRatio = cropperWidth / settings.aspectRatio;\n cropperPosition.y1 = (sourceImageElement.offsetHeight - cropperHeightWithAspectRatio) / 2;\n cropperPosition.y2 = cropperPosition.y1 + cropperHeightWithAspectRatio;\n } else {\n cropperPosition.y1 = 0;\n cropperPosition.y2 = cropperHeight;\n /** @type {?} */\n const cropperWidthWithAspectRatio = cropperHeight * settings.aspectRatio;\n cropperPosition.x1 = (sourceImageElement.offsetWidth - cropperWidthWithAspectRatio) / 2;\n cropperPosition.x2 = cropperPosition.x1 + cropperWidthWithAspectRatio;\n }\n }\n }\n /**\n * @param {?} event\n * @param {?} moveStart\n * @param {?} cropperPosition\n * @return {?}\n */\n move(event, moveStart, cropperPosition) {\n /** @type {?} */\n const diffX = this.getClientX(event) - moveStart.clientX;\n /** @type {?} */\n const diffY = this.getClientY(event) - moveStart.clientY;\n cropperPosition.x1 = moveStart.x1 + diffX;\n cropperPosition.y1 = moveStart.y1 + diffY;\n cropperPosition.x2 = moveStart.x2 + diffX;\n cropperPosition.y2 = moveStart.y2 + diffY;\n }\n /**\n * @param {?} event\n * @param {?} moveStart\n * @param {?} cropperPosition\n * @param {?} maxSize\n * @param {?} settings\n * @return {?}\n */\n resize(event, moveStart, cropperPosition, maxSize, settings) {\n /** @type {?} */\n const moveX = this.getClientX(event) - moveStart.clientX;\n /** @type {?} */\n const moveY = this.getClientY(event) - moveStart.clientY;\n switch (moveStart.position) {\n case 'left':\n cropperPosition.x1 = Math.min(Math.max(moveStart.x1 + moveX, cropperPosition.x2 - settings.cropperScaledMaxWidth), cropperPosition.x2 - settings.cropperScaledMinWidth);\n break;\n case 'topleft':\n cropperPosition.x1 = Math.min(Math.max(moveStart.x1 + moveX, cropperPosition.x2 - settings.cropperScaledMaxWidth), cropperPosition.x2 - settings.cropperScaledMinWidth);\n cropperPosition.y1 = Math.min(Math.max(moveStart.y1 + moveY, cropperPosition.y2 - settings.cropperScaledMaxHeight), cropperPosition.y2 - settings.cropperScaledMinHeight);\n break;\n case 'top':\n cropperPosition.y1 = Math.min(Math.max(moveStart.y1 + moveY, cropperPosition.y2 - settings.cropperScaledMaxHeight), cropperPosition.y2 - settings.cropperScaledMinHeight);\n break;\n case 'topright':\n cropperPosition.x2 = Math.max(Math.min(moveStart.x2 + moveX, cropperPosition.x1 + settings.cropperScaledMaxWidth), cropperPosition.x1 + settings.cropperScaledMinWidth);\n cropperPosition.y1 = Math.min(Math.max(moveStart.y1 + moveY, cropperPosition.y2 - settings.cropperScaledMaxHeight), cropperPosition.y2 - settings.cropperScaledMinHeight);\n break;\n case 'right':\n cropperPosition.x2 = Math.max(Math.min(moveStart.x2 + moveX, cropperPosition.x1 + settings.cropperScaledMaxWidth), cropperPosition.x1 + settings.cropperScaledMinWidth);\n break;\n case 'bottomright':\n cropperPosition.x2 = Math.max(Math.min(moveStart.x2 + moveX, cropperPosition.x1 + settings.cropperScaledMaxWidth), cropperPosition.x1 + settings.cropperScaledMinWidth);\n cropperPosition.y2 = Math.max(Math.min(moveStart.y2 + moveY, cropperPosition.y1 + settings.cropperScaledMaxHeight), cropperPosition.y1 + settings.cropperScaledMinHeight);\n break;\n case 'bottom':\n cropperPosition.y2 = Math.max(Math.min(moveStart.y2 + moveY, cropperPosition.y1 + settings.cropperScaledMaxHeight), cropperPosition.y1 + settings.cropperScaledMinHeight);\n break;\n case 'bottomleft':\n cropperPosition.x1 = Math.min(Math.max(moveStart.x1 + moveX, cropperPosition.x2 - settings.cropperScaledMaxWidth), cropperPosition.x2 - settings.cropperScaledMinWidth);\n cropperPosition.y2 = Math.max(Math.min(moveStart.y2 + moveY, cropperPosition.y1 + settings.cropperScaledMaxHeight), cropperPosition.y1 + settings.cropperScaledMinHeight);\n break;\n case 'center':\n /** @type {?} */\n const scale = event.scale;\n /** @type {?} */\n const newWidth = Math.min(Math.max(settings.cropperScaledMinWidth, Math.abs(moveStart.x2 - moveStart.x1) * scale), settings.cropperScaledMaxWidth);\n /** @type {?} */\n const newHeight = Math.min(Math.max(settings.cropperScaledMinHeight, Math.abs(moveStart.y2 - moveStart.y1) * scale), settings.cropperScaledMaxHeight);\n cropperPosition.x1 = moveStart.clientX - newWidth / 2;\n cropperPosition.x2 = moveStart.clientX + newWidth / 2;\n cropperPosition.y1 = moveStart.clientY - newHeight / 2;\n cropperPosition.y2 = moveStart.clientY + newHeight / 2;\n if (cropperPosition.x1 < 0) {\n cropperPosition.x2 -= cropperPosition.x1;\n cropperPosition.x1 = 0;\n } else if (cropperPosition.x2 > maxSize.width) {\n cropperPosition.x1 -= cropperPosition.x2 - maxSize.width;\n cropperPosition.x2 = maxSize.width;\n }\n if (cropperPosition.y1 < 0) {\n cropperPosition.y2 -= cropperPosition.y1;\n cropperPosition.y1 = 0;\n } else if (cropperPosition.y2 > maxSize.height) {\n cropperPosition.y1 -= cropperPosition.y2 - maxSize.height;\n cropperPosition.y2 = maxSize.height;\n }\n break;\n }\n if (settings.maintainAspectRatio) {\n this.checkAspectRatio(moveStart.position, cropperPosition, maxSize, settings);\n }\n }\n /**\n * @param {?} position\n * @param {?} cropperPosition\n * @param {?} maxSize\n * @param {?} settings\n * @return {?}\n */\n checkAspectRatio(position, cropperPosition, maxSize, settings) {\n /** @type {?} */\n let overflowX = 0;\n /** @type {?} */\n let overflowY = 0;\n switch (position) {\n case 'top':\n cropperPosition.x2 = cropperPosition.x1 + (cropperPosition.y2 - cropperPosition.y1) * settings.aspectRatio;\n overflowX = Math.max(cropperPosition.x2 - maxSize.width, 0);\n overflowY = Math.max(0 - cropperPosition.y1, 0);\n if (overflowX > 0 || overflowY > 0) {\n cropperPosition.x2 -= overflowY * settings.aspectRatio > overflowX ? overflowY * settings.aspectRatio : overflowX;\n cropperPosition.y1 += overflowY * settings.aspectRatio > overflowX ? overflowY : overflowX / settings.aspectRatio;\n }\n break;\n case 'bottom':\n cropperPosition.x2 = cropperPosition.x1 + (cropperPosition.y2 - cropperPosition.y1) * settings.aspectRatio;\n overflowX = Math.max(cropperPosition.x2 - maxSize.width, 0);\n overflowY = Math.max(cropperPosition.y2 - maxSize.height, 0);\n if (overflowX > 0 || overflowY > 0) {\n cropperPosition.x2 -= overflowY * settings.aspectRatio > overflowX ? overflowY * settings.aspectRatio : overflowX;\n cropperPosition.y2 -= overflowY * settings.aspectRatio > overflowX ? overflowY : overflowX / settings.aspectRatio;\n }\n break;\n case 'topleft':\n cropperPosition.y1 = cropperPosition.y2 - (cropperPosition.x2 - cropperPosition.x1) / settings.aspectRatio;\n overflowX = Math.max(0 - cropperPosition.x1, 0);\n overflowY = Math.max(0 - cropperPosition.y1, 0);\n if (overflowX > 0 || overflowY > 0) {\n cropperPosition.x1 += overflowY * settings.aspectRatio > overflowX ? overflowY * settings.aspectRatio : overflowX;\n cropperPosition.y1 += overflowY * settings.aspectRatio > overflowX ? overflowY : overflowX / settings.aspectRatio;\n }\n break;\n case 'topright':\n cropperPosition.y1 = cropperPosition.y2 - (cropperPosition.x2 - cropperPosition.x1) / settings.aspectRatio;\n overflowX = Math.max(cropperPosition.x2 - maxSize.width, 0);\n overflowY = Math.max(0 - cropperPosition.y1, 0);\n if (overflowX > 0 || overflowY > 0) {\n cropperPosition.x2 -= overflowY * settings.aspectRatio > overflowX ? overflowY * settings.aspectRatio : overflowX;\n cropperPosition.y1 += overflowY * settings.aspectRatio > overflowX ? overflowY : overflowX / settings.aspectRatio;\n }\n break;\n case 'right':\n case 'bottomright':\n cropperPosition.y2 = cropperPosition.y1 + (cropperPosition.x2 - cropperPosition.x1) / settings.aspectRatio;\n overflowX = Math.max(cropperPosition.x2 - maxSize.width, 0);\n overflowY = Math.max(cropperPosition.y2 - maxSize.height, 0);\n if (overflowX > 0 || overflowY > 0) {\n cropperPosition.x2 -= overflowY * settings.aspectRatio > overflowX ? overflowY * settings.aspectRatio : overflowX;\n cropperPosition.y2 -= overflowY * settings.aspectRatio > overflowX ? overflowY : overflowX / settings.aspectRatio;\n }\n break;\n case 'left':\n case 'bottomleft':\n cropperPosition.y2 = cropperPosition.y1 + (cropperPosition.x2 - cropperPosition.x1) / settings.aspectRatio;\n overflowX = Math.max(0 - cropperPosition.x1, 0);\n overflowY = Math.max(cropperPosition.y2 - maxSize.height, 0);\n if (overflowX > 0 || overflowY > 0) {\n cropperPosition.x1 += overflowY * settings.aspectRatio > overflowX ? overflowY * settings.aspectRatio : overflowX;\n cropperPosition.y2 -= overflowY * settings.aspectRatio > overflowX ? overflowY : overflowX / settings.aspectRatio;\n }\n break;\n case 'center':\n cropperPosition.x2 = cropperPosition.x1 + (cropperPosition.y2 - cropperPosition.y1) * settings.aspectRatio;\n cropperPosition.y2 = cropperPosition.y1 + (cropperPosition.x2 - cropperPosition.x1) / settings.aspectRatio;\n /** @type {?} */\n const overflowX1 = Math.max(0 - cropperPosition.x1, 0);\n /** @type {?} */\n const overflowX2 = Math.max(cropperPosition.x2 - maxSize.width, 0);\n /** @type {?} */\n const overflowY1 = Math.max(cropperPosition.y2 - maxSize.height, 0);\n /** @type {?} */\n const overflowY2 = Math.max(0 - cropperPosition.y1, 0);\n if (overflowX1 > 0 || overflowX2 > 0 || overflowY1 > 0 || overflowY2 > 0) {\n cropperPosition.x1 += overflowY1 * settings.aspectRatio > overflowX1 ? overflowY1 * settings.aspectRatio : overflowX1;\n cropperPosition.x2 -= overflowY2 * settings.aspectRatio > overflowX2 ? overflowY2 * settings.aspectRatio : overflowX2;\n cropperPosition.y1 += overflowY2 * settings.aspectRatio > overflowX2 ? overflowY2 : overflowX2 / settings.aspectRatio;\n cropperPosition.y2 -= overflowY1 * settings.aspectRatio > overflowX1 ? overflowY1 : overflowX1 / settings.aspectRatio;\n }\n break;\n }\n }\n /**\n * @param {?} event\n * @return {?}\n */\n getClientX(event) {\n var _a;\n return ((_a = event.touches) === null || _a === void 0 ? void 0 : _a[0].clientX) || event.clientX || 0;\n }\n /**\n * @param {?} event\n * @return {?}\n */\n getClientY(event) {\n var _a;\n return ((_a = event.touches) === null || _a === void 0 ? void 0 : _a[0].clientY) || event.clientY || 0;\n }\n}\nCropperPositionService.ɵfac = function CropperPositionService_Factory(t) {\n return new (t || CropperPositionService)();\n};\n/** @nocollapse */\nCropperPositionService.ɵprov = ɵɵdefineInjectable({\n factory: function CropperPositionService_Factory() {\n return new CropperPositionService();\n },\n token: CropperPositionService,\n providedIn: \"root\"\n});\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(CropperPositionService, [{\n type: Injectable,\n args: [{\n providedIn: 'root'\n }]\n }], null, null);\n})();\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/utils/exif.utils.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\n// Black 2x1 JPEG, with the following meta information set:\n// - EXIF Orientation: 6 (Rotated 90° CCW)\n// Source: https://github.com/blueimp/JavaScript-Load-Image\n/** @type {?} */\nconst testAutoOrientationImageURL = 'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' + 'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' + 'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' + 'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/x' + 'ABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAA' + 'AAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==';\n/**\n * @return {?}\n */\nfunction supportsAutomaticRotation() {\n return new Promise(\n /**\n * @param {?} resolve\n * @return {?}\n */\n resolve => {\n /** @type {?} */\n const img = new Image();\n img.onload =\n /**\n * @return {?}\n */\n () => {\n // Check if browser supports automatic image orientation:\n /** @type {?} */\n const supported = img.width === 1 && img.height === 2;\n resolve(supported);\n };\n img.src = testAutoOrientationImageURL;\n });\n}\n/**\n * @param {?} exifRotationOrBase64Image\n * @return {?}\n */\nfunction getTransformationsFromExifData(exifRotationOrBase64Image) {\n if (typeof exifRotationOrBase64Image === 'string') {\n exifRotationOrBase64Image = getExifRotation(exifRotationOrBase64Image);\n }\n switch (exifRotationOrBase64Image) {\n case 2:\n return {\n rotate: 0,\n flip: true\n };\n case 3:\n return {\n rotate: 2,\n flip: false\n };\n case 4:\n return {\n rotate: 2,\n flip: true\n };\n case 5:\n return {\n rotate: 1,\n flip: true\n };\n case 6:\n return {\n rotate: 1,\n flip: false\n };\n case 7:\n return {\n rotate: 3,\n flip: true\n };\n case 8:\n return {\n rotate: 3,\n flip: false\n };\n default:\n return {\n rotate: 0,\n flip: false\n };\n }\n}\n/**\n * @param {?} imageBase64\n * @return {?}\n */\nfunction getExifRotation(imageBase64) {\n /** @type {?} */\n const view = new DataView(base64ToArrayBuffer(imageBase64));\n if (view.getUint16(0, false) !== 0xFFD8) {\n return -2;\n }\n /** @type {?} */\n const length = view.byteLength;\n /** @type {?} */\n let offset = 2;\n while (offset < length) {\n if (view.getUint16(offset + 2, false) <= 8) return -1;\n /** @type {?} */\n const marker = view.getUint16(offset, false);\n offset += 2;\n if (marker == 0xFFE1) {\n if (view.getUint32(offset += 2, false) !== 0x45786966) {\n return -1;\n }\n /** @type {?} */\n const little = view.getUint16(offset += 6, false) == 0x4949;\n offset += view.getUint32(offset + 4, little);\n /** @type {?} */\n const tags = view.getUint16(offset, little);\n offset += 2;\n for (let i = 0; i < tags; i++) {\n if (view.getUint16(offset + i * 12, little) == 0x0112) {\n return view.getUint16(offset + i * 12 + 8, little);\n }\n }\n } else if ((marker & 0xFF00) !== 0xFF00) {\n break;\n } else {\n offset += view.getUint16(offset, false);\n }\n }\n return -1;\n}\n/**\n * @param {?} imageBase64\n * @return {?}\n */\nfunction base64ToArrayBuffer(imageBase64) {\n imageBase64 = imageBase64.replace(/^data\\:([^\\;]+)\\;base64,/gmi, '');\n /** @type {?} */\n const binaryString = atob(imageBase64);\n /** @type {?} */\n const len = binaryString.length;\n /** @type {?} */\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/services/load-image.service.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\n/**\n * @record\n */\nfunction LoadImageBase64() {}\nif (false) {\n /** @type {?} */\n LoadImageBase64.prototype.originalImage;\n /** @type {?} */\n LoadImageBase64.prototype.originalBase64;\n}\nclass LoadImageService {\n constructor() {\n this.autoRotateSupported = supportsAutomaticRotation();\n }\n /**\n * @param {?} file\n * @param {?} cropperSettings\n * @return {?}\n */\n loadImageFile(file, cropperSettings) {\n return new Promise(\n /**\n * @param {?} resolve\n * @param {?} reject\n * @return {?}\n */\n (resolve, reject) => {\n /** @type {?} */\n const fileReader = new FileReader();\n fileReader.onload =\n /**\n * @param {?} event\n * @return {?}\n */\n event => {\n this.loadImage(event.target.result, file.type, cropperSettings).then(resolve).catch(reject);\n };\n fileReader.readAsDataURL(file);\n });\n }\n /**\n * @private\n * @param {?} imageBase64\n * @param {?} imageType\n * @param {?} cropperSettings\n * @return {?}\n */\n loadImage(imageBase64, imageType, cropperSettings) {\n if (!this.isValidImageType(imageType)) {\n return Promise.reject(new Error('Invalid image type'));\n }\n return this.loadBase64Image(imageBase64, cropperSettings);\n }\n /**\n * @private\n * @param {?} type\n * @return {?}\n */\n isValidImageType(type) {\n return /image\\/(png|jpg|jpeg|bmp|gif|tiff|webp)/.test(type);\n }\n /**\n * @param {?} url\n * @param {?} cropperSettings\n * @return {?}\n */\n loadImageFromURL(url, cropperSettings) {\n return new Promise(\n /**\n * @param {?} resolve\n * @param {?} reject\n * @return {?}\n */\n (resolve, reject) => {\n /** @type {?} */\n const img = new Image();\n img.onerror =\n /**\n * @return {?}\n */\n () => reject;\n img.onload =\n /**\n * @return {?}\n */\n () => {\n /** @type {?} */\n const canvas = document.createElement('canvas');\n /** @type {?} */\n const context = canvas.getContext('2d');\n canvas.width = img.width;\n canvas.height = img.height;\n context.drawImage(img, 0, 0);\n this.loadBase64Image(canvas.toDataURL(), cropperSettings).then(resolve);\n };\n img.crossOrigin = 'anonymous';\n img.src = url;\n });\n }\n /**\n * @param {?} imageBase64\n * @param {?} cropperSettings\n * @return {?}\n */\n loadBase64Image(imageBase64, cropperSettings) {\n return new Promise(\n /**\n * @param {?} resolve\n * @param {?} reject\n * @return {?}\n */\n (resolve, reject) => {\n /** @type {?} */\n const originalImage = new Image();\n originalImage.onload =\n /**\n * @return {?}\n */\n () => resolve({\n originalImage,\n originalBase64: imageBase64\n });\n originalImage.onerror = reject;\n originalImage.src = imageBase64;\n }).then(\n /**\n * @param {?} res\n * @return {?}\n */\n res => this.transformImageBase64(res, cropperSettings));\n }\n /**\n * @private\n * @param {?} res\n * @param {?} cropperSettings\n * @return {?}\n */\n transformImageBase64(res, cropperSettings) {\n return __awaiter(this, void 0, void 0, function* () {\n /** @type {?} */\n const autoRotate = yield this.autoRotateSupported;\n /** @type {?} */\n const exifTransform = yield getTransformationsFromExifData(autoRotate ? -1 : res.originalBase64);\n if (!res.originalImage || !res.originalImage.complete) {\n return Promise.reject(new Error('No image loaded'));\n }\n /** @type {?} */\n const loadedImage = {\n original: {\n base64: res.originalBase64,\n image: res.originalImage,\n size: {\n width: res.originalImage.naturalWidth,\n height: res.originalImage.naturalHeight\n }\n },\n exifTransform\n };\n return this.transformLoadedImage(loadedImage, cropperSettings);\n });\n }\n /**\n * @param {?} loadedImage\n * @param {?} cropperSettings\n * @return {?}\n */\n transformLoadedImage(loadedImage, cropperSettings) {\n return __awaiter(this, void 0, void 0, function* () {\n /** @type {?} */\n const canvasRotation = cropperSettings.canvasRotation + loadedImage.exifTransform.rotate;\n /** @type {?} */\n const originalSize = {\n width: loadedImage.original.image.naturalWidth,\n height: loadedImage.original.image.naturalHeight\n };\n if (canvasRotation === 0 && !loadedImage.exifTransform.flip && !cropperSettings.containWithinAspectRatio) {\n return {\n original: {\n base64: loadedImage.original.base64,\n image: loadedImage.original.image,\n size: Object.assign({}, originalSize)\n },\n transformed: {\n base64: loadedImage.original.base64,\n image: loadedImage.original.image,\n size: Object.assign({}, originalSize)\n },\n exifTransform: loadedImage.exifTransform\n };\n }\n /** @type {?} */\n const transformedSize = this.getTransformedSize(originalSize, loadedImage.exifTransform, cropperSettings);\n /** @type {?} */\n const canvas = document.createElement('canvas');\n canvas.width = transformedSize.width;\n canvas.height = transformedSize.height;\n /** @type {?} */\n const ctx = canvas.getContext('2d');\n ctx.setTransform(loadedImage.exifTransform.flip ? -1 : 1, 0, 0, 1, canvas.width / 2, canvas.height / 2);\n ctx.rotate(Math.PI * (canvasRotation / 2));\n ctx.drawImage(loadedImage.original.image, -originalSize.width / 2, -originalSize.height / 2);\n /** @type {?} */\n const transformedBase64 = canvas.toDataURL();\n /** @type {?} */\n const transformedImage = yield this.loadImageFromBase64(transformedBase64);\n return {\n original: {\n base64: loadedImage.original.base64,\n image: loadedImage.original.image,\n size: Object.assign({}, originalSize)\n },\n transformed: {\n base64: transformedBase64,\n image: transformedImage,\n size: {\n width: transformedImage.width,\n height: transformedImage.height\n }\n },\n exifTransform: loadedImage.exifTransform\n };\n });\n }\n /**\n * @private\n * @param {?} imageBase64\n * @return {?}\n */\n loadImageFromBase64(imageBase64) {\n return new Promise(\n /**\n * @param {?} resolve\n * @param {?} reject\n * @return {?}\n */\n (resolve, reject) => {\n /** @type {?} */\n const image = new Image();\n image.onload =\n /**\n * @return {?}\n */\n () => resolve(image);\n image.onerror = reject;\n image.src = imageBase64;\n });\n }\n /**\n * @private\n * @param {?} originalSize\n * @param {?} exifTransform\n * @param {?} cropperSettings\n * @return {?}\n */\n getTransformedSize(originalSize, exifTransform, cropperSettings) {\n /** @type {?} */\n const canvasRotation = cropperSettings.canvasRotation + exifTransform.rotate;\n if (cropperSettings.containWithinAspectRatio) {\n if (canvasRotation % 2) {\n /** @type {?} */\n const minWidthToContain = originalSize.width * cropperSettings.aspectRatio;\n /** @type {?} */\n const minHeightToContain = originalSize.height / cropperSettings.aspectRatio;\n return {\n width: Math.max(originalSize.height, minWidthToContain),\n height: Math.max(originalSize.width, minHeightToContain)\n };\n } else {\n /** @type {?} */\n const minWidthToContain = originalSize.height * cropperSettings.aspectRatio;\n /** @type {?} */\n const minHeightToContain = originalSize.width / cropperSettings.aspectRatio;\n return {\n width: Math.max(originalSize.width, minWidthToContain),\n height: Math.max(originalSize.height, minHeightToContain)\n };\n }\n }\n if (canvasRotation % 2) {\n return {\n height: originalSize.width,\n width: originalSize.height\n };\n }\n return {\n width: originalSize.width,\n height: originalSize.height\n };\n }\n}\nLoadImageService.ɵfac = function LoadImageService_Factory(t) {\n return new (t || LoadImageService)();\n};\n/** @nocollapse */\nLoadImageService.ɵprov = ɵɵdefineInjectable({\n factory: function LoadImageService_Factory() {\n return new LoadImageService();\n },\n token: LoadImageService,\n providedIn: \"root\"\n});\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(LoadImageService, [{\n type: Injectable,\n args: [{\n providedIn: 'root'\n }]\n }], function () {\n return [];\n }, null);\n})();\nif (false) {\n /**\n * @type {?}\n * @private\n */\n LoadImageService.prototype.autoRotateSupported;\n}\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/utils/keyboard.utils.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\n/**\n * @param {?} key\n * @return {?}\n */\nfunction getPositionForKey(key) {\n switch (key) {\n case 'ArrowUp':\n return 'top';\n case 'ArrowRight':\n return 'right';\n case 'ArrowDown':\n return 'bottom';\n case 'ArrowLeft':\n default:\n return 'left';\n }\n}\n/**\n * @param {?} key\n * @return {?}\n */\nfunction getInvertedPositionForKey(key) {\n switch (key) {\n case 'ArrowUp':\n return 'bottom';\n case 'ArrowRight':\n return 'left';\n case 'ArrowDown':\n return 'top';\n case 'ArrowLeft':\n default:\n return 'right';\n }\n}\n/**\n * @param {?} key\n * @param {?} stepSize\n * @return {?}\n */\nfunction getEventForKey(key, stepSize) {\n switch (key) {\n case 'ArrowUp':\n return {\n clientX: 0,\n clientY: stepSize * -1\n };\n case 'ArrowRight':\n return {\n clientX: stepSize,\n clientY: 0\n };\n case 'ArrowDown':\n return {\n clientX: 0,\n clientY: stepSize\n };\n case 'ArrowLeft':\n default:\n return {\n clientX: stepSize * -1,\n clientY: 0\n };\n }\n}\n\n/**\n * @fileoverview added by tsickle\n * Generated from: lib/component/image-cropper.component.ts\n * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc\n */\nclass ImageCropperComponent {\n /**\n * @param {?} cropService\n * @param {?} cropperPositionService\n * @param {?} loadImageService\n * @param {?} sanitizer\n * @param {?} cd\n */\n constructor(cropService, cropperPositionService, loadImageService, sanitizer, cd) {\n this.cropService = cropService;\n this.cropperPositionService = cropperPositionService;\n this.loadImageService = loadImageService;\n this.sanitizer = sanitizer;\n this.cd = cd;\n this.Hammer = (window === null || window === void 0 ? void 0 : window['Hammer']) || null;\n this.settings = new CropperSettings();\n this.setImageMaxSizeRetries = 0;\n this.marginLeft = '0px';\n this.moveTypes = MoveTypes;\n this.imageVisible = false;\n this.format = this.settings.format;\n this.transform = {};\n this.maintainAspectRatio = this.settings.maintainAspectRatio;\n this.aspectRatio = this.settings.aspectRatio;\n this.resizeToWidth = this.settings.resizeToWidth;\n this.resizeToHeight = this.settings.resizeToHeight;\n this.cropperMinWidth = this.settings.cropperMinWidth;\n this.cropperMinHeight = this.settings.cropperMinHeight;\n this.cropperMaxHeight = this.settings.cropperMaxHeight;\n this.cropperMaxWidth = this.settings.cropperMaxWidth;\n this.cropperStaticWidth = this.settings.cropperStaticWidth;\n this.cropperStaticHeight = this.settings.cropperStaticHeight;\n this.canvasRotation = this.settings.canvasRotation;\n this.initialStepSize = this.settings.initialStepSize;\n this.roundCropper = this.settings.roundCropper;\n this.onlyScaleDown = this.settings.onlyScaleDown;\n this.imageQuality = this.settings.imageQuality;\n this.autoCrop = this.settings.autoCrop;\n this.backgroundColor = this.settings.backgroundColor;\n this.containWithinAspectRatio = this.settings.containWithinAspectRatio;\n this.hideResizeSquares = this.settings.hideResizeSquares;\n this.cropper = {\n x1: -100,\n y1: -100,\n x2: 10000,\n y2: 10000\n };\n this.alignImage = this.settings.alignImage;\n this.disabled = false;\n this.imageCropped = new EventEmitter();\n this.startCropImage = new EventEmitter();\n this.imageLoaded = new EventEmitter();\n this.cropperReady = new EventEmitter();\n this.loadImageFailed = new EventEmitter();\n this.reset();\n }\n /**\n * @param {?} changes\n * @return {?}\n */\n ngOnChanges(changes) {\n var _a;\n this.onChangesUpdateSettings(changes);\n this.onChangesInputImage(changes);\n if (((_a = this.loadedImage) === null || _a === void 0 ? void 0 : _a.original.image.complete) && (changes.containWithinAspectRatio || changes.canvasRotation)) {\n this.loadImageService.transformLoadedImage(this.loadedImage, this.settings).then(\n /**\n * @param {?} res\n * @return {?}\n */\n res => this.setLoadedImage(res)).catch(\n /**\n * @param {?} err\n * @return {?}\n */\n err => this.loadImageError(err));\n }\n if (changes.cropper || changes.maintainAspectRatio || changes.aspectRatio) {\n this.setMaxSize();\n this.setCropperScaledMinSize();\n this.setCropperScaledMaxSize();\n if (this.maintainAspectRatio && (changes.maintainAspectRatio || changes.aspectRatio)) {\n this.resetCropperPosition();\n } else if (changes.cropper) {\n this.checkCropperPosition(false);\n this.doAutoCrop();\n }\n this.cd.markForCheck();\n }\n if (changes.transform) {\n this.transform = this.transform || {};\n this.setCssTransform();\n this.doAutoCrop();\n }\n }\n /**\n * @private\n * @param {?} changes\n * @return {?}\n */\n onChangesUpdateSettings(changes) {\n this.settings.setOptionsFromChanges(changes);\n if (this.settings.cropperStaticHeight && this.settings.cropperStaticWidth) {\n this.settings.setOptions({\n hideResizeSquares: true,\n cropperMinWidth: this.settings.cropperStaticWidth,\n cropperMinHeight: this.settings.cropperStaticHeight,\n cropperMaxHeight: this.settings.cropperStaticHeight,\n cropperMaxWidth: this.settings.cropperStaticWidth,\n maintainAspectRatio: false\n });\n }\n }\n /**\n * @private\n * @param {?} changes\n * @return {?}\n */\n onChangesInputImage(changes) {\n if (changes.imageChangedEvent || changes.imageURL || changes.imageBase64 || changes.imageFile) {\n this.reset();\n }\n if (changes.imageChangedEvent && this.isValidImageChangedEvent()) {\n this.loadImageFile(this.imageChangedEvent.target.files[0]);\n }\n if (changes.imageURL && this.imageURL) {\n this.loadImageFromURL(this.imageURL);\n }\n if (changes.imageBase64 && this.imageBase64) {\n this.loadBase64Image(this.imageBase64);\n }\n if (changes.imageFile && this.imageFile) {\n this.loadImageFile(this.imageFile);\n }\n }\n /**\n * @private\n * @return {?}\n */\n isValidImageChangedEvent() {\n var _a, _b, _c;\n return ((_c = (_b = (_a = this.imageChangedEvent) === null || _a === void 0 ? void 0 : _a.target) === null || _b === void 0 ? void 0 : _b.files) === null || _c === void 0 ? void 0 : _c.length) > 0;\n }\n /**\n * @private\n * @return {?}\n */\n setCssTransform() {\n this.safeTransformStyle = this.sanitizer.bypassSecurityTrustStyle('scaleX(' + (this.transform.scale || 1) * (this.transform.flipH ? -1 : 1) + ')' + 'scaleY(' + (this.transform.scale || 1) * (this.transform.flipV ? -1 : 1) + ')' + 'rotate(' + (this.transform.rotate || 0) + 'deg)');\n }\n /**\n * @return {?}\n */\n ngOnInit() {\n this.settings.stepSize = this.initialStepSize;\n this.activatePinchGesture();\n }\n /**\n * @private\n * @return {?}\n */\n reset() {\n this.imageVisible = false;\n this.loadedImage = null;\n this.safeImgDataUrl = 'data:image/png;base64,iVBORw0KGg' + 'oAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAU' + 'AAarVyFEAAAAASUVORK5CYII=';\n this.moveStart = {\n active: false,\n type: null,\n position: null,\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0,\n clientX: 0,\n clientY: 0\n };\n this.maxSize = {\n width: 0,\n height: 0\n };\n this.cropper.x1 = -100;\n this.cropper.y1 = -100;\n this.cropper.x2 = 10000;\n this.cropper.y2 = 10000;\n }\n /**\n * @private\n * @param {?} file\n * @return {?}\n */\n loadImageFile(file) {\n this.loadImageService.loadImageFile(file, this.settings).then(\n /**\n * @param {?} res\n * @return {?}\n */\n res => this.setLoadedImage(res)).catch(\n /**\n * @param {?} err\n * @return {?}\n */\n err => this.loadImageError(err));\n }\n /**\n * @private\n * @param {?} imageBase64\n * @return {?}\n */\n loadBase64Image(imageBase64) {\n this.loadImageService.loadBase64Image(imageBase64, this.settings).then(\n /**\n * @param {?} res\n * @return {?}\n */\n res => this.setLoadedImage(res)).catch(\n /**\n * @param {?} err\n * @return {?}\n */\n err => this.loadImageError(err));\n }\n /**\n * @private\n * @param {?} url\n * @return {?}\n */\n loadImageFromURL(url) {\n this.loadImageService.loadImageFromURL(url, this.settings).then(\n /**\n * @param {?} res\n * @return {?}\n */\n res => this.setLoadedImage(res)).catch(\n /**\n * @param {?} err\n * @return {?}\n */\n err => this.loadImageError(err));\n }\n /**\n * @private\n * @param {?} loadedImage\n * @return {?}\n */\n setLoadedImage(loadedImage) {\n this.loadedImage = loadedImage;\n this.safeImgDataUrl = this.sanitizer.bypassSecurityTrustResourceUrl(loadedImage.transformed.base64);\n this.cd.markForCheck();\n }\n /**\n * @private\n * @param {?} error\n * @return {?}\n */\n loadImageError(error) {\n console.error(error);\n this.loadImageFailed.emit();\n }\n /**\n * @return {?}\n */\n imageLoadedInView() {\n if (this.loadedImage != null) {\n this.imageLoaded.emit(this.loadedImage);\n this.setImageMaxSizeRetries = 0;\n setTimeout(\n /**\n * @return {?}\n */\n () => this.checkImageMaxSizeRecursively());\n }\n }\n /**\n * @private\n * @return {?}\n */\n checkImageMaxSizeRecursively() {\n if (this.setImageMaxSizeRetries > 40) {\n this.loadImageFailed.emit();\n } else if (this.sourceImageLoaded()) {\n this.setMaxSize();\n this.setCropperScaledMinSize();\n this.setCropperScaledMaxSize();\n this.resetCropperPosition();\n this.cropperReady.emit(Object.assign({}, this.maxSize));\n this.cd.markForCheck();\n } else {\n this.setImageMaxSizeRetries++;\n setTimeout(\n /**\n * @return {?}\n */\n () => this.checkImageMaxSizeRecursively(), 50);\n }\n }\n /**\n * @private\n * @return {?}\n */\n sourceImageLoaded() {\n var _a, _b;\n return ((_b = (_a = this.sourceImage) === null || _a === void 0 ? void 0 : _a.nativeElement) === null || _b === void 0 ? void 0 : _b.offsetWidth) > 0;\n }\n /**\n * @return {?}\n */\n onResize() {\n if (!this.loadedImage) {\n return;\n }\n this.resizeCropperPosition();\n this.setMaxSize();\n this.setCropperScaledMinSize();\n this.setCropperScaledMaxSize();\n }\n /**\n * @private\n * @return {?}\n */\n activatePinchGesture() {\n if (this.Hammer) {\n /** @type {?} */\n const hammer = new this.Hammer(this.wrapper.nativeElement);\n hammer.get('pinch').set({\n enable: true\n });\n hammer.on('pinchmove', this.onPinch.bind(this));\n hammer.on('pinchend', this.pinchStop.bind(this));\n hammer.on('pinchstart', this.startPinch.bind(this));\n } else if (isDevMode()) {\n console.warn('[NgxImageCropper] Could not find HammerJS - Pinch Gesture won\\'t work');\n }\n }\n /**\n * @private\n * @return {?}\n */\n resizeCropperPosition() {\n /** @type {?} */\n const sourceImageElement = this.sourceImage.nativeElement;\n if (this.maxSize.width !== sourceImageElement.offsetWidth || this.maxSize.height !== sourceImageElement.offsetHeight) {\n this.cropper.x1 = this.cropper.x1 * sourceImageElement.offsetWidth / this.maxSize.width;\n this.cropper.x2 = this.cropper.x2 * sourceImageElement.offsetWidth / this.maxSize.width;\n this.cropper.y1 = this.cropper.y1 * sourceImageElement.offsetHeight / this.maxSize.height;\n this.cropper.y2 = this.cropper.y2 * sourceImageElement.offsetHeight / this.maxSize.height;\n }\n }\n /**\n * @return {?}\n */\n resetCropperPosition() {\n this.cropperPositionService.resetCropperPosition(this.sourceImage, this.cropper, this.settings);\n this.doAutoCrop();\n this.imageVisible = true;\n }\n /**\n * @param {?} event\n * @return {?}\n */\n keyboardAccess(event) {\n this.changeKeyboardStepSize(event);\n this.keyboardMoveCropper(event);\n }\n /**\n * @private\n * @param {?} event\n * @return {?}\n */\n changeKeyboardStepSize(event) {\n /** @type {?} */\n const key = +event.key;\n if (key >= 1 && key <= 9) {\n this.settings.stepSize = key;\n }\n }\n /**\n * @private\n * @param {?} event\n * @return {?}\n */\n keyboardMoveCropper(event) {\n /** @type {?} */\n const keyboardWhiteList = ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft'];\n if (!keyboardWhiteList.includes(event.key)) {\n return;\n }\n /** @type {?} */\n const moveType = event.shiftKey ? MoveTypes.Resize : MoveTypes.Move;\n /** @type {?} */\n const position = event.altKey ? getInvertedPositionForKey(event.key) : getPositionForKey(event.key);\n /** @type {?} */\n const moveEvent = getEventForKey(event.key, this.settings.stepSize);\n event.preventDefault();\n event.stopPropagation();\n this.startMove({\n clientX: 0,\n clientY: 0\n }, moveType, position);\n this.moveImg(moveEvent);\n this.moveStop();\n }\n /**\n * @param {?} event\n * @param {?} moveType\n * @param {?=} position\n * @return {?}\n */\n startMove(event, moveType, position = null) {\n var _a, _b;\n if (((_a = this.moveStart) === null || _a === void 0 ? void 0 : _a.active) && ((_b = this.moveStart) === null || _b === void 0 ? void 0 : _b.type) === MoveTypes.Pinch) {\n return;\n }\n if (event.preventDefault) {\n event.preventDefault();\n }\n this.moveStart = Object.assign({\n active: true,\n type: moveType,\n position,\n clientX: this.cropperPositionService.getClientX(event),\n clientY: this.cropperPositionService.getClientY(event)\n }, this.cropper);\n }\n /**\n * @param {?} event\n * @return {?}\n */\n startPinch(event) {\n if (!this.safeImgDataUrl) {\n return;\n }\n if (event.preventDefault) {\n event.preventDefault();\n }\n this.moveStart = Object.assign({\n active: true,\n type: MoveTypes.Pinch,\n position: 'center',\n clientX: this.cropper.x1 + (this.cropper.x2 - this.cropper.x1) / 2,\n clientY: this.cropper.y1 + (this.cropper.y2 - this.cropper.y1) / 2\n }, this.cropper);\n }\n /**\n * @param {?} event\n * @return {?}\n */\n moveImg(event) {\n if (this.moveStart.active) {\n if (event.stopPropagation) {\n event.stopPropagation();\n }\n if (event.preventDefault) {\n event.preventDefault();\n }\n if (this.moveStart.type === MoveTypes.Move) {\n this.cropperPositionService.move(event, this.moveStart, this.cropper);\n this.checkCropperPosition(true);\n } else if (this.moveStart.type === MoveTypes.Resize) {\n if (!this.cropperStaticWidth && !this.cropperStaticHeight) {\n this.cropperPositionService.resize(event, this.moveStart, this.cropper, this.maxSize, this.settings);\n }\n this.checkCropperPosition(false);\n }\n this.cd.detectChanges();\n }\n }\n /**\n * @param {?} event\n * @return {?}\n */\n onPinch(event) {\n if (this.moveStart.active) {\n if (event.stopPropagation) {\n event.stopPropagation();\n }\n if (event.preventDefault) {\n event.preventDefault();\n }\n if (this.moveStart.type === MoveTypes.Pinch) {\n this.cropperPositionService.resize(event, this.moveStart, this.cropper, this.maxSize, this.settings);\n this.checkCropperPosition(false);\n }\n this.cd.detectChanges();\n }\n }\n /**\n * @private\n * @return {?}\n */\n setMaxSize() {\n if (this.sourceImage) {\n /** @type {?} */\n const sourceImageElement = this.sourceImage.nativeElement;\n this.maxSize.width = sourceImageElement.offsetWidth;\n this.maxSize.height = sourceImageElement.offsetHeight;\n this.marginLeft = this.sanitizer.bypassSecurityTrustStyle('calc(50% - ' + this.maxSize.width / 2 + 'px)');\n }\n }\n /**\n * @private\n * @return {?}\n */\n setCropperScaledMinSize() {\n var _a, _b;\n if ((_b = (_a = this.loadedImage) === null || _a === void 0 ? void 0 : _a.transformed) === null || _b === void 0 ? void 0 : _b.image) {\n this.setCropperScaledMinWidth();\n this.setCropperScaledMinHeight();\n } else {\n this.settings.cropperScaledMinWidth = 20;\n this.settings.cropperScaledMinHeight = 20;\n }\n }\n /**\n * @private\n * @return {?}\n */\n setCropperScaledMinWidth() {\n this.settings.cropperScaledMinWidth = this.cropperMinWidth > 0 ? Math.max(20, this.cropperMinWidth / this.loadedImage.transformed.image.width * this.maxSize.width) : 20;\n }\n /**\n * @private\n * @return {?}\n */\n setCropperScaledMinHeight() {\n if (this.maintainAspectRatio) {\n this.settings.cropperScaledMinHeight = Math.max(20, this.settings.cropperScaledMinWidth / this.aspectRatio);\n } else if (this.cropperMinHeight > 0) {\n this.settings.cropperScaledMinHeight = Math.max(20, this.cropperMinHeight / this.loadedImage.transformed.image.height * this.maxSize.height);\n } else {\n this.settings.cropperScaledMinHeight = 20;\n }\n }\n /**\n * @private\n * @return {?}\n */\n setCropperScaledMaxSize() {\n var _a, _b;\n if ((_b = (_a = this.loadedImage) === null || _a === void 0 ? void 0 : _a.transformed) === null || _b === void 0 ? void 0 : _b.image) {\n /** @type {?} */\n const ratio = this.loadedImage.transformed.size.width / this.maxSize.width;\n this.settings.cropperScaledMaxWidth = this.cropperMaxWidth > 20 ? this.cropperMaxWidth / ratio : this.maxSize.width;\n this.settings.cropperScaledMaxHeight = this.cropperMaxHeight > 20 ? this.cropperMaxHeight / ratio : this.maxSize.height;\n if (this.maintainAspectRatio) {\n if (this.settings.cropperScaledMaxWidth > this.settings.cropperScaledMaxHeight * this.aspectRatio) {\n this.settings.cropperScaledMaxWidth = this.settings.cropperScaledMaxHeight * this.aspectRatio;\n } else if (this.settings.cropperScaledMaxWidth < this.settings.cropperScaledMaxHeight * this.aspectRatio) {\n this.settings.cropperScaledMaxHeight = this.settings.cropperScaledMaxWidth / this.aspectRatio;\n }\n }\n } else {\n this.settings.cropperScaledMaxWidth = this.maxSize.width;\n this.settings.cropperScaledMaxHeight = this.maxSize.height;\n }\n }\n /**\n * @private\n * @param {?=} maintainSize\n * @return {?}\n */\n checkCropperPosition(maintainSize = false) {\n if (this.cropper.x1 < 0) {\n this.cropper.x2 -= maintainSize ? this.cropper.x1 : 0;\n this.cropper.x1 = 0;\n }\n if (this.cropper.y1 < 0) {\n this.cropper.y2 -= maintainSize ? this.cropper.y1 : 0;\n this.cropper.y1 = 0;\n }\n if (this.cropper.x2 > this.maxSize.width) {\n this.cropper.x1 -= maintainSize ? this.cropper.x2 - this.maxSize.width : 0;\n this.cropper.x2 = this.maxSize.width;\n }\n if (this.cropper.y2 > this.maxSize.height) {\n this.cropper.y1 -= maintainSize ? this.cropper.y2 - this.maxSize.height : 0;\n this.cropper.y2 = this.maxSize.height;\n }\n }\n /**\n * @return {?}\n */\n moveStop() {\n if (this.moveStart.active) {\n this.moveStart.active = false;\n this.doAutoCrop();\n }\n }\n /**\n * @return {?}\n */\n pinchStop() {\n if (this.moveStart.active) {\n this.moveStart.active = false;\n this.doAutoCrop();\n }\n }\n /**\n * @private\n * @return {?}\n */\n doAutoCrop() {\n if (this.autoCrop) {\n this.crop();\n }\n }\n /**\n * @return {?}\n */\n crop() {\n var _a, _b;\n if (((_b = (_a = this.loadedImage) === null || _a === void 0 ? void 0 : _a.transformed) === null || _b === void 0 ? void 0 : _b.image) != null) {\n this.startCropImage.emit();\n /** @type {?} */\n const output = this.cropService.crop(this.sourceImage, this.loadedImage, this.cropper, this.settings);\n if (output != null) {\n this.imageCropped.emit(output);\n }\n return output;\n }\n return null;\n }\n}\nImageCropperComponent.ɵfac = function ImageCropperComponent_Factory(t) {\n return new (t || ImageCropperComponent)(ɵngcc0.ɵɵdirectiveInject(CropService), ɵngcc0.ɵɵdirectiveInject(CropperPositionService), ɵngcc0.ɵɵdirectiveInject(LoadImageService), ɵngcc0.ɵɵdirectiveInject(ɵngcc1.DomSanitizer), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ChangeDetectorRef));\n};\nImageCropperComponent.ɵcmp = /*@__PURE__*/ɵngcc0.ɵɵdefineComponent({\n type: ImageCropperComponent,\n selectors: [[\"image-cropper\"]],\n viewQuery: function ImageCropperComponent_Query(rf, ctx) {\n if (rf & 1) {\n ɵngcc0.ɵɵviewQuery(_c0, 7);\n ɵngcc0.ɵɵviewQuery(_c1, 5);\n }\n if (rf & 2) {\n let _t;\n ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx.wrapper = _t.first);\n ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx.sourceImage = _t.first);\n }\n },\n hostVars: 4,\n hostBindings: function ImageCropperComponent_HostBindings(rf, ctx) {\n if (rf & 1) {\n ɵngcc0.ɵɵlistener(\"resize\", function ImageCropperComponent_resize_HostBindingHandler() {\n return ctx.onResize();\n }, false, ɵngcc0.ɵɵresolveWindow)(\"mousemove\", function ImageCropperComponent_mousemove_HostBindingHandler($event) {\n return ctx.moveImg($event);\n }, false, ɵngcc0.ɵɵresolveDocument)(\"touchmove\", function ImageCropperComponent_touchmove_HostBindingHandler($event) {\n return ctx.moveImg($event);\n }, false, ɵngcc0.ɵɵresolveDocument)(\"mouseup\", function ImageCropperComponent_mouseup_HostBindingHandler() {\n return ctx.moveStop();\n }, false, ɵngcc0.ɵɵresolveDocument)(\"touchend\", function ImageCropperComponent_touchend_HostBindingHandler() {\n return ctx.moveStop();\n }, false, ɵngcc0.ɵɵresolveDocument);\n }\n if (rf & 2) {\n ɵngcc0.ɵɵstyleProp(\"text-align\", ctx.alignImage);\n ɵngcc0.ɵɵclassProp(\"disabled\", ctx.disabled);\n }\n },\n inputs: {\n format: \"format\",\n transform: \"transform\",\n maintainAspectRatio: \"maintainAspectRatio\",\n aspectRatio: \"aspectRatio\",\n resizeToWidth: \"resizeToWidth\",\n resizeToHeight: \"resizeToHeight\",\n cropperMinWidth: \"cropperMinWidth\",\n cropperMinHeight: \"cropperMinHeight\",\n cropperMaxHeight: \"cropperMaxHeight\",\n cropperMaxWidth: \"cropperMaxWidth\",\n cropperStaticWidth: \"cropperStaticWidth\",\n cropperStaticHeight: \"cropperStaticHeight\",\n canvasRotation: \"canvasRotation\",\n initialStepSize: \"initialStepSize\",\n roundCropper: \"roundCropper\",\n onlyScaleDown: \"onlyScaleDown\",\n imageQuality: \"imageQuality\",\n autoCrop: \"autoCrop\",\n backgroundColor: \"backgroundColor\",\n containWithinAspectRatio: \"containWithinAspectRatio\",\n hideResizeSquares: \"hideResizeSquares\",\n cropper: \"cropper\",\n alignImage: \"alignImage\",\n disabled: \"disabled\",\n imageChangedEvent: \"imageChangedEvent\",\n imageURL: \"imageURL\",\n imageBase64: \"imageBase64\",\n imageFile: \"imageFile\"\n },\n outputs: {\n imageCropped: \"imageCropped\",\n startCropImage: \"startCropImage\",\n imageLoaded: \"imageLoaded\",\n cropperReady: \"cropperReady\",\n loadImageFailed: \"loadImageFailed\"\n },\n features: [ɵngcc0.ɵɵNgOnChangesFeature],\n decls: 5,\n vars: 10,\n consts: [[\"wrapper\", \"\"], [\"class\", \"ngx-ic-source-image\", 3, \"src\", \"visibility\", \"transform\", \"load\", 4, \"ngIf\"], [1, \"ngx-ic-overlay\"], [\"class\", \"ngx-ic-cropper\", \"tabindex\", \"0\", 3, \"ngx-ic-round\", \"top\", \"left\", \"width\", \"height\", \"margin-left\", \"visibility\", \"keydown\", 4, \"ngIf\"], [1, \"ngx-ic-source-image\", 3, \"src\", \"load\"], [\"sourceImage\", \"\"], [\"tabindex\", \"0\", 1, \"ngx-ic-cropper\", 3, \"keydown\"], [1, \"ngx-ic-move\", 3, \"mousedown\", \"touchstart\"], [4, \"ngIf\"], [1, \"ngx-ic-resize\", \"ngx-ic-topleft\", 3, \"mousedown\", \"touchstart\"], [1, \"ngx-ic-square\"], [1, \"ngx-ic-resize\", \"ngx-ic-top\"], [1, \"ngx-ic-resize\", \"ngx-ic-topright\", 3, \"mousedown\", \"touchstart\"], [1, \"ngx-ic-resize\", \"ngx-ic-right\"], [1, \"ngx-ic-resize\", \"ngx-ic-bottomright\", 3, \"mousedown\", \"touchstart\"], [1, \"ngx-ic-resize\", \"ngx-ic-bottom\"], [1, \"ngx-ic-resize\", \"ngx-ic-bottomleft\", 3, \"mousedown\", \"touchstart\"], [1, \"ngx-ic-resize\", \"ngx-ic-left\"], [1, \"ngx-ic-resize-bar\", \"ngx-ic-top\", 3, \"mousedown\", \"touchstart\"], [1, \"ngx-ic-resize-bar\", \"ngx-ic-right\", 3, \"mousedown\", \"touchstart\"], [1, \"ngx-ic-resize-bar\", \"ngx-ic-bottom\", 3, \"mousedown\", \"touchstart\"], [1, \"ngx-ic-resize-bar\", \"ngx-ic-left\", 3, \"mousedown\", \"touchstart\"]],\n template: function ImageCropperComponent_Template(rf, ctx) {\n if (rf & 1) {\n ɵngcc0.ɵɵelementStart(0, \"div\", null, 0);\n ɵngcc0.ɵɵtemplate(2, ImageCropperComponent_img_2_Template, 2, 5, \"img\", 1);\n ɵngcc0.ɵɵelement(3, \"div\", 2);\n ɵngcc0.ɵɵtemplate(4, ImageCropperComponent_div_4_Template, 3, 15, \"div\", 3);\n ɵngcc0.ɵɵelementEnd();\n }\n if (rf & 2) {\n ɵngcc0.ɵɵstyleProp(\"background\", ctx.imageVisible && ctx.backgroundColor);\n ɵngcc0.ɵɵadvance(2);\n ɵngcc0.ɵɵproperty(\"ngIf\", ctx.safeImgDataUrl);\n ɵngcc0.ɵɵadvance(1);\n ɵngcc0.ɵɵstyleProp(\"width\", ctx.maxSize.width, \"px\")(\"height\", ctx.maxSize.height, \"px\")(\"margin-left\", ctx.alignImage === \"center\" ? ctx.marginLeft : null);\n ɵngcc0.ɵɵadvance(1);\n ɵngcc0.ɵɵproperty(\"ngIf\", ctx.imageVisible);\n }\n },\n dependencies: [ɵngcc2.NgIf],\n styles: [\"[_nghost-%COMP%]{display:flex;max-height:100%;max-width:100%;overflow:hidden;padding:5px;text-align:center}[_nghost-%COMP%], [_nghost-%COMP%] > div[_ngcontent-%COMP%]{position:relative;width:100%}[_nghost-%COMP%] > div[_ngcontent-%COMP%] img.ngx-ic-source-image[_ngcontent-%COMP%]{max-height:100%;max-width:100%;transform-origin:center}[_nghost-%COMP%] .ngx-ic-overlay[_ngcontent-%COMP%]{left:0;outline:var(--cropper-overlay-color,#fff) solid 100vw;pointer-events:none;position:absolute;top:0;touch-action:none}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%]{background:transparent;color:#53535c;display:flex;outline:100vw solid hsla(0,0%,100%,.3);outline:var(--cropper-outline-color,hsla(0,0%,100%,.3)) solid 100vw;position:absolute;touch-action:none}@media (orientation:portrait){[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%]{outline-width:100vh}}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%]:after{border:1px dashed;bottom:0;color:inherit;content:\\\"\\\";left:0;opacity:.75;pointer-events:none;position:absolute;right:0;top:0;z-index:1}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-move[_ngcontent-%COMP%]{border:1px solid hsla(0,0%,100%,.5);cursor:move;width:100%}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%]:focus .ngx-ic-move[_ngcontent-%COMP%]{border-color:#1e90ff;border-width:2px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize[_ngcontent-%COMP%]{display:inline-block;line-height:6px;opacity:.85;padding:8px;position:absolute;z-index:1}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize[_ngcontent-%COMP%] .ngx-ic-square[_ngcontent-%COMP%]{background:#53535c;border:1px solid hsla(0,0%,100%,.5);box-sizing:content-box;display:inline-block;height:6px;width:6px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-topleft[_ngcontent-%COMP%]{cursor:nwse-resize;left:-12px;top:-12px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-top[_ngcontent-%COMP%]{cursor:ns-resize;left:calc(50% - 12px);top:-12px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-topright[_ngcontent-%COMP%]{cursor:nesw-resize;right:-12px;top:-12px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-right[_ngcontent-%COMP%]{cursor:ew-resize;right:-12px;top:calc(50% - 12px)}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-bottomright[_ngcontent-%COMP%]{bottom:-12px;cursor:nwse-resize;right:-12px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-bottom[_ngcontent-%COMP%]{bottom:-12px;cursor:ns-resize;left:calc(50% - 12px)}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-bottomleft[_ngcontent-%COMP%]{bottom:-12px;cursor:nesw-resize;left:-12px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize.ngx-ic-left[_ngcontent-%COMP%]{cursor:ew-resize;left:-12px;top:calc(50% - 12px)}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize-bar[_ngcontent-%COMP%]{position:absolute;z-index:1}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize-bar.ngx-ic-top[_ngcontent-%COMP%]{cursor:ns-resize;height:22px;left:11px;top:-11px;width:calc(100% - 22px)}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize-bar.ngx-ic-right[_ngcontent-%COMP%]{cursor:ew-resize;height:calc(100% - 22px);right:-11px;top:11px;width:22px}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize-bar.ngx-ic-bottom[_ngcontent-%COMP%]{bottom:-11px;cursor:ns-resize;height:22px;left:11px;width:calc(100% - 22px)}[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize-bar.ngx-ic-left[_ngcontent-%COMP%]{cursor:ew-resize;height:calc(100% - 22px);left:-11px;top:11px;width:22px}[_nghost-%COMP%] .ngx-ic-cropper.ngx-ic-round[_ngcontent-%COMP%]{outline-color:transparent}[_nghost-%COMP%] .ngx-ic-cropper.ngx-ic-round[_ngcontent-%COMP%]:after{border-radius:100%;box-shadow:0 0 0 100vw hsla(0,0%,100%,.3);box-shadow:0 0 0 100vw var(--cropper-outline-color,hsla(0,0%,100%,.3))}@media (orientation:portrait){[_nghost-%COMP%] .ngx-ic-cropper.ngx-ic-round[_ngcontent-%COMP%]:after{box-shadow:0 0 0 100vh hsla(0,0%,100%,.3);box-shadow:0 0 0 100vh var(--cropper-outline-color,hsla(0,0%,100%,.3))}}[_nghost-%COMP%] .ngx-ic-cropper.ngx-ic-round[_ngcontent-%COMP%] .ngx-ic-move[_ngcontent-%COMP%]{border-radius:100%}.disabled[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-move[_ngcontent-%COMP%], .disabled[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize[_ngcontent-%COMP%], .disabled[_nghost-%COMP%] .ngx-ic-cropper[_ngcontent-%COMP%] .ngx-ic-resize-bar[_ngcontent-%COMP%]{display:none}\"],\n changeDetection: 0\n});\n/** @nocollapse */\nImageCropperComponent.ctorParameters = () => [{\n type: CropService\n}, {\n type: CropperPositionService\n}, {\n type: LoadImageService\n}, {\n type: DomSanitizer\n}, {\n type: ChangeDetectorRef\n}];\nImageCropperComponent.propDecorators = {\n wrapper: [{\n type: ViewChild,\n args: ['wrapper', {\n static: true\n }]\n }],\n sourceImage: [{\n type: ViewChild,\n args: ['sourceImage', {\n static: false\n }]\n }],\n imageChangedEvent: [{\n type: Input\n }],\n imageURL: [{\n type: Input\n }],\n imageBase64: [{\n type: Input\n }],\n imageFile: [{\n type: Input\n }],\n format: [{\n type: Input\n }],\n transform: [{\n type: Input\n }],\n maintainAspectRatio: [{\n type: Input\n }],\n aspectRatio: [{\n type: Input\n }],\n resizeToWidth: [{\n type: Input\n }],\n resizeToHeight: [{\n type: Input\n }],\n cropperMinWidth: [{\n type: Input\n }],\n cropperMinHeight: [{\n type: Input\n }],\n cropperMaxHeight: [{\n type: Input\n }],\n cropperMaxWidth: [{\n type: Input\n }],\n cropperStaticWidth: [{\n type: Input\n }],\n cropperStaticHeight: [{\n type: Input\n }],\n canvasRotation: [{\n type: Input\n }],\n initialStepSize: [{\n type: Input\n }],\n roundCropper: [{\n type: Input\n }],\n onlyScaleDown: [{\n type: Input\n }],\n imageQuality: [{\n type: Input\n }],\n autoCrop: [{\n type: Input\n }],\n backgroundColor: [{\n type: Input\n }],\n containWithinAspectRatio: [{\n type: Input\n }],\n hideResizeSquares: [{\n type: Input\n }],\n cropper: [{\n type: Input\n }],\n alignImage: [{\n type: HostBinding,\n args: ['style.text-align']\n }, {\n type: Input\n }],\n disabled: [{\n type: HostBinding,\n args: ['class.disabled']\n }, {\n type: Input\n }],\n imageCropped: [{\n type: Output\n }],\n startCropImage: [{\n type: Output\n }],\n imageLoaded: [{\n type: Output\n }],\n cropperReady: [{\n type: Output\n }],\n loadImageFailed: [{\n type: Output\n }],\n onResize: [{\n type: HostListener,\n args: ['window:resize']\n }],\n moveImg: [{\n type: HostListener,\n args: ['document:mousemove', ['$event']]\n }, {\n type: HostListener,\n args: ['document:touchmove', ['$event']]\n }],\n moveStop: [{\n type: HostListener,\n args: ['document:mouseup']\n }, {\n type: HostListener,\n args: ['document:touchend']\n }]\n};\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(ImageCropperComponent, [{\n type: Component,\n args: [{\n selector: 'image-cropper',\n template: \"