@eliorar/angular-cesium
Version:
Angular library for working with Cesium.
250 lines • 36.8 kB
JavaScript
import { CallbackProperty, Cartesian3, Math as cMath } from 'cesium';
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 = { ...editOptions.pointProps };
this.hippodromeProps = { ...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 = Cartesian3.lerp(firstP.getPosition(), secP.getPosition(), 0.5, new Cartesian3());
const bearingDeg = this.coordinateConverter.bearingToCartesian(firstP.getPosition(), secP.getPosition());
const upAzimuth = cMath.toRadians(bearingDeg) - Math.PI / 2;
this.createMiddleEditablePoint(midPointCartesian3, upAzimuth);
const downAzimuth = cMath.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 = Cartesian3.lerp(firstP.getPosition(), secP.getPosition(), 0.5, new 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(cMath.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 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtaGlwcG9kcm9tZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY2VzaXVtL3NyYy9saWIvYW5ndWxhci1jZXNpdW0td2lkZ2V0cy9tb2RlbHMvZWRpdGFibGUtaGlwcG9kcm9tZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLElBQUksSUFBSSxLQUFLLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFDbkUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHVDQUF1QyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFLdkMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLDJEQUEyRCxDQUFDO0FBQzFGLE9BQU8sRUFBQyxpQkFBaUIsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUU1RCxNQUFNLE9BQU8sa0JBQW1CLFNBQVEsUUFBUTtJQVU5QyxZQUNVLEVBQVUsRUFDVixXQUE2QixFQUM3QixlQUFpQyxFQUNqQyxtQkFBd0MsRUFDaEQsV0FBa0MsRUFDbEMsU0FBd0I7UUFFeEIsS0FBSyxFQUFFLENBQUM7UUFQQSxPQUFFLEdBQUYsRUFBRSxDQUFRO1FBQ1YsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO1FBQzdCLG9CQUFlLEdBQWYsZUFBZSxDQUFrQjtRQUNqQyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBYjFDLGNBQVMsR0FBZ0IsRUFBRSxDQUFDO1FBRTVCLFNBQUksR0FBRyxLQUFLLENBQUM7UUFDYixnQkFBVyxHQUFHLElBQUksQ0FBQztRQUluQixZQUFPLEdBQWlCLEVBQUUsQ0FBQztRQVdqQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsRUFBQyxHQUFHLFdBQVcsQ0FBQyxVQUFVLEVBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUMsR0FBRyxXQUFXLENBQUMs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QWlCLENBQUMsR0FBRyxLQUFrQjtRQUM3QyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRXJDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ2pDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQztTQUM5QjtRQUNELElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDL0IsQ0FBQztJQUVELEtBQUs7UUFDSCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDakIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDYWxsYmFja1Byb3BlcnR5LCBDYXJ0ZXNpYW4zLCBNYXRoIGFzIGNNYXRofSBmcm9tICdjZXNpdW0nO1xuaW1wb3J0IHtBY0VudGl0eX0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vbW9kZWxzL2FjLWVudGl0eSc7XG5pbXBvcnQge0VkaXRQb2ludH0gZnJvbSAnLi9lZGl0LXBvaW50JztcbmltcG9ydCB7QWNMYXllckNvbXBvbmVudH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vY29tcG9uZW50cy9hYy1sYXllci9hYy1sYXllci5jb21wb25lbnQnO1xuaW1wb3J0IHtDb29yZGluYXRlQ29udmVydGVyfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9jb29yZGluYXRlLWNvbnZlcnRlci9jb29yZGluYXRlLWNvbnZlcnRlci5zZXJ2aWNlJztcbmltcG9ydCB7UG9pbnRQcm9wc30gZnJvbSAnLi9wb2ludC1lZGl0LW9wdGlvbnMnO1xuaW1wb3J0IHtIaXBwb2Ryb21lRWRpdE9wdGlvbnMsIEhpcHBvZHJvbWVQcm9wc30gZnJvbSAnLi9oaXBwb2Ryb21lLWVkaXQtb3B0aW9ucyc7XG5pbXBvcnQge0dlb1V0aWxzU2VydmljZX0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vc2VydmljZXMvZ2VvLXV0aWxzL2dlby11dGlscy5zZXJ2aWNlJztcbmltcG9ydCB7ZGVmYXVsdExhYmVsUHJvcHMsIExhYmVsUHJvcHN9IGZyb20gJy4vbGFiZWwtcHJvcHMnO1xuXG5leHBvcnQgY2xhc3MgRWRpdGFibGVIaXBwb2Ryb21lIGV4dGVuZHMgQWNFbnRpdHkge1xuICBwcml2YXRlIHBvc2l0aW9uczogRWRpdFBvaW50W10gPSBbXTtcbiAgcHJpdmF0ZSBtb3ZpbmdQb2ludDogRWRpdFBvaW50O1xuICBwcml2YXRlIGRvbmUgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfZW5hYmxlRWRpdCA9IHRydWU7XG4gIHByaXZhdGUgX2RlZmF1bHRQb2ludFByb3BzOiBQb2ludFByb3BzO1xuICBwcml2YXRlIF9oaXBwb2Ryb21lUHJvcHM6IEhpcHBvZHJvbWVQcm9wcztcbiAgcHJpdmF0ZSBsYXN0RHJhZ2dlZFRvUG9zaXRpb246IENhcnRlc2lhbjM7XG4gIHByaXZhdGUgX2xhYmVsczogTGFiZWxQcm9wc1tdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nLFxuICAgIHByaXZhdGUgcG9pbnRzTGF5ZXI6IEFjTGF5ZXJDb21wb25lbnQsXG4gICAgcHJpdmF0ZSBoaXBwb2Ryb21lTGF5ZXI6IEFjTGF5ZXJDb21wb25lbnQsXG4gICAgcHJpdmF0ZSBjb29yZGluYXRlQ29udmVydGVyOiBDb29yZGluYXRlQ29udmVydGVyLFxuICAgIGVkaXRPcHRpb25zOiBIaXBwb2Ryb21lRWRpdE9wdGlvbnMsXG4gICAgcG9zaXRpb25zPzogQ2FydGVzaWFuM1tdLFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuZGVmYXVsdFBvaW50UHJvcHMgPSB7Li4uZWRpdE9wdGlvbnMucG9pbnRQcm9wc307XG4gICAgdGhpcy5oaXBwb2Ryb21lUHJvcHMgPSB7Li4uZWRpdE9wdGlvbnMuaGlwcG9kcm9tZVByb3BzfTtcbiAgICBpZiAocG9zaXRpb25zICYmIHBvc2l0aW9ucy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHRoaXMuY3JlYXRlRnJvbUV4aXN0aW5nKHBvc2l0aW9ucyk7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSGlwcG9kcm9tZSBjb25zaXN0IG9mIDIgcG9pbnRzIGJ1dCBwcm92aWRlZCAnICsgcG9zaXRpb25zLmxlbmd0aCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGxhYmVscygpOiBMYWJlbFByb3BzW10ge1xuICAgIHJldHVybiB0aGlzLl9sYWJlbHM7XG4gIH1cblxuICBzZXQgbGFiZWxzKGxhYmVsczogTGFiZWxQcm9wc1tdKSB7XG4gICAgaWYgKCFsYWJlbHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9zaXRpb25zID0gdGhpcy5nZXRSZWFsUG9zaXRpb25zKCk7XG4gICAgdGhpcy5fbGFiZWxzID0gbGFiZWxzLm1hcCgobGFiZWwsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWxhYmVsLnBvc2l0aW9uKSB7XG4gICAgICAgIGxhYmVsLnBvc2l0aW9uID0gcG9zaXRpb25zW2luZGV4XTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRMYWJlbFByb3BzLCBsYWJlbCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgaGlwcG9kcm9tZVByb3BzKCk6IEhpcHBvZHJvbWVQcm9wcyB7XG4gICAgcmV0dXJuIHRoaXMuX2hpcHBvZHJvbWVQcm9wcztcbiAgfVxuXG4gIHNldCBoaXBwb2Ryb21lUHJvcHModmFsdWU6IEhpcHBvZHJvbWVQcm9wcykge1xuICAgIHRoaXMuX2hpcHBvZHJvbWVQcm9wcyA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGRlZmF1bHRQb2ludFByb3BzKCk6IFBvaW50UHJvcHMge1xuICAgIHJldHVybiB0aGlzLl9kZWZhdWx0UG9pbnRQcm9wcztcbiAgfVxuXG4gIHNldCBkZWZhdWx0UG9pbnRQcm9wcyh2YWx1ZTogUG9pbnRQcm9wcykge1xuICAgIHRoaXMuX2RlZmF1bHRQb2ludFByb3BzID0gdmFsdWU7XG4gIH1cblxuICBnZXQgZW5hYmxlRWRpdCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZW5hYmxlRWRpdDtcbiAgfVxuXG4gIHNldCBlbmFibGVFZGl0KHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZW5hYmxlRWRpdCA9IHZhbHVlO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4ge1xuICAgICAgcG9pbnQuc2hvdyA9IHZhbHVlO1xuICAgICAgdGhpcy51cGRhdGVQb2ludHNMYXllcihwb2ludCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZyb21FeGlzdGluZyhwb3NpdGlvbnM6IENhcnRlc2lhbjNbXSkge1xuICAgIHBvc2l0aW9ucy5mb3JFYWNoKHBvc2l0aW9uID0+IHtcbiAgICAgIHRoaXMuYWRkUG9pbnRGcm9tRXhpc3RpbmcocG9zaXRpb24pO1xuICAgIH0pO1xuICAgIHRoaXMuY3JlYXRlSGVpZ2h0RWRpdFBvaW50cygpO1xuICAgIHRoaXMudXBkYXRlSGlwcGRyb21lTGF5ZXIoKTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLmRvbmUgPSB0cnVlO1xuICB9XG5cbiAgc2V0UG9pbnRzTWFudWFsbHkocG9pbnRzOiBFZGl0UG9pbnRbXSwgd2lkdGhNZXRlcnM/OiBudW1iZXIpIHtcbiAgICBpZiAoIXRoaXMuZG9uZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVcGRhdGUgbWFudWFsbHkgb25seSBpbiBlZGl0IG1vZGUsIGFmdGVyIHBvbHlsaW5lIGlzIGNyZWF0ZWQnKTtcbiAgICB9XG4gICAgdGhpcy5oaXBwb2Ryb21lUHJvcHMud2lkdGggPSB3aWR0aE1ldGVycyA/IHdpZHRoTWV0ZXJzIDogdGhpcy5oaXBwb2Ryb21lUHJvcHMud2lkdGg7XG4gICAgdGhpcy5wb3NpdGlvbnMuZm9yRWFjaChwID0+IHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHAuZ2V0SWQoKSkpO1xuICAgIHRoaXMucG9zaXRpb25zID0gcG9pbnRzO1xuICAgIHRoaXMuY3JlYXRlSGVpZ2h0RWRpdFBvaW50cygpO1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoLi4ucG9pbnRzKTtcbiAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XG4gIH1cblxuICBhZGRQb2ludEZyb21FeGlzdGluZyhwb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIGNvbnN0IG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbiwgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaChuZXdQb2ludCk7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcihuZXdQb2ludCk7XG4gIH1cblxuICBhZGRQb2ludChwb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIGlmICh0aGlzLmRvbmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaXNGaXJzdFBvaW50ID0gIXRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICBpZiAoaXNGaXJzdFBvaW50KSB7XG4gICAgICBjb25zdCBmaXJzdFBvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbiwgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XG4gICAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKGZpcnN0UG9pbnQpO1xuICAgICAgdGhpcy5tb3ZpbmdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24uY2xvbmUoKSwgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XG4gICAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKHRoaXMubW92aW5nUG9pbnQpO1xuICAgICAgdGhpcy51cGRhdGVQb2ludHNMYXllcihmaXJzdFBvaW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jcmVhdGVIZWlnaHRFZGl0UG9pbnRzKCk7XG5cbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoLi4udGhpcy5wb3NpdGlvbnMpO1xuICAgICAgdGhpcy51cGRhdGVIaXBwZHJvbWVMYXllcigpO1xuICAgICAgdGhpcy5kb25lID0gdHJ1ZTtcbiAgICAgIHRoaXMubW92aW5nUG9pbnQgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlSGVpZ2h0RWRpdFBvaW50cygpIHtcbiAgICB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocCA9PiBwLmlzVmlydHVhbEVkaXRQb2ludCgpKS5mb3JFYWNoKHAgPT4gdGhpcy5yZW1vdmVQb3NpdGlvbihwKSk7XG5cbiAgICBjb25zdCBmaXJzdFAgPSB0aGlzLmdldFJlYWxQb2ludHMoKVswXTtcbiAgICBjb25zdCBzZWNQID0gdGhpcy5nZXRSZWFsUG9pbnRzKClbMV07XG5cbiAgICBjb25zdCBtaWRQb2ludENhcnRlc2lhbjMgPSBDYXJ0ZXNpYW4zLmxlcnAoZmlyc3RQLmdldFBvc2l0aW9uKCksIHNlY1AuZ2V0UG9zaXRpb24oKSwgMC41LCBuZXcgQ2FydGVzaWFuMygpKTtcbiAgICBjb25zdCBiZWFyaW5nRGVnID0gdGhpcy5jb29yZGluYXRlQ29udmVydGVyLmJlYXJpbmdUb0NhcnRlc2lhbihmaXJzdFAuZ2V0UG9zaXRpb24oKSwgc2VjUC5nZXRQb3NpdGlvbigpKTtcblxuICAgIGNvbnN0IHVwQXppbXV0aCA9IGNNYXRoLnRvUmFkaWFucyhiZWFyaW5nRGVnKSAtIE1hdGguUEkgLyAyO1xuICAgIHRoaXMuY3JlYXRlTWlkZGxlRWRpdGFibGVQb2ludChtaWRQb2ludENhcnRlc2lhbjMsIHVwQXppbXV0aCk7XG4gICAgY29uc3QgZG93bkF6aW11dGggPSBjTWF0aC50b1JhZGlhbnMoYmVhcmluZ0RlZykgKyBNYXRoLlBJIC8gMjtcbiAgICB0aGlzLmNyZWF0ZU1pZGRsZUVkaXRhYmxlUG9pbnQobWlkUG9pbnRDYXJ0ZXNpYW4zLCBkb3duQXppbXV0aCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU1pZGRsZUVkaXRhYmxlUG9pbnQobWlkUG9pbnRDYXJ0ZXNpYW4zOiBhbnksIGF6aW11dGg6IG51bWJlcikge1xuICAgIGNvbnN0IHVwRWRpdENhcnRlc2lhbjMgPSBHZW9VdGlsc1NlcnZpY2UucG9pbnRCeUxvY2F0aW9uRGlzdGFuY2VBbmRBemltdXRoKFxuICAgICAgbWlkUG9pbnRDYXJ0ZXNpYW4zLFxuICAgICAgdGhpcy5oaXBwb2Ryb21lUHJvcHMud2lkdGggLyAyLFxuICAgICAgYXppbXV0aCxcbiAgICAgIHRydWUsXG4gICAgKTtcbiAgICBjb25zdCBtaWRQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgdXBFZGl0Q2FydGVzaWFuMywgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XG4gICAgbWlkUG9pbnQuc2V0VmlydHVhbEVkaXRQb2ludCh0cnVlKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKG1pZFBvaW50KTtcbiAgfVxuXG4gIG1vdmVQb2ludCh0b1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zLCBlZGl0UG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGlmICghZWRpdFBvaW50LmlzVmlydHVhbEVkaXRQb2ludCgpKSB7XG4gICAgICBlZGl0UG9pbnQuc2V0UG9zaXRpb24odG9Qb3NpdGlvbik7XG4gICAgICB0aGlzLmNyZWF0ZUhlaWdodEVkaXRQb2ludHMoKTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoLi4udGhpcy5wb3NpdGlvbnMpO1xuICAgICAgdGhpcy51cGRhdGVIaXBwZHJvbWVMYXllcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNoYW5nZVdpZHRoQnlOZXdQb2ludCh0b1Bvc2l0aW9uKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoYW5nZVdpZHRoQnlOZXdQb2ludCh0b1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgY29uc3QgZmlyc3RQID0gdGhpcy5nZXRSZWFsUG9pbnRzKClbMF07XG4gICAgY29uc3Qgc2VjUCA9IHRoaXMuZ2V0UmVhbFBvaW50cygpWzFdO1xuICAgIGNvbnN0IG1pZFBvaW50Q2FydGVzaWFuMyA9IENhcnRlc2lhbjMubGVycChmaXJzdFAuZ2V0UG9zaXRpb24oKSwgc2VjUC5nZXRQb3NpdGlvbigpLCAwLjUsIG5ldyBDYXJ0ZXNpYW4zKCkpO1xuXG4gICAgY29uc3QgYmVhcmluZ0RlZyA9IHRoaXMuY29vcmRpbmF0ZUNvbnZlcnRlci5iZWFyaW5nVG9DYXJ0ZXNpYW4obWlkUG9pbnRDYXJ0ZXNpYW4zLCB0b1Bvc2l0aW9uKTtcbiAgICBsZXQgbm9ybWFsaXplZEJlYXJpbmdEZWIgPSBiZWFyaW5nRGVnO1xuICAgIGlmIChiZWFyaW5nRGVnID4gMjcwKSB7XG4gICAgICBub3JtYWxpemVkQmVhcmluZ0RlYiA9IGJlYXJpbmdEZWcgLSAyNzA7XG4gICAgfSBlbHNlIGlmIChiZWFyaW5nRGVnID4gMTgwKSB7XG4gICAgICBub3JtYWxpemVkQmVhcmluZ0RlYiA9IGJlYXJpbmdEZWcgLSAxODA7XG4gICAgfVxuICAgIGxldCBiZWFyaW5nRGVnSGlwcG9kcm9tZURvdHMgPSB0aGlzLmNvb3JkaW5hdGVDb252ZXJ0ZXIuYmVhcmluZ1RvQ2FydGVzaWFuKGZpcnN0UC5nZXRQb3NpdGlvbigpLCBzZWNQLmdldFBvc2l0aW9uKCkpO1xuICAgIGlmIChiZWFyaW5nRGVnSGlwcG9kcm9tZURvdHMgPiAxODApIHtcbiAgICAgIGJlYXJpbmdEZWdIaXBwb2Ryb21lRG90cyA9IHRoaXMuY29vcmRpbmF0ZUNvbnZlcnRlci5iZWFyaW5nVG9DYXJ0ZXNpYW4oc2VjUC5nZXRQb3NpdGlvbigpLCBmaXJzdFAuZ2V0UG9zaXRpb24oKSk7XG4gICAgfVxuICAgIGxldCBmaXhlZEJlYXJpbmdEZWcgPVxuICAgICAgYmVhcmluZ0RlZ0hpcHBvZHJvbWVEb3RzID4gbm9ybWFsaXplZEJlYXJpbmdEZWJcbiAgICAgICAgPyBiZWFyaW5nRGVnSGlwcG9kcm9tZURvdHMgLSBub3JtYWxpemVkQmVhcmluZ0RlYlxuICAgICAgICA6IG5vcm1hbGl6ZWRCZWFyaW5nRGViIC0gYmVhcmluZ0RlZ0hpcHBvZHJvbWVEb3RzO1xuXG4gICAgaWYgKGJlYXJpbmdEZWcgPiAyNzApIHtcbiAgICAgIGZpeGVkQmVhcmluZ0RlZyA9IGJlYXJpbmdEZWcgLSBiZWFyaW5nRGVnSGlwcG9kcm9tZURvdHM7XG4gICAgfVxuXG4gICAgY29uc3QgZGlzdGFuY2VNZXRlcnMgPSBNYXRoLmFicyhHZW9VdGlsc1NlcnZpY2UuZGlzdGFuY2UobWlkUG9pbnRDYXJ0ZXNpYW4zLCB0b1Bvc2l0aW9uKSk7XG4gICAgY29uc3QgcmFkaXVzV2lkdGggPSBNYXRoLnNpbihjTWF0aC50b1JhZGlhbnMoZml4ZWRCZWFyaW5nRGVnKSkgKiBkaXN0YW5jZU1ldGVycztcblxuICAgIHRoaXMuaGlwcG9kcm9tZVByb3BzLndpZHRoID0gTWF0aC5hYnMocmFkaXVzV2lkdGgpICogMjtcbiAgICB0aGlzLmNyZWF0ZUhlaWdodEVkaXRQb2ludHMoKTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XG4gIH1cblxuICBtb3ZlU2hhcGUoc3RhcnRNb3ZpbmdQb3NpdGlvbjogQ2FydGVzaWFuMywgZHJhZ2dlZFRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAoIXRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uKSB7XG4gICAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IHN0YXJ0TW92aW5nUG9zaXRpb247XG4gICAgfVxuXG4gICAgY29uc3QgZGVsdGEgPSBHZW9VdGlsc1NlcnZpY2UuZ2V0UG9zaXRpb25zRGVsdGEodGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24sIGRyYWdnZWRUb1Bvc2l0aW9uKTtcbiAgICB0aGlzLmdldFJlYWxQb2ludHMoKS5mb3JFYWNoKHBvaW50ID0+IHtcbiAgICAgIGNvbnN0IG5ld1BvcyA9IEdlb1V0aWxzU2VydmljZS5hZGREZWx0YVRvUG9zaXRpb24ocG9pbnQuZ2V0UG9zaXRpb24oKSwgZGVsdGEsIHRydWUpO1xuICAgICAgcG9pbnQuc2V0UG9zaXRpb24obmV3UG9zKTtcbiAgICB9KTtcbiAgICB0aGlzLmNyZWF0ZUhlaWdodEVkaXRQb2ludHMoKTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XG4gICAgdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24gPSBkcmFnZ2VkVG9Qb3NpdGlvbjtcbiAgfVxuXG4gIGVuZE1vdmVTaGFwZSgpIHtcbiAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNyZWF0ZUhlaWdodEVkaXRQb2ludHMoKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKHBvaW50ID0+IHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIocG9pbnQpKTtcbiAgICB0aGlzLnVwZGF0ZUhpcHBkcm9tZUxheWVyKCk7XG4gIH1cblxuICBlbmRNb3ZlUG9pbnQoKSB7XG4gICAgdGhpcy5jcmVhdGVIZWlnaHRFZGl0UG9pbnRzKCk7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllciguLi50aGlzLnBvc2l0aW9ucyk7XG4gIH1cblxuICBtb3ZlVGVtcE1vdmluZ1BvaW50KHRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAodGhpcy5tb3ZpbmdQb2ludCkge1xuICAgICAgdGhpcy5tb3ZlUG9pbnQodG9Qb3NpdGlvbiwgdGhpcy5tb3ZpbmdQb2ludCk7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlUG9pbnQocG9pbnRUb1JlbW92ZTogRWRpdFBvaW50KSB7XG4gICAgdGhpcy5yZW1vdmVQb3NpdGlvbihwb2ludFRvUmVtb3ZlKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocCA9PiBwLmlzVmlydHVhbEVkaXRQb2ludCgpKS5mb3JFYWNoKHAgPT4gdGhpcy5yZW1vdmVQb3NpdGlvbihwKSk7XG4gIH1cblxuICBhZGRMYXN0UG9pbnQocG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICB0aGlzLmRvbmUgPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlUG9zaXRpb24odGhpcy5tb3ZpbmdQb2ludCk7IC8vIHJlbW92ZSBtb3ZpbmdQb2ludFxuICAgIHRoaXMubW92aW5nUG9pbnQgPSBudWxsO1xuICB9XG5cbiAgZ2V0UmVhbFBvc2l0aW9ucygpOiBDYXJ0ZXNpYW4zW10ge1xuICAgIHJldHVybiB0aGlzLmdldFJlYWxQb2ludHMoKS5tYXAocG9zaXRpb24gPT4gcG9zaXRpb24uZ2V0UG9zaXRpb24oKSk7XG4gIH1cblxuICBnZXRSZWFsUG9zaXRpb25zQ2FsbGJhY2tQcm9wZXJ0eSgpOiBDYWxsYmFja1Byb3BlcnR5IHtcbiAgICByZXR1cm4gbmV3IENhbGxiYWNrUHJvcGVydHkodGhpcy5nZXRSZWFsUG9zaXRpb25zLmJpbmQodGhpcyksIGZhbHNlKTtcbiAgfVxuXG4gIGdldFJlYWxQb2ludHMoKTogRWRpdFBvaW50W10ge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocG9zaXRpb24gPT4gIXBvc2l0aW9uLmlzVmlydHVhbEVkaXRQb2ludCgpKTtcbiAgfVxuXG4gIGdldFdpZHRoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaGlwcG9kcm9tZVByb3BzLndpZHRoO1xuICB9XG5cbiAgZ2V0UG9zaXRpb25zKCk6IENhcnRlc2lhbjNbXSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zLm1hcChwb3NpdGlvbiA9PiBwb3NpdGlvbi5nZXRQb3NpdGlvbigpKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUG9zaXRpb24ocG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5wb3NpdGlvbnMuZmluZEluZGV4KHAgPT4gcCA9PT0gcG9pbnQpO1xuICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLnBvaW50c0xheWVyLnJlbW92ZShwb2ludC5nZXRJZCgpKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUG9pbnRzTGF5ZXIoLi4ucG9pbnQ6IEVkaXRQb2ludFtdKSB7XG4gICAgcG9pbnQuZm9yRWFjaChwID0+IHRoaXMucG9pbnRzTGF5ZXIudXBkYXRlKHAsIHAuZ2V0SWQoKSkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVIaXBwZHJvbWVMYXllcigpIHtcbiAgICB0aGlzLmhpcHBvZHJvbWVMYXllci51cGRhdGUodGhpcywgdGhpcy5pZCk7XG4gIH1cblxuICBkaXNwb3NlKCkge1xuICAgIHRoaXMuaGlwcG9kcm9tZUxheWVyLnJlbW92ZSh0aGlzLmlkKTtcblxuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2goZWRpdFBvaW50ID0+IHtcbiAgICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKGVkaXRQb2ludC5nZXRJZCgpKTtcbiAgICB9KTtcbiAgICBpZiAodGhpcy5tb3ZpbmdQb2ludCkge1xuICAgICAgdGhpcy5wb2ludHNMYXllci5yZW1vdmUodGhpcy5tb3ZpbmdQb2ludC5nZXRJZCgpKTtcbiAgICAgIHRoaXMubW92aW5nUG9pbnQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25zLmxlbmd0aCA9IDA7XG4gIH1cblxuICBnZXRQb2ludHNDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XG4gIH1cblxuICBnZXRJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pZDtcbiAgfVxufVxuIl19