angular-cesium
Version:
Angular library for working with Cesium.
308 lines • 45.4 kB
JavaScript
import { __assign, __decorate } from "tslib";
import { publish, tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import { CesiumEvent } from '../../../../angular-cesium/services/map-events-mananger/consts/cesium-event.enum';
import { PickOptions } from '../../../../angular-cesium/services/map-events-mananger/consts/pickOptions.enum';
import { EditModes } from '../../../models/edit-mode.enum';
import { EditActions } from '../../../models/edit-actions.enum';
import { EditPoint } from '../../../models/edit-point';
import { generateKey } from '../../utils';
export var DEFAULT_POINT_OPTIONS = {
addLastPointEvent: CesiumEvent.LEFT_CLICK,
removePointEvent: CesiumEvent.RIGHT_CLICK,
dragPointEvent: CesiumEvent.LEFT_CLICK_DRAG,
allowDrag: true,
pointProps: {
color: Cesium.Color.WHITE.withAlpha(0.95),
outlineColor: Cesium.Color.BLACK.withAlpha(0.5),
outlineWidth: 1,
pixelSize: 10,
show: true,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
};
/**
* Service for creating editable point
*
* * You must provide `PointsEditorService` yourself.
* PolygonsEditorService works together with `<points-editor>` component. Therefor you need to create `<points-editor>`
* for each `PointsEditorService`, And of course somewhere under `<ac-map>`/
*
* + `create` for starting a creation of the shape over the map. Returns a extension of `PointEditorObservable`.
* + `edit` for editing shape over the map starting from a given positions. Returns an extension of `PointEditorObservable`.
* + To stop editing call `dsipose()` from the `PointEditorObservable` you get back from `create()` \ `edit()`.
*
* **Labels over editted shapes**
* Angular Cesium allows you to draw labels over a shape that is being edited with one of the editors.
* To add label drawing logic to your editor use the function `setLabelsRenderFn()` that is defined on the
* `PointEditorObservable` that is returned from calling `create()` \ `edit()` of one of the editor services.
* `setLabelsRenderFn()` - receives a callback that is called every time the shape is redrawn
* (except when the shape is being dragged). The callback is called with the last shape state and with an array of the current labels.
* The callback should return type `LabelProps[]`.
* You can also use `updateLabels()` to pass an array of labels of type `LabelProps[]` to be drawn.
*
* usage:
* ```typescript
* // Start creating point
* const editing$ = pointEditorService.create();
* this.editing$.subscribe(editResult => {
* console.log(editResult.positions);
* });
*
* // Or edit point from existing point cartesian3 positions
* const editing$ = this.pointEditor.edit(initialPos);
*
* ```
*/
var PointsEditorService = /** @class */ (function () {
function PointsEditorService() {
this.updateSubject = new Subject();
this.updatePublisher = publish()(this.updateSubject); // TODO maybe not needed
this.observablesMap = new Map();
}
PointsEditorService.prototype.init = function (mapEventsManager, coordinateConverter, cameraService, pointManager, cesiumViewer) {
this.mapEventsManager = mapEventsManager;
this.coordinateConverter = coordinateConverter;
this.cameraService = cameraService;
this.pointManager = pointManager;
this.updatePublisher.connect();
this.cesiumScene = cesiumViewer.getScene();
};
PointsEditorService.prototype.onUpdate = function () {
return this.updatePublisher;
};
PointsEditorService.prototype.screenToPosition = function (cartesian2) {
var cartesian3 = this.coordinateConverter.screenToCartesian3(cartesian2);
// If cartesian3 is undefined then the point inst on the globe
if (cartesian3) {
var ray = this.cameraService.getCamera().getPickRay(cartesian2);
return this.cesiumScene.globe.pick(ray, this.cesiumScene);
}
return cartesian3;
};
PointsEditorService.prototype.create = function (options, eventPriority) {
var _this = this;
if (options === void 0) { options = DEFAULT_POINT_OPTIONS; }
if (eventPriority === void 0) { eventPriority = 100; }
var id = generateKey();
var pointOptions = this.setOptions(options);
var clientEditSubject = new BehaviorSubject({
id: id,
editAction: null,
editMode: EditModes.CREATE
});
var finishedCreate = false;
this.updateSubject.next({
id: id,
editMode: EditModes.CREATE,
editAction: EditActions.INIT,
pointOptions: pointOptions,
});
var mouseMoveRegistration = this.mapEventsManager.register({
event: CesiumEvent.MOUSE_MOVE,
pick: PickOptions.NO_PICK,
priority: eventPriority,
pickConfig: options.pickConfiguration,
});
var addLastPointRegistration = this.mapEventsManager.register({
event: pointOptions.addLastPointEvent,
modifier: pointOptions.addLastPointModifier,
pick: PickOptions.NO_PICK,
priority: eventPriority,
pickConfig: options.pickConfiguration,
});
this.observablesMap.set(id, [mouseMoveRegistration, addLastPointRegistration]);
var editorObservable = this.createEditorObservable(clientEditSubject, id);
mouseMoveRegistration.subscribe(function (_a) {
var endPosition = _a.movement.endPosition;
var position = _this.screenToPosition(endPosition);
if (position) {
_this.updateSubject.next({
id: id,
position: position,
editMode: EditModes.CREATE,
updatedPosition: position,
editAction: EditActions.MOUSE_MOVE,
});
}
});
addLastPointRegistration.subscribe(function (_a) {
var endPosition = _a.movement.endPosition;
var position = _this.screenToPosition(endPosition);
finishedCreate = _this.switchToEditMode(id, clientEditSubject, position, eventPriority, pointOptions, editorObservable, true);
});
return editorObservable;
};
PointsEditorService.prototype.switchToEditMode = function (id, clientEditSubject, position, eventPriority, pointOptions, editorObservable, finishedCreate) {
var update = {
id: id,
position: position,
editMode: EditModes.CREATE_OR_EDIT,
updatedPosition: position,
editAction: EditActions.ADD_LAST_POINT,
};
this.updateSubject.next(update);
clientEditSubject.next(__assign(__assign({}, update), { position: position, point: this.getPoint(id) }));
var changeMode = {
id: id,
editMode: EditModes.CREATE,
editAction: EditActions.CHANGE_TO_EDIT,
};
this.updateSubject.next(changeMode);
clientEditSubject.next(changeMode);
if (this.observablesMap.has(id)) {
this.observablesMap.get(id).forEach(function (registration) { return registration.dispose(); });
}
this.observablesMap.delete(id);
this.editPoint(id, position, eventPriority, clientEditSubject, pointOptions, editorObservable);
finishedCreate = true;
return finishedCreate;
};
PointsEditorService.prototype.edit = function (position, options, priority) {
if (options === void 0) { options = DEFAULT_POINT_OPTIONS; }
if (priority === void 0) { priority = 100; }
var id = generateKey();
var pointOptions = this.setOptions(options);
var editSubject = new BehaviorSubject({
id: id,
editAction: null,
editMode: EditModes.EDIT
});
var update = {
id: id,
position: position,
editMode: EditModes.EDIT,
editAction: EditActions.INIT,
pointOptions: pointOptions,
};
this.updateSubject.next(update);
editSubject.next(__assign(__assign({}, update), { position: position, point: this.getPoint(id) }));
return this.editPoint(id, position, priority, editSubject, pointOptions);
};
PointsEditorService.prototype.editPoint = function (id, position, priority, editSubject, options, editObservable) {
var _this = this;
var pointDragRegistration = this.mapEventsManager.register({
event: options.dragPointEvent,
entityType: EditPoint,
pick: PickOptions.PICK_FIRST,
pickConfig: options.pickConfiguration,
priority: priority,
pickFilter: function (entity) { return id === entity.editedEntityId; },
});
var pointRemoveRegistration = this.mapEventsManager.register({
event: options.removePointEvent,
modifier: options.removePointModifier,
entityType: EditPoint,
pick: PickOptions.PICK_FIRST,
pickConfig: options.pickConfiguration,
priority: priority,
pickFilter: function (entity) { return id === entity.editedEntityId; },
});
pointDragRegistration.pipe(tap(function (_a) {
var drop = _a.movement.drop;
return _this.cameraService.enableInputs(drop);
}))
.subscribe(function (_a) {
var _b = _a.movement, endPosition = _b.endPosition, drop = _b.drop, entities = _a.entities;
var updatedPosition = _this.screenToPosition(endPosition);
if (!updatedPosition) {
return;
}
var update = {
id: id,
editMode: EditModes.EDIT,
updatedPosition: updatedPosition,
editAction: drop ? EditActions.DRAG_POINT_FINISH : EditActions.DRAG_POINT,
};
_this.updateSubject.next(update);
editSubject.next(__assign(__assign({}, update), { position: updatedPosition, point: _this.getPoint(id) }));
});
var observables = [pointDragRegistration, pointRemoveRegistration];
this.observablesMap.set(id, observables);
return this.createEditorObservable(editSubject, id);
};
PointsEditorService.prototype.setOptions = function (options) {
var defaultClone = JSON.parse(JSON.stringify(DEFAULT_POINT_OPTIONS));
var pointOptions = Object.assign(defaultClone, options);
pointOptions.pointProps = __assign(__assign({}, DEFAULT_POINT_OPTIONS.pointProps), options.pointProps);
pointOptions.pointProps = __assign(__assign({}, DEFAULT_POINT_OPTIONS.pointProps), options.pointProps);
return pointOptions;
};
PointsEditorService.prototype.createEditorObservable = function (observableToExtend, id) {
var _this = this;
observableToExtend.dispose = function () {
var observables = _this.observablesMap.get(id);
if (observables) {
observables.forEach(function (obs) { return obs.dispose(); });
}
_this.observablesMap.delete(id);
_this.updateSubject.next({
id: id,
editMode: EditModes.CREATE_OR_EDIT,
editAction: EditActions.DISPOSE,
});
};
observableToExtend.enable = function () {
_this.updateSubject.next({
id: id,
position: _this.getPosition(id),
editMode: EditModes.EDIT,
editAction: EditActions.ENABLE,
});
};
observableToExtend.disable = function () {
_this.updateSubject.next({
id: id,
position: _this.getPosition(id),
editMode: EditModes.EDIT,
editAction: EditActions.DISABLE,
});
};
observableToExtend.setManually = function (point, pointProps) {
var newPoint = _this.pointManager.get(id);
newPoint.setManually(point, pointProps);
_this.updateSubject.next({
id: id,
editMode: EditModes.CREATE_OR_EDIT,
editAction: EditActions.SET_MANUALLY,
});
};
observableToExtend.setLabelsRenderFn = function (callback) {
_this.updateSubject.next({
id: id,
editMode: EditModes.CREATE_OR_EDIT,
editAction: EditActions.SET_EDIT_LABELS_RENDER_CALLBACK,
labelsRenderFn: callback,
});
};
observableToExtend.updateLabels = function (labels) {
_this.updateSubject.next({
id: id,
editMode: EditModes.CREATE_OR_EDIT,
editAction: EditActions.UPDATE_EDIT_LABELS,
updateLabels: labels,
});
};
observableToExtend.getCurrentPoint = function () { return _this.getPoint(id); };
observableToExtend.getEditValue = function () { return observableToExtend.getValue(); };
observableToExtend.getLabels = function () { return _this.pointManager.get(id).labels; };
return observableToExtend;
};
PointsEditorService.prototype.getPosition = function (id) {
var point = this.pointManager.get(id);
return point.getPosition();
};
PointsEditorService.prototype.getPoint = function (id) {
var point = this.pointManager.get(id);
if (point) {
return point.getCurrentPoint();
}
};
PointsEditorService = __decorate([
Injectable()
], PointsEditorService);
return PointsEditorService;
}());
export { PointsEditorService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9pbnRzLWVkaXRvci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1jZXNpdW0vIiwic291cmNlcyI6WyJsaWIvYW5ndWxhci1jZXNpdW0td2lkZ2V0cy9zZXJ2aWNlcy9lbnRpdHktZWRpdG9ycy9wb2ludHMtZWRpdG9yL3BvaW50cy1lZGl0b3Iuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxlQUFlLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzVELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxrRkFBa0YsQ0FBQztBQUMvRyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUZBQWlGLENBQUM7QUFDOUcsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQzNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUdoRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFLdkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQU0xQyxNQUFNLENBQUMsSUFBTSxxQkFBcUIsR0FBcUI7SUFDckQsaUJBQWlCLEVBQUUsV0FBVyxDQUFDLFVBQVU7SUFDekMsZ0JBQWdCLEVBQUUsV0FBVyxDQUFDLFdBQVc7SUFDekMsY0FBYyxFQUFFLFdBQVcsQ0FBQyxlQUFlO0lBQzNDLFNBQVMsRUFBRSxJQUFJO0lBQ2YsVUFBVSxFQUFFO1FBQ1YsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7UUFDekMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxH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Q0FBNkIsQ0FBQztRQUV0RSxrQkFBa0IsQ0FBQyxTQUFTLEdBQUcsY0FBb0IsT0FBQSxLQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQWhDLENBQWdDLENBQUM7UUFFcEYsT0FBTyxrQkFBMkMsQ0FBQztJQUNyRCxDQUFDO0lBRU8seUNBQVcsR0FBbkIsVUFBb0IsRUFBVTtRQUM1QixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QyxPQUFPLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRU8sc0NBQVEsR0FBaEIsVUFBaUIsRUFBVTtRQUN6QixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QyxJQUFJLEtBQUssRUFBRTtZQUNULE9BQU8sS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1NBQ2hDO0lBQ0gsQ0FBQztJQXRUVSxtQkFBbUI7UUFEL0IsVUFBVSxFQUFFO09BQ0EsbUJBQW1CLENBdVQvQjtJQUFELDBCQUFDO0NBQUEsQUF2VEQsSUF1VEM7U0F2VFksbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcHVibGlzaCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTWFwRXZlbnRzTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9tYXAtZXZlbnRzLW1hbmFuZ2VyL21hcC1ldmVudHMtbWFuYWdlcic7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IENlc2l1bUV2ZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vYW5ndWxhci1jZXNpdW0vc2VydmljZXMvbWFwLWV2ZW50cy1tYW5hbmdlci9jb25zdHMvY2VzaXVtLWV2ZW50LmVudW0nO1xuaW1wb3J0IHsgUGlja09wdGlvbnMgfSBmcm9tICcuLi8uLi8uLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9tYXAtZXZlbnRzLW1hbmFuZ2VyL2NvbnN0cy9waWNrT3B0aW9ucy5lbnVtJztcbmltcG9ydCB7IEVkaXRNb2RlcyB9IGZyb20gJy4uLy4uLy4uL21vZGVscy9lZGl0LW1vZGUuZW51bSc7XG5pbXBvcnQgeyBFZGl0QWN0aW9ucyB9IGZyb20gJy4uLy4uLy4uL21vZGVscy9lZGl0LWFjdGlvbnMuZW51bSc7XG5pbXBvcnQgeyBEaXNwb3NhYmxlT2JzZXJ2YWJsZSB9IGZyb20gJy4uLy4uLy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL21hcC1ldmVudHMtbWFuYW5nZXIvZGlzcG9zYWJsZS1vYnNlcnZhYmxlJztcbmltcG9ydCB7IENvb3JkaW5hdGVDb252ZXJ0ZXIgfSBmcm9tICcuLi8uLi8uLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9jb29yZGluYXRlLWNvbnZlcnRlci9jb29yZGluYXRlLWNvbnZlcnRlci5zZXJ2aWNlJztcbmltcG9ydCB7IEVkaXRQb2ludCB9IGZyb20gJy4uLy4uLy4uL21vZGVscy9lZGl0LXBvaW50JztcbmltcG9ydCB7IENhbWVyYVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9jYW1lcmEvY2FtZXJhLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2FydGVzaWFuMyB9IGZyb20gJy4uLy4uLy4uLy4uL2FuZ3VsYXItY2VzaXVtL21vZGVscy9jYXJ0ZXNpYW4zJztcbmltcG9ydCB7IFBvaW50c01hbmFnZXJTZXJ2aWNlIH0gZnJvbSAnLi9wb2ludHMtbWFuYWdlci5zZXJ2aWNlJztcbmltcG9ydCB7IExhYmVsUHJvcHMgfSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvbGFiZWwtcHJvcHMnO1xuaW1wb3J0IHsgZ2VuZXJhdGVLZXkgfSBmcm9tICcuLi8uLi91dGlscyc7XG5pbXBvcnQgeyBDZXNpdW1TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vYW5ndWxhci1jZXNpdW0nO1xuaW1wb3J0IHsgUG9pbnRFZGl0T3B0aW9ucywgUG9pbnRQcm9wcyB9IGZyb20gJy4uLy4uLy4uL21vZGVscy9wb2ludC1lZGl0LW9wdGlvbnMnO1xuaW1wb3J0IHsgUG9pbnRFZGl0VXBkYXRlIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL3BvaW50LWVkaXQtdXBkYXRlJztcbmltcG9ydCB7IFBvaW50RWRpdG9yT2JzZXJ2YWJsZSB9IGZyb20gJy4uLy4uLy4uL21vZGVscy9wb2ludC1lZGl0b3Itb2JzZXJ2YWJsZSc7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1BPSU5UX09QVElPTlM6IFBvaW50RWRpdE9wdGlvbnMgPSB7XG4gIGFkZExhc3RQb2ludEV2ZW50OiBDZXNpdW1FdmVudC5MRUZUX0NMSUNLLFxuICByZW1vdmVQb2ludEV2ZW50OiBDZXNpdW1FdmVudC5SSUdIVF9DTElDSyxcbiAgZHJhZ1BvaW50RXZlbnQ6IENlc2l1bUV2ZW50LkxFRlRfQ0xJQ0tfRFJBRyxcbiAgYWxsb3dEcmFnOiB0cnVlLFxuICBwb2ludFByb3BzOiB7XG4gICAgY29sb3I6IENlc2l1bS5Db2xvci5XSElURS53aXRoQWxwaGEoMC45NSksXG4gICAgb3V0bGluZUNvbG9yOiBDZXNpdW0uQ29sb3IuQkxBQ0sud2l0aEFscGhhKDAuNSksXG4gICAgb3V0bGluZVdpZHRoOiAxLFxuICAgIHBpeGVsU2l6ZTogMTAsXG4gICAgc2hvdzogdHJ1ZSxcbiAgICBkaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2U6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxcbiAgfSxcbn07XG5cbi8qKlxuICogU2VydmljZSBmb3IgY3JlYXRpbmcgZWRpdGFibGUgcG9pbnRcbiAqXG4gKiAgKiBZb3UgbXVzdCBwcm92aWRlIGBQb2ludHNFZGl0b3JTZXJ2aWNlYCB5b3Vyc2VsZi5cbiAqIFBvbHlnb25zRWRpdG9yU2VydmljZSB3b3JrcyB0b2dldGhlciB3aXRoIGA8cG9pbnRzLWVkaXRvcj5gIGNvbXBvbmVudC4gVGhlcmVmb3IgeW91IG5lZWQgdG8gY3JlYXRlIGA8cG9pbnRzLWVkaXRvcj5gXG4gKiBmb3IgZWFjaCBgUG9pbnRzRWRpdG9yU2VydmljZWAsIEFuZCBvZiBjb3Vyc2Ugc29tZXdoZXJlIHVuZGVyIGA8YWMtbWFwPmAvXG4gKlxuICogKyBgY3JlYXRlYCBmb3Igc3RhcnRpbmcgYSBjcmVhdGlvbiBvZiB0aGUgc2hhcGUgb3ZlciB0aGUgbWFwLiBSZXR1cm5zIGEgZXh0ZW5zaW9uIG9mIGBQb2ludEVkaXRvck9ic2VydmFibGVgLlxuICogKyBgZWRpdGAgZm9yIGVkaXRpbmcgc2hhcGUgb3ZlciB0aGUgbWFwIHN0YXJ0aW5nIGZyb20gYSBnaXZlbiBwb3NpdGlvbnMuIFJldHVybnMgYW4gZXh0ZW5zaW9uIG9mIGBQb2ludEVkaXRvck9ic2VydmFibGVgLlxuICogKyBUbyBzdG9wIGVkaXRpbmcgY2FsbCBgZHNpcG9zZSgpYCBmcm9tIHRoZSBgUG9pbnRFZGl0b3JPYnNlcnZhYmxlYCB5b3UgZ2V0IGJhY2sgZnJvbSBgY3JlYXRlKClgIFxcIGBlZGl0KClgLlxuICpcbiAqICoqTGFiZWxzIG92ZXIgZWRpdHRlZCBzaGFwZXMqKlxuICogQW5ndWxhciBDZXNpdW0gYWxsb3dzIHlvdSB0byBkcmF3IGxhYmVscyBvdmVyIGEgc2hhcGUgdGhhdCBpcyBiZWluZyBlZGl0ZWQgd2l0aCBvbmUgb2YgdGhlIGVkaXRvcnMuXG4gKiBUbyBhZGQgbGFiZWwgZHJhd2luZyBsb2dpYyB0byB5b3VyIGVkaXRvciB1c2UgdGhlIGZ1bmN0aW9uIGBzZXRMYWJlbHNSZW5kZXJGbigpYCB0aGF0IGlzIGRlZmluZWQgb24gdGhlXG4gKiBgUG9pbnRFZGl0b3JPYnNlcnZhYmxlYCB0aGF0IGlzIHJldHVybmVkIGZyb20gY2FsbGluZyBgY3JlYXRlKClgIFxcIGBlZGl0KClgIG9mIG9uZSBvZiB0aGUgZWRpdG9yIHNlcnZpY2VzLlxuICogYHNldExhYmVsc1JlbmRlckZuKClgIC0gcmVjZWl2ZXMgYSBjYWxsYmFjayB0aGF0IGlzIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBzaGFwZSBpcyByZWRyYXduXG4gKiAoZXhjZXB0IHdoZW4gdGhlIHNoYXBlIGlzIGJlaW5nIGRyYWdnZWQpLiBUaGUgY2FsbGJhY2sgaXMgY2FsbGVkIHdpdGggdGhlIGxhc3Qgc2hhcGUgc3RhdGUgYW5kIHdpdGggYW4gYXJyYXkgb2YgdGhlIGN1cnJlbnQgbGFiZWxzLlxuICogVGhlIGNhbGxiYWNrIHNob3VsZCByZXR1cm4gdHlwZSBgTGFiZWxQcm9wc1tdYC5cbiAqIFlvdSBjYW4gYWxzbyB1c2UgYHVwZGF0ZUxhYmVscygpYCB0byBwYXNzIGFuIGFycmF5IG9mIGxhYmVscyBvZiB0eXBlIGBMYWJlbFByb3BzW11gIHRvIGJlIGRyYXduLlxuICpcbiAqIHVzYWdlOlxuICogYGBgdHlwZXNjcmlwdFxuICogIC8vIFN0YXJ0IGNyZWF0aW5nIHBvaW50XG4gKiAgY29uc3QgZWRpdGluZyQgPSBwb2ludEVkaXRvclNlcnZpY2UuY3JlYXRlKCk7XG4gKiAgdGhpcy5lZGl0aW5nJC5zdWJzY3JpYmUoZWRpdFJlc3VsdCA9PiB7XG4gKlx0XHRcdFx0Y29uc29sZS5sb2coZWRpdFJlc3VsdC5wb3NpdGlvbnMpO1xuICpcdFx0fSk7XG4gKlxuICogIC8vIE9yIGVkaXQgcG9pbnQgZnJvbSBleGlzdGluZyBwb2ludCBjYXJ0ZXNpYW4zIHBvc2l0aW9uc1xuICogIGNvbnN0IGVkaXRpbmckID0gdGhpcy5wb2ludEVkaXRvci5lZGl0KGluaXRpYWxQb3MpO1xuICpcbiAqIGBgYFxuICovXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUG9pbnRzRWRpdG9yU2VydmljZSB7XG4gIHByaXZhdGUgbWFwRXZlbnRzTWFuYWdlcjogTWFwRXZlbnRzTWFuYWdlclNlcnZpY2U7XG4gIHByaXZhdGUgdXBkYXRlU3ViamVjdCA9IG5ldyBTdWJqZWN0PFBvaW50RWRpdFVwZGF0ZT4oKTtcbiAgcHJpdmF0ZSB1cGRhdGVQdWJsaXNoZXIgPSBwdWJsaXNoPFBvaW50RWRpdFVwZGF0ZT4oKSh0aGlzLnVwZGF0ZVN1YmplY3QpOyAvLyBUT0RPIG1heWJlIG5vdCBuZWVkZWRcbiAgcHJpdmF0ZSBjb29yZGluYXRlQ29udmVydGVyOiBDb29yZGluYXRlQ29udmVydGVyO1xuICBwcml2YXRlIGNhbWVyYVNlcnZpY2U6IENhbWVyYVNlcnZpY2U7XG4gIHByaXZhdGUgcG9pbnRNYW5hZ2VyOiBQb2ludHNNYW5hZ2VyU2VydmljZTtcbiAgcHJpdmF0ZSBvYnNlcnZhYmxlc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBEaXNwb3NhYmxlT2JzZXJ2YWJsZTxhbnk+W10+KCk7XG4gIHByaXZhdGUgY2VzaXVtU2NlbmU7XG5cbiAgaW5pdChtYXBFdmVudHNNYW5hZ2VyOiBNYXBFdmVudHNNYW5hZ2VyU2VydmljZSxcbiAgICAgICBjb29yZGluYXRlQ29udmVydGVyOiBDb29yZGluYXRlQ29udmVydGVyLFxuICAgICAgIGNhbWVyYVNlcnZpY2U6IENhbWVyYVNlcnZpY2UsXG4gICAgICAgcG9pbnRNYW5hZ2VyOiBQb2ludHNNYW5hZ2VyU2VydmljZSxcbiAgICAgICBjZXNpdW1WaWV3ZXI6IENlc2l1bVNlcnZpY2UpIHtcbiAgICB0aGlzLm1hcEV2ZW50c01hbmFnZXIgPSBtYXBFdmVudHNNYW5hZ2VyO1xuICAgIHRoaXMuY29vcmRpbmF0ZUNvbnZlcnRlciA9IGNvb3JkaW5hdGVDb252ZXJ0ZXI7XG4gICAgdGhpcy5jYW1lcmFTZXJ2aWNlID0gY2FtZXJhU2VydmljZTtcbiAgICB0aGlzLnBvaW50TWFuYWdlciA9IHBvaW50TWFuYWdlcjtcbiAgICB0aGlzLnVwZGF0ZVB1Ymxpc2hlci5jb25uZWN0KCk7XG5cbiAgICB0aGlzLmNlc2l1bVNjZW5lID0gY2VzaXVtVmlld2VyLmdldFNjZW5lKCk7XG4gIH1cblxuICBvblVwZGF0ZSgpOiBPYnNlcnZhYmxlPFBvaW50RWRpdFVwZGF0ZT4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZVB1Ymxpc2hlcjtcbiAgfVxuXG4gIHByaXZhdGUgc2NyZWVuVG9Qb3NpdGlvbihjYXJ0ZXNpYW4yKSB7XG4gICAgY29uc3QgY2FydGVzaWFuMyA9IHRoaXMuY29vcmRpbmF0ZUNvbnZlcnRlci5zY3JlZW5Ub0NhcnRlc2lhbjMoY2FydGVzaWFuMik7XG5cbiAgICAvLyBJZiBjYXJ0ZXNpYW4zIGlzIHVuZGVmaW5lZCB0aGVuIHRoZSBwb2ludCBpbnN0IG9uIHRoZSBnbG9iZVxuICAgIGlmIChjYXJ0ZXNpYW4zKSB7XG4gICAgICBjb25zdCByYXkgPSB0aGlzLmNhbWVyYVNlcnZpY2UuZ2V0Q2FtZXJhKCkuZ2V0UGlja1JheShjYXJ0ZXNpYW4yKTtcbiAgICAgIHJldHVybiB0aGlzLmNlc2l1bVNjZW5lLmdsb2JlLnBpY2socmF5LCB0aGlzLmNlc2l1bVNjZW5lKTtcbiAgICB9XG4gICAgcmV0dXJuIGNhcnRlc2lhbjM7XG4gIH1cblxuICBjcmVhdGUob3B0aW9ucyA9IERFRkFVTFRfUE9JTlRfT1BUSU9OUywgZXZlbnRQcmlvcml0eSA9IDEwMCk6IFBvaW50RWRpdG9yT2JzZXJ2YWJsZSB7XG4gICAgY29uc3QgaWQgPSBnZW5lcmF0ZUtleSgpO1xuICAgIGNvbnN0IHBvaW50T3B0aW9ucyA9IHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKTtcblxuICAgIGNvbnN0IGNsaWVudEVkaXRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxQb2ludEVkaXRVcGRhdGU+KHtcbiAgICAgIGlkLFxuICAgICAgZWRpdEFjdGlvbjogbnVsbCxcbiAgICAgIGVkaXRNb2RlOiBFZGl0TW9kZXMuQ1JFQVRFXG4gICAgfSk7XG4gICAgbGV0IGZpbmlzaGVkQ3JlYXRlID0gZmFsc2U7XG5cbiAgICB0aGlzLnVwZGF0ZVN1YmplY3QubmV4dCh7XG4gICAgICBpZCxcbiAgICAgIGVkaXRNb2RlOiBFZGl0TW9kZXMuQ1JFQVRFLFxuICAgICAgZWRpdEFjdGlvbjogRWRpdEFjdGlvbnMuSU5JVCxcbiAgICAgIHBvaW50T3B0aW9uczogcG9pbnRPcHRpb25zLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbW91c2VNb3ZlUmVnaXN0cmF0aW9uID0gdGhpcy5tYXBFdmVudHNNYW5hZ2VyLnJlZ2lzdGVyKHtcbiAgICAgIGV2ZW50OiBDZXNpdW1FdmVudC5NT1VTRV9NT1ZFLFxuICAgICAgcGljazogUGlja09wdGlvbnMuTk9fUElDSyxcbiAgICAgIHByaW9yaXR5OiBldmVudFByaW9yaXR5LFxuICAgICAgcGlja0NvbmZpZzogb3B0aW9ucy5waWNrQ29uZmlndXJhdGlvbixcbiAgICB9KTtcbiAgICBjb25zdCBhZGRMYXN0UG9pbnRSZWdpc3RyYXRpb24gPSB0aGlzLm1hcEV2ZW50c01hbmFnZXIucmVnaXN0ZXIoe1xuICAgICAgZXZlbnQ6IHBvaW50T3B0aW9ucy5hZGRMYXN0UG9pbnRFdmVudCxcbiAgICAgIG1vZGlmaWVyOiBwb2ludE9wdGlvbnMuYWRkTGFzdFBvaW50TW9kaWZpZXIsXG4gICAgICBwaWNrOiBQaWNrT3B0aW9ucy5OT19QSUNLLFxuICAgICAgcHJpb3JpdHk6IGV2ZW50UHJpb3JpdHksXG4gICAgICBwaWNrQ29uZmlnOiBvcHRpb25zLnBpY2tDb25maWd1cmF0aW9uLFxuICAgIH0pO1xuXG4gICAgdGhpcy5vYnNlcnZhYmxlc01hcC5zZXQoaWQsIFttb3VzZU1vdmVSZWdpc3RyYXRpb24sIGFkZExhc3RQb2ludFJlZ2lzdHJhdGlvbl0pO1xuICAgIGNvbnN0IGVkaXRvck9ic2VydmFibGUgPSB0aGlzLmNyZWF0ZUVkaXRvck9ic2VydmFibGUoY2xpZW50RWRpdFN1YmplY3QsIGlkKTtcblxuICAgIG1vdXNlTW92ZVJlZ2lzdHJhdGlvbi5zdWJzY3JpYmUoKHsgbW92ZW1lbnQ6IHsgZW5kUG9zaXRpb24gfSB9KSA9PiB7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuc2NyZWVuVG9Qb3NpdGlvbihlbmRQb3NpdGlvbik7XG4gICAgICBpZiAocG9zaXRpb24pIHtcblxuICAgICAgICB0aGlzLnVwZGF0ZVN1YmplY3QubmV4dCh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgcG9zaXRpb24sXG4gICAgICAgICAgZWRpdE1vZGU6IEVkaXRNb2Rlcy5DUkVBVEUsXG4gICAgICAgICAgdXBkYXRlZFBvc2l0aW9uOiBwb3NpdGlvbixcbiAgICAgICAgICBlZGl0QWN0aW9uOiBFZGl0QWN0aW9ucy5NT1VTRV9NT1ZFLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBhZGRMYXN0UG9pbnRSZWdpc3RyYXRpb24uc3Vic2NyaWJlKCh7IG1vdmVtZW50OiB7IGVuZFBvc2l0aW9uIH0gfSkgPT4ge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLnNjcmVlblRvUG9zaXRpb24oZW5kUG9zaXRpb24pO1xuICAgICAgZmluaXNoZWRDcmVhdGUgPSB0aGlzLnN3aXRjaFRvRWRpdE1vZGUoXG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY2xpZW50RWRpdFN1YmplY3QsXG4gICAgICAgICAgcG9zaXRpb24sXG4gICAgICAgICAgZXZlbnRQcmlvcml0eSxcbiAgICAgICAgICBwb2ludE9wdGlvbnMsXG4gICAgICAgICAgZWRpdG9yT2JzZXJ2YWJsZSxcbiAgICAgICAgICB0cnVlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZWRpdG9yT2JzZXJ2YWJsZTtcbiAgfVxuXG4gIHByaXZhdGUgc3dpdGNoVG9FZGl0TW9kZShpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEVkaXRTdWJqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IENhcnRlc2lhbjMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFByaW9yaXR5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yT2JzZXJ2YWJsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmlzaGVkQ3JlYXRlOiBib29sZWFuKSB7XG4gICAgY29uc3QgdXBkYXRlID0ge1xuICAgICAgaWQsXG4gICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICBlZGl0TW9kZTogRWRpdE1vZGVzLkNSRUFURV9PUl9FRElULFxuICAgICAgdXBkYXRlZFBvc2l0aW9uOiBwb3NpdGlvbixcbiAgICAgIGVkaXRBY3Rpb246IEVkaXRBY3Rpb25zLkFERF9MQVNUX1BPSU5ULFxuICAgIH07XG4gICAgdGhpcy51cGRhdGVTdWJqZWN0Lm5leHQodXBkYXRlKTtcbiAgICBjbGllbnRFZGl0U3ViamVjdC5uZXh0KHtcbiAgICAgIC4uLnVwZGF0ZSxcbiAgICAgIHBvc2l0aW9uOiBwb3NpdGlvbixcbiAgICAgIHBvaW50OiB0aGlzLmdldFBvaW50KGlkKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNoYW5nZU1vZGUgPSB7XG4gICAgICBpZCxcbiAgICAgIGVkaXRNb2RlOiBFZGl0TW9kZXMuQ1JFQVRFLFxuICAgICAgZWRpdEFjdGlvbjogRWRpdEFjdGlvbnMuQ0hBTkdFX1RPX0VESVQsXG4gICAgfTtcbiAgICB0aGlzLnVwZGF0ZVN1YmplY3QubmV4dChjaGFuZ2VNb2RlKTtcbiAgICBjbGllbnRFZGl0U3ViamVjdC5uZXh0KGNoYW5nZU1vZGUpO1xuICAgIGlmICh0aGlzLm9ic2VydmFibGVzTWFwLmhhcyhpZCkpIHtcbiAgICAgIHRoaXMub2JzZXJ2YWJsZXNNYXAuZ2V0KGlkKS5mb3JFYWNoKHJlZ2lzdHJhdGlvbiA9PiByZWdpc3RyYXRpb24uZGlzcG9zZSgpKTtcbiAgICB9XG4gICAgdGhpcy5vYnNlcnZhYmxlc01hcC5kZWxldGUoaWQpO1xuICAgIHRoaXMuZWRpdFBvaW50KGlkLCBwb3NpdGlvbiwgZXZlbnRQcmlvcml0eSwgY2xpZW50RWRpdFN1YmplY3QsIHBvaW50T3B0aW9ucywgZWRpdG9yT2JzZXJ2YWJsZSk7XG4gICAgZmluaXNoZWRDcmVhdGUgPSB0cnVlO1xuICAgIHJldHVybiBmaW5pc2hlZENyZWF0ZTtcbiAgfVxuXG4gIGVkaXQocG9zaXRpb246IENhcnRlc2lhbjMsIG9wdGlvbnMgPSBERUZBVUxUX1BPSU5UX09QVElPTlMsIHByaW9yaXR5ID0gMTAwKTogUG9pbnRFZGl0b3JPYnNlcnZhYmxlIHtcbiAgICBjb25zdCBpZCA9IGdlbmVyYXRlS2V5KCk7XG4gICAgY29uc3QgcG9pbnRPcHRpb25zID0gdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICAgIGNvbnN0IGVkaXRTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxQb2ludEVkaXRVcGRhdGU+KHtcbiAgICAgIGlkLFxuICAgICAgZWRpdEFjdGlvbjogbnVsbCxcbiAgICAgIGVkaXRNb2RlOiBFZGl0TW9kZXMuRURJVFxuICAgIH0pO1xuICAgIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICAgIGlkLFxuICAgICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgICAgZWRpdE1vZGU6IEVkaXRNb2Rlcy5FRElULFxuICAgICAgZWRpdEFjdGlvbjogRWRpdEFjdGlvbnMuSU5JVCxcbiAgICAgIHBvaW50T3B0aW9uczogcG9pbnRPcHRpb25zLFxuICAgIH07XG4gICAgdGhpcy51cGRhdGVTdWJqZWN0Lm5leHQodXBkYXRlKTtcbiAgICBlZGl0U3ViamVjdC5uZXh0KHtcbiAgICAgIC4uLnVwZGF0ZSxcbiAgICAgIHBvc2l0aW9uOiBwb3NpdGlvbixcbiAgICAgIHBvaW50OiB0aGlzLmdldFBvaW50KGlkKSxcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5lZGl0UG9pbnQoXG4gICAgICBpZCxcbiAgICAgIHBvc2l0aW9uLFxuICAgICAgcHJpb3JpdHksXG4gICAgICBlZGl0U3ViamVjdCxcbiAgICAgIHBvaW50T3B0aW9uc1xuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGVkaXRQb2ludChpZDogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjogQ2FydGVzaWFuMyxcbiAgICAgICAgICAgICAgICAgICAgICAgcHJpb3JpdHk6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgZWRpdFN1YmplY3Q6IFN1YmplY3Q8UG9pbnRFZGl0VXBkYXRlPixcbiAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczogUG9pbnRFZGl0T3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgZWRpdE9ic2VydmFibGU/OiBQb2ludEVkaXRvck9ic2VydmFibGUpIHtcbiAgICBjb25zdCBwb2ludERyYWdSZWdpc3RyYXRpb24gPSB0aGlzLm1hcEV2ZW50c01hbmFnZXIucmVnaXN0ZXIoe1xuICAgICAgZXZlbnQ6IG9wdGlvbnMuZHJhZ1BvaW50RXZlbnQsXG4gICAgICBlbnRpdHlUeXBlOiBFZGl0UG9pbnQsXG4gICAgICBwaWNrOiBQaWNrT3B0aW9ucy5QSUNLX0ZJUlNULFxuICAgICAgcGlja0NvbmZpZzogb3B0aW9ucy5waWNrQ29uZmlndXJhdGlvbixcbiAgICAgIHByaW9yaXR5LFxuICAgICAgcGlja0ZpbHRlcjogZW50aXR5ID0+IGlkID09PSBlbnRpdHkuZWRpdGVkRW50aXR5SWQsXG4gICAgfSk7XG5cbiAgICBjb25zdCBwb2ludFJlbW92ZVJlZ2lzdHJhdGlvbiA9IHRoaXMubWFwRXZlbnRzTWFuYWdlci5yZWdpc3Rlcih7XG4gICAgICBldmVudDogb3B0aW9ucy5yZW1vdmVQb2ludEV2ZW50LFxuICAgICAgbW9kaWZpZXI6IG9wdGlvbnMucmVtb3ZlUG9pbnRNb2RpZmllcixcbiAgICAgIGVudGl0eVR5cGU6IEVkaXRQb2ludCxcbiAgICAgIHBpY2s6IFBpY2tPcHRpb25zLlBJQ0tfRklSU1QsXG4gICAgICBwaWNrQ29uZmlnOiBvcHRpb25zLnBpY2tDb25maWd1cmF0aW9uLFxuICAgICAgcHJpb3JpdHksXG4gICAgICBwaWNrRmlsdGVyOiBlbnRpdHkgPT4gaWQgPT09IGVudGl0eS5lZGl0ZWRFbnRpdHlJZCxcbiAgICB9KTtcblxuICAgIHBvaW50RHJhZ1JlZ2lzdHJhdGlvbi5waXBlKFxuICAgICAgdGFwKCh7IG1vdmVtZW50OiB7IGRyb3AgfSB9KSA9PiB0aGlzLmNhbWVyYVNlcnZpY2UuZW5hYmxlSW5wdXRzKGRyb3ApKSlcbiAgICAgIC5zdWJzY3JpYmUoKHsgbW92ZW1lbnQ6IHsgZW5kUG9zaXRpb24sIGRyb3AgfSwgZW50aXRpZXMgfSkgPT4ge1xuICAgICAgICBjb25zdCB1cGRhdGVkUG9zaXRpb24gPSB0aGlzLnNjcmVlblRvUG9zaXRpb24oZW5kUG9zaXRpb24pO1xuICAgICAgICBpZiAoIXVwZGF0ZWRQb3NpdGlvbikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgZWRpdE1vZGU6IEVkaXRNb2Rlcy5FRElULFxuICAgICAgICAgIHVwZGF0ZWRQb3NpdGlvbixcbiAgICAgICAgICBlZGl0QWN0aW9uOiBkcm9wID8gRWRpdEFjdGlvbnMuRFJBR19QT0lOVF9GSU5JU0ggOiBFZGl0QWN0aW9ucy5EUkFHX1BPSU5ULFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnVwZGF0ZVN1YmplY3QubmV4dCh1cGRhdGUpO1xuICAgICAgICBlZGl0U3ViamVjdC5uZXh0KHtcbiAgICAgICAgICAuLi51cGRhdGUsXG4gICAgICAgICAgcG9zaXRpb246IHVwZGF0ZWRQb3NpdGlvbixcbiAgICAgICAgICBwb2ludDogdGhpcy5nZXRQb2ludChpZCksXG4gICAgICAgIH0pO1xuXG4gICAgICB9KTtcblxuICAgIGNvbnN0IG9ic2VydmFibGVzID0gW3BvaW50RHJhZ1JlZ2lzdHJhdGlvbiwgcG9pbnRSZW1vdmVSZWdpc3RyYXRpb25dO1xuICAgIHRoaXMub2JzZXJ2YWJsZXNNYXAuc2V0KGlkLCBvYnNlcnZhYmxlcyk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlRWRpdG9yT2JzZXJ2YWJsZShlZGl0U3ViamVjdCwgaWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRPcHRpb25zKG9wdGlvbnM6IFBvaW50RWRpdE9wdGlvbnMpIHtcbiAgICBjb25zdCBkZWZhdWx0Q2xvbmUgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KERFRkFVTFRfUE9JTlRfT1BUSU9OUykpO1xuICAgIGNvbnN0IHBvaW50T3B0aW9uczogUG9pbnRFZGl0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdENsb25lLCBvcHRpb25zKTtcbiAgICBwb2ludE9wdGlvbnMucG9pbnRQcm9wcyA9IHsuLi5ERUZBVUxUX1BPSU5UX09QVElPTlMucG9pbnRQcm9wcywgLi4ub3B0aW9ucy5wb2ludFByb3BzfTtcbiAgICBwb2ludE9wdGlvbnMucG9pbnRQcm9wcyA9IHsuLi5ERUZBVUxUX1BPSU5UX09QVElPTlMucG9pbnRQcm9wcywgLi4ub3B0aW9ucy5wb2ludFByb3BzfTtcbiAgICByZXR1cm4gcG9pbnRPcHRpb25zO1xuICB9XG5cblxuICBwcml2YXRlIGNyZWF0ZUVkaXRvck9ic2VydmFibGUob2JzZXJ2YWJsZVRvRXh0ZW5kOiBhbnksIGlkOiBzdHJpbmcpOiBQb2ludEVkaXRvck9ic2VydmFibGUge1xuICAgIG9ic2VydmFibGVUb0V4dGVuZC5kaXNwb3NlID0gKCkgPT4ge1xuICAgICAgY29uc3Qgb2JzZXJ2YWJsZXMgPSB0aGlzLm9ic2VydmFibGVzTWFwLmdldChpZCk7XG4gICAgICBpZiAob2JzZXJ2YWJsZXMpIHtcbiAgICAgICAgb2JzZXJ2YWJsZXMuZm9yRWFjaChvYnMgPT4gb2JzLmRpc3Bvc2UoKSk7XG4gICAgICB9XG4gICAgICB0aGlzLm9ic2VydmFibGVzTWFwLmRlbGV0ZShpZCk7XG4gICAgICB0aGlzLnVwZGF0ZVN1YmplY3QubmV4dCh7XG4gICAgICAgIGlkLFxuICAgICAgICBlZGl0TW9kZTogRWRpdE1vZGVzLkNSRUFURV9PUl9FRElULFxuICAgICAgICBlZGl0QWN0aW9uOiBFZGl0QWN0aW9ucy5ESVNQT1NFLFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIG9ic2VydmFibGVUb0V4dGVuZC5lbmFibGUgPSAoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVN1YmplY3QubmV4dCh7XG4gICAgICAgIGlkLFxuICAgICAgICBwb3NpdGlvbjogdGhpcy5nZXRQb3NpdGlvbihpZCksXG4gICAgICAgIGVkaXRNb2RlOiBFZGl0TW9kZXMuRURJVCxcbiAgICAgICAgZWRpdEFjdGlvbjogRWRpdEFjdGlvbnMuRU5BQkxFLFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIG9ic2VydmFibGVUb0V4dGVuZC5kaXNhYmxlID0gKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVTdWJqZWN0Lm5leHQoe1xuICAgICAgICBpZCxcbiAgICAgICAgcG9zaXRpb246IHRoaXMuZ2V0UG9zaXRpb24oaWQpLFxuICAgICAgICBlZGl0TW9kZTogRWRpdE1vZGVzLkVESVQsXG4gICAgICAgIGVkaXRBY3Rpb246IEVkaXRBY3Rpb25zLkRJU0FCTEUsXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgb2JzZXJ2YWJsZVRvRXh0ZW5kLnNldE1hbnVhbGx5ID0gKHBvaW50OiB7XG4gICAgICBwb3NpdGlvbjogQ2FydGVzaWFuMyxcbiAgICAgIHBvaW50UHJvcD86IFBvaW50UHJvcHNcbiAgICB9IHwgQ2FydGVzaWFuMywgcG9pbnRQcm9wcz86IFBvaW50UHJvcHMpID0+IHtcbiAgICAgIGNvbnN0IG5ld1BvaW50ID0gdGhpcy5wb2ludE1hbmFnZXIuZ2V0KGlkKTtcbiAgICAgIG5ld1BvaW50LnNldE1hbnVhbGx5KHBvaW50LCBwb2ludFByb3BzKTtcbiAgICAgIHRoaXMudXBkYXRlU3ViamVjdC5uZXh0KHtcbiAgICAgICAgaWQsXG4gICAgICAgIGVkaXRNb2RlOiBFZGl0TW9kZXMuQ1JFQVRFX09SX0VESVQsXG4gICAgICAgIGVkaXRBY3Rpb246IEVkaXRBY3Rpb25zLlNFVF9NQU5VQUxMWSxcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBvYnNlcnZhYmxlVG9FeHRlbmQuc2V0TGFiZWxzUmVuZGVyRm4gPSAoY2FsbGJhY2s6IGFueSkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVTdWJqZWN0Lm5leHQoe1xuICAgICAgICBpZCxcbiAgICAgICAgZWRpdE1vZGU6IEVkaXRNb2Rlcy5DUkVBVEVfT1JfRURJVCxcbiAgICAgICAgZWRpdEFjdGlvbjogRWRpdEFjdGlvbnMuU0VUX0VESVRfTEFCRUxTX1JFTkRFUl9DQUxMQkFDSyxcbiAgICAgICAgbGFiZWxzUmVuZGVyRm46IGNhbGxiYWNrLFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIG9ic2VydmFibGVUb0V4dGVuZC51cGRhdGVMYWJlbHMgPSAobGFiZWxzOiBMYWJlbFByb3BzW10pID0+IHtcbiAgICAgIHRoaXMudXBkYXRlU3ViamVjdC5uZXh0KHtcbiAgICAgICAgaWQsXG4gICAgICAgIGVkaXRNb2RlOiBFZGl0TW9kZXMuQ1JFQVRFX09SX0VESVQsXG4gICAgICAgIGVkaXRBY3Rpb246IEVkaXRBY3Rpb25zLlVQREFURV9FRElUX0xBQkVMUyxcbiAgICAgICAgdXBkYXRlTGFiZWxzOiBsYWJlbHMsXG4gICAgICB9KTtcbiAgICB9O1xuICAgIG9ic2VydmFibGVUb0V4dGVuZC5nZXRDdXJyZW50UG9pbnQgPSAoKSA9PiB0aGlzLmdldFBvaW50KGlkKTtcblxuICAgIG9ic2VydmFibGVUb0V4dGVuZC5nZXRFZGl0VmFsdWUgPSAoKSA9PiBvYnNlcnZhYmxlVG9FeHRlbmQuZ2V0VmFsdWUoKTtcblxuICAgIG9ic2VydmFibGVUb0V4dGVuZC5nZXRMYWJlbHMgPSAoKTogTGFiZWxQcm9wc1tdID0+IHRoaXMucG9pbnRNYW5hZ2VyLmdldChpZCkubGFiZWxzO1xuXG4gICAgcmV0dXJuIG9ic2VydmFibGVUb0V4dGVuZCBhcyBQb2ludEVkaXRvck9ic2VydmFibGU7XG4gIH1cblxuICBwcml2YXRlIGdldFBvc2l0aW9uKGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwb2ludCA9IHRoaXMucG9pbnRNYW5hZ2VyLmdldChpZCk7XG4gICAgcmV0dXJuIHBvaW50LmdldFBvc2l0aW9uKCk7XG4gIH1cblxuICBwcml2YXRlIGdldFBvaW50KGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwb2ludCA9IHRoaXMucG9pbnRNYW5hZ2VyLmdldChpZCk7XG4gICAgaWYgKHBvaW50KSB7XG4gICAgICByZXR1cm4gcG9pbnQuZ2V0Q3VycmVudFBvaW50KCk7XG4gICAgfVxuICB9XG59XG4iXX0=