angular-upcrop
Version:
Library with upload and crop feature for Angular 6+
294 lines (284 loc) • 24 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, ViewChild, Input, Output, EventEmitter } from '@angular/core';
import { CropperComponent } from 'angular-cropperjs';
export class UpcropCropComponent {
constructor() {
this.config = {};
this.uploader = [];
this.onCropImage = new EventEmitter();
this.uploading = false;
this.current = false;
this.currentNumber = false;
}
/**
* @return {?}
*/
ngOnInit() {
}
/**
* Set cropping
* set cropping and everything to start crop
* @param {?} uploader
* @return {?}
*/
setCropping(uploader) {
//
// Disable cropping
this.current = false;
this.currentNumber = false;
//
// Set uploader
this.uploader = uploader;
//
// Set queue for crop
this.uploader.queue;
//
// Get next crop in the queue
this.goToNextCrop();
}
/**
* Unset cropping
* @return {?}
*/
unsetCropping() {
this.angularCropper.cropper.destroy();
this.current = false;
}
/**
* Go to next crop
* @return {?}
*/
goToNextCrop() {
//
// Validate file
if (!this.uploader.queue.length)
return;
//
// Update counter and file
if (this.currentNumber === false) {
this.currentNumber = 0;
}
else {
this.emitOnCropImage();
//
// Unset cropping
this.unsetCropping();
//
// Update counter
this.currentNumber++;
}
//
// Get next crop in the queue
this.current = this.uploader.queue[this.currentNumber];
/** @type {?} */
let reader = new FileReader();
//
// Callback for reader.readAsDataUrl() below
reader.onloadend = (e) => {
//
// Set _dataUrl
this.current._dataUrl = reader.result;
};
//
// Get data url
reader.readAsDataURL(this.current._file);
}
/**
* Emit on crop image
* @return {?}
*/
emitOnCropImage() {
//
// Add image data to current file
this.onCropImage.emit({
data: this.angularCropper.cropper.getData(),
file: this.currentNumber
});
}
/**
* Zoom in
* @return {?}
*/
zoomIn() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.zoom(0.1);
}
/**
* Zoom out
* @return {?}
*/
zoomOut() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.zoom(-0.1);
}
/**
* Go left
* @return {?}
*/
goLeft() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(-10, 0);
}
/**
* Go right
* @return {?}
*/
goRight() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(10, 0);
}
/**
* Go up
* @return {?}
*/
goUp() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(0, -10);
}
/**
* Go down
* @return {?}
*/
goDown() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.move(0, 10);
}
/**
* Rotate left
* @return {?}
*/
rotateLeft() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.rotate(-45);
}
/**
* Rotate right
* @return {?}
*/
rotateRight() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.rotate(45);
}
/**
* Reset
* @return {?}
*/
reset() {
//
// Validate
if (!this.angularCropper || !this.angularCropper.cropper)
return;
//
// Action
this.angularCropper.cropper.reset();
}
}
UpcropCropComponent.decorators = [
{ type: Component, args: [{
selector: 'upcrop-crop',
template: `<!-- MAIN LOAD -->
<div class="crop-loading" [fxHide]="!uploading">
<div class="spinner"></div>
</div>
<div [hidden]="uploading" class="upcrop-crop">
<h2 class="has-text-centered mat-subheading-2">Imagem {{currentNumber + 1}} de {{uploader?.queue?.length}}</h2>
<div class="crop-image-container">
<angular-cropper #angularCropper *ngIf="current && current._dataUrl" [cropperOptions]="config" [imageUrl]="current?._dataUrl"></angular-cropper>
</div>
<!--CROPPER CONTROLS-->
<div class="crop-controls" fxLayout fxLayoutAlign="center center" fxLayoutWrap *ngIf="current && current._dataUrl">
<button mat-button (click)="zoomIn()" class="mat-icon-button" aria-label="Aumentar zoom" mdTooltip="Aumentar zoom">
<mat-icon>zoom_in</mat-icon>
</button>
<button mat-button (click)="zoomOut()" class="mat-icon-button" aria-label="Diminuir zoom" mdTooltip="Diminuir zoom">
<mat-icon>zoom_out</mat-icon>
</button>
<button mat-button (click)="goLeft()" class="mat-icon-button" aria-label="Mover para esquerda" mdTooltip="Mover para esquerda">
<mat-icon>keyboard_arrow_left</mat-icon>
</button>
<button mat-button (click)="goRight()" class="mat-icon-button" aria-label="Mover para direita" mdTooltip="Mover para direita">
<mat-icon>keyboard_arrow_right</mat-icon>
</button>
<button mat-button (click)="goUp()" class="mat-icon-button" aria-label="Mover para cima" mdTooltip="Mover para cima">
<mat-icon>keyboard_arrow_up</mat-icon>
</button>
<button mat-button (click)="goDown()" class="mat-icon-button" aria-label="Mover para baixo" mdTooltip="Mover para baixo">
<mat-icon>keyboard_arrow_down</mat-icon>
</button>
<button mat-button (click)="reset()" class="mat-icon-button mat-primary" aria-label="Restaurar imagem original" mdTooltip="Restaurar imagem original">
<mat-icon>cached</mat-icon>
</button>
</div>
</div>
`,
styles: [`.crop-image-container{max-height:500px;width:100%}.crop-image-container img{max-width:100%;max-height:100%}.crop-controls{padding-top:20px;padding-bottom:20px}.crop-loading{min-height:120px;padding-top:34px;margin:100px 24px;box-sizing:border-box;flex-direction:column;max-width:100%;place-content:center;align-items:center;display:flex}.crop-loading .spinner{margin-top:-20px;border:4px solid rgba(0,0,0,.06);border-top:4px solid #2196f3;border-radius:50%;width:50px;height:50px;-webkit-animation:1.1s linear infinite spin;animation:1.1s linear infinite spin}.upcrop-crop .has-text-centered{text-align:center!important}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}} spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}`]
},] },
];
/** @nocollapse */
UpcropCropComponent.ctorParameters = () => [];
UpcropCropComponent.propDecorators = {
angularCropper: [{ type: ViewChild, args: ['angularCropper',] }],
config: [{ type: Input }],
uploader: [{ type: Input }],
onCropImage: [{ type: Output }]
};
if (false) {
/** @type {?} */
UpcropCropComponent.prototype.angularCropper;
/** @type {?} */
UpcropCropComponent.prototype.config;
/** @type {?} */
UpcropCropComponent.prototype.uploader;
/** @type {?} */
UpcropCropComponent.prototype.onCropImage;
/** @type {?} */
UpcropCropComponent.prototype.uploading;
/** @type {?} */
UpcropCropComponent.prototype.current;
/** @type {?} */
UpcropCropComponent.prototype.currentNumber;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBjcm9wLWNyb3AuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci11cGNyb3AvIiwic291cmNlcyI6WyJsaWIvdXBjcm9wLWNyb3AvdXBjcm9wLWNyb3AuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQWtEckQsTUFBTTtJQVdGO3NCQVI4QixFQUFFO3dCQUNBLEVBQUU7MkJBQ0gsSUFBSSxZQUFZLEVBQUU7eUJBRXpCLEtBQUs7dUJBQ1AsS0FBSzs2QkFDQyxLQUFLO0tBRWhCOzs7O0lBRWpCLFFBQVE7S0FDUDs7Ozs7OztJQU9ELFdBQVcsQ0FBQyxRQUFROzs7UUFJaEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7OztRQUkzQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQzs7O1FBSXpCLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDOzs7UUFJcEIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0tBQ3ZCOzs7OztJQUtELGFBQWE7UUFDVCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztLQUN4Qjs7Ozs7SUFLRCxZQUFZOzs7UUFJUixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztZQUFDLE1BQU0sQ0FBQzs7O1FBSXhDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztZQUMvQixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQztTQUMxQjtRQUFDLElBQUksQ0FBQyxDQUFDO1lBRUosSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDOzs7WUFJdkIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDOzs7WUFJckIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1NBQ3hCOzs7UUFJRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzs7UUFJdkQsSUFBSSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQzs7O1FBSTlCLE1BQU0sQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRTs7O1lBSXJCLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7U0FDekMsQ0FBQzs7O1FBSUYsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzVDOzs7OztJQUtELGVBQWU7OztRQUlYLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO1lBQ2xCLElBQUksRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUU7WUFDM0MsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhO1NBQzNCLENBQUMsQ0FBQztLQUNOOzs7OztJQUtELE1BQU07OztRQUlGLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1lBQUMsTUFBTSxDQUFDOzs7UUFJakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0tBQ3pDOzs7OztJQUtELE9BQU87OztRQUlILEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1lBQUMsTUFBTSxDQUFDOzs7UUFJakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDMUM7Ozs7O0lBS0QsTUFBTTs7O1FBSUYsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUM7WUFBQyxNQUFNLENBQUM7OztRQUlqRSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDNUM7Ozs7O0lBS0QsT0FBTzs7O1FBSUgsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUM7WUFBQyxNQUFNLENBQUM7OztRQUlqRSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0tBQzNDOzs7OztJQUtELElBQUk7OztRQUlBLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1lBQUMsTUFBTSxDQUFDOzs7UUFJakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQzVDOzs7OztJQUtELE1BQU07OztRQUlGLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1lBQUMsTUFBTSxDQUFDOzs7UUFJakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztLQUMzQzs7Ozs7SUFLRCxVQUFVOzs7UUFJTixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQztZQUFDLE1BQU0sQ0FBQzs7O1FBSWpFLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQzNDOzs7OztJQUtELFdBQVc7OztRQUlQLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1lBQUMsTUFBTSxDQUFDOzs7UUFJakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQzFDOzs7OztJQUtELEtBQUs7OztRQUlELEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDO1lBQUMsTUFBTSxDQUFDOzs7UUFJakUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7S0FDdkM7OztZQTFSSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQTJDYjtnQkFDRyxNQUFNLEVBQUUsQ0FBQyw0M0JBQTQzQixDQUFDO2FBQ3o0Qjs7Ozs7NkJBR0ksU0FBUyxTQUFDLGdCQUFnQjtxQkFDMUIsS0FBSzt1QkFDTCxLQUFLOzBCQUNMLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkLCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENyb3BwZXJDb21wb25lbnQgfSBmcm9tICdhbmd1bGFyLWNyb3BwZXJqcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAndXBjcm9wLWNyb3AnLFxuICAgIHRlbXBsYXRlOiBgPCEtLSBNQUlOIExPQUQgLS0+XG48ZGl2IGNsYXNzPVwiY3JvcC1sb2FkaW5nXCIgW2Z4SGlkZV09XCIhdXBsb2FkaW5nXCI+XG4gICAgPGRpdiBjbGFzcz1cInNwaW5uZXJcIj48L2Rpdj5cbjwvZGl2PlxuXG48ZGl2IFtoaWRkZW5dPVwidXBsb2FkaW5nXCIgY2xhc3M9XCJ1cGNyb3AtY3JvcFwiPlxuICAgIDxoMiBjbGFzcz1cImhhcy10ZXh0LWNlbnRlcmVkIG1hdC1zdWJoZWFkaW5nLTJcIj5JbWFnZW0ge3tjdXJyZW50TnVtYmVyICsgMX19IGRlIHt7dXBsb2FkZXI/LnF1ZXVlPy5sZW5ndGh9fTwvaDI+XG5cbiAgICA8ZGl2IGNsYXNzPVwiY3JvcC1pbWFnZS1jb250YWluZXJcIj5cbiAgICAgICAgPGFuZ3VsYXItY3JvcHBlciAjYW5ndWxhckNyb3BwZXIgKm5nSWY9XCJjdXJyZW50ICYmIGN1cnJlbnQuX2RhdGFVcmxcIiBbY3JvcHBlck9wdGlvbnNdPVwiY29uZmlnXCIgW2ltYWdlVXJsXT1cImN1cnJlbnQ/Ll9kYXRhVXJsXCI+PC9hbmd1bGFyLWNyb3BwZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tQ1JPUFBFUiBDT05UUk9MUy0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcm9wLWNvbnRyb2xzXCIgZnhMYXlvdXQgZnhMYXlvdXRBbGlnbj1cImNlbnRlciBjZW50ZXJcIiBmeExheW91dFdyYXAgKm5nSWY9XCJjdXJyZW50ICYmIGN1cnJlbnQuX2RhdGFVcmxcIj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIChjbGljayk9XCJ6b29tSW4oKVwiIGNsYXNzPVwibWF0LWljb24tYnV0dG9uXCIgYXJpYS1sYWJlbD1cIkF1bWVudGFyIHpvb21cIiBtZFRvb2x0aXA9XCJBdW1lbnRhciB6b29tXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+em9vbV9pbjwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiAoY2xpY2spPVwiem9vbU91dCgpXCIgY2xhc3M9XCJtYXQtaWNvbi1idXR0b25cIiBhcmlhLWxhYmVsPVwiRGltaW51aXIgem9vbVwiIG1kVG9vbHRpcD1cIkRpbWludWlyIHpvb21cIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj56b29tX291dDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiAoY2xpY2spPVwiZ29MZWZ0KClcIiBjbGFzcz1cIm1hdC1pY29uLWJ1dHRvblwiIGFyaWEtbGFiZWw9XCJNb3ZlciBwYXJhIGVzcXVlcmRhXCIgbWRUb29sdGlwPVwiTW92ZXIgcGFyYSBlc3F1ZXJkYVwiPlxuICAgICAgICAgICAgPG1hdC1pY29uPmtleWJvYXJkX2Fycm93X2xlZnQ8L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gKGNsaWNrKT1cImdvUmlnaHQoKVwiIGNsYXNzPVwibWF0LWljb24tYnV0dG9uXCIgYXJpYS1sYWJlbD1cIk1vdmVyIHBhcmEgZGlyZWl0YVwiIG1kVG9vbHRpcD1cIk1vdmVyIHBhcmEgZGlyZWl0YVwiPlxuICAgICAgICAgICAgPG1hdC1pY29uPmtleWJvYXJkX2Fycm93X3JpZ2h0PC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIChjbGljayk9XCJnb1VwKClcIiBjbGFzcz1cIm1hdC1pY29uLWJ1dHRvblwiIGFyaWEtbGFiZWw9XCJNb3ZlciBwYXJhIGNpbWFcIiBtZFRvb2x0aXA9XCJNb3ZlciBwYXJhIGNpbWFcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5rZXlib2FyZF9hcnJvd191cDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiAoY2xpY2spPVwiZ29Eb3duKClcIiBjbGFzcz1cIm1hdC1pY29uLWJ1dHRvblwiIGFyaWEtbGFiZWw9XCJNb3ZlciBwYXJhIGJhaXhvXCIgbWRUb29sdGlwPVwiTW92ZXIgcGFyYSBiYWl4b1wiPlxuICAgICAgICAgICAgPG1hdC1pY29uPmtleWJvYXJkX2Fycm93X2Rvd248L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICA8YnV0dG9uIG1hdC1idXR0b24gKGNsaWNrKT1cInJlc2V0KClcIiBjbGFzcz1cIm1hdC1pY29uLWJ1dHRvbiBtYXQtcHJpbWFyeVwiIGFyaWEtbGFiZWw9XCJSZXN0YXVyYXIgaW1hZ2VtIG9yaWdpbmFsXCIgbWRUb29sdGlwPVwiUmVzdGF1cmFyIGltYWdlbSBvcmlnaW5hbFwiPlxuICAgICAgICAgICAgPG1hdC1pY29uPmNhY2hlZDwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuPC9kaXY+XG5gLFxuICAgIHN0eWxlczogW2AuY3JvcC1pbWFnZS1jb250YWluZXJ7bWF4LWhlaWdodDo1MDBweDt3aWR0aDoxMDAlfS5jcm9wLWltYWdlLWNvbnRhaW5lciBpbWd7bWF4LXdpZHRoOjEwMCU7bWF4LWhlaWdodDoxMDAlfS5jcm9wLWNvbnRyb2xze3BhZGRpbmctdG9wOjIwcHg7cGFkZGluZy1ib3R0b206MjBweH0uY3JvcC1sb2FkaW5ne21pbi1oZWlnaHQ6MTIwcHg7cGFkZGluZy10b3A6MzRweDttYXJnaW46MTAwcHggMjRweDtib3gtc2l6aW5nOmJvcmRlci1ib3g7ZmxleC1kaXJlY3Rpb246Y29sdW1uO21heC13aWR0aDoxMDAlO3BsYWNlLWNvbnRlbnQ6Y2VudGVyO2FsaWduLWl0ZW1zOmNlbnRlcjtkaXNwbGF5OmZsZXh9LmNyb3AtbG9hZGluZyAuc3Bpbm5lcnttYXJnaW4tdG9wOi0yMHB4O2JvcmRlcjo0cHggc29saWQgcmdiYSgwLDAsMCwuMDYpO2JvcmRlci10b3A6NHB4IHNvbGlkICMyMTk2ZjM7Ym9yZGVyLXJhZGl1czo1MCU7d2lkdGg6NTBweDtoZWlnaHQ6NTBweDstd2Via2l0LWFuaW1hdGlvbjoxLjFzIGxpbmVhciBpbmZpbml0ZSBzcGluO2FuaW1hdGlvbjoxLjFzIGxpbmVhciBpbmZpbml0ZSBzcGlufS51cGNyb3AtY3JvcCAuaGFzLXRleHQtY2VudGVyZWR7dGV4dC1hbGlnbjpjZW50ZXIhaW1wb3J0YW50fUAtd2Via2l0LWtleWZyYW1lcyBzcGluezAley13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgwKTt0cmFuc2Zvcm06cm90YXRlKDApfTEwMCV7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDM2MGRlZyk7dHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpfX1Aa2V5ZnJhbWVzIHNwaW57MCV7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDApO3RyYW5zZm9ybTpyb3RhdGUoMCl9MTAwJXstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKTt0cmFuc2Zvcm06cm90YXRlKDM2MGRlZyl9fWBdXG59KVxuZXhwb3J0IGNsYXNzIFVwY3JvcENyb3BDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gICAgQFZpZXdDaGlsZCgnYW5ndWxhckNyb3BwZXInKSBwdWJsaWMgYW5ndWxhckNyb3BwZXI6IENyb3BwZXJDb21wb25lbnQ7XG4gICAgQElucHV0KCkgcHVibGljIGNvbmZpZzogYW55ID0ge307XG4gICAgQElucHV0KCkgcHVibGljIHVwbG9hZGVyOiBhbnkgPSBbXTtcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uQ3JvcEltYWdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgcHVibGljIHVwbG9hZGluZzogYW55ID0gZmFsc2U7XG4gICAgcHVibGljIGN1cnJlbnQ6IGFueSA9IGZhbHNlO1xuICAgIHB1YmxpYyBjdXJyZW50TnVtYmVyOiBhbnkgPSBmYWxzZTtcblxuICAgIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgY3JvcHBpbmdcbiAgICAgKiBzZXQgY3JvcHBpbmcgYW5kIGV2ZXJ5dGhpbmcgdG8gc3RhcnQgY3JvcFxuICAgICAqIEBwYXJhbSB1cGxvYWRlclxuICAgICAqL1xuICAgIHNldENyb3BwaW5nKHVwbG9hZGVyKSB7XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gRGlzYWJsZSBjcm9wcGluZ1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jdXJyZW50TnVtYmVyID0gZmFsc2U7XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gU2V0IHVwbG9hZGVyXG4gICAgICAgIHRoaXMudXBsb2FkZXIgPSB1cGxvYWRlcjtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBTZXQgcXVldWUgZm9yIGNyb3BcbiAgICAgICAgdGhpcy51cGxvYWRlci5xdWV1ZTtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBHZXQgbmV4dCBjcm9wIGluIHRoZSBxdWV1ZVxuICAgICAgICB0aGlzLmdvVG9OZXh0Q3JvcCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVuc2V0IGNyb3BwaW5nXG4gICAgICovXG4gICAgdW5zZXRDcm9wcGluZygpIHtcbiAgICAgICAgdGhpcy5hbmd1bGFyQ3JvcHBlci5jcm9wcGVyLmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gdG8gbmV4dCBjcm9wXG4gICAgICovXG4gICAgZ29Ub05leHRDcm9wKCkge1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFZhbGlkYXRlIGZpbGVcbiAgICAgICAgaWYgKCF0aGlzLnVwbG9hZGVyLnF1ZXVlLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFVwZGF0ZSBjb3VudGVyIGFuZCBmaWxlXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnROdW1iZXIgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnROdW1iZXIgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICB0aGlzLmVtaXRPbkNyb3BJbWFnZSgpO1xuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gVW5zZXQgY3JvcHBpbmdcbiAgICAgICAgICAgIHRoaXMudW5zZXRDcm9wcGluZygpO1xuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gVXBkYXRlIGNvdW50ZXJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudE51bWJlcisrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gR2V0IG5leHQgY3JvcCBpbiB0aGUgcXVldWVcbiAgICAgICAgdGhpcy5jdXJyZW50ID0gdGhpcy51cGxvYWRlci5xdWV1ZVt0aGlzLmN1cnJlbnROdW1iZXJdO1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFNldCBpbWFnZSBkYXRhIHVybFxuICAgICAgICBsZXQgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBDYWxsYmFjayBmb3IgcmVhZGVyLnJlYWRBc0RhdGFVcmwoKSBiZWxvd1xuICAgICAgICByZWFkZXIub25sb2FkZW5kID0gKGUpID0+IHtcblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIFNldCBfZGF0YVVybFxuICAgICAgICAgICAgdGhpcy5jdXJyZW50Ll9kYXRhVXJsID0gcmVhZGVyLnJlc3VsdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBHZXQgZGF0YSB1cmxcbiAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwodGhpcy5jdXJyZW50Ll9maWxlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbWl0IG9uIGNyb3AgaW1hZ2VcbiAgICAgKi9cbiAgICBlbWl0T25Dcm9wSW1hZ2UoKSB7XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQWRkIGltYWdlIGRhdGEgdG8gY3VycmVudCBmaWxlXG4gICAgICAgIHRoaXMub25Dcm9wSW1hZ2UuZW1pdCh7XG4gICAgICAgICAgICBkYXRhOiB0aGlzLmFuZ3VsYXJDcm9wcGVyLmNyb3BwZXIuZ2V0RGF0YSgpLFxuICAgICAgICAgICAgZmlsZTogdGhpcy5jdXJyZW50TnVtYmVyXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFpvb20gaW5cbiAgICAgKi9cbiAgICB6b29tSW4oKSB7XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gVmFsaWRhdGVcbiAgICAgICAgaWYgKCF0aGlzLmFuZ3VsYXJDcm9wcGVyIHx8ICF0aGlzLmFuZ3VsYXJDcm9wcGVyLmNyb3BwZXIpIHJldHVybjtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBBY3Rpb25cbiAgICAgICAgdGhpcy5hbmd1bGFyQ3JvcHBlci5jcm9wcGVyLnpvb20oMC4xKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBab29tIG91dFxuICAgICAqL1xuICAgIHpvb21PdXQoKSB7XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gVmFsaWRhdGVcbiAgICAgICAgaWYgKCF0aGlzLmFuZ3VsYXJDcm9wcGVyIHx8ICF0aGlzLmFuZ3VsYXJDcm9wcGVyLmNyb3BwZXIpIHJldHVybjtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBBY3Rpb25cbiAgICAgICAgdGhpcy5hbmd1bGFyQ3JvcHBlci5jcm9wcGVyLnpvb20oLTAuMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gbGVmdFxuICAgICAqL1xuICAgIGdvTGVmdCgpIHtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBWYWxpZGF0ZVxuICAgICAgICBpZiAoIXRoaXMuYW5ndWxhckNyb3BwZXIgfHwgIXRoaXMuYW5ndWxhckNyb3BwZXIuY3JvcHBlcikgcmV0dXJuO1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEFjdGlvblxuICAgICAgICB0aGlzLmFuZ3VsYXJDcm9wcGVyLmNyb3BwZXIubW92ZSgtMTAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdvIHJpZ2h0XG4gICAgICovXG4gICAgZ29SaWdodCgpIHtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBWYWxpZGF0ZVxuICAgICAgICBpZiAoIXRoaXMuYW5ndWxhckNyb3BwZXIgfHwgIXRoaXMuYW5ndWxhckNyb3BwZXIuY3JvcHBlcikgcmV0dXJuO1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEFjdGlvblxuICAgICAgICB0aGlzLmFuZ3VsYXJDcm9wcGVyLmNyb3BwZXIubW92ZSgxMCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gdXBcbiAgICAgKi9cbiAgICBnb1VwKCkge1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFZhbGlkYXRlXG4gICAgICAgIGlmICghdGhpcy5hbmd1bGFyQ3JvcHBlciB8fCAhdGhpcy5hbmd1bGFyQ3JvcHBlci5jcm9wcGVyKSByZXR1cm47XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQWN0aW9uXG4gICAgICAgIHRoaXMuYW5ndWxhckNyb3BwZXIuY3JvcHBlci5tb3ZlKDAsIC0xMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gZG93blxuICAgICAqL1xuICAgIGdvRG93bigpIHtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBWYWxpZGF0ZVxuICAgICAgICBpZiAoIXRoaXMuYW5ndWxhckNyb3BwZXIgfHwgIXRoaXMuYW5ndWxhckNyb3BwZXIuY3JvcHBlcikgcmV0dXJuO1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEFjdGlvblxuICAgICAgICB0aGlzLmFuZ3VsYXJDcm9wcGVyLmNyb3BwZXIubW92ZSgwLCAxMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUm90YXRlIGxlZnRcbiAgICAgKi9cbiAgICByb3RhdGVMZWZ0KCkge1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFZhbGlkYXRlXG4gICAgICAgIGlmICghdGhpcy5hbmd1bGFyQ3JvcHBlciB8fCAhdGhpcy5hbmd1bGFyQ3JvcHBlci5jcm9wcGVyKSByZXR1cm47XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQWN0aW9uXG4gICAgICAgIHRoaXMuYW5ndWxhckNyb3BwZXIuY3JvcHBlci5yb3RhdGUoLTQ1KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSb3RhdGUgcmlnaHRcbiAgICAgKi9cbiAgICByb3RhdGVSaWdodCgpIHtcblxuICAgICAgICAvL1xuICAgICAgICAvLyBWYWxpZGF0ZVxuICAgICAgICBpZiAoIXRoaXMuYW5ndWxhckNyb3BwZXIgfHwgIXRoaXMuYW5ndWxhckNyb3BwZXIuY3JvcHBlcikgcmV0dXJuO1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEFjdGlvblxuICAgICAgICB0aGlzLmFuZ3VsYXJDcm9wcGVyLmNyb3BwZXIucm90YXRlKDQ1KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNldFxuICAgICAqL1xuICAgIHJlc2V0KCkge1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFZhbGlkYXRlXG4gICAgICAgIGlmICghdGhpcy5hbmd1bGFyQ3JvcHBlciB8fCAhdGhpcy5hbmd1bGFyQ3JvcHBlci5jcm9wcGVyKSByZXR1cm47XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQWN0aW9uXG4gICAgICAgIHRoaXMuYW5ndWxhckNyb3BwZXIuY3JvcHBlci5yZXNldCgpO1xuICAgIH1cbn1cbiJdfQ==