335 lines
30 KiB
JavaScript
335 lines
30 KiB
JavaScript
/**
|
|
* @fileoverview added by tsickle
|
|
* @suppress {checkTypes} checked by tsc
|
|
*/
|
|
/**
|
|
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
|
* 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: `<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'],] }]
|
|
};
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JhcGhzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25scy1ndWlsbG9jaGUvIiwic291cmNlcyI6WyJubHMvY29tcG9uZW50cy9ncmFwaHMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQkEsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBNEIsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQVUxSCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFNUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDOztBQUU5RCxNQUFNLGdCQUFnQixHQUFHLEdBQUcsQ0FBQztBQVc3QixNQUFNOzs7Ozs7O0lBK0JKLFlBQ1UsZUFDQSxnQkFDQSxNQUNBO1FBSEEsa0JBQWEsR0FBYixhQUFhO1FBQ2IsbUJBQWMsR0FBZCxjQUFjO1FBQ2QsU0FBSSxHQUFKLElBQUk7UUFDSixpQkFBWSxHQUFaLFlBQVk7eUJBbkJBLElBQUksWUFBWSxFQUFFOzJCQUNoQixJQUFJLFlBQVksRUFBRTtRQW9CeEMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO0tBQzdCOzs7OztJQWxCRCxRQUFRLENBQUMsS0FBSztRQUNaLFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ3BDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFD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Ozs7WUF2T0osU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxZQUFZO2dCQUN0QixRQUFRLEVBQUU7Ozs7Q0FJWDtnQkFDQyxNQUFNLEVBQUUsQ0FBQyw4RUFBOEUsQ0FBQzthQUN6Rjs7OztZQWhCUSxnQkFBZ0I7WUFDaEIsaUJBQWlCO1lBQ2pCLGNBQWM7WUFFZCxlQUFlOzs7cUJBMEJyQixLQUFLOzhCQUNMLEtBQUs7d0JBQ0wsS0FBSzt3QkFDTCxNQUFNOzBCQUNOLE1BQU07NEJBQ04sU0FBUyxTQUFDLEtBQUs7dUJBRWYsWUFBWSxTQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChDKSAyMDE4IE1pY2hhZWwgQ3plY2hvd3NraSA8bWFpbEBkYWlseXNoLml0PlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXRcbiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG4gKiBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB2ZXJzaW9uIDIuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3JcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvclxuICogbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGhcbiAqIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MVxuICogRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuXG4gKi9cblxuaW1wb3J0IHsgVmlld0NoaWxkLCBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIE9uQ2hhbmdlcywgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGludGVydmFsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgKiBhcyBTZWxlY3Rpb24gZnJvbSAnZDMtc2VsZWN0aW9uJztcbmltcG9ydCAqIGFzIFNoYXBlIGZyb20gJ2QzLXNoYXBlJztcbmltcG9ydCAqIGFzIFJhbmRvbSBmcm9tICdkMy1yYW5kb20nO1xuaW1wb3J0ICogYXMgRHJhZyBmcm9tICdkMy1kcmFnJztcblxuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLy4uL21vZGVscy9ncmFwaC5tb2RlbCc7XG5pbXBvcnQgeyBDb25maWcgfSBmcm9tICcuLy4uL21vZGVscy9jb25maWcubW9kZWwnO1xuaW1wb3J0IHsgUG9pbnQgfSBmcm9tICcuLy4uL21vZGVscy9wb2ludC5tb2RlbCc7XG5pbXBvcnQgeyBObHNDYW52YXNTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9jYW52YXMuc2VydmljZSc7XG5pbXBvcnQgeyBObHNIaXN0b3J5U2VydmljZSB9IGZyb20gJy4vLi4vc2VydmljZXMvaGlzdG9yeS5zZXJ2aWNlJztcbmltcG9ydCB7IE5sc01hdGhTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9tYXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmxzR3VpbGxvY2hlRGlyZWN0aXZlIH0gZnJvbSAnLi8uLi9kaXJlY3RpdmVzL2d1aWxsb2NoZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTmxzR3JhcGhTZXJ2aWNlIH0gZnJvbSAnLi8uLi9zZXJ2aWNlcy9ncmFwaC5zZXJ2aWNlJztcblxuY29uc3QgUkVTSVpJTkdfVElNRU9VVCA9IDgwMDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmxzLWdyYXBocycsXG4gIHRlbXBsYXRlOiBgPHN2ZyAjc3ZnIHdpZHRoPVwiMTAwJVwiIGhlaWdodD1cIjEwMCVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcbnZlcnNpb249XCIxLjFcIiBzaGFwZS1yZW5kZXJpbmc9XCJnZW9tZXRyaWNQcmVjaXNpb25cIj5cbiAgPGcgbmxzR3VpbGxvY2hlICpuZ0Zvcj1cImxldCBncmFwaCBvZiBncmFwaHNcIiBbZ3JhcGhdPVwiZ3JhcGhcIiBbYW5pbWF0aW9uXT1cImFuaW1hdGlvblwiPjwvZz5cbjwvc3ZnPlxuYCxcbiAgc3R5bGVzOiBbYDpob3N0e3Bvc2l0aW9uOmFic29sdXRlO3dpZHRoOjEwMCU7aGVpZ2h0OjEwMCU7dG9wOjA7bGVmdDowO292ZXJmbG93OmhpZGRlbn1gXVxufSlcbmV4cG9ydCBjbGFzcyBObHNHcmFwaHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuXG4gIHB1YmxpYyBjYW52YXM6IGFueSB8IG51bGw7XG4gIHB1YmxpYyBtYXRyaXg6IGFueSB8IG51bGw7XG4gIHB1YmxpYyBncmFwaHM6IEdyYXBoW107XG4gIHB1YmxpYyB3aW5kb3dIZWlnaHQ6IG51bWJlciB8IG51bGw7XG4gIHB1YmxpYyB3aW5kb3dXaWR0aDogbnVtYmVyIHwgbnVsbDtcblxuICBwcml2YXRlIGdlblNoaWZ0UG9pbnQ6IGFueSB8IG51bGw7XG4gIHByaXZhdGUgZ2VuTG9hZGVkQWxsR3JhcGhzOiBhbnkgfCBudWxsO1xuICBwcml2YXRlIGhhc2g6IHN0cmluZztcbiAgcHJpdmF0ZSByZXNpemluZ1dpbmRvdzogYW55O1xuXG4gIEBJbnB1dCgpIGNvbmZpZzogQ29uZmlnO1xuICBASW5wdXQoKSByZXN0b3JlZEhpc3Rvcnk6IGFueTtcbiAgQElucHV0KCkgYW5pbWF0aW9uOiBib29sZWFuO1xuICBAT3V0cHV0KCkgc3ZnQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgZ3JhcGhDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBWaWV3Q2hpbGQoJ3N2ZycpIHN2Z0VsZW1lbnRSZWY7XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXG4gIG9uUmVzaXplKGV2ZW50KSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucmVzaXppbmdXaW5kb3cpO1xuXG4gICAgdGhpcy5yZXNpemluZ1dpbmRvdyA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5jYW52YXMgPSB0aGlzLmFkanVzdENhbnZhcygpO1xuICAgICAgdGhpcy5tYXRyaXggPSB0aGlzLmNhbGNNYXRyaXgoKTtcbiAgICAgIHRoaXMudXBkYXRlR3JhcGhzKCk7XG4gICAgfSwgUkVTSVpJTkdfVElNRU9VVCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNhbnZhc1NlcnZpY2U6IE5sc0NhbnZhc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBoaXN0b3J5U2VydmljZTogTmxzSGlzdG9yeVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtYXRoOiBObHNNYXRoU2VydmljZSxcbiAgICBwcml2YXRlIGdyYXBoU2VydmljZTogTmxzR3JhcGhTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMuZ2VuTG9hZGVkQWxsR3JhcGhzID0gdGhpcy5jb3VudExvYWRlZEdyYXBocygpO1xuICAgIHRoaXMucmVzaXppbmdXaW5kb3cgPSBmYWxzZTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICB0aGlzLmNhbnZhcyA9IHRoaXMuYWRqdXN0Q2FudmFzKCk7XG4gICAgdGhpcy5tYXRyaXggPSB0aGlzLmNhbGNNYXRyaXgoKTtcblxuICAgIGlmIChjaGFuZ2VzLmNvbmZpZykge1xuICAgICAgdGhpcy51cGRhdGVHcmFwaHMoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5yZXN0b3JlZEhpc3RvcnkgJiYgdGhpcy5yZXN0b3JlZEhpc3RvcnkuaGFzaCAhPT0gdGhpcy5oYXNoKSB7XG4gICAgICB0aGlzLnJlc3RvcmVHcmFwaCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVzdG9yZUdyYXBoKCkge1xuICAgIHRoaXMuZ3JhcGhzID0gdGhpcy5yZXN0b3JlZEhpc3RvcnkuZ3JhcGhzO1xuICAgIHRoaXMuaGFzaCA9IHRoaXMucmVzdG9yZWRIaXN0b3J5Lmhhc2g7XG4gIH1cblxuICBwcml2YXRlIHNhdmVIaXN0b3J5KCkge1xuICAgIHRoaXMuaGFzaCA9IHRoaXMuaGlzdG9yeVNlcnZpY2UuaGFzaCh0aGlzLmdyYXBocyk7XG4gICAgdGhpcy5oaXN0b3J5U2VydmljZS5zYXZlKHRoaXMuZ3JhcGhzLCB0aGlzLmNvbmZpZyk7XG4gIH1cblxuICBwcml2YXRlIHNhdmVHcmFwaCgpIHtcbiAgICB0aGlzLmdyYXBoU2VydmljZS5zZXQodGhpcy5ncmFwaHMpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVHcmFwaHMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2VuU2hpZnRTdGFydCA9IHRoaXMuc2hpZnRQb2ludCh0aGlzLm1hdHJpeC5zdGFydCwgdGhpcy5jb25maWcudmVjdG9ycy5zdGFydCk7XG4gICAgY29uc3QgZ2VuU2hpZnRFbmQgPSB0aGlzLnNoaWZ0UG9pbnQodGhpcy5tYXRyaXguZW5kLCB0aGlzLmNvbmZpZy52ZWN0b3JzLmVuZCwgZmFsc2UpO1xuXG4gICAgY29uc29sZS5sb2codGhpcy5tYXRyaXgpO1xuXG4gICAgY29uc3QgY3VydmVMaXN0ID0gW1xuICAgICAge1xuICAgICAgICBjb2xvcjogdGhpcy5jb25maWcuY29sb3JzLnByaW1hcnksXG4gICAgICAgIHN0YXJ0OiBnZW5TaGlmdFN0YXJ0Lm5leHQoKS52YWx1ZSxcbiAgICAgICAgZW5kOiBnZW5TaGlmdEVuZC5uZXh0KCkudmFsdWVcbiAgICAgICAgLy8gc3RhcnQ6IHtcbiAgICAgICAgLy8gICBwb2ludDogdGhpcy5tYXRyaXguc3RhcnQsXG4gICAgICAgIC8vICAgdmVjdG9yOiB0aGlzLmNvbmZpZy52ZWN0b3JzLnN0YXJ0XG4gICAgICAgIC8vIH0sXG4gICAgICAgIC8vIGVuZDoge1xuICAgICAgICAvLyAgIHBvaW50OiB0aGlzLm1hdHJpeC5lbmQsXG4gICAgICAgIC8vICAgdmVjdG9yOiB0aGlzLmNvbmZpZy52ZWN0b3JzLmVuZFxuICAgICAgICAvLyB9XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBjb2xvcjogdGhpcy5jb25maWcuY29sb3JzLnNlY29uZGFyeSxcbiAgICAgICAgc3RhcnQ6IGdlblNoaWZ0RW5kLm5leHQoKS52YWx1ZSxcbiAgICAgICAgZW5kOiBnZW5TaGlmdFN0YXJ0Lm5leHQoKS52YWx1ZVxuICAgICAgICAvLyBlbmQ6IHtcbiAgICAgICAgLy8gICBwb2ludDogdGhpcy5tYXRyaXguc3RhcnQsXG4gICAgICAgIC8vICAgdmVjdG9yOiB0aGlzLmNvbmZpZy52ZWN0b3JzLnN0YXJ0XG4gICAgICAgIC8vIH0sXG4gICAgICAgIC8vIHN0YXJ0OiB7XG4gICAgICAgIC8vICAgcG9pbnQ6IHRoaXMubWF0cml4LmVuZCxcbiAgICAgICAgLy8gICB2ZWN0b3I6IHRoaXMuY29uZmlnLnZlY3RvcnMuZW5kXG4gICAgICAgIC8vIH1cbiAgICAgIH1cbiAgICBdO1xuXG4gICAgdGhpcy5ncmFwaHMgPSBjdXJ2ZUxpc3QubWFwKGN1cnZlID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnRoaXMuYWRqdXN0R3JhcGgoY3VydmUpLFxuICAgICAgICBzcHJlYWQ6IHRoaXMuY29uZmlnLnNwcmVhZCxcbiAgICAgICAgaW50ZXJ2YWw6IHRoaXMuY29uZmlnLmludGVydmFsXG4gICAgICB9O1xuICAgIH0pO1xuICAgIHRoaXMuaGFzaCA9IHRoaXMuaGlzdG9yeVNlcnZpY2UuaGFzaCh0aGlzLmdyYXBocyk7XG4gICAgdGhpcy5zYXZlSGlzdG9yeSgpO1xuICAgIHRoaXMuc2F2ZUdyYXBoKCk7XG4gIH1cblxuICBwcml2YXRlIGFkanVzdEdyYXBoKGN1cnZlKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oY3VydmUsIHtcbiAgICAgIHN0cm9rZTogdGhpcy5jb25maWcuc3Ryb2tlLFxuICAgICAgc3RhcnQ6IE9iamVjdC5hc3NpZ24oY3VydmUuc3RhcnQsIHtcbiAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmdlblZlY3RvclBvaW50KGN1cnZlLnN0YXJ0LnBvaW50LCBjdXJ2ZS5zdGFydC52ZWN0b3IpXG4gICAgICB9KSxcbiAgICAgIGVuZDogT2JqZWN0LmFzc2lnbihjdXJ2ZS5lbmQsIHtcbiAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmdlblZlY3RvclBvaW50KGN1cnZlLmVuZC5wb2ludCwgY3VydmUuZW5kLnZlY3RvcilcbiAgICAgIH0pLFxuICAgICAgbm9kZXM6IHRoaXMuZ2VuUmFuZG9tUG9pbnRzKHRoaXMuY29uZmlnLm5vZGVzKVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZW5SYW5kb21Qb2ludHMobnVtOiBudW1iZXIpIHtcbiAgICBjb25zdCBnZW5lcmF0ZWRQb2ludHMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb25maWcubm9kZXM7IGkrKykge1xuICAgICAgZ2VuZXJhdGVkUG9pbnRzLnB1c2godGhpcy5tYXRoLnJhbmRvbVBvaW50KHRoaXMubWF0cml4LCB0aGlzLmNvbmZpZy5vdmVybGFwKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdlbmVyYXRlZFBvaW50cztcbiAgfVxuXG4gIHByaXZhdGUgZmxpcGZsb3AoeDogc3RyaW5nKSB7XG4gICAgcmV0dXJuICh4ID09PSAnc3RhcnQnKSA/ICdlbmQnIDogJ3N0YXJ0JztcbiAgfVxuXG4gIHByaXZhdGUgYWRqdXN0Q2FudmFzKCk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzU2VydmljZS5zZXQodGhpcy5jYW52YXMpO1xuICAgIHRoaXMuY2FudmFzU2VydmljZS5hZGp1c3RUb1dpbmRvdygpO1xuXG4gICAgcmV0dXJuIHRoaXMuc3ZnRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjTWF0cml4KCkge1xuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gdGhpcy5jYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGg7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gdGhpcy5jYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xuICAgIGNvbnN0IHRvdGFsQXJlYSA9IE1hdGguYWJzKGNhbnZhc1dpZHRoICogY2FudmFzSGVpZ2h0KTtcbiAgICBjb25zdCB0b3RhbENlbnRlciA9IHRoaXMubWF0aC5jZW50ZXJPZkFyZWEoY2FudmFzV2lkdGgsIGNhbnZhc0hlaWdodCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhcnQ6IHtcbiAgICAgICAgeDogMCxcbiAgICAgICAgeTogY2FudmFzSGVpZ2h0IC0gdGhpcy5jb25maWcudmVjdG9ycy5zcGFjaW5nIC0gdGhpcy5jb25maWcubWFyZ2luLnlcbiAgICAgIH0sXG4gICAgICBlbmQ6IHtcbiAgICAgICAgeDogY2FudmFzV2lkdGggLSB0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcgLSB0aGlzLmNvbmZpZy5tYXJnaW4ueCxcbiAgICAgICAgeTogMFxuICAgICAgfSxcbiAgICAgIHdpZHRoOiBjYW52YXNXaWR0aCxcbiAgICAgIGhlaWdodDogY2FudmFzSGVpZ2h0LFxuICAgICAgY2VudGVyOiB0b3RhbENlbnRlclxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdlblZlY3RvclBvaW50KHBvaW50OiBQb2ludCwgdmVjdG9yOiBudW1iZXIpIHtcbiAgICBjb25zdCByYW5nZSA9IHRoaXMubWF0aC7OlCh0aGlzLm1hdHJpeC5zdGFydCwgdGhpcy5tYXRyaXguZW5kKSAqIHRoaXMuY29uZmlnLnZlY3RvcnMucmFuZ2U7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogcmFuZ2UgKiBNYXRoLnNpbihNYXRoLlBJICogdmVjdG9yKSArIHBvaW50LngsXG4gICAgICB5OiByYW5nZSAqIE1hdGguY29zKE1hdGguUEkgKiB2ZWN0b3IpICsgcG9pbnQueVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlICpzaGlmdFBvaW50KHBvaW50OiBQb2ludCwgdmVjdG9yOiBudW1iZXIsIHN0YXJ0UG9zaXRpdmU6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgY29uc3QgZ2VuU2hpZnRYID0gdGhpcy5zaGlmdE51bWJlcih0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcsIHZlY3Rvciwgc3RhcnRQb3NpdGl2ZSk7XG4gICAgY29uc3QgZ2VuU2hpZnRZID0gdGhpcy5zaGlmdE51bWJlcih0aGlzLmNvbmZpZy52ZWN0b3JzLnNwYWNpbmcsIHZlY3Rvciwgc3RhcnRQb3NpdGl2ZSk7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgeWllbGQge1xuICAgICAgICBwb2ludDoge1xuICAgICAgICAgIHg6IE1hdGguY29zKE1hdGguUEkgKiB2ZWN0b3IpICogZ2VuU2hpZnRYLm5leHQoKS52YWx1ZSArIHBvaW50LngsXG4gICAgICAgICAgeTogTWF0aC5zaW4oTWF0aC5QSSAqIHZlY3RvcikgKiBnZW5TaGlmdFkubmV4dCgpLnZhbHVlICsgcG9pbnQueSxcbiAgICAgICAgfSxcbiAgICAgICAgdmVjdG9yOiB2ZWN0b3JcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSAqc2hpZnROdW1iZXIoc3BhY2U6IG51bWJlciwgdmVjdG9yOiBudW1iZXIsIHN0YXJ0UG9zaXRpdmU6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgbGV0IGN1cnJlbnQgPSAwO1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgY29uc3Qgc2lnbiA9IHRoaXMubWF0aC5mbGlwU2lnbihzdGFydFBvc2l0aXZlKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICB5aWVsZCBjdXJyZW50ID0gc2lnbi5uZXh0KCkudmFsdWUgKiBpbmRleCAqIHNwYWNlICsgY3VycmVudDtcbiAgICAgIGluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHByZXBhcmVHdWlsbG9jaGVFeHBvcnQoZ3VpbGxvY2hlRWxlbWVudCkge1xuICAgIGlmICh0aGlzLmdlbkxvYWRlZEFsbEdyYXBocy5uZXh0KCkudmFsdWUpIHtcbiAgICAgIHRoaXMuc3ZnQ2hhbmdlLmVtaXQodGhpcy5zdmdFbGVtZW50UmVmKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlICpjb3VudExvYWRlZEdyYXBocygpIHtcbiAgICBsZXQgY3ljbGVzID0gMTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAoY3ljbGVzIDwgdGhpcy5ncmFwaHMubGVuZ3RoKSB7XG4gICAgICAgIHlpZWxkIGZhbHNlO1xuICAgICAgICBjeWNsZXMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHlpZWxkIHRydWU7XG4gICAgICAgIGN5Y2xlcyA9IDE7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
|