angular-cesium
Version:
Angular library for working with Cesium.
249 lines • 37.9 kB
JavaScript
import { AcEntity } from '../../angular-cesium/models/ac-entity';
import { EditPoint } from './edit-point';
import { GeoUtilsService } from '../../angular-cesium/services/geo-utils/geo-utils.service';
import { defaultLabelProps } from './label-props';
export class EditableHippodrome extends AcEntity {
constructor(id, pointsLayer, hippodromeLayer, coordinateConverter, editOptions, positions) {
super();
this.id = id;
this.pointsLayer = pointsLayer;
this.hippodromeLayer = hippodromeLayer;
this.coordinateConverter = coordinateConverter;
this.positions = [];
this.done = false;
this._enableEdit = true;
this._labels = [];
this.defaultPointProps = Object.assign({}, editOptions.pointProps);
this.hippodromeProps = Object.assign({}, editOptions.hippodromeProps);
if (positions && positions.length === 2) {
this.createFromExisting(positions);
}
else if (positions) {
throw new Error('Hippodrome consist of 2 points but provided ' + positions.length);
}
}
get labels() {
return this._labels;
}
set labels(labels) {
if (!labels) {
return;
}
const positions = this.getRealPositions();
this._labels = labels.map((label, index) => {
if (!label.position) {
label.position = positions[index];
}
return Object.assign({}, defaultLabelProps, label);
});
}
get hippodromeProps() {
return this._hippodromeProps;
}
set hippodromeProps(value) {
this._hippodromeProps = value;
}
get defaultPointProps() {
return this._defaultPointProps;
}
set defaultPointProps(value) {
this._defaultPointProps = value;
}
get enableEdit() {
return this._enableEdit;
}
set enableEdit(value) {
this._enableEdit = value;
this.positions.forEach(point => {
point.show = value;
this.updatePointsLayer(point);
});
}
createFromExisting(positions) {
positions.forEach(position => {
this.addPointFromExisting(position);
});
this.createHeightEditPoints();
this.updateHippdromeLayer();
this.updatePointsLayer(...this.positions);
this.done = true;
}
setPointsManually(points, widthMeters) {
if (!this.done) {
throw new Error('Update manually only in edit mode, after polyline is created');
}
this.hippodromeProps.width = widthMeters ? widthMeters : this.hippodromeProps.width;
this.positions.forEach(p => this.pointsLayer.remove(p.getId()));
this.positions = points;
this.createHeightEditPoints();
this.updatePointsLayer(...points);
this.updateHippdromeLayer();
}
addPointFromExisting(position) {
const newPoint = new EditPoint(this.id, position, this.defaultPointProps);
this.positions.push(newPoint);
this.updatePointsLayer(newPoint);
}
addPoint(position) {
if (this.done) {
return;
}
const isFirstPoint = !this.positions.length;
if (isFirstPoint) {
const firstPoint = new EditPoint(this.id, position, this.defaultPointProps);
this.positions.push(firstPoint);
this.movingPoint = new EditPoint(this.id, position.clone(), this.defaultPointProps);
this.positions.push(this.movingPoint);
this.updatePointsLayer(firstPoint);
}
else {
this.createHeightEditPoints();
this.updatePointsLayer(...this.positions);
this.updateHippdromeLayer();
this.done = true;
this.movingPoint = null;
}
}
createHeightEditPoints() {
this.positions.filter(p => p.isVirtualEditPoint()).forEach(p => this.removePosition(p));
const firstP = this.getRealPoints()[0];
const secP = this.getRealPoints()[1];
const midPointCartesian3 = Cesium.Cartesian3.lerp(firstP.getPosition(), secP.getPosition(), 0.5, new Cesium.Cartesian3());
const bearingDeg = this.coordinateConverter.bearingToCartesian(firstP.getPosition(), secP.getPosition());
const upAzimuth = Cesium.Math.toRadians(bearingDeg) - Math.PI / 2;
this.createMiddleEditablePoint(midPointCartesian3, upAzimuth);
const downAzimuth = Cesium.Math.toRadians(bearingDeg) + Math.PI / 2;
this.createMiddleEditablePoint(midPointCartesian3, downAzimuth);
}
createMiddleEditablePoint(midPointCartesian3, azimuth) {
const upEditCartesian3 = GeoUtilsService.pointByLocationDistanceAndAzimuth(midPointCartesian3, this.hippodromeProps.width / 2, azimuth, true);
const midPoint = new EditPoint(this.id, upEditCartesian3, this.defaultPointProps);
midPoint.setVirtualEditPoint(true);
this.positions.push(midPoint);
}
movePoint(toPosition, editPoint) {
if (!editPoint.isVirtualEditPoint()) {
editPoint.setPosition(toPosition);
this.createHeightEditPoints();
this.updatePointsLayer(...this.positions);
this.updateHippdromeLayer();
}
else {
this.changeWidthByNewPoint(toPosition);
}
}
changeWidthByNewPoint(toPosition) {
const firstP = this.getRealPoints()[0];
const secP = this.getRealPoints()[1];
const midPointCartesian3 = Cesium.Cartesian3.lerp(firstP.getPosition(), secP.getPosition(), 0.5, new Cesium.Cartesian3());
const bearingDeg = this.coordinateConverter.bearingToCartesian(midPointCartesian3, toPosition);
let normalizedBearingDeb = bearingDeg;
if (bearingDeg > 270) {
normalizedBearingDeb = bearingDeg - 270;
}
else if (bearingDeg > 180) {
normalizedBearingDeb = bearingDeg - 180;
}
let bearingDegHippodromeDots = this.coordinateConverter.bearingToCartesian(firstP.getPosition(), secP.getPosition());
if (bearingDegHippodromeDots > 180) {
bearingDegHippodromeDots = this.coordinateConverter.bearingToCartesian(secP.getPosition(), firstP.getPosition());
}
let fixedBearingDeg = bearingDegHippodromeDots > normalizedBearingDeb
? bearingDegHippodromeDots - normalizedBearingDeb
: normalizedBearingDeb - bearingDegHippodromeDots;
if (bearingDeg > 270) {
fixedBearingDeg = bearingDeg - bearingDegHippodromeDots;
}
const distanceMeters = Math.abs(GeoUtilsService.distance(midPointCartesian3, toPosition));
const radiusWidth = Math.sin(Cesium.Math.toRadians(fixedBearingDeg)) * distanceMeters;
this.hippodromeProps.width = Math.abs(radiusWidth) * 2;
this.createHeightEditPoints();
this.updatePointsLayer(...this.positions);
this.updateHippdromeLayer();
}
moveShape(startMovingPosition, draggedToPosition) {
if (!this.lastDraggedToPosition) {
this.lastDraggedToPosition = startMovingPosition;
}
const delta = GeoUtilsService.getPositionsDelta(this.lastDraggedToPosition, draggedToPosition);
this.getRealPoints().forEach(point => {
const newPos = GeoUtilsService.addDeltaToPosition(point.getPosition(), delta, true);
point.setPosition(newPos);
});
this.createHeightEditPoints();
this.updatePointsLayer(...this.positions);
this.updateHippdromeLayer();
this.lastDraggedToPosition = draggedToPosition;
}
endMoveShape() {
this.lastDraggedToPosition = undefined;
this.createHeightEditPoints();
this.positions.forEach(point => this.updatePointsLayer(point));
this.updateHippdromeLayer();
}
endMovePoint() {
this.createHeightEditPoints();
this.updatePointsLayer(...this.positions);
}
moveTempMovingPoint(toPosition) {
if (this.movingPoint) {
this.movePoint(toPosition, this.movingPoint);
}
}
removePoint(pointToRemove) {
this.removePosition(pointToRemove);
this.positions.filter(p => p.isVirtualEditPoint()).forEach(p => this.removePosition(p));
}
addLastPoint(position) {
this.done = true;
this.removePosition(this.movingPoint); // remove movingPoint
this.movingPoint = null;
}
getRealPositions() {
return this.getRealPoints().map(position => position.getPosition());
}
getRealPositionsCallbackProperty() {
return new Cesium.CallbackProperty(this.getRealPositions.bind(this), false);
}
getRealPoints() {
return this.positions.filter(position => !position.isVirtualEditPoint());
}
getWidth() {
return this.hippodromeProps.width;
}
getPositions() {
return this.positions.map(position => position.getPosition());
}
removePosition(point) {
const index = this.positions.findIndex(p => p === point);
if (index < 0) {
return;
}
this.positions.splice(index, 1);
this.pointsLayer.remove(point.getId());
}
updatePointsLayer(...point) {
point.forEach(p => this.pointsLayer.update(p, p.getId()));
}
updateHippdromeLayer() {
this.hippodromeLayer.update(this, this.id);
}
dispose() {
this.hippodromeLayer.remove(this.id);
this.positions.forEach(editPoint => {
this.pointsLayer.remove(editPoint.getId());
});
if (this.movingPoint) {
this.pointsLayer.remove(this.movingPoint.getId());
this.movingPoint = undefined;
}
this.positions.length = 0;
}
getPointsCount() {
return this.positions.length;
}
getId() {
return this.id;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtaGlwcG9kcm9tZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY2VzaXVtL3NyYy9saWIvYW5ndWxhci1jZXNpdW0td2lkZ2V0cy9tb2RlbHMvZWRpdGFibGUtaGlwcG9kcm9tZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQU16QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkRBQTJELENBQUM7QUFDNUYsT0FBTyxFQUFFLGlCQUFpQixFQUFjLE1BQU0sZUFBZSxDQUFDO0FBRTlELE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxRQUFRO0lBVTlDLFlBQ1UsRUFBVSxFQUNWLFdBQTZCLEVBQzdCLGVBQWlDLEVBQ2pDLG1CQUF3QyxFQUNoRCxXQUFrQyxFQUNsQyxTQUF3QjtRQUV4QixLQUFLLEVBQUUsQ0FBQztRQVBBLE9BQUUsR0FBRixFQUFFLENBQVE7UUFDVixnQkFBVyxHQUFYLFdBQVcsQ0FBa0I7UUFDN0Isb0JBQWUsR0FBZixlQUFlLENBQWtCO1FBQ2pDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFiMUMsY0FBUyxHQUFnQixFQUFFLENBQUM7UUFFNUIsU0FBSSxHQUFHLEtBQUssQ0FBQztRQUNiLGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBSW5CLFlBQU8sR0FBaUIsRUFBRSxDQUFDO1FBV2pDLElBQUksQ0FBQyxpQkFBaUIscUJBQU8sV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxlQUFlLHFCQUFPLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN4RCxJQUFJLFNBQVMsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUN2QyxJQUFJLENBQUMsa0JBQWtCLENB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QUcsS0FBa0I7UUFDN0MsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFTyxvQkFBb0I7UUFDMUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVyQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUNqQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7U0FDOUI7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELGNBQWM7UUFDWixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQy9CLENBQUM7SUFFRCxLQUFLO1FBQ0gsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjRW50aXR5IH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vbW9kZWxzL2FjLWVudGl0eSc7XHJcbmltcG9ydCB7IEVkaXRQb2ludCB9IGZyb20gJy4vZWRpdC1wb2ludCc7XHJcbmltcG9ydCB7IEFjTGF5ZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9jb21wb25lbnRzL2FjLWxheWVyL2FjLWxheWVyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENhcnRlc2lhbjMgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9tb2RlbHMvY2FydGVzaWFuMyc7XHJcbmltcG9ydCB7IENvb3JkaW5hdGVDb252ZXJ0ZXIgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9jb29yZGluYXRlLWNvbnZlcnRlci9jb29yZGluYXRlLWNvbnZlcnRlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUG9pbnRQcm9wcyB9IGZyb20gJy4vcG9pbnQtZWRpdC1vcHRpb25zJztcclxuaW1wb3J0IHsgSGlwcG9kcm9tZUVkaXRPcHRpb25zLCBIaXBwb2Ryb21lUHJvcHMgfSBmcm9tICcuL2hpcHBvZHJvbWUtZWRpdC1vcHRpb25zJztcclxuaW1wb3J0IHsgR2VvVXRpbHNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vc2VydmljZXMvZ2VvLXV0aWxzL2dlby11dGlscy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgZGVmYXVsdExhYmVsUHJvcHMsIExhYmVsUHJvcHMgfSBmcm9tICcuL2xhYmVsLXByb3BzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFZGl0YWJsZUhpcHBvZHJvbWUgZXh0ZW5kcyBBY0VudGl0eSB7XHJcbiAgcHJpdmF0ZSBwb3NpdGlvbnM6IEVkaXRQb2ludFtdID0gW107XHJcbiAgcHJpdmF0ZSBtb3ZpbmdQb2ludDogRWRpdFBvaW50O1xyXG4gIHByaXZhdGUgZG9uZSA9IGZhbHNlO1xyXG4gIHByaXZhdGUgX2VuYWJsZUVkaXQgPSB0cnVlO1xyXG4gIHByaXZhdGUgX2RlZmF1bHRQb2ludFByb3BzOiBQb2ludFByb3BzO1xyXG4gIHByaXZhdGUgX2hpcHBvZHJvbWVQcm9wczogSGlwcG9kcm9tZVByb3BzO1xyXG4gIHByaXZhdGUgbGFzdERyYWdnZWRUb1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zO1xyXG4gIHByaXZhdGUgX2xhYmVsczogTGFiZWxQcm9wc1tdID0gW107XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nLFxyXG4gICAgcHJpdmF0ZSBwb2ludHNMYXllcjogQWNMYXllckNvbXBvbmVudCxcclxuICAgIHByaXZhdGUgaGlwcG9kcm9tZUxheWVyOiBBY0xheWVyQ29tcG9uZW50LFxyXG4gICAgcHJpdmF0ZSBjb29yZGluYXRlQ29udmVydGVyOiBDb29yZGluYXRlQ29udmVydGVyLFxyXG4gICAgZWRpdE9wdGlvbnM6IEhpcHBvZHJvbWVFZGl0T3B0aW9ucyxcclxuICAgIHBvc2l0aW9ucz86IENhcnRlc2lhbjNbXSxcclxuICApIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgICB0aGlzLmRlZmF1bHRQb2ludFByb3BzID0gey4uLmVkaXRPcHRpb25zLnBvaW50UHJvcHN9O1xyXG4gICAgdGhpcy5oaXBwb2Ryb21lUHJvcHMgPSB7Li4uZWRpdE9wdGlvbnMuaGlwcG9kcm9tZVByb3BzfTtcclxuICAgIGlmIChwb3NpdGlvbnMgJiYgcG9zaXRpb25zLmxlbmd0aCA9PT0gMikge1xyXG4gICAgICB0aGlzLmNyZWF0ZUZyb21FeGlzdGluZyhwb3NpdGlvbnMpO1xyXG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbnMpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdIaXBwb2Ryb21lIGNvbnNpc3Qgb2YgMiBwb2ludHMgYnV0IHByb3ZpZGVkICcgKyBwb3NpdGlvbnMubGVuZ3RoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBsYWJlbHMoKTogTGFiZWxQcm9wc1tdIHtcclxuICAgIHJldHVybiB0aGlzLl9sYWJlbHM7XHJcbiAgfVxyXG5cclxuICBzZXQgbGFiZWxzKGxhYmVsczogTGFiZWxQcm9wc1tdKSB7XHJcbiAgICBpZiAoIWxhYmVscykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBwb3NpdGlvbnMgPSB0aGlzLmdldFJlYWxQb3NpdGlvbnMoKTtcclxuICAgIHRoaXMuX2xhYmVscyA9IGxhYmVscy5tYXAoKGxhYmVsLCBpbmRleCkgPT4ge1xyXG4gICAgICBpZiAoIWxhYmVsLnBvc2l0aW9uKSB7XHJcbiAgICAgICAgbGFiZWwucG9zaXRpb24gPSBwb3NpdGlvbnNbaW5kZXhdO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdExhYmVsUHJvcHMsIGxhYmVsKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGhpcHBvZHJvbWVQcm9wcygpOiBIaXBwb2Ryb21lUHJvcHMge1xyXG4gICAgcmV0dXJuIHRoaXMuX2hpcHBvZHJvbWVQcm9wcztcclxuICB9XHJcblxyXG4gIHNldCBoaXBwb2Ryb21lUHJvcHModmFsdWU6IEhpcHBvZHJvbWVQcm9wcykge1xyXG4gICAgdGhpcy5faGlwcG9kcm9tZVByb3BzID0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBnZXQgZGVmYXVsdFBvaW50UHJvcHMoKTogUG9pbnRQcm9wcyB7XHJcbiAgICByZXR1cm4gdGhpcy5fZGVmYXVsdFBvaW50UHJvcHM7XHJcbiAgfVxyXG5cclxuICBzZXQgZGVmYXVsdFBvaW50UHJvcHModmFsdWU6IFBvaW50UHJvcHMpIHtcclxuICAgIHRoaXMuX2RlZmF1bHRQb2ludFByb3BzID0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBnZXQgZW5hYmxlRWRpdCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9lbmFibGVFZGl0O1xyXG4gIH1cclxuXHJcbiAgc2V0IGVuYWJsZUVkaXQodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX2VuYWJsZUVkaXQgPSB2YWx1ZTtcclxuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4ge1xyXG4gICAgICBwb2ludC5zaG93ID0gdmFsdWU7XHJcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIocG9pbnQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNyZWF0ZUZyb21FeGlzdGluZyhwb3NpdGlvbnM6IENhcnRlc2lhbjNbXSkge1xyXG4gICAgcG9zaXRpb25zLmZvckVhY2gocG9zaXRpb24gPT4ge1xyXG4gICAgICB0aGlzLmFkZFBvaW50RnJvbUV4aXN0aW5nKHBvc2l0aW9uKTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy5jcmVhdGVIZWlnaHRFZGl0UG9pbnRzKCk7XHJcbiAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XHJcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKC4uLnRoaXMucG9zaXRpb25zKTtcclxuICAgIHRoaXMuZG9uZSA9IHRydWU7XHJcbiAgfVxyXG5cclxuICBzZXRQb2ludHNNYW51YWxseShwb2ludHM6IEVkaXRQb2ludFtdLCB3aWR0aE1ldGVycz86IG51bWJlcikge1xyXG4gICAgaWYgKCF0aGlzLmRvbmUpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVcGRhdGUgbWFudWFsbHkgb25seSBpbiBlZGl0IG1vZGUsIGFmdGVyIHBvbHlsaW5lIGlzIGNyZWF0ZWQnKTtcclxuICAgIH1cclxuICAgIHRoaXMuaGlwcG9kcm9tZVByb3BzLndpZHRoID0gd2lkdGhNZXRlcnMgPyB3aWR0aE1ldGVycyA6IHRoaXMuaGlwcG9kcm9tZVByb3BzLndpZHRoO1xyXG4gICAgdGhpcy5wb3NpdGlvbnMuZm9yRWFjaChwID0+IHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHAuZ2V0SWQoKSkpO1xyXG4gICAgdGhpcy5wb3NpdGlvbnMgPSBwb2ludHM7XHJcbiAgICB0aGlzLmNyZWF0ZUhlaWdodEVkaXRQb2ludHMoKTtcclxuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoLi4ucG9pbnRzKTtcclxuICAgIHRoaXMudXBkYXRlSGlwcGRyb21lTGF5ZXIoKTtcclxuICB9XHJcblxyXG4gIGFkZFBvaW50RnJvbUV4aXN0aW5nKHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XHJcbiAgICBjb25zdCBuZXdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24sIHRoaXMuZGVmYXVsdFBvaW50UHJvcHMpO1xyXG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaChuZXdQb2ludCk7XHJcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKG5ld1BvaW50KTtcclxuICB9XHJcblxyXG4gIGFkZFBvaW50KHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XHJcbiAgICBpZiAodGhpcy5kb25lKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGNvbnN0IGlzRmlyc3RQb2ludCA9ICF0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XHJcbiAgICBpZiAoaXNGaXJzdFBvaW50KSB7XHJcbiAgICAgIGNvbnN0IGZpcnN0UG9pbnQgPSBuZXcgRWRpdFBvaW50KHRoaXMuaWQsIHBvc2l0aW9uLCB0aGlzLmRlZmF1bHRQb2ludFByb3BzKTtcclxuICAgICAgdGhpcy5wb3NpdGlvbnMucHVzaChmaXJzdFBvaW50KTtcclxuICAgICAgdGhpcy5tb3ZpbmdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24uY2xvbmUoKSwgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XHJcbiAgICAgIHRoaXMucG9zaXRpb25zLnB1c2godGhpcy5tb3ZpbmdQb2ludCk7XHJcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmlyc3RQb2ludCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmNyZWF0ZUhlaWdodEVkaXRQb2ludHMoKTtcclxuXHJcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoLi4udGhpcy5wb3NpdGlvbnMpO1xyXG4gICAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XHJcbiAgICAgIHRoaXMuZG9uZSA9IHRydWU7XHJcbiAgICAgIHRoaXMubW92aW5nUG9pbnQgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjcmVhdGVIZWlnaHRFZGl0UG9pbnRzKCkge1xyXG4gICAgdGhpcy5wb3NpdGlvbnMuZmlsdGVyKHAgPT4gcC5pc1ZpcnR1YWxFZGl0UG9pbnQoKSkuZm9yRWFjaChwID0+IHRoaXMucmVtb3ZlUG9zaXRpb24ocCkpO1xyXG5cclxuICAgIGNvbnN0IGZpcnN0UCA9IHRoaXMuZ2V0UmVhbFBvaW50cygpWzBdO1xyXG4gICAgY29uc3Qgc2VjUCA9IHRoaXMuZ2V0UmVhbFBvaW50cygpWzFdO1xyXG5cclxuICAgIGNvbnN0IG1pZFBvaW50Q2FydGVzaWFuMyA9IENlc2l1bS5DYXJ0ZXNpYW4zLmxlcnAoZmlyc3RQLmdldFBvc2l0aW9uKCksIHNlY1AuZ2V0UG9zaXRpb24oKSwgMC41LCBuZXcgQ2VzaXVtLkNhcnRlc2lhbjMoKSk7XHJcbiAgICBjb25zdCBiZWFyaW5nRGVnID0gdGhpcy5jb29yZGluYXRlQ29udmVydGVyLmJlYXJpbmdUb0NhcnRlc2lhbihmaXJzdFAuZ2V0UG9zaXRpb24oKSwgc2VjUC5nZXRQb3NpdGlvbigpKTtcclxuXHJcbiAgICBjb25zdCB1cEF6aW11dGggPSBDZXNpdW0uTWF0aC50b1JhZGlhbnMoYmVhcmluZ0RlZykgLSBNYXRoLlBJIC8gMjtcclxuICAgIHRoaXMuY3JlYXRlTWlkZGxlRWRpdGFibGVQb2ludChtaWRQb2ludENhcnRlc2lhbjMsIHVwQXppbXV0aCk7XHJcbiAgICBjb25zdCBkb3duQXppbXV0aCA9IENlc2l1bS5NYXRoLnRvUmFkaWFucyhiZWFyaW5nRGVnKSArIE1hdGguUEkgLyAyO1xyXG4gICAgdGhpcy5jcmVhdGVNaWRkbGVFZGl0YWJsZVBvaW50KG1pZFBvaW50Q2FydGVzaWFuMywgZG93bkF6aW11dGgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjcmVhdGVNaWRkbGVFZGl0YWJsZVBvaW50KG1pZFBvaW50Q2FydGVzaWFuMzogYW55LCBhemltdXRoOiBudW1iZXIpIHtcclxuICAgIGNvbnN0IHVwRWRpdENhcnRlc2lhbjMgPSBHZW9VdGlsc1NlcnZpY2UucG9pbnRCeUxvY2F0aW9uRGlzdGFuY2VBbmRBemltdXRoKFxyXG4gICAgICBtaWRQb2ludENhcnRlc2lhbjMsXHJcbiAgICAgIHRoaXMuaGlwcG9kcm9tZVByb3BzLndpZHRoIC8gMixcclxuICAgICAgYXppbXV0aCxcclxuICAgICAgdHJ1ZSxcclxuICAgICk7XHJcbiAgICBjb25zdCBtaWRQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgdXBFZGl0Q2FydGVzaWFuMywgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XHJcbiAgICBtaWRQb2ludC5zZXRWaXJ0dWFsRWRpdFBvaW50KHRydWUpO1xyXG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaChtaWRQb2ludCk7XHJcbiAgfVxyXG5cclxuICBtb3ZlUG9pbnQodG9Qb3NpdGlvbjogQ2FydGVzaWFuMywgZWRpdFBvaW50OiBFZGl0UG9pbnQpIHtcclxuICAgIGlmICghZWRpdFBvaW50LmlzVmlydHVhbEVkaXRQb2ludCgpKSB7XHJcbiAgICAgIGVkaXRQb2ludC5zZXRQb3NpdGlvbih0b1Bvc2l0aW9uKTtcclxuICAgICAgdGhpcy5jcmVhdGVIZWlnaHRFZGl0UG9pbnRzKCk7XHJcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoLi4udGhpcy5wb3NpdGlvbnMpO1xyXG4gICAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmNoYW5nZVdpZHRoQnlOZXdQb2ludCh0b1Bvc2l0aW9uKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2hhbmdlV2lkdGhCeU5ld1BvaW50KHRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcclxuICAgIGNvbnN0IGZpcnN0UCA9IHRoaXMuZ2V0UmVhbFBvaW50cygpWzBdO1xyXG4gICAgY29uc3Qgc2VjUCA9IHRoaXMuZ2V0UmVhbFBvaW50cygpWzFdO1xyXG4gICAgY29uc3QgbWlkUG9pbnRDYXJ0ZXNpYW4zID0gQ2VzaXVtLkNhcnRlc2lhbjMubGVycChmaXJzdFAuZ2V0UG9zaXRpb24oKSwgc2VjUC5nZXRQb3NpdGlvbigpLCAwLjUsIG5ldyBDZXNpdW0uQ2FydGVzaWFuMygpKTtcclxuXHJcbiAgICBjb25zdCBiZWFyaW5nRGVnID0gdGhpcy5jb29yZGluYXRlQ29udmVydGVyLmJlYXJpbmdUb0NhcnRlc2lhbihtaWRQb2ludENhcnRlc2lhbjMsIHRvUG9zaXRpb24pO1xyXG4gICAgbGV0IG5vcm1hbGl6ZWRCZWFyaW5nRGViID0gYmVhcmluZ0RlZztcclxuICAgIGlmIChiZWFyaW5nRGVnID4gMjcwKSB7XHJcbiAgICAgIG5vcm1hbGl6ZWRCZWFyaW5nRGViID0gYmVhcmluZ0RlZyAtIDI3MDtcclxuICAgIH0gZWxzZSBpZiAoYmVhcmluZ0RlZyA+IDE4MCkge1xyXG4gICAgICBub3JtYWxpemVkQmVhcmluZ0RlYiA9IGJlYXJpbmdEZWcgLSAxODA7XHJcbiAgICB9XHJcbiAgICBsZXQgYmVhcmluZ0RlZ0hpcHBvZHJvbWVEb3RzID0gdGhpcy5jb29yZGluYXRlQ29udmVydGVyLmJlYXJpbmdUb0NhcnRlc2lhbihmaXJzdFAuZ2V0UG9zaXRpb24oKSwgc2VjUC5nZXRQb3NpdGlvbigpKTtcclxuICAgIGlmIChiZWFyaW5nRGVnSGlwcG9kcm9tZURvdHMgPiAxODApIHtcclxuICAgICAgYmVhcmluZ0RlZ0hpcHBvZHJvbWVEb3RzID0gdGhpcy5jb29yZGluYXRlQ29udmVydGVyLmJlYXJpbmdUb0NhcnRlc2lhbihzZWNQLmdldFBvc2l0aW9uKCksIGZpcnN0UC5nZXRQb3NpdGlvbigpKTtcclxuICAgIH1cclxuICAgIGxldCBmaXhlZEJlYXJpbmdEZWcgPVxyXG4gICAgICBiZWFyaW5nRGVnSGlwcG9kcm9tZURvdHMgPiBub3JtYWxpemVkQmVhcmluZ0RlYlxyXG4gICAgICAgID8gYmVhcmluZ0RlZ0hpcHBvZHJvbWVEb3RzIC0gbm9ybWFsaXplZEJlYXJpbmdEZWJcclxuICAgICAgICA6IG5vcm1hbGl6ZWRCZWFyaW5nRGViIC0gYmVhcmluZ0RlZ0hpcHBvZHJvbWVEb3RzO1xyXG5cclxuICAgIGlmIChiZWFyaW5nRGVnID4gMjcwKSB7XHJcbiAgICAgIGZpeGVkQmVhcmluZ0RlZyA9IGJlYXJpbmdEZWcgLSBiZWFyaW5nRGVnSGlwcG9kcm9tZURvdHM7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZGlzdGFuY2VNZXRlcnMgPSBNYXRoLmFicyhHZW9VdGlsc1NlcnZpY2UuZGlzdGFuY2UobWlkUG9pbnRDYXJ0ZXNpYW4zLCB0b1Bvc2l0aW9uKSk7XHJcbiAgICBjb25zdCByYWRpdXNXaWR0aCA9IE1hdGguc2luKENlc2l1bS5NYXRoLnRvUmFkaWFucyhmaXhlZEJlYXJpbmdEZWcpKSAqIGRpc3RhbmNlTWV0ZXJzO1xyXG5cclxuICAgIHRoaXMuaGlwcG9kcm9tZVByb3BzLndpZHRoID0gTWF0aC5hYnMocmFkaXVzV2lkdGgpICogMjtcclxuICAgIHRoaXMuY3JlYXRlSGVpZ2h0RWRpdFBvaW50cygpO1xyXG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllciguLi50aGlzLnBvc2l0aW9ucyk7XHJcbiAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XHJcbiAgfVxyXG5cclxuICBtb3ZlU2hhcGUoc3RhcnRNb3ZpbmdQb3NpdGlvbjogQ2FydGVzaWFuMywgZHJhZ2dlZFRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcclxuICAgIGlmICghdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24pIHtcclxuICAgICAgdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24gPSBzdGFydE1vdmluZ1Bvc2l0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGRlbHRhID0gR2VvVXRpbHNTZXJ2aWNlLmdldFBvc2l0aW9uc0RlbHRhKHRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uLCBkcmFnZ2VkVG9Qb3NpdGlvbik7XHJcbiAgICB0aGlzLmdldFJlYWxQb2ludHMoKS5mb3JFYWNoKHBvaW50ID0+IHtcclxuICAgICAgY29uc3QgbmV3UG9zID0gR2VvVXRpbHNTZXJ2aWNlLmFkZERlbHRhVG9Qb3NpdGlvbihwb2ludC5nZXRQb3NpdGlvbigpLCBkZWx0YSwgdHJ1ZSk7XHJcbiAgICAgIHBvaW50LnNldFBvc2l0aW9uKG5ld1Bvcyk7XHJcbiAgICB9KTtcclxuICAgIHRoaXMuY3JlYXRlSGVpZ2h0RWRpdFBvaW50cygpO1xyXG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllciguLi50aGlzLnBvc2l0aW9ucyk7XHJcbiAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XHJcbiAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IGRyYWdnZWRUb1Bvc2l0aW9uO1xyXG4gIH1cclxuXHJcbiAgZW5kTW92ZVNoYXBlKCkge1xyXG4gICAgdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24gPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmNyZWF0ZUhlaWdodEVkaXRQb2ludHMoKTtcclxuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4gdGhpcy51cGRhdGVQb2ludHNMYXllcihwb2ludCkpO1xyXG4gICAgdGhpcy51cGRhdGVIaXBwZHJvbWVMYXllcigpO1xyXG4gIH1cclxuXHJcbiAgZW5kTW92ZVBvaW50KCkge1xyXG4gICAgdGhpcy5jcmVhdGVIZWlnaHRFZGl0UG9pbnRzKCk7XHJcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKC4uLnRoaXMucG9zaXRpb25zKTtcclxuICB9XHJcblxyXG4gIG1vdmVUZW1wTW92aW5nUG9pbnQodG9Qb3NpdGlvbjogQ2FydGVzaWFuMykge1xyXG4gICAgaWYgKHRoaXMubW92aW5nUG9pbnQpIHtcclxuICAgICAgdGhpcy5tb3ZlUG9pbnQodG9Qb3NpdGlvbiwgdGhpcy5tb3ZpbmdQb2ludCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZW1vdmVQb2ludChwb2ludFRvUmVtb3ZlOiBFZGl0UG9pbnQpIHtcclxuICAgIHRoaXMucmVtb3ZlUG9zaXRpb24ocG9pbnRUb1JlbW92ZSk7XHJcbiAgICB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocCA9PiBwLmlzVmlydHVhbEVkaXRQb2ludCgpKS5mb3JFYWNoKHAgPT4gdGhpcy5yZW1vdmVQb3NpdGlvbihwKSk7XHJcbiAgfVxyXG5cclxuICBhZGRMYXN0UG9pbnQocG9zaXRpb246IENhcnRlc2lhbjMpIHtcclxuICAgIHRoaXMuZG9uZSA9IHRydWU7XHJcbiAgICB0aGlzLnJlbW92ZVBvc2l0aW9uKHRoaXMubW92aW5nUG9pbnQpOyAvLyByZW1vdmUgbW92aW5nUG9pbnRcclxuICAgIHRoaXMubW92aW5nUG9pbnQgPSBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0UmVhbFBvc2l0aW9ucygpOiBDYXJ0ZXNpYW4zW10ge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVhbFBvaW50cygpLm1hcChwb3NpdGlvbiA9PiBwb3NpdGlvbi5nZXRQb3NpdGlvbigpKTtcclxuICB9XHJcblxyXG4gIGdldFJlYWxQb3NpdGlvbnNDYWxsYmFja1Byb3BlcnR5KCkge1xyXG4gICAgcmV0dXJuIG5ldyBDZXNpdW0uQ2FsbGJhY2tQcm9wZXJ0eSh0aGlzLmdldFJlYWxQb3NpdGlvbnMuYmluZCh0aGlzKSwgZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UmVhbFBvaW50cygpOiBFZGl0UG9pbnRbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMuZmlsdGVyKHBvc2l0aW9uID0+ICFwb3NpdGlvbi5pc1ZpcnR1YWxFZGl0UG9pbnQoKSk7XHJcbiAgfVxyXG5cclxuICBnZXRXaWR0aCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuaGlwcG9kcm9tZVByb3BzLndpZHRoO1xyXG4gIH1cclxuXHJcbiAgZ2V0UG9zaXRpb25zKCk6IENhcnRlc2lhbjNbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMubWFwKHBvc2l0aW9uID0+IHBvc2l0aW9uLmdldFBvc2l0aW9uKCkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZW1vdmVQb3NpdGlvbihwb2ludDogRWRpdFBvaW50KSB7XHJcbiAgICBjb25zdCBpbmRleCA9IHRoaXMucG9zaXRpb25zLmZpbmRJbmRleChwID0+IHAgPT09IHBvaW50KTtcclxuICAgIGlmIChpbmRleCA8IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5wb3NpdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHBvaW50LmdldElkKCkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVQb2ludHNMYXllciguLi5wb2ludDogRWRpdFBvaW50W10pIHtcclxuICAgIHBvaW50LmZvckVhY2gocCA9PiB0aGlzLnBvaW50c0xheWVyLnVwZGF0ZShwLCBwLmdldElkKCkpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlSGlwcGRyb21lTGF5ZXIoKSB7XHJcbiAgICB0aGlzLmhpcHBvZHJvbWVMYXllci51cGRhdGUodGhpcywgdGhpcy5pZCk7XHJcbiAgfVxyXG5cclxuICBkaXNwb3NlKCkge1xyXG4gICAgdGhpcy5oaXBwb2Ryb21lTGF5ZXIucmVtb3ZlKHRoaXMuaWQpO1xyXG5cclxuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2goZWRpdFBvaW50ID0+IHtcclxuICAgICAgdGhpcy5wb2ludHNMYXllci5yZW1vdmUoZWRpdFBvaW50LmdldElkKCkpO1xyXG4gICAgfSk7XHJcbiAgICBpZiAodGhpcy5tb3ZpbmdQb2ludCkge1xyXG4gICAgICB0aGlzLnBvaW50c0xheWVyLnJlbW92ZSh0aGlzLm1vdmluZ1BvaW50LmdldElkKCkpO1xyXG4gICAgICB0aGlzLm1vdmluZ1BvaW50ID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gICAgdGhpcy5wb3NpdGlvbnMubGVuZ3RoID0gMDtcclxuICB9XHJcblxyXG4gIGdldFBvaW50c0NvdW50KCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xyXG4gIH1cclxuXHJcbiAgZ2V0SWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5pZDtcclxuICB9XHJcbn1cclxuIl19