UNPKG

@junte/ui

Version:

Quality Angular UI components kit

380 lines 40.4 kB
import { __assign, __decorate, __metadata, __read, __spread } 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'; var CROPPER_SIZE = 200; var DEFAULT_SCALE = 1; var DEFAULT_MIN = 0.01; var DEFAULT_MAX = 5; var DEFAULT_STEP = 0.01; export var MoveTypes; (function (MoveTypes) { MoveTypes["Move"] = "move"; MoveTypes["Pinch"] = "pinch"; })(MoveTypes || (MoveTypes = {})); var MoveStart = /** @class */ (function () { function MoveStart() { this.active = false; this.type = null; this.left = 0; this.top = 0; this.clientX = 0; this.clientY = 0; } return MoveStart; }()); export { MoveStart }; var ImagePosition = /** @class */ (function () { function ImagePosition() { this.left = 0; this.top = 0; this.scale = DEFAULT_SCALE; this.width = 0; this.height = 0; } return ImagePosition; }()); export { ImagePosition }; var CropperPosition = /** @class */ (function () { function CropperPosition() { this.width = CROPPER_SIZE; this.height = CROPPER_SIZE; } return CropperPosition; }()); export { CropperPosition }; var ImageCropperComponent = /** @class */ (function () { function ImageCropperComponent(logger, cd, fb, sanitizer) { var _this = this; 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 = function () { return _this.logger.error('value accessor is not registered'); }; this.onTouched = function () { return _this.logger.error('value accessor is not registered'); }; this.registerOnChange = function (fn) { return _this.onChange = fn; }; this.registerOnTouched = function (fn) { return _this.onTouched = fn; }; this.onBlur = function () { return _this.onTouched(); }; } ImageCropperComponent_1 = ImageCropperComponent; Object.defineProperty(ImageCropperComponent.prototype, "min", { get: function () { return this._min; }, set: function (min) { this._min = min || DEFAULT_MIN; }, enumerable: true, configurable: true }); Object.defineProperty(ImageCropperComponent.prototype, "max", { get: function () { return this._max; }, set: function (max) { this._max = max || DEFAULT_MAX; }, enumerable: true, configurable: true }); Object.defineProperty(ImageCropperComponent.prototype, "step", { get: function () { return this._step; }, set: function (step) { this._step = step || DEFAULT_STEP; }, enumerable: true, configurable: true }); Object.defineProperty(ImageCropperComponent.prototype, "url", { get: function () { return this._url; }, set: function (url) { this._url = url; if (!!url) { this.moveStart = new MoveStart(); this.imagePosition = new ImagePosition(); } }, enumerable: true, configurable: true }); Object.defineProperty(ImageCropperComponent.prototype, "shape", { set: function (shape) { this._shape = shape || Shape.circle; }, enumerable: true, configurable: true }); ImageCropperComponent.prototype.ngOnInit = function () { var _this = this; this.form.valueChanges.subscribe(function (_a) { var zoom = _a.zoom; return _this.zoom(zoom); }); }; ImageCropperComponent.prototype.inView = function () { var _this = this; if (this.image.nativeElement.currentSrc.includes('image/svg')) { this.disabled = true; } this.loaded.emit(); this.sizeRetries = 0; setTimeout(function () { return _this.checkImageMaxSizeRecursively(); }); }; ImageCropperComponent.prototype.checkImageMaxSizeRecursively = function () { var _this = this; if (this.sizeRetries > 40) { this.failed.emit(); } else if (!!this.image && !!this.image.nativeElement && this.image.nativeElement.offsetWidth > 0) { var image = this.image.nativeElement; var 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; var 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(function () { return _this.checkImageMaxSizeRecursively(); }, 50); } }; ImageCropperComponent.prototype.startMove = function (event, moveType) { if (!!this.moveStart && this.moveStart.active && this.moveStart.type === MoveTypes.Pinch) { return; } if (!!event.preventDefault) { event.preventDefault(); } this.moveStart = __assign({ active: true, type: moveType, clientX: this.getClientX(event), clientY: this.getClientY(event) }, this.imagePosition); }; ImageCropperComponent.prototype.moveImg = function (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(); } }; ImageCropperComponent.prototype.moveStop = function () { if (this.moveStart.active) { this.moveStart.active = false; this.crop(); } }; ImageCropperComponent.prototype.crop = function () { var image = this.image.nativeElement; var cropper = this.cropper.nativeElement; var 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: scale }); }; ImageCropperComponent.prototype.move = function (event) { var diffX = this.getClientX(event) - this.moveStart.clientX; var diffY = this.getClientY(event) - this.moveStart.clientY; this.imagePosition.left = this.moveStart.left + diffX; this.imagePosition.top = this.moveStart.top + diffY; }; ; ImageCropperComponent.prototype.getClientX = function (event) { return (event.touches && event.touches[0] ? event.touches[0].clientX : event.clientX) || 0; }; ImageCropperComponent.prototype.getClientY = function (event) { return (event.touches && event.touches[0] ? event.touches[0].clientY : event.clientY) || 0; }; ImageCropperComponent.prototype.zoom = function (scale) { if (scale === void 0) { 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(); }; ImageCropperComponent.prototype.writeValue = function (data) { if (!!data) { this.imagePosition = __assign(__assign({}, this.imagePosition), data); } }; ImageCropperComponent.prototype.setDisabledState = function (isDisabled) { this.disabled = isDisabled; }; var ImageCropperComponent_1; ImageCropperComponent.ctorParameters = function () { return [ { 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: __spread([ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(function () { return ImageCropperComponent_1; }), multi: true } ], I18N_PROVIDERS) }), __metadata("design:paramtypes", [NGXLogger, ChangeDetectorRef, FormBuilder, DomSanitizer]) ], ImageCropperComponent); return ImageCropperComponent; }()); export { ImageCropperComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtY3JvcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AanVudGUvdWkvIiwic291cmNlcyI6WyJsaWIvZm9ybXMvaW1hZ2UtY3JvcHBlci9pbWFnZS1jcm9wcGVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxZQUFZLEVBQ1osS0FBSyxFQUFFLE1BQU0sRUFDYixNQUFNLEVBQ04sU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM3RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUUzRCxJQUFNLFlBQVksR0FBRyxHQUFHLENBQUM7QUFDekIsSUFBTSxhQUFhLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQztBQUN6QixJQUFNLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDdEIsSUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDO0FBRTFCLE1BQU0sQ0FBTixJQUFZLFNBR1g7QUFIRCxXQUFZLFNBQVM7SUFDbkIsMEJBQWEsQ0FBQTtJQUNiLDRCQUFlLENBQUE7QUFD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O1lBQ3JCLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUN0QyxDQUFDO1FBQ0QsS0FBSyxFQUFFOzs7c0RBRVA7SUFFUztRQUFULE1BQU0sRUFBRTs7eURBQW1DO0lBQ2xDO1FBQVQsTUFBTSxFQUFFOzt5REFBbUM7SUFNdEI7UUFBckIsWUFBWSxDQUFDLE1BQU0sQ0FBQzs7eURBQWlDO0lBMkR0RDtRQUZDLFlBQVksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLFlBQVksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDOzs7O3dEQWM5QztJQUlEO1FBRkMsWUFBWSxDQUFDLGtCQUFrQixDQUFDO1FBQ2hDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQzs7Ozt5REFNakM7SUFsTVUscUJBQXFCO1FBWmpDLFNBQVMsQ0FBQztZQUNULFFBQVEsRUFBRSxtQkFBbUI7WUFDN0IsdTNDQUFnRDtZQUNoRCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtZQUMvQyxTQUFTO2dCQUNQO29CQUNFLE9BQU8sRUFBRSxpQkFBaUI7b0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsY0FBTSxPQUFBLHVCQUFxQixFQUFyQixDQUFxQixDQUFDO29CQUNwRCxLQUFLLEVBQUUsSUFBSTtpQkFDWjtlQUFLLGNBQWMsQ0FDckI7U0FDRixDQUFDO3lDQW9INEIsU0FBUztZQUNiLGlCQUFpQjtZQUNqQixXQUFXO1lBQ0wsWUFBWTtPQXRIL0IscUJBQXFCLENBa1BqQztJQUFELDRCQUFDO0NBQUEsQUFsUEQsSUFrUEM7U0FsUFkscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSG9zdEJpbmRpbmcsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgRm9ybUJ1aWxkZXIsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlU3R5bGUsIFNhZmVVcmwgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IE5HWExvZ2dlciB9IGZyb20gJ25neC1sb2dnZXInO1xuaW1wb3J0IHsgUHJvcGVydHlBcGkgfSBmcm9tICcuLi8uLi9jb3JlL2RlY29yYXRvcnMvYXBpJztcbmltcG9ydCB7IFNoYXBlIH0gZnJvbSAnLi4vLi4vY29yZS9lbnVtcy9zaGFwZSc7XG5pbXBvcnQgeyBVSSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvdWknO1xuaW1wb3J0IHsgSTE4Tl9QUk9WSURFUlMgfSBmcm9tICcuLi8uLi9jb3JlL2kxOG4vcHJvdmlkZXJzJztcblxuY29uc3QgQ1JPUFBFUl9TSVpFID0gMjAwO1xuY29uc3QgREVGQVVMVF9TQ0FMRSA9IDE7XG5jb25zdCBERUZBVUxUX01JTiA9IDAuMDE7XG5jb25zdCBERUZBVUxUX01BWCA9IDU7XG5jb25zdCBERUZBVUxUX1NURVAgPSAwLjAxO1xuXG5leHBvcnQgZW51bSBNb3ZlVHlwZXMge1xuICBNb3ZlID0gJ21vdmUnLFxuICBQaW5jaCA9ICdwaW5jaCdcbn1cblxuZXhwb3J0IGNsYXNzIE1vdmVTdGFydCB7XG4gIGFjdGl2ZTogYm9vbGVhbiA9IGZhbHNlO1xuICB0eXBlOiBNb3ZlVHlwZXMgfCBudWxsID0gbnVsbDtcbiAgbGVmdDogbnVtYmVyID0gMDtcbiAgdG9wOiBudW1iZXIgPSAwO1xuICBjbGllbnRYOiBudW1iZXIgPSAwO1xuICBjbGllbnRZOiBudW1iZXIgPSAwO1xufVxuXG5leHBvcnQgY2xhc3MgSW1hZ2VQb3NpdGlvbiB7XG4gIGxlZnQ6IG51bWJlciA9IDA7XG4gIHRvcDogbnVtYmVyID0gMDtcbiAgc2NhbGU6IG51bWJlciA9IERFRkFVTFRfU0NBTEU7XG4gIHdpZHRoOiBudW1iZXIgPSAwO1xuICBoZWlnaHQ6IG51bWJlciA9IDA7XG59XG5cbmV4cG9ydCBjbGFzcyBDcm9wcGVyUG9zaXRpb24ge1xuICB3aWR0aDogbnVtYmVyID0gQ1JPUFBFUl9TSVpFO1xuICBoZWlnaHQ6IG51bWJlciA9IENST1BQRVJfU0laRTtcbn1cblxuZXhwb3J0IHR5cGUgSW1hZ2VDcm9wcGVkRGF0YSA9IHtcbiAgbGVmdDogbnVtYmVyLFxuICB0b3A6IG51bWJlcixcbiAgc2NhbGU6IG51bWJlclxufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdqbnQtaW1hZ2UtY3JvcHBlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbWFnZS1jcm9wcGVyLmVuY2Fwc3VsYXRlZC5odG1sJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gSW1hZ2VDcm9wcGVyQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfSwgLi4uSTE4Tl9QUk9WSURFUlNcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBJbWFnZUNyb3BwZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcblxuICB1aSA9IFVJO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5ob3N0JylcbiAgcmVhZG9ubHkgaG9zdCA9ICdqbnQtaW1hZ2UtY3JvcHBlci1ob3N0JztcblxuICBwcml2YXRlIG1vdmVTdGFydCA9IG5ldyBNb3ZlU3RhcnQoKTtcbiAgcHJpdmF0ZSBzaXplUmV0cmllcyA9IDA7XG4gIHByaXZhdGUgX3VybDogU2FmZVVybCB8IHN0cmluZztcbiAgcHJpdmF0ZSBfbWluID0gREVGQVVMVF9NSU47XG4gIHByaXZhdGUgX21heCA9IERFRkFVTFRfTUFYO1xuICBwcml2YXRlIF9zdGVwID0gREVGQVVMVF9TVEVQO1xuXG4gIHRyYW5zZm9ybVN0eWxlOiBTYWZlU3R5bGUgfCBzdHJpbmc7XG4gIG1hcmdpbkxlZnQ6IFNhZmVTdHlsZSB8IHN0cmluZyA9ICcwcHgnO1xuICBtb3ZlVHlwZXMgPSBNb3ZlVHlwZXM7XG4gIGltYWdlUG9zaXRpb24gPSBuZXcgSW1hZ2VQb3NpdGlvbigpO1xuXG4gIGZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICB6b29tOiBbdGhpcy5pbWFnZVBvc2l0aW9uLnNjYWxlXVxuICB9KTtcblxuICBAVmlld0NoaWxkKCd3cmFwcGVyJywge3N0YXRpYzogdHJ1ZX0pIHdyYXBwZXI6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2ltYWdlJykgaW1hZ2U6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2Nyb3BwZXInKSBjcm9wcGVyOiBFbGVtZW50UmVmO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdTaXplIG9mIGNyb3AgYXJlYScsXG4gICAgdHlwZTogJ0Nyb3BwZXJQb3NpdGlvbicsXG4gICAgZGVmYXVsdDogJ3t3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH0nXG4gIH0pXG4gIEBJbnB1dCgpIGFyZWEgPSBuZXcgQ3JvcHBlclBvc2l0aW9uKCk7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ01pbiBvZiBjcm9wcGluZycsXG4gICAgdHlwZTogJ251bWJlcicsXG4gICAgZGVmYXVsdDogJzAuMDEnXG4gIH0pXG4gIEBJbnB1dCgpIHNldCBtaW4obWluOiBudW1iZXIpIHtcbiAgICB0aGlzLl9taW4gPSBtaW4gfHwgREVGQVVMVF9NSU47XG4gIH1cblxuICBnZXQgbWluKCkge1xuICAgIHJldHVybiB0aGlzLl9taW47XG4gIH1cblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnTWF4IG9mIGNyb3BwaW5nJyxcbiAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICBkZWZhdWx0OiAnNSdcbiAgfSlcbiAgQElucHV0KCkgc2V0IG1heChtYXg6IG51bWJlcikge1xuICAgIHRoaXMuX21heCA9IG1heCB8fCBERUZBVUxUX01BWFxuICB9XG5cbiAgZ2V0IG1heCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbWF4O1xuICB9XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1N0ZXAgb2YgY3JvcHBpbmcnLFxuICAgIHR5cGU6ICdudW1iZXInLFxuICAgIGRlZmF1bHQ6ICcwLjAxJ1xuICB9KVxuICBASW5wdXQoKSBzZXQgc3RlcChzdGVwOiBudW1iZXIpIHtcbiAgICB0aGlzLl9zdGVwID0gc3RlcCB8fCBERUZBVUxUX1NURVA7XG4gIH1cblxuICBnZXQgc3RlcCgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RlcDtcbiAgfVxuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdVcmwgb2YgaW1hZ2UnLFxuICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIGRlZmF1bHQ6IG51bGxcbiAgfSlcbiAgQElucHV0KCkgc2V0IHVybCh1cmw6IFNhZmVVcmwgfCBzdHJpbmcpIHtcbiAgICB0aGlzLl91cmwgPSB1cmw7XG4gICAgaWYgKCEhdXJsKSB7XG4gICAgICB0aGlzLm1vdmVTdGFydCA9IG5ldyBNb3ZlU3RhcnQoKTtcbiAgICAgIHRoaXMuaW1hZ2VQb3NpdGlvbiA9IG5ldyBJbWFnZVBvc2l0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHVybCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdXJsO1xuICB9XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmRhdGEtZGlzYWJsZWQnKVxuICBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXNoYXBlJylcbiAgX3NoYXBlOiBTaGFwZSA9IFNoYXBlLmNpcmNsZTtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnQXZhdGFyIHNoYXBlJyxcbiAgICBwYXRoOiAndWkuc2hhcGUnLFxuICAgIGRlZmF1bHQ6IFNoYXBlLmNpcmNsZSxcbiAgICBvcHRpb25zOiBbU2hhcGUuY2lyY2xlLCBTaGFwZS5zcXVhcmVdXG4gIH0pXG4gIEBJbnB1dCgpIHNldCBzaGFwZShzaGFwZTogU2hhcGUpIHtcbiAgICB0aGlzLl9zaGFwZSA9IHNoYXBlIHx8IFNoYXBlLmNpcmNsZTtcbiAgfVxuXG4gIEBPdXRwdXQoKSBsb2FkZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBmYWlsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgb25DaGFuZ2U6IChkYXRlOiBJbWFnZUNyb3BwZWREYXRhKSA9PiB2b2lkID0gKCkgPT4gdGhpcy5sb2dnZXIuZXJyb3IoJ3ZhbHVlIGFjY2Vzc29yIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIG9uVG91Y2hlZDogKCkgPT4gdm9pZCA9ICgpID0+IHRoaXMubG9nZ2VyLmVycm9yKCd2YWx1ZSBhY2Nlc3NvciBpcyBub3QgcmVnaXN0ZXJlZCcpO1xuICByZWdpc3Rlck9uQ2hhbmdlID0gZm4gPT4gdGhpcy5vbkNoYW5nZSA9IGZuO1xuICByZWdpc3Rlck9uVG91Y2hlZCA9IGZuID0+IHRoaXMub25Ub3VjaGVkID0gZm47XG4gIEBIb3N0TGlzdGVuZXIoJ2JsdXInKSBvbkJsdXIgPSAoKSA9PiB0aGlzLm9uVG91Y2hlZCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbG9nZ2VyOiBOR1hMb2dnZXIsXG4gICAgICAgICAgICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICAgICAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICAgICAgICAgICAgcHVibGljIHNhbml0aXplcjogRG9tU2FuaXRpemVyKSB7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmZvcm0udmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgoe3pvb219KSA9PiB0aGlzLnpvb20oem9vbSkpXG4gIH1cblxuICBpblZpZXcoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW1hZ2UubmF0aXZlRWxlbWVudC5jdXJyZW50U3JjLmluY2x1ZGVzKCdpbWFnZS9zdmcnKSkge1xuICAgICAgdGhpcy5kaXNhYmxlZCA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMubG9hZGVkLmVtaXQoKTtcbiAgICB0aGlzLnNpemVSZXRyaWVzID0gMDtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuY2hlY2tJbWFnZU1heFNpemVSZWN1cnNpdmVseSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tJbWFnZU1heFNpemVSZWN1cnNpdmVseSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zaXplUmV0cmllcyA+IDQwKSB7XG4gICAgICB0aGlzLmZhaWxlZC5lbWl0KCk7XG4gICAgfSBlbHNlIGlmICghIXRoaXMuaW1hZ2UgJiYgISF0aGlzLmltYWdlLm5hdGl2ZUVsZW1lbnQgJiYgdGhpcy5pbWFnZS5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoID4gMCkge1xuICAgICAgY29uc3QgaW1hZ2UgPSB0aGlzLmltYWdlLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICBjb25zdCB3cmFwcGVyID0gdGhpcy53cmFwcGVyLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICB0aGlzLmltYWdlUG9zaXRpb24ud2lkdGggPSBpbWFnZS5vZmZzZXRXaWR0aDtcbiAgICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi5oZWlnaHQgPSBpbWFnZS5vZmZzZXRIZWlnaHQ7XG4gICAgICB0aGlzLmltYWdlUG9zaXRpb24udG9wID0gKHdyYXBwZXIub2Zmc2V0SGVpZ2h0IC0gaW1hZ2Uub2Zmc2V0SGVpZ2h0KSAvIDI7XG4gICAgICB0aGlzLmltYWdlUG9zaXRpb24ubGVmdCA9ICh3cmFwcGVyLm9mZnNldFdpZHRoIC0gaW1hZ2Uub2Zmc2V0V2lkdGgpIC8gMjtcbiAgICAgIGxldCBzY2FsZSA9IE1hdGgudHJ1bmMod3JhcHBlci5vZmZzZXRXaWR0aCAvIGltYWdlLm9mZnNldFdpZHRoICogMTAwKSAvIDEwMDtcbiAgICAgIHNjYWxlID0gTWF0aC5taW4oc2NhbGUsIE1hdGgudHJ1bmMod3JhcHBlci5vZmZzZXRIZWlnaHQgLyBpbWFnZS5vZmZzZXRIZWlnaHQgKiAxMDApIC8gMTAwLCB0aGlzLm1heCk7XG4gICAgICB0aGlzLnpvb20oc2NhbGUpO1xuICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2l6ZVJldHJpZXMrKztcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5jaGVja0ltYWdlTWF4U2l6ZVJlY3Vyc2l2ZWx5KCksIDUwKTtcbiAgICB9XG4gIH1cblxuICBzdGFydE1vdmUoZXZlbnQ6IGFueSwgbW92ZVR5cGU6IE1vdmVUeXBlcyk6IHZvaWQge1xuICAgIGlmICghIXRoaXMubW92ZVN0YXJ0ICYmIHRoaXMubW92ZVN0YXJ0LmFjdGl2ZSAmJiB0aGlzLm1vdmVTdGFydC50eXBlID09PSBNb3ZlVHlwZXMuUGluY2gpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCEhZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHRoaXMubW92ZVN0YXJ0ID0ge1xuICAgICAgYWN0aXZlOiB0cnVlLFxuICAgICAgdHlwZTogbW92ZVR5cGUsXG4gICAgICBjbGllbnRYOiB0aGlzLmdldENsaWVudFgoZXZlbnQpLFxuICAgICAgY2xpZW50WTogdGhpcy5nZXRDbGllbnRZKGV2ZW50KSxcbiAgICAgIC4uLnRoaXMuaW1hZ2VQb3NpdGlvblxuICAgIH07XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZW1vdmUnLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDp0b3VjaG1vdmUnLCBbJyRldmVudCddKVxuICBtb3ZlSW1nKGV2ZW50OiBhbnkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tb3ZlU3RhcnQuYWN0aXZlKSB7XG4gICAgICBpZiAoZXZlbnQuc3RvcFByb3BhZ2F0aW9uKSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5tb3ZlU3RhcnQudHlwZSA9PT0gTW92ZVR5cGVzLk1vdmUpIHtcbiAgICAgICAgdGhpcy5tb3ZlKGV2ZW50KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnKVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDp0b3VjaGVuZCcpXG4gIG1vdmVTdG9wKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vdmVTdGFydC5hY3RpdmUpIHtcbiAgICAgIHRoaXMubW92ZVN0YXJ0LmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgdGhpcy5jcm9wKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjcm9wKCkge1xuICAgIGNvbnN0IGltYWdlID0gdGhpcy5pbWFnZS5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGNyb3BwZXIgPSB0aGlzLmNyb3BwZXIubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBzY2FsZSA9IHRoaXMuaW1hZ2VQb3NpdGlvbi5zY2FsZTtcbiAgICB0aGlzLm9uQ2hhbmdlKHtcbiAgICAgIGxlZnQ6IE1hdGgucm91bmQoY3JvcHBlci5vZmZzZXRMZWZ0IC0gKGltYWdlLm9mZnNldExlZnQgLSAoKGltYWdlLndpZHRoICogc2NhbGUgLSBpbWFnZS53aWR0aCkgLyAyKSkpLFxuICAgICAgdG9wOiBNYXRoLnJvdW5kKGNyb3BwZXIub2Zmc2V0VG9wIC0gKGltYWdlLm9mZnNldFRvcCAtICgoaW1hZ2UuaGVpZ2h0ICogc2NhbGUgLSBpbWFnZS5oZWlnaHQpIC8gMikpKSxcbiAgICAgIHNjYWxlXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG1vdmUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBjb25zdCBkaWZmWCA9IHRoaXMuZ2V0Q2xpZW50WChldmVudCkgLSB0aGlzLm1vdmVTdGFydC5jbGllbnRYO1xuICAgIGNvbnN0IGRpZmZZID0gdGhpcy5nZXRDbGllbnRZKGV2ZW50KSAtIHRoaXMubW92ZVN0YXJ0LmNsaWVudFk7XG5cbiAgICB0aGlzLmltYWdlUG9zaXRpb24ubGVmdCA9IHRoaXMubW92ZVN0YXJ0LmxlZnQgKyBkaWZmWDtcbiAgICB0aGlzLmltYWdlUG9zaXRpb24udG9wID0gdGhpcy5tb3ZlU3RhcnQudG9wICsgZGlmZlk7XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRDbGllbnRYKGV2ZW50OiBhbnkpOiBudW1iZXIge1xuICAgIHJldHVybiAoZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzWzBdID8gZXZlbnQudG91Y2hlc1swXS5jbGllbnRYIDogZXZlbnQuY2xpZW50WCkgfHwgMDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q2xpZW50WShldmVudDogYW55KTogbnVtYmVyIHtcbiAgICByZXR1cm4gKGV2ZW50LnRvdWNoZXMgJiYgZXZlbnQudG91Y2hlc1swXSA/IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WSA6IGV2ZW50LmNsaWVudFkpIHx8IDA7XG4gIH1cblxuICB6b29tKHNjYWxlID0gREVGQVVMVF9TQ0FMRSkge1xuICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi5zY2FsZSA9IHNjYWxlO1xuICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi53aWR0aCA9IHRoaXMuaW1hZ2VQb3NpdGlvbi53aWR0aCAqIHNjYWxlO1xuICAgIHRoaXMuaW1hZ2VQb3NpdGlvbi5oZWlnaHQgPSB0aGlzLmltYWdlUG9zaXRpb24uaGVpZ2h0ICogc2NhbGU7XG4gICAgdGhpcy50cmFuc2Zvcm1TdHlsZSA9IHRoaXMuc2FuaXRpemVyXG4gICAgICAuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKGBzY2FsZVgoJHtzY2FsZSB8fCBERUZBVUxUX1NDQUxFfSlzY2FsZVkoJHtzY2FsZSB8fCBERUZBVUxUX1NDQUxFfSlgKTtcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB0aGlzLmNyb3AoKTtcbiAgfVxuXG4gIHdyaXRlVmFsdWUoZGF0YTogSW1hZ2VDcm9wcGVkRGF0YSk6IHZvaWQge1xuICAgIGlmICghIWRhdGEpIHtcbiAgICAgIHRoaXMuaW1hZ2VQb3NpdGlvbiA9IHsuLi50aGlzLmltYWdlUG9zaXRpb24sIC4uLmRhdGF9O1xuICAgIH1cbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbikge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICB9XG59XG4iXX0=