2
0
Files

906 lines
82 KiB
JavaScript

import { Injectable, RendererFactory2, ViewChild, Component, Input, Output, EventEmitter, HostListener, ElementRef, Directive, NgModule } from '@angular/core';
import { randomUniform } from 'd3-random';
import { select } from 'd3-selection';
import { line, curveBasis } from 'd3-shape';
import { BrowserModule } from '@angular/platform-browser';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NlsCanvasService {
/**
* @param {?} rendererFactory
*/
constructor(rendererFactory) {
this.rendererFactory = rendererFactory;
this.renderer = rendererFactory.createRenderer(null, null);
}
/**
* @return {?}
*/
get get() {
return this.canvas;
}
/**
* @param {?} el
* @return {?}
*/
set(el) {
this.canvas = el;
}
/**
* @return {?}
*/
adjustToWindow() {
if (this.canvas) {
this.renderer.setStyle(this.canvas, 'width', this.canvas.innerWidth);
this.renderer.setStyle(this.canvas, 'height', this.canvas.innerHeight);
}
}
}
NlsCanvasService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
NlsCanvasService.ctorParameters = () => [
{ type: RendererFactory2 }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NlsHistoryService {
constructor() {
this.history = [];
}
/**
* @param {?} graphs
* @param {?} config
* @return {?}
*/
save(graphs, config) {
this.history.push({
date: new Date(),
graphs: graphs,
config: config,
hash: this.hash(graphs)
});
}
/**
* @param {?} graphs
* @return {?}
*/
hash(graphs) {
return btoa(JSON.stringify(graphs));
}
/**
* @return {?}
*/
list() {
return this.history;
}
}
NlsHistoryService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
NlsHistoryService.ctorParameters = () => [];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NlsMathService {
/**
* Calculate distance between to points with coordinates.
* @param {?} a
* @param {?} b
* @return {?}
*/
Δ(a, b) {
return Math.pow(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2), 0.5);
}
/**
* @param {?} point
* @param {?} matrix
* @return {?}
*/
getClosestCenter(point, matrix) {
if (this.Δ(point, matrix.start) < this.Δ(point, matrix.end)) {
return matrix.start;
}
else {
return matrix.end;
}
}
/**
* @param {?} point
* @param {?} matrix
* @return {?}
*/
getFarestCenter(point, matrix) {
if (this.Δ(point, matrix.start) > this.Δ(point, matrix.end)) {
return matrix.start;
}
else {
return matrix.end;
}
}
/**
* @param {?} matrix
* @param {?} overlap
* @return {?}
*/
randomPoint(matrix, overlap) {
/** @type {?} */
const x = {
min: matrix.center.x - matrix.width * overlap,
max: matrix.center.x + matrix.width * overlap
};
/** @type {?} */
const y = {
min: matrix.center.y - matrix.height * overlap,
max: matrix.center.y + matrix.height * overlap
};
return {
x: randomUniform(x.min, x.max)(),
y: randomUniform(y.min, y.max)()
};
}
/**
* @param {?} width
* @param {?} height
* @return {?}
*/
centerOfArea(width, height) {
return {
x: width * 0.5,
y: height * 0.5
};
}
/**
* @param {?} p1
* @param {?} p2
* @return {?}
*/
centerOfPoints(p1, p2) {
return {
x: (p1.x + p2.x) * 0.5,
y: (p1.y + p2.y) * 0.5
};
}
/**
* @param {?} curve
* @return {?}
*/
centerOfCurve(curve) {
/** @type {?} */
const genMedian = this.medianPoint(curve);
/** @type {?} */
const p1 = genMedian.next().value;
/** @type {?} */
const p2 = genMedian.next().value;
/** @type {?} */
const radians = this.angleRadians(p1, p2);
return Object.assign(this.centerOfPoints(p1, p2), { ascent: radians });
}
/**
* @param {?} curve
* @return {?}
*/
medianOfCurve(curve) {
/** @type {?} */
const genMedian = this.medianPoint(curve);
/** @type {?} */
const p1 = genMedian.next().value;
/** @type {?} */
const p2 = genMedian.next().value;
/** @type {?} */
const p3 = genMedian.next().value;
/** @type {?} */
const radians = this.angleRadians(p2, p3);
// const radians = Math.round(Math.random() * 10000) / 1000;
// @todo if nodes are less than 5 error occures
return Object.assign(p1, { ascent: radians });
}
/**
* @param {?} p1
* @param {?} p2
* @return {?}
*/
angleRadians(p1, p2) {
return Math.atan2(p2.y - p1.y, p2.x - p1.x);
}
/**
* @param {?} p1
* @param {?} p2
* @return {?}
*/
angleDegree(p1, p2) {
return this.angleRadians(p1, p2) * 180 / Math.PI;
}
/**
* @param {?} list
* @return {?}
*/
medianIndex(list) {
return Math.floor(list.length * 0.5);
}
/**
* @param {?} points
* @return {?}
*/
*medianPoint(points) {
/** @type {?} */
let index;
/** @type {?} */
const list = points.slice();
while (list) {
index = this.medianIndex(points);
yield list[index];
list.splice(index, 1);
}
}
/**
* Generator for sine bounce
*
* @param {?=} amplitude default to 1 indicates the amplitude in positive as well
* in negative range
* @param {?=} decimals amount of decimal places
* @param {?=} start 0 indicates to initiate with positive numbers, 1 indicates to
* start with negative numbers first
* @return {?}
*/
*bounce(amplitude = 1, decimals = 1, start = 0) {
/** @type {?} */
const power = Math.pow(10, decimals);
/** @type {?} */
const step = 2 / (power);
/** @type {?} */
let index = 0;
while (true) {
/** @type {?} */
const radians = Math.PI * step * index + start;
yield Math.round((Math.sin(radians) * amplitude) * power) / power;
index++;
}
}
/**
* @param {?=} startPositive
* @return {?}
*/
*flipSign(startPositive = true) {
/** @type {?} */
let sign = startPositive ? 1 : -1;
while (true) {
yield sign = sign * (-1);
}
}
}
NlsMathService.decorators = [
{ type: Injectable },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NlsGraphService {
/**
* @param {?} math
*/
constructor(math) {
this.math = math;
}
/**
* @return {?}
*/
get() {
return this.graphs;
}
/**
* @param {?} newGraphs
* @return {?}
*/
set(newGraphs) {
this.graphs = newGraphs;
}
/**
* @return {?}
*/
get isAnimated() {
return this.animation;
}
/**
* @return {?}
*/
startAnimation() {
this.animation = true;
}
/**
* @return {?}
*/
stopAnimation() {
this.animation = false;
}
/**
* @param {?} start
* @param {?} spacing
* @return {?}
*/
*spreadOrthogonal(start, spacing) {
/** @type {?} */
const sign = this.math.flipSign();
/** @type {?} */
let currentPoint = start;
/** @type {?} */
let i = 0;
while (true) {
/** @type {?} */
const currentSpacing = sign.next().value * spacing * i;
currentPoint = this.shiftPoint(currentPoint, start.ascent, currentSpacing);
yield currentPoint;
i++;
}
}
/**
* @param {?} point
* @param {?} radians
* @param {?} spacing
* @return {?}
*/
shiftPoint(point, radians, spacing) {
return {
x: Math.sin(radians * Math.PI) * spacing + point.x,
y: Math.cos(radians * Math.PI) * spacing + point.y
};
}
}
NlsGraphService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
NlsGraphService.ctorParameters = () => [
{ type: NlsMathService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/** @type {?} */
const RESIZING_TIMEOUT = 800;
class NlsGraphsComponent {
/**
* @param {?} canvasService
* @param {?} historyService
* @param {?} math
* @param {?} graphService
*/
constructor(canvasService, historyService, math, graphService) {
this.canvasService = canvasService;
this.historyService = historyService;
this.math = math;
this.graphService = graphService;
this.svgChange = new EventEmitter();
this.graphChange = new EventEmitter();
this.genLoadedAllGraphs = this.countLoadedGraphs();
this.resizingWindow = false;
}
/**
* @param {?} event
* @return {?}
*/
onResize(event) {
clearTimeout(this.resizingWindow);
this.resizingWindow = setTimeout(() => {
this.canvas = this.adjustCanvas();
this.matrix = this.calcMatrix();
this.updateGraphs();
}, RESIZING_TIMEOUT);
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
this.canvas = this.adjustCanvas();
this.matrix = this.calcMatrix();
if (changes["config"]) {
this.updateGraphs();
}
if (this.restoredHistory && this.restoredHistory.hash !== this.hash) {
this.restoreGraph();
}
}
/**
* @return {?}
*/
restoreGraph() {
this.graphs = this.restoredHistory.graphs;
this.hash = this.restoredHistory.hash;
}
/**
* @return {?}
*/
saveHistory() {
this.hash = this.historyService.hash(this.graphs);
this.historyService.save(this.graphs, this.config);
}
/**
* @return {?}
*/
saveGraph() {
this.graphService.set(this.graphs);
}
/**
* @return {?}
*/
updateGraphs() {
/** @type {?} */
const genShiftStart = this.shiftPoint(this.matrix.start, this.config.vectors.start);
/** @type {?} */
const genShiftEnd = this.shiftPoint(this.matrix.end, this.config.vectors.end, false);
console.log(this.matrix);
/** @type {?} */
const curveList = [
{
color: this.config.colors.primary,
start: genShiftStart.next().value,
end: genShiftEnd.next().value
},
{
color: this.config.colors.secondary,
start: genShiftEnd.next().value,
end: genShiftStart.next().value
}
];
this.graphs = curveList.map(curve => {
return Object.assign({}, this.adjustGraph(curve), { spread: this.config.spread, interval: this.config.interval });
});
this.hash = this.historyService.hash(this.graphs);
this.saveHistory();
this.saveGraph();
}
/**
* @param {?} curve
* @return {?}
*/
adjustGraph(curve) {
return Object.assign(curve, {
stroke: this.config.stroke,
start: Object.assign(curve.start, {
direction: this.genVectorPoint(curve.start.point, curve.start.vector)
}),
end: Object.assign(curve.end, {
direction: this.genVectorPoint(curve.end.point, curve.end.vector)
}),
nodes: this.genRandomPoints(this.config.nodes)
});
}
/**
* @param {?} num
* @return {?}
*/
genRandomPoints(num) {
/** @type {?} */
const generatedPoints = [];
for (let i = 0; i < this.config.nodes; i++) {
generatedPoints.push(this.math.randomPoint(this.matrix, this.config.overlap));
}
return generatedPoints;
}
/**
* @param {?} x
* @return {?}
*/
flipflop(x) {
return (x === 'start') ? 'end' : 'start';
}
/**
* @return {?}
*/
adjustCanvas() {
this.canvasService.set(this.canvas);
this.canvasService.adjustToWindow();
return this.svgElementRef.nativeElement;
}
/**
* @return {?}
*/
calcMatrix() {
/** @type {?} */
const canvasWidth = this.canvas.getBoundingClientRect().width;
/** @type {?} */
const canvasHeight = this.canvas.getBoundingClientRect().height;
/** @type {?} */
const totalCenter = this.math.centerOfArea(canvasWidth, canvasHeight);
return {
start: {
x: 0,
y: canvasHeight - this.config.vectors.spacing - this.config.margin.y
},
end: {
x: canvasWidth - this.config.vectors.spacing - this.config.margin.x,
y: 0
},
width: canvasWidth,
height: canvasHeight,
center: totalCenter
};
}
/**
* @param {?} point
* @param {?} vector
* @return {?}
*/
genVectorPoint(point, vector) {
/** @type {?} */
const range = this.math.Δ(this.matrix.start, this.matrix.end) * this.config.vectors.range;
return {
x: range * Math.sin(Math.PI * vector) + point.x,
y: range * Math.cos(Math.PI * vector) + point.y
};
}
/**
* @param {?} point
* @param {?} vector
* @param {?=} startPositive
* @return {?}
*/
*shiftPoint(point, vector, startPositive = true) {
/** @type {?} */
const genShiftX = this.shiftNumber(this.config.vectors.spacing, vector, startPositive);
/** @type {?} */
const genShiftY = this.shiftNumber(this.config.vectors.spacing, vector, startPositive);
while (true) {
yield {
point: {
x: Math.cos(Math.PI * vector) * genShiftX.next().value + point.x,
y: Math.sin(Math.PI * vector) * genShiftY.next().value + point.y,
},
vector: vector
};
}
}
/**
* @param {?} space
* @param {?} vector
* @param {?=} startPositive
* @return {?}
*/
*shiftNumber(space, vector, startPositive = true) {
/** @type {?} */
let current = 0;
/** @type {?} */
let index = 0;
/** @type {?} */
const sign = this.math.flipSign(startPositive);
while (true) {
yield current = sign.next().value * index * space + current;
index++;
}
}
/**
* @param {?} guillocheElement
* @return {?}
*/
prepareGuillocheExport(guillocheElement) {
if (this.genLoadedAllGraphs.next().value) {
this.svgChange.emit(this.svgElementRef);
}
}
/**
* @return {?}
*/
*countLoadedGraphs() {
/** @type {?} */
let cycles = 1;
while (true) {
if (cycles < this.graphs.length) {
yield false;
cycles++;
}
else {
yield true;
cycles = 1;
}
}
}
}
NlsGraphsComponent.decorators = [
{ type: Component, args: [{
selector: 'nls-graphs',
template: `<svg #svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
version="1.1" shape-rendering="geometricPrecision">
<g nlsGuilloche *ngFor="let graph of graphs" [graph]="graph" [animation]="animation"></g>
</svg>
`,
styles: [`:host{position:absolute;width:100%;height:100%;top:0;left:0;overflow:hidden}`]
},] },
];
/** @nocollapse */
NlsGraphsComponent.ctorParameters = () => [
{ type: NlsCanvasService },
{ type: NlsHistoryService },
{ type: NlsMathService },
{ type: NlsGraphService }
];
NlsGraphsComponent.propDecorators = {
config: [{ type: Input }],
restoredHistory: [{ type: Input }],
animation: [{ type: Input }],
svgChange: [{ type: Output }],
graphChange: [{ type: Output }],
svgElementRef: [{ type: ViewChild, args: ['svg',] }],
onResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NlsGuillocheDirective {
/**
* @param {?} canvasService
* @param {?} el
* @param {?} math
* @param {?} graphService
*/
constructor(canvasService, el, math, graphService) {
this.canvasService = canvasService;
this.el = el;
this.math = math;
this.graphService = graphService;
}
/**
* @return {?}
*/
ngOnDestroy() {
this.group.selectAll('*').remove();
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
this.group = select(this.el.nativeElement);
this.canvas = select(this.canvasService.get);
// @todo modify graph here instead of in graphs.component.ts
this.initialNodes = this.graph.nodes.slice();
this.initialCurve = [
this.graph.start.point,
this.graph.start.direction,
...this.graph.nodes.slice(),
this.graph.end.direction,
this.graph.end.point
];
this.medianPoint = this.math.medianOfCurve(this.initialCurve);
this.medianIndex = this.math.medianIndex(this.initialCurve);
if (this.animation) {
this.graph.nodes = this.graph.nodes.slice().map((node, i) => {
return {
x: node.x,
y: node.y,
// ascent: Math.round(Math.random() * 100) / 100
ascent: this.medianPoint.ascent + i * 0.5
};
});
this.bounces = this.initialNodes.map(node => {
/** @type {?} */
const bounceAmplitude = Math.round(Math.random() * 150);
return this.math.bounce(bounceAmplitude, 3);
});
/** @type {?} */
let i = 0;
this.animationInterval = setInterval(() => {
this.animateGraph(i++ % 1000 / 10000);
}, this.graph.interval);
}
else {
if (this.animationInterval) {
this.bounce = null;
clearInterval(this.animationInterval);
}
}
this.group.selectAll('*').remove();
this.pathElements = [];
/** @type {?} */
const graphs = this.spreadLines([
this.graph.start.point,
this.graph.start.direction,
...this.graph.nodes,
this.graph.end.direction,
this.graph.end.point,
]).forEach((points, index) => this.drawGraph(points));
}
/**
* @param {?} x
* @return {?}
*/
animateGraph(x) {
/** @type {?} */
const graphs = this.spreadLines([
this.graph.start.point,
this.graph.start.direction,
...this.graph.nodes.map((point, i) => {
/** @type {?} */
const ascent = point.ascent * Math.sin(Math.PI * x);
return this.graphService.shiftPoint(point, ascent, this.bounces[i].next().value);
}),
this.graph.end.direction,
this.graph.end.point,
]);
graphs.forEach((points, i) => this.updateGraph(points, i));
}
/**
* @param {?} points
* @return {?}
*/
spreadLines(points) {
/** @type {?} */
const shiftedMedians = [];
/** @type {?} */
const genshiftedMedians = this.graphService.spreadOrthogonal(this.medianPoint, this.graph.spread.spacing);
for (let i = 0; i < this.graph.spread.amount; i++) {
shiftedMedians.push(genshiftedMedians.next().value);
}
return shiftedMedians.map(median => {
/** @type {?} */
const shiftedPoints = points.slice();
shiftedPoints.splice(this.medianIndex, 1, median);
return shiftedPoints;
});
}
/**
* @param {?} points
* @param {?} index
* @return {?}
*/
updateGraph(points, index) {
this.pathElements[index]
.attr('d', line()
.x(p => p.x)
.y(p => p.y)
.curve(curveBasis)(points));
}
/**
* @param {?} points
* @return {?}
*/
drawGraph(points) {
this.group
.attr('stroke', this.graph.color)
.attr('stroke-width', this.graph.stroke)
.attr('fill', 'none');
this.pathElements.push(this.group.append('path')
.attr('d', line()
.x(p => p.x)
.y(p => p.y)
.curve(curveBasis)(points)));
}
/**
* @param {?} points
* @return {?}
*/
debugGraph(points) {
points.forEach((point, index) => {
/** @type {?} */
const circle = this.group.append('g');
circle.append('circle')
.attr('cx', point.x)
.attr('cy', point.y)
.attr('r', 3)
.attr('fill-opacity', 0.6)
.attr('fill', this.graph.color);
circle.append('text')
.attr('x', point.x)
.attr('y', point.y)
.attr('dx', 8)
.attr('dy', 15)
.attr('fill', this.graph.color)
.text(index);
});
}
}
NlsGuillocheDirective.decorators = [
{ type: Directive, args: [{
selector: '[nlsGuilloche]'
},] },
];
/** @nocollapse */
NlsGuillocheDirective.ctorParameters = () => [
{ type: NlsCanvasService },
{ type: ElementRef },
{ type: NlsMathService },
{ type: NlsGraphService }
];
NlsGuillocheDirective.propDecorators = {
graph: [{ type: Input }],
animation: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NlsAnimationService {
/**
* @param {?} math
* @param {?} historyService
*/
constructor(math, historyService) {
this.math = math;
this.historyService = historyService;
}
/**
* @param {?} initialGraph
* @return {?}
*/
animate(initialGraph) {
/** @type {?} */
const newGraph = Object.assign({}, initialGraph);
/** @type {?} */
const indexMiddle = Math.floor(newGraph.nodes.length * 0.5);
/** @type {?} */
const pointMiddle = newGraph.nodes[indexMiddle];
newGraph.nodes.splice(indexMiddle, 1, {
x: pointMiddle.x - 2,
y: pointMiddle.y + 2,
});
return newGraph;
// });
}
}
NlsAnimationService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
NlsAnimationService.ctorParameters = () => [
{ type: NlsMathService },
{ type: NlsHistoryService }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NlsGuillocheModule {
}
NlsGuillocheModule.decorators = [
{ type: NgModule, args: [{
imports: [
BrowserModule
],
declarations: [
NlsGraphsComponent,
NlsGuillocheDirective
],
providers: [
NlsHistoryService,
NlsCanvasService,
NlsMathService,
NlsGraphService,
],
exports: [
NlsGraphsComponent,
NlsGuillocheDirective
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { NlsGraphsComponent, NlsGuillocheDirective, NlsAnimationService, NlsCanvasService, NlsGraphService, NlsHistoryService, NlsMathService, NlsGuillocheModule };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmxzLWd1aWxsb2NoZS5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmxzLWd1aWxsb2NoZS9ubHMvc2VydmljZXMvY2FudmFzLnNlcnZpY2UudHMiLCJuZzovL25scy1ndWlsbG9jaGUvbmxzL3NlcnZpY2VzL2hpc3Rvcnkuc2VydmljZS50cyIsIm5nOi8vbmxzLWd1aWxsb2NoZS9ubHMvc2VydmljZXMvbWF0aC5zZXJ2aWNlLnRzIiwibmc6Ly9ubHMtZ3VpbGxvY2hlL25scy9zZXJ2aWNlcy9ncmFwaC5zZXJ2aWNlLnRzIiwibmc6Ly9ubHMtZ3VpbGxvY2hlL25scy9jb21wb25lbnRzL2dyYXBocy5jb21wb25lbnQudHMiLCJuZzovL25scy1ndWlsbG9jaGUvbmxzL2RpcmVjdGl2ZXMvZ3VpbGxvY2hlLmRpcmVjdGl2ZS50cyIsIm5nOi8vbmxzLWd1aWxsb2NoZS9ubHMvc2VydmljZXMvYW5pbWF0aW9uLnNlcnZpY2UudHMiLCJuZzovL25scy1ndWlsbG9jaGUvbmxzL25scy1ndWlsbG9jaGUubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChDKSAyMDE4IE1pY2hhZWwgQ3plY2hvd3NraSA8bWFpbEBkYWlseXNoLml0PlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXRcbiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG4gKiBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB2ZXJzaW9uIDIuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3JcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvclxuICogbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGhcbiAqIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MVxuICogRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBSZW5kZXJlcjIsIFJlbmRlcmVyRmFjdG9yeTIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIFNlbGVjdGlvbiBmcm9tICdkMy1zZWxlY3Rpb24nO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmxzQ2FudmFzU2VydmljZSB7XG4gIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMjtcblxuICBwdWJsaWMgY2FudmFzOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZW5kZXJlckZhY3Rvcnk6IFJlbmRlcmVyRmFjdG9yeTJcbiAgKSB7XG4gICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcztcbiAgfVxuXG4gIHB1YmxpYyBzZXQoZWwpIHtcbiAgICB0aGlzLmNhbnZhcyA9IGVsO1xuICB9XG5cbiAgcHVibGljIGFkanVzdFRvV2luZG93KCkge1xuICAgIGlmICh0aGlzLmNhbnZhcykge1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICd3aWR0aCcsXG4gICAgICAgIHRoaXMuY2FudmFzLmlubmVyV2lkdGhcbiAgICAgICk7XG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgJ2hlaWdodCcsXG4gICAgICAgIHRoaXMuY2FudmFzLmlubmVySGVpZ2h0XG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTggTWljaGFlbCBDemVjaG93c2tpIDxtYWlsQGRhaWx5c2guaXQ+XG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdFxuICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IHZlcnNpb24gMi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVRcbiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvclxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yXG4gKiBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcgd2l0aFxuICogdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDUxXG4gKiBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS5cbiAqL1xuXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIFNlbGVjdGlvbiBmcm9tICdkMy1zZWxlY3Rpb24nO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uL21vZGVscy9ncmFwaC5tb2RlbCc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBObHNIaXN0b3J5U2VydmljZSB7XG5cbiAgcHVibGljIGhpc3Rvcnk6IGFueVtdO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaGlzdG9yeSA9IFtdO1xuICB9XG5cbiAgcHVibGljIHNhdmUoZ3JhcGhzOiBHcmFwaFtdLCBjb25maWcpIHtcbiAgICB0aGlzLmhpc3RvcnkucHVzaCh7XG4gICAgICBkYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgZ3JhcGhzOiBncmFwaHMsXG4gICAgICBjb25maWc6IGNvbmZpZyxcbiAgICAgIGhhc2g6IHRoaXMuaGFzaChncmFwaHMpXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgaGFzaChncmFwaHMpIHtcbiAgICByZXR1cm4gYnRvYShKU09OLnN0cmluZ2lmeShncmFwaHMpKTtcbiAgfVxuXG4gIHB1YmxpYyBsaXN0KCkge1xuICAgIHJldHVybiB0aGlzLmhpc3Rvcnk7XG4gIH1cbn1cblxuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTggTWljaGFlbCBDemVjaG93c2tpIDxtYWlsQGRhaWx5c2guaXQ+XG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdFxuICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IHZlcnNpb24gMi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVRcbiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvclxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yXG4gKiBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcgd2l0aFxuICogdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDUxXG4gKiBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS5cbiAqL1xuXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIFNlbGVjdGlvbiBmcm9tICdkMy1zZWxlY3Rpb24nO1xuaW1wb3J0ICogYXMgUmFuZG9tIGZyb20gJ2QzLXJhbmRvbSc7XG5cbmltcG9ydCB7IFBvaW50IH0gZnJvbSAnLi8uLi9tb2RlbHMvcG9pbnQubW9kZWwnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLy4uL21vZGVscy9ncmFwaC5tb2RlbCc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBObHNNYXRoU2VydmljZSB7XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBkaXN0YW5jZSBiZXR3ZWVuIHRvIHBvaW50cyB3aXRoIGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0gYVxuICAgKiBAcGFyYW0gYlxuICAgKi9cbiAgcHVibGljIMOOwpQoYTogUG9pbnQsIGI6IFBvaW50KSB7XG4gICAgcmV0dXJuIE1hdGgucG93KE1hdGgucG93KGEueCAtIGIueCwgMikgKyBNYXRoLnBvdyhhLnkgLSBiLnksIDIpLCAwLjUpO1xuICB9XG5cbiAgcHVibGljIGdldENsb3Nlc3RDZW50ZXIocG9pbnQ6IFBvaW50LCBtYXRyaXg6IGFueSkge1xuICAgIGlmICh0aGlzLsOOwpQocG9pbnQsIG1hdHJpeC5zdGFydCkgPCB0aGlzLsOOwpQocG9pbnQsIG1hdHJpeC5lbmQpKSB7XG4gICAgICByZXR1cm4gbWF0cml4LnN0YXJ0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWF0cml4LmVuZDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0RmFyZXN0Q2VudGVyKHBvaW50OiBQb2ludCwgbWF0cml4OiBhbnkpIHtcbiAgICBpZiAodGhpcy7DjsKUKHBvaW50LCBtYXRyaXguc3RhcnQpID4gdGhpcy7DjsKUKHBvaW50LCBtYXRyaXguZW5kKSkge1xuICAgICAgcmV0dXJuIG1hdHJpeC5zdGFydDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1hdHJpeC5lbmQ7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJhbmRvbVBvaW50KG1hdHJpeDogYW55LCBvdmVybGFwOiBudW1iZXIpIHtcbiAgICBjb25zdCB4ID0ge1xuICAgICAgbWluOiBtYXRyaXguY2VudGVyLnggLSBtYXRyaXgud2lkdGggKiBvdmVybGFwLFxuICAgICAgbWF4OiBtYXRyaXguY2VudGVyLnggKyBtYXRyaXgud2lkdGggKiBvdmVybGFwXG4gICAgfTtcbiAgICBjb25zdCB5ID0ge1xuICAgICAgbWluOiBtYXRyaXguY2VudGVyLnkgLSBtYXRyaXguaGVpZ2h0ICogb3ZlcmxhcCxcbiAgICAgIG1heDogbWF0cml4LmNlbnRlci55ICsgbWF0cml4LmhlaWdodCAqIG92ZXJsYXBcbiAgICB9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IFJhbmRvbS5yYW5kb21Vbmlmb3JtKHgubWluLCB4Lm1heCkoKSxcbiAgICAgIHk6IFJhbmRvbS5yYW5kb21Vbmlmb3JtKHkubWluLCB5Lm1heCkoKVxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgY2VudGVyT2ZBcmVhKHdpZHRoLCBoZWlnaHQpOiBQb2ludCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHdpZHRoICogMC41LFxuICAgICAgeTogaGVpZ2h0ICogMC41XG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBjZW50ZXJPZlBvaW50cyhwMTogUG9pbnQsIHAyOiBQb2ludCkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiAocDEueCArIHAyLngpICogMC41LFxuICAgICAgeTogKHAxLnkgKyBwMi55KSAqIDAuNVxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgY2VudGVyT2ZDdXJ2ZShjdXJ2ZTogUG9pbnRbXSkge1xuICAgIGNvbnN0IGdlbk1lZGlhbiA9IHRoaXMubWVkaWFuUG9pbnQoY3VydmUpO1xuICAgIGNvbnN0IHAxID0gZ2VuTWVkaWFuLm5leHQoKS52YWx1ZTtcbiAgICBjb25zdCBwMiA9IGdlbk1lZGlhbi5uZXh0KCkudmFsdWU7XG4gICAgY29uc3QgcmFkaWFucyA9IHRoaXMuYW5nbGVSYWRpYW5zKHAxLCBwMik7XG5cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih0aGlzLmNlbnRlck9mUG9pbnRzKHAxLCBwMiksIHsgYXNjZW50OiByYWRpYW5zIH0pO1xuICB9XG5cbiAgcHVibGljIG1lZGlhbk9mQ3VydmUoY3VydmU6IFBvaW50W10pIHtcbiAgICBjb25zdCBnZW5NZWRpYW4gPSB0aGlzLm1lZGlhblBvaW50KGN1cnZlKTtcbiAgICBjb25zdCBwMSA9IGdlbk1lZGlhbi5uZXh0KCkudmFsdWU7XG4gICAgY29uc3QgcDIgPSBnZW5NZWRpYW4ubmV4dCgpLnZhbHVlO1xuICAgIGNvbnN0IHAzID0gZ2VuTWVkaWFuLm5leHQoKS52YWx1ZTtcbiAgICBjb25zdCByYWRpYW5zID0gdGhpcy5hbmdsZVJhZGlhbnMocDIsIHAzKTtcbiAgICAvLyBjb25zdCByYWRpYW5zID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogMTAwMDApIC8gMTAwMDtcbiAgICAvLyBAdG9kbyBpZiBub2RlcyBhcmUgbGVzcyB0aGFuIDUgZXJyb3Igb2NjdXJlc1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHAxLCB7IGFzY2VudDogcmFkaWFucyB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhbmdsZVJhZGlhbnMocDE6IFBvaW50LCBwMjogUG9pbnQpIHtcbiAgICByZXR1cm4gTWF0aC5hdGFuMihwMi55IC0gcDEueSwgcDIueCAtIHAxLngpO1xuICB9XG5cbiAgcHVibGljIGFuZ2xlRGVncmVlKHAxOiBQb2ludCwgcDI6IFBvaW50KSB7XG4gICAgcmV0dXJuIHRoaXMuYW5nbGVSYWRpYW5zKHAxLCBwMikgKiAxODAgLyBNYXRoLlBJO1xuICB9XG5cbiAgcHVibGljIG1lZGlhbkluZGV4KGxpc3Q6IGFueSk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IobGlzdC5sZW5ndGggKiAwLjUpO1xuICB9XG5cbiAgcHVibGljICptZWRpYW5Qb2ludChwb2ludHM6IFBvaW50W10pIHtcbiAgICBsZXQgaW5kZXg6IG51bWJlcjtcbiAgICBjb25zdCBsaXN0OiBQb2ludFtdID0gcG9pbnRzLnNsaWNlKCk7XG5cbiAgICB3aGlsZSAobGlzdCkge1xuICAgICAgaW5kZXggPSB0aGlzLm1lZGlhbkluZGV4KHBvaW50cyk7XG4gICAgICB5aWVsZCBsaXN0W2luZGV4XTtcblxuICAgICAgbGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0b3IgZm9yIHNpbmUgYm91bmNlXG4gICAqXG4gICAqIEBwYXJhbSBzdGFydCAwIGluZGljYXRlcyB0byBpbml0aWF0ZSB3aXRoIHBvc2l0aXZlIG51bWJlcnMsIDEgaW5kaWNhdGVzIHRvXG4gICAqIHN0YXJ0IHdpdGggbmVnYXRpdmUgbnVtYmVycyBmaXJzdFxuICAgKiBAcGFyYW0gYW1wbGl0dWRlIGRlZmF1bHQgdG8gMSBpbmRpY2F0ZXMgdGhlIGFtcGxpdHVkZSBpbiBwb3NpdGl2ZSBhcyB3ZWxsXG4gICAqIGluIG5lZ2F0aXZlIHJhbmdlXG4gICAqIEBwYXJhbSBkZWNpbWFscyBhbW91bnQgb2YgZGVjaW1hbCBwbGFjZXNcbiAgICovXG5cbiAgcHVibGljICpib3VuY2UoXG4gICAgYW1wbGl0dWRlOiBudW1iZXIgPSAxLFxuICAgIGRlY2ltYWxzOiBudW1iZXIgPSAxLFxuICAgIHN0YXJ0OiBudW1iZXIgPSAwXG4gICkge1xuICAgIGNvbnN0IHBvd2VyID0gTWF0aC5wb3coMTAsIGRlY2ltYWxzKTtcbiAgICBjb25zdCBzdGVwID0gMiAvIChwb3dlcik7XG4gICAgbGV0IGluZGV4ID0gMDtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCByYWRpYW5zID0gTWF0aC5QSSAqIHN0ZXAgKiBpbmRleCArIHN0YXJ0O1xuICAgICAgeWllbGQgTWF0aC5yb3VuZCgoTWF0aC5zaW4ocmFkaWFucykgKiBhbXBsaXR1ZGUpICogcG93ZXIpIC8gcG93ZXI7XG5cbiAgICAgIGluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgcHVibGljICpmbGlwU2lnbihzdGFydFBvc2l0aXZlOiBib29sZWFuID0gdHJ1ZSkge1xuICAgIGxldCBzaWduID0gc3RhcnRQb3NpdGl2ZSA/IDEgOiAtMTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICB5aWVsZCBzaWduID0gc2lnbiAqICgtMSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTggTWljaGFlbCBDemVjaG93c2tpIDxtYWlsQGRhaWx5c2guaXQ+XG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdFxuICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IHZlcnNpb24gMi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVRcbiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvclxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yXG4gKiBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcgd2l0aFxuICogdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDUxXG4gKiBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS5cbiAqL1xuXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIFJlbmRlcmVyMiwgUmVuZGVyZXJGYWN0b3J5MiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgU2VsZWN0aW9uIGZyb20gJ2QzLXNlbGVjdGlvbic7XG5cbmltcG9ydCB7IE5sc01hdGhTZXJ2aWNlIH0gZnJvbSAnLi9tYXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLy4uL21vZGVscy9ncmFwaC5tb2RlbCc7XG5pbXBvcnQgeyBQb2ludCB9IGZyb20gJy4vLi4vbW9kZWxzL3BvaW50Lm1vZGVsJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5sc0dyYXBoU2VydmljZSB7XG4gIHByaXZhdGUgZ3JhcGhzOiBHcmFwaFtdO1xuICBwcml2YXRlIGFuaW1hdGlvbjogYm9vbGVhbiB8IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBtYXRoOiBObHNNYXRoU2VydmljZVxuICApIHt9XG5cbiAgcHVibGljIGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5ncmFwaHM7XG4gIH1cblxuICBwdWJsaWMgc2V0KG5ld0dyYXBoczogR3JhcGhbXSkge1xuICAgIHRoaXMuZ3JhcGhzID0gbmV3R3JhcGhzO1xuICB9XG5cbiAgcHVibGljIGdldCBpc0FuaW1hdGVkKCkge1xuICAgIHJldHVybiB0aGlzLmFuaW1hdGlvbjtcbiAgfVxuXG4gIHB1YmxpYyBzdGFydEFuaW1hdGlvbigpIHtcbiAgICB0aGlzLmFuaW1hdGlvbiA9IHRydWU7XG4gIH1cblxuICBwdWJsaWMgc3RvcEFuaW1hdGlvbigpIHtcbiAgICB0aGlzLmFuaW1hdGlvbiA9IGZhbHNlO1xuICB9XG5cbiAgcHVibGljICpzcHJlYWRPcnRob2dvbmFsKHN0YXJ0OiBQb2ludCwgc3BhY2luZzogbnVtYmVyKSB7XG4gICAgY29uc3Qgc2lnbiA9IHRoaXMubWF0aC5mbGlwU2lnbigpO1xuICAgIGxldCBjdXJyZW50UG9pbnQgPSBzdGFydDtcbiAgICBsZXQgaSA9IDA7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgY3VycmVudFNwYWNpbmcgPSBzaWduLm5leHQoKS52YWx1ZSAqIHNwYWNpbmcgKiBpO1xuICAgICAgY3VycmVudFBvaW50ID0gdGhpcy5zaGlmdFBvaW50KGN1cnJlbnRQb2ludCwgc3RhcnQuYXNjZW50LCBjdXJyZW50U3BhY2luZyk7XG5cbiAgICAgIHlpZWxkIGN1cnJlbnRQb2ludDtcblxuICAgICAgaSsrO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzaGlmdFBvaW50KHBvaW50OiBQb2ludCwgcmFkaWFuczogbnVtYmVyLCBzcGFjaW5nOiBudW1iZXIpOiBQb2ludCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IE1hdGguc2luKHJhZGlhbnMgKiBNYXRoLlBJKSAqIHNwYWNpbmcgKyBwb2ludC54LFxuICAgICAgeTogTWF0aC5jb3MocmFkaWFucyAqIE1hdGguUEkpICogc3BhY2luZyArIHBvaW50LnlcbiAgICB9O1xuICB9XG59XG4iLCIvKipcbiAqIENvcHlyaWdodCAoQykgMjAxOCBNaWNoYWVsIEN6ZWNob3dza2kgPG1haWxAZGFpbHlzaC5pdD5cbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0XG4gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZVxuICogU29mdHdhcmUgRm91bmRhdGlvbjsgdmVyc2lvbiAyLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVFxuICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3JcbiAqIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbG9uZyB3aXRoXG4gKiB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTFcbiAqIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBLlxuICovXG5cbmltcG9ydCB7IFZpZXdDaGlsZCwgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBPbkNoYW5nZXMsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBpbnRlcnZhbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0ICogYXMgU2VsZWN0aW9uIGZyb20gJ2QzLXNlbGVjdGlvbic7XG5pbXBvcnQgKiBhcyBTaGFwZSBmcm9tICdkMy1zaGFwZSc7XG5pbXBvcnQgKiBhcyBSYW5kb20gZnJvbSAnZDMtcmFuZG9tJztcbmltcG9ydCAqIGFzIERyYWcgZnJvbSAnZDMtZHJhZyc7XG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi8uLi9tb2RlbHMvZ3JhcGgubW9kZWwnO1xuaW1wb3J0IHsgQ29uZmlnIH0gZnJvbSAnLi8uLi9tb2RlbHMvY29uZmlnLm1vZGVsJztcbmltcG9ydCB7IFBvaW50IH0gZnJvbSAnLi8uLi9tb2RlbHMvcG9pbnQubW9kZWwnO1xuaW1wb3J0IHsgTmxzQ2FudmFzU2VydmljZSB9IGZyb20gJy4vLi4vc2VydmljZXMvY2FudmFzLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmxzSGlzdG9yeVNlcnZpY2UgfSBmcm9tICcuLy4uL3NlcnZpY2VzL2hpc3Rvcnkuc2VydmljZSc7XG5pbXBvcnQgeyBObHNNYXRoU2VydmljZSB9IGZyb20gJy4vLi4vc2VydmljZXMvbWF0aC5zZXJ2aWNlJztcbmltcG9ydCB7IE5sc0d1aWxsb2NoZURpcmVjdGl2ZSB9IGZyb20gJy4vLi4vZGlyZWN0aXZlcy9ndWlsbG9jaGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IE5sc0dyYXBoU2VydmljZSB9IGZyb20gJy4vLi4vc2VydmljZXMvZ3JhcGguc2VydmljZSc7XG5cbmNvbnN0IFJFU0laSU5HX1RJTUVPVVQgPSA4MDA7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25scy1ncmFwaHMnLFxuICB0ZW1wbGF0ZTogYDxzdmcgI3N2ZyB3aWR0aD1cIjEwMCVcIiBoZWlnaHQ9XCIxMDAlXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG52ZXJzaW9uPVwiMS4xXCIgc2hhcGUtcmVuZGVyaW5nPVwiZ2VvbWV0cmljUHJlY2lzaW9uXCI+XG4gIDxnIG5sc0d1aWxsb2NoZSAqbmdGb3I9XCJsZXQgZ3JhcGggb2YgZ3JhcGhzXCIgW2dyYXBoXT1cImdyYXBoXCIgW2FuaW1hdGlvbl09XCJhbmltYXRpb25cIj48L2c+XG48L3N2Zz5cbmAsXG4gIHN0eWxlczogW2A6aG9zdHtwb3NpdGlvbjphYnNvbHV0ZTt3aWR0aDoxMDAlO2hlaWdodDoxMDAlO3RvcDowO2xlZnQ6MDtvdmVyZmxvdzpoaWRkZW59YF1cbn0pXG5leHBvcnQgY2xhc3MgTmxzR3JhcGhzQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuICBwdWJsaWMgY2FudmFzOiBhbnkgfCBudWxsO1xuICBwdWJsaWMgbWF0cml4OiBhbnkgfCBudWxsO1xuICBwdWJsaWMgZ3JhcGhzOiBHcmFwaFtdO1xuICBwdWJsaWMgd2luZG93SGVpZ2h0OiBudW1iZXIgfCBudWxsO1xuICBwdWJsaWMgd2luZG93V2lkdGg6IG51bWJlciB8IG51bGw7XG5cbiAgcHJpdmF0ZSBnZW5TaGlmdFBvaW50OiBhbnkgfCBudWxsO1xuICBwcml2YXRlIGdlbkxvYWRlZEFsbEdyYXBoczogYW55IHwgbnVsbDtcbiAgcHJpdmF0ZSBoYXNoOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVzaXppbmdXaW5kb3c6IGFueTtcblxuICBASW5wdXQoKSBjb25maWc6IENvbmZpZztcbiAgQElucHV0KCkgcmVzdG9yZWRIaXN0b3J5OiBhbnk7XG4gIEBJbnB1dCgpIGFuaW1hdGlvbjogYm9vbGVhbjtcbiAgQE91dHB1dCgpIHN2Z0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGdyYXBoQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAVmlld0NoaWxkKCdzdmcnKSBzdmdFbGVtZW50UmVmO1xuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbJyRldmVudCddKVxuICBvblJlc2l6ZShldmVudCkge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnJlc2l6aW5nV2luZG93KTtcblxuICAgIHRoaXMucmVzaXppbmdXaW5kb3cgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY2FudmFzID0gdGhpcy5hZGp1c3RDYW52YXMoKTtcbiAgICAgIHRoaXMubWF0cml4ID0gdGhpcy5jYWxjTWF0cml4KCk7XG4gICAgICB0aGlzLnVwZGF0ZUdyYXBocygpO1xuICAgIH0sIFJFU0laSU5HX1RJTUVPVVQpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjYW52YXNTZXJ2aWNlOiBObHNDYW52YXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgaGlzdG9yeVNlcnZpY2U6IE5sc0hpc3RvcnlTZXJ2aWNlLFxuICAgIHByaXZhdGUgbWF0aDogTmxzTWF0aFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBncmFwaFNlcnZpY2U6IE5sc0dyYXBoU2VydmljZVxuICApIHtcbiAgICB0aGlzLmdlbkxvYWRlZEFsbEdyYXBocyA9IHRoaXMuY291bnRMb2FkZWRHcmFwaHMoKTtcbiAgICB0aGlzLnJlc2l6aW5nV2luZG93ID0gZmFsc2U7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgdGhpcy5jYW52YXMgPSB0aGlzLmFkanVzdENhbnZhcygpO1xuICAgIHRoaXMubWF0cml4ID0gdGhpcy5jYWxjTWF0cml4KCk7XG5cbiAgICBpZiAoY2hhbmdlcy5jb25maWcpIHtcbiAgICAgIHRoaXMudXBkYXRlR3JhcGhzKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVzdG9yZWRIaXN0b3J5ICYmIHRoaXMucmVzdG9yZWRIaXN0b3J5Lmhhc2ggIT09IHRoaXMuaGFzaCkge1xuICAgICAgdGhpcy5yZXN0b3JlR3JhcGgoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlc3RvcmVHcmFwaCgpIHtcbiAgICB0aGlzLmdyYXBocyA9IHRoaXMucmVzdG9yZWRIaXN0b3J5LmdyYXBocztcbiAgICB0aGlzLmhhc2ggPSB0aGlzLnJlc3RvcmVkSGlzdG9yeS5oYXNoO1xuICB9XG5cbiAgcHJpdmF0ZSBzYXZlSGlzdG9yeSgpIHtcbiAgICB0aGlzLmhhc2ggPSB0aGlzLmhpc3RvcnlTZXJ2aWNlLmhhc2godGhpcy5ncmFwaHMpO1xuICAgIHRoaXMuaGlzdG9yeVNlcnZpY2Uuc2F2ZSh0aGlzLmdyYXBocywgdGhpcy5jb25maWcpO1xuICB9XG5cbiAgcHJpdmF0ZSBzYXZlR3JhcGgoKSB7XG4gICAgdGhpcy5ncmFwaFNlcnZpY2Uuc2V0KHRoaXMuZ3JhcGhzKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlR3JhcGhzKCk6IHZvaWQge1xuICAgIGNvbnN0IGdlblNoaWZ0U3RhcnQgPSB0aGlzLnNoaWZ0UG9pbnQodGhpcy5tYXRyaXguc3RhcnQsIHRoaXMuY29uZmlnLnZlY3RvcnMuc3RhcnQpO1xuICAgIGNvbnN0IGdlblNoaWZ0RW5kID0gdGhpcy5zaGlmdFBvaW50KHRoaXMubWF0cml4LmVuZCwgdGhpcy5jb25maWcudmVjdG9ycy5lbmQsIGZhbHNlKTtcblxuICAgIGNvbnNvbGUubG9nKHRoaXMubWF0cml4KTtcblxuICAgIGNvbnN0IGN1cnZlTGlzdCA9IFtcbiAgICAgIHtcbiAgICAgICAgY29sb3I6IHRoaXMuY29uZmlnLmNvbG9ycy5wcmltYXJ5LFxuICAgICAgICBzdGFydDogZ2VuU2hpZnRTdGFydC5uZXh0KCkudmFsdWUsXG4gICAgICAgIGVuZDogZ2VuU2hpZnRFbmQubmV4dCgpLnZhbHVlXG4gICAgICAgIC8vIHN0YXJ0OiB7XG4gICAgICAgIC8vICAgcG9pbnQ6IHRoaXMubWF0cml4LnN0YXJ0LFxuICAgICAgICAvLyAgIHZlY3RvcjogdGhpcy5jb25maWcudmVjdG9ycy5zdGFydFxuICAgICAgICAvLyB9LFxuICAgICAgICAvLyBlbmQ6IHtcbiAgICAgICAgLy8gICBwb2ludDogdGhpcy5tYXRyaXguZW5kLFxuICAgICAgICAvLyAgIHZlY3RvcjogdGhpcy5jb25maWcudmVjdG9ycy5lbmRcbiAgICAgICAgLy8gfVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgY29sb3I6IHRoaXMuY29uZmlnLmNvbG9ycy5zZWNvbmRhcnksXG4gICAgICAgIHN0YXJ0OiBnZW5TaGlmdEVuZC5uZXh0KCkudmFsdWUsXG4gICAgICAgIGVuZDogZ2VuU2hpZnRTdGFydC5uZXh0KCkudmFsdWVcbiAgICAgICAgLy8gZW5kOiB7XG4gICAgICAgIC8vICAgcG9pbnQ6IHRoaXMubWF0cml4LnN0YXJ0LFxuICAgICAgICAvLyAgIHZlY3RvcjogdGhpcy5jb25maWcudmVjdG9ycy5zdGFydFxuICAgICAgICAvLyB9LFxuICAgICAgICAvLyBzdGFydDoge1xuICAgICAgICAvLyAgIHBvaW50OiB0aGlzLm1hdHJpeC5lbmQsXG4gICAgICAgIC8vICAgdmVjdG9yOiB0aGlzLmNvbmZpZy52ZWN0b3JzLmVuZFxuICAgICAgICAvLyB9XG4gICAgICB9XG4gICAgXTtcblxuICAgIHRoaXMuZ3JhcGhzID0gY3VydmVMaXN0Lm1hcChjdXJ2ZSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi50aGlzLmFkanVzdEdyYXBoKGN1cnZlKSxcbiAgICAgICAgc3ByZWFkOiB0aGlzLmNvbmZpZy5zcHJlYWQsXG4gICAgICAgIGludGVydmFsOiB0aGlzLmNvbmZpZy5pbnRlcnZhbFxuICAgICAgfTtcbiAgICB9KTtcbiAgICB0aGlzLmhhc2ggPSB0aGlzLmhpc3RvcnlTZXJ2aWNlLmhhc2godGhpcy5ncmFwaHMpO1xuICAgIHRoaXMuc2F2ZUhpc3RvcnkoKTtcbiAgICB0aGlzLnNhdmVHcmFwaCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGp1c3RHcmFwaChjdXJ2ZSkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKGN1cnZlLCB7XG4gICAgICBzdHJva2U6IHRoaXMuY29uZmlnLnN0cm9rZSxcbiAgICAgIHN0YXJ0OiBPYmplY3QuYXNzaWduKGN1cnZlLnN0YXJ0LCB7XG4gICAgICAgIGRpcmVjdGlvbjogdGhpcy5nZW5WZWN0b3JQb2ludChjdXJ2ZS5zdGFydC5wb2ludCwgY3VydmUuc3RhcnQudmVjdG9yKVxuICAgICAgfSksXG4gICAgICBlbmQ6IE9iamVjdC5hc3NpZ24oY3VydmUuZW5kLCB7XG4gICAgICAgIGRpcmVjdGlvbjogdGhpcy5nZW5WZWN0b3JQb2ludChjdXJ2ZS5lbmQucG9pbnQsIGN1cnZlLmVuZC52ZWN0b3IpXG4gICAgICB9KSxcbiAgICAgIG5vZGVzOiB0aGlzLmdlblJhbmRvbVBvaW50cyh0aGlzLmNvbmZpZy5ub2RlcylcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2VuUmFuZG9tUG9pbnRzKG51bTogbnVtYmVyKSB7XG4gICAgY29uc3QgZ2VuZXJhdGVkUG9pbnRzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY29uZmlnLm5vZGVzOyBpKyspIHtcbiAgICAgIGdlbmVyYXRlZFBvaW50cy5wdXNoKHRoaXMubWF0aC5yYW5kb21Qb2ludCh0aGlzLm1hdHJpeCwgdGhpcy5jb25maWcub3ZlcmxhcCkpO1xuICAgIH1cblxuICAgIHJldHVybiBnZW5lcmF0ZWRQb2ludHM7XG4gIH1cblxuICBwcml2YXRlIGZsaXBmbG9wKHg6IHN0cmluZykge1xuICAgIHJldHVybiAoeCA9PT0gJ3N0YXJ0JykgPyAnZW5kJyA6ICdzdGFydCc7XG4gIH1cblxuICBwcml2YXRlIGFkanVzdENhbnZhcygpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhc1NlcnZpY2Uuc2V0KHRoaXMuY2FudmFzKTtcbiAgICB0aGlzLmNhbnZhc1NlcnZpY2UuYWRqdXN0VG9XaW5kb3coKTtcblxuICAgIHJldHVybiB0aGlzLnN2Z0VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgfVxuXG4gIHByaXZhdGUgY2FsY01hdHJpeCgpIHtcbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodDtcbiAgICBjb25zdCB0b3RhbEFyZWEgPSBNYXRoLmFicyhjYW52YXNXaWR0aCAqIGNhbnZhc0hlaWdodCk7XG4gICAgY29uc3QgdG90YWxDZW50ZXIgPSB0aGlzLm1hdGguY2VudGVyT2ZBcmVhKGNhbnZhc1dpZHRoLCBjYW52YXNIZWlnaHQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXJ0OiB7XG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IGNhbnZhc0hlaWdodCAtIHRoaXMuY29uZmlnLnZlY3RvcnMuc3BhY2luZyAtIHRoaXMuY29uZmlnLm1hcmdpbi55XG4gICAgICB9LFxuICAgICAgZW5kOiB7XG4gICAgICAgIHg6IGNhbnZhc1dpZHRoIC0gdGhpcy5jb25maWcudmVjdG9ycy5zcGFjaW5nIC0gdGhpcy5jb25maWcubWFyZ2luLngsXG4gICAgICAgIHk6IDBcbiAgICAgIH0sXG4gICAgICB3aWR0aDogY2FudmFzV2lkdGgsXG4gICAgICBoZWlnaHQ6IGNhbnZhc0hlaWdodCxcbiAgICAgIGNlbnRlcjogdG90YWxDZW50ZXJcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBnZW5WZWN0b3JQb2ludChwb2ludDogUG9pbnQsIHZlY3RvcjogbnVtYmVyKSB7XG4gICAgY29uc3QgcmFuZ2UgPSB0aGlzLm1hdGguw47ClCh0aGlzLm1hdHJpeC5zdGFydCwgdGhpcy5tYXRyaXguZW5kKSAqIHRoaXMuY29uZmlnLnZlY3RvcnMucmFuZ2U7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogcmFuZ2UgKiBNYXRoLnNpbihNYXRoLlBJICogdmVjdG9yKSArIHBvaW50LngsXG4gICAgICB5OiByYW5nZSAqIE1hdGguY29zKE1hdGguUEkgKiB2ZWN0b3IpICsgcG9pbnQueVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlICpzaGlmdFBvaW50KHBvaW50OiBQb2ludCwgdmVjdG9yOiBudW1iZXIsIHN0YXJ0UG9zaXRpdmU6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgY29uc3QgZ2VuU2hpZnRYID0gdGhpcy5zaGlmdE51bWJlcih0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcsIHZlY3Rvciwgc3RhcnRQb3NpdGl2ZSk7XG4gICAgY29uc3QgZ2VuU2hpZnRZID0gdGhpcy5zaGlmdE51bWJlcih0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcsIHZlY3Rvciwgc3RhcnRQb3NpdGl2ZSk7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgeWllbGQge1xuICAgICAgICBwb2ludDoge1xuICAgICAgICAgIHg6IE1hdGguY29zKE1hdGguUEkgKiB2ZWN0b3IpICogZ2VuU2hpZnRYLm5leHQoKS52YWx1ZSArIHBvaW50LngsXG4gICAgICAgICAgeTogTWF0aC5zaW4oTWF0aC5QSSAqIHZlY3RvcikgKiBnZW5TaGlmdFkubmV4dCgpLnZhbHVlICsgcG9pbnQueSxcbiAgICAgICAgfSxcbiAgICAgICAgdmVjdG9yOiB2ZWN0b3JcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSAqc2hpZnROdW1iZXIoc3BhY2U6IG51bWJlciwgdmVjdG9yOiBudW1iZXIsIHN0YXJ0UG9zaXRpdmU6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgbGV0IGN1cnJlbnQgPSAwO1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgY29uc3Qgc2lnbiA9IHRoaXMubWF0aC5mbGlwU2lnbihzdGFydFBvc2l0aXZlKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICB5aWVsZCBjdXJyZW50ID0gc2lnbi5uZXh0KCkudmFsdWUgKiBpbmRleCAqIHNwYWNlICsgY3VycmVudDtcbiAgICAgIGluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHByZXBhcmVHdWlsbG9jaGVFeHBvcnQoZ3VpbGxvY2hlRWxlbWVudCkge1xuICAgIGlmICh0aGlzLmdlbkxvYWRlZEFsbEdyYXBocy5uZXh0KCkudmFsdWUpIHtcbiAgICAgIHRoaXMuc3ZnQ2hhbmdlLmVtaXQodGhpcy5zdmdFbGVtZW50UmVmKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlICpjb3VudExvYWRlZEdyYXBocygpIHtcbiAgICBsZXQgY3ljbGVzID0gMTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAoY3ljbGVzIDwgdGhpcy5ncmFwaHMubGVuZ3RoKSB7XG4gICAgICAgIHlpZWxkIGZhbHNlO1xuICAgICAgICBjeWNsZXMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHlpZWxkIHRydWU7XG4gICAgICAgIGN5Y2xlcyA9IDE7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIENvcHlyaWdodCAoQykgMjAxOCBNaWNoYWVsIEN6ZWNob3dza2kgPG1haWxAZGFpbHlzaC5pdD5cbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0XG4gKiB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZVxuICogU29mdHdhcmUgRm91bmRhdGlvbjsgdmVyc2lvbiAyLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVFxuICogQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3JcbiAqIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbG9uZyB3aXRoXG4gKiB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTFcbiAqIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBLlxuICovXG5cbmltcG9ydCB7IEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIERpcmVjdGl2ZSwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIFNlbGVjdGlvbiBmcm9tICdkMy1zZWxlY3Rpb24nO1xuaW1wb3J0ICogYXMgU2hhcGUgZnJvbSAnZDMtc2hhcGUnO1xuaW1wb3J0ICogYXMgUmFuZG9tIGZyb20gJ2QzLXJhbmRvbSc7XG5pbXBvcnQgKiBhcyBEcmFnIGZyb20gJ2QzLWRyYWcnO1xuaW1wb3J0ICogYXMgRWFzZSBmcm9tICdkMy1lYXNlJztcbmltcG9ydCAqIGFzIFRpbWVyIGZyb20gJ2QzLXRpbWVyJztcblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLy4uL21vZGVscy9ncmFwaC5tb2RlbCc7XG5pbXBvcnQgeyBQb2ludCB9IGZyb20gJy4vLi4vbW9kZWxzL3BvaW50Lm1vZGVsJztcbmltcG9ydCB7IE5sc0NhbnZhc1NlcnZpY2UgfSBmcm9tICcuLy4uL3NlcnZpY2VzL2NhbnZhcy5zZXJ2aWNlJztcbmltcG9ydCB7IE5sc01hdGhTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9tYXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmxzR3JhcGhTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvZ3JhcGguc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tubHNHdWlsbG9jaGVdJ1xufSlcbmV4cG9ydCBjbGFzcyBObHNHdWlsbG9jaGVEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cbiAgcHJpdmF0ZSBjYW52YXM6IGFueTtcbiAgcHJpdmF0ZSBncm91cDogYW55O1xuICBwcml2YXRlIGJvdW5jZTogYW55IHwgbnVsbDtcbiAgcHJpdmF0ZSBib3VuY2VzOiBhbnkgfCBudWxsO1xuICBwcml2YXRlIGluaXRpYWxOb2RlczogYW55O1xuICBwcml2YXRlIGluaXRpYWxDdXJ2ZTogYW55O1xuICBwcml2YXRlIGFuaW1hdGlvbkludGVydmFsOiBhbnk7XG4gIHByaXZhdGUgbWVkaWFuUG9pbnQ6IFBvaW50O1xuICBwcml2YXRlIG1lZGlhbkluZGV4OiBudW1iZXI7XG4gIHByaXZhdGUgcGF0aEVsZW1lbnRzOiBhbnk7XG5cbiAgQElucHV0KCkgZ3JhcGg6IEdyYXBoO1xuICBASW5wdXQoKSBhbmltYXRpb246IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjYW52YXNTZXJ2aWNlOiBObHNDYW52YXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBtYXRoOiBObHNNYXRoU2VydmljZSxcbiAgICBwcml2YXRlIGdyYXBoU2VydmljZTogTmxzR3JhcGhTZXJ2aWNlXG4gICkge1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5ncm91cC5zZWxlY3RBbGwoJyonKS5yZW1vdmUoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICB0aGlzLmdyb3VwID0gU2VsZWN0aW9uLnNlbGVjdCh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICAgIHRoaXMuY2FudmFzID0gU2VsZWN0aW9uLnNlbGVjdCh0aGlzLmNhbnZhc1NlcnZpY2UuZ2V0KTtcbiAgICAvLyBAdG9kbyBtb2RpZnkgZ3JhcGggaGVyZSBpbnN0ZWFkIG9mIGluIGdyYXBocy5jb21wb25lbnQudHNcbiAgICB0aGlzLmluaXRpYWxOb2RlcyA9IHRoaXMuZ3JhcGgubm9kZXMuc2xpY2UoKTtcbiAgICB0aGlzLmluaXRpYWxDdXJ2ZSA9IFtcbiAgICAgIHRoaXMuZ3JhcGguc3RhcnQucG9pbnQsXG4gICAgICB0aGlzLmdyYXBoLnN0YXJ0LmRpcmVjdGlvbixcbiAgICAgIC4uLnRoaXMuZ3JhcGgubm9kZXMuc2xpY2UoKSxcbiAgICAgIHRoaXMuZ3JhcGguZW5kLmRpcmVjdGlvbixcbiAgICAgIHRoaXMuZ3JhcGguZW5kLnBvaW50XG4gICAgXTtcbiAgICB0aGlzLm1lZGlhblBvaW50ID0gdGhpcy5tYXRoLm1lZGlhbk9mQ3VydmUodGhpcy5pbml0aWFsQ3VydmUpO1xuICAgIHRoaXMubWVkaWFuSW5kZXggPSB0aGlzLm1hdGgubWVkaWFuSW5kZXgodGhpcy5pbml0aWFsQ3VydmUpO1xuXG4gICAgaWYgKHRoaXMuYW5pbWF0aW9uKSB7XG4gICAgICB0aGlzLmdyYXBoLm5vZGVzID0gdGhpcy5ncmFwaC5ub2Rlcy5zbGljZSgpLm1hcCgobm9kZSwgaSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHg6IG5vZGUueCxcbiAgICAgICAgICB5OiBub2RlLnksXG4gICAgICAgICAgLy8gYXNjZW50OiBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAxMDApIC8gMTAwXG4gICAgICAgICAgYXNjZW50OiB0aGlzLm1lZGlhblBvaW50LmFzY2VudCArIGkgKiAwLjVcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5ib3VuY2VzID0gdGhpcy5pbml0aWFsTm9kZXMubWFwKG5vZGUgPT4ge1xuICAgICAgICBjb25zdCBib3VuY2VBbXBsaXR1ZGUgPSBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAxNTApO1xuICAgICAgICByZXR1cm4gdGhpcy5tYXRoLmJvdW5jZShib3VuY2VBbXBsaXR1ZGUsIDMpO1xuICAgICAgfSk7XG4gICAgICBsZXQgaSA9IDA7XG4gICAgICB0aGlzLmFuaW1hdGlvbkludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICB0aGlzLmFuaW1hdGVHcmFwaChpKysgJSAxMDAwIC8gMTAwMDApO1xuICAgICAgfSwgdGhpcy5ncmFwaC5pbnRlcnZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmFuaW1hdGlvbkludGVydmFsKSB7XG4gICAgICAgIHRoaXMuYm91bmNlID0gbnVsbDtcbiAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmFuaW1hdGlvbkludGVydmFsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmdyb3VwLnNlbGVjdEFsbCgnKicpLnJlbW92ZSgpO1xuICAgIHRoaXMucGF0aEVsZW1lbnRzID0gW107XG5cbiAgICBjb25zdCBncmFwaHMgPSB0aGlzLnNwcmVhZExpbmVzKFtcbiAgICAgIHRoaXMuZ3JhcGguc3RhcnQucG9pbnQsXG4gICAgICB0aGlzLmdyYXBoLnN0YXJ0LmRpcmVjdGlvbixcbiAgICAgIC4uLnRoaXMuZ3JhcGgubm9kZXMsXG4gICAgICB0aGlzLmdyYXBoLmVuZC5kaXJlY3Rpb24sXG4gICAgICB0aGlzLmdyYXBoLmVuZC5wb2ludCxcbiAgICBdKS5mb3JFYWNoKChwb2ludHMsIGluZGV4KSA9PiB0aGlzLmRyYXdHcmFwaChwb2ludHMpKTtcbiAgfVxuXG4gIHByaXZhdGUgYW5pbWF0ZUdyYXBoKHgpIHtcbiAgICBjb25zdCBncmFwaHMgPSB0aGlzLnNwcmVhZExpbmVzKFtcbiAgICAgIHRoaXMuZ3JhcGguc3RhcnQucG9pbnQsXG4gICAgICB0aGlzLmdyYXBoLnN0YXJ0LmRpcmVjdGlvbixcbiAgICAgIC4uLnRoaXMuZ3JhcGgubm9kZXMubWFwKChwb2ludCwgaSkgPT4ge1xuICAgICAgICBjb25zdCBhc2NlbnQgPSBwb2ludC5hc2NlbnQgKiBNYXRoLnNpbihNYXRoLlBJICogeCk7XG4gICAgICAgIHJldHVybiB0aGlzLmdyYXBoU2VydmljZS5zaGlmdFBvaW50KHBvaW50LCBhc2NlbnQsIHRoaXMuYm91bmNlc1tpXS5uZXh0KCkudmFsdWUpO1xuICAgICAgfSksXG4gICAgICB0aGlzLmdyYXBoLmVuZC5kaXJlY3Rpb24sXG4gICAgICB0aGlzLmdyYXBoLmVuZC5wb2ludCxcbiAgICBdKTtcblxuICAgIGdyYXBocy5mb3JFYWNoKChwb2ludHMsIGkpID0+IHRoaXMudXBkYXRlR3JhcGgocG9pbnRzLCBpKSk7XG4gIH1cblxuICBwcml2YXRlIHNwcmVhZExpbmVzKHBvaW50czogUG9pbnRbXSkge1xuICAgIGNvbnN0IHNoaWZ0ZWRNZWRpYW5zID0gW107XG4gICAgY29uc3QgZ2Vuc2hpZnRlZE1lZGlhbnMgPSB0aGlzLmdyYXBoU2VydmljZS5zcHJlYWRPcnRob2dvbmFsKHRoaXMubWVkaWFuUG9pbnQsIHRoaXMuZ3JhcGguc3ByZWFkLnNwYWNpbmcpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmdyYXBoLnNwcmVhZC5hbW91bnQ7IGkrKykge1xuICAgICAgc2hpZnRlZE1lZGlhbnMucHVzaChnZW5zaGlmdGVkTWVkaWFucy5uZXh0KCkudmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiBzaGlmdGVkTWVkaWFucy5tYXAobWVkaWFuID0+IHtcbiAgICAgIGNvbnN0IHNoaWZ0ZWRQb2ludHMgPSBwb2ludHMuc2xpY2UoKTtcbiAgICAgIHNoaWZ0ZWRQb2ludHMuc3BsaWNlKHRoaXMubWVkaWFuSW5kZXgsIDEsIG1lZGlhbik7XG4gICAgICByZXR1cm4gc2hpZnRlZFBvaW50cztcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlR3JhcGgocG9pbnRzOiBQb2ludFtdLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5wYXRoRWxlbWVudHNbaW5kZXhdXG4gICAgICAuYXR0cignZCcsIFNoYXBlLmxpbmUoKVxuICAgICAgICAueChwID0+IHAueClcbiAgICAgICAgLnkocCA9PiBwLnkpXG4gICAgICAgIC5jdXJ2ZShTaGFwZS5jdXJ2ZUJhc2lzKShwb2ludHMpKTtcbiAgfVxuXG4gIHByaXZhdGUgZHJhd0dyYXBoKHBvaW50czogUG9pbnRbXSk6IHZvaWQge1xuICAgIHRoaXMuZ3JvdXBcbiAgICAgIC5hdHRyKCdzdHJva2UnLCB0aGlzLmdyYXBoLmNvbG9yKVxuICAgICAgLmF0dHIoJ3N0cm9rZS13aWR0aCcsIHRoaXMuZ3JhcGguc3Ryb2tlKVxuICAgICAgLmF0dHIoJ2ZpbGwnLCAnbm9uZScpO1xuXG4gICAgdGhpcy5wYXRoRWxlbWVudHMucHVzaChcbiAgICAgIHRoaXMuZ3JvdXAuYXBwZW5kKCdwYXRoJylcbiAgICAgICAgLmF0dHIoJ2QnLCBTaGFwZS5saW5lKClcbiAgICAgICAgICAueChwID0+IHAueClcbiAgICAgICAgICAueShwID0+IHAueSlcbiAgICAgICAgICAuY3VydmUoU2hhcGUuY3VydmVCYXNpcykocG9pbnRzKSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBkZWJ1Z0dyYXBoKHBvaW50czogUG9pbnRbXSkge1xuICAgIHBvaW50cy5mb3JFYWNoKChwb2ludCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGNpcmNsZSA9IHRoaXMuZ3JvdXAuYXBwZW5kKCdnJyk7XG5cbiAgICAgIGNpcmNsZS5hcHBlbmQoJ2NpcmNsZScpXG4gICAgICAgIC5hdHRyKCdjeCcsIHBvaW50LngpXG4gICAgICAgIC5hdHRyKCdjeScsIHBvaW50LnkpXG4gICAgICAgIC5hdHRyKCdyJywgMylcbiAgICAgICAgLmF0dHIoJ2ZpbGwtb3BhY2l0eScsIDAuNilcbiAgICAgICAgLmF0dHIoJ2ZpbGwnLCB0aGlzLmdyYXBoLmNvbG9yKTtcblxuICAgICAgY2lyY2xlLmFwcGVuZCgndGV4dCcpXG4gICAgICAgIC5hdHRyKCd4JywgcG9pbnQueClcbiAgICAgICAgLmF0dHIoJ3knLCBwb2ludC55KVxuICAgICAgICAuYXR0cignZHgnLCA4KVxuICAgICAgICAuYXR0cignZHknLCAxNSlcbiAgICAgICAgLmF0dHIoJ2ZpbGwnLCB0aGlzLmdyYXBoLmNvbG9yKVxuICAgICAgICAudGV4dChpbmRleCk7XG4gICAgfSk7XG4gIH1cbn1cbiIsIi8qKlxuICogQ29weXJpZ2h0IChDKSAyMDE4IE1pY2hhZWwgQ3plY2hvd3NraSA8bWFpbEBkYWlseXNoLml0PlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXRcbiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG4gKiBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB2ZXJzaW9uIDIuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3JcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvclxuICogbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGhcbiAqIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MVxuICogRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBPcHRpb25hbCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpbnRlcnZhbCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0ICogYXMgU2VsZWN0aW9uIGZyb20gJ2QzLXNlbGVjdGlvbic7XG5cbmltcG9ydCB7IEdyYXBoIH0gZnJvbSAnLi4vbW9kZWxzL2dyYXBoLm1vZGVsJztcbmltcG9ydCB7IE5sc01hdGhTZXJ2aWNlIH0gZnJvbSAnLi9tYXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmxzSGlzdG9yeVNlcnZpY2UgfSBmcm9tICcuL2hpc3Rvcnkuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBObHNBbmltYXRpb25TZXJ2aWNlIHtcblxuICBwdWJsaWMgZ3JhcGhzOiBHcmFwaFtdO1xuICBwdWJsaWMgc3BlZWQ6IG51bWJlcjtcbiAgcHVibGljIHJhbmdlOiBudW1iZXI7XG4gIC8vIHB1YmxpYyBnZW5BbmltYXRpb246IGFueTtcbiAgLy8gcHJpdmF0ZSB0aW1lcjogT2JzZXJ2YWJsZTxudW1iZXI+O1xuICAvLyBwcml2YXRlIHN1YnNjcmlidGlvbjogYW55O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbWF0aDogTmxzTWF0aFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBoaXN0b3J5U2VydmljZTogTmxzSGlzdG9yeVNlcnZpY2UsXG4gICkge1xuICB9XG5cbiAgLy8gcHVibGljIGFuaW1hdGUoaW5pdGlhbEdyYXBoczogR3JhcGhbXSkge1xuICBwdWJsaWMgYW5pbWF0ZShpbml0aWFsR3JhcGg6IEdyYXBoKSB7XG4gICAgLy8gY29uc3QgbmV3R3JhcGhzID0gaW5pdGlhbEdyYXBocy5zbGljZSgpO1xuXG4gICAgLy8gcmV0dXJuIG5ld0dyYXBocy5tYXAoZ3JhcGggPT4ge1xuXG4gICAgICBjb25zdCBuZXdHcmFwaCA9IE9iamVjdC5hc3NpZ24oe30sIGluaXRpYWxHcmFwaCk7XG4gICAgICBjb25zdCBpbmRleE1pZGRsZSA9IE1hdGguZmxvb3IobmV3R3JhcGgubm9kZXMubGVuZ3RoICogMC41KTtcbiAgICAgIGNvbnN0IHBvaW50TWlkZGxlID0gbmV3R3JhcGgubm9kZXNbaW5kZXhNaWRkbGVdO1xuXG4gICAgICBuZXdHcmFwaC5ub2Rlcy5zcGxpY2UoaW5kZXhNaWRkbGUsIDEsIHtcbiAgICAgICAgeDogcG9pbnRNaWRkbGUueCAtIDIsXG4gICAgICAgIHk6IHBvaW50TWlkZGxlLnkgKyAyLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBuZXdHcmFwaDtcbiAgLy8gICB9KTtcbiAgfVxufVxuXG4iLCJpbXBvcnQgeyBCcm93c2VyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBObHNHcmFwaHNDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvZ3JhcGhzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBObHNHdWlsbG9jaGVEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZXMvZ3VpbGxvY2hlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBObHNIaXN0b3J5U2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvaGlzdG9yeS5zZXJ2aWNlJztcbmltcG9ydCB7IE5sc0NhbnZhc1NlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2NhbnZhcy5zZXJ2aWNlJztcbmltcG9ydCB7IE5sc01hdGhTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9tYXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmxzR3JhcGhTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9ncmFwaC5zZXJ2aWNlJztcblxuQE5nTW9kdWxlKHtcbiAgaW1wb3J0czogW1xuICAgIEJyb3dzZXJNb2R1bGVcbiAgXSxcbiAgZGVjbGFyYXRpb25zOiBbXG4gICAgTmxzR3JhcGhzQ29tcG9uZW50LFxuICAgIE5sc0d1aWxsb2NoZURpcmVjdGl2ZVxuICBdLFxuICBwcm92aWRlcnM6IFtcbiAgICBObHNIaXN0b3J5U2VydmljZSxcbiAgICBObHNDYW52YXNTZXJ2aWNlLFxuICAgIE5sc01hdGhTZXJ2aWNlLFxuICAgIE5sc0dyYXBoU2VydmljZSxcbiAgXSxcbiAgZXhwb3J0czogW1xuICAgIE5sc0dyYXBoc0NvbXBvbmVudCxcbiAgICBObHNHdWlsbG9jaGVEaXJlY3RpdmVcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBObHNHdWlsbG9jaGVNb2R1bGUge31cbiJdLCJuYW1lcyI6WyJSYW5kb20ucmFuZG9tVW5pZm9ybSIsIlNlbGVjdGlvbi5zZWxlY3QiLCJTaGFwZS5saW5lIiwiU2hhcGUuY3VydmVCYXNpcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7SUF5QkUsWUFDVTtRQUFBLG9CQUFlLEdBQWYsZUFBZTtRQUV2QixJQUFJLENBQUMsUUFBUSxHQUFHLGVBQWUsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0tBQzVEOzs7O1FBRVUsR0FBRztRQUNaLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQzs7Ozs7O0lBR2QsR0FBRyxDQUFDLEVBQUU7UUFDWCxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQzs7Ozs7SUFHWixjQUFjO1FBQ25CLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUNwQixJQUFJLENBQUMsTUFBTSxFQUNYLE9BQU8sRUFDUCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FDdkIsQ0FBQztZQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUNwQixJQUFJLENBQUMsTUFBTSxFQUNYLFFBQVEsRUFDUixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FDeEIsQ0FBQztTQUNIOzs7O1lBaENKLFVBQVU7Ozs7WUFINkIsZ0JBQWdCOzs7Ozs7OztJQ1V0RDtRQUNFLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0tBQ25COzs7Ozs7SUFFTSxJQUFJLENBQUMsTUFBZSxFQUFFLE1BQU07UUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDaEIsSUFBSSxFQUFFLElBQUks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