ng-feedback
Version:
An angular directive for sending feedback featuring Angular 6, Html2canvas, Angular Material, Rxjs, inspired by Google send feedback, based on angular-cli.
966 lines • 103 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('html2canvas'), require('rxjs'), require('rxjs/operators'), require('@angular/material'), require('@angular/cdk/overlay'), require('@angular/common'), require('@angular/forms')) :
typeof define === 'function' && define.amd ? define('ng-feedback', ['exports', '@angular/core', 'html2canvas', 'rxjs', 'rxjs/operators', '@angular/material', '@angular/cdk/overlay', '@angular/common', '@angular/forms'], factory) :
(factory((global['ng-feedback'] = {}),global.ng.core,global.html2canvas,global.rxjs,global.rxjs.operators,global.ng.material,global.ng.cdk.overlay,global.ng.common,global.ng.forms));
}(this, (function (exports,core,html2canvas,rxjs,operators,material,overlay,common,forms) { 'use strict';
html2canvas = html2canvas && html2canvas.hasOwnProperty('default') ? html2canvas['default'] : html2canvas;
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var Feedback = /** @class */ (function () {
function Feedback() {
}
return Feedback;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var FeedbackService = /** @class */ (function () {
function FeedbackService() {
this.initialVariables = {};
this.highlightedColor = 'yellow';
this.hiddenColor = 'black';
this.screenshotCanvasSource = new rxjs.Subject();
this.screenshotCanvas$ = this.screenshotCanvasSource.asObservable();
this.feedbackSource = new rxjs.Subject();
this.feedback$ = this.feedbackSource.asObservable();
this.isDraggingToolbarSource = new rxjs.Subject();
this.isDraggingToolbar$ = this.isDraggingToolbarSource.asObservable();
}
/**
* @return {?}
*/
FeedbackService.prototype.initScreenshotCanvas = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var body = document.body;
html2canvas(body, {
logging: false,
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
x: document.documentElement.scrollLeft,
y: document.documentElement.scrollTop,
allowTaint: true
}).then(function (bodyCanvas) {
_this.screenshotCanvasSource.next(bodyCanvas);
});
};
/**
* @param {?} canvas
* @return {?}
*/
FeedbackService.prototype.setCanvas = /**
* @param {?} canvas
* @return {?}
*/
function (canvas) {
this.screenshotCanvasSource.next(canvas);
};
/**
* @param {?} feedback
* @return {?}
*/
FeedbackService.prototype.setFeedback = /**
* @param {?} feedback
* @return {?}
*/
function (feedback) {
this.feedbackSource.next(feedback);
};
/**
* @param {?} isDragging
* @return {?}
*/
FeedbackService.prototype.setIsDraggingToolbar = /**
* @param {?} isDragging
* @return {?}
*/
function (isDragging) {
this.isDraggingToolbarSource.next(isDragging);
};
/**
* @param {?} canvas
* @return {?}
*/
FeedbackService.prototype.getImgEle = /**
* @param {?} canvas
* @return {?}
*/
function (canvas) {
/** @type {?} */
var img = canvas.toDataURL('image/png');
/** @type {?} */
var imageEle = document.createElement('img');
imageEle.setAttribute('src', img);
Object.assign(imageEle.style, {
position: 'absolute',
top: '50%',
right: '0',
left: '0',
margin: '0 auto',
maxHeight: '100%',
maxWidth: '100%',
transform: 'translateY(-50%)'
});
return imageEle;
};
/**
* @return {?}
*/
FeedbackService.prototype.hideBackDrop = /**
* @return {?}
*/
function () {
/** @type {?} */
var dialogBackDrop = /** @type {?} */ (document.getElementsByClassName('dialogBackDrop')[0]);
dialogBackDrop.style.backgroundColor = 'initial';
};
/**
* @return {?}
*/
FeedbackService.prototype.showBackDrop = /**
* @return {?}
*/
function () {
/** @type {?} */
var dialogBackDrop = /** @type {?} */ (document.getElementsByClassName('dialogBackDrop')[0]);
if (!dialogBackDrop.getAttribute('data-html2canvas-ignore')) {
dialogBackDrop.setAttribute('data-html2canvas-ignore', 'true');
}
dialogBackDrop.style.backgroundColor = 'rgba(0, 0, 0, .288)';
};
FeedbackService.decorators = [
{ type: core.Injectable }
];
return FeedbackService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var Rectangle = /** @class */ (function () {
function Rectangle() {
this.windowScrollY = window.scrollY;
this.windowScrollX = window.scrollX;
}
return Rectangle;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var FeedbackDialogComponent = /** @class */ (function () {
function FeedbackDialogComponent(dialogRef, feedbackService, detector, el) {
this.dialogRef = dialogRef;
this.feedbackService = feedbackService;
this.detector = detector;
this.el = el;
this.showToolbar = false;
this.vars = {};
this.feedback = new Feedback();
this.includeScreenshot = true;
this.showSpinner = true;
this.showToolbarTips = true;
this.drawColor = this.feedbackService.highlightedColor;
this.rectangles = [];
this.scrollWidth = document.documentElement.scrollWidth;
this.scrollHeight = document.documentElement.scrollHeight;
this.elCouldBeHighlighted = ['button', 'a', 'span', 'em', 'i', 'h1', 'h2', 'h3', 'h4',
'h5', 'h6', 'p', 'strong', 'small', 'sub', 'sup', 'b', 'time', 'img',
'video', 'input', 'label', 'select', 'textarea', 'article', 'summary', 'section'];
this.isDrawingRect = false;
this.feedback = new Feedback();
this.feedback.description = '';
this.vars = this.feedbackService.initialVariables;
}
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
this.feedbackService.screenshotCanvas$.subscribe(function (canvas) {
_this.showSpinner = false;
_this.feedback.screenshot = canvas.toDataURL('image/png');
_this.screenshotEle = _this.feedbackService.getImgEle(canvas);
_this.appendScreenshot();
});
this.feedbackService.isDraggingToolbar$.subscribe(function (isDragging) {
if (isDragging) {
_this.destroyCanvasListeners();
}
else {
_this.addCanvasListeners();
}
});
this.dialogRef.afterClosed().subscribe(function (sendNow) {
if (sendNow === true) {
_this.feedbackService.setFeedback(_this.feedback);
}
});
this.feedbackService.showBackDrop();
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.expandDrawingBoard = /**
* @return {?}
*/
function () {
this.showToolbar = true;
if (!this.drawCanvas) {
this.detector.detectChanges();
this.initBackgroundCanvas();
this.feedbackService.hideBackDrop();
}
this.addCanvasListeners();
this.el.nativeElement.appendChild(this.drawCanvas);
this.feedbackService.hideBackDrop();
console.log('expand the board');
};
/**
* @param {?} evt
* @return {?}
*/
FeedbackDialogComponent.prototype.onEscapeKeyDownHandler = /**
* @param {?} evt
* @return {?}
*/
function (evt) {
this.showToolbar = false;
this.includeScreenshot = true;
this.detector.detectChanges();
this.dialogRef.close('key down esc to close');
};
/**
* @param {?} manipulation
* @return {?}
*/
FeedbackDialogComponent.prototype.manipulate = /**
* @param {?} manipulation
* @return {?}
*/
function (manipulation) {
if (manipulation === 'done') {
this.showToolbarTips = false;
this.showSpinner = true;
this.destroyCanvasListeners();
this.showToolbar = false;
this.detector.detectChanges();
this.feedbackService.initScreenshotCanvas();
}
else {
this.startDraw(manipulation);
}
};
/**
* @param {?} color
* @return {?}
*/
FeedbackDialogComponent.prototype.startDraw = /**
* @param {?} color
* @return {?}
*/
function (color) {
this.drawColor = color;
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.isIncludeScreenshot = /**
* @return {?}
*/
function () {
if (this.includeScreenshot) {
this.detector.detectChanges();
this.showSpinner = false;
this.appendScreenshot();
this.feedback.screenshot = this.screenshotEle.getAttribute('src');
}
else {
delete this.feedback['screenshot'];
this.showSpinner = true;
}
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.appendScreenshot = /**
* @return {?}
*/
function () {
if (this.screenshotParent) {
this.screenshotParent.nativeElement.appendChild(this.screenshotEle);
}
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.initBackgroundCanvas = /**
* @return {?}
*/
function () {
this.drawCanvas = /** @type {?} */ (document.getElementById('draw-canvas'));
// The canvas to draw, must use this way to initial the height and width
this.drawCanvas.style.height = this.scrollHeight + '';
this.drawCanvas.style.width = this.scrollWidth + '';
this.drawCanvas.height = this.scrollHeight;
this.drawCanvas.width = this.scrollWidth;
this.drawContainerRect();
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.drawContainerRect = /**
* @return {?}
*/
function () {
/** @type {?} */
var drawContext = this.drawCanvas.getContext('2d');
/** @type {?} */
var width = this.scrollWidth;
/** @type {?} */
var height = this.scrollHeight;
drawContext.beginPath();
drawContext.fillStyle = 'rgba(0,0,0,0.3)';
drawContext.clearRect(0, 0, width, height);
drawContext.fillRect(0, 0, width, height); // draw the rectangle
};
/**
* @param {?} rect
* @return {?}
*/
FeedbackDialogComponent.prototype.drawRectangle = /**
* @param {?} rect
* @return {?}
*/
function (rect) {
var _this = this;
/** @type {?} */
var context = this.drawCanvas.getContext('2d');
context.lineJoin = 'round';
context.beginPath();
if (rect.color === this.feedbackService.hiddenColor) {
context.fillStyle = 'rgba(31, 31, 31, 0.75)';
context.fillRect(rect.startX, rect.startY, rect.width, rect.height);
context.rect(rect.startX, rect.startY, rect.width, rect.height);
}
else {
context.clearRect(rect.startX, rect.startY, rect.width, rect.height);
context.lineWidth = 5;
context.strokeStyle = rect.color;
context.rect(rect.startX, rect.startY, rect.width, rect.height);
context.stroke();
context.clearRect(rect.startX, rect.startY, rect.width, rect.height);
this.rectangles.forEach(function (tmpRect) {
if (tmpRect.color === _this.feedbackService.highlightedColor) {
context.clearRect(tmpRect.startX, tmpRect.startY, tmpRect.width, tmpRect.height);
}
});
}
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.addCanvasListeners = /**
* @return {?}
*/
function () {
/** @type {?} */
var mouseUp = rxjs.fromEvent(document.documentElement, 'mouseup');
/** @type {?} */
var mouseMove = rxjs.fromEvent(document.documentElement, 'mousemove');
/** @type {?} */
var mouseDown = rxjs.fromEvent(document.documentElement, 'mousedown');
/** @type {?} */
var scroll = rxjs.fromEvent(window, 'scroll');
this.manuallyDrawRect(mouseDown, mouseMove, mouseUp);
this.autoDrawRect(mouseMove);
this.changeRectPosition(scroll);
};
/**
* @param {?} scroll
* @return {?}
*/
FeedbackDialogComponent.prototype.changeRectPosition = /**
* @param {?} scroll
* @return {?}
*/
function (scroll) {
var _this = this;
scroll.subscribe(function (event) {
/** @type {?} */
var currentWindowScrollX = window.scrollX;
/** @type {?} */
var currentWindowScrollY = window.scrollY;
_this.rectangles.forEach(function (rect) {
rect.startY = rect.startY - (currentWindowScrollY - rect.windowScrollY);
rect.startX = rect.startX - (currentWindowScrollX - rect.windowScrollX);
rect.windowScrollY = currentWindowScrollY;
rect.windowScrollX = currentWindowScrollX;
});
_this.drawPersistCanvasRectangles();
}, function (error) { return console.error(error); });
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.destroyCanvasListeners = /**
* @return {?}
*/
function () {
if (this.manuallyDrawRect$) {
this.manuallyDrawRect$.unsubscribe();
}
if (this.autoDrawRect$) {
this.autoDrawRect$.unsubscribe();
}
};
/**
* @param {?} mouseDown
* @param {?} mouseMove
* @param {?} mouseUp
* @return {?}
*/
FeedbackDialogComponent.prototype.manuallyDrawRect = /**
* @param {?} mouseDown
* @param {?} mouseMove
* @param {?} mouseUp
* @return {?}
*/
function (mouseDown, mouseMove, mouseUp) {
var _this = this;
/** @type {?} */
var mouseDrag = mouseDown.pipe(operators.mergeMap(function (mouseDownEvent) {
if (_this.showToolbarTips) {
_this.showToolbarTips = false;
}
_this.autoDrawRect$.unsubscribe();
_this.isDrawingRect = true;
/** @type {?} */
var newRectangle = new Rectangle();
newRectangle.startX = mouseDownEvent.clientX;
newRectangle.startY = mouseDownEvent.clientY;
newRectangle.color = _this.drawColor;
return mouseMove.pipe(operators.map(function (mouseMoveEvent) {
newRectangle.width = mouseMoveEvent.clientX - mouseDownEvent.clientX;
newRectangle.height = mouseMoveEvent.clientY - mouseDownEvent.clientY;
return newRectangle;
}), operators.finalize(function () {
// click to draw rectangle
if (newRectangle.width === undefined || newRectangle.height === undefined ||
newRectangle.width === 0 || newRectangle.height === 0) {
/** @type {?} */
var rect = _this.drawTempCanvasRectangle(mouseDownEvent);
if (rect) {
_this.rectangles.push(rect);
}
}
else {
// drag to draw rectangle
if (newRectangle.height < 0) {
newRectangle.startY = newRectangle.startY + newRectangle.height;
newRectangle.height = Math.abs(newRectangle.height);
}
if (newRectangle.width < 0) {
newRectangle.startX = newRectangle.startX + newRectangle.width;
newRectangle.width = Math.abs(newRectangle.width);
}
_this.rectangles.push(newRectangle);
}
_this.drawPersistCanvasRectangles();
_this.autoDrawRect(mouseMove);
_this.isDrawingRect = false;
}), operators.takeUntil(mouseUp));
}));
this.manuallyDrawRect$ = mouseDrag.subscribe(function (rec) {
_this.drawPersistCanvasRectangles();
_this.drawRectangle(rec);
});
};
/**
* @param {?} mouseMove
* @return {?}
*/
FeedbackDialogComponent.prototype.autoDrawRect = /**
* @param {?} mouseMove
* @return {?}
*/
function (mouseMove) {
var _this = this;
this.autoDrawRect$ = mouseMove.subscribe({
next: function (mouseMoveEvent) {
_this.drawPersistCanvasRectangles();
_this.drawTempCanvasRectangle(mouseMoveEvent);
},
error: function (err) { return console.error('something wrong occurred: ' + err); },
});
};
/**
* @return {?}
*/
FeedbackDialogComponent.prototype.drawPersistCanvasRectangles = /**
* @return {?}
*/
function () {
var _this = this;
this.drawContainerRect();
this.rectangles.forEach(function (tmpRect) {
_this.drawRectangle(tmpRect);
});
};
/**
* @param {?} event
* @return {?}
*/
FeedbackDialogComponent.prototype.drawTempCanvasRectangle = /**
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var rectangle = null;
/** @type {?} */
var clientX = event.clientX;
/** @type {?} */
var clientY = event.clientY;
/** @type {?} */
var els = document.elementsFromPoint(clientX, clientY);
/** @type {?} */
var el = els[2];
if ((!this.isExcludeRect(els)) && el && this.elCouldBeHighlighted.indexOf(el.nodeName.toLowerCase()) > -1) {
rectangle = new Rectangle();
/** @type {?} */
var rect = el.getBoundingClientRect();
this.drawCanvas.style.cursor = 'pointer';
Object.assign(rectangle, {
startX: rect.left,
startY: rect.top,
width: rect.width,
height: rect.height,
color: this.drawColor
});
this.drawRectangle(rectangle);
}
else {
this.drawCanvas.style.cursor = 'crosshair';
}
return rectangle;
};
/**
* @param {?} index
* @return {?}
*/
FeedbackDialogComponent.prototype.closeRect = /**
* @param {?} index
* @return {?}
*/
function (index) {
this.rectangles.splice(index, 1);
this.drawPersistCanvasRectangles();
};
/**
* @param {?} elements
* @return {?}
*/
FeedbackDialogComponent.prototype.isExcludeRect = /**
* @param {?} elements
* @return {?}
*/
function (elements) {
/** @type {?} */
var result = elements.some(function (el) {
return el.getAttribute('exclude-rect') === 'true';
});
return result;
};
FeedbackDialogComponent.decorators = [
{ type: core.Component, args: [{
selector: 'feedback-dialog',
template: "<div class=\"dialog\" *ngIf=\"!showToolbar\" data-html2canvas-ignore=\"true\">\r\n <div class=\"dialog-title\">\r\n <div class=\"title-font\">\r\n {{vars['title']}}\r\n </div>\r\n </div>\r\n <div class=\"dialog-content\">\r\n <div class=\"description-tips\">\r\n <div *ngIf=\"feedback.description==''\">{{vars['placeholder']}}</div>\r\n </div>\r\n <textarea\r\n autofocus\r\n class=\"description\"\r\n [(ngModel)]=\"feedback.description\"\r\n ></textarea>\r\n </div>\r\n <div class=\"screenshot-checkbox\">\r\n <mat-checkbox [(ngModel)]=\"includeScreenshot\" (change)=\"isIncludeScreenshot()\">{{vars['checkboxLabel']}}</mat-checkbox>\r\n </div>\r\n\r\n <div #screenshotParent class=\"screenshot-content\" (click)=\"expandDrawingBoard()\" *ngIf=\"includeScreenshot\">\r\n <mat-spinner class=\"loading\" [diameter]=\"30\" ></mat-spinner>\r\n <div></div>\r\n <div class=\"screenshot-tips\" *ngIf=\"!showSpinner\">\r\n <svg focusable=\"false\" aria-label=\"\" viewBox=\"0 0 24 24\">\r\n <path\r\n d=\"M21 17h-2.58l2.51 2.56c-.18.69-.73 1.26-1.41 1.44L17 18.5V21h-2v-6h6v2zM19 7h2v2h-2V7zm2-2h-2V3.08c1.1 0 2 .92 2 1.92zm-6-2h2v2h-2V3zm4 8h2v2h-2v-2zM9 21H7v-2h2v2zM5 9H3V7h2v2zm0-5.92V5H3c0-1 1-1.92 2-1.92zM5 17H3v-2h2v2zM9 5H7V3h2v2zm4 0h-2V3h2v2zm0 16h-2v-2h2v2zm-8-8H3v-2h2v2zm0 8.08C3.9 21.08 3 20 3 19h2v2.08z\"></path>\r\n </svg>\r\n <span class=\"screenshot-tips-content\">{{vars['editTip']}}</span>\r\n </div>\r\n </div>\r\n\r\n <mat-dialog-actions class=\"dialog-actions\" align=\"end\">\r\n <button mat-button (click)=\"dialogRef.close()\" class=\"action-button\">{{vars['cancelLabel']}}</button>\r\n <button mat-button (click)=\"dialogRef.close(true)\" class=\"submit-button action-button\">{{vars['sendLabel']}}</button>\r\n </mat-dialog-actions>\r\n</div>\r\n<div *ngIf=\"showToolbar\" data-html2canvas-ignore=\"true\">\r\n <div class=\"toolbar-tips\" *ngIf=\"showToolbarTips\">\r\n {{vars['drawRectTip']}}\r\n </div>\r\n\r\n <feedback-toolbar [drawColor]=\"drawColor\" (manipulate)=\"manipulate($event)\"></feedback-toolbar>\r\n</div>\r\n<div *ngFor=\"let rectangle of rectangles; index as index\" >\r\n <feedback-rectangle [rectangle]=\"rectangle\" [noHover]=\"!showToolbar || isDrawingRect\" (close)=\"closeRect(index)\">\r\n </feedback-rectangle>\r\n</div>\r\n<canvas id=\"draw-canvas\" class=\"drawCanvas\" [ngClass]=\"{'pointerCursor': !showToolbar}\"></canvas>\r\n",
styles: [".dialog{z-index:1000;position:relative;width:360px;background-color:#fff}.dialog-title{background-color:#607d8b;color:#fff;height:56px}.title-font{color:#fff;float:left;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:20px;line-height:56px;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;padding:0 16px;margin:0}.dialog-content{display:-webkit-flex;flex-grow:1;height:200px;position:relative}.description{border:none;box-sizing:border-box;box-shadow:none;color:#212121;flex-grow:1;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:16px;line-height:normal;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;max-width:100%;outline:0;padding:18px 16px 0;resize:none;width:100%;height:inherit}.description-tips{color:#bdbdbd;display:block;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:16px;line-height:normal;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;left:0;position:absolute;padding:18px 16px 0;right:0}.screenshot-checkbox{padding:0 16px;background-color:#f8f8f8;height:40px;display:flex;flex-direction:column;justify-content:center}.screenshot-content{border:none;cursor:pointer;text-align:center;display:block;position:relative;padding:0;overflow:hidden;height:192px;width:100%;background:#ededed}.screenshot-tips{align-items:center;background-color:rgba(248,248,248,.6);border-radius:4px;box-sizing:border-box;display:-webkit-flex;flex-direction:column;justify-content:center;min-height:112px;width:224px;z-index:5;position:absolute;top:50%;right:0;bottom:0;left:0;-webkit-transform:translateY(-50%);transform:translateY(-50%);margin:0 auto}.screenshot-content:hover .screenshot-tips{background-color:rgba(248,248,248,.8)}.screenshot-content:hover .screenshot-tips-content{color:#4285f4}.screenshot-content:hover svg{color:#4285f4;fill:currentColor}.screenshot-tips svg{color:#757575;fill:currentColor;height:48px;width:48px}.screenshot-tips-content{color:#757575;font-weight:400;font-size:14px;line-height:20px;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;margin-top:12px}.dialog-actions{border-top:1px solid #e0e0e0}.submit-button{margin-right:8px!important;margin-left:5px!important;color:#4285f4}.action-button{font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:14px;height:35px;line-height:normal;margin:10px 0;padding:0 8px;position:relative;min-width:75px}.loading{margin:0 auto;position:absolute;top:45%;bottom:0;left:0;right:0}.mat-dialog-actions{padding:0!important}::ng-deep .feedbackDialog .mat-dialog-container{padding:0;overflow:visible;background-color:rgba(255,255,255,0);box-shadow:initial}.toolbar-tips{background-color:rgba(255,255,255,.6);border-radius:12px;color:#757575;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:34px;line-height:40px;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;margin-bottom:72px;padding:22px 0;text-align:center;visibility:visible;width:656px;height:auto;-webkit-animation:0s ease-in 5s forwards cssAnimation;animation:0s ease-in 5s forwards cssAnimation}@keyframes cssAnimation{to{width:0;height:0;overflow:hidden}}@-webkit-keyframes cssAnimation{to{width:0;height:0;visibility:hidden}}.drawCanvas{position:absolute;top:0;left:0;z-index:-1;margin:0 auto;cursor:crosshair}.pointerCursor{cursor:default!important}"]
}] }
];
/** @nocollapse */
FeedbackDialogComponent.ctorParameters = function () {
return [
{ type: material.MatDialogRef },
{ type: FeedbackService },
{ type: core.ChangeDetectorRef },
{ type: core.ElementRef }
];
};
FeedbackDialogComponent.propDecorators = {
screenshotParent: [{ type: core.ViewChild, args: ['screenshotParent',] }],
onEscapeKeyDownHandler: [{ type: core.HostListener, args: ['document:keydown.escape', ['$event'],] }]
};
return FeedbackDialogComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var FeedbackToolbarComponent = /** @class */ (function () {
function FeedbackToolbarComponent(el, feedbackService) {
this.el = el;
this.feedbackService = feedbackService;
this.manipulate = new core.EventEmitter();
this.disableToolbarTips = false;
this.isSwitch = false;
this.isDragging = false;
this.vars = {};
this.vars = feedbackService.initialVariables;
}
/**
* @return {?}
*/
FeedbackToolbarComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
/** @type {?} */
var elStyle = this.el.nativeElement.style;
elStyle.position = 'absolute';
elStyle.left = '43%';
elStyle.top = '60%';
this.addDragListenerOnMoveBtn();
};
/**
* @return {?}
*/
FeedbackToolbarComponent.prototype.ngOnChanges = /**
* @return {?}
*/
function () {
this.isSwitch = this.drawColor !== this.feedbackService.highlightedColor;
};
/**
* @return {?}
*/
FeedbackToolbarComponent.prototype.done = /**
* @return {?}
*/
function () {
this.manipulate.emit('done');
};
/**
* @return {?}
*/
FeedbackToolbarComponent.prototype.toggleHighlight = /**
* @return {?}
*/
function () {
this.isSwitch = false;
this.manipulate.emit(this.feedbackService.highlightedColor);
};
/**
* @return {?}
*/
FeedbackToolbarComponent.prototype.toggleHide = /**
* @return {?}
*/
function () {
this.isSwitch = true;
this.manipulate.emit(this.feedbackService.hiddenColor);
};
/**
* @return {?}
*/
FeedbackToolbarComponent.prototype.addDragListenerOnMoveBtn = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var mouseUp = rxjs.fromEvent(this.toggleMoveBtn.nativeElement, 'mouseup');
/** @type {?} */
var mouseMove = rxjs.fromEvent(document.documentElement, 'mousemove');
/** @type {?} */
var mouseDown = rxjs.fromEvent(this.toggleMoveBtn.nativeElement, 'mousedown');
/** @type {?} */
var mouseDrag = mouseDown.pipe(operators.mergeMap(function (md) {
_this.feedbackService.setIsDraggingToolbar(true);
/** @type {?} */
var startX = md.offsetX;
/** @type {?} */
var startY = md.offsetY;
_this.disableToolbarTips = true;
_this.isDragging = true;
// Calculate dif with mousemove until mouseup
return mouseMove.pipe(operators.map(function (mm) {
mm.preventDefault();
return {
left: mm.clientX - startX,
top: mm.clientY - startY
};
}), operators.finalize(function () {
_this.isDragging = false;
_this.disableToolbarTips = false;
_this.feedbackService.setIsDraggingToolbar(false);
}), operators.takeUntil(mouseUp));
}));
mouseDrag.subscribe(function (pos) {
_this.el.nativeElement.style.left = pos.left + 'px';
_this.el.nativeElement.style.top = pos.top + 'px';
});
};
FeedbackToolbarComponent.decorators = [
{ type: core.Component, args: [{
selector: 'feedback-toolbar',
template: "<div exclude-rect=\"true\" class=\"toolbar\">\r\n <div class=\"move-toolbar\" #toggleMove [matTooltip]=\"vars['moveToolbarTip']\" [matTooltipDisabled]=\"disableToolbarTips\">\r\n <svg focusable=\"false\" aria-label=\"Drag\" fill=\"#BDBDBD\" height=\"56\" width=\"16\"\r\n viewBox=\"-2 2 12 12\">\r\n <circle cx=\"1.5\" cy=\"1.5\" r=\"1.5\"></circle>\r\n <circle cx=\"1.5\" cy=\"7.5\" r=\"1.5\"></circle>\r\n <circle cx=\"1.5\" cy=\"13.5\" r=\"1.5\"></circle>\r\n <circle cx=\"6.5\" cy=\"1.5\" r=\"1.5\"></circle>\r\n <circle cx=\"6.5\" cy=\"7.5\" r=\"1.5\"></circle>\r\n <circle cx=\"6.5\" cy=\"13.5\" r=\"1.5\"></circle>\r\n </svg>\r\n </div>\r\n <button #highlightBtn (click)=\"toggleHighlight()\" [matTooltip]=\"vars['highlightTip']\"\r\n [matTooltipDisabled]=\"disableToolbarTips\" class=\"highlight-toggle\" [ngClass]=\"{'deepen-color': !isSwitch}\">\r\n <span class=\"toggle\">\r\n <svg focusable=\"false\" aria-label=\"\" viewBox=\"0 0 24 24\" height=\"36\" width=\"36\"\r\n fill=\"#ffd740\">\r\n <path d=\"M3 3h18v18H3z\"></path>\r\n </svg>\r\n\r\n <svg focusable=\"false\" aria-label=\"\" fill=\"#757575\" viewBox=\"0 0 24 24\"\r\n height=\"36\" width=\"36\" [ngClass]=\"{'toggle-decorator': !isSwitch}\" *ngIf=\"!isSwitch\">\r\n <path\r\n d=\"M21 17h-2.58l2.51 2.56c-.18.69-.73 1.26-1.41 1.44L17 18.5V21h-2v-6h6v2zM19 7h2v2h-2V7zm2-2h-2V3.08c1.1 0 2 .92 2 1.92zm-6-2h2v2h-2V3zm4 8h2v2h-2v-2zM9 21H7v-2h2v2zM5 9H3V7h2v2zm0-5.92V5H3c0-1 1-1.92 2-1.92zM5 17H3v-2h2v2zM9 5H7V3h2v2zm4 0h-2V3h2v2zm0 16h-2v-2h2v2zm-8-8H3v-2h2v2zm0 8.08C3.9 21.08 3 20 3 19h2v2.08z\"></path>\r\n </svg>\r\n </span>\r\n </button>\r\n <button (click)=\"toggleHide()\" [matTooltip]=\"vars['hideTip']\" [matTooltipDisabled]=\"disableToolbarTips\"\r\n class=\"hide-toggle\" [ngClass]=\"{'deepen-color': isSwitch}\">\r\n <span class=\"toggle\">\r\n <svg focusable=\"false\" aria-label=\"\" viewBox=\"0 0 24 24\" height=\"36\" width=\"36\"\r\n fill=\"#000\">\r\n <path d=\"M3 3h18v18H3z\"></path>\r\n </svg>\r\n <svg focusable=\"false\" aria-label=\"\" fill=\"#757575\" viewBox=\"0 0 24 24\"\r\n height=\"36\" width=\"36\" [ngClass]=\"{'toggle-decorator': isSwitch}\" *ngIf=\"isSwitch\">\r\n <path\r\n d=\"M21 17h-2.58l2.51 2.56c-.18.69-.73 1.26-1.41 1.44L17 18.5V21h-2v-6h6v2zM19 7h2v2h-2V7zm2-2h-2V3.08c1.1 0 2 .92 2 1.92zm-6-2h2v2h-2V3zm4 8h2v2h-2v-2zM9 21H7v-2h2v2zM5 9H3V7h2v2zm0-5.92V5H3c0-1 1-1.92 2-1.92zM5 17H3v-2h2v2zM9 5H7V3h2v2zm4 0h-2V3h2v2zm0 16h-2v-2h2v2zm-8-8H3v-2h2v2zm0 8.08C3.9 21.08 3 20 3 19h2v2.08z\"></path>\r\n </svg>\r\n </span>\r\n </button>\r\n <button mat-button class=\"merge-button\" (click)=\"done()\">{{vars['editDoneLabel']}}</button>\r\n</div>\r\n",
styles: [".toolbar{align-items:center;background-color:#fff;border-radius:2px;box-shadow:rgba(0,0,0,.14) 0 24px 38px 3px,rgba(0,0,0,.12) 0 9px 46px 8px,rgba(0,0,0,.2) 0 11px 15px -7px;cursor:pointer;display:-webkit-inline-flex;flex-direction:row;height:56px;min-width:232px;pointer-events:auto;overflow:visible;position:absolute;margin:0 auto;width:228px;bottom:0;top:25%;left:0;right:0;z-index:999}.move-toolbar{cursor:-webkit-grab;height:56px;padding:0 12px;position:relative}.move-toolbar:active{cursor:-webkit-grabbing}.toggle{display:inline-block;position:relative;height:36px;width:36px}.toggle-decorator{left:0;position:absolute;top:0}.highlight-toggle{align-items:center;background-color:#fff;border:none;box-sizing:border-box;cursor:pointer;display:-webkit-flex;justify-content:center;outline:0;padding:10px;pointer-events:auto;position:relative;height:56px;width:56px}.deepen-color{background-color:#e0e0e0!important}.hide-toggle{align-items:center;background-color:#fff;border:none;box-sizing:border-box;cursor:pointer;display:-webkit-flex;justify-content:center;outline:0;padding:10px;pointer-events:auto;position:relative;height:56px;width:56px}.merge-button{padding:0!important;margin:0 10px!important;min-width:56px;color:#4285f4}"]
}] }
];
/** @nocollapse */
FeedbackToolbarComponent.ctorParameters = function () {
return [
{ type: core.ElementRef },
{ type: FeedbackService }
];
};
FeedbackToolbarComponent.propDecorators = {
drawColor: [{ type: core.Input }],
manipulate: [{ type: core.Output }],
toggleMoveBtn: [{ type: core.ViewChild, args: ['toggleMove',] }]
};
return FeedbackToolbarComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var FeedbackRectangleComponent = /** @class */ (function () {
function FeedbackRectangleComponent(feedbackService) {
this.feedbackService = feedbackService;
this.close = new core.EventEmitter();
this.showCloseTag = false;
}
/**
* @return {?}
*/
FeedbackRectangleComponent.prototype.onMouseEnter = /**
* @return {?}
*/
function () {
this.showCloseTag = this.noHover === false;
};
/**
* @return {?}
*/
FeedbackRectangleComponent.prototype.onMouseLeave = /**
* @return {?}
*/
function () {
this.showCloseTag = false;
};
/**
* @return {?}
*/
FeedbackRectangleComponent.prototype.onClose = /**
* @return {?}
*/
function () {
this.close.emit();
};
FeedbackRectangleComponent.decorators = [
{ type: core.Component, args: [{
selector: 'feedback-rectangle',
template: "<div exclude-rect=\"true\" class=\"rect\" [ngStyle]=\"{'left.px': rectangle.startX,\r\n 'top.px': rectangle.startY,\r\n 'width.px': rectangle.width ,\r\n 'height.px': rectangle.height }\"\r\n [ngClass]=\"{'highlight': rectangle.color === feedbackService.highlightedColor,\r\n 'hide': rectangle.color !== feedbackService.highlightedColor,\r\n 'noHover': noHover}\">\r\n <span exclude-rect=\"true\" class=\"close\" *ngIf=\"showCloseTag\" (click)=\"onClose()\">\r\n <svg viewBox=\"0 0 1024 1024\"\r\n width=\"16\" height=\"16\">\r\n <path\r\n d=\"M896 224l-96-96-288 288-288-288-96 96 288 288-288 288 96 96 288-288 288 288 96-96-288-288 288-288z\"></path>\r\n </svg>\r\n </span>\r\n</div>\r\n",
styles: [".rect{position:fixed;background:0 0;z-index:3}.highlight:not(.noHover):hover{cursor:default;background:rgba(55,131,249,.2)}.hide{background-color:#000}.hide:not(.noHover):hover{background-color:rgba(31,31,31,.75)}.rect .close{width:24px;height:24px;background:#fff;border-radius:50%;justify-content:center;align-items:center;color:#999;position:absolute;right:-12px;top:-12px;cursor:pointer;display:flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"]
}] }
];
/** @nocollapse */
FeedbackRectangleComponent.ctorParameters = function () {
return [
{ type: FeedbackService }
];
};
FeedbackRectangleComponent.propDecorators = {
rectangle: [{ type: core.Input }],
noHover: [{ type: core.Input }],
close: [{ type: core.Output }],
onMouseEnter: [{ type: core.HostListener, args: ['mouseenter',] }],
onMouseLeave: [{ type: core.HostListener, args: ['mouseleave',] }]
};
return FeedbackRectangleComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var FeedbackDirective = /** @class */ (function () {
function FeedbackDirective(dialogRef, feedbackService, overlay$$1) {
var _this = this;
this.dialogRef = dialogRef;
this.feedbackService = feedbackService;
this.title = 'Send feedback';
this.placeholder = 'Describe your issue or share your ideas';
this.editTip = 'Click to highlight or hide info';
this.checkboxLabel = 'Include screenshot';
this.cancelLabel = 'CANCEL';
this.sendLabel = 'SEND';
this.moveToolbarTip = 'move toolbar';
this.drawRectTip = 'Draw using yellow to highlight issues or black to hide sensitive info';
this.highlightTip = 'highlight issues';
this.hideTip = 'hide sensitive info';
this.editDoneLabel = 'DONE';
this.send = new core.EventEmitter();
this.feedbackService.feedback$.subscribe(function (feedback) {
_this.send.emit(feedback);
});
this.overlay = overlay$$1;
}
/**
* @return {?}
*/
FeedbackDirective.prototype.onClick = /**
* @return {?}
*/
function () {
this.openFeedbackDialog();
};
/**
* @return {?}
*/
FeedbackDirective.prototype.openFeedbackDialog = /**
* @return {?}
*/
function () {
this.feedbackService.initScreenshotCanvas();
/** @type {?} */
var dialogRef = this.dialogRef.open(FeedbackDialogComponent, {
panelClass: 'feedbackDialog',
backdropClass: 'dialogBackDrop',
disableClose: true,
height: 'auto',
width: 'auto',
scrollStrategy: this.overlay.scrollStrategies.reposition()
});
};
/**
* @return {?}
*/
FeedbackDirective.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.feedbackService.initialVariables = {
title: this.title,
placeholder: this.placeholder,
editTip: this.editTip,
checkboxLabel: this.checkboxLabel,
cancelLabel: this.cancelLabel,
sendLabel: this.sendLabel,
moveToolbarTip: this.moveToolbarTip,
drawRectTip: this.drawRectTip,
highlightTip: this.highlightTip,
hideTip: this.hideTip,
editDoneLabel: this.editDoneLabel
};
};
FeedbackDirective.decorators = [
{ type: core.Directive, args: [{ selector: '[feedback]' },] }
];
/** @nocollapse */
FeedbackDirective.ctorParameters = function () {
return [
{ type: material.MatDialog },
{ type: FeedbackService },
{ type: overlay.Overlay }
];
};
FeedbackDirective.propDecorators = {
title: [{ type: core.Input }],
placeholder: [{ type: core.Input }],
editTip: [{ type: core.Input }],
checkboxLabel: [{ type: core.Input }],
cancelLabel: [{ type: core.Input }],
sendLabel: [{ type: core.Input }],
moveToolbarTip: [{ type: core.Input }],
drawRectTip: [{ type: core.Input }],
highlightTip: [{ type: core.Input }],
hideTip: [{ type: core.Input }],
editDoneLabel: [{ type: core.Input }],
send: [{ type: core.Output }],
onClick: [{ type: core.HostListener, args: ['click',] }]
};
return FeedbackDirective;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var FeedbackModule = /** @class */ (function () {
function FeedbackModule() {
}
FeedbackModule.decorators = [
{ type: core.NgModule, args: [{
declarations: [
FeedbackDialogComponent,
FeedbackToolbarComponent,
FeedbackRectangleComponent,
FeedbackDirective
],
imports: [
material.MatDialogModule,
material.MatButtonModule,
material.MatIconModule,
material.MatInputModule,
material.MatTooltipModule,
common.CommonModule,
forms.FormsModule,
material.MatCheckboxModule,
material.MatProgressSpinnerModule
],
exports: [
FeedbackDirective
],
entryComponents: [
FeedbackDialogComponent
],
providers: [
FeedbackService
]
},] }
];
return FeedbackModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
exports.FeedbackModule = FeedbackModule;
exports.ɵa = FeedbackDialogComponent;
exports.ɵd = FeedbackRectangleComponent;
exports.ɵc = FeedbackToolbarComponent;
exports.ɵe = FeedbackDirective;
exports.ɵb = FeedbackService;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctZmVlZGJhY2sudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9uZy1mZWVkYmFjay9saWIvZW50aXR5L2ZlZWRiYWNrLnRzIiwibmc6Ly9uZy1mZWVkYmFjay9saWIvZmVlZGJhY2suc2VydmljZS50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2VudGl0eS9yZWN0YW5nbGUudHMiLCJuZzovL25nLWZlZWRiYWNrL2xpYi9mZWVkYmFjay1kaWFsb2cvZmVlZGJhY2stZGlhbG9nLmNvbXBvbmVudC50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2ZlZWRiYWNrLXRvb2xiYXIvZmVlZGJhY2stdG9vbGJhci5jb21wb25lbnQudHMiLCJuZzovL25nLWZlZWRiYWNrL2xpYi9mZWVkYmFjay1yZWN0YW5nbGUvZmVlZGJhY2stcmVjdGFuZ2xlLmNvbXBvbmVudC50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2ZlZWRiYWNrLmRpcmVjdGl2ZS50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2ZlZWRiYWNrLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgRmVlZGJhY2sge1xyXG4gIHB1YmxpYyBkZXNjcmlwdGlvbjogc3RyaW5nO1xyXG4gIHB1YmxpYyBzY3JlZW5zaG90OiBzdHJpbmc7XHJcbn1cclxuIiwiaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IGh0bWwyY2FudmFzIGZyb20gJ2h0bWwyY2FudmFzJztcclxuaW1wb3J0IHtTdWJqZWN0LCBPYnNlcnZhYmxlfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtGZWVkYmFja30gZnJvbSAnLi9lbnRpdHkvZmVlZGJhY2snOyAvLyBpbXBvcnQgT2JzZXJ2YWJsZSB0byBzb2x2ZSBidWlsZCBpc3N1ZVxyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tTZXJ2aWNlIHtcclxuICBwdWJsaWMgaW5pdGlhbFZhcmlhYmxlczogb2JqZWN0ID0ge307XHJcbiAgcHVibGljIGhpZ2hsaWdodGVkQ29sb3IgPSAneWVsbG93JztcclxuICBwdWJsaWMgaGlkZGVuQ29sb3IgPSAnYmxhY2snO1xyXG4gIHByaXZhdGUgc2NyZWVuc2hvdENhbnZhc1NvdXJjZSA9IG5ldyBTdWJqZWN0PEhUTUxDYW52YXNFbGVtZW50PigpO1xyXG4gIHB1YmxpYyBzY3JlZW5zaG90Q2FudmFzJDogT2JzZXJ2YWJsZTxIVE1MQ2FudmFzRWxlbWVudD4gPSB0aGlzLnNjcmVlbnNob3RDYW52YXNTb3VyY2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgZmVlZGJhY2tTb3VyY2UgPSBuZXcgU3ViamVjdDxGZWVkYmFjaz4oKTtcclxuICBwdWJsaWMgZmVlZGJhY2skOiBPYnNlcnZhYmxlPEZlZWRiYWNrPiA9IHRoaXMuZmVlZGJhY2tTb3VyY2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgaXNEcmFnZ2luZ1Rvb2xiYXJTb3VyY2UgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xyXG4gIHB1YmxpYyBpc0RyYWdnaW5nVG9vbGJhciQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLmlzRHJhZ2dpbmdUb29sYmFyU291cmNlLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuXHJcbiAgcHVibGljIGluaXRTY3JlZW5zaG90Q2FudmFzKCkge1xyXG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XHJcbiAgICBjb25zdCBib2R5ID0gZG9jdW1lbnQuYm9keTtcclxuICAgIGh0bWwyY2FudmFzKGJvZHksIHtcclxuICAgICAgbG9nZ2luZzogZmFsc2UsXHJcbiAgICAgIHdpZHRoOiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgsXHJcbiAgICAgIGhlaWdodDogZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCxcclxuICAgICAgeDogZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQsXHJcbiAgICAgIHk6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AsXHJcbiAgICAgIGFsbG93VGFpbnQgOiB0cnVlXHJcbiAgICB9KS50aGVuKGJvZHlDYW52YXMgPT4ge1xyXG4gICAgICB0aGlzLnNjcmVlbnNob3RDYW52YXNTb3VyY2UubmV4dChib2R5Q2FudmFzKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldENhbnZhcyhjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KTogdm9pZCB7XHJcbiAgICB0aGlzLnNjcmVlbnNob3RDYW52YXNTb3VyY2UubmV4dChjYW52YXMpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldEZlZWRiYWNrKGZlZWRiYWNrOiBGZWVkYmFjayk6IHZvaWQge1xyXG4gICAgdGhpcy5mZWVkYmFja1NvdXJjZS5uZXh0KGZlZWRiYWNrKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXRJc0RyYWdnaW5nVG9vbGJhcihpc0RyYWdnaW5nOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzRHJhZ2dpbmdUb29sYmFyU291cmNlLm5leHQoaXNEcmFnZ2luZyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0SW1nRWxlKGNhbnZhcyk6IEhUTUxFbGVtZW50IHtcclxuICAgIGNvbnN0IGltZyA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpLFxyXG4gICAgICAgICAgaW1hZ2VFbGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcclxuICAgIGltYWdlRWxlLnNldEF0dHJpYnV0ZSgnc3JjJywgaW1nKTtcclxuICAgIE9iamVjdC5hc3NpZ24oaW1hZ2VFbGUuc3R5bGUsIHtcclxuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXHJcbiAgICAgIHRvcDogJzUwJScsXHJcbiAgICAgIHJpZ2h0OiAnMCcsXHJcbiAgICAgIGxlZnQ6ICcwJyxcclxuICAgICAgbWFyZ2luOiAnMCBhdXRvJyxcclxuICAgICAgbWF4SGVpZ2h0OiAnMTAwJScsXHJcbiAgICAgIG1heFdpZHRoOiAnMTAwJScsXHJcbiAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTUwJSknXHJcbiAgICB9KTtcclxuICAgIHJldHVybiBpbWFnZUVsZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBoaWRlQmFja0Ryb3AoKSB7XHJcbiAgICBjb25zdCBkaWFsb2dCYWNrRHJvcCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2RpYWxvZ0JhY2tEcm9wJylbMF0gYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBkaWFsb2dCYWNrRHJvcC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAnaW5pdGlhbCc7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2hvd0JhY2tEcm9wKCkge1xyXG4gICAgY29uc3QgZGlhbG9nQmFja0Ryb3AgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdkaWFsb2dCYWNrRHJvcCcpWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgaWYgKCFkaWFsb2dCYWNrRHJvcC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaHRtbDJjYW52YXMtaWdub3JlJykpIHtcclxuICAgICAgZGlhbG9nQmFja0Ryb3Auc2V0QXR0cmlidXRlKCdkYXRhLWh0bWwyY2FudmFzLWlnbm9yZScsICd0cnVlJyk7XHJcbiAgICB9XHJcbiAgICBkaWFsb2dCYWNrRHJvcC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAncmdiYSgwLCAwLCAwLCAuMjg4KSc7XHJcbiAgfVxyXG59XHJcbiIsImV4cG9ydCBjbGFzcyBSZWN0YW5nbGUge1xyXG4gIHB1YmxpYyBzdGFydFg6IG51bWJlcjtcclxuICBwdWJsaWMgc3RhcnRZOiBudW1iZXI7XHJcbiAgcHVibGljIHdpZHRoOiBudW1iZXI7XHJcbiAgcHVibGljIGhlaWdodDogbnVtYmVyO1xyXG4gIHB1YmxpYyBjb2xvcjogc3RyaW5nO1xyXG4gIHB1YmxpYyB3aW5kb3dTY3JvbGxZOiBudW1iZXIgPSB3aW5kb3cuc2Nyb2xsWTtcclxuICBwdWJsaWMgd2luZG93U2Nyb2xsWDogbnVtYmVyID0gd2luZG93LnNjcm9sbFg7XHJcbn1cclxuIiwiaW1wb3J0IHtmcm9tLCBmcm9tRXZlbnQgYXMgb2JzZXJ2YWJsZUZyb21FdmVudCwgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7dGFrZVVudGlsLCBmaW5hbGl6ZSwgbWFwLCBtZXJnZU1hcCwgdGltZW91dCwgc2tpcFdoaWxlLCBmaWx0ZXIsIHNjYW4sIGZpcnN0fSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7Q29tcG9uZW50LCBBZnRlclZpZXdJbml0LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIENoYW5nZURldGVjdG9yUmVmLCBIb3N0TGlzdGVuZXIsIFJlbmRlcmVyMn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7TWF0RGlhbG9nUmVmfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbCc7XHJcbmltcG9ydCB7RmVlZGJhY2t9IGZyb20gJy4uL2VudGl0eS9mZWVkYmFjayc7XHJcbmltcG9ydCB7RmVlZGJhY2tTZXJ2aWNlfSBmcm9tICcuLi9mZWVkYmFjay5zZXJ2aWNlJztcclxuXHJcbmltcG9ydCB7UmVjdGFuZ2xlfSBmcm9tICcuLi9lbnRpdHkvcmVjdGFuZ2xlJztcclxuaW1wb3J0IHtlbGVtZW50fSBmcm9tICdwcm90cmFjdG9yJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZmVlZGJhY2stZGlhbG9nJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vZmVlZGJhY2stZGlhbG9nLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9mZWVkYmFjay1kaWFsb2cuY29tcG9uZW50LmNzcyddXHJcbn0pXHJcblxyXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tEaWFsb2dDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcclxuICBwdWJsaWMgc2hvd1Rvb2xiYXIgPSBmYWxzZTtcclxuICBwdWJsaWMgdmFyczogb2JqZWN0ID0ge307XHJcbiAgcHVibGljIGZlZWRiYWNrID0gbmV3IEZlZWRiYWNrKCk7XHJcbiAgcHVibGljIGluY2x1ZGVTY3JlZW5zaG90OiBib29sZWFuID0gdHJ1ZTtcclxuICBwdWJsaWMgc2hvd1NwaW5uZXIgPSB0cnVlO1xyXG4gIHB1YmxpYyBzY3JlZW5zaG90RWxlOiBIVE1MRWxlbWVudDtcclxuICBwdWJsaWMgZHJhd0NhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7XHJcbiAgcHVibGljIHNob3dUb29sYmFyVGlwczogYm9vbGVhbiA9IHRydWU7XHJcbiAgQFZpZXdDaGlsZCgnc2NyZWVuc2hvdFBhcmVudCcpXHJcbiAgcHVibGljIHNjcmVlbnNob3RQYXJlbnQ6IEVsZW1lbnRSZWY7XHJcbiAgcHVibGljIGRyYXdDb2xvcjogc3RyaW5nID0gdGhpcy5mZWVkYmFja1NlcnZpY2UuaGlnaGxpZ2h0ZWRDb2xvcjtcclxuICBwdWJsaWMgcmVjdGFuZ2xlczogUmVjdGFuZ2xlW10gPSBbXTtcclxuICBwcml2YXRlIHNjcm9sbFdpZHRoID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFdpZHRoO1xyXG4gIHByaXZhdGUgc2Nyb2xsSGVpZ2h0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbEhlaWdodDtcclxuICBwcml2YXRlIGVsQ291bGRCZUhpZ2hsaWdodGVkID0gWydidXR0b24nLCAnYScsICdzcGFuJywgJ2VtJywgJ2knLCAnaDEnLCAnaDInLCAnaDMnLCAnaDQnLFxyXG4gICAgJ2g1JywgJ2g2JywgJ3AnLCAnc3Ryb25nJywgJ3NtYWxsJywgJ3N1YicsICdzdXAnLCAnYicsICd0aW1lJywgJ2ltZycsXHJcbiAgICAndmlkZW8nLCAnaW5wdXQnLCAnbGFiZWwnLCAnc2VsZWN0JywgJ3RleHRhcmVhJywgJ2FydGljbGUnLCAnc3VtbWFyeScsICdzZWN0aW9uJ107XHJcbiAgLy8gdGhlIGZsYWcgZmllbGQgJ2lzTWFudWFsbHlEcmF3UmVjdCcgdG8gc29sdmUgY29uZmxpY3QgYmV0d2VlbiBtYW51YWxseSBkcmF3IGFuZCBhdXRvIGRyYXdcclxuICBwcml2YXRlIG1hbnVhbGx5RHJhd1JlY3QkOiBTdWJzY3JpcHRpb247XHJcbiAgcHJpdmF0ZSBhdXRvRHJhd1JlY3QkOiBTdWJzY3JpcHRpb247XHJcbiAgcHVibGljIGlzRHJhd2luZ1JlY3Q6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgY29uc3RydWN0b3IocHVibGljIGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPEZlZWRiYWNrRGlhbG9nQ29tcG9uZW50PixcclxuICAgICAgICAgICAgICBwcml2YXRlIGZlZWRiYWNrU2VydmljZTogRmVlZGJhY2tTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgZGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYpIHtcclxuICAgIHRoaXMuZmVlZGJhY2sgPSBuZXcgRmVlZGJhY2soKTtcclxuICAgIHRoaXMuZmVlZGJhY2suZGVzY3JpcHRpb24gPSAnJztcclxuICAgIHRoaXMudmFycyA9IHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmluaXRpYWxWYXJpYWJsZXM7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2NyZWVuc2hvdENhbnZhcyQuc3Vic2NyaWJlKChjYW52YXMpID0+IHtcclxuICAgICAgdGhpcy5zaG93U3Bpbm5lciA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmZlZWRiYWNrLnNjcmVlbnNob3QgPSBjYW52YXMudG9EYXRhVVJMKCdpbWFnZS9wbmcnKTtcclxuICAgICAgdGhpcy5zY3JlZW5zaG90RWxlID0gdGhpcy5mZWVkYmFja1NlcnZpY2UuZ2V0SW1nRWxlKGNhbnZhcyk7XHJcbiAgICAgIHRoaXMuYXBwZW5kU2NyZWVuc2hvdCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2UuaXNEcmFnZ2luZ1Rvb2xiYXIkLnN1YnNjcmliZSgoaXNEcmFnZ2luZykgPT4ge1xyXG4gICAgICBpZiAoaXNEcmFnZ2luZykge1xyXG4gICAgICAgIHRoaXMuZGVzdHJveUNhbnZhc0xpc3RlbmVycygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuYWRkQ2FudmFzTGlzdGVuZXJzKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKChzZW5kTm93KSA9PiB7XHJcbiAgICAgIGlmIChzZW5kTm93ID09PSB0cnVlKSB7XHJcbiAgICAgICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2V0RmVlZGJhY2sodGhpcy5mZWVkYmFjayk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2hvd0JhY2tEcm9wKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZXhwYW5kRHJhd2luZ0JvYXJkKCkge1xyXG4gICAgdGhpcy5zaG93VG9vbGJhciA9IHRydWU7XHJcbiAgICBpZiAoIXRoaXMuZHJhd0NhbnZhcykge1xyXG4gICAgICB0aGlzLmRldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgdGhpcy5pbml0QmFja2dyb3VuZENhbnZhcygpO1xyXG4gICAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5oaWRlQmFja0Ryb3AoKTtcclxuICAgIH1cclxuICAgIHRoaXMuYWRkQ2FudmFzTGlzdGVuZXJzKCk7XHJcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5kcmF3Q2FudmFzKTtcclxuICAgIHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmhpZGVCYWNrRHJvcCgpO1xyXG4gICAgY29uc29sZS5sb2coJ2V4cGFuZCB0aGUgYm9hcmQnKTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24uZXNjYXBlJywgWyckZXZlbnQnXSlcclxuICBwdWJsaWMgb25Fc2NhcGVLZXlEb3duSGFuZGxlcihldnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgIHRoaXMuc2hvd1Rvb2xiYXIgPSBmYWxzZTtcclxuICAgIHRoaXMuaW5jbHVkZVNjcmVlbnNob3QgPSB0cnVlO1xyXG4gICAgdGhpcy5kZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSgna2V5IGRvd24gZXNjIHRvIGNsb3NlJyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbWFuaXB1bGF0ZShtYW5pcHVsYXRpb246IHN0cmluZykge1xyXG4gICAgaWYgKG1hbmlwdWxhdGlvbiA9PT0gJ2RvbmUnKSB7XHJcbiAgICAgIHRoaXMuc2hvd1Rvb2xiYXJUaXBzID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuc2hvd1NwaW5uZXIgPSB0cnVlO1xyXG4gICAgICB0aGlzLmRlc3Ryb3lDYW52YXNMaXN0ZW5lcnMoKTtcclxuICAgICAgdGhpcy5zaG93VG9vbGJhciA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmRldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgdGhpcy5mZWVkYmFja1NlcnZpY2UuaW5pdFNjcmVlbnNob3RDYW52YXMoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc3RhcnREcmF3KG1hbmlwdWxhdGlvbik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc3RhcnREcmF3KGNvbG9yOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuZHJhd0NvbG9yID0gY29sb3I7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgaXNJbmNsdWRlU2NyZWVuc2hvdCgpIHtcclxuICAgIGlmICh0aGlzLmluY2x1ZGVTY3JlZW5zaG90KSB7XHJcbiAgICAgIHRoaXMuZGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICB0aGlzLnNob3dTcGlubmVyID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuYXBwZW5kU2NyZWVuc2hvdCgpO1xyXG4gICAgICB0aGlzLmZlZWRiYWNrLnNjcmVlbnNob3QgPSB0aGlzLnNjcmVlbnNob3RFbGUuZ2V0QXR0cmlidXRlKCdzcmMnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLmZlZWRiYWNrWydzY3JlZW5zaG90J107XHJcbiAgICAgIHRoaXMuc2hvd1NwaW5uZXIgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhcHBlbmRTY3JlZW5zaG90KCkge1xyXG4gICAgaWYgKHRoaXMuc2NyZWVuc2hvdFBhcmVudCkgeyB0aGlzLnNjcmVlbnNob3RQYXJlbnQubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNjcmVlbnNob3RFbGUpOyB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXRCYWNrZ3JvdW5kQ2FudmFzKCkge1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyYXctY2FudmFzJykgYXMgSFRNTENhbnZhc0VsZW1lbnQ7XHJcbiAgICAvLyBUaGUgY2FudmFzIHRvIGRyYXcsIG11c3QgdXNlIHRoaXMgd2F5IHRvIGluaXRpYWwgdGhlIGhlaWdodCBhbmQgd2lkdGhcclxuICAgIHRoaXMuZHJhd0NhbnZhcy5zdHlsZS5oZWlnaHQgPSB0aGlzLnNjcm9sbEhlaWdodCArICcnO1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzLnN0eWxlLndpZHRoID0gdGhpcy5zY3JvbGxXaWR0aCArICcnO1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzLmhlaWdodCA9IHRoaXMuc2Nyb2xsSGVpZ2h0O1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzLndpZHRoID0gdGhpcy5zY3JvbGxXaWR0aDtcclxuICAgIHRoaXMuZHJhd0NvbnRhaW5lclJlY3QoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd0NvbnRhaW5lclJlY3QoKSB7XHJcbiAgICBjb25zdCBkcmF3Q29udGV4dCA9IHRoaXMuZHJhd0NhbnZhcy5nZXRDb250ZXh0KCcyZCcpLFxyXG4gICAgICB3aWR0aCA9IHRoaXMuc2Nyb2xsV2lkdGgsXHJcbiAgICAgIGhlaWdodCA9IHRoaXMuc2Nyb2xsSGVpZ2h0O1xyXG4gICAgZHJhd0NvbnRleHQuYmVnaW5QYXRoKCk7XHJcbiAgICBkcmF3Q29udGV4dC5maWxsU3R5bGUgPSAncmdiYSgwLDAsMCwwLjMpJztcclxuICAgIGRyYXdDb250ZXh0LmNsZWFyUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcclxuICAgIGRyYXdDb250ZXh0LmZpbGxSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpOyAvLyBkcmF3IHRoZSByZWN0YW5nbGVcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd1JlY3RhbmdsZShyZWN0OiBSZWN0YW5nbGUpIHtcclxuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmRyYXdDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGNvbnRleHQubGluZUpvaW4gPSAncm91bmQnO1xyXG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcclxuICAgIGlmIChyZWN0LmNvbG9yID09PSB0aGlzLmZlZWRiYWNrU2VydmljZS5oaWRkZW5Db2xvcikge1xyXG4gICAgICBjb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKDMxLCAzMSwgMzEsIDAuNzUpJztcclxuICAgICAgY29udGV4dC5maWxsUmVjdChyZWN0LnN0YXJ0WCwgcmVjdC5zdGFydFksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTtcclxuICAgICAgY29udGV4dC5yZWN0KHJlY3Quc3RhcnRYLCByZWN0LnN0YXJ0WSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGV4dC5jbGVhclJlY3QocmVjdC5zdGFydFgsIHJlY3Quc3RhcnRZLCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7XHJcbiAgICAgIGNvbnRleHQubGluZVdpZHRoID0gNTtcclxuICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IHJlY3QuY29sb3I7XHJcbiAgICAgIGNvbnRleHQucmVjdChyZWN0LnN0YXJ0WCwgcmVjdC5zdGFydFksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTtcclxuICAgICAgY29udGV4dC5zdHJva2UoKTtcclxuICAgICAgY29udGV4dC5jbGVhclJlY3QocmVjdC5zdGFydFgsIHJlY3Quc3RhcnRZLCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7XHJcbiAgICAgIHRoaXMucmVjdGFuZ2xlcy5mb3JFYWNoKHRtcFJlY3QgPT4ge1xyXG4gICAgICAgIGlmICh0bXBSZWN0LmNvbG9yID09PSB0aGlzLmZlZWRiYWNrU2VydmljZS5oaWdobGlnaHRlZENvbG9yKSB7XHJcbiAgICAgICAgICBjb250ZXh0LmNsZWFyUmVjdCh0bXBSZWN0LnN0YXJ0WCwgdG1wUmVjdC5zdGFydFksIHRtcFJlY3Qud2lkdGgsIHRtcFJlY3QuaGVpZ2h0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGRDYW52YXNMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBtb3VzZVVwID0gb2JzZXJ2YWJsZUZyb21FdmVudChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdtb3VzZXVwJyksXHJcbiAgICAgICAgICBtb3VzZU1vdmUgPSBvYnNlcnZhYmxlRnJvbUV2ZW50KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgJ21vdXNlbW92ZScpLFxyXG4gICAgICAgICAgbW91c2VEb3duID0gb2JzZXJ2YWJsZUZyb21FdmVudChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdtb3VzZWRvd24nKSxcclxuICAgICAgICAgIHNjcm9sbCA9IG9ic2VydmFibGVGcm9tRXZlbnQod2luZG93LCAnc2Nyb2xsJyk7XHJcblxyXG4gICAgdGhpcy5tYW51YWxseURyYXdSZWN0KG1vdXNlRG93biwgbW91c2VNb3ZlLCBtb3VzZVVwKTtcclxuICAgIHRoaXMuYXV0b0RyYXdSZWN0KG1vdXNlTW92ZSk7XHJcbiAgICB0aGlzLmNoYW5nZVJlY3RQb3NpdGlvbihzY3JvbGwpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGFuZ2VSZWN0UG9zaXRpb24oc2Nyb2xsOiBPYnNlcnZhYmxlPEV2ZW50Pikge1xyXG4gICAgc2Nyb2xsLnN1YnNjcmliZShcclxuICAgICAgZXZlbnQgPT4ge1xyXG4gICAgICAgIGNvbnN0IGN1cnJlbnRXaW5kb3dTY3JvbGxYID0gd2luZG93LnNjcm9sbFgsXHJcbiAgICAgICAgICAgICAgY3VycmVudFdpbmRvd1Njcm9sbFkgPSB3aW5kb3cuc2Nyb2xsWTtcclxuICAgICAgICB0aGlzLnJlY3RhbmdsZXMuZm9yRWFjaChyZWN0ID0+IHtcclxuICAgICAgICAgIHJlY3Quc3RhcnRZID0gcmVjdC5zdGFydFkgLSAoY3VycmVudFdpbmRvd1Njcm9sbFkgLSByZWN0LndpbmRvd1Njcm9sbFkpO1xyXG4gICAgICAgICAgcmVjdC5zdGFydFggPSByZWN0LnN0YXJ0WCAtIChjdXJyZW50V2luZG93U2Nyb2xsWCAtIHJlY3Qud2luZG93U2Nyb2xsWCk7XHJcbiAgICAgICAgICByZWN0LndpbmRvd1Njcm9sbFkgPSBjdXJyZW50V2luZG93U2Nyb2xsWTtcclxuICAgICAgICAgIHJlY3Qud2luZG93U2Nyb2xsWCA9IGN1cnJlbnRXaW5kb3dTY3JvbGxYO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yID0+IGNvbnNvbGUuZXJyb3IoZXJyb3IpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkZXN0cm95Q2FudmFzTGlzdGVuZXJzKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMubWFudWFsbHlEcmF3UmVjdCQpIHsgdGhpcy5tYW51YWxseURyYXdSZWN0JC51bnN1YnNjcmliZSgpOyB9XHJcbiAgICBpZiAodGhpcy5hdXRvRHJhd1JlY3QkKSB7IHRoaXMuYXV0b0RyYXdSZWN0JC51bnN1YnNjcmliZSgpOyB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG1hbnVhbGx5RHJhd1JlY3QobW91c2VEb3duOiBPYnNlcnZhYmxlPEV2ZW50PiwgbW91c2VNb3ZlOiBPYnNlcnZhYmxlPEV2ZW50PiwgbW91c2VVcDogT2JzZXJ2YWJsZTxFdmVudD4pOiB2b2lkIHtcclxuICAgIGNvbnN0IG1vdXNlRHJhZyA9IG1vdXNlRG93bi5waXBlKG1lcmdlTWFwKChtb3VzZURvd25FdmVudDogTW91c2VFdmVudCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5zaG93VG9vbGJhclRpcHMpIHsgdGhpcy5zaG93VG9vbGJhclRpcHMgPSBmYWxzZTsgfVxyXG4gICAgICB0aGlzLmF1dG9EcmF3UmVjdCQudW5zdWJzY3JpYmUoKTtcclxuICAgICAgdGhpcy5pc0RyYXdpbmdSZWN0ID0gdHJ1ZTtcclxuXHJcbiAgICAgIGNvbnN0IG5ld1JlY3RhbmdsZSA9IG5ldyBSZWN0YW5nbGUoKTtcclxuICAgICAgbmV3UmVjdGFuZ2xlLnN0YXJ0WCA9IG1vdXNlRG93bkV2ZW50LmNsaWVudFg7XHJcbiAgICAgIG5ld1JlY3RhbmdsZS5zdGFydFkgPSBtb3VzZURvd25FdmVudC5jbGllbnRZO1xyXG4gICAgICBuZXdSZWN0YW5nbGUuY29sb3IgPSB0aGlzLmRyYXdDb2xvcjtcclxuXHJcbiAgICAgIHJldHVybiBtb3VzZU1vdmUucGlwZShcclxuICAgICAgICBtYXAoKG1vdXNlTW92ZUV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgICBuZXdSZWN0YW5nbGUud2lkdGggPSBtb3VzZU1vdmVFdmVudC5jbGllbnRYIC0gbW91c2VEb3duRXZlbnQuY2xpZW50WDtcclxuICAgICAgICAgIG5ld1JlY3RhbmdsZS5oZWlnaHQgPSBtb3VzZU1vdmVFdmVudC5jbGllbnRZIC0gbW91c2VEb3duRXZlbnQuY2xpZW50WTtcclxuICAgICAgICAgIHJldHVybiBuZXdSZWN0YW5nbGU7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgZmluYWxpemUoKCkgPT4ge1xyXG4gICAgICAgICAgLy8gY2xpY2sgdG8gZHJhdyByZWN0YW5nbGVcclxuICAgICAgICAgIGlmIChuZXdSZWN0YW5nbGUud2lkdGggPT09IHVuZGVmaW5lZCB8fCBuZXdSZWN0YW5nbGUuaGVpZ2h0ID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgbmV3UmVjdGFuZ2xlLndpZHRoID09PSAwIHx8IG5ld1JlY3RhbmdsZS5oZWlnaHQgPT09IDApIHtcclxuICAgICAgICAgICAgY29uc3QgcmVjdCA9IHRoaXMuZHJhd1RlbXBDYW52YXNSZWN0YW5nbGUobW91c2VEb3duRXZlbnQpO1xyXG4gICAgICAgICAgICBpZiAocmVjdCkgeyB0aGlzLnJlY3RhbmdsZXMucHVzaChyZWN0KTsgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIGRyYWcgdG8gZHJhdyByZWN0YW5nbGVcclxuICAgICAgICAgICAgaWYgKG5ld1JlY3RhbmdsZS5oZWlnaHQgPCAwKSB7XHJcbiAgICAgICAgICAgICAgbmV3UmVjdGFuZ2xlLnN0YXJ0WSA9IG5ld1JlY3RhbmdsZS5zdGFydFkgKyBuZXdSZWN0YW5nbGUuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgIG5ld1JlY3RhbmdsZS5oZWlnaHQgPSBNYXRoLmFicyhuZXdSZWN0YW5nbGUuaGVpZ2h0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAobmV3UmVjdGFuZ2xlLndpZHRoIDwgMCkge1xyXG4gICAgICAgICAgICAgIG5ld1JlY3RhbmdsZS5zdGFydFggPSBuZXdSZWN0YW5nbGUuc3RhcnRYICsgbmV3UmVjdGFuZ2xlLndpZHRoO1xyXG4gICAgICAgICAgICAgIG5ld1JlY3RhbmdsZS53aWR0aCA9IE1hdGguYWJzKG5ld1JlY3RhbmdsZS53aWR0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5yZWN0YW5nbGVzLnB1c2gobmV3UmVjdGFuZ2xlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgICAgICAgICB0aGlzLmF1dG9EcmF3UmVjdChtb3VzZU1vdmUpO1xyXG4gICAgICAgICAgdGhpcy5pc0RyYXdpbmdSZWN0ID0gZmFsc2U7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgdGFrZVVudGlsKG1vdXNlVXApKTtcclxuICAgIH0pKTtcclxuXHJcbiAgICB0aGlzLm1hbnVhbGx5RHJhd1JlY3QkID0gbW91c2VEcmFnLnN1YnNjcmliZShcclxuICAgICAgKHJlYykgPT4ge1xyXG4gICAgICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgICAgICAgdGhpcy5kcmF3UmVjdGFuZ2xlKHJlYyk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGF1dG9EcmF3UmVjdChtb3VzZU1vdmU6IE9ic2VydmFibGU8RXZlbnQ+KTogdm9pZCB7XHJcbiAgICB0aGlzLmF1dG9EcmF3UmVjdCQgPSBtb3VzZU1vdmUuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKG1vdXNlTW92ZUV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgdGhpcy5kcmF3UGVyc2lzdENhbnZhc1JlY3RhbmdsZXMoKTtcclxuICAgICAgICB0aGlzLmRyYXdUZW1wQ2FudmFzUmVjdGFuZ2xlKG1vdXNlTW92ZUV2ZW50KTtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IGVyciA9PiBjb25zb2xlLmVycm9yKCdzb21ldGhpbmcgd3Jvbmcgb2NjdXJyZWQ6ICcgKyBlcnIpLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRyYXdQZXJzaXN0Q2FudmFzUmVjdGFuZ2xlcygpIHtcclxuICAgIHRoaXMuZHJhd0NvbnRhaW5lclJlY3QoKTtcclxuICAgIHRoaXMucmVjdGFuZ2xlcy5mb3JFYWNoKHRtcFJlY3QgPT4ge1xyXG4gICAgICB0aGlzLmRyYXdSZWN0YW5nbGUodG1wUmVjdCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd1RlbXBDYW52YXNSZWN0YW5nbGUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIGxldCByZWN0YW5nbGU6IFJlY3RhbmdsZSA9IG51bGw7XHJcbiAgICBjb25zdCBjbGllbnRYID0gZXZlbnQuY2xpZW50WCxcclxuICAgICAgICAgIGNsaWVudFkgPSBldmVudC5jbGllbnRZLFxyXG4gICAgICAgICAgZWxzID0gZG9jdW1lbnQuZWxlbWVudHNGcm9tUG9pbnQoY2xpZW50WCwgY2xpZW50WSksXHJcbiAgICAgICAgICBlbCA9IGVsc1syXTtcclxuICAgIGlmICgoIXRoaXMuaXNFeGNsdWRlUmVjdChlbHMpKSAmJiBlbCAmJiB0aGlzLmVsQ291bGRCZUhpZ2hsaWdodGVkLmluZGV4T2YoZWwubm9kZU5hbWUudG9Mb3dlckNhc2UoKSkgPiAtMSkge1xyXG4gICAgICByZWN0YW5nbGUgPSBuZXcgUmVjdGFuZ2xlKCk7XHJcbiAgICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgdGhpcy5kcmF3Q2FudmFzLnN0eWxlLmN1cnNvciA9ICdwb2ludGVyJztcclxuXHJcbiAgICAgIE9iamVjdC5hc3NpZ24ocmVjdGFuZ2xlLCB7XHJcbiAgICAgICAgc3RhcnRYOiByZWN0LmxlZnQsXHJcbiAgICAgICAgc3RhcnRZOiByZWN0LnRvcCxcclxuICAgICAgICB3aWR0aDogcmVjdC53aWR0aCxcclxuICAgICAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0LFxyXG4gICAgICAgIGNvbG9yOiB0aGlzLmRyYXdDb2xvclxyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5kcmF3UmVjdGFuZ2xlKHJlY3RhbmdsZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmRyYXdDYW52YXMuc3R5bGUuY3Vyc29yID0gJ2Nyb3NzaGFpcic7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVjdGFuZ2xlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGNsb3NlUmVjdChpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnJlY3RhbmdsZXMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGlzRXhjbHVkZVJlY3QoZWxlbWVudHM6IEVsZW1lbnRbXSk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgcmVzdWx0ID0gZWxlbWVudHMuc29tZSggZWwgPT4ge1xyXG4gICAgICByZXR1cm4gZWwuZ2V0QXR0cmlidXRlKCdleGNsdWRlLXJlY3QnKSA9PT0gJ3RydWUnO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQge2Zyb21FdmVudCBhcyBvYnNlcnZhYmxlRnJvbUV2ZW50fSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7dGFrZVVudGlsLCBmaW5hbGl6ZSwgbWFwLCBtZXJnZU1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQge0NvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBBZnRlclZpZXdJbml0LCBWaWV3Q2hpbGQsIE9uQ2hhbmdlc30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7RmVlZGJhY2tTZXJ2aWNlfSBmcm9tICcuLi9mZWVkYmFjay5zZXJ2aWNlJztcclxuXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2ZlZWRiYWNrLXRvb2xiYXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9mZWVkYmFjay10b29sYmFyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9mZWVkYmFjay10b29sYmFyLmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIEZlZWRiYWNrVG9vbGJhckNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcyB7XHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZHJhd0NvbG9yOiBzdHJpbmc7XHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIG1hbmlwdWxhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuICBwdWJsaWMgZGlzYWJsZVRvb2xiYXJUaXBzID0gZmFsc2U7XHJcbiAgQFZpZXdDaGlsZCgndG9nZ2xlTW92ZScpXHJcbiAgcHJpdmF0ZSB0b2dnbGVNb3ZlQnRuOiBFbGVtZW50UmVmO1xyXG4gIHB1YmxpYyBpc1N3aXRjaCA9IGZhbHNlO1xyXG4gIHB1YmxpYyBpc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgcHVibGljIHZhcnM6IG9iamVjdCA9IHt9O1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZWw6IEVsZW1lbnRSZWYsIHByaXZhdGUgZmVlZGJhY2tTZXJ2aWNlOiBGZWVkYmFja1NlcnZpY2UpIHtcclxuICAgIHRoaXMudmFycyA9IGZlZWRiYWNrU2VydmljZS5pbml0aWFsVmFyaWFibGVzO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGNvbnN0IGVsU3R5bGUgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuc3R5bGU7XHJcbiAgICBlbFN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcclxuICAgIGVsU3R5bGUubGVmdCA9ICc0MyUnO1xyXG4gICAgZWxTdHlsZS50b3AgPSAnNjAlJztcclxuICAgIHRoaXMuYWRkRHJhZ0xpc3RlbmVyT25Nb3ZlQnRuKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoKSB7XHJcbiAgICB0aGlzLmlzU3dpdGNoID0gdGhpcy5kcmF3Q29sb3IgIT09IHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmhpZ2hsaWdodGVkQ29sb3I7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZG9uZSgpIHtcclxuICAgIHRoaXMubWFuaXB1bGF0ZS5lbWl0KCdkb25lJyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdG9nZ2xlSGlnaGxpZ2h0KCkge1xyXG4gICAgdGhpcy5pc1N3aXRjaCA9IGZhbHNlO1xyXG4gICAgdGhpcy5tYW5pcHVsYXRlLmVtaXQodGhpcy5mZWVkYmFja1NlcnZpY2UuaGlnaGxpZ2h0ZWRDb2xvcik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdG9nZ2xlSGlkZSgpIHtcclxuICAgIHRoaXMuaXNTd2l0Y2ggPSB0cnVlO1xyXG4gICAgdGhpcy5tYW5pcHVsYXRlLmVtaXQodGhpcy5mZWVkYmFja1NlcnZpY2UuaGlkZGVuQ29sb3IpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFkZERyYWdMaXN0ZW5lck9uTW92ZUJ0bigpIHtcclxuICAgIGNvbnN0IG1vdXNlVXAgPSBvYnNlcnZhYmxlRnJvbUV2ZW50KHRoaXMudG9nZ2xlTW92ZUJ0bi5uYXRpdmVFbGVtZW50LCAnbW91c2V1cCcpO1xyXG4gICAgY29uc3QgbW91c2VNb3ZlID0gb2JzZXJ2YWJsZUZyb21FdmVudChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdtb3VzZW1vdmUnKTtcclxuICAgIGNvbnN0IG1vdXNlRG93biA9IG9ic2VydmFibGVGcm9tRXZlbnQodGhpcy50b2dnbGVNb3ZlQnRuLm5hdGl2ZUVsZW1lbnQsICdtb3VzZWRvd24nKTtcclxuICAgIGNvbnN0IG1vdXNlRHJhZyA9IG1vdXNlRG93bi5waXBlKG1lcmdlTWFwKChtZDogTW91c2VFdmVudCkgPT4ge1xyXG4gICAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5zZXRJc0RyYWdnaW5nVG9vbGJhcih0cnVlKTtcclxuICAgICAgY29uc3Qgc3RhcnRYID0gbWQub2Zmc2V0WDtcclxuICAgICAgY29uc3Qgc3RhcnRZID0gbWQub2Zmc2V0WTtcclxuICAgICAgdGhpcy5kaXNhYmxlVG9vbGJhclRpcHMgPSB0cnVlO1xyXG4gICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICAvLyBDYWxjdWxhdGUgZGlmIHdpdGggbW91c2Vtb3ZlIHVudGlsIG1vdXNldXBcclxuICAgICAgcmV0dXJuIG1vdXNlTW92ZS5waXBlKFxyXG4gICAgICAgIG1hcCgobW06IE1vdXNlRXZlbnQpID0+IHtcclxuICAgICAgICAgIG1tLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBsZWZ0OiBtbS5jbGllbnRYIC0gc3RhcnRYLFxyXG4gICAgICAgICAgICB0b3A6IG1tLmNsaWVudFkgLSBzdGFydFlcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgZmluYWxpemUoKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICB0aGlzLmRpc2FibGVUb29sYmFyVGlwcyA9IGZhbHNlO1xyXG4gICAgICAgICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2V0SXNEcmFnZ2luZ1Rvb2xiYXIoZmFsc2UpO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIHRha2VVbnRpbChtb3VzZVVwKSk7XHJcbiAgICB9KSk7XHJcbiAgICBtb3VzZURyYWcuc3Vic2NyaWJlKFxyXG4gICAgICAocG9zKSA9PiB7XHJcbiAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLmxlZnQgPSBwb3MubGVmdCArICdweCc7XHJcbiAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLnRvcCA9IHBvcy50b3AgKyAncHgnO1xyXG4gICAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHtDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtSZWN0YW5nbGV9IGZyb20gJy4uL2VudGl0eS9yZWN0YW5nbGUnO1xyXG5pbXBvcnQge0ZlZWRiYWNrU2VydmljZX0gZnJvbSAnLi4vZmVlZGJhY2suc2VydmljZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2ZlZWRiYWNrLXJlY3RhbmdsZScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2ZlZWRiYWNrLXJlY3RhbmdsZS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZmVlZGJhY2stcmVjdGFuZ2xlLmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIEZlZWRiYWNrUmVjdGFuZ2xlQ29tcG9uZW50IHtcclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyByZWN0YW5nbGU6IFJlY3RhbmdsZTtcclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBub0hvdmVyOiBib29sZWFuO1xyXG4gIEBPdXRwdXQoKVxyXG4gIHB1YmxpYyBjbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcclxuICBwdWJsaWMgc2hvd0Nsb3NlVGFnOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBmZWVkYmFja1NlcnZpY2U6IEZlZWRiYWNrU2VydmljZSkge1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2VlbnRlcicpXHJcbiAgcHVibGljIG9uTW91c2VFbnRlcigpOiB2b2lkIHtcclxuICAgIHRoaXMuc2hvd0Nsb3NlVGFnID0gdGhpcy5ub0hvdmVyID09PSBmYWxzZTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxyXG4gIHB1YmxpYyBvbk1vdXNlTGVhdmUoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNob3dDbG9zZVRhZyA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uQ2xvc2UoKTogdm9pZCB7XHJcbiAgICB0aGlzLmNsb3NlLmVtaXQoKTtcclxuICB9XHJcblxyXG5cclxufVxyXG4iLCJpbXBvcnQge0RpcmVjdGl2ZSwgSG9zdExpc3RlbmVyLCBFdmVudEVtaXR0ZXIsIE91dHB1dCwgSW5wdXQsIE9uSW5pdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7TWF0RGlhbG9nfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbCc7XHJcbmltcG9ydCB7RmVlZGJhY2tEaWFsb2dDb21wb25lbnR9IGZyb20gJy4vZmVlZGJhY2stZGlhbG9nL2ZlZWRiYWNrLWRpYWxvZy5jb21wb25lbnQnO1xyXG5pbXBvcnQge0ZlZWRiYWNrU2VydmljZX0gZnJvbSAnLi9mZWVkYmFjay5zZXJ2aWNlJztcclxuaW1wb3J0IHtPdmVybGF5fSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XHJcblxyXG5ARGlyZWN0aXZlKHtzZWxlY3RvcjogJ1tmZWVkYmFja10nfSlcclxuZXhwb3J0IGNsYXNzIEZlZWRiYWNrRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0IHtcclxuICBwcml2YXRlIG92ZXJsYXk6IE92ZXJsYXk7XHJcbiAgQElucHV0KCkgdGl0bGU6IHN0cmluZyA9ICdTZW5kIGZlZWRiYWNrJztcclxuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJ0Rlc2NyaWJlIHlvdXIgaXNzdWUgb3Igc2hhcmUgeW91ciBpZGVhcyc7XHJcbiAgQElucHV0KCkgZWRpdFRpcCA9ICdDbGljayB0byBoaWdobGlnaHQgb3IgaGlkZSBpbmZvJztcclxuICBASW5wdXQoKSBjaGVja2JveExhYmVsID0gJ0luY2x1ZGUgc2NyZWVuc2hvdCc7XHJcbiAgQElucHV0KCkgY2FuY2VsTGFiZWwgPSAnQ0FOQ0VMJztcclxuICBASW5wdXQoKSBzZW5kTGFiZWwgPSAnU0VORCc7XHJcbiAgQElucHV0KCkgbW92ZVRvb2xiYXJUaXAgPSAnbW92ZSB0b29sYmFyJztcclxuICBASW5wdXQoKSBkcmF3UmVjdFRpcCA9ICdEcmF3IHVzaW5nIHllbGxvdyB0byBoaWdobGlnaHQgaXNzdWVzIG9yIGJsYWNrIHRvIGhpZGUgc2Vuc2l0aXZlIGluZm8nO1xyXG4gIEBJbnB1dCgpIGhpZ2hsaWdodFRpcCA9ICdoaWdobGlnaHQgaXNzdWVzJztcclxuICBASW5wdXQoKSBoaWRlVGlwID0gJ2hpZGUgc2Vuc2l0aXZlIGluZm8nO1xyXG4gIEBJbnB1dCgpIGVkaXREb25lTGFiZWwgPSAnRE9ORSc7XHJcbiAgQE91dHB1dCgpIHB1YmxpYyBzZW5kID0gbmV3IEV2ZW50RW1pdHRlcjxvYmplY3Q+KCk7XHJcblxyXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIGRpYWxvZ1JlZjogTWF0RGlhbG9nLCBwcml2YXRlIGZlZWRiYWNrU2VydmljZTogRmVlZGJhY2tTZXJ2aWNlLCBvdmVybGF5OiBPdmVybGF5KSB7XHJcbiAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5mZWVkYmFjayQuc3Vic2NyaWJlKFxyXG4gICAgICAoZmVlZGJhY2spID0+IHtcclxuICAgICAgICB0aGlzLnNlbmQuZW1pdChmZWVkYmFjayk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgICB0aGlzLm92ZXJsYXkgPSBvdmVybGF5O1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snKVxyXG4gIHB1YmxpYyBvbkNsaWNrKCkge1xyXG4gICAgdGhpcy5vcGVuRmVlZGJhY2tEaWFsb2coKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvcGVuRmVlZGJhY2tEaWFsb2coKSB7XHJcbiAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5pbml0U2NyZWVuc2hvdENhbnZhcygpO1xyXG4gICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2dSZWYub3BlbihGZWVkYmFja0RpYWxvZ0NvbXBvbmVudCwge1xyXG4gICAgICBwYW5lbENsYXNzOiAnZmVlZGJhY2tEaWFsb2cnLFxyXG4gICAgICBiYWNrZHJvcENsYXNzOiAnZGlhbG9nQmFja0Ryb3AnLFxyXG4gICAgICBkaXNhYmxlQ2xvc2U6IHRydWUsXHJcbiAgICAgIGhlaWdodDogJ2F1dG8nLFxyXG4gICAgICB3aWR0aDogJ2F1dG8nLFxyXG4gICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbigpXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2UuaW5pdGlhbFZhcmlhYmxlcyA9IHtcclxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXHJcbiAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLnBsYWNlaG9sZGVyLFxyXG4gICAgICBlZGl0VGlwOiB0aGlzLmVkaXRUaXAsXHJcbiAgICAgIGNoZWNrYm94TGFiZWw6IHRoaXMuY2hlY2tib3hMYWJlbCxcclxuICAgICAgY2FuY2VsTGFiZWw6IHRoaXMuY2FuY2VsTGFiZWwsXHJcbiAgICAgIHNlbmRMYWJlbDogdGhpcy5zZW5kTGFiZWwsXHJcbiAgICAgIG1vdmVUb29sYmFyVGlwOiB0aGlzLm1vdmVUb29sYmFyVGlwLFxyXG4gICAgICBkcmF3UmVjdFRpcDogdGhpcy5kcmF3UmVjdFRpcCxcclxuICAgICAgaGlnaGxpZ2h0VGlwOiB0aGlzLmhpZ2hsaWdodFRpcCxcclxuICAgICAgaGlkZVRpcDogdGhpcy5oaWRlVGlwLFxyXG4gICAgICBlZGl0RG9uZUxhYmVsOiB0aGlzLmVkaXREb25lTGFiZWxcclxuICAgIH07XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQge05nTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtDb21tb25Nb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7Rm9ybXNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHtGZWVkYmFja0RpYWxvZ0NvbXBvbmVudH0gZnJvbSAnLi9mZWVkYmFjay1kaWFsb2cvZmVlZGJhY2stZGlhbG9nLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7RmVlZGJhY2tUb29sYmFyQ29tcG9uZW50fSBmcm9tICcuL2ZlZWRiYWNrLXRvb2xiYXIvZmVlZGJhY2stdG9vbGJhci5jb21wb25lbnQnO1xyXG5pbXBvcnQge0ZlZWRiYWNrUmVjdGFuZ2xlQ29tcG9uZW50fSBmcm9tICcuL2ZlZWRiYWNrLXJlY3RhbmdsZS9mZWVkYmFjay1yZWN0YW5nbGUuY29tcG9uZW50JztcclxuaW1wb3J0IHtcclxuICBNYXREaWFsb2dNb2R1bGUsXHJcbiAgTWF0QnV0dG9uTW9kdWxlLFxyXG4gIE1hdEljb25Nb2R1bGUsXHJcbiAgTWF0SW5wdXRNb2R1bGUsXHJcbiAgTWF0VG9vbHRpcE1vZHVsZSxcclxuICBNYXRDaGVja2JveE1vZHVsZSxcclxuICBNYXRQcm9ncmVzc1NwaW5uZXJNb2R1bGVcclxufSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbCc7XHJcbmltcG9ydCB7RmVlZGJhY2tTZXJ2aWNlfSBmcm9tICcuL2ZlZWRiYWNrLnNlcnZpY2UnO1xyXG5pbXBvcnQge0ZlZWRiYWNrRGlyZWN0aXZlfSBmcm9tICcuL2ZlZWRiYWNrLmRpcmVjdGl2ZSc7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gIGRlY2xhcmF0aW9uczogW1xyXG4gICAgRmVlZGJhY2tEaWFsb2dDb21wb25lbnQsXHJcbiAgICBGZWVkYmFja1Rvb2xiYXJDb21wb25lbnQsXHJcbiAgICBGZWVkYmFja1JlY3RhbmdsZUNvbXBvbmVudCxcclxuICAgIEZlZWRiYWNrRGlyZWN0aXZlXHJcbiAgXSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBNYXREaWFsb2dNb2R1bGUsXHJcbiAgICBNYXRCdXR0b25Nb2R1bGUsXHJcbiAgICBNYXRJY29uTW9kdWxlLFxyXG4gICAgTWF0SW5wdXRNb2R1bGUsXHJcbiAgICBNYXRUb29sdGlwTW9kdWxlLFxyXG4gICAgQ29tbW9uTW9kdWxlLFxyXG4gICAgRm9ybXNNb2R1bGUsXHJcbiAgICBNYXRDaGVja2JveE1vZHVsZSxcclxuICAgIE1hdFByb2dyZXNzU3Bpbm5lck1vZHVsZVxyXG4gIF0sXHJcbiAgZXhwb3J0czogW1xyXG4gICAgRmVlZGJhY2tEaXJlY3RpdmVcclxuICBdLFxyXG4gIGVudHJ5Q29tcG9uZW50czogW1xyXG4gICAgRmVlZGJhY2tEaWFsb2dDb21wb25lbnRcclxuICBdLFxyXG4gIHByb3ZpZGVyczogW1xyXG4gICAgRmVlZGJhY2tTZXJ2aWNlXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tNb2R1bGUge1xyXG59XHJcbiJdLCJuYW1lcyI6WyJTdWJqZWN0IiwiSW5qZWN0YWJsZSIsIm9ic2VydmFibGVGcm9tRXZlbnQiLCJtZXJnZU1hcCIsIm1hcCIsImZpbmFsaXplIiwidGFrZVVudGlsIiwiQ29tcG9uZW50IiwiTWF0RGlhbG9nUmVmIiwiQ2hhbmdlRGV0ZWN0b3JSZWYiLCJFbGVtZW50UmVmIiwiVmlld0NoaWxkIiwiSG9zdExpc3RlbmVyIiwiRXZlbnRFbWl0dGVyIiwiSW5wdXQiLCJPdXRwdXQiLCJvdmVybGF5IiwiRGlyZWN0aXZlIiwiTWF0RGlhbG9nIiwiT3ZlcmxheSIsIk5nTW9kdWxlIiwiTWF0RGlhbG9nTW9kdWxlIiwiTWF0QnV0dG9uTW9kdWxlIiwiTWF0SWNvbk1vZHVsZSIsIk1hdElucHV0TW9kdWxlIiwiTWF0VG9vbHRpcE1vZHVsZSIsIkNvbW1vbk1vZHVsZSIsIkZvcm1zTW9kdWxlIiwiTWF0Q2hlY2tib3hNb2R1bGUiLCJNYXRQcm9ncmVzc1NwaW5uZXJNb2R1bGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztJQUFBLElBQUE7Ozt1QkFBQTtRQUdDLENBQUE7Ozs7OztBQ0hEOztvQ0FPb0MsRUFBRTtvQ0FDVixRQUFROytCQUNiLE9BQU87MENBQ0ssSUFBSUEsWUFBTyxFQUFxQjtxQ0FDUCxJQUFJLENBQUMsc0JBQXNCLENBQUMsWUFBWSxFQUFFO2tDQUUzRSxJQUFJQSxZQUFPLEVBQVk7NkJBQ1AsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUU7MkNBRXpDLElBQUlBLFlBQU8sRUFBVztzQ0FDUCxJQUFJLENBQUMsdUJBQXVCLENBQUMsWUFBWSxFQUFFOzs7OztRQUdyRiw4Q0FBb0I7Ozs7OztnQkFFekIsSUFB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