/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Copyright (C) 2018 Michael Czechowski * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; version 2. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { ViewChild, Component, Input, Output, EventEmitter, HostListener } from '@angular/core'; import { NlsCanvasService } from './../services/canvas.service'; import { NlsHistoryService } from './../services/history.service'; import { NlsMathService } from './../services/math.service'; import { NlsGraphService } from './../services/graph.service'; /** @type {?} */ const RESIZING_TIMEOUT = 800; export 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 totalArea = Math.abs(canvasWidth * canvasHeight); /** @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: ` `, 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'],] }] }; function NlsGraphsComponent_tsickle_Closure_declarations() { /** @type {?} */ NlsGraphsComponent.prototype.canvas; /** @type {?} */ NlsGraphsComponent.prototype.matrix; /** @type {?} */ NlsGraphsComponent.prototype.graphs; /** @type {?} */ NlsGraphsComponent.prototype.windowHeight; /** @type {?} */ NlsGraphsComponent.prototype.windowWidth; /** @type {?} */ NlsGraphsComponent.prototype.genShiftPoint; /** @type {?} */ NlsGraphsComponent.prototype.genLoadedAllGraphs; /** @type {?} */ NlsGraphsComponent.prototype.hash; /** @type {?} */ NlsGraphsComponent.prototype.resizingWindow; /** @type {?} */ NlsGraphsComponent.prototype.config; /** @type {?} */ NlsGraphsComponent.prototype.restoredHistory; /** @type {?} */ NlsGraphsComponent.prototype.animation; /** @type {?} */ NlsGraphsComponent.prototype.svgChange; /** @type {?} */ NlsGraphsComponent.prototype.graphChange; /** @type {?} */ NlsGraphsComponent.prototype.svgElementRef; /** @type {?} */ NlsGraphsComponent.prototype.canvasService; /** @type {?} */ NlsGraphsComponent.prototype.historyService; /** @type {?} */ NlsGraphsComponent.prototype.math; /** @type {?} */ NlsGraphsComponent.prototype.graphService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JhcGhzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25scy1ndWlsbG9jaGUvIiwic291cmNlcyI6WyJubHMvY29tcG9uZW50cy9ncmFwaHMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQkEsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBNEIsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQVUxSCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFNUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDOztBQUU5RCxNQUFNLGdCQUFnQixHQUFHLEdBQUcsQ0FBQztBQVc3QixNQUFNOzs7Ozs7O0lBK0JKLFlBQ1UsZUFDQSxnQkFDQSxNQUNBO1FBSEEsa0JBQWEsR0FBYixhQUFhO1FBQ2IsbUJBQWMsR0FBZCxjQUFjO1FBQ2QsU0FBSSxHQUFKLElBQUk7UUFDSixpQkFBWSxHQUFaLFlBQVk7eUJBbkJBLElBQUksWUFBWSxFQUFFOzJCQUNoQixJQUFJLFlBQVksRUFBRTtRQW9CeEMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO0tBQzdCOzs7OztJQWxCRCxRQUFRLENBQUMsS0FBSztRQUNaLFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ3BDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztTQUNyQixFQUFFLGdCQUFnQixDQUFDLENBQUM7S0FDdEI7Ozs7O0lBWUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRWhDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sWUFBUyxDQUFDO1lBQ25CLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztTQUNyQjtRQUVELEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDcEUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ3JCO0tBQ0Y7Ozs7SUFFTyxZQUFZO1FBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUM7UUFDMUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQzs7Ozs7SUFHaEMsV0FBVztRQUNqQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzs7Ozs7SUFHN0MsU0FBUztRQUNmLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzs7Ozs7SUFHN0IsWUFBWTs7UUFDbEIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQzs7UUFDcEYsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFckYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7O1FBRXpCLE1BQU0sU0FBUyxHQUFHO1lBQ2hCO2dCQUNFLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPO2dCQUNqQyxLQUFLLEVBQUUsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUs7Z0JBQ2pDLEdBQUcsRUFBRSxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSzthQVM5QjtZQUNEO2dCQUNFLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTO2dCQUNuQyxLQUFLLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUs7Z0JBQy9CLEdBQUcsRUFBRSxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSzthQVNoQztTQUNGLENBQUM7UUFFRixJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDbEMsTUFBTSxtQkFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUMxQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQzFCLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFDOUI7U0FDSCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDOzs7Ozs7SUFHWCxXQUFXLENBQUMsS0FBSztRQUN2QixNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7WUFDMUIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtZQUMxQixLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFO2dCQUNoQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQzthQUN0RSxDQUFDO1lBQ0YsR0FBRyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDNUIsU0FBUyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUM7YUFDbEUsQ0FBQztZQUNGLEtBQUssRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1NBQy9DLENBQUMsQ0FBQzs7Ozs7O0lBR0csZUFBZSxDQUFDLEdBQVc7O1FBQ2pDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQztRQUUzQixHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDM0MsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztTQUMvRTtRQUVELE1BQU0sQ0FBQyxlQUFlLENBQUM7Ozs7OztJQUdqQixRQUFRLENBQUMsQ0FBUztRQUN4QixNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDOzs7OztJQUduQyxZQUFZO1FBQ2xCLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRXBDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQzs7Ozs7SUFHbEMsVUFBVTs7UUFDaEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLEtBQUssQ0FBQzs7UUFDOUQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLE1BQU0sQ0FBQzs7UUFDaEUsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsWUFBWSxDQUFDLENBQUM7O1FBQ3ZELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUV0RSxNQUFNLENBQUM7WUFDTCxLQUFLLEVBQUU7Z0JBQ0wsQ0FBQyxFQUFFLENBQUM7Z0JBQ0osQ0FBQyxFQUFFLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUNyRTtZQUNELEdBQUcsRUFBRTtnQkFDSCxDQUFDLEVBQUUsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNuRSxDQUFDLEVBQUUsQ0FBQzthQUNMO1lBQ0QsS0FBSyxFQUFFLFdBQVc7WUFDbEIsTUFBTSxFQUFFLFlBQVk7WUFDcEIsTUFBTSxFQUFFLFdBQVc7U0FDcEIsQ0FBQzs7Ozs7OztJQUdJLGNBQWMsQ0FBQyxLQUFZLEVBQUUsTUFBYzs7UUFDakQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFFMUYsTUFBTSxDQUFDO1lBQ0wsQ0FBQyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUM7U0FDaEQsQ0FBQzs7Ozs7Ozs7S0FHSyxVQUFVLENBQUMsS0FBWSxFQUFFLE1BQWMsRUFBRSxnQkFBeUIsSUFBSTs7UUFDN0UsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDOztRQUN2RixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFFdkYsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUNaLE1BQU07Z0JBQ0osS0FBSyxFQUFFO29CQUNMLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQztvQkFDaEUsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDO2lCQUNqRTtnQkFDRCxNQUFNLEVBQUUsTUFBTTthQUNmLENBQUM7U0FDSDs7Ozs7Ozs7S0FHTSxXQUFXLENBQUMsS0FBYSxFQUFFLE1BQWMsRUFBRSxnQkFBeUIsSUFBSTs7UUFDL0UsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDOztRQUNoQixJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7O1FBQ2QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFL0MsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUNaLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEdBQUcsS0FBSyxHQUFHLEtBQUssR0FBRyxPQUFPLENBQUM7WUFDNUQsS0FBSyxFQUFFLENBQUM7U0FDVDs7Ozs7O0lBR0ksc0JBQXNCLENBQUMsZ0JBQWdCO1FBQzVDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztTQUN6Qzs7Ozs7S0FHTSxpQkFBaUI7O1FBQ3hCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztRQUVmLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDWixFQUFFLENBQUMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUNoQyxNQUFNLEtBQUssQ0FBQztnQkFDWixNQUFNLEVBQUUsQ0FBQzthQUNWO1lBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ04sTUFBTSxJQUFJLENBQUM7Z0JBQ1gsTUFBTSxHQUFHLENBQUMsQ0FBQzthQUNaO1NBQ0Y7Ozs7WUF2T0osU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxZQUFZO2dCQUN0QixRQUFRLEVBQUU7Ozs7Q0FJWDtnQkFDQyxNQUFNLEVBQUUsQ0FBQyw4RUFBOEUsQ0FBQzthQUN6Rjs7OztZQWhCUSxnQkFBZ0I7WUFDaEIsaUJBQWlCO1lBQ2pCLGNBQWM7WUFFZCxlQUFlOzs7cUJBMEJyQixLQUFLOzhCQUNMLEtBQUs7d0JBQ0wsS0FBSzt3QkFDTCxNQUFNOzBCQUNOLE1BQU07NEJBQ04sU0FBUyxTQUFDLEtBQUs7dUJBRWYsWUFBWSxTQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChDKSAyMDE4IE1pY2hhZWwgQ3plY2hvd3NraSA8bWFpbEBkYWlseXNoLml0PlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXRcbiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG4gKiBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB2ZXJzaW9uIDIuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3JcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvclxuICogbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGhcbiAqIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MVxuICogRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuXG4gKi9cblxuaW1wb3J0IHsgVmlld0NoaWxkLCBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIE9uQ2hhbmdlcywgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGludGVydmFsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgKiBhcyBTZWxlY3Rpb24gZnJvbSAnZDMtc2VsZWN0aW9uJztcbmltcG9ydCAqIGFzIFNoYXBlIGZyb20gJ2QzLXNoYXBlJztcbmltcG9ydCAqIGFzIFJhbmRvbSBmcm9tICdkMy1yYW5kb20nO1xuaW1wb3J0ICogYXMgRHJhZyBmcm9tICdkMy1kcmFnJztcblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLy4uL21vZGVscy9ncmFwaC5tb2RlbCc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLy4uL21vZGVscy9jb25maWcubW9kZWwnO1xuaW1wb3J0IHsgUG9pbnQgfSBmcm9tICcuLy4uL21vZGVscy9wb2ludC5tb2RlbCc7XG5pbXBvcnQgeyBObHNDYW52YXNTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9jYW52YXMuc2VydmljZSc7XG5pbXBvcnQgeyBObHNIaXN0b3J5U2VydmljZSB9IGZyb20gJy4vLi4vc2VydmljZXMvaGlzdG9yeS5zZXJ2aWNlJztcbmltcG9ydCB7IE5sc01hdGhTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9tYXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmxzR3VpbGxvY2hlRGlyZWN0aXZlIH0gZnJvbSAnLi8uLi9kaXJlY3RpdmVzL2d1aWxsb2NoZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTmxzR3JhcGhTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9ncmFwaC5zZXJ2aWNlJztcblxuY29uc3QgUkVTSVpJTkdfVElNRU9VVCA9IDgwMDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmxzLWdyYXBocycsXG4gIHRlbXBsYXRlOiBgPHN2ZyAjc3ZnIHdpZHRoPVwiMTAwJVwiIGhlaWdodD1cIjEwMCVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcbnZlcnNpb249XCIxLjFcIiBzaGFwZS1yZW5kZXJpbmc9XCJnZW9tZXRyaWNQcmVjaXNpb25cIj5cbiAgPGcgbmxzR3VpbGxvY2hlICpuZ0Zvcj1cImxldCBncmFwaCBvZiBncmFwaHNcIiBbZ3JhcGhdPVwiZ3JhcGhcIiBbYW5pbWF0aW9uXT1cImFuaW1hdGlvblwiPjwvZz5cbjwvc3ZnPlxuYCxcbiAgc3R5bGVzOiBbYDpob3N0e3Bvc2l0aW9uOmFic29sdXRlO3dpZHRoOjEwMCU7aGVpZ2h0OjEwMCU7dG9wOjA7bGVmdDowO292ZXJmbG93OmhpZGRlbn1gXVxufSlcbmV4cG9ydCBjbGFzcyBObHNHcmFwaHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuXG4gIHB1YmxpYyBjYW52YXM6IGFueSB8IG51bGw7XG4gIHB1YmxpYyBtYXRyaXg6IGFueSB8IG51bGw7XG4gIHB1YmxpYyBncmFwaHM6IEdyYXBoW107XG4gIHB1YmxpYyB3aW5kb3dIZWlnaHQ6IG51bWJlciB8IG51bGw7XG4gIHB1YmxpYyB3aW5kb3dXaWR0aDogbnVtYmVyIHwgbnVsbDtcblxuICBwcml2YXRlIGdlblNoaWZ0UG9pbnQ6IGFueSB8IG51bGw7XG4gIHByaXZhdGUgZ2VuTG9hZGVkQWxsR3JhcGhzOiBhbnkgfCBudWxsO1xuICBwcml2YXRlIGhhc2g6IHN0cmluZztcbiAgcHJpdmF0ZSByZXNpemluZ1dpbmRvdzogYW55O1xuXG4gIEBJbnB1dCgpIGNvbmZpZzogQ29uZmlnO1xuICBASW5wdXQoKSByZXN0b3JlZEhpc3Rvcnk6IGFueTtcbiAgQElucHV0KCkgYW5pbWF0aW9uOiBib29sZWFuO1xuICBAT3V0cHV0KCkgc3ZnQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgZ3JhcGhDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBWaWV3Q2hpbGQoJ3N2ZycpIHN2Z0VsZW1lbnRSZWY7XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gIG9uUmVzaXplKGV2ZW50KSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucmVzaXppbmdXaW5kb3cpO1xuXG4gICAgdGhpcy5yZXNpemluZ1dpbmRvdyA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5jYW52YXMgPSB0aGlzLmFkanVzdENhbnZhcygpO1xuICAgICAgdGhpcy5tYXRyaXggPSB0aGlzLmNhbGNNYXRyaXgoKTtcbiAgICAgIHRoaXMudXBkYXRlR3JhcGhzKCk7XG4gICAgfSwgUkVTSVpJTkdfVElNRU9VVCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNhbnZhc1NlcnZpY2U6IE5sc0NhbnZhc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBoaXN0b3J5U2VydmljZTogTmxzSGlzdG9yeVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtYXRoOiBObHNNYXRoU2VydmljZSxcbiAgICBwcml2YXRlIGdyYXBoU2VydmljZTogTmxzR3JhcGhTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMuZ2VuTG9hZGVkQWxsR3JhcGhzID0gdGhpcy5jb3VudExvYWRlZEdyYXBocygpO1xuICAgIHRoaXMucmVzaXppbmdXaW5kb3cgPSBmYWxzZTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICB0aGlzLmNhbnZhcyA9IHRoaXMuYWRqdXN0Q2FudmFzKCk7XG4gICAgdGhpcy5tYXRyaXggPSB0aGlzLmNhbGNNYXRyaXgoKTtcblxuICAgIGlmIChjaGFuZ2VzLmNvbmZpZykge1xuICAgICAgdGhpcy51cGRhdGVHcmFwaHMoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5yZXN0b3JlZEhpc3RvcnkgJiYgdGhpcy5yZXN0b3JlZEhpc3RvcnkuaGFzaCAhPT0gdGhpcy5oYXNoKSB7XG4gICAgICB0aGlzLnJlc3RvcmVHcmFwaCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVzdG9yZUdyYXBoKCkge1xuICAgIHRoaXMuZ3JhcGhzID0gdGhpcy5yZXN0b3JlZEhpc3RvcnkuZ3JhcGhzO1xuICAgIHRoaXMuaGFzaCA9IHRoaXMucmVzdG9yZWRIaXN0b3J5Lmhhc2g7XG4gIH1cblxuICBwcml2YXRlIHNhdmVIaXN0b3J5KCkge1xuICAgIHRoaXMuaGFzaCA9IHRoaXMuaGlzdG9yeVNlcnZpY2UuaGFzaCh0aGlzLmdyYXBocyk7XG4gICAgdGhpcy5oaXN0b3J5U2VydmljZS5zYXZlKHRoaXMuZ3JhcGhzLCB0aGlzLmNvbmZpZyk7XG4gIH1cblxuICBwcml2YXRlIHNhdmVHcmFwaCgpIHtcbiAgICB0aGlzLmdyYXBoU2VydmljZS5zZXQodGhpcy5ncmFwaHMpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVHcmFwaHMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2VuU2hpZnRTdGFydCA9IHRoaXMuc2hpZnRQb2ludCh0aGlzLm1hdHJpeC5zdGFydCwgdGhpcy5jb25maWcudmVjdG9ycy5zdGFydCk7XG4gICAgY29uc3QgZ2VuU2hpZnRFbmQgPSB0aGlzLnNoaWZ0UG9pbnQodGhpcy5tYXRyaXguZW5kLCB0aGlzLmNvbmZpZy52ZWN0b3JzLmVuZCwgZmFsc2UpO1xuXG4gICAgY29uc29sZS5sb2codGhpcy5tYXRyaXgpO1xuXG4gICAgY29uc3QgY3VydmVMaXN0ID0gW1xuICAgICAge1xuICAgICAgICBjb2xvcjogdGhpcy5jb25maWcuY29sb3JzLnByaW1hcnksXG4gICAgICAgIHN0YXJ0OiBnZW5TaGlmdFN0YXJ0Lm5leHQoKS52YWx1ZSxcbiAgICAgICAgZW5kOiBnZW5TaGlmdEVuZC5uZXh0KCkudmFsdWVcbiAgICAgICAgLy8gc3RhcnQ6IHtcbiAgICAgICAgLy8gICBwb2ludDogdGhpcy5tYXRyaXguc3RhcnQsXG4gICAgICAgIC8vICAgdmVjdG9yOiB0aGlzLmNvbmZpZy52ZWN0b3JzLnN0YXJ0XG4gICAgICAgIC8vIH0sXG4gICAgICAgIC8vIGVuZDoge1xuICAgICAgICAvLyAgIHBvaW50OiB0aGlzLm1hdHJpeC5lbmQsXG4gICAgICAgIC8vICAgdmVjdG9yOiB0aGlzLmNvbmZpZy52ZWN0b3JzLmVuZFxuICAgICAgICAvLyB9XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBjb2xvcjogdGhpcy5jb25maWcuY29sb3JzLnNlY29uZGFyeSxcbiAgICAgICAgc3RhcnQ6IGdlblNoaWZ0RW5kLm5leHQoKS52YWx1ZSxcbiAgICAgICAgZW5kOiBnZW5TaGlmdFN0YXJ0Lm5leHQoKS52YWx1ZVxuICAgICAgICAvLyBlbmQ6IHtcbiAgICAgICAgLy8gICBwb2ludDogdGhpcy5tYXRyaXguc3RhcnQsXG4gICAgICAgIC8vICAgdmVjdG9yOiB0aGlzLmNvbmZpZy52ZWN0b3JzLnN0YXJ0XG4gICAgICAgIC8vIH0sXG4gICAgICAgIC8vIHN0YXJ0OiB7XG4gICAgICAgIC8vICAgcG9pbnQ6IHRoaXMubWF0cml4LmVuZCxcbiAgICAgICAgLy8gICB2ZWN0b3I6IHRoaXMuY29uZmlnLnZlY3RvcnMuZW5kXG4gICAgICAgIC8vIH1cbiAgICAgIH1cbiAgICBdO1xuXG4gICAgdGhpcy5ncmFwaHMgPSBjdXJ2ZUxpc3QubWFwKGN1cnZlID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnRoaXMuYWRqdXN0R3JhcGgoY3VydmUpLFxuICAgICAgICBzcHJlYWQ6IHRoaXMuY29uZmlnLnNwcmVhZCxcbiAgICAgICAgaW50ZXJ2YWw6IHRoaXMuY29uZmlnLmludGVydmFsXG4gICAgICB9O1xuICAgIH0pO1xuICAgIHRoaXMuaGFzaCA9IHRoaXMuaGlzdG9yeVNlcnZpY2UuaGFzaCh0aGlzLmdyYXBocyk7XG4gICAgdGhpcy5zYXZlSGlzdG9yeSgpO1xuICAgIHRoaXMuc2F2ZUdyYXBoKCk7XG4gIH1cblxuICBwcml2YXRlIGFkanVzdEdyYXBoKGN1cnZlKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oY3VydmUsIHtcbiAgICAgIHN0cm9rZTogdGhpcy5jb25maWcuc3Ryb2tlLFxuICAgICAgc3RhcnQ6IE9iamVjdC5hc3NpZ24oY3VydmUuc3RhcnQsIHtcbiAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmdlblZlY3RvclBvaW50KGN1cnZlLnN0YXJ0LnBvaW50LCBjdXJ2ZS5zdGFydC52ZWN0b3IpXG4gICAgICB9KSxcbiAgICAgIGVuZDogT2JqZWN0LmFzc2lnbihjdXJ2ZS5lbmQsIHtcbiAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmdlblZlY3RvclBvaW50KGN1cnZlLmVuZC5wb2ludCwgY3VydmUuZW5kLnZlY3RvcilcbiAgICAgIH0pLFxuICAgICAgbm9kZXM6IHRoaXMuZ2VuUmFuZG9tUG9pbnRzKHRoaXMuY29uZmlnLm5vZGVzKVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZW5SYW5kb21Qb2ludHMobnVtOiBudW1iZXIpIHtcbiAgICBjb25zdCBnZW5lcmF0ZWRQb2ludHMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb25maWcubm9kZXM7IGkrKykge1xuICAgICAgZ2VuZXJhdGVkUG9pbnRzLnB1c2godGhpcy5tYXRoLnJhbmRvbVBvaW50KHRoaXMubWF0cml4LCB0aGlzLmNvbmZpZy5vdmVybGFwKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdlbmVyYXRlZFBvaW50cztcbiAgfVxuXG4gIHByaXZhdGUgZmxpcGZsb3AoeDogc3RyaW5nKSB7XG4gICAgcmV0dXJuICh4ID09PSAnc3RhcnQnKSA/ICdlbmQnIDogJ3N0YXJ0JztcbiAgfVxuXG4gIHByaXZhdGUgYWRqdXN0Q2FudmFzKCk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzU2VydmljZS5zZXQodGhpcy5jYW52YXMpO1xuICAgIHRoaXMuY2FudmFzU2VydmljZS5hZGp1c3RUb1dpbmRvdygpO1xuXG4gICAgcmV0dXJuIHRoaXMuc3ZnRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjTWF0cml4KCkge1xuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gdGhpcy5jYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gdGhpcy5jYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xuICAgIGNvbnN0IHRvdGFsQXJlYSA9IE1hdGguYWJzKGNhbnZhc1dpZHRoICogY2FudmFzSGVpZ2h0KTtcbiAgICBjb25zdCB0b3RhbENlbnRlciA9IHRoaXMubWF0aC5jZW50ZXJPZkFyZWEoY2FudmFzV2lkdGgsIGNhbnZhc0hlaWdodCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnQ6IHtcbiAgICAgICAgeDogMCxcbiAgICAgICAgeTogY2FudmFzSGVpZ2h0IC0gdGhpcy5jb25maWcudmVjdG9ycy5zcGFjaW5nIC0gdGhpcy5jb25maWcubWFyZ2luLnlcbiAgICAgIH0sXG4gICAgICBlbmQ6IHtcbiAgICAgICAgeDogY2FudmFzV2lkdGggLSB0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcgLSB0aGlzLmNvbmZpZy5tYXJnaW4ueCxcbiAgICAgICAgeTogMFxuICAgICAgfSxcbiAgICAgIHdpZHRoOiBjYW52YXNXaWR0aCxcbiAgICAgIGhlaWdodDogY2FudmFzSGVpZ2h0LFxuICAgICAgY2VudGVyOiB0b3RhbENlbnRlclxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdlblZlY3RvclBvaW50KHBvaW50OiBQb2ludCwgdmVjdG9yOiBudW1iZXIpIHtcbiAgICBjb25zdCByYW5nZSA9IHRoaXMubWF0aC7OlCh0aGlzLm1hdHJpeC5zdGFydCwgdGhpcy5tYXRyaXguZW5kKSAqIHRoaXMuY29uZmlnLnZlY3RvcnMucmFuZ2U7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogcmFuZ2UgKiBNYXRoLnNpbihNYXRoLlBJICogdmVjdG9yKSArIHBvaW50LngsXG4gICAgICB5OiByYW5nZSAqIE1hdGguY29zKE1hdGguUEkgKiB2ZWN0b3IpICsgcG9pbnQueVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlICpzaGlmdFBvaW50KHBvaW50OiBQb2ludCwgdmVjdG9yOiBudW1iZXIsIHN0YXJ0UG9zaXRpdmU6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgY29uc3QgZ2VuU2hpZnRYID0gdGhpcy5zaGlmdE51bWJlcih0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcsIHZlY3Rvciwgc3RhcnRQb3NpdGl2ZSk7XG4gICAgY29uc3QgZ2VuU2hpZnRZID0gdGhpcy5zaGlmdE51bWJlcih0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcsIHZlY3Rvciwgc3RhcnRQb3NpdGl2ZSk7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgeWllbGQge1xuICAgICAgICBwb2ludDoge1xuICAgICAgICAgIHg6IE1hdGguY29zKE1hdGguUEkgKiB2ZWN0b3IpICogZ2VuU2hpZnRYLm5leHQoKS52YWx1ZSArIHBvaW50LngsXG4gICAgICAgICAgeTogTWF0aC5zaW4oTWF0aC5QSSAqIHZlY3RvcikgKiBnZW5TaGlmdFkubmV4dCgpLnZhbHVlICsgcG9pbnQueSxcbiAgICAgICAgfSxcbiAgICAgICAgdmVjdG9yOiB2ZWN0b3JcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSAqc2hpZnROdW1iZXIoc3BhY2U6IG51bWJlciwgdmVjdG9yOiBudW1iZXIsIHN0YXJ0UG9zaXRpdmU6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgbGV0IGN1cnJlbnQgPSAwO1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgY29uc3Qgc2lnbiA9IHRoaXMubWF0aC5mbGlwU2lnbihzdGFydFBvc2l0aXZlKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICB5aWVsZCBjdXJyZW50ID0gc2lnbi5uZXh0KCkudmFsdWUgKiBpbmRleCAqIHNwYWNlICsgY3VycmVudDtcbiAgICAgIGluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHByZXBhcmVHdWlsbG9jaGVFeHBvcnQoZ3VpbGxvY2hlRWxlbWVudCkge1xuICAgIGlmICh0aGlzLmdlbkxvYWRlZEFsbEdyYXBocy5uZXh0KCkudmFsdWUpIHtcbiAgICAgIHRoaXMuc3ZnQ2hhbmdlLmVtaXQodGhpcy5zdmdFbGVtZW50UmVmKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlICpjb3VudExvYWRlZEdyYXBocygpIHtcbiAgICBsZXQgY3ljbGVzID0gMTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAoY3ljbGVzIDwgdGhpcy5ncmFwaHMubGVuZ3RoKSB7XG4gICAgICAgIHlpZWxkIGZhbHNlO1xuICAgICAgICBjeWNsZXMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHlpZWxkIHRydWU7XG4gICAgICAgIGN5Y2xlcyA9IDE7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=