@junte/ui
Version:
Quality Angular UI components kit
344 lines • 37.3 kB
JavaScript
var ImageCropperComponent_1;
import { __decorate, __metadata } from "tslib";
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, HostBinding, HostListener, Input, OnInit, Output, ViewChild } from '@angular/core';
import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms';
import { DomSanitizer, SafeStyle, SafeUrl } from '@angular/platform-browser';
import { NGXLogger } from 'ngx-logger';
import { PropertyApi } from '../../core/decorators/api';
import { Shape } from '../../core/enums/shape';
import { UI } from '../../core/enums/ui';
import { I18N_PROVIDERS } from '../../core/i18n/providers';
const CROPPER_SIZE = 200;
const DEFAULT_SCALE = 1;
const DEFAULT_MIN = 0.01;
const DEFAULT_MAX = 5;
const DEFAULT_STEP = 0.01;
export var MoveTypes;
(function (MoveTypes) {
MoveTypes["Move"] = "move";
MoveTypes["Pinch"] = "pinch";
})(MoveTypes || (MoveTypes = {}));
export class MoveStart {
constructor() {
this.active = false;
this.type = null;
this.left = 0;
this.top = 0;
this.clientX = 0;
this.clientY = 0;
}
}
export class ImagePosition {
constructor() {
this.left = 0;
this.top = 0;
this.scale = DEFAULT_SCALE;
this.width = 0;
this.height = 0;
}
}
export class CropperPosition {
constructor() {
this.width = CROPPER_SIZE;
this.height = CROPPER_SIZE;
}
}
let ImageCropperComponent = ImageCropperComponent_1 = class ImageCropperComponent {
constructor(logger, cd, fb, sanitizer) {
this.logger = logger;
this.cd = cd;
this.fb = fb;
this.sanitizer = sanitizer;
this.ui = UI;
this.host = 'jnt-image-cropper-host';
this.moveStart = new MoveStart();
this.sizeRetries = 0;
this._min = DEFAULT_MIN;
this._max = DEFAULT_MAX;
this._step = DEFAULT_STEP;
this.marginLeft = '0px';
this.moveTypes = MoveTypes;
this.imagePosition = new ImagePosition();
this.form = this.fb.group({
zoom: [this.imagePosition.scale]
});
this.area = new CropperPosition();
this.disabled = false;
this._shape = Shape.circle;
this.loaded = new EventEmitter();
this.failed = new EventEmitter();
this.onChange = () => this.logger.error('value accessor is not registered');
this.onTouched = () => this.logger.error('value accessor is not registered');
this.registerOnChange = fn => this.onChange = fn;
this.registerOnTouched = fn => this.onTouched = fn;
this.onBlur = () => this.onTouched();
}
set min(min) {
this._min = min || DEFAULT_MIN;
}
get min() {
return this._min;
}
set max(max) {
this._max = max || DEFAULT_MAX;
}
get max() {
return this._max;
}
set step(step) {
this._step = step || DEFAULT_STEP;
}
get step() {
return this._step;
}
set url(url) {
this._url = url;
if (!!url) {
this.moveStart = new MoveStart();
this.imagePosition = new ImagePosition();
}
}
get url() {
return this._url;
}
set shape(shape) {
this._shape = shape || Shape.circle;
}
ngOnInit() {
this.form.valueChanges.subscribe(({ zoom }) => this.zoom(zoom));
}
inView() {
if (this.image.nativeElement.currentSrc.includes('image/svg')) {
this.disabled = true;
}
this.loaded.emit();
this.sizeRetries = 0;
setTimeout(() => this.checkImageMaxSizeRecursively());
}
checkImageMaxSizeRecursively() {
if (this.sizeRetries > 40) {
this.failed.emit();
}
else if (!!this.image && !!this.image.nativeElement && this.image.nativeElement.offsetWidth > 0) {
const image = this.image.nativeElement;
const wrapper = this.wrapper.nativeElement;
this.imagePosition.width = image.offsetWidth;
this.imagePosition.height = image.offsetHeight;
this.imagePosition.top = (wrapper.offsetHeight - image.offsetHeight) / 2;
this.imagePosition.left = (wrapper.offsetWidth - image.offsetWidth) / 2;
let scale = Math.trunc(wrapper.offsetWidth / image.offsetWidth * 100) / 100;
scale = Math.min(scale, Math.trunc(wrapper.offsetHeight / image.offsetHeight * 100) / 100, this.max);
this.zoom(scale);
this.cd.detectChanges();
}
else {
this.sizeRetries++;
setTimeout(() => this.checkImageMaxSizeRecursively(), 50);
}
}
startMove(event, moveType) {
if (!!this.moveStart && this.moveStart.active && this.moveStart.type === MoveTypes.Pinch) {
return;
}
if (!!event.preventDefault) {
event.preventDefault();
}
this.moveStart = Object.assign({ active: true, type: moveType, clientX: this.getClientX(event), clientY: this.getClientY(event) }, this.imagePosition);
}
moveImg(event) {
if (this.moveStart.active) {
if (event.stopPropagation) {
event.stopPropagation();
}
if (event.preventDefault) {
event.preventDefault();
}
if (this.moveStart.type === MoveTypes.Move) {
this.move(event);
}
this.cd.detectChanges();
}
}
moveStop() {
if (this.moveStart.active) {
this.moveStart.active = false;
this.crop();
}
}
crop() {
const image = this.image.nativeElement;
const cropper = this.cropper.nativeElement;
const scale = this.imagePosition.scale;
this.onChange({
left: Math.round(cropper.offsetLeft - (image.offsetLeft - ((image.width * scale - image.width) / 2))),
top: Math.round(cropper.offsetTop - (image.offsetTop - ((image.height * scale - image.height) / 2))),
scale
});
}
move(event) {
const diffX = this.getClientX(event) - this.moveStart.clientX;
const diffY = this.getClientY(event) - this.moveStart.clientY;
this.imagePosition.left = this.moveStart.left + diffX;
this.imagePosition.top = this.moveStart.top + diffY;
}
;
getClientX(event) {
return (event.touches && event.touches[0] ? event.touches[0].clientX : event.clientX) || 0;
}
getClientY(event) {
return (event.touches && event.touches[0] ? event.touches[0].clientY : event.clientY) || 0;
}
zoom(scale = DEFAULT_SCALE) {
this.imagePosition.scale = scale;
this.imagePosition.width = this.imagePosition.width * scale;
this.imagePosition.height = this.imagePosition.height * scale;
this.transformStyle = this.sanitizer
.bypassSecurityTrustStyle(`scaleX(${scale || DEFAULT_SCALE})scaleY(${scale || DEFAULT_SCALE})`);
this.cd.detectChanges();
this.crop();
}
writeValue(data) {
if (!!data) {
this.imagePosition = Object.assign(Object.assign({}, this.imagePosition), data);
}
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
};
ImageCropperComponent.ctorParameters = () => [
{ type: NGXLogger },
{ type: ChangeDetectorRef },
{ type: FormBuilder },
{ type: DomSanitizer }
];
__decorate([
HostBinding('attr.host'),
__metadata("design:type", Object)
], ImageCropperComponent.prototype, "host", void 0);
__decorate([
ViewChild('wrapper', { static: true }),
__metadata("design:type", ElementRef)
], ImageCropperComponent.prototype, "wrapper", void 0);
__decorate([
ViewChild('image'),
__metadata("design:type", ElementRef)
], ImageCropperComponent.prototype, "image", void 0);
__decorate([
ViewChild('cropper'),
__metadata("design:type", ElementRef)
], ImageCropperComponent.prototype, "cropper", void 0);
__decorate([
PropertyApi({
description: 'Size of crop area',
type: 'CropperPosition',
default: '{width: 200, height: 200}'
}),
Input(),
__metadata("design:type", Object)
], ImageCropperComponent.prototype, "area", void 0);
__decorate([
PropertyApi({
description: 'Min of cropping',
type: 'number',
default: '0.01'
}),
Input(),
__metadata("design:type", Number),
__metadata("design:paramtypes", [Number])
], ImageCropperComponent.prototype, "min", null);
__decorate([
PropertyApi({
description: 'Max of cropping',
type: 'number',
default: '5'
}),
Input(),
__metadata("design:type", Number),
__metadata("design:paramtypes", [Number])
], ImageCropperComponent.prototype, "max", null);
__decorate([
PropertyApi({
description: 'Step of cropping',
type: 'number',
default: '0.01'
}),
Input(),
__metadata("design:type", Number),
__metadata("design:paramtypes", [Number])
], ImageCropperComponent.prototype, "step", null);
__decorate([
PropertyApi({
description: 'Url of image',
type: 'string',
default: null
}),
Input(),
__metadata("design:type", Object),
__metadata("design:paramtypes", [Object])
], ImageCropperComponent.prototype, "url", null);
__decorate([
HostBinding('attr.data-disabled'),
__metadata("design:type", Object)
], ImageCropperComponent.prototype, "disabled", void 0);
__decorate([
HostBinding('attr.data-shape'),
__metadata("design:type", String)
], ImageCropperComponent.prototype, "_shape", void 0);
__decorate([
PropertyApi({
description: 'Avatar shape',
path: 'ui.shape',
default: Shape.circle,
options: [Shape.circle, Shape.square]
}),
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], ImageCropperComponent.prototype, "shape", null);
__decorate([
Output(),
__metadata("design:type", Object)
], ImageCropperComponent.prototype, "loaded", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], ImageCropperComponent.prototype, "failed", void 0);
__decorate([
HostListener('blur'),
__metadata("design:type", Object)
], ImageCropperComponent.prototype, "onBlur", void 0);
__decorate([
HostListener('document:mousemove', ['$event']),
HostListener('document:touchmove', ['$event']),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], ImageCropperComponent.prototype, "moveImg", null);
__decorate([
HostListener('document:mouseup'),
HostListener('document:touchend'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], ImageCropperComponent.prototype, "moveStop", null);
ImageCropperComponent = ImageCropperComponent_1 = __decorate([
Component({
selector: 'jnt-image-cropper',
template: "<label child-of=\"jnt-image-cropper-host\" *ngIf=\"!imagePosition.width && !imagePosition.height\">\n <jnt-icon child-of=\"jnt-image-cropper-host\" [icon]=\"ui.icons.download\"></jnt-icon>\n</label>\n\n<div child-of=\"jnt-image-cropper-host\" #wrapper data-wrapper>\n <img child-of=\"jnt-image-cropper-host\" #image\n *ngIf=\"!!url\"\n [src]=\"url\"\n (load)=\"inView()\"\n [style.top.px]=\"imagePosition.top\"\n [style.left.px]=\"imagePosition.left\"\n [style.transform]=\"transformStyle\"\n (mousedown)=\"startMove($event, moveTypes.Move)\"\n (touchstart)=\"startMove($event, moveTypes.Move)\" />\n\n <div child-of=\"jnt-image-cropper-host\" #cropper\n data-cropper *ngIf=\"!!imagePosition.width && !!imagePosition.height\"\n [style.top]=\"'calc(50% - ' + area.height / 2 + 'px)'\"\n [style.left]=\"'calc(50% - ' + area.width / 2 + 'px)'\"\n [style.width.px]=\"area.width\"\n [style.height.px]=\"area.height\"\n tabindex=\"0\">\n </div>\n</div>\n\n<form child-of=\"jnt-image-cropper-host\" [formGroup]=\"form\" data-zoom [attr.data-disabled]=\"!imagePosition.width || !imagePosition.height || disabled\">\n <jnt-slider child-of=\"jnt-image-cropper-host\" formControlName=\"zoom\"\n [min]=\"min\"\n [max]=\"max\"\n [step]=\"step\">\n </jnt-slider>\n</form>",
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ImageCropperComponent_1),
multi: true
}, ...I18N_PROVIDERS
]
}),
__metadata("design:paramtypes", [NGXLogger,
ChangeDetectorRef,
FormBuilder,
DomSanitizer])
], ImageCropperComponent);
export { ImageCropperComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtY3JvcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AanVudGUvdWkvIiwic291cmNlcyI6WyJsaWIvZm9ybXMvaW1hZ2UtY3JvcHBlci9pbWFnZS1jcm9wcGVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFBRSxNQUFNLEVBQ2IsTUFBTSxFQUNOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDN0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDeEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9DLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFM0QsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDO0FBQ3pCLE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQztBQUN4QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFDekIsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQztBQUUxQixNQUFNLENBQU4sSUFBWSxTQUdYO0FBSEQsV0FBWSxTQUFTO0lBQ25CLDBCQUFhLENBQUE7SUFDYiw0QkFBZSxDQUFBO0FB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LG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7Ozs7b0RBYzlDO0FBSUQ7SUFGQyxZQUFZLENBQUMsa0JBQWtCLENBQUM7SUFDaEMsWUFBWSxDQUFDLG1CQUFtQixDQUFDOzs7O3FEQU1qQztBQWxNVSxxQkFBcUI7SUFaakMsU0FBUyxDQUFDO1FBQ1QsUUFBUSxFQUFFLG1CQUFtQjtRQUM3Qix1M0NBQWdEO1FBQ2hELGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO1FBQy9DLFNBQVMsRUFBRTtZQUNUO2dCQUNFLE9BQU8sRUFBRSxpQkFBaUI7Z0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsdUJBQXFCLENBQUM7Z0JBQ3BELEtBQUssRUFBRSxJQUFJO2FBQ1osRUFBRSxHQUFHLGNBQWM7U0FDckI7S0FDRixDQUFDO3FDQW9INEIsU0FBUztRQUNiLGlCQUFpQjtRQUNqQixXQUFXO1FBQ0wsWUFBWTtHQXRIL0IscUJBQXFCLENBa1BqQztTQWxQWSxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCwgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBGb3JtQnVpbGRlciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIsIFNhZmVTdHlsZSwgU2FmZVVybCB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgTkdYTG9nZ2VyIH0gZnJvbSAnbmd4LWxvZ2dlcic7XG5pbXBvcnQgeyBQcm9wZXJ0eUFwaSB9IGZyb20gJy4uLy4uL2NvcmUvZGVjb3JhdG9ycy9hcGknO1xuaW1wb3J0IHsgU2hhcGUgfSBmcm9tICcuLi8uLi9jb3JlL2VudW1zL3NoYXBlJztcbmltcG9ydCB7IFVJIH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy91aSc7XG5pbXBvcnQgeyBJMThOX1BST1ZJREVSUyB9IGZyb20gJy4uLy4uL2NvcmUvaTE4bi9wcm92aWRlcnMnO1xuXG5jb25zdCBDUk9QUEVSX1NJWkUgPSAyMDA7XG5jb25zdCBERUZBVUxUX1NDQUxFID0gMTtcbmNvbnN0IERFRkFVTFRfTUlOID0gMC4wMTtcbmNvbnN0IERFRkFVTFRfTUFYID0gNTtcbmNvbnN0IERFRkFVTFRfU1RFUCA9IDAuMDE7XG5cbmV4cG9ydCBlbnVtIE1vdmVUeXBlcyB7XG4gIE1vdmUgPSAnbW92ZScsXG4gIFBpbmNoID0gJ3BpbmNoJ1xufVxuXG5leHBvcnQgY2xhc3MgTW92ZVN0YXJ0IHtcbiAgYWN0aXZlOiBib29sZWFuID0gZmFsc2U7XG4gIHR5cGU6IE1vdmVUeXBlcyB8IG51bGwgPSBudWxsO1xuICBsZWZ0OiBudW1iZXIgPSAwO1xuICB0b3A6IG51bWJlciA9IDA7XG4gIGNsaWVudFg6IG51bWJlciA9IDA7XG4gIGNsaWVudFk6IG51bWJlciA9IDA7XG59XG5cbmV4cG9ydCBjbGFzcyBJbWFnZVBvc2l0aW9uIHtcbiAgbGVmdDogbnVtYmVyID0gMDtcbiAgdG9wOiBudW1iZXIgPSAwO1xuICBzY2FsZTogbnVtYmVyID0gREVGQVVMVF9TQ0FMRTtcbiAgd2lkdGg6IG51bWJlciA9IDA7XG4gIGhlaWdodDogbnVtYmVyID0gMDtcbn1cblxuZXhwb3J0IGNsYXNzIENyb3BwZXJQb3NpdGlvbiB7XG4gIHdpZHRoOiBudW1iZXIgPSBDUk9QUEVSX1NJWkU7XG4gIGhlaWdodDogbnVtYmVyID0gQ1JPUFBFUl9TSVpFO1xufVxuXG5leHBvcnQgdHlwZSBJbWFnZUNyb3BwZWREYXRhID0ge1xuICBsZWZ0OiBudW1iZXIsXG4gIHRvcDogbnVtYmVyLFxuICBzY2FsZTogbnVtYmVyXG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2pudC1pbWFnZS1jcm9wcGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ltYWdlLWNyb3BwZXIuZW5jYXBzdWxhdGVkLmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBJbWFnZUNyb3BwZXJDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9LCAuLi5JMThOX1BST1ZJREVSU1xuICBdXG59KVxuZXhwb3J0IGNsYXNzIEltYWdlQ3JvcHBlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuXG4gIHVpID0gVUk7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmhvc3QnKVxuICByZWFkb25seSBob3N0ID0gJ2pudC1pbWFnZS1jcm9wcGVyLWhvc3QnO1xuXG4gIHByaXZhdGUgbW92ZVN0YXJ0ID0gbmV3IE1vdmVTdGFydCgpO1xuICBwcml2YXRlIHNpemVSZXRyaWVzID0gMDtcbiAgcHJpdmF0ZSBfdXJsOiBTYWZlVXJsIHwgc3RyaW5nO1xuICBwcml2YXRlIF9taW4gPSBERUZBVUxUX01JTjtcbiAgcHJpdmF0ZSBfbWF4ID0gREVGQVVMVF9NQVg7XG4gIHByaXZhdGUgX3N0ZXAgPSBERUZBVUxUX1NURVA7XG5cbiAgdHJhbnNmb3JtU3R5bGU6IFNhZmVTdHlsZSB8IHN0cmluZztcbiAgbWFyZ2luTGVmdDogU2FmZVN0eWxlIHwgc3RyaW5nID0gJzBweCc7XG4gIG1vdmVUeXBlcyA9IE1vdmVUeXBlcztcbiAgaW1hZ2VQb3NpdGlvbiA9IG5ldyBJbWFnZVBvc2l0aW9uKCk7XG5cbiAgZm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgIHpvb206IFt0aGlzLmltYWdlUG9zaXRpb24uc2NhbGVdXG4gIH0pO1xuXG4gIEBWaWV3Q2hpbGQoJ3dyYXBwZXInLCB7c3RhdGljOiB0cnVlfSkgd3JhcHBlcjogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnaW1hZ2UnKSBpbWFnZTogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnY3JvcHBlcicpIGNyb3BwZXI6IEVsZW1lbnRSZWY7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1NpemUgb2YgY3JvcCBhcmVhJyxcbiAgICB0eXBlOiAnQ3JvcHBlclBvc2l0aW9uJyxcbiAgICBkZWZhdWx0OiAne3dpZHRoOiAyMDAsIGhlaWdodDogMjAwfSdcbiAgfSlcbiAgQElucHV0KCkgYXJlYSA9IG5ldyBDcm9wcGVyUG9zaXRpb24oKTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnTWluIG9mIGNyb3BwaW5nJyxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBkZWZhdWx0OiAnMC4wMSdcbiAgfSlcbiAgQElucHV0KCkgc2V0IG1pbihtaW46IG51bWJlcikge1xuICAgIHRoaXMuX21pbiA9IG1pbiB8fCBERUZBVUxUX01JTjtcbiAgfVxuXG4gIGdldCBtaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuX21pbjtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdNYXggb2YgY3JvcHBpbmcnLFxuICAgIHR5cGU6ICdudW1iZXInLFxuICAgIGRlZmF1bHQ6ICc1J1xuICB9KVxuICBASW5wdXQoKSBzZXQgbWF4KG1heDogbnVtYmVyKSB7XG4gICAgdGhpcy5fbWF4ID0gbWF4IHx8IERFRkFVTFRfTUFYXG4gIH1cblxuICBnZXQgbWF4KCkge1xuICAgIHJldHVybiB0aGlzLl9tYXg7XG4gIH1cblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnU3RlcCBvZiBjcm9wcGluZycsXG4gICAgdHlwZTogJ251bWJlcicsXG4gICAgZGVmYXVsdDogJzAuMDEnXG4gIH0pXG4gIEBJbnB1dCgpIHNldCBzdGVwKHN0ZXA6IG51bWJlcikge1xuICAgIHRoaXMuX3N0ZXAgPSBzdGVwIHx8IERFRkFVTFRfU1RFUDtcbiAgfVxuXG4gIGdldCBzdGVwKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGVwO1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1VybCBvZiBpbWFnZScsXG4gICAgdHlwZTogJ3N0cmluZycsXG4gICAgZGVmYXVsdDogbnVsbFxuICB9KVxuICBASW5wdXQoKSBzZXQgdXJsKHVybDogU2FmZVVybCB8IHN0cmluZykge1xuICAgIHRoaXMuX3VybCA9IHVybDtcbiAgICBpZiAoISF1cmwpIHtcbiAgICAgIHRoaXMubW92ZVN0YXJ0ID0gbmV3IE1vdmVTdGFydCgpO1xuICAgICAgdGhpcy5pbWFnZVBvc2l0aW9uID0gbmV3IEltYWdlUG9zaXRpb24oKTtcbiAgICB9XG4gIH1cblxuICBnZXQgdXJsKCkge1xuICAgIHJldHVybiB0aGlzLl91cmw7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoJ2F0dHIuZGF0YS1kaXNhYmxlZCcpXG4gIGRpc2FibGVkID0gZmFsc2U7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtc2hhcGUnKVxuICBfc2hhcGU6IFNoYXBlID0gU2hhcGUuY2lyY2xlO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdBdmF0YXIgc2hhcGUnLFxuICAgIHBhdGg6ICd1aS5zaGFwZScsXG4gICAgZGVmYXVsdDogU2hhcGUuY2lyY2xlLFxuICAgIG9wdGlvbnM6IFtTaGFwZS5jaXJjbGUsIFNoYXBlLnNxdWFyZV1cbiAgfSlcbiAgQElucHV0KCkgc2V0IHNoYXBlKHNoYXBlOiBTaGFwZSkge1xuICAgIHRoaXMuX3NoYXBlID0gc2hhcGUgfHwgU2hhcGUuY2lyY2xlO1xuICB9XG5cbiAgQE91dHB1dCgpIGxvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIGZhaWxlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBvbkNoYW5nZTogKGRhdGU6IEltYWdlQ3JvcHBlZERhdGEpID0+IHZvaWQgPSAoKSA9PiB0aGlzLmxvZ2dlci5lcnJvcigndmFsdWUgYWNjZXNzb3IgaXMgbm90IHJlZ2lzdGVyZWQnKTtcbiAgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4gdGhpcy5sb2dnZXIuZXJyb3IoJ3ZhbHVlIGFjY2Vzc29yIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIHJlZ2lzdGVyT25DaGFuZ2UgPSBmbiA9PiB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIHJlZ2lzdGVyT25Ub3VjaGVkID0gZm4gPT4gdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpIG9uQmx1ciA9ICgpID0+IHRoaXMub25Ub3VjaGVkKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBsb2dnZXI6IE5HWExvZ2dlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgICAgICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgICAgICAgICAgICBwdWJsaWMgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZm9ybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCh7em9vbX0pID0+IHRoaXMuem9vbSh6b29tKSlcbiAgfVxuXG4gIGluVmlldygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pbWFnZS5uYXRpdmVFbGVtZW50LmN1cnJlbnRTcmMuaW5jbHVkZXMoJ2ltYWdlL3N2ZycpKSB7XG4gICAgICB0aGlzLmRpc2FibGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5sb2FkZWQuZW1pdCgpO1xuICAgIHRoaXMuc2l6ZVJldHJpZXMgPSAwO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jaGVja0ltYWdlTWF4U2l6ZVJlY3Vyc2l2ZWx5KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0ltYWdlTWF4U2l6ZVJlY3Vyc2l2ZWx5KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNpemVSZXRyaWVzID4gNDApIHtcbiAgICAgIHRoaXMuZmFpbGVkLmVtaXQoKTtcbiAgICB9IGVsc2UgaWYgKCEhdGhpcy5pbWFnZSAmJiAhIXRoaXMuaW1hZ2UubmF0aXZlRWxlbWVudCAmJiB0aGlzLmltYWdlLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGggPiAwKSB7XG4gICAgICBjb25zdCBpbWFnZSA9IHRoaXMuaW1hZ2UubmF0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IHdyYXBwZXIgPSB0aGlzLndyYXBwZXIubmF0aXZlRWxlbWVudDtcbiAgICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi53aWR0aCA9IGltYWdlLm9mZnNldFdpZHRoO1xuICAgICAgdGhpcy5pbWFnZVBvc2l0aW9uLmhlaWdodCA9IGltYWdlLm9mZnNldEhlaWdodDtcbiAgICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi50b3AgPSAod3JhcHBlci5vZmZzZXRIZWlnaHQgLSBpbWFnZS5vZmZzZXRIZWlnaHQpIC8gMjtcbiAgICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi5sZWZ0ID0gKHdyYXBwZXIub2Zmc2V0V2lkdGggLSBpbWFnZS5vZmZzZXRXaWR0aCkgLyAyO1xuICAgICAgbGV0IHNjYWxlID0gTWF0aC50cnVuYyh3cmFwcGVyLm9mZnNldFdpZHRoIC8gaW1hZ2Uub2Zmc2V0V2lkdGggKiAxMDApIC8gMTAwO1xuICAgICAgc2NhbGUgPSBNYXRoLm1pbihzY2FsZSwgTWF0aC50cnVuYyh3cmFwcGVyLm9mZnNldEhlaWdodCAvIGltYWdlLm9mZnNldEhlaWdodCAqIDEwMCkgLyAxMDAsIHRoaXMubWF4KTtcbiAgICAgIHRoaXMuem9vbShzY2FsZSk7XG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zaXplUmV0cmllcysrO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNoZWNrSW1hZ2VNYXhTaXplUmVjdXJzaXZlbHkoKSwgNTApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXJ0TW92ZShldmVudDogYW55LCBtb3ZlVHlwZTogTW92ZVR5cGVzKTogdm9pZCB7XG4gICAgaWYgKCEhdGhpcy5tb3ZlU3RhcnQgJiYgdGhpcy5tb3ZlU3RhcnQuYWN0aXZlICYmIHRoaXMubW92ZVN0YXJ0LnR5cGUgPT09IE1vdmVUeXBlcy5QaW5jaCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoISFldmVudC5wcmV2ZW50RGVmYXVsdCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgdGhpcy5tb3ZlU3RhcnQgPSB7XG4gICAgICBhY3RpdmU6IHRydWUsXG4gICAgICB0eXBlOiBtb3ZlVHlwZSxcbiAgICAgIGNsaWVudFg6IHRoaXMuZ2V0Q2xpZW50WChldmVudCksXG4gICAgICBjbGllbnRZOiB0aGlzLmdldENsaWVudFkoZXZlbnQpLFxuICAgICAgLi4udGhpcy5pbWFnZVBvc2l0aW9uXG4gICAgfTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNlbW92ZScsIFsnJGV2ZW50J10pXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OnRvdWNobW92ZScsIFsnJGV2ZW50J10pXG4gIG1vdmVJbWcoZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vdmVTdGFydC5hY3RpdmUpIHtcbiAgICAgIGlmIChldmVudC5zdG9wUHJvcGFnYXRpb24pIHtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm1vdmVTdGFydC50eXBlID09PSBNb3ZlVHlwZXMuTW92ZSkge1xuICAgICAgICB0aGlzLm1vdmUoZXZlbnQpO1xuICAgICAgfVxuICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6bW91c2V1cCcpXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OnRvdWNoZW5kJylcbiAgbW92ZVN0b3AoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubW92ZVN0YXJ0LmFjdGl2ZSkge1xuICAgICAgdGhpcy5tb3ZlU3RhcnQuYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLmNyb3AoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyb3AoKSB7XG4gICAgY29uc3QgaW1hZ2UgPSB0aGlzLmltYWdlLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgY3JvcHBlciA9IHRoaXMuY3JvcHBlci5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHNjYWxlID0gdGhpcy5pbWFnZVBvc2l0aW9uLnNjYWxlO1xuICAgIHRoaXMub25DaGFuZ2Uoe1xuICAgICAgbGVmdDogTWF0aC5yb3VuZChjcm9wcGVyLm9mZnNldExlZnQgLSAoaW1hZ2Uub2Zmc2V0TGVmdCAtICgoaW1hZ2Uud2lkdGggKiBzY2FsZSAtIGltYWdlLndpZHRoKSAvIDIpKSksXG4gICAgICB0b3A6IE1hdGgucm91bmQoY3JvcHBlci5vZmZzZXRUb3AgLSAoaW1hZ2Uub2Zmc2V0VG9wIC0gKChpbWFnZS5oZWlnaHQgKiBzY2FsZSAtIGltYWdlLmhlaWdodCkgLyAyKSkpLFxuICAgICAgc2NhbGVcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZShldmVudDogTW91c2VFdmVudCkge1xuICAgIGNvbnN0IGRpZmZYID0gdGhpcy5nZXRDbGllbnRYKGV2ZW50KSAtIHRoaXMubW92ZVN0YXJ0LmNsaWVudFg7XG4gICAgY29uc3QgZGlmZlkgPSB0aGlzLmdldENsaWVudFkoZXZlbnQpIC0gdGhpcy5tb3ZlU3RhcnQuY2xpZW50WTtcblxuICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi5sZWZ0ID0gdGhpcy5tb3ZlU3RhcnQubGVmdCArIGRpZmZYO1xuICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi50b3AgPSB0aGlzLm1vdmVTdGFydC50b3AgKyBkaWZmWTtcbiAgfTtcblxuICBwcml2YXRlIGdldENsaWVudFgoZXZlbnQ6IGFueSk6IG51bWJlciB7XG4gICAgcmV0dXJuIChldmVudC50b3VjaGVzICYmIGV2ZW50LnRvdWNoZXNbMF0gPyBldmVudC50b3VjaGVzWzBdLmNsaWVudFggOiBldmVudC5jbGllbnRYKSB8fCAwO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDbGllbnRZKGV2ZW50OiBhbnkpOiBudW1iZXIge1xuICAgIHJldHVybiAoZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzWzBdID8gZXZlbnQudG91Y2hlc1swXS5jbGllbnRZIDogZXZlbnQuY2xpZW50WSkgfHwgMDtcbiAgfVxuXG4gIHpvb20oc2NhbGUgPSBERUZBVUxUX1NDQUxFKSB7XG4gICAgdGhpcy5pbWFnZVBvc2l0aW9uLnNjYWxlID0gc2NhbGU7XG4gICAgdGhpcy5pbWFnZVBvc2l0aW9uLndpZHRoID0gdGhpcy5pbWFnZVBvc2l0aW9uLndpZHRoICogc2NhbGU7XG4gICAgdGhpcy5pbWFnZVBvc2l0aW9uLmhlaWdodCA9IHRoaXMuaW1hZ2VQb3NpdGlvbi5oZWlnaHQgKiBzY2FsZTtcbiAgICB0aGlzLnRyYW5zZm9ybVN0eWxlID0gdGhpcy5zYW5pdGl6ZXJcbiAgICAgIC5ieXBhc3NTZWN1cml0eVRydXN0U3R5bGUoYHNjYWxlWCgke3NjYWxlIHx8IERFRkFVTFRfU0NBTEV9KXNjYWxlWSgke3NjYWxlIHx8IERFRkFVTFRfU0NBTEV9KWApO1xuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIHRoaXMuY3JvcCgpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZShkYXRhOiBJbWFnZUNyb3BwZWREYXRhKTogdm9pZCB7XG4gICAgaWYgKCEhZGF0YSkge1xuICAgICAgdGhpcy5pbWFnZVBvc2l0aW9uID0gey4uLnRoaXMuaW1hZ2VQb3NpdGlvbiwgLi4uZGF0YX07XG4gICAgfVxuICB9XG5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gIH1cbn1cbiJdfQ==