ngx-diagrams
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.
143 lines • 16.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/defaults/components/default-link/default-link.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, ChangeDetectorRef, ViewChild, ViewContainerRef } from '@angular/core';
import { DefaultLinkModel } from '../../models/default-link.model';
import { generateCurvePath } from '../../../utils/tool-kit.util';
import { combineLatest, BehaviorSubject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
export class DefaultLinkComponent extends DefaultLinkModel {
/**
* @param {?} cdRef
*/
constructor(cdRef) {
super('ngdx-default-link');
this.cdRef = cdRef;
this._path$ = new BehaviorSubject(null);
this.path$ = this._path$.asObservable();
this.points$ = new BehaviorSubject([]);
}
/**
* @return {?}
*/
ngAfterViewInit() {
/** @type {?} */
const firstPCoords$ = this.getFirstPoint().selectCoords();
/** @type {?} */
const lastPCoords$ = this.getLastPoint().selectCoords();
// Observe link coords and update drawing accordingly
combineLatest([firstPCoords$, lastPCoords$])
.pipe(takeUntil(this.onEntityDestroy()))
.subscribe((/**
* @param {?} __0
* @return {?}
*/
([firstPCoords, lastPCoords]) => {
/** @type {?} */
const points = [firstPCoords, lastPCoords];
/** @type {?} */
const isHorizontal = Math.abs(firstPCoords.x - lastPCoords.x) > Math.abs(firstPCoords.y - lastPCoords.y);
/** @type {?} */
const xOrY = isHorizontal ? 'x' : 'y';
// draw the smoothing
// if the points are too close, just draw a straight line
/** @type {?} */
let isStraight = false;
if (Math.abs(points[0][xOrY] - points[1][xOrY]) < 50) {
isStraight = true;
}
/** @type {?} */
const path = generateCurvePath(firstPCoords, lastPCoords, isStraight ? 0 : this.curvyness);
this._path$.next(path);
if (!this.getTargetPort()) {
/** @type {?} */
const danglingPoint = this.generatePoint(lastPCoords);
this.points$.next([danglingPoint]);
}
/** @type {?} */
const label = this.getLabel();
// update label position
if (label) {
label.setCoords(this.calcCenterOfPath(firstPCoords, lastPCoords));
// TODO: check whether we want the label to rotate along with the line
// label.setRotation(this.calcLabelIncline(firstPCoords, lastPCoords));
}
// TODO: handle the multiple lines in between the points
// https://github.com/projectstorm/react-diagrams/blob/master/src/defaults/widgets/DefaultLinkWidget.tsx#L344-L371
this.cdRef.detectChanges();
}));
// observe link label and draw/remove accordingly
this.selectLabel()
.pipe(filter(Boolean))
.subscribe((/**
* @param {?} label
* @return {?}
*/
(label) => {
this.diagramEngine.generateWidgetForLabel(label, this.labelLayer);
this.cdRef.detectChanges();
}));
}
/**
* @param {?} firstPoint
* @param {?} secondPoint
* @return {?}
*/
calcLabelIncline(firstPoint, secondPoint) {
/** @type {?} */
const dy = secondPoint.y - firstPoint.y;
/** @type {?} */
const dx = secondPoint.x - firstPoint.x;
if (dx === 0) {
return 0;
}
/** @type {?} */
let inclineAngel = (Math.atan(dy / dx) * 180) / Math.PI;
if (inclineAngel < 0) {
inclineAngel += 180;
}
return inclineAngel;
}
/**
* @param {?} firstPoint
* @param {?} secondPoint
* @return {?}
*/
calcCenterOfPath(firstPoint, secondPoint) {
return { x: (firstPoint.x + secondPoint.x) / 2 + 20, y: (firstPoint.y + secondPoint.y) / 2 + 20 };
}
}
DefaultLinkComponent.decorators = [
{ type: Component, args: [{
selector: 'ngdx-default-link',
template: "<!-- Label Host -->\n<ng-template #labelLayer></ng-template>\n\n<!-- Link -->\n<svg class=\"default-link\">\n\t<g>\n\t\t<path [attr.stroke-width]=\"width\" [attr.stroke]=\"color\" [attr.d]=\"path$ | async\"></path>\n\t\t<path\n\t\t\t(mouseleave)=\"setSelected(false)\"\n\t\t\t(mouseenter)=\"setSelected()\"\n\t\t\t[attr.stroke-width]=\"20\"\n\t\t\t[attr.stroke]=\"color\"\n\t\t\t[attr.stroke-linecap]=\"'round'\"\n\t\t\t[attr.data-linkid]=\"id\"\n\t\t\t[attr.stroke-opacity]=\"(selectSelected() | async) ? '0.1' : '0'\"\n\t\t\t[attr.d]=\"path$ | async\"\n\t\t></path>\n\t</g>\n\t<g *ngFor=\"let point of points$ | async\">\n\t\t<circle [attr.cx]=\"point.selectX() | async\" [attr.cy]=\"point.selectY() | async\" r=\"5\" class=\"default-point\" />\n\n\t\t<circle\n\t\t\t(mouseleave)=\"setSelected(false)\"\n\t\t\t(mouseenter)=\"setSelected()\"\n\t\t\t[attr.data-id]=\"point.id\"\n\t\t\t[attr.data-linkid]=\"id\"\n\t\t\t[attr.cx]=\"point.selectX() | async\"\n\t\t\t[attr.cy]=\"point.selectY() | async\"\n\t\t\tr=\"15\"\n\t\t\t[attr.opacity]=\"0\"\n\t\t\tclass=\"default-point\"\n\t\t\t[ngClass]=\"{ 'default-point': true, selected: point.selectSelected() | async }\"\n\t\t/>\n\t\t{{ point.selectSelected() | async }}\n\t</g>\n</svg>\n",
styles: [".default-link{fill:none;overflow:visible}.default-link .default-point{fill:rgba(255,255,255,.5)}.default-link .default-point.selected{fill:rgba(0,0,255,.5)}@-webkit-keyframes dash{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}@keyframes dash{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}.default-link path{fill:none;pointer-events:all}.default-link.path-selected{stroke:#00c0ff!important;stroke-dasharray:10,2;-webkit-animation:1s linear infinite dash;animation:1s linear infinite dash}"]
}] }
];
/** @nocollapse */
DefaultLinkComponent.ctorParameters = () => [
{ type: ChangeDetectorRef }
];
DefaultLinkComponent.propDecorators = {
labelLayer: [{ type: ViewChild, args: ['labelLayer', { read: ViewContainerRef, static: true },] }]
};
if (false) {
/** @type {?} */
DefaultLinkComponent.prototype.labelLayer;
/** @type {?} */
DefaultLinkComponent.prototype._path$;
/** @type {?} */
DefaultLinkComponent.prototype.path$;
/** @type {?} */
DefaultLinkComponent.prototype.points$;
/** @type {?} */
DefaultLinkComponent.prototype.label$;
/**
* @type {?}
* @private
*/
DefaultLinkComponent.prototype.cdRef;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC1saW5rLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1kaWFncmFtcy8iLCJzb3VyY2VzIjpbImxpYi9kZWZhdWx0cy9jb21wb25lbnRzL2RlZmF1bHQtbGluay9kZWZhdWx0LWxpbmsuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBaUIsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBR2xFLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFRbkQsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGdCQUFnQjs7OztJQVF6RCxZQUFvQixLQUF3QjtRQUMzQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQURSLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBTDVDLFdBQU0sR0FBNEIsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUQsVUFBSyxHQUF1QixJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3ZELFlBQU8sR0FBa0MsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7SUFLakUsQ0FBQzs7OztJQUVELGVBQWU7O2NBQ1IsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxZQUFZLEVBQUU7O2NBQ25ELFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsWUFBWSxFQUFFO1FBRXZELHFEQUFxRDtRQUNyRCxhQUFhLENBQUMsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUM7YUFDMUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQzthQUN2QyxTQUFTOzs7O1FBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsRUFBRSxFQUFFOztrQkFDcEMsTUFBTSxHQUFHLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQzs7a0JBRXBDLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDOztrQkFDbEcsSUFBSSxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHOzs7O2dCQUlqQyxVQUFVLEdBQUcsS0FBSztZQUN0QixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDckQsVUFBVSxHQUFHLElBQUksQ0FBQzthQUNsQjs7a0JBRUssSUFBSSxHQUFHLGlCQUFpQixDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDMUYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRTs7c0JBQ3BCLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQztnQkFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO2FBQ25DOztrQkFFSyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUM3Qix3QkFBd0I7WUFDeEIsSUFBSSxLQUFLLEVBQUU7Z0JBQ1YsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBRWxFLHNFQUFzRTtnQkFDdEUsdUVBQXVFO2FBQ3ZFO1lBRUQsd0RBQXdEO1lBQ3hELGtIQUFrSDtZQUVsSCxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzVCLENBQUMsRUFBQyxDQUFDO1FBRUosaURBQWlEO1FBQ2pELElBQUksQ0FBQyxXQUFXLEVBQUU7YUFDaEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUNyQixTQUFTOzs7O1FBQUMsQ0FBQyxLQUFpQixFQUFFLEVBQUU7WUFDaEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDNUIsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7Ozs7SUFFRCxnQkFBZ0IsQ0FBQyxVQUFrQixFQUFFLFdBQW1COztjQUNqRCxFQUFFLEdBQUcsV0FBVyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQzs7Y0FDakMsRUFBRSxHQUFHLFdBQVcsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUM7UUFFdkMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQ2IsT0FBTyxDQUFDLENBQUM7U0FDVDs7WUFFRyxZQUFZLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRTtRQUV2RCxJQUFJLFlBQVksR0FBRyxDQUFDLEVBQUU7WUFDckIsWUFBWSxJQUFJLEdBQUcsQ0FBQztTQUNwQjtRQUVELE9BQU8sWUFBWSxDQUFDO0lBQ3JCLENBQUM7Ozs7OztJQUVELGdCQUFnQixDQUFDLFVBQWtCLEVBQUUsV0FBbUI7UUFDdkQsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQ25HLENBQUM7OztZQXhGRCxTQUFTLFNBQUM7Z0JBQ1YsUUFBUSxFQUFFLG1CQUFtQjtnQkFDN0IsNHRDQUE0Qzs7YUFFNUM7Ozs7WUFia0MsaUJBQWlCOzs7eUJBZWxELFNBQVMsU0FBQyxZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTs7OztJQUFqRSwwQ0FBZ0c7O0lBRWhHLHNDQUE0RDs7SUFDNUQscUNBQXVEOztJQUN2RCx1Q0FBaUU7O0lBQ2pFLHNDQUErQjs7Ozs7SUFFbkIscUNBQWdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBBZnRlclZpZXdJbml0LCBDaGFuZ2VEZXRlY3RvclJlZiwgVmlld0NoaWxkLCBWaWV3Q29udGFpbmVyUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEZWZhdWx0TGlua01vZGVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2RlZmF1bHQtbGluay5tb2RlbCc7XG5pbXBvcnQgeyBnZW5lcmF0ZUN1cnZlUGF0aCB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Rvb2wta2l0LnV0aWwnO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCwgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBQb2ludE1vZGVsIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL3BvaW50Lm1vZGVsJztcbmltcG9ydCB7IExhYmVsTW9kZWwgfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvbGFiZWwubW9kZWwnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDb29yZHMgfSBmcm9tICcuLi8uLi8uLi9pbnRlcmZhY2VzJztcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnbmdkeC1kZWZhdWx0LWxpbmsnLFxuXHR0ZW1wbGF0ZVVybDogJy4vZGVmYXVsdC1saW5rLmNvbXBvbmVudC5odG1sJyxcblx0c3R5bGVVcmxzOiBbJy4vZGVmYXVsdC1saW5rLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRGVmYXVsdExpbmtDb21wb25lbnQgZXh0ZW5kcyBEZWZhdWx0TGlua01vZGVsIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG5cdEBWaWV3Q2hpbGQoJ2xhYmVsTGF5ZXInLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KSBsYWJlbExheWVyOiBWaWV3Q29udGFpbmVyUmVmO1xuXG5cdF9wYXRoJDogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KG51bGwpO1xuXHRwYXRoJDogT2JzZXJ2YWJsZTxzdHJpbmc+ID0gdGhpcy5fcGF0aCQuYXNPYnNlcnZhYmxlKCk7XG5cdHBvaW50cyQ6IEJlaGF2aW9yU3ViamVjdDxQb2ludE1vZGVsW10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChbXSk7XG5cdGxhYmVsJDogT2JzZXJ2YWJsZTxMYWJlbE1vZGVsPjtcblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuXHRcdHN1cGVyKCduZ2R4LWRlZmF1bHQtbGluaycpO1xuXHR9XG5cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdGNvbnN0IGZpcnN0UENvb3JkcyQgPSB0aGlzLmdldEZpcnN0UG9pbnQoKS5zZWxlY3RDb29yZHMoKTtcblx0XHRjb25zdCBsYXN0UENvb3JkcyQgPSB0aGlzLmdldExhc3RQb2ludCgpLnNlbGVjdENvb3JkcygpO1xuXG5cdFx0Ly8gT2JzZXJ2ZSBsaW5rIGNvb3JkcyBhbmQgdXBkYXRlIGRyYXdpbmcgYWNjb3JkaW5nbHlcblx0XHRjb21iaW5lTGF0ZXN0KFtmaXJzdFBDb29yZHMkLCBsYXN0UENvb3JkcyRdKVxuXHRcdFx0LnBpcGUodGFrZVVudGlsKHRoaXMub25FbnRpdHlEZXN0cm95KCkpKVxuXHRcdFx0LnN1YnNjcmliZSgoW2ZpcnN0UENvb3JkcywgbGFzdFBDb29yZHNdKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHBvaW50cyA9IFtmaXJzdFBDb29yZHMsIGxhc3RQQ29vcmRzXTtcblxuXHRcdFx0XHRjb25zdCBpc0hvcml6b250YWwgPSBNYXRoLmFicyhmaXJzdFBDb29yZHMueCAtIGxhc3RQQ29vcmRzLngpID4gTWF0aC5hYnMoZmlyc3RQQ29vcmRzLnkgLSBsYXN0UENvb3Jkcy55KTtcblx0XHRcdFx0Y29uc3QgeE9yWSA9IGlzSG9yaXpvbnRhbCA/ICd4JyA6ICd5JztcblxuXHRcdFx0XHQvLyBkcmF3IHRoZSBzbW9vdGhpbmdcblx0XHRcdFx0Ly8gaWYgdGhlIHBvaW50cyBhcmUgdG9vIGNsb3NlLCBqdXN0IGRyYXcgYSBzdHJhaWdodCBsaW5lXG5cdFx0XHRcdGxldCBpc1N0cmFpZ2h0ID0gZmFsc2U7XG5cdFx0XHRcdGlmIChNYXRoLmFicyhwb2ludHNbMF1beE9yWV0gLSBwb2ludHNbMV1beE9yWV0pIDwgNTApIHtcblx0XHRcdFx0XHRpc1N0cmFpZ2h0ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IHBhdGggPSBnZW5lcmF0ZUN1cnZlUGF0aChmaXJzdFBDb29yZHMsIGxhc3RQQ29vcmRzLCBpc1N0cmFpZ2h0ID8gMCA6IHRoaXMuY3VydnluZXNzKTtcblx0XHRcdFx0dGhpcy5fcGF0aCQubmV4dChwYXRoKTtcblxuXHRcdFx0XHRpZiAoIXRoaXMuZ2V0VGFyZ2V0UG9ydCgpKSB7XG5cdFx0XHRcdFx0Y29uc3QgZGFuZ2xpbmdQb2ludCA9IHRoaXMuZ2VuZXJhdGVQb2ludChsYXN0UENvb3Jkcyk7XG5cdFx0XHRcdFx0dGhpcy5wb2ludHMkLm5leHQoW2RhbmdsaW5nUG9pbnRdKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IGxhYmVsID0gdGhpcy5nZXRMYWJlbCgpO1xuXHRcdFx0XHQvLyB1cGRhdGUgbGFiZWwgcG9zaXRpb25cblx0XHRcdFx0aWYgKGxhYmVsKSB7XG5cdFx0XHRcdFx0bGFiZWwuc2V0Q29vcmRzKHRoaXMuY2FsY0NlbnRlck9mUGF0aChmaXJzdFBDb29yZHMsIGxhc3RQQ29vcmRzKSk7XG5cblx0XHRcdFx0XHQvLyBUT0RPOiBjaGVjayB3aGV0aGVyIHdlIHdhbnQgdGhlIGxhYmVsIHRvIHJvdGF0ZSBhbG9uZyB3aXRoIHRoZSBsaW5lXG5cdFx0XHRcdFx0Ly8gbGFiZWwuc2V0Um90YXRpb24odGhpcy5jYWxjTGFiZWxJbmNsaW5lKGZpcnN0UENvb3JkcywgbGFzdFBDb29yZHMpKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRPRE86IGhhbmRsZSB0aGUgbXVsdGlwbGUgbGluZXMgaW4gYmV0d2VlbiB0aGUgcG9pbnRzXG5cdFx0XHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wcm9qZWN0c3Rvcm0vcmVhY3QtZGlhZ3JhbXMvYmxvYi9tYXN0ZXIvc3JjL2RlZmF1bHRzL3dpZGdldHMvRGVmYXVsdExpbmtXaWRnZXQudHN4I0wzNDQtTDM3MVxuXG5cdFx0XHRcdHRoaXMuY2RSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXHRcdFx0fSk7XG5cblx0XHQvLyBvYnNlcnZlIGxpbmsgbGFiZWwgYW5kIGRyYXcvcmVtb3ZlIGFjY29yZGluZ2x5XG5cdFx0dGhpcy5zZWxlY3RMYWJlbCgpXG5cdFx0XHQucGlwZShmaWx0ZXIoQm9vbGVhbikpXG5cdFx0XHQuc3Vic2NyaWJlKChsYWJlbDogTGFiZWxNb2RlbCkgPT4ge1xuXHRcdFx0XHR0aGlzLmRpYWdyYW1FbmdpbmUuZ2VuZXJhdGVXaWRnZXRGb3JMYWJlbChsYWJlbCwgdGhpcy5sYWJlbExheWVyKTtcblx0XHRcdFx0dGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG5cdFx0XHR9KTtcblx0fVxuXG5cdGNhbGNMYWJlbEluY2xpbmUoZmlyc3RQb2ludDogQ29vcmRzLCBzZWNvbmRQb2ludDogQ29vcmRzKTogbnVtYmVyIHtcblx0XHRjb25zdCBkeSA9IHNlY29uZFBvaW50LnkgLSBmaXJzdFBvaW50Lnk7XG5cdFx0Y29uc3QgZHggPSBzZWNvbmRQb2ludC54IC0gZmlyc3RQb2ludC54O1xuXG5cdFx0aWYgKGR4ID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHRsZXQgaW5jbGluZUFuZ2VsID0gKE1hdGguYXRhbihkeSAvIGR4KSAqIDE4MCkgLyBNYXRoLlBJO1xuXG5cdFx0aWYgKGluY2xpbmVBbmdlbCA8IDApIHtcblx0XHRcdGluY2xpbmVBbmdlbCArPSAxODA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGluY2xpbmVBbmdlbDtcblx0fVxuXG5cdGNhbGNDZW50ZXJPZlBhdGgoZmlyc3RQb2ludDogQ29vcmRzLCBzZWNvbmRQb2ludDogQ29vcmRzKTogQ29vcmRzIHtcblx0XHRyZXR1cm4geyB4OiAoZmlyc3RQb2ludC54ICsgc2Vjb25kUG9pbnQueCkgLyAyICsgMjAsIHk6IChmaXJzdFBvaW50LnkgKyBzZWNvbmRQb2ludC55KSAvIDIgKyAyMCB9O1xuXHR9XG59XG4iXX0=