UNPKG

@junte/ui

Version:

Quality Angular UI components kit

344 lines 37.3 kB
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==