UNPKG

angular-cesium-ivy

Version:
320 lines 48.9 kB
import { AcEntity } from '../../angular-cesium/models/ac-entity'; import { EditPoint } from './edit-point'; import { EditPolyline } from './edit-polyline'; import { GeoUtilsService } from '../../angular-cesium/services/geo-utils/geo-utils.service'; import { defaultLabelProps } from './label-props'; export class EditablePolygon extends AcEntity { constructor(id, polygonsLayer, pointsLayer, polylinesLayer, coordinateConverter, scene, polygonOptions, positions) { super(); this.id = id; this.polygonsLayer = polygonsLayer; this.pointsLayer = pointsLayer; this.polylinesLayer = polylinesLayer; this.coordinateConverter = coordinateConverter; this.scene = scene; this.polygonOptions = polygonOptions; this.positions = []; this.polylines = []; this.doneCreation = false; this._enableEdit = true; this._labels = []; this._outlineInstance = null; this.polygonProps = Object.assign({}, polygonOptions.polygonProps); this.defaultPointProps = Object.assign({}, polygonOptions.pointProps); this.defaultPolylineProps = Object.assign({}, polygonOptions.polylineProps); if (positions && positions.length >= 3) { this.createFromExisting(positions); } } 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 defaultPolylineProps() { return this._defaultPolylineProps; } set defaultPolylineProps(value) { this._defaultPolylineProps = value; } get defaultPointProps() { return this._defaultPointProps; } get polygonProps() { return this._polygonProps; } set polygonProps(value) { this._polygonProps = value; } 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(false, point); }); } createFromExisting(positions) { positions.forEach((position) => { this.addPointFromExisting(position); }); this.addAllVirtualEditPoints(); this.updatePolygonsLayer(); this.doneCreation = true; } setPointsManually(points, polygonProps) { if (!this.doneCreation) { throw new Error('Update manually only in edit mode, after polygon is created'); } this.positions.forEach(p => this.pointsLayer.remove(p.getId())); const newPoints = []; for (let i = 0; i < points.length; i++) { const pointOrCartesian = points[i]; let newPoint = null; if (pointOrCartesian.pointProps) { newPoint = new EditPoint(this.id, pointOrCartesian.position, pointOrCartesian.pointProps); } else { newPoint = new EditPoint(this.id, pointOrCartesian, this.defaultPointProps); } newPoints.push(newPoint); } this.positions = newPoints; this.polygonProps = polygonProps ? polygonProps : this.polygonProps; this.updatePointsLayer(true, ...this.positions); this.addAllVirtualEditPoints(); this.updatePolygonsLayer(); } addAllVirtualEditPoints() { const currentPoints = [...this.positions]; currentPoints.forEach((pos, index) => { const currentPoint = pos; const nextIndex = (index + 1) % (currentPoints.length); const nextPoint = currentPoints[nextIndex]; const midPoint = this.setMiddleVirtualPoint(currentPoint, nextPoint); this.updatePointsLayer(false, midPoint); }); } setMiddleVirtualPoint(firstP, secondP) { const midPointCartesian3 = Cesium.Cartesian3.lerp(firstP.getPosition(), secondP.getPosition(), 0.5, new Cesium.Cartesian3()); const midPoint = new EditPoint(this.id, midPointCartesian3, this.defaultPointProps); midPoint.setVirtualEditPoint(true); const firstIndex = this.positions.indexOf(firstP); this.positions.splice(firstIndex + 1, 0, midPoint); return midPoint; } updateMiddleVirtualPoint(virtualEditPoint, prevPoint, nextPoint) { const midPointCartesian3 = Cesium.Cartesian3.lerp(prevPoint.getPosition(), nextPoint.getPosition(), 0.5, new Cesium.Cartesian3()); virtualEditPoint.setPosition(midPointCartesian3); } changeVirtualPointToRealPoint(point) { point.setVirtualEditPoint(false); // virtual point becomes a real point const pointsCount = this.positions.length; const pointIndex = this.positions.indexOf(point); const nextIndex = (pointIndex + 1) % (pointsCount); const preIndex = ((pointIndex - 1) + pointsCount) % pointsCount; const nextPoint = this.positions[nextIndex]; const prePoint = this.positions[preIndex]; const firstMidPoint = this.setMiddleVirtualPoint(prePoint, point); const secMidPoint = this.setMiddleVirtualPoint(point, nextPoint); this.updatePointsLayer(true, firstMidPoint, secMidPoint, point); this.updatePolygonsLayer(); } renderPolylines() { const realPoints = this.positions.filter(pos => !pos.isVirtualEditPoint()); if (this.defaultPolylineProps.useGroundPrimitiveOutline) { if (realPoints.length < 2) { return; } this.scene.groundPrimitives.remove(this._outlineInstance); const instance = new Cesium.GeometryInstance({ geometry: new Cesium.GroundPolylineGeometry({ positions: this.positions.map(p => p.getPosition()), width: this.defaultPolylineProps.width, loop: true }), id: 'edit-ground-primitive-' + this.id, attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.defaultPolylineProps.material()) } }); this._outlineInstance = this.scene.groundPrimitives.add(new Cesium.GroundPolylinePrimitive({ geometryInstances: instance, asynchronous: false, appearance: new Cesium.PolylineColorAppearance() })); } else { this.polylines.forEach(polyline => this.polylinesLayer.remove(polyline.getId())); this.polylines = []; realPoints.forEach((point, index) => { const nextIndex = (index + 1) % (realPoints.length); const nextPoint = realPoints[nextIndex]; const polyline = new EditPolyline(this.id, point.getPosition(), nextPoint.getPosition(), this.defaultPolylineProps); this.polylines.push(polyline); this.polylinesLayer.update(polyline, polyline.getId()); }); } } addPointFromExisting(position) { const newPoint = new EditPoint(this.id, position, this.defaultPointProps); this.positions.push(newPoint); this.updatePointsLayer(true, newPoint); } addPoint(position) { if (this.doneCreation) { return; } const isFirstPoint = !this.positions.length; if (isFirstPoint) { const firstPoint = new EditPoint(this.id, position, this.defaultPointProps); this.positions.push(firstPoint); this.updatePointsLayer(true, firstPoint); } this.movingPoint = new EditPoint(this.id, position.clone(), this.defaultPointProps); this.positions.push(this.movingPoint); this.updatePointsLayer(true, this.movingPoint); this.updatePolygonsLayer(); } movePointFinish(editPoint) { if (this.polygonOptions.clampHeightTo3D) { editPoint.props.disableDepthTestDistance = Number.POSITIVE_INFINITY; this.updatePointsLayer(false, editPoint); } } movePoint(toPosition, editPoint) { editPoint.setPosition(toPosition); if (this.doneCreation) { if (editPoint.props.disableDepthTestDistance && this.polygonOptions.clampHeightTo3D) { // To avoid bug with pickPosition() on point with disableDepthTestDistance editPoint.props.disableDepthTestDistance = undefined; return; // ignore first move because the pickPosition() could be wrong } if (editPoint.isVirtualEditPoint()) { this.changeVirtualPointToRealPoint(editPoint); } const pointsCount = this.positions.length; const pointIndex = this.positions.indexOf(editPoint); const nextVirtualPoint = this.positions[(pointIndex + 1) % (pointsCount)]; const nextRealPoint = this.positions[(pointIndex + 2) % (pointsCount)]; const prevVirtualPoint = this.positions[((pointIndex - 1) + pointsCount) % pointsCount]; const prevRealPoint = this.positions[((pointIndex - 2) + pointsCount) % pointsCount]; this.updateMiddleVirtualPoint(nextVirtualPoint, editPoint, nextRealPoint); this.updateMiddleVirtualPoint(prevVirtualPoint, editPoint, prevRealPoint); } this.updatePolygonsLayer(); this.updatePointsLayer(true, editPoint); } moveTempMovingPoint(toPosition) { if (this.movingPoint) { this.movePoint(toPosition, this.movingPoint); } } movePolygon(startMovingPosition, draggedToPosition) { if (!this.doneCreation) { return; } if (!this.lastDraggedToPosition) { this.lastDraggedToPosition = startMovingPosition; } const delta = GeoUtilsService.getPositionsDelta(this.lastDraggedToPosition, draggedToPosition); this.positions.forEach(point => { const newPos = GeoUtilsService.addDeltaToPosition(point.getPosition(), delta, true); point.setPosition(newPos); }); this.updatePointsLayer(); this.lastDraggedToPosition = draggedToPosition; this.positions.forEach(point => this.updatePointsLayer(true, point)); } endMovePolygon() { this.lastDraggedToPosition = undefined; } removePoint(pointToRemove) { this.removePosition(pointToRemove); this.positions .filter(p => p.isVirtualEditPoint()) .forEach(p => this.removePosition(p)); this.addAllVirtualEditPoints(); this.renderPolylines(); if (this.getPointsCount() >= 3) { this.polygonsLayer.update(this, this.id); } } addLastPoint(position) { this.doneCreation = true; this.removePosition(this.movingPoint); // remove movingPoint this.movingPoint = null; this.updatePolygonsLayer(); this.addAllVirtualEditPoints(); } getRealPositions() { return this.getRealPoints().map(position => position.getPosition()); } getRealPoints() { return this.positions.filter(position => !position.isVirtualEditPoint() && position !== this.movingPoint); } getPoints() { return this.positions.filter(position => position !== this.movingPoint); } getPositionsHierarchy() { const positions = this.positions.filter(position => !position.isVirtualEditPoint()).map(position => position.getPosition().clone()); return new Cesium.PolygonHierarchy(positions); } getPositionsHierarchyCallbackProperty() { return new Cesium.CallbackProperty(this.getPositionsHierarchy.bind(this), false); } removePosition(point) { const index = this.positions.findIndex((p) => p === point); if (index < 0) { return; } this.positions.splice(index, 1); this.pointsLayer.remove(point.getId()); } updatePolygonsLayer() { if (this.getPointsCount() >= 3) { this.polygonsLayer.update(this, this.id); } } updatePointsLayer(renderPolylines = true, ...points) { if (renderPolylines) { this.renderPolylines(); } points.forEach(p => this.pointsLayer.update(p, p.getId())); } dispose() { this.polygonsLayer.remove(this.id); this.scene.groundPrimitives.remove(this._outlineInstance); this.positions.forEach(editPoint => { this.pointsLayer.remove(editPoint.getId()); }); this.polylines.forEach(line => this.polylinesLayer.remove(line.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtcG9seWdvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY2VzaXVtL3NyYy9saWIvYW5ndWxhci1jZXNpdW0td2lkZ2V0cy9tb2RlbHMvZWRpdGFibGUtcG9seWdvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFJL0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJEQUEyRCxDQUFDO0FBSTVGLE9BQU8sRUFBRSxpQkFBaUIsRUFBYyxNQUFNLGVBQWUsQ0FBQztBQUU5RCxNQUFNLE9BQU8sZUFBZ0IsU0FBUSxRQUFRO0lBYTNDLFlBQW9CLEVBQVUsRUFDVixhQUErQixFQUMvQixXQUE2QixFQUM3QixjQUFnQyxFQUNoQyxtQkFBd0MsRUFDeEMsS0FBVSxFQUNWLGNBQWtDLEVBQzFDLFNBQXdCO1FBQ2xDLEtBQUssRUFBRSxDQUFDO1FBUlUsT0FBRSxHQUFGLEVBQUUsQ0FBUTtRQUNWLGtCQUFhLEdBQWIsYUFBYSxDQUFrQjtRQUMvQixnQkFBVyxHQUFYLFdBQVcsQ0FBa0I7UUFDN0IsbUJBQWMsR0FBZCxjQUFjLENBQWtCO1FBQ2hDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsVUFBSyxHQUFMLEtBQUssQ0FBSztRQUNWLG1CQUFjLEdBQWQsY0FBYyxDQUFvQjtRQWxCOUMsY0FBUyxHQUFnQixFQUFFLENBQUM7UUFDNUIsY0FBUyxHQUFtQixFQUFFLENBQUM7UUFFL0IsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsZ0JBQVcsR0FBRyxJQUFJLENBQUM7UUFLbkIsWUFBTyxHQUFpQixFQUFFLENBQUM7UUFDM0IscUJBQWdC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QUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7U0FDOUI7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELGNBQWM7UUFDWixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQy9CLENBQUM7SUFFRCxLQUFLO1FBQ0gsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjRW50aXR5IH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vbW9kZWxzL2FjLWVudGl0eSc7XG5pbXBvcnQgeyBFZGl0UG9pbnQgfSBmcm9tICcuL2VkaXQtcG9pbnQnO1xuaW1wb3J0IHsgRWRpdFBvbHlsaW5lIH0gZnJvbSAnLi9lZGl0LXBvbHlsaW5lJztcbmltcG9ydCB7IEFjTGF5ZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9jb21wb25lbnRzL2FjLWxheWVyL2FjLWxheWVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDYXJ0ZXNpYW4zIH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vbW9kZWxzL2NhcnRlc2lhbjMnO1xuaW1wb3J0IHsgQ29vcmRpbmF0ZUNvbnZlcnRlciB9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL2Nvb3JkaW5hdGUtY29udmVydGVyL2Nvb3JkaW5hdGUtY29udmVydGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgR2VvVXRpbHNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vc2VydmljZXMvZ2VvLXV0aWxzL2dlby11dGlscy5zZXJ2aWNlJztcbmltcG9ydCB7IFBvbHlnb25FZGl0T3B0aW9ucywgUG9seWdvblByb3BzIH0gZnJvbSAnLi9wb2x5Z29uLWVkaXQtb3B0aW9ucyc7XG5pbXBvcnQgeyBQb2ludFByb3BzIH0gZnJvbSAnLi9wb2ludC1lZGl0LW9wdGlvbnMnO1xuaW1wb3J0IHsgUG9seWxpbmVQcm9wcyB9IGZyb20gJy4vcG9seWxpbmUtZWRpdC1vcHRpb25zJztcbmltcG9ydCB7IGRlZmF1bHRMYWJlbFByb3BzLCBMYWJlbFByb3BzIH0gZnJvbSAnLi9sYWJlbC1wcm9wcyc7XG5cbmV4cG9ydCBjbGFzcyBFZGl0YWJsZVBvbHlnb24gZXh0ZW5kcyBBY0VudGl0eSB7XG4gIHByaXZhdGUgcG9zaXRpb25zOiBFZGl0UG9pbnRbXSA9IFtdO1xuICBwcml2YXRlIHBvbHlsaW5lczogRWRpdFBvbHlsaW5lW10gPSBbXTtcbiAgcHJpdmF0ZSBtb3ZpbmdQb2ludDogRWRpdFBvaW50O1xuICBwcml2YXRlIGRvbmVDcmVhdGlvbiA9IGZhbHNlO1xuICBwcml2YXRlIF9lbmFibGVFZGl0ID0gdHJ1ZTtcbiAgcHJpdmF0ZSBfcG9seWdvblByb3BzOiBQb2x5Z29uUHJvcHM7XG4gIHByaXZhdGUgX2RlZmF1bHRQb2ludFByb3BzOiBQb2ludFByb3BzO1xuICBwcml2YXRlIF9kZWZhdWx0UG9seWxpbmVQcm9wczogUG9seWxpbmVQcm9wcztcbiAgcHJpdmF0ZSBsYXN0RHJhZ2dlZFRvUG9zaXRpb246IENhcnRlc2lhbjM7XG4gIHByaXZhdGUgX2xhYmVsczogTGFiZWxQcm9wc1tdID0gW107XG4gIHByaXZhdGUgX291dGxpbmVJbnN0YW5jZSA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBpZDogc3RyaW5nLFxuICAgICAgICAgICAgICBwcml2YXRlIHBvbHlnb25zTGF5ZXI6IEFjTGF5ZXJDb21wb25lbnQsXG4gICAgICAgICAgICAgIHByaXZhdGUgcG9pbnRzTGF5ZXI6IEFjTGF5ZXJDb21wb25lbnQsXG4gICAgICAgICAgICAgIHByaXZhdGUgcG9seWxpbmVzTGF5ZXI6IEFjTGF5ZXJDb21wb25lbnQsXG4gICAgICAgICAgICAgIHByaXZhdGUgY29vcmRpbmF0ZUNvbnZlcnRlcjogQ29vcmRpbmF0ZUNvbnZlcnRlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBzY2VuZTogYW55LFxuICAgICAgICAgICAgICBwcml2YXRlIHBvbHlnb25PcHRpb25zOiBQb2x5Z29uRWRpdE9wdGlvbnMsXG4gICAgICAgICAgICAgIHBvc2l0aW9ucz86IENhcnRlc2lhbjNbXSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5wb2x5Z29uUHJvcHMgPSB7Li4ucG9seWdvbk9wdGlvbnMucG9seWdvblByb3BzfTtcbiAgICB0aGlzLmRlZmF1bHRQb2ludFByb3BzID0gey4uLnBvbHlnb25PcHRpb25zLnBvaW50UHJvcHN9O1xuICAgIHRoaXMuZGVmYXVsdFBvbHlsaW5lUHJvcHMgPSB7Li4ucG9seWdvbk9wdGlvbnMucG9seWxpbmVQcm9wc307XG4gICAgaWYgKHBvc2l0aW9ucyAmJiBwb3NpdGlvbnMubGVuZ3RoID49IDMpIHtcbiAgICAgIHRoaXMuY3JlYXRlRnJvbUV4aXN0aW5nKHBvc2l0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGxhYmVscygpOiBMYWJlbFByb3BzW10ge1xuICAgIHJldHVybiB0aGlzLl9sYWJlbHM7XG4gIH1cblxuICBzZXQgbGFiZWxzKGxhYmVsczogTGFiZWxQcm9wc1tdKSB7XG4gICAgaWYgKCFsYWJlbHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9zaXRpb25zID0gdGhpcy5nZXRSZWFsUG9zaXRpb25zKCk7XG4gICAgdGhpcy5fbGFiZWxzID0gbGFiZWxzLm1hcCgobGFiZWwsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWxhYmVsLnBvc2l0aW9uKSB7XG4gICAgICAgIGxhYmVsLnBvc2l0aW9uID0gcG9zaXRpb25zW2luZGV4XTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRMYWJlbFByb3BzLCBsYWJlbCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgZGVmYXVsdFBvbHlsaW5lUHJvcHMoKTogUG9seWxpbmVQcm9wcyB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRQb2x5bGluZVByb3BzO1xuICB9XG5cbiAgc2V0IGRlZmF1bHRQb2x5bGluZVByb3BzKHZhbHVlOiBQb2x5bGluZVByb3BzKSB7XG4gICAgdGhpcy5fZGVmYXVsdFBvbHlsaW5lUHJvcHMgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBkZWZhdWx0UG9pbnRQcm9wcygpOiBQb2ludFByb3BzIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmYXVsdFBvaW50UHJvcHM7XG4gIH1cblxuICBnZXQgcG9seWdvblByb3BzKCk6IFBvbHlnb25Qcm9wcyB7XG4gICAgcmV0dXJuIHRoaXMuX3BvbHlnb25Qcm9wcztcbiAgfVxuXG4gIHNldCBwb2x5Z29uUHJvcHModmFsdWU6IFBvbHlnb25Qcm9wcykge1xuICAgIHRoaXMuX3BvbHlnb25Qcm9wcyA9IHZhbHVlO1xuICB9XG5cbiAgc2V0IGRlZmF1bHRQb2ludFByb3BzKHZhbHVlOiBQb2ludFByb3BzKSB7XG4gICAgdGhpcy5fZGVmYXVsdFBvaW50UHJvcHMgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBlbmFibGVFZGl0KCkge1xuICAgIHJldHVybiB0aGlzLl9lbmFibGVFZGl0O1xuICB9XG5cbiAgc2V0IGVuYWJsZUVkaXQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9lbmFibGVFZGl0ID0gdmFsdWU7XG4gICAgdGhpcy5wb3NpdGlvbnMuZm9yRWFjaChwb2ludCA9PiB7XG4gICAgICBwb2ludC5zaG93ID0gdmFsdWU7XG4gICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBwb2ludCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZyb21FeGlzdGluZyhwb3NpdGlvbnM6IENhcnRlc2lhbjNbXSkge1xuICAgIHBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbikgPT4ge1xuICAgICAgdGhpcy5hZGRQb2ludEZyb21FeGlzdGluZyhwb3NpdGlvbik7XG4gICAgfSk7XG4gICAgdGhpcy5hZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpO1xuICAgIHRoaXMudXBkYXRlUG9seWdvbnNMYXllcigpO1xuICAgIHRoaXMuZG9uZUNyZWF0aW9uID0gdHJ1ZTtcbiAgfVxuXG4gIHNldFBvaW50c01hbnVhbGx5KHBvaW50czogeyBwb3NpdGlvbjogQ2FydGVzaWFuMywgcG9pbnRQcm9wczogUG9pbnRQcm9wcyB9W10gfCBDYXJ0ZXNpYW4zW10sIHBvbHlnb25Qcm9wcz86IFBvbHlnb25Qcm9wcykge1xuICAgIGlmICghdGhpcy5kb25lQ3JlYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVXBkYXRlIG1hbnVhbGx5IG9ubHkgaW4gZWRpdCBtb2RlLCBhZnRlciBwb2x5Z29uIGlzIGNyZWF0ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKHAgPT4gdGhpcy5wb2ludHNMYXllci5yZW1vdmUocC5nZXRJZCgpKSk7XG4gICAgY29uc3QgbmV3UG9pbnRzOiBFZGl0UG9pbnRbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwb2ludE9yQ2FydGVzaWFuOiBhbnkgPSBwb2ludHNbaV07XG4gICAgICBsZXQgbmV3UG9pbnQgPSBudWxsO1xuICAgICAgaWYgKHBvaW50T3JDYXJ0ZXNpYW4ucG9pbnRQcm9wcykge1xuICAgICAgICBuZXdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9pbnRPckNhcnRlc2lhbi5wb3NpdGlvbiwgcG9pbnRPckNhcnRlc2lhbi5wb2ludFByb3BzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb2ludE9yQ2FydGVzaWFuLCB0aGlzLmRlZmF1bHRQb2ludFByb3BzKTtcbiAgICAgIH1cbiAgICAgIG5ld1BvaW50cy5wdXNoKG5ld1BvaW50KTtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMgPSBuZXdQb2ludHM7XG4gICAgdGhpcy5wb2x5Z29uUHJvcHMgPSBwb2x5Z29uUHJvcHMgPyBwb2x5Z29uUHJvcHMgOiB0aGlzLnBvbHlnb25Qcm9wcztcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG4gICAgdGhpcy51cGRhdGVQb2x5Z29uc0xheWVyKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCkge1xuICAgIGNvbnN0IGN1cnJlbnRQb2ludHMgPSBbLi4udGhpcy5wb3NpdGlvbnNdO1xuICAgIGN1cnJlbnRQb2ludHMuZm9yRWFjaCgocG9zLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudFBvaW50ID0gcG9zO1xuICAgICAgY29uc3QgbmV4dEluZGV4ID0gKGluZGV4ICsgMSkgJSAoY3VycmVudFBvaW50cy5sZW5ndGgpO1xuICAgICAgY29uc3QgbmV4dFBvaW50ID0gY3VycmVudFBvaW50c1tuZXh0SW5kZXhdO1xuICAgICAgY29uc3QgbWlkUG9pbnQgPSB0aGlzLnNldE1pZGRsZVZpcnR1YWxQb2ludChjdXJyZW50UG9pbnQsIG5leHRQb2ludCk7XG4gICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBtaWRQb2ludCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldE1pZGRsZVZpcnR1YWxQb2ludChmaXJzdFA6IEVkaXRQb2ludCwgc2Vjb25kUDogRWRpdFBvaW50KTogRWRpdFBvaW50IHtcbiAgICBjb25zdCBtaWRQb2ludENhcnRlc2lhbjMgPSBDZXNpdW0uQ2FydGVzaWFuMy5sZXJwKGZpcnN0UC5nZXRQb3NpdGlvbigpLCBzZWNvbmRQLmdldFBvc2l0aW9uKCksIDAuNSwgbmV3IENlc2l1bS5DYXJ0ZXNpYW4zKCkpO1xuICAgIGNvbnN0IG1pZFBvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBtaWRQb2ludENhcnRlc2lhbjMsIHRoaXMuZGVmYXVsdFBvaW50UHJvcHMpO1xuICAgIG1pZFBvaW50LnNldFZpcnR1YWxFZGl0UG9pbnQodHJ1ZSk7XG5cbiAgICBjb25zdCBmaXJzdEluZGV4ID0gdGhpcy5wb3NpdGlvbnMuaW5kZXhPZihmaXJzdFApO1xuICAgIHRoaXMucG9zaXRpb25zLnNwbGljZShmaXJzdEluZGV4ICsgMSwgMCwgbWlkUG9pbnQpO1xuICAgIHJldHVybiBtaWRQb2ludDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KHZpcnR1YWxFZGl0UG9pbnQ6IEVkaXRQb2ludCwgcHJldlBvaW50OiBFZGl0UG9pbnQsIG5leHRQb2ludDogRWRpdFBvaW50KSB7XG4gICAgY29uc3QgbWlkUG9pbnRDYXJ0ZXNpYW4zID0gQ2VzaXVtLkNhcnRlc2lhbjMubGVycChwcmV2UG9pbnQuZ2V0UG9zaXRpb24oKSwgbmV4dFBvaW50LmdldFBvc2l0aW9uKCksIDAuNSwgbmV3IENlc2l1bS5DYXJ0ZXNpYW4zKCkpO1xuICAgIHZpcnR1YWxFZGl0UG9pbnQuc2V0UG9zaXRpb24obWlkUG9pbnRDYXJ0ZXNpYW4zKTtcbiAgfVxuXG4gIGNoYW5nZVZpcnR1YWxQb2ludFRvUmVhbFBvaW50KHBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBwb2ludC5zZXRWaXJ0dWFsRWRpdFBvaW50KGZhbHNlKTsgLy8gdmlydHVhbCBwb2ludCBiZWNvbWVzIGEgcmVhbCBwb2ludFxuICAgIGNvbnN0IHBvaW50c0NvdW50ID0gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xuICAgIGNvbnN0IHBvaW50SW5kZXggPSB0aGlzLnBvc2l0aW9ucy5pbmRleE9mKHBvaW50KTtcbiAgICBjb25zdCBuZXh0SW5kZXggPSAocG9pbnRJbmRleCArIDEpICUgKHBvaW50c0NvdW50KTtcbiAgICBjb25zdCBwcmVJbmRleCA9ICgocG9pbnRJbmRleCAtIDEpICsgcG9pbnRzQ291bnQpICUgcG9pbnRzQ291bnQ7XG5cbiAgICBjb25zdCBuZXh0UG9pbnQgPSB0aGlzLnBvc2l0aW9uc1tuZXh0SW5kZXhdO1xuICAgIGNvbnN0IHByZVBvaW50ID0gdGhpcy5wb3NpdGlvbnNbcHJlSW5kZXhdO1xuXG4gICAgY29uc3QgZmlyc3RNaWRQb2ludCA9IHRoaXMuc2V0TWlkZGxlVmlydHVhbFBvaW50KHByZVBvaW50LCBwb2ludCk7XG4gICAgY29uc3Qgc2VjTWlkUG9pbnQgPSB0aGlzLnNldE1pZGRsZVZpcnR1YWxQb2ludChwb2ludCwgbmV4dFBvaW50KTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIGZpcnN0TWlkUG9pbnQsIHNlY01pZFBvaW50LCBwb2ludCk7XG4gICAgdGhpcy51cGRhdGVQb2x5Z29uc0xheWVyKCk7XG5cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyUG9seWxpbmVzKCkge1xuICAgIGNvbnN0IHJlYWxQb2ludHMgPSB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocG9zID0+ICFwb3MuaXNWaXJ0dWFsRWRpdFBvaW50KCkpO1xuICAgIGlmICh0aGlzLmRlZmF1bHRQb2x5bGluZVByb3BzLnVzZUdyb3VuZFByaW1pdGl2ZU91dGxpbmUpIHtcbiAgICAgIGlmIChyZWFsUG9pbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zY2VuZS5ncm91bmRQcmltaXRpdmVzLnJlbW92ZSh0aGlzLl9vdXRsaW5lSW5zdGFuY2UpO1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgQ2VzaXVtLkdlb21ldHJ5SW5zdGFuY2Uoe1xuICAgICAgICBnZW9tZXRyeTogbmV3IENlc2l1bS5Hcm91bmRQb2x5bGluZUdlb21ldHJ5KHtcbiAgICAgICAgICBwb3NpdGlvbnM6IHRoaXMucG9zaXRpb25zLm1hcChwID0+IHAuZ2V0UG9zaXRpb24oKSksXG4gICAgICAgICAgd2lkdGg6IHRoaXMuZGVmYXVsdFBvbHlsaW5lUHJvcHMud2lkdGgsXG4gICAgICAgICAgbG9vcDogdHJ1ZVxuICAgICAgICB9KSxcbiAgICAgICAgaWQ6ICdlZGl0LWdyb3VuZC1wcmltaXRpdmUtJyArIHRoaXMuaWQsXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICBjb2xvcjogQ2VzaXVtLkNvbG9yR2VvbWV0cnlJbnN0YW5jZUF0dHJpYnV0ZS5mcm9tQ29sb3IodGhpcy5kZWZhdWx0UG9seWxpbmVQcm9wcy5tYXRlcmlhbCgpKVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX291dGxpbmVJbnN0YW5jZSA9IHRoaXMuc2NlbmUuZ3JvdW5kUHJpbWl0aXZlcy5hZGQoXG4gICAgICAgIG5ldyBDZXNpdW0uR3JvdW5kUG9seWxpbmVQcmltaXRpdmUoe1xuICAgICAgICAgIGdlb21ldHJ5SW5zdGFuY2VzOiBpbnN0YW5jZSxcbiAgICAgICAgICBhc3luY2hyb25vdXM6IGZhbHNlLFxuICAgICAgICAgIGFwcGVhcmFuY2U6IG5ldyBDZXNpdW0uUG9seWxpbmVDb2xvckFwcGVhcmFuY2UoKVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wb2x5bGluZXMuZm9yRWFjaChwb2x5bGluZSA9PiB0aGlzLnBvbHlsaW5lc0xheWVyLnJlbW92ZShwb2x5bGluZS5nZXRJZCgpKSk7XG4gICAgICB0aGlzLnBvbHlsaW5lcyA9IFtdO1xuICAgICAgcmVhbFBvaW50cy5mb3JFYWNoKChwb2ludCwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgbmV4dEluZGV4ID0gKGluZGV4ICsgMSkgJSAocmVhbFBvaW50cy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBuZXh0UG9pbnQgPSByZWFsUG9pbnRzW25leHRJbmRleF07XG4gICAgICAgIGNvbnN0IHBvbHlsaW5lID0gbmV3IEVkaXRQb2x5bGluZSh0aGlzLmlkLCBwb2ludC5nZXRQb3NpdGlvbigpLCBuZXh0UG9pbnQuZ2V0UG9zaXRpb24oKSwgdGhpcy5kZWZhdWx0UG9seWxpbmVQcm9wcyk7XG4gICAgICAgIHRoaXMucG9seWxpbmVzLnB1c2gocG9seWxpbmUpO1xuICAgICAgICB0aGlzLnBvbHlsaW5lc0xheWVyLnVwZGF0ZShwb2x5bGluZSwgcG9seWxpbmUuZ2V0SWQoKSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBhZGRQb2ludEZyb21FeGlzdGluZyhwb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIGNvbnN0IG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbiwgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaChuZXdQb2ludCk7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCBuZXdQb2ludCk7XG4gIH1cblxuXG4gIGFkZFBvaW50KHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgaWYgKHRoaXMuZG9uZUNyZWF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGlzRmlyc3RQb2ludCA9ICF0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XG4gICAgaWYgKGlzRmlyc3RQb2ludCkge1xuICAgICAgY29uc3QgZmlyc3RQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24sIHRoaXMuZGVmYXVsdFBvaW50UHJvcHMpO1xuICAgICAgdGhpcy5wb3NpdGlvbnMucHVzaChmaXJzdFBvaW50KTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgZmlyc3RQb2ludCk7XG4gICAgfVxuXG4gICAgdGhpcy5tb3ZpbmdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24uY2xvbmUoKSwgdGhpcy5kZWZhdWx0UG9pbnRQcm9wcyk7XG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaCh0aGlzLm1vdmluZ1BvaW50KTtcblxuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgdGhpcy5tb3ZpbmdQb2ludCk7XG4gICAgdGhpcy51cGRhdGVQb2x5Z29uc0xheWVyKCk7XG4gIH1cblxuICBtb3ZlUG9pbnRGaW5pc2goZWRpdFBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBpZiAodGhpcy5wb2x5Z29uT3B0aW9ucy5jbGFtcEhlaWdodFRvM0QpIHtcbiAgICAgIGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBlZGl0UG9pbnQpO1xuICAgIH1cbiAgfVxuXG4gIG1vdmVQb2ludCh0b1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zLCBlZGl0UG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGVkaXRQb2ludC5zZXRQb3NpdGlvbih0b1Bvc2l0aW9uKTtcbiAgICBpZiAodGhpcy5kb25lQ3JlYXRpb24pIHtcbiAgICAgIGlmIChlZGl0UG9pbnQucHJvcHMuZGlzYWJsZURlcHRoVGVzdERpc3RhbmNlICYmIHRoaXMucG9seWdvbk9wdGlvbnMuY2xhbXBIZWlnaHRUbzNEKSB7XG4gICAgICAgIC8vIFRvIGF2b2lkIGJ1ZyB3aXRoIHBpY2tQb3NpdGlvbigpIG9uIHBvaW50IHdpdGggZGlzYWJsZURlcHRoVGVzdERpc3RhbmNlXG4gICAgICAgIGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybjsgLy8gaWdub3JlIGZpcnN0IG1vdmUgYmVjYXVzZSB0aGUgcGlja1Bvc2l0aW9uKCkgY291bGQgYmUgd3JvbmdcbiAgICAgIH1cblxuICAgICAgaWYgKGVkaXRQb2ludC5pc1ZpcnR1YWxFZGl0UG9pbnQoKSkge1xuICAgICAgICB0aGlzLmNoYW5nZVZpcnR1YWxQb2ludFRvUmVhbFBvaW50KGVkaXRQb2ludCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwb2ludHNDb3VudCA9IHRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICAgIGNvbnN0IHBvaW50SW5kZXggPSB0aGlzLnBvc2l0aW9ucy5pbmRleE9mKGVkaXRQb2ludCk7XG4gICAgICBjb25zdCBuZXh0VmlydHVhbFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbKHBvaW50SW5kZXggKyAxKSAlIChwb2ludHNDb3VudCldO1xuICAgICAgY29uc3QgbmV4dFJlYWxQb2ludCA9IHRoaXMucG9zaXRpb25zWyhwb2ludEluZGV4ICsgMikgJSAocG9pbnRzQ291bnQpXTtcbiAgICAgIGNvbnN0IHByZXZWaXJ0dWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1soKHBvaW50SW5kZXggLSAxKSArIHBvaW50c0NvdW50KSAlIHBvaW50c0NvdW50XTtcbiAgICAgIGNvbnN0IHByZXZSZWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1soKHBvaW50SW5kZXggLSAyKSArIHBvaW50c0NvdW50KSAlIHBvaW50c0NvdW50XTtcbiAgICAgIHRoaXMudXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KG5leHRWaXJ0dWFsUG9pbnQsIGVkaXRQb2ludCwgbmV4dFJlYWxQb2ludCk7XG4gICAgICB0aGlzLnVwZGF0ZU1pZGRsZVZpcnR1YWxQb2ludChwcmV2VmlydHVhbFBvaW50LCBlZGl0UG9pbnQsIHByZXZSZWFsUG9pbnQpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVBvbHlnb25zTGF5ZXIoKTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIGVkaXRQb2ludCk7XG4gIH1cblxuICBtb3ZlVGVtcE1vdmluZ1BvaW50KHRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAodGhpcy5tb3ZpbmdQb2ludCkge1xuICAgICAgdGhpcy5tb3ZlUG9pbnQodG9Qb3NpdGlvbiwgdGhpcy5tb3ZpbmdQb2ludCk7XG4gICAgfVxuICB9XG5cbiAgbW92ZVBvbHlnb24oc3RhcnRNb3ZpbmdQb3NpdGlvbjogQ2FydGVzaWFuMywgZHJhZ2dlZFRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAoIXRoaXMuZG9uZUNyZWF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24pIHtcbiAgICAgIHRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uID0gc3RhcnRNb3ZpbmdQb3NpdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWx0YSA9IEdlb1V0aWxzU2VydmljZS5nZXRQb3NpdGlvbnNEZWx0YSh0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiwgZHJhZ2dlZFRvUG9zaXRpb24pO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4ge1xuICAgICAgY29uc3QgbmV3UG9zID0gR2VvVXRpbHNTZXJ2aWNlLmFkZERlbHRhVG9Qb3NpdGlvbihwb2ludC5nZXRQb3NpdGlvbigpLCBkZWx0YSwgdHJ1ZSk7XG4gICAgICBwb2ludC5zZXRQb3NpdGlvbihuZXdQb3MpO1xuICAgIH0pO1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoKTtcbiAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IGRyYWdnZWRUb1Bvc2l0aW9uO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4gdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCBwb2ludCkpO1xuICB9XG5cbiAgZW5kTW92ZVBvbHlnb24oKSB7XG4gICAgdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24gPSB1bmRlZmluZWQ7XG4gIH1cblxuICByZW1vdmVQb2ludChwb2ludFRvUmVtb3ZlOiBFZGl0UG9pbnQpIHtcbiAgICB0aGlzLnJlbW92ZVBvc2l0aW9uKHBvaW50VG9SZW1vdmUpO1xuICAgIHRoaXMucG9zaXRpb25zXG4gICAgICAuZmlsdGVyKHAgPT4gcC5pc1ZpcnR1YWxFZGl0UG9pbnQoKSlcbiAgICAgIC5mb3JFYWNoKHAgPT4gdGhpcy5yZW1vdmVQb3NpdGlvbihwKSk7XG4gICAgdGhpcy5hZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpO1xuXG4gICAgdGhpcy5yZW5kZXJQb2x5bGluZXMoKTtcbiAgICBpZiAodGhpcy5nZXRQb2ludHNDb3VudCgpID49IDMpIHtcbiAgICAgIHRoaXMucG9seWdvbnNMYXllci51cGRhdGUodGhpcywgdGhpcy5pZCk7XG4gICAgfVxuICB9XG5cbiAgYWRkTGFzdFBvaW50KHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgdGhpcy5kb25lQ3JlYXRpb24gPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlUG9zaXRpb24odGhpcy5tb3ZpbmdQb2ludCk7IC8vIHJlbW92ZSBtb3ZpbmdQb2ludFxuICAgIHRoaXMubW92aW5nUG9pbnQgPSBudWxsO1xuICAgIHRoaXMudXBkYXRlUG9seWdvbnNMYXllcigpO1xuXG4gICAgdGhpcy5hZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpO1xuICB9XG5cbiAgZ2V0UmVhbFBvc2l0aW9ucygpOiBDYXJ0ZXNpYW4zW10ge1xuICAgIHJldHVybiB0aGlzLmdldFJlYWxQb2ludHMoKS5tYXAocG9zaXRpb24gPT4gcG9zaXRpb24uZ2V0UG9zaXRpb24oKSk7XG4gIH1cblxuICBnZXRSZWFsUG9pbnRzKCk6IEVkaXRQb2ludFtdIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMuZmlsdGVyKHBvc2l0aW9uID0+ICFwb3NpdGlvbi5pc1ZpcnR1YWxFZGl0UG9pbnQoKSAmJiBwb3NpdGlvbiAhPT0gdGhpcy5tb3ZpbmdQb2ludCk7XG4gIH1cblxuICBnZXRQb2ludHMoKTogRWRpdFBvaW50W10ge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocG9zaXRpb24gPT4gcG9zaXRpb24gIT09IHRoaXMubW92aW5nUG9pbnQpO1xuICB9XG5cbiAgZ2V0UG9zaXRpb25zSGllcmFyY2h5KCk6IENhcnRlc2lhbjNbXSB7XG4gICAgY29uc3QgcG9zaXRpb25zID0gdGhpcy5wb3NpdGlvbnMuZmlsdGVyKHBvc2l0aW9uID0+ICFwb3NpdGlvbi5pc1ZpcnR1YWxFZGl0UG9pbnQoKSkubWFwKHBvc2l0aW9uID0+IHBvc2l0aW9uLmdldFBvc2l0aW9uKCkuY2xvbmUoKSk7XG4gICAgcmV0dXJuIG5ldyBDZXNpdW0uUG9seWdvbkhpZXJhcmNoeShwb3NpdGlvbnMpO1xuICB9XG5cbiAgZ2V0UG9zaXRpb25zSGllcmFyY2h5Q2FsbGJhY2tQcm9wZXJ0eSgpOiBDYXJ0ZXNpYW4zW10ge1xuICAgIHJldHVybiBuZXcgQ2VzaXVtLkNhbGxiYWNrUHJvcGVydHkodGhpcy5nZXRQb3NpdGlvbnNIaWVyYXJjaHkuYmluZCh0aGlzKSwgZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVQb3NpdGlvbihwb2ludDogRWRpdFBvaW50KSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnBvc2l0aW9ucy5maW5kSW5kZXgoKHApID0+IHAgPT09IHBvaW50KTtcbiAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25zLnNwbGljZShpbmRleCwgMSk7XG4gICAgdGhpcy5wb2ludHNMYXllci5yZW1vdmUocG9pbnQuZ2V0SWQoKSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBvbHlnb25zTGF5ZXIoKSB7XG4gICAgaWYgKHRoaXMuZ2V0UG9pbnRzQ291bnQoKSA+PSAzKSB7XG4gICAgICB0aGlzLnBvbHlnb25zTGF5ZXIudXBkYXRlKHRoaXMsIHRoaXMuaWQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUG9pbnRzTGF5ZXIocmVuZGVyUG9seWxpbmVzID0gdHJ1ZSwgLi4ucG9pbnRzOiBFZGl0UG9pbnRbXSkge1xuICAgIGlmIChyZW5kZXJQb2x5bGluZXMpIHtcbiAgICAgIHRoaXMucmVuZGVyUG9seWxpbmVzKCk7XG4gICAgfVxuICAgIHBvaW50cy5mb3JFYWNoKHAgPT4gdGhpcy5wb2ludHNMYXllci51cGRhdGUocCwgcC5nZXRJZCgpKSk7XG4gIH1cblxuICBkaXNwb3NlKCkge1xuICAgIHRoaXMucG9seWdvbnNMYXllci5yZW1vdmUodGhpcy5pZCk7XG4gICAgdGhpcy5zY2VuZS5ncm91bmRQcmltaXRpdmVzLnJlbW92ZSh0aGlzLl9vdXRsaW5lSW5zdGFuY2UpO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2goZWRpdFBvaW50ID0+IHtcbiAgICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKGVkaXRQb2ludC5nZXRJZCgpKTtcbiAgICB9KTtcbiAgICB0aGlzLnBvbHlsaW5lcy5mb3JFYWNoKGxpbmUgPT4gdGhpcy5wb2x5bGluZXNMYXllci5yZW1vdmUobGluZS5nZXRJZCgpKSk7XG4gICAgaWYgKHRoaXMubW92aW5nUG9pbnQpIHtcbiAgICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHRoaXMubW92aW5nUG9pbnQuZ2V0SWQoKSk7XG4gICAgICB0aGlzLm1vdmluZ1BvaW50ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9ucy5sZW5ndGggPSAwO1xuICB9XG5cbiAgZ2V0UG9pbnRzQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xuICB9XG5cbiAgZ2V0SWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaWQ7XG4gIH1cbn1cbiJdfQ==