UNPKG

angular-cesium-ivy

Version:
309 lines 46.1 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 EditablePolyline extends AcEntity { constructor(id, pointsLayer, polylinesLayer, coordinateConverter, scene, editOptions, positions) { super(); this.id = id; this.pointsLayer = pointsLayer; this.polylinesLayer = polylinesLayer; this.coordinateConverter = coordinateConverter; this.scene = scene; this.editOptions = editOptions; this.positions = []; this.polylines = []; this.doneCreation = false; this._enableEdit = true; this._labels = []; this._outlineInstance = null; this._pointProps = Object.assign({}, editOptions.pointProps); this.props = Object.assign({}, editOptions.polylineProps); if (positions && positions.length >= 2) { 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 props() { return this.polylineProps; } set props(value) { this.polylineProps = value; } get pointProps() { return this._pointProps; } set pointProps(value) { this._pointProps = 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.doneCreation = true; } setManually(points, polylineProps) { if (!this.doneCreation) { throw new Error('Update manually only in edit mode, after polyline 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._pointProps); } newPoints.push(newPoint); } this.positions = newPoints; this.polylineProps = polylineProps ? polylineProps : this.polylineProps; this.updatePointsLayer(true, ...this.positions); this.addAllVirtualEditPoints(); } addAllVirtualEditPoints() { const currentPoints = [...this.positions]; currentPoints.forEach((pos, index) => { if (index !== currentPoints.length - 1) { 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._pointProps); 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); // actual 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(false, firstMidPoint, secMidPoint, point); } renderPolylines() { const realPoints = this.positions.filter(point => !point.isVirtualEditPoint()); if (this.polylineProps.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.polylineProps.width, loop: false }), id: 'edit-polygon-outline-' + this.id, attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.polylineProps.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) => { if (index !== realPoints.length - 1) { const nextIndex = (index + 1); const nextPoint = realPoints[nextIndex]; const polyline = new EditPolyline(this.id, point.getPosition(), nextPoint.getPosition(), this.polylineProps); this.polylines.push(polyline); this.polylinesLayer.update(polyline, polyline.getId()); } }); } } addPointFromExisting(position) { const newPoint = new EditPoint(this.id, position, this._pointProps); 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._pointProps); this.positions.push(firstPoint); this.updatePointsLayer(true, firstPoint); } this.movingPoint = new EditPoint(this.id, position.clone(), this._pointProps); this.positions.push(this.movingPoint); this.updatePointsLayer(true, this.movingPoint); } movePointFinish(editPoint) { if (this.editOptions.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.editOptions.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); if (pointIndex < this.positions.length - 1) { const nextVirtualPoint = this.positions[(pointIndex + 1) % (pointsCount)]; const nextRealPoint = this.positions[(pointIndex + 2) % (pointsCount)]; this.updateMiddleVirtualPoint(nextVirtualPoint, editPoint, nextRealPoint); } if (pointIndex > 0) { const prevVirtualPoint = this.positions[((pointIndex - 1) + pointsCount) % pointsCount]; const prevRealPoint = this.positions[((pointIndex - 2) + pointsCount) % pointsCount]; this.updateMiddleVirtualPoint(prevVirtualPoint, editPoint, prevRealPoint); } } this.updatePointsLayer(true, editPoint); } moveTempMovingPoint(toPosition) { if (this.movingPoint) { this.movePoint(toPosition, this.movingPoint); } } moveShape(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(true, ...this.positions); this.lastDraggedToPosition = draggedToPosition; } endMoveShape() { this.lastDraggedToPosition = undefined; this.updatePointsLayer(true, ...this.positions); } removePoint(pointToRemove) { this.removePosition(pointToRemove); this.positions .filter(p => p.isVirtualEditPoint()) .forEach(p => this.removePosition(p)); this.addAllVirtualEditPoints(); this.renderPolylines(); } addLastPoint(position) { this.doneCreation = true; this.removePosition(this.movingPoint); // remove movingPoint this.movingPoint = null; 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); } getPositions() { return this.positions.map(position => position.getPosition()); } getPositionsCallbackProperty() { return new Cesium.CallbackProperty(this.getPositions.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()); } updatePointsLayer(renderPolylines = true, ...point) { if (renderPolylines) { this.renderPolylines(); } point.forEach(p => this.pointsLayer.update(p, p.getId())); } update() { this.updatePointsLayer(); } dispose() { 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtcG9seWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNlc2l1bS9zcmMvbGliL2FuZ3VsYXItY2VzaXVtLXdpZGdldHMvbW9kZWxzL2VkaXRhYmxlLXBvbHlsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQU0vQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkRBQTJELENBQUM7QUFDNUYsT0FBTyxFQUFFLGlCQUFpQixFQUFjLE1BQU0sZUFBZSxDQUFDO0FBRTlELE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxRQUFRO0lBYTVDLFlBQW9CLEVBQVUsRUFDVixXQUE2QixFQUM3QixjQUFnQyxFQUNoQyxtQkFBd0MsRUFDeEMsS0FBVSxFQUNWLFdBQWdDLEVBQ3hDLFNBQXdCO1FBQ2xDLEtBQUssRUFBRSxDQUFDO1FBUFUsT0FBRSxHQUFGLEVBQUUsQ0FBUTtRQUNWLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtRQUM3QixtQkFBYyxHQUFkLGNBQWMsQ0FBa0I7UUFDaEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QyxVQUFLLEdBQUwsS0FBSyxDQUFLO1FBQ1YsZ0JBQVcsR0FBWCxXQUFXLENBQXFCO1FBakI1QyxjQUFTLEdBQWdCLEVBQUUsQ0FBQztRQUU1QixjQUFTLEdBQW1CLEVBQUUsQ0FBQztRQUUvQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixnQkFBVyxHQUFHLElBQUksQ0FBQztRQUluQixZQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUMzQixxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFVOUIsSUFBSSxDQUFDLFdBQVcs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LENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNwQixJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7U0FDOUI7UUFDRCxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELGNBQWM7UUFDWixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQy9CLENBQUM7SUFFRCxLQUFLO1FBQ0gsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjRW50aXR5IH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vbW9kZWxzL2FjLWVudGl0eSc7XG5pbXBvcnQgeyBFZGl0UG9pbnQgfSBmcm9tICcuL2VkaXQtcG9pbnQnO1xuaW1wb3J0IHsgRWRpdFBvbHlsaW5lIH0gZnJvbSAnLi9lZGl0LXBvbHlsaW5lJztcbmltcG9ydCB7IEFjTGF5ZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9jb21wb25lbnRzL2FjLWxheWVyL2FjLWxheWVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDYXJ0ZXNpYW4zIH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vbW9kZWxzL2NhcnRlc2lhbjMnO1xuaW1wb3J0IHsgQ29vcmRpbmF0ZUNvbnZlcnRlciB9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL2Nvb3JkaW5hdGUtY29udmVydGVyL2Nvb3JkaW5hdGUtY29udmVydGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgUG9pbnRQcm9wcyB9IGZyb20gJy4vcG9pbnQtZWRpdC1vcHRpb25zJztcbmltcG9ydCB7IFBvbHlsaW5lRWRpdE9wdGlvbnMsIFBvbHlsaW5lUHJvcHMgfSBmcm9tICcuL3BvbHlsaW5lLWVkaXQtb3B0aW9ucyc7XG5pbXBvcnQgeyBHZW9VdGlsc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9nZW8tdXRpbHMvZ2VvLXV0aWxzLnNlcnZpY2UnO1xuaW1wb3J0IHsgZGVmYXVsdExhYmVsUHJvcHMsIExhYmVsUHJvcHMgfSBmcm9tICcuL2xhYmVsLXByb3BzJztcblxuZXhwb3J0IGNsYXNzIEVkaXRhYmxlUG9seWxpbmUgZXh0ZW5kcyBBY0VudGl0eSB7XG4gIHByaXZhdGUgcG9zaXRpb25zOiBFZGl0UG9pbnRbXSA9IFtdO1xuXG4gIHByaXZhdGUgcG9seWxpbmVzOiBFZGl0UG9seWxpbmVbXSA9IFtdO1xuICBwcml2YXRlIG1vdmluZ1BvaW50OiBFZGl0UG9pbnQ7XG4gIHByaXZhdGUgZG9uZUNyZWF0aW9uID0gZmFsc2U7XG4gIHByaXZhdGUgX2VuYWJsZUVkaXQgPSB0cnVlO1xuICBwcml2YXRlIF9wb2ludFByb3BzOiBQb2ludFByb3BzO1xuICBwcml2YXRlIHBvbHlsaW5lUHJvcHM6IFBvbHlsaW5lUHJvcHM7XG4gIHByaXZhdGUgbGFzdERyYWdnZWRUb1Bvc2l0aW9uOiBhbnk7XG4gIHByaXZhdGUgX2xhYmVsczogTGFiZWxQcm9wc1tdID0gW107XG4gIHByaXZhdGUgX291dGxpbmVJbnN0YW5jZSA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBpZDogc3RyaW5nLFxuICAgICAgICAgICAgICBwcml2YXRlIHBvaW50c0xheWVyOiBBY0xheWVyQ29tcG9uZW50LFxuICAgICAgICAgICAgICBwcml2YXRlIHBvbHlsaW5lc0xheWVyOiBBY0xheWVyQ29tcG9uZW50LFxuICAgICAgICAgICAgICBwcml2YXRlIGNvb3JkaW5hdGVDb252ZXJ0ZXI6IENvb3JkaW5hdGVDb252ZXJ0ZXIsXG4gICAgICAgICAgICAgIHByaXZhdGUgc2NlbmU6IGFueSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBlZGl0T3B0aW9uczogUG9seWxpbmVFZGl0T3B0aW9ucyxcbiAgICAgICAgICAgICAgcG9zaXRpb25zPzogQ2FydGVzaWFuM1tdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9wb2ludFByb3BzID0gey4uLmVkaXRPcHRpb25zLnBvaW50UHJvcHN9O1xuICAgIHRoaXMucHJvcHMgPSB7Li4uZWRpdE9wdGlvbnMucG9seWxpbmVQcm9wc307XG4gICAgaWYgKHBvc2l0aW9ucyAmJiBwb3NpdGlvbnMubGVuZ3RoID49IDIpIHtcbiAgICAgIHRoaXMuY3JlYXRlRnJvbUV4aXN0aW5nKHBvc2l0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGxhYmVscygpOiBMYWJlbFByb3BzW10ge1xuICAgIHJldHVybiB0aGlzLl9sYWJlbHM7XG4gIH1cblxuICBzZXQgbGFiZWxzKGxhYmVsczogTGFiZWxQcm9wc1tdKSB7XG4gICAgaWYgKCFsYWJlbHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcG9zaXRpb25zID0gdGhpcy5nZXRSZWFsUG9zaXRpb25zKCk7XG4gICAgdGhpcy5fbGFiZWxzID0gbGFiZWxzLm1hcCgobGFiZWwsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWxhYmVsLnBvc2l0aW9uKSB7XG4gICAgICAgIGxhYmVsLnBvc2l0aW9uID0gcG9zaXRpb25zW2luZGV4XTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRMYWJlbFByb3BzLCBsYWJlbCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgcHJvcHMoKTogUG9seWxpbmVQcm9wcyB7XG4gICAgcmV0dXJuIHRoaXMucG9seWxpbmVQcm9wcztcbiAgfVxuXG4gIHNldCBwcm9wcyh2YWx1ZTogUG9seWxpbmVQcm9wcykge1xuICAgIHRoaXMucG9seWxpbmVQcm9wcyA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHBvaW50UHJvcHMoKTogUG9pbnRQcm9wcyB7XG4gICAgcmV0dXJuIHRoaXMuX3BvaW50UHJvcHM7XG4gIH1cblxuICBzZXQgcG9pbnRQcm9wcyh2YWx1ZTogUG9pbnRQcm9wcykge1xuICAgIHRoaXMuX3BvaW50UHJvcHMgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBlbmFibGVFZGl0KCkge1xuICAgIHJldHVybiB0aGlzLl9lbmFibGVFZGl0O1xuICB9XG5cbiAgc2V0IGVuYWJsZUVkaXQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9lbmFibGVFZGl0ID0gdmFsdWU7XG4gICAgdGhpcy5wb3NpdGlvbnMuZm9yRWFjaChwb2ludCA9PiB7XG4gICAgICBwb2ludC5zaG93ID0gdmFsdWU7XG4gICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBwb2ludCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZyb21FeGlzdGluZyhwb3NpdGlvbnM6IENhcnRlc2lhbjNbXSkge1xuICAgIHBvc2l0aW9ucy5mb3JFYWNoKChwb3NpdGlvbikgPT4ge1xuICAgICAgdGhpcy5hZGRQb2ludEZyb21FeGlzdGluZyhwb3NpdGlvbik7XG4gICAgfSk7XG4gICAgdGhpcy5hZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpO1xuICAgIHRoaXMuZG9uZUNyZWF0aW9uID0gdHJ1ZTtcbiAgfVxuXG4gIHNldE1hbnVhbGx5KHBvaW50czoge1xuICAgIHBvc2l0aW9uOiBDYXJ0ZXNpYW4zLFxuICAgIHBvaW50UHJvcD86IFBvaW50UHJvcHNcbiAgfVtdIHwgQ2FydGVzaWFuM1tdLCBwb2x5bGluZVByb3BzPzogUG9seWxpbmVQcm9wcykge1xuICAgIGlmICghdGhpcy5kb25lQ3JlYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVXBkYXRlIG1hbnVhbGx5IG9ubHkgaW4gZWRpdCBtb2RlLCBhZnRlciBwb2x5bGluZSBpcyBjcmVhdGVkJyk7XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocCA9PiB0aGlzLnBvaW50c0xheWVyLnJlbW92ZShwLmdldElkKCkpKTtcblxuICAgIGNvbnN0IG5ld1BvaW50czogRWRpdFBvaW50W10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcG9pbnRPckNhcnRlc2lhbjogYW55ID0gcG9pbnRzW2ldO1xuICAgICAgbGV0IG5ld1BvaW50ID0gbnVsbDtcbiAgICAgIGlmIChwb2ludE9yQ2FydGVzaWFuLnBvaW50UHJvcHMpIHtcbiAgICAgICAgbmV3UG9pbnQgPSBuZXcgRWRpdFBvaW50KHRoaXMuaWQsIHBvaW50T3JDYXJ0ZXNpYW4ucG9zaXRpb24sIHBvaW50T3JDYXJ0ZXNpYW4ucG9pbnRQcm9wcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9pbnRPckNhcnRlc2lhbiwgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgICB9XG4gICAgICBuZXdQb2ludHMucHVzaChuZXdQb2ludCk7XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25zID0gbmV3UG9pbnRzO1xuICAgIHRoaXMucG9seWxpbmVQcm9wcyA9IHBvbHlsaW5lUHJvcHMgPyBwb2x5bGluZVByb3BzIDogdGhpcy5wb2x5bGluZVByb3BzO1xuXG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCAuLi50aGlzLnBvc2l0aW9ucyk7XG4gICAgdGhpcy5hZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpIHtcbiAgICBjb25zdCBjdXJyZW50UG9pbnRzID0gWy4uLnRoaXMucG9zaXRpb25zXTtcbiAgICBjdXJyZW50UG9pbnRzLmZvckVhY2goKHBvcywgaW5kZXgpID0+IHtcbiAgICAgIGlmIChpbmRleCAhPT0gY3VycmVudFBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQb2ludCA9IHBvcztcbiAgICAgICAgY29uc3QgbmV4dEluZGV4ID0gKGluZGV4ICsgMSkgJSAoY3VycmVudFBvaW50cy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBuZXh0UG9pbnQgPSBjdXJyZW50UG9pbnRzW25leHRJbmRleF07XG5cbiAgICAgICAgY29uc3QgbWlkUG9pbnQgPSB0aGlzLnNldE1pZGRsZVZpcnR1YWxQb2ludChjdXJyZW50UG9pbnQsIG5leHRQb2ludCk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVQb2ludHNMYXllcihmYWxzZSwgbWlkUG9pbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRNaWRkbGVWaXJ0dWFsUG9pbnQoZmlyc3RQOiBFZGl0UG9pbnQsIHNlY29uZFA6IEVkaXRQb2ludCk6IEVkaXRQb2ludCB7XG4gICAgY29uc3QgbWlkUG9pbnRDYXJ0ZXNpYW4zID0gQ2VzaXVtLkNhcnRlc2lhbjMubGVycChmaXJzdFAuZ2V0UG9zaXRpb24oKSwgc2Vjb25kUC5nZXRQb3NpdGlvbigpLCAwLjUsIG5ldyBDZXNpdW0uQ2FydGVzaWFuMygpKTtcbiAgICBjb25zdCBtaWRQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgbWlkUG9pbnRDYXJ0ZXNpYW4zLCB0aGlzLl9wb2ludFByb3BzKTtcbiAgICBtaWRQb2ludC5zZXRWaXJ0dWFsRWRpdFBvaW50KHRydWUpO1xuXG4gICAgY29uc3QgZmlyc3RJbmRleCA9IHRoaXMucG9zaXRpb25zLmluZGV4T2YoZmlyc3RQKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5zcGxpY2UoZmlyc3RJbmRleCArIDEsIDAsIG1pZFBvaW50KTtcbiAgICByZXR1cm4gbWlkUG9pbnQ7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZU1pZGRsZVZpcnR1YWxQb2ludCh2aXJ0dWFsRWRpdFBvaW50OiBFZGl0UG9pbnQsIHByZXZQb2ludDogRWRpdFBvaW50LCBuZXh0UG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGNvbnN0IG1pZFBvaW50Q2FydGVzaWFuMyA9IENlc2l1bS5DYXJ0ZXNpYW4zLmxlcnAocHJldlBvaW50LmdldFBvc2l0aW9uKCksIG5leHRQb2ludC5nZXRQb3NpdGlvbigpLCAwLjUsIG5ldyBDZXNpdW0uQ2FydGVzaWFuMygpKTtcbiAgICB2aXJ0dWFsRWRpdFBvaW50LnNldFBvc2l0aW9uKG1pZFBvaW50Q2FydGVzaWFuMyk7XG4gIH1cblxuICBjaGFuZ2VWaXJ0dWFsUG9pbnRUb1JlYWxQb2ludChwb2ludDogRWRpdFBvaW50KSB7XG4gICAgcG9pbnQuc2V0VmlydHVhbEVkaXRQb2ludChmYWxzZSk7IC8vIGFjdHVhbCBwb2ludCBiZWNvbWVzIGEgcmVhbCBwb2ludFxuICAgIGNvbnN0IHBvaW50c0NvdW50ID0gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xuICAgIGNvbnN0IHBvaW50SW5kZXggPSB0aGlzLnBvc2l0aW9ucy5pbmRleE9mKHBvaW50KTtcbiAgICBjb25zdCBuZXh0SW5kZXggPSAocG9pbnRJbmRleCArIDEpICUgKHBvaW50c0NvdW50KTtcbiAgICBjb25zdCBwcmVJbmRleCA9ICgocG9pbnRJbmRleCAtIDEpICsgcG9pbnRzQ291bnQpICUgcG9pbnRzQ291bnQ7XG5cbiAgICBjb25zdCBuZXh0UG9pbnQgPSB0aGlzLnBvc2l0aW9uc1tuZXh0SW5kZXhdO1xuICAgIGNvbnN0IHByZVBvaW50ID0gdGhpcy5wb3NpdGlvbnNbcHJlSW5kZXhdO1xuXG4gICAgY29uc3QgZmlyc3RNaWRQb2ludCA9IHRoaXMuc2V0TWlkZGxlVmlydHVhbFBvaW50KHByZVBvaW50LCBwb2ludCk7XG4gICAgY29uc3Qgc2VjTWlkUG9pbnQgPSB0aGlzLnNldE1pZGRsZVZpcnR1YWxQb2ludChwb2ludCwgbmV4dFBvaW50KTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBmaXJzdE1pZFBvaW50LCBzZWNNaWRQb2ludCwgcG9pbnQpO1xuXG4gIH1cblxuICBwcml2YXRlIHJlbmRlclBvbHlsaW5lcygpIHtcbiAgICBjb25zdCByZWFsUG9pbnRzID0gdGhpcy5wb3NpdGlvbnMuZmlsdGVyKHBvaW50ID0+ICFwb2ludC5pc1ZpcnR1YWxFZGl0UG9pbnQoKSk7XG4gICAgaWYgKHRoaXMucG9seWxpbmVQcm9wcy51c2VHcm91bmRQcmltaXRpdmVPdXRsaW5lKSB7XG4gICAgICBpZiAocmVhbFBvaW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2NlbmUuZ3JvdW5kUHJpbWl0aXZlcy5yZW1vdmUodGhpcy5fb3V0bGluZUluc3RhbmNlKTtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IENlc2l1bS5HZW9tZXRyeUluc3RhbmNlKHtcbiAgICAgICAgZ2VvbWV0cnk6IG5ldyBDZXNpdW0uR3JvdW5kUG9seWxpbmVHZW9tZXRyeSh7XG4gICAgICAgICAgcG9zaXRpb25zOiB0aGlzLnBvc2l0aW9ucy5tYXAocCA9PiBwLmdldFBvc2l0aW9uKCkpLFxuICAgICAgICAgIHdpZHRoOiB0aGlzLnBvbHlsaW5lUHJvcHMud2lkdGgsXG4gICAgICAgICAgbG9vcDogZmFsc2VcbiAgICAgICAgfSksXG4gICAgICAgIGlkOiAnZWRpdC1wb2x5Z29uLW91dGxpbmUtJyArIHRoaXMuaWQsXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICBjb2xvcjogQ2VzaXVtLkNvbG9yR2VvbWV0cnlJbnN0YW5jZUF0dHJpYnV0ZS5mcm9tQ29sb3IodGhpcy5wb2x5bGluZVByb3BzLm1hdGVyaWFsKCkpXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5fb3V0bGluZUluc3RhbmNlID0gdGhpcy5zY2VuZS5ncm91bmRQcmltaXRpdmVzLmFkZChcbiAgICAgICAgbmV3IENlc2l1bS5Hcm91bmRQb2x5bGluZVByaW1pdGl2ZSh7XG4gICAgICAgICAgZ2VvbWV0cnlJbnN0YW5jZXM6IGluc3RhbmNlLFxuICAgICAgICAgIGFzeW5jaHJvbm91czogZmFsc2UsXG4gICAgICAgICAgYXBwZWFyYW5jZTogbmV3IENlc2l1bS5Qb2x5bGluZUNvbG9yQXBwZWFyYW5jZSgpXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBvbHlsaW5lcy5mb3JFYWNoKHBvbHlsaW5lID0+IHRoaXMucG9seWxpbmVzTGF5ZXIucmVtb3ZlKHBvbHlsaW5lLmdldElkKCkpKTtcbiAgICAgIHRoaXMucG9seWxpbmVzID0gW107XG4gICAgICByZWFsUG9pbnRzLmZvckVhY2goKHBvaW50LCBpbmRleCkgPT4ge1xuICAgICAgICBpZiAoaW5kZXggIT09IHJlYWxQb2ludHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIGNvbnN0IG5leHRJbmRleCA9IChpbmRleCArIDEpO1xuICAgICAgICAgIGNvbnN0IG5leHRQb2ludCA9IHJlYWxQb2ludHNbbmV4dEluZGV4XTtcbiAgICAgICAgICBjb25zdCBwb2x5bGluZSA9IG5ldyBFZGl0UG9seWxpbmUodGhpcy5pZCwgcG9pbnQuZ2V0UG9zaXRpb24oKSwgbmV4dFBvaW50LmdldFBvc2l0aW9uKCksIHRoaXMucG9seWxpbmVQcm9wcyk7XG4gICAgICAgICAgdGhpcy5wb2x5bGluZXMucHVzaChwb2x5bGluZSk7XG4gICAgICAgICAgdGhpcy5wb2x5bGluZXNMYXllci51cGRhdGUocG9seWxpbmUsIHBvbHlsaW5lLmdldElkKCkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBhZGRQb2ludEZyb21FeGlzdGluZyhwb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIGNvbnN0IG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbiwgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaChuZXdQb2ludCk7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCBuZXdQb2ludCk7XG4gIH1cblxuXG4gIGFkZFBvaW50KHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgaWYgKHRoaXMuZG9uZUNyZWF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGlzRmlyc3RQb2ludCA9ICF0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XG4gICAgaWYgKGlzRmlyc3RQb2ludCkge1xuICAgICAgY29uc3QgZmlyc3RQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24sIHRoaXMuX3BvaW50UHJvcHMpO1xuICAgICAgdGhpcy5wb3NpdGlvbnMucHVzaChmaXJzdFBvaW50KTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgZmlyc3RQb2ludCk7XG4gICAgfVxuXG4gICAgdGhpcy5tb3ZpbmdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24uY2xvbmUoKSwgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaCh0aGlzLm1vdmluZ1BvaW50KTtcblxuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgdGhpcy5tb3ZpbmdQb2ludCk7XG4gIH1cblxuICBtb3ZlUG9pbnRGaW5pc2goZWRpdFBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBpZiAodGhpcy5lZGl0T3B0aW9ucy5jbGFtcEhlaWdodFRvM0QpIHtcbiAgICAgIGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBlZGl0UG9pbnQpO1xuICAgIH1cbiAgfVxuXG4gIG1vdmVQb2ludCh0b1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zLCBlZGl0UG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGVkaXRQb2ludC5zZXRQb3NpdGlvbih0b1Bvc2l0aW9uKTtcbiAgICBpZiAodGhpcy5kb25lQ3JlYXRpb24pIHtcbiAgICAgIGlmIChlZGl0UG9pbnQucHJvcHMuZGlzYWJsZURlcHRoVGVzdERpc3RhbmNlICYmIHRoaXMuZWRpdE9wdGlvbnMuY2xhbXBIZWlnaHRUbzNEKSB7XG4gICAgICAgIC8vIFRvIGF2b2lkIGJ1ZyB3aXRoIHBpY2tQb3NpdGlvbigpIG9uIHBvaW50IHdpdGggZGlzYWJsZURlcHRoVGVzdERpc3RhbmNlXG4gICAgICAgIGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybjsgLy8gaWdub3JlIGZpcnN0IG1vdmUgYmVjYXVzZSB0aGUgcGlja1Bvc2l0aW9uKCkgY291bGQgYmUgd3JvbmdcbiAgICAgIH1cblxuICAgICAgaWYgKGVkaXRQb2ludC5pc1ZpcnR1YWxFZGl0UG9pbnQoKSkge1xuICAgICAgICB0aGlzLmNoYW5nZVZpcnR1YWxQb2ludFRvUmVhbFBvaW50KGVkaXRQb2ludCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwb2ludHNDb3VudCA9IHRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICAgIGNvbnN0IHBvaW50SW5kZXggPSB0aGlzLnBvc2l0aW9ucy5pbmRleE9mKGVkaXRQb2ludCk7XG5cbiAgICAgIGlmIChwb2ludEluZGV4IDwgdGhpcy5wb3NpdGlvbnMubGVuZ3RoIC0gMSkge1xuICAgICAgICBjb25zdCBuZXh0VmlydHVhbFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbKHBvaW50SW5kZXggKyAxKSAlIChwb2ludHNDb3VudCldO1xuICAgICAgICBjb25zdCBuZXh0UmVhbFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbKHBvaW50SW5kZXggKyAyKSAlIChwb2ludHNDb3VudCldO1xuICAgICAgICB0aGlzLnVwZGF0ZU1pZGRsZVZpcnR1YWxQb2ludChuZXh0VmlydHVhbFBvaW50LCBlZGl0UG9pbnQsIG5leHRSZWFsUG9pbnQpO1xuICAgICAgfVxuICAgICAgaWYgKHBvaW50SW5kZXggPiAwKSB7XG4gICAgICAgIGNvbnN0IHByZXZWaXJ0dWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1soKHBvaW50SW5kZXggLSAxKSArIHBvaW50c0NvdW50KSAlIHBvaW50c0NvdW50XTtcbiAgICAgICAgY29uc3QgcHJldlJlYWxQb2ludCA9IHRoaXMucG9zaXRpb25zWygocG9pbnRJbmRleCAtIDIpICsgcG9pbnRzQ291bnQpICUgcG9pbnRzQ291bnRdO1xuICAgICAgICB0aGlzLnVwZGF0ZU1pZGRsZVZpcnR1YWxQb2ludChwcmV2VmlydHVhbFBvaW50LCBlZGl0UG9pbnQsIHByZXZSZWFsUG9pbnQpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIGVkaXRQb2ludCk7XG4gIH1cblxuICBtb3ZlVGVtcE1vdmluZ1BvaW50KHRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAodGhpcy5tb3ZpbmdQb2ludCkge1xuICAgICAgdGhpcy5tb3ZlUG9pbnQodG9Qb3NpdGlvbiwgdGhpcy5tb3ZpbmdQb2ludCk7XG4gICAgfVxuICB9XG5cbiAgbW92ZVNoYXBlKHN0YXJ0TW92aW5nUG9zaXRpb246IENhcnRlc2lhbjMsIGRyYWdnZWRUb1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgaWYgKCF0aGlzLmRvbmVDcmVhdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uKSB7XG4gICAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IHN0YXJ0TW92aW5nUG9zaXRpb247XG4gICAgfVxuXG4gICAgY29uc3QgZGVsdGEgPSBHZW9VdGlsc1NlcnZpY2UuZ2V0UG9zaXRpb25zRGVsdGEodGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24sIGRyYWdnZWRUb1Bvc2l0aW9uKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKHBvaW50ID0+IHtcbiAgICAgIGNvbnN0IG5ld1BvcyA9IEdlb1V0aWxzU2VydmljZS5hZGREZWx0YVRvUG9zaXRpb24ocG9pbnQuZ2V0UG9zaXRpb24oKSwgZGVsdGEsIHRydWUpO1xuICAgICAgcG9pbnQuc2V0UG9zaXRpb24obmV3UG9zKTtcbiAgICB9KTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IGRyYWdnZWRUb1Bvc2l0aW9uO1xuICB9XG5cbiAgZW5kTW92ZVNoYXBlKCkge1xuICAgIHRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgLi4udGhpcy5wb3NpdGlvbnMpO1xuICB9XG5cbiAgcmVtb3ZlUG9pbnQocG9pbnRUb1JlbW92ZTogRWRpdFBvaW50KSB7XG4gICAgdGhpcy5yZW1vdmVQb3NpdGlvbihwb2ludFRvUmVtb3ZlKTtcbiAgICB0aGlzLnBvc2l0aW9uc1xuICAgICAgLmZpbHRlcihwID0+IHAuaXNWaXJ0dWFsRWRpdFBvaW50KCkpXG4gICAgICAuZm9yRWFjaChwID0+IHRoaXMucmVtb3ZlUG9zaXRpb24ocCkpO1xuICAgIHRoaXMuYWRkQWxsVmlydHVhbEVkaXRQb2ludHMoKTtcblxuICAgIHRoaXMucmVuZGVyUG9seWxpbmVzKCk7XG4gIH1cblxuICBhZGRMYXN0UG9pbnQocG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICB0aGlzLmRvbmVDcmVhdGlvbiA9IHRydWU7XG4gICAgdGhpcy5yZW1vdmVQb3NpdGlvbih0aGlzLm1vdmluZ1BvaW50KTsgLy8gcmVtb3ZlIG1vdmluZ1BvaW50XG4gICAgdGhpcy5tb3ZpbmdQb2ludCA9IG51bGw7XG5cbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG4gIH1cblxuICBnZXRSZWFsUG9zaXRpb25zKCk6IENhcnRlc2lhbjNbXSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVhbFBvaW50cygpXG4gICAgICAubWFwKHBvc2l0aW9uID0+IHBvc2l0aW9uLmdldFBvc2l0aW9uKCkpO1xuICB9XG5cbiAgZ2V0UmVhbFBvaW50cygpOiBFZGl0UG9pbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zXG4gICAgICAuZmlsdGVyKHBvc2l0aW9uID0+ICFwb3NpdGlvbi5pc1ZpcnR1YWxFZGl0UG9pbnQoKSAmJiBwb3NpdGlvbiAhPT0gdGhpcy5tb3ZpbmdQb2ludCk7XG4gIH1cblxuICBnZXRQb2ludHMoKTogRWRpdFBvaW50W10ge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocG9zaXRpb24gPT4gcG9zaXRpb24gIT09IHRoaXMubW92aW5nUG9pbnQpO1xuICB9XG5cbiAgZ2V0UG9zaXRpb25zKCk6IENhcnRlc2lhbjNbXSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zLm1hcChwb3NpdGlvbiA9PiBwb3NpdGlvbi5nZXRQb3NpdGlvbigpKTtcbiAgfVxuXG4gIGdldFBvc2l0aW9uc0NhbGxiYWNrUHJvcGVydHkoKTogQ2FydGVzaWFuM1tdIHtcbiAgICByZXR1cm4gbmV3IENlc2l1bS5DYWxsYmFja1Byb3BlcnR5KHRoaXMuZ2V0UG9zaXRpb25zLmJpbmQodGhpcyksIGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUG9zaXRpb24ocG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5wb3NpdGlvbnMuZmluZEluZGV4KChwKSA9PiBwID09PSBwb2ludCk7XG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHBvaW50LmdldElkKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVQb2ludHNMYXllcihyZW5kZXJQb2x5bGluZXMgPSB0cnVlLCAuLi5wb2ludDogRWRpdFBvaW50W10pIHtcbiAgICBpZiAocmVuZGVyUG9seWxpbmVzKSB7XG4gICAgICB0aGlzLnJlbmRlclBvbHlsaW5lcygpO1xuICAgIH1cbiAgICBwb2ludC5mb3JFYWNoKHAgPT4gdGhpcy5wb2ludHNMYXllci51cGRhdGUocCwgcC5nZXRJZCgpKSk7XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcigpO1xuICB9XG5cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLnNjZW5lLmdyb3VuZFByaW1pdGl2ZXMucmVtb3ZlKHRoaXMuX291dGxpbmVJbnN0YW5jZSk7XG4gICAgdGhpcy5wb3NpdGlvbnMuZm9yRWFjaChlZGl0UG9pbnQgPT4ge1xuICAgICAgdGhpcy5wb2ludHNMYXllci5yZW1vdmUoZWRpdFBvaW50LmdldElkKCkpO1xuICAgIH0pO1xuICAgIHRoaXMucG9seWxpbmVzLmZvckVhY2gobGluZSA9PiB0aGlzLnBvbHlsaW5lc0xheWVyLnJlbW92ZShsaW5lLmdldElkKCkpKTtcbiAgICBpZiAodGhpcy5tb3ZpbmdQb2ludCkge1xuICAgICAgdGhpcy5wb2ludHNMYXllci5yZW1vdmUodGhpcy5tb3ZpbmdQb2ludC5nZXRJZCgpKTtcbiAgICAgIHRoaXMubW92aW5nUG9pbnQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25zLmxlbmd0aCA9IDA7XG4gIH1cblxuICBnZXRQb2ludHNDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XG4gIH1cblxuICBnZXRJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pZDtcbiAgfVxufVxuIl19