ngx-image-cropper
Version:
An image cropper for Angular
188 lines • 28.2 kB
JavaScript
import { signal } from '@angular/core';
import { checkCropperPosition } from '../utils/cropper-position.utils';
export class CropperState {
constructor() {
this.cropper = signal({ x1: 0, x2: 0, y1: 0, y2: 0 });
this.transform = {};
this.options = {
format: 'png',
output: 'blob',
autoCrop: true,
maintainAspectRatio: true,
aspectRatio: 1,
resetCropOnAspectRatioChange: true,
resizeToWidth: 0,
resizeToHeight: 0,
cropperMinWidth: 0,
cropperMinHeight: 0,
cropperMaxHeight: 0,
cropperMaxWidth: 0,
cropperStaticWidth: 0,
cropperStaticHeight: 0,
canvasRotation: 0,
roundCropper: false,
onlyScaleDown: false,
imageQuality: 92,
backgroundColor: null,
containWithinAspectRatio: false,
hideResizeSquares: false,
alignImage: 'center',
cropperFrameAriaLabel: undefined,
checkImageType: true
};
// Internal
this.cropperScaledMinWidth = 20;
this.cropperScaledMinHeight = 20;
this.cropperScaledMaxWidth = 20;
this.cropperScaledMaxHeight = 20;
this.stepSize = 3;
}
setOptionsFromChanges(changes) {
if (changes['options']?.currentValue) {
this.setOptions(changes['options'].currentValue);
}
const options = Object.entries(changes)
.filter(([key]) => key in this.options)
.reduce((acc, [key, change]) => ({
...acc,
[key]: change.currentValue
}), {});
if (Object.keys(options).length > 0) {
this.setOptions(options);
}
}
setOptions(options) {
this.options = {
...this.options,
...(options || {})
};
this.validateOptions();
if (!this.loadedImage?.transformed.image.complete || !this.maxSize) {
return;
}
let positionPossiblyChanged = false;
if ((this.options.maintainAspectRatio && options['aspectRatio']) || options['maintainAspectRatio']) {
this.setCropperScaledMinSize();
this.setCropperScaledMaxSize();
if (this.options.maintainAspectRatio && (this.options.resetCropOnAspectRatioChange || !this.aspectRatioIsCorrect())) {
this.cropper.set(this.maxSizeCropperPosition());
positionPossiblyChanged = true;
}
}
else {
if (options['cropperMinWidth'] || options['cropperMinHeight']) {
this.setCropperScaledMinSize();
positionPossiblyChanged = true;
}
if (options['cropperMaxWidth'] || options['cropperMaxHeight']) {
this.setCropperScaledMaxSize();
positionPossiblyChanged = true;
}
if (options['cropperStaticWidth'] || options['cropperStaticHeight']) {
positionPossiblyChanged = true;
}
}
if (positionPossiblyChanged) {
this.cropper.update((cropper) => checkCropperPosition(cropper, this, false));
}
}
validateOptions() {
if (this.options.maintainAspectRatio && !this.options.aspectRatio) {
throw new Error('`aspectRatio` should > 0 when `maintainAspectRatio` is enabled');
}
}
setMaxSize(width, height) {
this.maxSize = { width, height };
this.setCropperScaledMinSize();
this.setCropperScaledMaxSize();
}
setCropperScaledMinSize() {
if (this.loadedImage?.transformed.size) {
this.setCropperScaledMinWidth();
this.setCropperScaledMinHeight();
}
else {
this.cropperScaledMinWidth = 20;
this.cropperScaledMinHeight = 20;
}
}
setCropperScaledMinWidth() {
this.cropperScaledMinWidth = this.options.cropperMinWidth > 0
? Math.max(20, this.options.cropperMinWidth / this.loadedImage.transformed.size.width * this.maxSize.width)
: 20;
}
setCropperScaledMinHeight() {
if (this.options.maintainAspectRatio) {
this.cropperScaledMinHeight = Math.max(20, this.cropperScaledMinWidth / this.options.aspectRatio);
}
else if (this.options.cropperMinHeight > 0) {
this.cropperScaledMinHeight = Math.max(20, this.options.cropperMinHeight / this.loadedImage.transformed.size.height * this.maxSize.height);
}
else {
this.cropperScaledMinHeight = 20;
}
}
setCropperScaledMaxSize() {
if (this.loadedImage?.transformed.size) {
const ratio = this.loadedImage.transformed.size.width / this.maxSize.width;
this.cropperScaledMaxWidth = this.options.cropperMaxWidth > 20 ? this.options.cropperMaxWidth / ratio : this.maxSize.width;
this.cropperScaledMaxHeight = this.options.cropperMaxHeight > 20 ? this.options.cropperMaxHeight / ratio : this.maxSize.height;
if (this.options.maintainAspectRatio) {
if (this.cropperScaledMaxWidth > this.cropperScaledMaxHeight * this.options.aspectRatio) {
this.cropperScaledMaxWidth = this.cropperScaledMaxHeight * this.options.aspectRatio;
}
else if (this.cropperScaledMaxWidth < this.cropperScaledMaxHeight * this.options.aspectRatio) {
this.cropperScaledMaxHeight = this.cropperScaledMaxWidth / this.options.aspectRatio;
}
}
}
else {
this.cropperScaledMaxWidth = this.maxSize.width;
this.cropperScaledMaxHeight = this.maxSize.height;
}
}
equalsCropperPosition(cropper) {
const localCropper = this.cropper();
return localCropper == null && cropper == null
|| localCropper != null && cropper != null
&& localCropper.x1.toFixed(3) === cropper.x1.toFixed(3)
&& localCropper.y1.toFixed(3) === cropper.y1.toFixed(3)
&& localCropper.x2.toFixed(3) === cropper.x2.toFixed(3)
&& localCropper.y2.toFixed(3) === cropper.y2.toFixed(3);
}
equalsTransformTranslate(transform) {
return (this.transform.translateH ?? 0) === (transform.translateH ?? 0)
&& (this.transform.translateV ?? 0) === (transform.translateV ?? 0);
}
equalsTransform(transform) {
return this.equalsTransformTranslate(transform)
&& (this.transform.scale ?? 1) === (transform.scale ?? 1)
&& (this.transform.rotate ?? 0) === (transform.rotate ?? 0)
&& (this.transform.flipH ?? false) === (transform.flipH ?? false)
&& (this.transform.flipV ?? false) === (transform.flipV ?? false);
}
aspectRatioIsCorrect() {
const localCropper = this.cropper();
const currentCropAspectRatio = (localCropper.x2 - localCropper.x1) / (localCropper.y2 - localCropper.y1);
return currentCropAspectRatio === this.options.aspectRatio;
}
resizeCropperPosition(oldMaxSize) {
if (oldMaxSize.width !== this.maxSize.width || oldMaxSize.height !== this.maxSize.height) {
this.cropper.update(cropper => ({
x1: cropper.x1 * this.maxSize.width / oldMaxSize.width,
x2: cropper.x2 * this.maxSize.width / oldMaxSize.width,
y1: cropper.y1 * this.maxSize.height / oldMaxSize.height,
y2: cropper.y2 * this.maxSize.height / oldMaxSize.height
}));
}
}
maxSizeCropperPosition() {
return {
x1: 0,
y1: 0,
x2: this.maxSize.width,
y2: this.maxSize.height
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JvcHBlci5zdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1pbWFnZS1jcm9wcGVyL3NyYy9saWIvY29tcG9uZW50L2Nyb3BwZXIuc3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLE1BQU0sRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDdEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFdkUsTUFBTSxPQUFPLFlBQVk7SUFBekI7UUFFVyxZQUFPLEdBQUcsTUFBTSxDQUFrQixFQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1FBSXpFLGNBQVMsR0FBbUIsRUFBRSxDQUFDO1FBQy9CLFlBQU8sR0FBbUI7WUFDeEIsTUFBTSxFQUFFLEtBQUs7WUFDYixNQUFNLEVBQUUsTUFBTTtZQUNkLFFBQVEsRUFBRSxJQUFJO1lBQ2QsbUJBQW1CLEVBQUUsSUFBSTtZQUN6QixXQUFXLEVBQUUsQ0FBQztZQUNkLDRCQUE0QixFQUFFLElBQUk7WUFDbEMsYUFBYSxFQUFFLENBQUM7WUFDaEIsY0FBYyxFQUFFLENBQUM7WUFDakIsZUFBZSxFQUFFLENBQUM7WUFDbEIsZ0JBQWdCLEVBQUUsQ0FBQztZQUNuQixnQkFBZ0IsRUFBRSxDQUFDO1lBQ25CLGVBQWUsRUFBRSxDQUFDO1lBQ2xCLGtCQUFrQixFQUFFLENBQUM7WUFDckIsbUJBQW1CLEVBQUUsQ0FBQztZQUN0QixjQUFjLEVBQUUsQ0FBQztZQUNqQixZQUFZLEVBQUUsS0FBSztZQUNuQixhQUFhLEVBQUUsS0FBSztZQUNwQixZQUFZLEVBQUUsRUFBRTtZQUNoQixlQUFlLEVBQUUsSUFBSTtZQUNyQix3QkFBd0IsRUFBRSxLQUFLO1lBQy9CLGlCQUFpQixFQUFFLEtBQUs7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QUFDLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSztnQkFDdkQsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQVEsQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU07Z0JBQ3pELEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFRLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNO2FBQzFELENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQztJQUNILENBQUM7SUFFRCxzQkFBc0I7UUFDcEIsT0FBTztZQUNMLEVBQUUsRUFBRSxDQUFDO1lBQ0wsRUFBRSxFQUFFLENBQUM7WUFDTCxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQVEsQ0FBQyxLQUFLO1lBQ3ZCLEVBQUUsRUFBRSxJQUFJLENBQUMsT0FBUSxDQUFDLE1BQU07U0FDekIsQ0FBQztJQUNKLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENyb3BwZXJPcHRpb25zIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9jcm9wcGVyLW9wdGlvbnMuaW50ZXJmYWNlJztcbmltcG9ydCB7IENyb3BwZXJQb3NpdGlvbiwgRGltZW5zaW9ucywgSW1hZ2VUcmFuc2Zvcm0sIExvYWRlZEltYWdlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBzaWduYWwsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNoZWNrQ3JvcHBlclBvc2l0aW9uIH0gZnJvbSAnLi4vdXRpbHMvY3JvcHBlci1wb3NpdGlvbi51dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBDcm9wcGVyU3RhdGUge1xuXG4gIHJlYWRvbmx5IGNyb3BwZXIgPSBzaWduYWw8Q3JvcHBlclBvc2l0aW9uPih7eDE6IDAsIHgyOiAwLCB5MTogMCwgeTI6IDB9KTtcblxuICBsb2FkZWRJbWFnZT86IExvYWRlZEltYWdlO1xuICBtYXhTaXplPzogRGltZW5zaW9ucztcbiAgdHJhbnNmb3JtOiBJbWFnZVRyYW5zZm9ybSA9IHt9O1xuICBvcHRpb25zOiBDcm9wcGVyT3B0aW9ucyA9IHtcbiAgICBmb3JtYXQ6ICdwbmcnLFxuICAgIG91dHB1dDogJ2Jsb2InLFxuICAgIGF1dG9Dcm9wOiB0cnVlLFxuICAgIG1haW50YWluQXNwZWN0UmF0aW86IHRydWUsXG4gICAgYXNwZWN0UmF0aW86IDEsXG4gICAgcmVzZXRDcm9wT25Bc3BlY3RSYXRpb0NoYW5nZTogdHJ1ZSxcbiAgICByZXNpemVUb1dpZHRoOiAwLFxuICAgIHJlc2l6ZVRvSGVpZ2h0OiAwLFxuICAgIGNyb3BwZXJNaW5XaWR0aDogMCxcbiAgICBjcm9wcGVyTWluSGVpZ2h0OiAwLFxuICAgIGNyb3BwZXJNYXhIZWlnaHQ6IDAsXG4gICAgY3JvcHBlck1heFdpZHRoOiAwLFxuICAgIGNyb3BwZXJTdGF0aWNXaWR0aDogMCxcbiAgICBjcm9wcGVyU3RhdGljSGVpZ2h0OiAwLFxuICAgIGNhbnZhc1JvdGF0aW9uOiAwLFxuICAgIHJvdW5kQ3JvcHBlcjogZmFsc2UsXG4gICAgb25seVNjYWxlRG93bjogZmFsc2UsXG4gICAgaW1hZ2VRdWFsaXR5OiA5MixcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IG51bGwsXG4gICAgY29udGFpbldpdGhpbkFzcGVjdFJhdGlvOiBmYWxzZSxcbiAgICBoaWRlUmVzaXplU3F1YXJlczogZmFsc2UsXG4gICAgYWxpZ25JbWFnZTogJ2NlbnRlcicsXG4gICAgY3JvcHBlckZyYW1lQXJpYUxhYmVsOiB1bmRlZmluZWQsXG4gICAgY2hlY2tJbWFnZVR5cGU6IHRydWVcbiAgfTtcblxuICAvLyBJbnRlcm5hbFxuICBjcm9wcGVyU2NhbGVkTWluV2lkdGggPSAyMDtcbiAgY3JvcHBlclNjYWxlZE1pbkhlaWdodCA9IDIwO1xuICBjcm9wcGVyU2NhbGVkTWF4V2lkdGggPSAyMDtcbiAgY3JvcHBlclNjYWxlZE1heEhlaWdodCA9IDIwO1xuICBzdGVwU2l6ZSA9IDM7XG5cbiAgc2V0T3B0aW9uc0Zyb21DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snb3B0aW9ucyddPy5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMuc2V0T3B0aW9ucyhjaGFuZ2VzWydvcHRpb25zJ10uY3VycmVudFZhbHVlKTtcbiAgICB9XG4gICAgY29uc3Qgb3B0aW9ucyA9IE9iamVjdC5lbnRyaWVzKGNoYW5nZXMpXG4gICAgICAuZmlsdGVyKChba2V5XSkgPT4ga2V5IGluIHRoaXMub3B0aW9ucylcbiAgICAgIC5yZWR1Y2UoKGFjYywgW2tleSwgY2hhbmdlXSkgPT4gKHtcbiAgICAgICAgLi4uYWNjLFxuICAgICAgICBba2V5XTogY2hhbmdlLmN1cnJlbnRWYWx1ZVxuICAgICAgfSksIHt9IGFzIFBhcnRpYWw8Q3JvcHBlck9wdGlvbnM+KTtcbiAgICBpZiAoT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHNldE9wdGlvbnMob3B0aW9uczogUGFydGlhbDxDcm9wcGVyT3B0aW9ucz4pOiB2b2lkIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAuLi50aGlzLm9wdGlvbnMsXG4gICAgICAuLi4ob3B0aW9ucyB8fCB7fSlcbiAgICB9O1xuICAgIHRoaXMudmFsaWRhdGVPcHRpb25zKCk7XG5cbiAgICBpZiAoIXRoaXMubG9hZGVkSW1hZ2U/LnRyYW5zZm9ybWVkLmltYWdlLmNvbXBsZXRlIHx8ICF0aGlzLm1heFNpemUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgcG9zaXRpb25Qb3NzaWJseUNoYW5nZWQgPSBmYWxzZTtcbiAgICBpZiAoKHRoaXMub3B0aW9ucy5tYWludGFpbkFzcGVjdFJhdGlvICYmIG9wdGlvbnNbJ2FzcGVjdFJhdGlvJ10pIHx8IG9wdGlvbnNbJ21haW50YWluQXNwZWN0UmF0aW8nXSkge1xuICAgICAgdGhpcy5zZXRDcm9wcGVyU2NhbGVkTWluU2l6ZSgpO1xuICAgICAgdGhpcy5zZXRDcm9wcGVyU2NhbGVkTWF4U2l6ZSgpO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5tYWludGFpbkFzcGVjdFJhdGlvICYmICh0aGlzLm9wdGlvbnMucmVzZXRDcm9wT25Bc3BlY3RSYXRpb0NoYW5nZSB8fCAhdGhpcy5hc3BlY3RSYXRpb0lzQ29ycmVjdCgpKSkge1xuICAgICAgICB0aGlzLmNyb3BwZXIuc2V0KHRoaXMubWF4U2l6ZUNyb3BwZXJQb3NpdGlvbigpKTtcbiAgICAgICAgcG9zaXRpb25Qb3NzaWJseUNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAob3B0aW9uc1snY3JvcHBlck1pbldpZHRoJ10gfHwgb3B0aW9uc1snY3JvcHBlck1pbkhlaWdodCddKSB7XG4gICAgICAgIHRoaXMuc2V0Q3JvcHBlclNjYWxlZE1pblNpemUoKTtcbiAgICAgICAgcG9zaXRpb25Qb3NzaWJseUNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnNbJ2Nyb3BwZXJNYXhXaWR0aCddIHx8IG9wdGlvbnNbJ2Nyb3BwZXJNYXhIZWlnaHQnXSkge1xuICAgICAgICB0aGlzLnNldENyb3BwZXJTY2FsZWRNYXhTaXplKCk7XG4gICAgICAgIHBvc2l0aW9uUG9zc2libHlDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zWydjcm9wcGVyU3RhdGljV2lkdGgnXSB8fCBvcHRpb25zWydjcm9wcGVyU3RhdGljSGVpZ2h0J10pIHtcbiAgICAgICAgcG9zaXRpb25Qb3NzaWJseUNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvblBvc3NpYmx5Q2hhbmdlZCkge1xuICAgICAgdGhpcy5jcm9wcGVyLnVwZGF0ZSgoY3JvcHBlcikgPT4gY2hlY2tDcm9wcGVyUG9zaXRpb24oY3JvcHBlciwgdGhpcywgZmFsc2UpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlT3B0aW9ucygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLm1haW50YWluQXNwZWN0UmF0aW8gJiYgIXRoaXMub3B0aW9ucy5hc3BlY3RSYXRpbykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdgYXNwZWN0UmF0aW9gIHNob3VsZCA+IDAgd2hlbiBgbWFpbnRhaW5Bc3BlY3RSYXRpb2AgaXMgZW5hYmxlZCcpO1xuICAgIH1cbiAgfVxuXG4gIHNldE1heFNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLm1heFNpemUgPSB7d2lkdGgsIGhlaWdodH07XG4gICAgdGhpcy5zZXRDcm9wcGVyU2NhbGVkTWluU2l6ZSgpO1xuICAgIHRoaXMuc2V0Q3JvcHBlclNjYWxlZE1heFNpemUoKTtcbiAgfVxuXG4gIHNldENyb3BwZXJTY2FsZWRNaW5TaXplKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxvYWRlZEltYWdlPy50cmFuc2Zvcm1lZC5zaXplKSB7XG4gICAgICB0aGlzLnNldENyb3BwZXJTY2FsZWRNaW5XaWR0aCgpO1xuICAgICAgdGhpcy5zZXRDcm9wcGVyU2NhbGVkTWluSGVpZ2h0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3JvcHBlclNjYWxlZE1pbldpZHRoID0gMjA7XG4gICAgICB0aGlzLmNyb3BwZXJTY2FsZWRNaW5IZWlnaHQgPSAyMDtcbiAgICB9XG4gIH1cblxuICBzZXRDcm9wcGVyU2NhbGVkTWluV2lkdGgoKTogdm9pZCB7XG4gICAgdGhpcy5jcm9wcGVyU2NhbGVkTWluV2lkdGggPSB0aGlzLm9wdGlvbnMuY3JvcHBlck1pbldpZHRoID4gMFxuICAgICAgPyBNYXRoLm1heCgyMCwgdGhpcy5vcHRpb25zLmNyb3BwZXJNaW5XaWR0aCAvIHRoaXMubG9hZGVkSW1hZ2UhLnRyYW5zZm9ybWVkLnNpemUud2lkdGggKiB0aGlzLm1heFNpemUhLndpZHRoKVxuICAgICAgOiAyMDtcbiAgfVxuXG4gIHNldENyb3BwZXJTY2FsZWRNaW5IZWlnaHQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5tYWludGFpbkFzcGVjdFJhdGlvKSB7XG4gICAgICB0aGlzLmNyb3BwZXJTY2FsZWRNaW5IZWlnaHQgPSBNYXRoLm1heCgyMCwgdGhpcy5jcm9wcGVyU2NhbGVkTWluV2lkdGggLyB0aGlzLm9wdGlvbnMuYXNwZWN0UmF0aW8pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5vcHRpb25zLmNyb3BwZXJNaW5IZWlnaHQgPiAwKSB7XG4gICAgICB0aGlzLmNyb3BwZXJTY2FsZWRNaW5IZWlnaHQgPSBNYXRoLm1heChcbiAgICAgICAgMjAsXG4gICAgICAgIHRoaXMub3B0aW9ucy5jcm9wcGVyTWluSGVpZ2h0IC8gdGhpcy5sb2FkZWRJbWFnZSEudHJhbnNmb3JtZWQuc2l6ZS5oZWlnaHQgKiB0aGlzLm1heFNpemUhLmhlaWdodFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jcm9wcGVyU2NhbGVkTWluSGVpZ2h0ID0gMjA7XG4gICAgfVxuICB9XG5cbiAgc2V0Q3JvcHBlclNjYWxlZE1heFNpemUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubG9hZGVkSW1hZ2U/LnRyYW5zZm9ybWVkLnNpemUpIHtcbiAgICAgIGNvbnN0IHJhdGlvID0gdGhpcy5sb2FkZWRJbWFnZS50cmFuc2Zvcm1lZC5zaXplLndpZHRoIC8gdGhpcy5tYXhTaXplIS53aWR0aDtcbiAgICAgIHRoaXMuY3JvcHBlclNjYWxlZE1heFdpZHRoID0gdGhpcy5vcHRpb25zLmNyb3BwZXJNYXhXaWR0aCA+IDIwID8gdGhpcy5vcHRpb25zLmNyb3BwZXJNYXhXaWR0aCAvIHJhdGlvIDogdGhpcy5tYXhTaXplIS53aWR0aDtcbiAgICAgIHRoaXMuY3JvcHBlclNjYWxlZE1heEhlaWdodCA9IHRoaXMub3B0aW9ucy5jcm9wcGVyTWF4SGVpZ2h0ID4gMjAgPyB0aGlzLm9wdGlvbnMuY3JvcHBlck1heEhlaWdodCAvIHJhdGlvIDogdGhpcy5tYXhTaXplIS5oZWlnaHQ7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLm1haW50YWluQXNwZWN0UmF0aW8pIHtcbiAgICAgICAgaWYgKHRoaXMuY3JvcHBlclNjYWxlZE1heFdpZHRoID4gdGhpcy5jcm9wcGVyU2NhbGVkTWF4SGVpZ2h0ICogdGhpcy5vcHRpb25zLmFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgdGhpcy5jcm9wcGVyU2NhbGVkTWF4V2lkdGggPSB0aGlzLmNyb3BwZXJTY2FsZWRNYXhIZWlnaHQgKiB0aGlzLm9wdGlvbnMuYXNwZWN0UmF0aW87XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jcm9wcGVyU2NhbGVkTWF4V2lkdGggPCB0aGlzLmNyb3BwZXJTY2FsZWRNYXhIZWlnaHQgKiB0aGlzLm9wdGlvbnMuYXNwZWN0UmF0aW8pIHtcbiAgICAgICAgICB0aGlzLmNyb3BwZXJTY2FsZWRNYXhIZWlnaHQgPSB0aGlzLmNyb3BwZXJTY2FsZWRNYXhXaWR0aCAvIHRoaXMub3B0aW9ucy5hc3BlY3RSYXRpbztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNyb3BwZXJTY2FsZWRNYXhXaWR0aCA9IHRoaXMubWF4U2l6ZSEud2lkdGg7XG4gICAgICB0aGlzLmNyb3BwZXJTY2FsZWRNYXhIZWlnaHQgPSB0aGlzLm1heFNpemUhLmhlaWdodDtcbiAgICB9XG4gIH1cblxuICBlcXVhbHNDcm9wcGVyUG9zaXRpb24oY3JvcHBlcj86IENyb3BwZXJQb3NpdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGxvY2FsQ3JvcHBlciA9IHRoaXMuY3JvcHBlcigpO1xuICAgIHJldHVybiBsb2NhbENyb3BwZXIgPT0gbnVsbCAmJiBjcm9wcGVyID09IG51bGxcbiAgICAgIHx8IGxvY2FsQ3JvcHBlciAhPSBudWxsICYmIGNyb3BwZXIgIT0gbnVsbFxuICAgICAgJiYgbG9jYWxDcm9wcGVyLngxLnRvRml4ZWQoMykgPT09IGNyb3BwZXIueDEudG9GaXhlZCgzKVxuICAgICAgJiYgbG9jYWxDcm9wcGVyLnkxLnRvRml4ZWQoMykgPT09IGNyb3BwZXIueTEudG9GaXhlZCgzKVxuICAgICAgJiYgbG9jYWxDcm9wcGVyLngyLnRvRml4ZWQoMykgPT09IGNyb3BwZXIueDIudG9GaXhlZCgzKVxuICAgICAgJiYgbG9jYWxDcm9wcGVyLnkyLnRvRml4ZWQoMykgPT09IGNyb3BwZXIueTIudG9GaXhlZCgzKTtcbiAgfVxuXG4gIGVxdWFsc1RyYW5zZm9ybVRyYW5zbGF0ZSh0cmFuc2Zvcm06IEltYWdlVHJhbnNmb3JtKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLnRyYW5zZm9ybS50cmFuc2xhdGVIID8/IDApID09PSAodHJhbnNmb3JtLnRyYW5zbGF0ZUggPz8gMClcbiAgICAgICYmICh0aGlzLnRyYW5zZm9ybS50cmFuc2xhdGVWID8/IDApID09PSAodHJhbnNmb3JtLnRyYW5zbGF0ZVYgPz8gMCk7XG4gIH1cblxuICBlcXVhbHNUcmFuc2Zvcm0odHJhbnNmb3JtOiBJbWFnZVRyYW5zZm9ybSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVxdWFsc1RyYW5zZm9ybVRyYW5zbGF0ZSh0cmFuc2Zvcm0pXG4gICAgICAmJiAodGhpcy50cmFuc2Zvcm0uc2NhbGUgPz8gMSkgPT09ICh0cmFuc2Zvcm0uc2NhbGUgPz8gMSlcbiAgICAgICYmICh0aGlzLnRyYW5zZm9ybS5yb3RhdGUgPz8gMCkgPT09ICh0cmFuc2Zvcm0ucm90YXRlID8/IDApXG4gICAgICAmJiAodGhpcy50cmFuc2Zvcm0uZmxpcEggPz8gZmFsc2UpID09PSAodHJhbnNmb3JtLmZsaXBIID8/IGZhbHNlKVxuICAgICAgJiYgKHRoaXMudHJhbnNmb3JtLmZsaXBWID8/IGZhbHNlKSA9PT0gKHRyYW5zZm9ybS5mbGlwViA/PyBmYWxzZSk7XG4gIH1cblxuICBhc3BlY3RSYXRpb0lzQ29ycmVjdCgpOiBib29sZWFuIHtcbiAgICBjb25zdCBsb2NhbENyb3BwZXIgPSB0aGlzLmNyb3BwZXIoKTtcbiAgICBjb25zdCBjdXJyZW50Q3JvcEFzcGVjdFJhdGlvID0gKGxvY2FsQ3JvcHBlci54MiAtIGxvY2FsQ3JvcHBlci54MSkgLyAobG9jYWxDcm9wcGVyLnkyIC0gbG9jYWxDcm9wcGVyLnkxKTtcbiAgICByZXR1cm4gY3VycmVudENyb3BBc3BlY3RSYXRpbyA9PT0gdGhpcy5vcHRpb25zLmFzcGVjdFJhdGlvO1xuICB9XG5cbiAgcmVzaXplQ3JvcHBlclBvc2l0aW9uKG9sZE1heFNpemU6IERpbWVuc2lvbnMpOiB2b2lkIHtcbiAgICBpZiAob2xkTWF4U2l6ZS53aWR0aCAhPT0gdGhpcy5tYXhTaXplIS53aWR0aCB8fCBvbGRNYXhTaXplLmhlaWdodCAhPT0gdGhpcy5tYXhTaXplIS5oZWlnaHQpIHtcbiAgICAgIHRoaXMuY3JvcHBlci51cGRhdGUoY3JvcHBlciA9PiAoe1xuICAgICAgICB4MTogY3JvcHBlci54MSAqIHRoaXMubWF4U2l6ZSEud2lkdGggLyBvbGRNYXhTaXplLndpZHRoLFxuICAgICAgICB4MjogY3JvcHBlci54MiAqIHRoaXMubWF4U2l6ZSEud2lkdGggLyBvbGRNYXhTaXplLndpZHRoLFxuICAgICAgICB5MTogY3JvcHBlci55MSAqIHRoaXMubWF4U2l6ZSEuaGVpZ2h0IC8gb2xkTWF4U2l6ZS5oZWlnaHQsXG4gICAgICAgIHkyOiBjcm9wcGVyLnkyICogdGhpcy5tYXhTaXplIS5oZWlnaHQgLyBvbGRNYXhTaXplLmhlaWdodFxuICAgICAgfSkpO1xuICAgIH1cbiAgfVxuXG4gIG1heFNpemVDcm9wcGVyUG9zaXRpb24oKTogQ3JvcHBlclBvc2l0aW9uIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDE6IDAsXG4gICAgICB5MTogMCxcbiAgICAgIHgyOiB0aGlzLm1heFNpemUhLndpZHRoLFxuICAgICAgeTI6IHRoaXMubWF4U2l6ZSEuaGVpZ2h0XG4gICAgfTtcbiAgfVxufVxuIl19