lib-sketch-tool
Version:
## Installing with npm $ npm install --save lib-sketch-tool
637 lines • 78.8 kB
JavaScript
import * as tslib_1 from "tslib";
import { Injectable } from '@angular/core';
import { fabric } from 'fabric';
import { AvailableGeometricShape } from './../constants/available-geometric-shapes';
import { SHAPE_DATA } from './../constants/shape-data';
var CanvasManagerService = /** @class */ (function () {
function CanvasManagerService() {
this.canvasId = 'canvas';
this.mousePosition = { x: 0, y: 0 };
this.left = 0;
}
Object.defineProperty(CanvasManagerService.prototype, "canvasObjects", {
get: function () {
return this.canvas.getObjects();
},
enumerable: true,
configurable: true
});
Object.defineProperty(CanvasManagerService.prototype, "canvasBackgroundImage", {
get: function () {
return this.canvas.backgroundImage;
},
enumerable: true,
configurable: true
});
Object.defineProperty(CanvasManagerService.prototype, "activeObject", {
get: function () {
return this.canvas.getActiveObject();
},
enumerable: true,
configurable: true
});
Object.defineProperty(CanvasManagerService.prototype, "activeGroup", {
get: function () {
return this.canvas.getActiveObjects();
},
enumerable: true,
configurable: true
});
Object.defineProperty(CanvasManagerService.prototype, "divCanvasContainer", {
get: function () {
var collection = document.getElementsByClassName('div-canvas-container');
return collection[collection.length - 1];
},
enumerable: true,
configurable: true
});
CanvasManagerService.prototype.createCanvas = function (canvasId) {
this.canvasId = canvasId;
this.canvas = new fabric.Canvas(this.canvasId);
};
CanvasManagerService.prototype.emptyCanvas = function () {
if (this.canvas) {
this.canvas.dispose();
}
this.canvas = new fabric.Canvas(this.canvasId);
this.canvas.clear();
this.canvas.remove(this.canvas.getObjects());
};
CanvasManagerService.prototype.loadNewImage = function (backgroundImageURL) {
this.emptyCanvas();
if (backgroundImageURL) {
this.setBackgroundFromURL(backgroundImageURL);
}
};
CanvasManagerService.prototype.renderCanvas = function () {
this.markSelectedObjectsDirty();
this.canvas.renderAll();
};
CanvasManagerService.prototype.addGeometricShape = function (strokeColor, fillColor, shape) {
switch (shape) {
case AvailableGeometricShape.Rectangle:
this.addRectangle(strokeColor, fillColor);
break;
case AvailableGeometricShape.Circle:
this.addCircle(strokeColor, fillColor);
break;
case AvailableGeometricShape.Triangle:
this.addTriangle(strokeColor, fillColor);
break;
case AvailableGeometricShape.Line:
this.addHorizontalLine(strokeColor, fillColor);
break;
case AvailableGeometricShape.Cross:
this.addCross(strokeColor, fillColor);
break;
}
};
CanvasManagerService.prototype.addRectangle = function (strokeColor, fillColor) {
this.canvas.add(new fabric.Rect({
width: SHAPE_DATA.width,
height: SHAPE_DATA.height,
left: SHAPE_DATA.left,
top: SHAPE_DATA.top,
fill: fillColor,
stroke: strokeColor,
strokeWidth: SHAPE_DATA.stroke,
cornerSize: SHAPE_DATA.cornerSize
}));
};
CanvasManagerService.prototype.addCircle = function (strokeColor, fillColor) {
this.canvas.add(new fabric.Circle({
left: SHAPE_DATA.left,
top: SHAPE_DATA.top,
radius: SHAPE_DATA.radius,
stroke: strokeColor,
strokeWidth: SHAPE_DATA.stroke,
fill: fillColor,
cornerSize: SHAPE_DATA.cornerSize
}));
};
CanvasManagerService.prototype.addTriangle = function (strokeColor, fillColor) {
this.canvas.add(new fabric.Triangle({
width: SHAPE_DATA.width,
height: SHAPE_DATA.height,
left: SHAPE_DATA.left,
top: SHAPE_DATA.top,
fill: fillColor,
stroke: strokeColor,
strokeWidth: SHAPE_DATA.stroke,
cornerSize: SHAPE_DATA.cornerSize
}));
};
CanvasManagerService.prototype.addHorizontalLine = function (strokeColor, fillColor) {
this.canvas.add(this.createHorizontalLine(strokeColor));
};
CanvasManagerService.prototype.createHorizontalLine = function (strokeColor) {
var line = new fabric.Line([100, 150, 200, 150], {
left: 50,
top: 100,
stroke: strokeColor,
strokeWidth: 5,
cornerSize: SHAPE_DATA.cornerSize
});
line.setControlsVisibility({
bl: false,
br: false,
tl: false,
tr: false,
mt: false,
mb: false
});
return line;
};
CanvasManagerService.prototype.createVerticalLine = function (strokeColor) {
var line = new fabric.Line([150, 100, 150, 200], {
left: 100,
top: 50,
stroke: strokeColor,
strokeWidth: 5,
cornerSize: SHAPE_DATA.cornerSize
});
line.setControlsVisibility({
bl: false,
br: false,
tl: false,
tr: false,
ml: false,
mr: false
});
return line;
};
CanvasManagerService.prototype.addCross = function (strokeColor, fillColor) {
var horizontalLine = this.createHorizontalLine(strokeColor);
var verticalLine = this.createVerticalLine(strokeColor);
this.canvas.add(horizontalLine);
this.canvas.add(verticalLine);
};
CanvasManagerService.prototype.toggleFreeDrawing = function () {
this.canvas.isDrawingMode = !this.canvas.isDrawingMode;
};
CanvasManagerService.prototype.setFreeDrawingBrushColor = function (color) {
this.canvas.freeDrawingBrush.color = color;
this.setFreeDrawingBrushWidthFromZoom(this.canvas.getZoom());
};
CanvasManagerService.prototype.setFreeDrawingBrushWidthFromZoom = function (zoom) {
this.canvas.freeDrawingBrush.width = SHAPE_DATA.freeDrawingBrushWidth * (1 / zoom);
};
CanvasManagerService.prototype.addText = function (color, inputText) {
var text = new fabric.IText('text', {
fontFamily: 'arial black',
fontStyle: 'bold',
left: SHAPE_DATA.left,
top: SHAPE_DATA.top,
cornerSize: SHAPE_DATA.cornerSize
});
text.setColor(color);
this.canvas.add(text);
};
CanvasManagerService.prototype.addImage = function (imageURL) {
var _this = this;
return new Promise(function (resolve, reject) {
var canvas = _this.canvas;
var image = new Image();
image.onload = function (img) {
var fabricImage = new fabric.Image(image, {
angle: 0,
width: image.width,
height: image.height,
left: SHAPE_DATA.left,
top: SHAPE_DATA.top,
scaleX: 1,
scaleY: 1,
cornerSize: SHAPE_DATA.cornerSize
});
canvas.add(fabricImage);
resolve();
};
image.src = imageURL;
});
};
CanvasManagerService.prototype.setBackgroundFromURL = function (backgroundImageURL) {
var _this = this;
var container = this.divCanvasContainer;
this.setCanvasSize(container.clientWidth, container.clientHeight);
return new Promise(function (resolve, reject) {
if (backgroundImageURL == null) {
return reject();
}
var image = new Image();
image.onload = function () {
var f_img = new fabric.Image(image, {});
var scaleData = _this.computeScaleFactor(f_img, _this.canvas);
_this.canvas.setBackgroundImage(f_img, _this.canvas.renderAll.bind(_this.canvas), {
scaleX: scaleData.scaleFactor,
scaleY: scaleData.scaleFactor
});
_this.setCanvasSize(f_img.width * scaleData.scaleFactor, f_img.height * scaleData.scaleFactor);
_this.canvas.renderAll();
resolve();
};
image.src = backgroundImageURL;
});
};
CanvasManagerService.prototype.computeScaleFactor = function (f_img, canvas) {
var container = this.divCanvasContainer;
var canvasAspect = container.clientWidth / container.clientHeight;
var imgAspect = f_img.width / f_img.height;
var left, top, scaleFactor;
if (canvasAspect <= imgAspect) {
scaleFactor = container.clientWidth / f_img.width;
left = 0;
top = -(f_img.height * scaleFactor - container.clientHeight) / 2;
}
else {
scaleFactor = container.clientHeight / f_img.height;
top = 0;
left = -(f_img.width * scaleFactor - container.clientWidth) / 2;
}
this.left = left;
return { scaleFactor: scaleFactor, left: left, top: top };
};
CanvasManagerService.prototype.onOrientationChange = function () {
this.mousePosition = { x: this.canvas.getWidth, y: this.canvas.getHeight };
this.cropImage();
};
CanvasManagerService.prototype.changeSelectedObjectsFillColor = function (color) {
var e_1, _a;
var activeObjects = this.canvas.getActiveObjects();
if (activeObjects) {
try {
for (var activeObjects_1 = tslib_1.__values(activeObjects), activeObjects_1_1 = activeObjects_1.next(); !activeObjects_1_1.done; activeObjects_1_1 = activeObjects_1.next()) {
var object = activeObjects_1_1.value;
object.setColor(color);
this.canvas.renderAll();
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (activeObjects_1_1 && !activeObjects_1_1.done && (_a = activeObjects_1.return)) _a.call(activeObjects_1);
}
finally { if (e_1) throw e_1.error; }
}
}
};
CanvasManagerService.prototype.changeSelectedObjectsStrokeColor = function (color) {
var e_2, _a;
var activeObjects = this.canvas.getActiveObjects();
if (activeObjects) {
try {
for (var activeObjects_2 = tslib_1.__values(activeObjects), activeObjects_2_1 = activeObjects_2.next(); !activeObjects_2_1.done; activeObjects_2_1 = activeObjects_2.next()) {
var object = activeObjects_2_1.value;
if (object.type === 'i-text') {
object.setColor(color);
}
else {
object.stroke = color;
object.set('dirty', true);
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (activeObjects_2_1 && !activeObjects_2_1.done && (_a = activeObjects_2.return)) _a.call(activeObjects_2);
}
finally { if (e_2) throw e_2.error; }
}
this.canvas.renderAll();
}
};
CanvasManagerService.prototype.deleteSelectedObjects = function () {
var e_3, _a;
var activeObjects = this.canvas.getActiveObjects();
if (activeObjects) {
try {
for (var activeObjects_3 = tslib_1.__values(activeObjects), activeObjects_3_1 = activeObjects_3.next(); !activeObjects_3_1.done; activeObjects_3_1 = activeObjects_3.next()) {
var object = activeObjects_3_1.value;
this.canvas.remove(object);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (activeObjects_3_1 && !activeObjects_3_1.done && (_a = activeObjects_3.return)) _a.call(activeObjects_3);
}
finally { if (e_3) throw e_3.error; }
}
this.canvas.discardActiveObject();
this.canvas.renderAll();
}
};
CanvasManagerService.prototype.bringSelectedObjectsToFront = function () {
var e_4, _a;
var activeObjects = this.canvas.getActiveObjects();
if (activeObjects) {
try {
for (var activeObjects_4 = tslib_1.__values(activeObjects), activeObjects_4_1 = activeObjects_4.next(); !activeObjects_4_1.done; activeObjects_4_1 = activeObjects_4.next()) {
var object = activeObjects_4_1.value;
this.canvas.bringToFront(object);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (activeObjects_4_1 && !activeObjects_4_1.done && (_a = activeObjects_4.return)) _a.call(activeObjects_4);
}
finally { if (e_4) throw e_4.error; }
}
}
};
CanvasManagerService.prototype.sendSelectedObjectsToBack = function () {
var e_5, _a;
var activeObjects = this.canvas.getActiveObjects();
if (activeObjects) {
try {
for (var activeObjects_5 = tslib_1.__values(activeObjects), activeObjects_5_1 = activeObjects_5.next(); !activeObjects_5_1.done; activeObjects_5_1 = activeObjects_5.next()) {
var object = activeObjects_5_1.value;
this.canvas.sendToBack(object);
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (activeObjects_5_1 && !activeObjects_5_1.done && (_a = activeObjects_5.return)) _a.call(activeObjects_5);
}
finally { if (e_5) throw e_5.error; }
}
}
};
CanvasManagerService.prototype.jsonFromCanvas = function () {
return this.canvas.toJSON(['width', 'height']);
};
CanvasManagerService.prototype.loadfromJson = function (json) {
var _this = this;
var container = this.divCanvasContainer;
this.setCanvasSize(container.clientWidth, container.clientHeight);
return new Promise(function (resolve, reject) {
_this.adjustCanvas(json);
_this.canvas.loadFromJSON(json, _this.canvas.renderAll.bind(_this.canvas));
_this.canvas.renderAll();
resolve();
});
};
CanvasManagerService.prototype.adjustCanvas = function (json) {
var backgroundImage = json['backgroundImage'];
var container = this.divCanvasContainer;
var width = json['width'];
var height = json['height'];
var canvasWidth = container.clientWidth;
var canvasHeight = container.clientHeight;
var canvasAspect = canvasWidth / canvasHeight;
var imgAspect = width / height;
var scaleFactor, left;
if (canvasAspect <= imgAspect) {
scaleFactor = canvasWidth / width;
left = 0;
}
else {
scaleFactor = canvasHeight / height;
left = -(width * scaleFactor - container.clientWidth) / 2;
}
this.left = left;
backgroundImage['scaleX'] *= scaleFactor;
backgroundImage['scaleY'] *= scaleFactor;
this.setCanvasSize(width * scaleFactor, height * scaleFactor);
var objects = json['objects'];
for (var i = 0; i < objects.length; i++) {
objects[i]['left'] *= scaleFactor;
objects[i]['top'] *= scaleFactor;
objects[i]['scaleX'] *= scaleFactor;
objects[i]['scaleY'] *= scaleFactor;
}
};
CanvasManagerService.prototype.exportImageAsDataURL = function () {
return this.canvas.toDataURL('image/png');
};
CanvasManagerService.prototype.selectItem = function (itemNumber) {
this.canvas.setActiveObject(this.canvas.item(itemNumber));
};
CanvasManagerService.prototype.getIndexOf = function (activeObject) {
return this.canvas.getObjects().indexOf(activeObject);
};
CanvasManagerService.prototype.markSelectedObjectsDirty = function () {
var e_6, _a;
var activeObjects = this.canvas.getActiveObjects();
if (activeObjects) {
try {
for (var activeObjects_6 = tslib_1.__values(activeObjects), activeObjects_6_1 = activeObjects_6.next(); !activeObjects_6_1.done; activeObjects_6_1 = activeObjects_6.next()) {
var object = activeObjects_6_1.value;
object.set('dirty', true);
}
}
catch (e_6_1) { e_6 = { error: e_6_1 }; }
finally {
try {
if (activeObjects_6_1 && !activeObjects_6_1.done && (_a = activeObjects_6.return)) _a.call(activeObjects_6);
}
finally { if (e_6) throw e_6.error; }
}
}
};
CanvasManagerService.prototype.addSelectionRectangle = function () {
this.cropRectangle = new fabric.Rect({
fill: 'transparent',
originX: 'left',
originY: 'top',
stroke: '#ccc',
strokeDashArray: [2, 2],
opacity: 1,
width: 0,
height: 0
});
this.cropRectangle.visible = false;
this.canvas.add(this.cropRectangle);
};
CanvasManagerService.prototype.ajustCropRectangleFromMouse = function (event) {
var x = Math.min(event.offsetX, this.mousePosition.x), y = Math.min(event.offsetY, this.mousePosition.y), w = Math.abs(event.offsetX - this.mousePosition.x), h = Math.abs(event.offsetY - this.mousePosition.y);
if (!w || !h) {
return false;
}
this.cropRectangle
.set('top', y)
.set('left', x)
.set('width', w)
.set('height', h);
this.canvas.renderAll();
return true;
};
CanvasManagerService.prototype.startSelectingCropRectangleFromMouse = function (event) {
this.cropRectangle.left = event.offsetX;
this.cropRectangle.top = event.offsetY;
this.cropRectangle.setCoords();
this.mousePosition = { x: event.offsetX, y: event.offsetY };
this.cropRectangle.visible = true;
this.canvas.bringToFront(this.cropRectangle);
};
CanvasManagerService.prototype.cropImage = function () {
var left = this.cropRectangle.left;
var top = this.cropRectangle.top;
var width = this.cropRectangle.width;
var height = this.cropRectangle.height;
var container = this.divCanvasContainer;
var canvasWidth = container.clientWidth;
var canvasHeight = container.clientHeight;
var canvasAspect = canvasWidth / canvasHeight;
var imgAspect = width / height;
var scaleFactor;
if (canvasAspect <= imgAspect) {
scaleFactor = canvasWidth / width;
}
else {
scaleFactor = canvasHeight / height;
}
this.setCanvasSize(width * scaleFactor, height * scaleFactor);
this.canvas.backgroundImage.scaleX *= scaleFactor;
this.canvas.backgroundImage.scaleY *= scaleFactor;
this.canvas.backgroundImage.left -= left;
this.canvas.backgroundImage.left *= scaleFactor;
this.canvas.backgroundImage.top -= top - scaleFactor;
this.canvas.backgroundImage.top *= scaleFactor;
this.moveAllObjectsInCanvas(-1 * left, -1 * top, scaleFactor);
this.enableSlection();
this.cropRectangle.visible = false;
this.canvas.remove(this.cropRectangle);
this.canvas.renderAll();
};
CanvasManagerService.prototype.enableSlection = function () {
this.canvas.selectable = true;
this.canvas.selection = true;
};
CanvasManagerService.prototype.ajustCropRectangle = function (event) {
var touch = event.touches[0];
var rect = event.target.getBoundingClientRect();
var x = Math.min(touch.clientX - rect.left, this.mousePosition.x), y = Math.min(touch.clientY - rect.top, this.mousePosition.y), w = Math.abs(touch.clientX - rect.left - this.mousePosition.x), h = Math.abs(touch.clientY - rect.top - this.mousePosition.y);
if (!w || !h) {
return false;
}
this.cropRectangle
.set('left', x)
.set('top', y)
.set('width', w)
.set('height', h);
this.canvas.renderAll();
return true;
};
CanvasManagerService.prototype.startSelectingCropRectangle = function (event) {
var touch = event.touches[0];
var rect = event.target.getBoundingClientRect();
this.cropRectangle.left = touch.clientX - rect.left;
this.cropRectangle.top = touch.clientY - rect.top;
this.cropRectangle.setCoords();
this.mousePosition = { x: touch.clientX - rect.left, y: touch.clientY - rect.top };
this.canvas.renderAll();
this.cropRectangle.visible = true;
this.canvas.bringToFront(this.cropRectangle);
};
CanvasManagerService.prototype.disableSelection = function () {
this.canvas.selection = false;
};
CanvasManagerService.prototype.moveAllObjectsInCanvas = function (x, y, scaleFactor) {
var e_7, _a;
var objects = this.canvas.getObjects();
try {
for (var objects_1 = tslib_1.__values(objects), objects_1_1 = objects_1.next(); !objects_1_1.done; objects_1_1 = objects_1.next()) {
var obj = objects_1_1.value;
obj.left += x;
obj.left *= scaleFactor;
obj.scaleX *= scaleFactor;
obj.top += y;
obj.scaleY *= scaleFactor;
obj.top *= scaleFactor;
obj.setCoords();
}
}
catch (e_7_1) { e_7 = { error: e_7_1 }; }
finally {
try {
if (objects_1_1 && !objects_1_1.done && (_a = objects_1.return)) _a.call(objects_1);
}
finally { if (e_7) throw e_7.error; }
}
};
CanvasManagerService.prototype.groupSelectedObjects = function () {
var e_8, _a;
var activeObjects = this.canvas.getActiveObjects();
if (activeObjects) {
var objects = [];
try {
for (var activeObjects_7 = tslib_1.__values(activeObjects), activeObjects_7_1 = activeObjects_7.next(); !activeObjects_7_1.done; activeObjects_7_1 = activeObjects_7.next()) {
var object = activeObjects_7_1.value;
objects.push(object);
}
}
catch (e_8_1) { e_8 = { error: e_8_1 }; }
finally {
try {
if (activeObjects_7_1 && !activeObjects_7_1.done && (_a = activeObjects_7.return)) _a.call(activeObjects_7);
}
finally { if (e_8) throw e_8.error; }
}
this.deleteSelectedObjects();
var group = new fabric.Group(objects);
this.canvas.add(group);
group.setCoords();
this.canvas.setActiveObject(group);
this.canvas.renderAll();
}
};
CanvasManagerService.prototype.setLastPanPosition = function (event) {
this.lastPanPosition = new fabric.Point(event.touches[0].clientX, event.touches[0].clientY);
};
CanvasManagerService.prototype.panCanvas = function (event) {
var delta = new fabric.Point(event.touches[0].clientX - this.lastPanPosition.x, event.touches[0].clientY - this.lastPanPosition.y);
this.canvas.relativePan(delta);
this.preventPanOutsideCanvas();
this.canvas.renderAll();
this.setLastPanPosition(event);
};
CanvasManagerService.prototype.preventPanOutsideCanvas = function () {
var canvasViewPort = this.canvas.viewportTransform;
var bottomEndPoint = this.canvas.height * (canvasViewPort[0] - 1);
if (canvasViewPort[5] >= 0 || -bottomEndPoint > canvasViewPort[5]) {
canvasViewPort[5] = (canvasViewPort[5] >= 0) ? 0 : -bottomEndPoint;
}
var rightEndPoint = this.canvas.width * (canvasViewPort[0] - 1);
if (canvasViewPort[4] >= 0 || -rightEndPoint > canvasViewPort[4]) {
canvasViewPort[4] = (canvasViewPort[4] >= 0) ? 0 : -rightEndPoint;
}
};
CanvasManagerService.prototype.zoom = function (event) {
if (Math.abs(event.overallVelocity) > 0.005) {
var point = new fabric.Point(event.center.x, event.center.y);
var zoom = this.canvas.getZoom();
zoom = zoom + (event.scale - zoom) / 20;
if (zoom < 1) {
zoom = 1;
this.canvas.zoomToPoint(new fabric.Point(0, 0), zoom);
this.canvas.absolutePan(new fabric.Point(0, 0));
}
else {
if (zoom > 10) {
zoom = 10;
}
this.canvas.zoomToPoint(point, zoom);
}
this.setFreeDrawingBrushWidthFromZoom(zoom);
this.canvas.renderAll();
}
};
CanvasManagerService.prototype.setCanvasSize = function (width, height) {
this.canvas.setWidth(width);
this.canvas.setHeight(height);
};
CanvasManagerService.prototype.resetZoom = function () {
this.canvas.zoomToPoint(new fabric.Point(0, 0), 1);
this.canvas.absolutePan(new fabric.Point(0, 0));
};
CanvasManagerService = tslib_1.__decorate([
Injectable(),
tslib_1.__metadata("design:paramtypes", [])
], CanvasManagerService);
return CanvasManagerService;
}());
export { CanvasManagerService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FudmFzLW1hbmFnZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2xpYi1za2V0Y2gtdG9vbC8iLCJzb3VyY2VzIjpbImFwcC9saWItc2tldGNoLXRvb2wvc2VydmljZXMvY2FudmFzLW1hbmFnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRWhDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQWN2RDtJQVNFO1FBRlEsYUFBUSxHQUFJLFFBQVEsQ0FBQztRQUczQixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7SUFDaEIsQ0FBQztJQUVELHNCQUFJLCtDQUFhO2FBQWpCO1lBQ0UsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLENBQUM7OztPQUFBO0lBRUQsc0JBQUksdURBQXFCO2FBQXpCO1lBQ0UsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQztRQUNyQyxDQUFDOzs7T0FBQTtJQUVELHNCQUFJLDhDQUFZO2FBQWhCO1lBQ0UsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7OztPQUFBO0lBRUQsc0JBQUksNkNBQVc7YUFBZjtZQUNFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hDLENBQUM7OztPQUFBO0lBRUQsc0JBQUksb0RBQWtCO2FBQXRCO1lBQ0UsSUFBSSxVQUFVLEdBQUcsUUFBUSxDQUFD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b3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZmFicmljIH0gZnJvbSAnZmFicmljJztcblxuaW1wb3J0IHsgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUgfSBmcm9tICcuLy4uL2NvbnN0YW50cy9hdmFpbGFibGUtZ2VvbWV0cmljLXNoYXBlcyc7XG5pbXBvcnQgeyBTSEFQRV9EQVRBIH0gZnJvbSAnLi8uLi9jb25zdGFudHMvc2hhcGUtZGF0YSc7XG5cbmludGVyZmFjZSBTY2FsZURhdGEge1xuICBzY2FsZUZhY3RvcjogbnVtYmVyO1xuICBsZWZ0OiBudW1iZXI7XG4gIHRvcDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUG9zaXRpb24ge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENhbnZhc01hbmFnZXJTZXJ2aWNlIHtcbiAgcHVibGljIGNhbnZhcztcbiAgcHVibGljIGxlZnQ7XG5cbiAgcHJpdmF0ZSBjcm9wUmVjdGFuZ2xlOiBmYWJyaWMuUmVjdDtcbiAgcHJpdmF0ZSBtb3VzZVBvc2l0aW9uOiBQb3NpdGlvbjtcbiAgcHJpdmF0ZSBsYXN0UGFuUG9zaXRpb246IGZhYnJpYy5Qb2ludDtcbiAgcHJpdmF0ZSBjYW52YXNJZCA9ICAnY2FudmFzJztcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLm1vdXNlUG9zaXRpb24gPSB7eDogMCwgeTogMH07XG4gICAgdGhpcy5sZWZ0ID0gMDtcbiAgfVxuXG4gIGdldCBjYW52YXNPYmplY3RzKCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCk7XG4gIH1cblxuICBnZXQgY2FudmFzQmFja2dyb3VuZEltYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2U7XG4gIH1cblxuICBnZXQgYWN0aXZlT2JqZWN0KCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3QoKTtcbiAgfVxuXG4gIGdldCBhY3RpdmVHcm91cCgpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuICB9XG5cbiAgZ2V0IGRpdkNhbnZhc0NvbnRhaW5lcigpIHtcbiAgICBsZXQgY29sbGVjdGlvbiA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2Rpdi1jYW52YXMtY29udGFpbmVyJyk7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb25bY29sbGVjdGlvbi5sZW5ndGggLTFdO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZUNhbnZhcyhjYW52YXNJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jYW52YXNJZCA9IGNhbnZhc0lkO1xuICAgIHRoaXMuY2FudmFzID0gbmV3IGZhYnJpYy5DYW52YXModGhpcy5jYW52YXNJZCk7XG4gIH1cblxuICBwdWJsaWMgZW1wdHlDYW52YXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2FudmFzKSB7XG4gICAgICB0aGlzLmNhbnZhcy5kaXNwb3NlKCk7XG4gICAgfVxuICAgIHRoaXMuY2FudmFzID0gbmV3IGZhYnJpYy5DYW52YXModGhpcy5jYW52YXNJZCk7XG4gICAgdGhpcy5jYW52YXMuY2xlYXIoKTtcbiAgICB0aGlzLmNhbnZhcy5yZW1vdmUodGhpcy5jYW52YXMuZ2V0T2JqZWN0cygpKTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkTmV3SW1hZ2UoYmFja2dyb3VuZEltYWdlVVJMPzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5lbXB0eUNhbnZhcygpO1xuICAgIGlmIChiYWNrZ3JvdW5kSW1hZ2VVUkwpIHtcbiAgICAgIHRoaXMuc2V0QmFja2dyb3VuZEZyb21VUkwoYmFja2dyb3VuZEltYWdlVVJMKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcmVuZGVyQ2FudmFzKCk6IHZvaWQge1xuICAgIHRoaXMubWFya1NlbGVjdGVkT2JqZWN0c0RpcnR5KCk7XG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gIH1cblxuICBwdWJsaWMgYWRkR2VvbWV0cmljU2hhcGUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcsIHNoYXBlOiBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZSk6IHZvaWQge1xuICAgIHN3aXRjaCAoc2hhcGUpIHtcbiAgICAgIGNhc2UgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuUmVjdGFuZ2xlOlxuICAgICAgICB0aGlzLmFkZFJlY3RhbmdsZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLkNpcmNsZTpcbiAgICAgICAgdGhpcy5hZGRDaXJjbGUoc3Ryb2tlQ29sb3IsIGZpbGxDb2xvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5UcmlhbmdsZTpcbiAgICAgICAgdGhpcy5hZGRUcmlhbmdsZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLkxpbmU6XG4gICAgICAgIHRoaXMuYWRkSG9yaXpvbnRhbExpbmUoc3Ryb2tlQ29sb3IsIGZpbGxDb2xvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5Dcm9zczpcbiAgICAgICAgdGhpcy5hZGRDcm9zcyhzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRSZWN0YW5nbGUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5hZGQoXG4gICAgICBuZXcgZmFicmljLlJlY3Qoe1xuICAgICAgICB3aWR0aDogU0hBUEVfREFUQS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBTSEFQRV9EQVRBLmhlaWdodCxcbiAgICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgICB0b3A6IFNIQVBFX0RBVEEudG9wLFxuICAgICAgICBmaWxsOiBmaWxsQ29sb3IsXG4gICAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICAgIHN0cm9rZVdpZHRoOiBTSEFQRV9EQVRBLnN0cm9rZSxcbiAgICAgICAgY29ybmVyU2l6ZTogU0hBUEVfREFUQS5jb3JuZXJTaXplXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFkZENpcmNsZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmFkZChcbiAgICAgIG5ldyBmYWJyaWMuQ2lyY2xlKHtcbiAgICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgICB0b3A6IFNIQVBFX0RBVEEudG9wLFxuICAgICAgICByYWRpdXM6IFNIQVBFX0RBVEEucmFkaXVzLFxuICAgICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogU0hBUEVfREFUQS5zdHJva2UsXG4gICAgICAgIGZpbGw6IGZpbGxDb2xvcixcbiAgICAgICAgY29ybmVyU2l6ZTogU0hBUEVfREFUQS5jb3JuZXJTaXplXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRyaWFuZ2xlKHN0cm9rZUNvbG9yOiBzdHJpbmcsIGZpbGxDb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jYW52YXMuYWRkKFxuICAgICAgbmV3IGZhYnJpYy5UcmlhbmdsZSh7XG4gICAgICAgIHdpZHRoOiBTSEFQRV9EQVRBLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IFNIQVBFX0RBVEEuaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBTSEFQRV9EQVRBLmxlZnQsXG4gICAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICAgIGZpbGw6IGZpbGxDb2xvcixcbiAgICAgICAgc3Ryb2tlOiBzdHJva2VDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IFNIQVBFX0RBVEEuc3Ryb2tlLFxuICAgICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkSG9yaXpvbnRhbExpbmUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5hZGQodGhpcy5jcmVhdGVIb3Jpem9udGFsTGluZShzdHJva2VDb2xvcikpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVIb3Jpem9udGFsTGluZShzdHJva2VDb2xvcjogc3RyaW5nKTogZmFicmljLkxpbmUge1xuICAgIGNvbnN0IGxpbmUgPSBuZXcgZmFicmljLkxpbmUoWzEwMCwgMTUwLCAyMDAsIDE1MF0sIHtcbiAgICAgIGxlZnQ6IDUwLFxuICAgICAgdG9wOiAxMDAsXG4gICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgc3Ryb2tlV2lkdGg6IDUsXG4gICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICB9KTtcblxuICAgIGxpbmUuc2V0Q29udHJvbHNWaXNpYmlsaXR5KHtcbiAgICAgIGJsOiBmYWxzZSxcbiAgICAgIGJyOiBmYWxzZSxcbiAgICAgIHRsOiBmYWxzZSxcbiAgICAgIHRyOiBmYWxzZSxcbiAgICAgIG10OiBmYWxzZSxcbiAgICAgIG1iOiBmYWxzZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVZlcnRpY2FsTGluZShzdHJva2VDb2xvcjogc3RyaW5nKTogZmFicmljLkxpbmUge1xuICAgIGNvbnN0IGxpbmUgPSBuZXcgZmFicmljLkxpbmUoWzE1MCwgMTAwLCAxNTAsIDIwMF0sIHtcbiAgICAgIGxlZnQ6IDEwMCxcbiAgICAgIHRvcDogNTAsXG4gICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgc3Ryb2tlV2lkdGg6IDUsXG4gICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICB9KTtcblxuICAgIGxpbmUuc2V0Q29udHJvbHNWaXNpYmlsaXR5KHtcbiAgICAgIGJsOiBmYWxzZSxcbiAgICAgIGJyOiBmYWxzZSxcbiAgICAgIHRsOiBmYWxzZSxcbiAgICAgIHRyOiBmYWxzZSxcbiAgICAgIG1sOiBmYWxzZSxcbiAgICAgIG1yOiBmYWxzZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICBwcml2YXRlIGFkZENyb3NzKHN0cm9rZUNvbG9yOiBzdHJpbmcsIGZpbGxDb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgaG9yaXpvbnRhbExpbmUgPSB0aGlzLmNyZWF0ZUhvcml6b250YWxMaW5lKHN0cm9rZUNvbG9yKTtcbiAgICBjb25zdCB2ZXJ0aWNhbExpbmUgPSB0aGlzLmNyZWF0ZVZlcnRpY2FsTGluZShzdHJva2VDb2xvcik7XG4gICAgdGhpcy5jYW52YXMuYWRkKGhvcml6b250YWxMaW5lKTtcbiAgICB0aGlzLmNhbnZhcy5hZGQodmVydGljYWxMaW5lKTtcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVGcmVlRHJhd2luZygpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5pc0RyYXdpbmdNb2RlID0gIXRoaXMuY2FudmFzLmlzRHJhd2luZ01vZGU7XG4gIH1cblxuICBwdWJsaWMgc2V0RnJlZURyYXdpbmdCcnVzaENvbG9yKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5mcmVlRHJhd2luZ0JydXNoLmNvbG9yID0gY29sb3I7XG4gICAgdGhpcy5zZXRGcmVlRHJhd2luZ0JydXNoV2lkdGhGcm9tWm9vbSh0aGlzLmNhbnZhcy5nZXRab29tKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRGcmVlRHJhd2luZ0JydXNoV2lkdGhGcm9tWm9vbSh6b29tOiBudW1iZXIpIHtcbiAgICB0aGlzLmNhbnZhcy5mcmVlRHJhd2luZ0JydXNoLndpZHRoID0gU0hBUEVfREFUQS5mcmVlRHJhd2luZ0JydXNoV2lkdGggKiAoMSAvIHpvb20pO1xuICB9XG5cbiAgcHVibGljIGFkZFRleHQoY29sb3I6IHN0cmluZywgaW5wdXRUZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB0ZXh0ID0gbmV3IGZhYnJpYy5JVGV4dCgndGV4dCcsIHtcbiAgICAgIGZvbnRGYW1pbHk6ICdhcmlhbCBibGFjaycsXG4gICAgICBmb250U3R5bGU6ICdib2xkJyxcbiAgICAgIGxlZnQ6IFNIQVBFX0RBVEEubGVmdCxcbiAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICB9KTtcblxuICAgIHRleHQuc2V0Q29sb3IoY29sb3IpO1xuXG4gICAgdGhpcy5jYW52YXMuYWRkKHRleHQpO1xuICB9XG5cbiAgcHVibGljIGFkZEltYWdlKGltYWdlVVJMOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoXG4gICAgICAocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuY2FudmFzO1xuXG4gICAgICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XG4gICAgICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uKGltZykge1xuICAgICAgICAgIGNvbnN0IGZhYnJpY0ltYWdlID0gbmV3IGZhYnJpYy5JbWFnZShpbWFnZSwge1xuICAgICAgICAgICAgYW5nbGU6IDAsXG4gICAgICAgICAgICB3aWR0aDogaW1hZ2Uud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IGltYWdlLmhlaWdodCxcbiAgICAgICAgICAgIGxlZnQ6IFNIQVBFX0RBVEEubGVmdCxcbiAgICAgICAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICAgICAgICBzY2FsZVg6IDEsXG4gICAgICAgICAgICBzY2FsZVk6IDEsXG4gICAgICAgICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjYW52YXMuYWRkKGZhYnJpY0ltYWdlKTtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIGltYWdlLnNyYyA9IGltYWdlVVJMO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc2V0QmFja2dyb3VuZEZyb21VUkwoYmFja2dyb3VuZEltYWdlVVJMOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb250YWluZXIgPSAgdGhpcy5kaXZDYW52YXNDb250YWluZXI7XG4gICAgdGhpcy5zZXRDYW52YXNTaXplKGNvbnRhaW5lci5jbGllbnRXaWR0aCwgY29udGFpbmVyLmNsaWVudEhlaWdodCk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoXG4gICAgICAocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICAgIGlmIChiYWNrZ3JvdW5kSW1hZ2VVUkwgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiByZWplY3QoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgICAgICBpbWFnZS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZl9pbWcgPSBuZXcgZmFicmljLkltYWdlKGltYWdlLCB7fSk7XG5cbiAgICAgICAgICBjb25zdCBzY2FsZURhdGEgPSB0aGlzLmNvbXB1dGVTY2FsZUZhY3RvcihmX2ltZywgdGhpcy5jYW52YXMpO1xuXG4gICAgICAgICAgdGhpcy5jYW52YXMuc2V0QmFja2dyb3VuZEltYWdlKGZfaW1nLCB0aGlzLmNhbnZhcy5yZW5kZXJBbGwuYmluZCh0aGlzLmNhbnZhcyksIHtcbiAgICAgICAgICAgIHNjYWxlWDogc2NhbGVEYXRhLnNjYWxlRmFjdG9yLFxuICAgICAgICAgICAgc2NhbGVZOiBzY2FsZURhdGEuc2NhbGVGYWN0b3JcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMuc2V0Q2FudmFzU2l6ZShmX2ltZy53aWR0aCAqIHNjYWxlRGF0YS5zY2FsZUZhY3RvciwgZl9pbWcuaGVpZ2h0ICogc2NhbGVEYXRhLnNjYWxlRmFjdG9yKTtcblxuICAgICAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1hZ2Uuc3JjID0gYmFja2dyb3VuZEltYWdlVVJMO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGNvbXB1dGVTY2FsZUZhY3RvcihmX2ltZzogZmFicmljLkltYWdlLCBjYW52YXM6IGZhYnJpYy5DYW52YXMpOiBTY2FsZURhdGEge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZGl2Q2FudmFzQ29udGFpbmVyO1xuXG4gICAgY29uc3QgY2FudmFzQXNwZWN0ID0gY29udGFpbmVyLmNsaWVudFdpZHRoIC8gY29udGFpbmVyLmNsaWVudEhlaWdodDtcbiAgICBjb25zdCBpbWdBc3BlY3QgPSBmX2ltZy53aWR0aCAvIGZfaW1nLmhlaWdodDtcbiAgICBsZXQgbGVmdCwgdG9wLCBzY2FsZUZhY3RvcjtcblxuICAgIGlmIChjYW52YXNBc3BlY3QgPD0gaW1nQXNwZWN0KSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNvbnRhaW5lci5jbGllbnRXaWR0aCAvIGZfaW1nLndpZHRoO1xuICAgICAgbGVmdCA9IDA7XG4gICAgICB0b3AgPSAtKGZfaW1nLmhlaWdodCAqIHNjYWxlRmFjdG9yIC0gY29udGFpbmVyLmNsaWVudEhlaWdodCkgLyAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNvbnRhaW5lci5jbGllbnRIZWlnaHQgLyBmX2ltZy5oZWlnaHQ7XG4gICAgICB0b3AgPSAwO1xuICAgICAgbGVmdCA9IC0oZl9pbWcud2lkdGggKiBzY2FsZUZhY3RvciAtIGNvbnRhaW5lci5jbGllbnRXaWR0aCkgLyAyO1xuICAgIH1cblxuICAgIHRoaXMubGVmdCA9IGxlZnQ7XG5cbiAgICByZXR1cm4geyBzY2FsZUZhY3Rvcjogc2NhbGVGYWN0b3IsIGxlZnQ6IGxlZnQsIHRvcDogdG9wIH07XG4gIH1cblxuICBwdWJsaWMgb25PcmllbnRhdGlvbkNoYW5nZSgpIHtcbiAgICB0aGlzLm1vdXNlUG9zaXRpb24gPSB7eDogdGhpcy5jYW52YXMuZ2V0V2lkdGgsIHk6IHRoaXMuY2FudmFzLmdldEhlaWdodCB9O1xuICAgIHRoaXMuY3JvcEltYWdlKCk7XG4gIH1cblxuICBwdWJsaWMgY2hhbmdlU2VsZWN0ZWRPYmplY3RzRmlsbENvbG9yKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVPYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuXG4gICAgaWYgKGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgb2JqZWN0LnNldENvbG9yKGNvbG9yKTtcbiAgICAgICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNoYW5nZVNlbGVjdGVkT2JqZWN0c1N0cm9rZUNvbG9yKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVPYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuXG4gICAgaWYgKGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgaWYgKG9iamVjdC50eXBlID09PSAnaS10ZXh0Jykge1xuICAgICAgICAgIG9iamVjdC5zZXRDb2xvcihjb2xvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb2JqZWN0LnN0cm9rZSA9IGNvbG9yO1xuICAgICAgICAgIG9iamVjdC5zZXQoJ2RpcnR5JywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBkZWxldGVTZWxlY3RlZE9iamVjdHMoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIHRoaXMuY2FudmFzLnJlbW92ZShvYmplY3QpO1xuICAgICAgfVxuICAgICAgdGhpcy5jYW52YXMuZGlzY2FyZEFjdGl2ZU9iamVjdCgpO1xuICAgICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGJyaW5nU2VsZWN0ZWRPYmplY3RzVG9Gcm9udCgpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVPYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuXG4gICAgaWYgKGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgdGhpcy5jYW52YXMuYnJpbmdUb0Zyb250KG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNlbmRTZWxlY3RlZE9iamVjdHNUb0JhY2soKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIHRoaXMuY2FudmFzLnNlbmRUb0JhY2sob2JqZWN0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMganNvbkZyb21DYW52YXMoKTogSlNPTiB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLnRvSlNPTihbJ3dpZHRoJywgJ2hlaWdodCddKTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkZnJvbUpzb24oanNvbjogSlNPTik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZGl2Q2FudmFzQ29udGFpbmVyO1xuXG4gICAgdGhpcy5zZXRDYW52YXNTaXplKGNvbnRhaW5lci5jbGllbnRXaWR0aCwgY29udGFpbmVyLmNsaWVudEhlaWdodCk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoXG4gICAgICAocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuYWRqdXN0Q2FudmFzKGpzb24pO1xuICAgICAgICB0aGlzLmNhbnZhcy5sb2FkRnJvbUpTT04oanNvbiwgdGhpcy5jYW52YXMucmVuZGVyQWxsLmJpbmQodGhpcy5jYW52YXMpKTtcbiAgICAgICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcHVibGljIGFkanVzdENhbnZhcyhqc29uOiBKU09OKTogdm9pZCB7XG4gICAgY29uc3QgYmFja2dyb3VuZEltYWdlID0ganNvblsnYmFja2dyb3VuZEltYWdlJ107XG5cbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmRpdkNhbnZhc0NvbnRhaW5lcjtcblxuICAgIGNvbnN0IHdpZHRoID0ganNvblsnd2lkdGgnXTtcbiAgICBjb25zdCBoZWlnaHQgPSBqc29uWydoZWlnaHQnXTtcblxuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IGNvbnRhaW5lci5jbGllbnRIZWlnaHQ7XG5cbiAgICBjb25zdCBjYW52YXNBc3BlY3QgPSBjYW52YXNXaWR0aCAvIGNhbnZhc0hlaWdodDtcbiAgICBjb25zdCBpbWdBc3BlY3QgPSB3aWR0aCAvIGhlaWdodDtcbiAgICBsZXQgc2NhbGVGYWN0b3IsIGxlZnQ7XG5cbiAgICBpZiAoY2FudmFzQXNwZWN0IDw9IGltZ0FzcGVjdCkge1xuICAgICAgc2NhbGVGYWN0b3IgPSBjYW52YXNXaWR0aCAvIHdpZHRoO1xuICAgICAgbGVmdCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzSGVpZ2h0IC8gaGVpZ2h0O1xuICAgICAgbGVmdCA9IC0od2lkdGggKiBzY2FsZUZhY3RvciAtIGNvbnRhaW5lci5jbGllbnRXaWR0aCkgLyAyO1xuICAgIH1cblxuICAgIHRoaXMubGVmdCA9IGxlZnQ7XG5cbiAgICBiYWNrZ3JvdW5kSW1hZ2VbJ3NjYWxlWCddICo9IHNjYWxlRmFjdG9yO1xuICAgIGJhY2tncm91bmRJbWFnZVsnc2NhbGVZJ10gKj0gc2NhbGVGYWN0b3I7XG5cbiAgICB0aGlzLnNldENhbnZhc1NpemUod2lkdGggKiBzY2FsZUZhY3RvciwgaGVpZ2h0ICogc2NhbGVGYWN0b3IpO1xuXG4gICAgY29uc3Qgb2JqZWN0cyA9IGpzb25bJ29iamVjdHMnXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2JqZWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgb2JqZWN0c1tpXVsnbGVmdCddICo9IHNjYWxlRmFjdG9yO1xuICAgICAgb2JqZWN0c1tpXVsndG9wJ10gKj0gc2NhbGVGYWN0b3I7XG4gICAgICBvYmplY3RzW2ldWydzY2FsZVgnXSAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iamVjdHNbaV1bJ3NjYWxlWSddICo9IHNjYWxlRmFjdG9yO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBleHBvcnRJbWFnZUFzRGF0YVVSTCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xuICB9XG5cbiAgcHVibGljIHNlbGVjdEl0ZW0oaXRlbU51bWJlcjogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jYW52YXMuc2V0QWN0aXZlT2JqZWN0KHRoaXMuY2FudmFzLml0ZW0oaXRlbU51bWJlcikpO1xuICB9XG5cbiAgcHVibGljIGdldEluZGV4T2YoYWN0aXZlT2JqZWN0KTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMuZ2V0T2JqZWN0cygpLmluZGV4T2YoYWN0aXZlT2JqZWN0KTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya1NlbGVjdGVkT2JqZWN0c0RpcnR5KCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICBvYmplY3Quc2V0KCdkaXJ0eScsIHRydWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGRTZWxlY3Rpb25SZWN0YW5nbGUoKTogdm9pZCB7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlID0gbmV3IGZhYnJpYy5SZWN0KHtcbiAgICAgIGZpbGw6ICd0cmFuc3BhcmVudCcsXG4gICAgICBvcmlnaW5YOiAnbGVmdCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIHN0cm9rZTogJyNjY2MnLFxuICAgICAgc3Ryb2tlRGFzaEFycmF5OiBbMiwgMl0sXG4gICAgICBvcGFjaXR5OiAxLFxuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDBcbiAgICB9KTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS52aXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy5jYW52YXMuYWRkKHRoaXMuY3JvcFJlY3RhbmdsZSk7XG4gIH1cblxuICBwdWJsaWMgYWp1c3RDcm9wUmVjdGFuZ2xlRnJvbU1vdXNlKGV2ZW50OiBNb3VzZUV2ZW50KTogYm9vbGVhbiB7XG5cbiAgICBjb25zdCB4ID0gTWF0aC5taW4oZXZlbnQub2Zmc2V0WCwgdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgeSA9IE1hdGgubWluKGV2ZW50Lm9mZnNldFksIHRoaXMubW91c2VQb3NpdGlvbi55KSxcbiAgICAgIHcgPSBNYXRoLmFicyhldmVudC5vZmZzZXRYIC0gdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgaCA9IE1hdGguYWJzKGV2ZW50Lm9mZnNldFkgLSB0aGlzLm1vdXNlUG9zaXRpb24ueSk7XG5cbiAgICBpZiAoIXcgfHwgIWgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGVcbiAgICAgIC5zZXQoJ3RvcCcsIHkpXG4gICAgICAuc2V0KCdsZWZ0JywgeClcbiAgICAgIC5zZXQoJ3dpZHRoJywgdylcbiAgICAgIC5zZXQoJ2hlaWdodCcsIGgpO1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBzdGFydFNlbGVjdGluZ0Nyb3BSZWN0YW5nbGVGcm9tTW91c2UoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUubGVmdCA9IGV2ZW50Lm9mZnNldFg7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnRvcCA9IGV2ZW50Lm9mZnNldFk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnNldENvb3JkcygpO1xuXG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IGV2ZW50Lm9mZnNldFgsIHk6IGV2ZW50Lm9mZnNldFkgfTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS52aXNpYmxlID0gdHJ1ZTtcbiAgICB0aGlzLmNhbnZhcy5icmluZ1RvRnJvbnQodGhpcy5jcm9wUmVjdGFuZ2xlKTtcbiAgfVxuXG4gIHB1YmxpYyBjcm9wSW1hZ2UoKTogdm9pZCB7XG4gICAgY29uc3QgbGVmdCA9IHRoaXMuY3JvcFJlY3RhbmdsZS5sZWZ0O1xuICAgIGNvbnN0IHRvcCA9IHRoaXMuY3JvcFJlY3RhbmdsZS50b3A7XG5cbiAgICBjb25zdCB3aWR0aCA9IHRoaXMuY3JvcFJlY3RhbmdsZS53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmNyb3BSZWN0YW5nbGUuaGVpZ2h0O1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5kaXZDYW52YXNDb250YWluZXI7XG5cbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNvbnRhaW5lci5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBjYW52YXNIZWlnaHQgPSBjb250YWluZXIuY2xpZW50SGVpZ2h0O1xuXG4gICAgY29uc3QgY2FudmFzQXNwZWN0ID0gY2FudmFzV2lkdGggLyBjYW52YXNIZWlnaHQ7XG4gICAgY29uc3QgaW1nQXNwZWN0ID0gd2lkdGggLyBoZWlnaHQ7XG4gICAgbGV0IHNjYWxlRmFjdG9yO1xuXG4gICAgaWYgKGNhbnZhc0FzcGVjdCA8PSBpbWdBc3BlY3QpIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzV2lkdGggLyB3aWR0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGVGYWN0b3IgPSBjYW52YXNIZWlnaHQgLyBoZWlnaHQ7XG4gICAgfVxuXG4gICAgdGhpcy5zZXRDYW52YXNTaXplKHdpZHRoICogc2NhbGVGYWN0b3IsIGhlaWdodCAqIHNjYWxlRmFjdG9yKTtcblxuICAgIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZS5zY2FsZVggKj0gc2NhbGVGYWN0b3I7XG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLnNjYWxlWSAqPSBzY2FsZUZhY3RvcjtcblxuICAgIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZS5sZWZ0IC09IGxlZnQ7XG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLmxlZnQgKj0gc2NhbGVGYWN0b3I7XG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLnRvcCAtPSB0b3AgLSBzY2FsZUZhY3RvcjtcbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2UudG9wICo9IHNjYWxlRmFjdG9yO1xuXG4gICAgdGhpcy5tb3ZlQWxsT2JqZWN0c0luQ2FudmFzKC0xICogbGVmdCwgLTEgKiB0b3AsIHNjYWxlRmFjdG9yKTtcblxuICAgIHRoaXMuZW5hYmxlU2xlY3Rpb24oKTtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUudmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5jYW52YXMucmVtb3ZlKHRoaXMuY3JvcFJlY3RhbmdsZSk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgfVxuXG4gIHB1YmxpYyBlbmFibGVTbGVjdGlvbigpIHtcbiAgICB0aGlzLmNhbnZhcy5zZWxlY3RhYmxlID0gdHJ1ZTtcbiAgICB0aGlzLmNhbnZhcy5zZWxlY3Rpb24gPSB0cnVlO1xuICB9XG5cbiAgcHVibGljIGFqdXN0Q3JvcFJlY3RhbmdsZShldmVudCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTtcblxuICAgIGNvbnN0IHJlY3QgPSBldmVudC50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICBjb25zdCB4ID0gTWF0aC5taW4odG91Y2guY2xpZW50WCAtIHJlY3QubGVmdCwgdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgeSA9IE1hdGgubWluKHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcCwgdGhpcy5tb3VzZVBvc2l0aW9uLnkpLFxuICAgICAgdyA9IE1hdGguYWJzKHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQgLSB0aGlzLm1vdXNlUG9zaXRpb24ueCksXG4gICAgICBoID0gTWF0aC5hYnModG91Y2guY2xpZW50WSAtIHJlY3QudG9wIC0gdGhpcy5tb3VzZVBvc2l0aW9uLnkpO1xuXG4gICAgaWYgKCF3IHx8ICFoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlXG4gICAgICAuc2V0KCdsZWZ0JywgeClcbiAgICAgIC5zZXQoJ3RvcCcsIHkpXG4gICAgICAuc2V0KCd3aWR0aCcsIHcpXG4gICAgICAuc2V0KCdoZWlnaHQnLCBoKTtcblxuICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwdWJsaWMgc3RhcnRTZWxlY3RpbmdDcm9wUmVjdGFuZ2xlKGV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdG91Y2ggPSBldmVudC50b3VjaGVzWzBdO1xuICAgIGNvbnN0IHJlY3QgPSBldmVudC50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUubGVmdCA9IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQ7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnRvcCA9IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUuc2V0Q29vcmRzKCk7XG5cbiAgICB0aGlzLm1vdXNlUG9zaXRpb24gPSB7IHg6IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQsIHk6IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcCB9O1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnZpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuY2FudmFzLmJyaW5nVG9Gcm9udCh0aGlzLmNyb3BSZWN0YW5nbGUpO1xuICB9XG5cbiAgcHVibGljIGRpc2FibGVTZWxlY3Rpb24oKSB7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG1vdmVBbGxPYmplY3RzSW5DYW52YXMoeDogbnVtYmVyLCB5OiBudW1iZXIsIHNjYWxlRmFjdG9yOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBvYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0T2JqZWN0cygpO1xuICAgIGZvciAoY29uc3Qgb2JqIG9mIG9iamVjdHMpIHtcbiAgICAgIG9iai5sZWZ0ICs9IHg7XG4gICAgICBvYmoubGVmdCAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iai5zY2FsZVggKj0gc2NhbGVGYWN0b3I7XG4gICAgICBvYmoudG9wICs9IHk7XG4gICAgICBvYmouc2NhbGVZICo9IHNjYWxlRmFjdG9yO1xuICAgICAgb2JqLnRvcCAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iai5zZXRDb29yZHMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ3JvdXBTZWxlY3RlZE9iamVjdHMoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBjb25zdCBvYmplY3RzID0gW107XG5cbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgb2JqZWN0cy5wdXNoKG9iamVjdCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlbGV0ZVNlbGVjdGVkT2JqZWN0cygpO1xuXG4gICAgICBjb25zdCBncm91cCA9IG5ldyBmYWJyaWMuR3JvdXAob2JqZWN0cyk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGQoZ3JvdXApO1xuICAgICAgZ3JvdXAuc2V0Q29vcmRzKCk7XG5cbiAgICAgIHRoaXMuY2FudmFzLnNldEFjdGl2ZU9iamVjdChncm91cCk7XG5cbiAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRMYXN0UGFuUG9zaXRpb24oZXZlbnQpIHtcbiAgICB0aGlzLmxhc3RQYW5Qb3NpdGlvbiA9IG5ldyBmYWJyaWMuUG9pbnQoZXZlbnQudG91Y2hlc1swXS5jbGllbnRYLCBldmVudC50b3VjaGVzWzBdLmNsaWVudFkpO1xuICB9XG5cbiAgcHVibGljIHBhbkNhbnZhcyhldmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGRlbHRhID0gbmV3IGZhYnJpYy5Qb2ludChcbiAgICAgIGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMubGFzdFBhblBvc2l0aW9uLngsXG4gICAgICBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLmxhc3RQYW5Qb3NpdGlvbi55XG4gICAgKTtcblxuICAgIHRoaXMuY2FudmFzLnJlbGF0aXZlUGFuKGRlbHRhKTtcbiAgICB0aGlzLnByZXZlbnRQYW5PdXRzaWRlQ2FudmFzKCk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB0aGlzLnNldExhc3RQYW5Qb3NpdGlvbihldmVudCk7XG4gIH1cblxuICBwcml2YXRlIHByZXZlbnRQYW5PdXRzaWRlQ2FudmFzKCkge1xuICAgIGNvbnN0IGNhbnZhc1ZpZXdQb3J0ID0gdGhpcy5jYW52YXMudmlld3BvcnRUcmFuc2Zvcm07XG5cbiAgICBjb25zdCBib3R0b21FbmRQb2ludCA9IHRoaXMuY2FudmFzLmhlaWdodCAqIChjYW52YXNWaWV3UG9ydFswXSAtIDEpO1xuICAgIGlmIChjYW52YXNWaWV3UG9ydFs1XSA+PSAwIHx8IC1ib3R0b21FbmRQb2ludCA+IGNhbnZhc1ZpZXdQb3J0WzVdKSB7XG4gICAgICAgIGNhbnZhc1ZpZXdQb3J0WzVdID0gKGNhbnZhc1ZpZXdQb3J0WzVdID49IDApID8gMCA6IC1ib3R0b21FbmRQb2ludDtcbiAgICB9XG5cbiAgICBjb25zdCByaWdodEVuZFBvaW50ID0gdGhpcy5jYW52YXMud2lkdGggKiAoY2FudmFzVmlld1BvcnRbMF0gLSAxKTtcbiAgICBpZiAoY2FudmFzVmlld1BvcnRbNF0gPj0gMCB8fCAtcmlnaHRFbmRQb2ludCA+IGNhbnZhc1ZpZXdQb3J0WzRdKSB7XG4gICAgICAgIGNhbnZhc1ZpZXdQb3J0WzRdID0gKGNhbnZhc1ZpZXdQb3J0WzRdID49IDApID8gMCA6IC1yaWdodEVuZFBvaW50O1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyB6b29tKGV2ZW50KTogdm9pZCB7XG4gICAgaWYgKE1hdGguYWJzKGV2ZW50Lm92ZXJhbGxWZWxvY2l0eSkgPiAwLjAwNSkge1xuICAgICAgY29uc3QgcG9pbnQgPSBuZXcgZmFicmljLlBvaW50KGV2ZW50LmNlbnRlci54LCBldmVudC5jZW50ZXIueSk7XG5cbiAgICAgIGxldCB6b29tID0gdGhpcy5jYW52YXMuZ2V0Wm9vbSgpO1xuICAgICAgem9vbSA9IHpvb20gKyAoZXZlbnQuc2NhbGUgLSB6b29tKSAvIDIwO1xuXG5cbiAgICAgIGlmICh6b29tIDwgMSkge1xuICAgICAgICB6b29tID0gMTtcbiAgICAgICAgdGhpcy5jYW52YXMuem9vbVRvUG9pbnQobmV3IGZhYnJpYy5Qb2ludCgwLCAwKSwgem9vbSk7XG4gICAgICAgIHRoaXMuY2FudmFzLmFic29sdXRlUGFuKG5ldyBmYWJyaWMuUG9pbnQoMCwgMCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHpvb20gPiAxMCkge1xuICAgICAgICAgIHpvb20gPSAxMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNhbnZhcy56b29tVG9Qb2ludChwb2ludCwgem9vbSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0RnJlZURyYXdpbmdCcnVzaFdpZHRoRnJvbVpvb20oem9vbSk7XG4gICAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldENhbnZhc1NpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICB0aGlzLmNhbnZhcy5zZXRXaWR0aCh3aWR0aCk7XG4gICAgdGhpcy5jYW52YXMuc2V0SGVpZ2h0KGhlaWdodCk7XG4gIH1cblxuICBwdWJsaWMgcmVzZXRab29tKCkge1xuICAgIHRoaXMuY2FudmFzLnpvb21Ub1BvaW50KG5ldyBmYWJyaWMuUG9pbnQoMCwgMCksIDEpO1xuICAgIHRoaXMuY2FudmFzLmFic29sdXRlUGFuKG5ldyBmYWJyaWMuUG9pbnQoMCwgMCkpO1xuICB9XG59XG4iXX0=