@eliorar/angular-cesium
Version:
Angular library for working with Cesium.
225 lines • 35.7 kB
JavaScript
import { merge, of as observableOf, Subject } from 'rxjs';
import { filter, map, mergeMap, switchMap, takeUntil, tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { Entity } from 'cesium';
import { CesiumEventBuilder } from './cesium-event-builder';
import { PickOptions } from './consts/pickOptions.enum';
import { CesiumEvent } from './consts/cesium-event.enum';
import { UtilsService } from '../../utils/utils.service';
import { CesiumDragDropHelper } from './event-observers/cesium-drag-drop-helper';
import * as i0 from "@angular/core";
import * as i1 from "../cesium/cesium.service";
import * as i2 from "./cesium-event-builder";
import * as i3 from "../plonter/plonter.service";
class Registration {
constructor(observable, stopper, priority, isPaused) {
this.observable = observable;
this.stopper = stopper;
this.priority = priority;
this.isPaused = isPaused;
}
}
/**
* Manages all map events. Notice events will run outside of Angular zone.
* Provided by `<ac-map/>` component there for could be injected at any component under `<ac-map/>` hierarchy
* or from the `<ac-map/>` component reference `acMapComponent.getMapEventsManager()`
*
* __usage:__
* ```
* MapEventsManagerService.register({event, modifier, priority, entityType, pickOption}).subscribe()
* ```
* __param:__ {CesiumEvent} event
* __param:__ {CesiumEventModifier} modifier
* __param:__ priority - the bigger the number the bigger the priority. default : 0.
* __param:__ entityType - entity type class that you are interested like (Track). the class must extends AcEntity
* __param:__ pickOption - self explained
*/
export class MapEventsManagerService {
constructor(cesiumService, eventBuilder, plonterService) {
this.cesiumService = cesiumService;
this.eventBuilder = eventBuilder;
this.plonterService = plonterService;
this.eventRegistrations = new Map();
}
init() {
this.eventBuilder.init();
this.scene = this.cesiumService.getScene();
}
/**
* Register to map event
* @param input Event Registration Input
*
* @returns DisposableObservable<EventResult>
*/
register(input) {
if (this.scene === undefined) {
throw new Error('CesiumService has not been initialized yet - MapEventsManagerService must be injected under ac-map');
}
input.pick = input.pick || PickOptions.NO_PICK;
input.priority = input.priority || 0;
input.pickConfig = input.pickConfig || {};
if (input.entityType && input.pick === PickOptions.NO_PICK) {
throw new Error('MapEventsManagerService: can\'t register an event ' +
'with entityType and PickOptions.NO_PICK - It doesn\'t make sense ');
}
const eventName = CesiumEventBuilder.getEventFullName(input.event, input.modifier);
if (!this.eventRegistrations.has(eventName)) {
this.eventRegistrations.set(eventName, []);
}
const eventRegistration = this.createEventRegistration(input);
const registrationObservable = eventRegistration.observable;
registrationObservable.dispose = () => this.disposeObservable(eventRegistration, eventName);
this.eventRegistrations.get(eventName).push(eventRegistration);
this.sortRegistrationsByPriority(eventName);
return registrationObservable;
}
disposeObservable(eventRegistration, eventName) {
eventRegistration.stopper.next(1);
const registrations = this.eventRegistrations.get(eventName);
const index = registrations.indexOf(eventRegistration);
if (index !== -1) {
registrations.splice(index, 1);
}
this.sortRegistrationsByPriority(eventName);
}
sortRegistrationsByPriority(eventName) {
const registrations = this.eventRegistrations.get(eventName);
registrations.sort((a, b) => b.priority - a.priority);
if (registrations.length === 0) {
return;
}
// Active registrations by priority
const currentPriority = registrations[0].priority;
registrations.forEach((registration) => {
registration.isPaused = registration.priority < currentPriority;
});
}
createEventRegistration({ event, modifier, entityType, pick: pickOption, priority, pickFilter, pickConfig, }) {
const cesiumEventObservable = this.eventBuilder.get(event, modifier);
const stopper = new Subject();
const registration = new Registration(undefined, stopper, priority, false);
let observable;
if (!CesiumDragDropHelper.dragEvents.has(event)) {
observable = cesiumEventObservable.pipe(filter(() => !registration.isPaused), map((movement) => this.triggerPick(movement, pickOption, pickConfig)), filter((result) => result.cesiumEntities !== null || entityType === undefined), map((picksAndMovement) => this.addEntities(picksAndMovement, entityType, pickOption, pickFilter)), filter((result) => result.entities !== null || (entityType === undefined && !pickFilter)), switchMap((entitiesAndMovement) => this.plonter(entitiesAndMovement, pickOption)), takeUntil(stopper));
}
else {
observable = this.createDragEvent({
event,
modifier,
entityType,
pick: pickOption,
priority,
pickFilter,
pickConfig
}).pipe(takeUntil(stopper));
}
registration.observable = observable;
return registration;
}
createDragEvent({ event, modifier, entityType, pick: pickOption, priority, pickFilter, pickConfig, }) {
const { mouseDownEvent, mouseUpEvent } = CesiumDragDropHelper.getDragEventTypes(event);
const mouseUpObservable = this.eventBuilder.get(mouseUpEvent);
const mouseMoveObservable = this.eventBuilder.get(CesiumEvent.MOUSE_MOVE);
const mouseDownRegistration = this.createEventRegistration({
event: mouseDownEvent,
modifier,
entityType,
pick: pickOption,
priority,
pickFilter,
pickConfig,
});
const dropSubject = new Subject();
const dragObserver = mouseDownRegistration.observable.pipe(mergeMap(e => {
let lastMove = null;
const dragStartPositionX = e.movement.startPosition.x;
const dragStartPositionY = e.movement.startPosition.y;
return mouseMoveObservable.pipe(map((movement) => {
lastMove = {
movement: {
drop: false,
startPosition: {
x: dragStartPositionX,
y: dragStartPositionY,
},
endPosition: movement.endPosition,
},
entities: e.entities,
cesiumEntities: e.cesiumEntities
};
return lastMove;
}), takeUntil(mouseUpObservable), tap({
complete: () => {
// On complete
if (lastMove) {
const dropEvent = Object.assign({}, lastMove);
dropEvent.movement.drop = true;
dropSubject.next(dropEvent);
}
}
}));
}));
return merge(dragObserver, dropSubject);
}
triggerPick(movement, pickOptions, pickConfig) {
let picks = [];
switch (pickOptions) {
case PickOptions.PICK_ONE:
case PickOptions.PICK_ALL:
picks = this.scene.drillPick(movement.endPosition, pickConfig.drillPickLimit, pickConfig.pickWidth, pickConfig.pickHeight);
picks = picks.length === 0 ? null : picks;
break;
case PickOptions.PICK_FIRST:
const pick = this.scene.pick(movement.endPosition, pickConfig.pickWidth, pickConfig.pickHeight);
picks = pick === undefined ? null : [pick];
break;
case PickOptions.NO_PICK:
break;
default:
break;
}
// Picks can be cesium entity or cesium primitive
if (picks) {
picks = picks.map((pick) => pick.id && pick.id instanceof Entity ? pick.id : pick.primitive);
}
return { movement: movement, cesiumEntities: picks };
}
addEntities(picksAndMovement, entityType, pickOption, pickFilter) {
if (picksAndMovement.cesiumEntities === null) {
picksAndMovement.entities = null;
return picksAndMovement;
}
let entities = [];
if (pickOption !== PickOptions.NO_PICK) {
if (entityType) {
entities = picksAndMovement.cesiumEntities.map((pick) => pick.acEntity).filter((acEntity) => {
return acEntity && acEntity instanceof entityType;
});
}
else {
entities = picksAndMovement.cesiumEntities.map((pick) => pick.acEntity);
}
entities = UtilsService.unique(entities);
entities = (pickFilter && entities) ? entities.filter(pickFilter) : entities;
if (entities.length === 0) {
entities = null;
}
}
picksAndMovement.entities = entities;
return picksAndMovement;
}
plonter(entitiesAndMovement, pickOption) {
if (pickOption === PickOptions.PICK_ONE && entitiesAndMovement.entities !== null && entitiesAndMovement.entities.length > 1) {
return this.plonterService.plonterIt(entitiesAndMovement);
}
else {
return observableOf(entitiesAndMovement);
}
}
}
MapEventsManagerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MapEventsManagerService, deps: [{ token: i1.CesiumService }, { token: i2.CesiumEventBuilder }, { token: i3.PlonterService }], target: i0.ɵɵFactoryTarget.Injectable });
MapEventsManagerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MapEventsManagerService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MapEventsManagerService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i1.CesiumService }, { type: i2.CesiumEventBuilder }, { type: i3.PlonterService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLWV2ZW50cy1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jZXNpdW0vc3JjL2xpYi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9tYXAtZXZlbnRzLW1hbmFuZ2VyL21hcC1ldmVudHMtbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsS0FBSyxFQUFjLEVBQUUsSUFBSSxZQUFZLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRXBFLE9BQU8sRUFBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ2hGLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUU5QixPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUcxRCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDdEQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBRXZELE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwyQ0FBMkMsQ0FBQzs7Ozs7QUFFL0UsTUFBTSxZQUFZO0lBQ2hCLFlBQW1CLFVBQW1DLEVBQ2xDLE9BQXFCLEVBQ3JCLFFBQWdCLEVBQ2hCLFFBQWlCO1FBSGxCLGVBQVUsR0FBVixVQUFVLENBQXlCO1FBQ2xDLFlBQU8sR0FBUCxPQUFPLENBQWM7UUFDckIsYUFBUSxHQUFSLFFBQVEsQ0FBUTtRQUNoQixhQUFRLEdBQVIsUUFBUSxDQUFTO0lBQ3JDLENBQUM7Q0FDRjtBQWlCRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztB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QUFDO2FBQ0o7aUJBQU07Z0JBQ0wsUUFBUSxHQUFHLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUM5RTtZQUVELFFBQVEsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3pDLFFBQVEsR0FBRyxDQUFDLFVBQVUsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQzdFLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQ3pCLFFBQVEsR0FBRyxJQUFJLENBQUM7YUFDakI7U0FDRjtRQUVELGdCQUFnQixDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFFckMsT0FBTyxnQkFBZ0IsQ0FBQztJQUMxQixDQUFDO0lBRU8sT0FBTyxDQUFDLG1CQUFnQyxFQUFFLFVBQXVCO1FBQ3ZFLElBQUksVUFBVSxLQUFLLFdBQVcsQ0FBQyxRQUFRLElBQUksbUJBQW1CLENBQUMsUUFBUSxLQUFLLElBQUksSUFBSSxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUMzSCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDLENBQUM7U0FDM0Q7YUFBTTtZQUNMLE9BQU8sWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7U0FDMUM7SUFDSCxDQUFDOztvSEExT1UsdUJBQXVCO3dIQUF2Qix1QkFBdUI7MkZBQXZCLHVCQUF1QjtrQkFEbkMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7bWVyZ2UsIE9ic2VydmFibGUsIG9mIGFzIG9ic2VydmFibGVPZiwgU3ViamVjdH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7ZmlsdGVyLCBtYXAsIG1lcmdlTWFwLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCwgdGFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge0luamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtFbnRpdHl9IGZyb20gJ2Nlc2l1bSc7XG5pbXBvcnQge0Nlc2l1bVNlcnZpY2V9IGZyb20gJy4uL2Nlc2l1bS9jZXNpdW0uc2VydmljZSc7XG5pbXBvcnQge0Nlc2l1bUV2ZW50QnVpbGRlcn0gZnJvbSAnLi9jZXNpdW0tZXZlbnQtYnVpbGRlcic7XG5pbXBvcnQge0V2ZW50UmVnaXN0cmF0aW9uSW5wdXQsIFBpY2tDb25maWd1cmF0aW9ufSBmcm9tICcuL2V2ZW50LXJlZ2lzdHJhdGlvbi1pbnB1dCc7XG5pbXBvcnQge0Rpc3Bvc2FibGVPYnNlcnZhYmxlfSBmcm9tICcuL2Rpc3Bvc2FibGUtb2JzZXJ2YWJsZSc7XG5pbXBvcnQge1BpY2tPcHRpb25zfSBmcm9tICcuL2NvbnN0cy9waWNrT3B0aW9ucy5lbnVtJztcbmltcG9ydCB7Q2VzaXVtRXZlbnR9IGZyb20gJy4vY29uc3RzL2Nlc2l1bS1ldmVudC5lbnVtJztcbmltcG9ydCB7UGxvbnRlclNlcnZpY2V9IGZyb20gJy4uL3Bsb250ZXIvcGxvbnRlci5zZXJ2aWNlJztcbmltcG9ydCB7VXRpbHNTZXJ2aWNlfSBmcm9tICcuLi8uLi91dGlscy91dGlscy5zZXJ2aWNlJztcbmltcG9ydCB7Q2VzaXVtRHJhZ0Ryb3BIZWxwZXJ9IGZyb20gJy4vZXZlbnQtb2JzZXJ2ZXJzL2Nlc2l1bS1kcmFnLWRyb3AtaGVscGVyJztcblxuY2xhc3MgUmVnaXN0cmF0aW9uIHtcbiAgY29uc3RydWN0b3IocHVibGljIG9ic2VydmFibGU6IE9ic2VydmFibGU8RXZlbnRSZXN1bHQ+LFxuICAgICAgICAgICAgICBwdWJsaWMgIHN0b3BwZXI6IFN1YmplY3Q8YW55PixcbiAgICAgICAgICAgICAgcHVibGljICBwcmlvcml0eTogbnVtYmVyLFxuICAgICAgICAgICAgICBwdWJsaWMgIGlzUGF1c2VkOiBib29sZWFuKSB7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHNjcmVlbiBwb3NpdGlvbiwgZHJhZyBib29sZWFuIGZvciBkcmFnIGV2ZW50cyBvbmx5XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTW92ZW1lbnQge1xuICBzdGFydFBvc2l0aW9uOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH07XG4gIGVuZFBvc2l0aW9uOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH07XG4gIGRyb3A/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV2ZW50UmVzdWx0IHtcbiAgbW92ZW1lbnQ6IE1vdmVtZW50O1xuICBjZXNpdW1FbnRpdGllczogYW55W107XG4gIGVudGl0aWVzOiBhbnlbXTtcbn1cblxuLyoqXG4gKiBNYW5hZ2VzIGFsbCBtYXAgZXZlbnRzLiBOb3RpY2UgZXZlbnRzIHdpbGwgcnVuIG91dHNpZGUgb2YgQW5ndWxhciB6b25lLlxuICogUHJvdmlkZWQgYnkgYDxhYy1tYXAvPmAgY29tcG9uZW50IHRoZXJlIGZvciBjb3VsZCBiZSBpbmplY3RlZCBhdCBhbnkgY29tcG9uZW50IHVuZGVyIGA8YWMtbWFwLz5gIGhpZXJhcmNoeVxuICogb3IgZnJvbSB0aGUgYDxhYy1tYXAvPmAgY29tcG9uZW50IHJlZmVyZW5jZSBgYWNNYXBDb21wb25lbnQuZ2V0TWFwRXZlbnRzTWFuYWdlcigpYFxuICpcbiAqIF9fdXNhZ2U6X19cbiAqIGBgYFxuICogTWFwRXZlbnRzTWFuYWdlclNlcnZpY2UucmVnaXN0ZXIoe2V2ZW50LCBtb2RpZmllciwgcHJpb3JpdHksIGVudGl0eVR5cGUsIHBpY2tPcHRpb259KS5zdWJzY3JpYmUoKVxuICogYGBgXG4gKiBfX3BhcmFtOl9fIHtDZXNpdW1FdmVudH0gZXZlbnRcbiAqIF9fcGFyYW06X18ge0Nlc2l1bUV2ZW50TW9kaWZpZXJ9IG1vZGlmaWVyXG4gKiBfX3BhcmFtOl9fIHByaW9yaXR5IC0gdGhlIGJpZ2dlciB0aGUgbnVtYmVyIHRoZSBiaWdnZXIgdGhlIHByaW9yaXR5LiBkZWZhdWx0IDogMC5cbiAqIF9fcGFyYW06X18gZW50aXR5VHlwZSAtIGVudGl0eSB0eXBlIGNsYXNzIHRoYXQgeW91IGFyZSBpbnRlcmVzdGVkIGxpa2UgKFRyYWNrKS4gdGhlIGNsYXNzIG11c3QgZXh0ZW5kcyBBY0VudGl0eVxuICogX19wYXJhbTpfXyBwaWNrT3B0aW9uIC0gc2VsZiBleHBsYWluZWRcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE1hcEV2ZW50c01hbmFnZXJTZXJ2aWNlIHtcblxuICBwcml2YXRlIHNjZW5lOiBhbnk7XG4gIHByaXZhdGUgZXZlbnRSZWdpc3RyYXRpb25zID0gbmV3IE1hcDxzdHJpbmcsIFJlZ2lzdHJhdGlvbltdPigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2VzaXVtU2VydmljZTogQ2VzaXVtU2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBldmVudEJ1aWxkZXI6IENlc2l1bUV2ZW50QnVpbGRlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBwbG9udGVyU2VydmljZTogUGxvbnRlclNlcnZpY2UpIHtcbiAgfVxuXG4gIGluaXQoKSB7XG4gICAgdGhpcy5ldmVudEJ1aWxkZXIuaW5pdCgpO1xuICAgIHRoaXMuc2NlbmUgPSB0aGlzLmNlc2l1bVNlcnZpY2UuZ2V0U2NlbmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciB0byBtYXAgZXZlbnRcbiAgICogQHBhcmFtIGlucHV0IEV2ZW50IFJlZ2lzdHJhdGlvbiBJbnB1dFxuICAgKlxuICAgKiBAcmV0dXJucyBEaXNwb3NhYmxlT2JzZXJ2YWJsZTxFdmVudFJlc3VsdD5cbiAgICovXG4gIHJlZ2lzdGVyKGlucHV0OiBFdmVudFJlZ2lzdHJhdGlvbklucHV0KTogRGlzcG9zYWJsZU9ic2VydmFibGU8RXZlbnRSZXN1bHQ+IHtcbiAgICBpZiAodGhpcy5zY2VuZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nlc2l1bVNlcnZpY2UgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldCAtIE1hcEV2ZW50c01hbmFnZXJTZXJ2aWNlIG11c3QgYmUgaW5qZWN0ZWQgIHVuZGVyIGFjLW1hcCcpO1xuICAgIH1cblxuICAgIGlucHV0LnBpY2sgPSBpbnB1dC5waWNrIHx8IFBpY2tPcHRpb25zLk5PX1BJQ0s7XG4gICAgaW5wdXQucHJpb3JpdHkgPSBpbnB1dC5wcmlvcml0eSB8fCAwO1xuICAgIGlucHV0LnBpY2tDb25maWcgPSBpbnB1dC5waWNrQ29uZmlnIHx8IHt9O1xuXG4gICAgaWYgKGlucHV0LmVudGl0eVR5cGUgJiYgaW5wdXQucGljayA9PT0gUGlja09wdGlvbnMuTk9fUElDSykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYXBFdmVudHNNYW5hZ2VyU2VydmljZTogY2FuXFwndCByZWdpc3RlciBhbiBldmVudCAnICtcbiAgICAgICAgJ3dpdGggZW50aXR5VHlwZSBhbmQgUGlja09wdGlvbnMuTk9fUElDSyAtIEl0IGRvZXNuXFwndCBtYWtlIHNlbnNlICcpO1xuICAgIH1cblxuICAgIGNvbnN0IGV2ZW50TmFtZSA9IENlc2l1bUV2ZW50QnVpbGRlci5nZXRFdmVudEZ1bGxOYW1lKGlucHV0LmV2ZW50LCBpbnB1dC5tb2RpZmllcik7XG5cbiAgICBpZiAoIXRoaXMuZXZlbnRSZWdpc3RyYXRpb25zLmhhcyhldmVudE5hbWUpKSB7XG4gICAgICB0aGlzLmV2ZW50UmVnaXN0cmF0aW9ucy5zZXQoZXZlbnROYW1lLCBbXSk7XG4gICAgfVxuXG4gICAgY29uc3QgZXZlbnRSZWdpc3RyYXRpb24gPSB0aGlzLmNyZWF0ZUV2ZW50UmVnaXN0cmF0aW9uKGlucHV0KTtcbiAgICBjb25zdCByZWdpc3RyYXRpb25PYnNlcnZhYmxlOiBhbnkgPSBldmVudFJlZ2lzdHJhdGlvbi5vYnNlcnZhYmxlO1xuICAgIHJlZ2lzdHJhdGlvbk9ic2VydmFibGUuZGlzcG9zZSA9ICgpID0+IHRoaXMuZGlzcG9zZU9ic2VydmFibGUoZXZlbnRSZWdpc3RyYXRpb24sIGV2ZW50TmFtZSk7XG4gICAgdGhpcy5ldmVudFJlZ2lzdHJhdGlvbnMuZ2V0KGV2ZW50TmFtZSkucHVzaChldmVudFJlZ2lzdHJhdGlvbik7XG5cbiAgICB0aGlzLnNvcnRSZWdpc3RyYXRpb25zQnlQcmlvcml0eShldmVudE5hbWUpO1xuICAgIHJldHVybiA8RGlzcG9zYWJsZU9ic2VydmFibGU8RXZlbnRSZXN1bHQ+PnJlZ2lzdHJhdGlvbk9ic2VydmFibGU7XG4gIH1cblxuICBwcml2YXRlIGRpc3Bvc2VPYnNlcnZhYmxlKGV2ZW50UmVnaXN0cmF0aW9uOiBSZWdpc3RyYXRpb24sIGV2ZW50TmFtZTogc3RyaW5nKSB7XG4gICAgZXZlbnRSZWdpc3RyYXRpb24uc3RvcHBlci5uZXh0KDEpO1xuICAgIGNvbnN0IHJlZ2lzdHJhdGlvbnMgPSB0aGlzLmV2ZW50UmVnaXN0cmF0aW9ucy5nZXQoZXZlbnROYW1lKTtcbiAgICBjb25zdCBpbmRleCA9IHJlZ2lzdHJhdGlvbnMuaW5kZXhPZihldmVudFJlZ2lzdHJhdGlvbik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgcmVnaXN0cmF0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgICB0aGlzLnNvcnRSZWdpc3RyYXRpb25zQnlQcmlvcml0eShldmVudE5hbWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBzb3J0UmVnaXN0cmF0aW9uc0J5UHJpb3JpdHkoZXZlbnROYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZWdpc3RyYXRpb25zID0gdGhpcy5ldmVudFJlZ2lzdHJhdGlvbnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgcmVnaXN0cmF0aW9ucy5zb3J0KChhLCBiKSA9PiBiLnByaW9yaXR5IC0gYS5wcmlvcml0eSk7XG4gICAgaWYgKHJlZ2lzdHJhdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQWN0aXZlIHJlZ2lzdHJhdGlvbnMgYnkgcHJpb3JpdHlcbiAgICBjb25zdCBjdXJyZW50UHJpb3JpdHkgPSByZWdpc3RyYXRpb25zWzBdLnByaW9yaXR5O1xuICAgIHJlZ2lzdHJhdGlvbnMuZm9yRWFjaCgocmVnaXN0cmF0aW9uKSA9PiB7XG4gICAgICByZWdpc3RyYXRpb24uaXNQYXVzZWQgPSByZWdpc3RyYXRpb24ucHJpb3JpdHkgPCBjdXJyZW50UHJpb3JpdHk7XG4gICAgfSk7XG5cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRXZlbnRSZWdpc3RyYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eVR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaWNrOiBwaWNrT3B0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3JpdHksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaWNrRmlsdGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlja0NvbmZpZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OiBFdmVudFJlZ2lzdHJhdGlvbklucHV0KTogUmVnaXN0cmF0aW9uIHtcbiAgICBjb25zdCBjZXNpdW1FdmVudE9ic2VydmFibGUgPSB0aGlzLmV2ZW50QnVpbGRlci5nZXQoZXZlbnQsIG1vZGlmaWVyKTtcbiAgICBjb25zdCBzdG9wcGVyID0gbmV3IFN1YmplY3Q8YW55PigpO1xuXG4gICAgY29uc3QgcmVnaXN0cmF0aW9uID0gbmV3IFJlZ2lzdHJhdGlvbih1bmRlZmluZWQsIHN0b3BwZXIsIHByaW9yaXR5LCBmYWxzZSk7XG4gICAgbGV0IG9ic2VydmFibGU6IE9ic2VydmFibGU8RXZlbnRSZXN1bHQ+O1xuXG4gICAgaWYgKCFDZXNpdW1EcmFnRHJvcEhlbHBlci5kcmFnRXZlbnRzLmhhcyhldmVudCkpIHtcbiAgICAgIG9ic2VydmFibGUgPSBjZXNpdW1FdmVudE9ic2VydmFibGUucGlwZShcbiAgICAgICAgZmlsdGVyKCgpID0+ICFyZWdpc3RyYXRpb24uaXNQYXVzZWQpLFxuICAgICAgICBtYXAoKG1vdmVtZW50KSA9PiB0aGlzLnRyaWdnZXJQaWNrKG1vdmVtZW50LCBwaWNrT3B0aW9uLCBwaWNrQ29uZmlnKSksXG4gICAgICAgIGZpbHRlcigocmVzdWx0KSA9PiByZXN1bHQuY2VzaXVtRW50aXRpZXMgIT09IG51bGwgfHwgZW50aXR5VHlwZSA9PT0gdW5kZWZpbmVkKSxcbiAgICAgICAgbWFwKChwaWNrc0FuZE1vdmVtZW50KSA9PiB0aGlzLmFkZEVudGl0aWVzKHBpY2tzQW5kTW92ZW1lbnQsIGVudGl0eVR5cGUsIHBpY2tPcHRpb24sIHBpY2tGaWx0ZXIpKSxcbiAgICAgICAgZmlsdGVyKChyZXN1bHQpID0+IHJlc3VsdC5lbnRpdGllcyAhPT0gbnVsbCB8fCAoZW50aXR5VHlwZSA9PT0gdW5kZWZpbmVkICYmICFwaWNrRmlsdGVyKSksXG4gICAgICAgIHN3aXRjaE1hcCgoZW50aXRpZXNBbmRNb3ZlbWVudCkgPT4gdGhpcy5wbG9udGVyKGVudGl0aWVzQW5kTW92ZW1lbnQsIHBpY2tPcHRpb24pKSxcbiAgICAgICAgdGFrZVVudGlsKHN0b3BwZXIpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb2JzZXJ2YWJsZSA9IHRoaXMuY3JlYXRlRHJhZ0V2ZW50KHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIG1vZGlmaWVyLFxuICAgICAgICBlbnRpdHlUeXBlLFxuICAgICAgICBwaWNrOiBwaWNrT3B0aW9uLFxuICAgICAgICBwcmlvcml0eSxcbiAgICAgICAgcGlja0ZpbHRlcixcbiAgICAgICAgcGlja0NvbmZpZ1xuICAgICAgfSkucGlwZSh0YWtlVW50aWwoc3RvcHBlcikpO1xuICAgIH1cblxuICAgIHJlZ2lzdHJhdGlvbi5vYnNlcnZhYmxlID0gb2JzZXJ2YWJsZTtcbiAgICByZXR1cm4gcmVnaXN0cmF0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEcmFnRXZlbnQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudGl0eVR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGljazogcGlja09wdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvcml0eSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaWNrRmlsdGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpY2tDb25maWcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH06IEV2ZW50UmVnaXN0cmF0aW9uSW5wdXQpOiBPYnNlcnZhYmxlPEV2ZW50UmVzdWx0PiB7XG4gICAgY29uc3QgeyBtb3VzZURvd25FdmVudCwgbW91c2VVcEV2ZW50IH0gPSBDZXNpdW1EcmFnRHJvcEhlbHBlci5nZXREcmFnRXZlbnRUeXBlcyhldmVudCk7XG5cbiAgICBjb25zdCBtb3VzZVVwT2JzZXJ2YWJsZSA9IHRoaXMuZXZlbnRCdWlsZGVyLmdldChtb3VzZVVwRXZlbnQpO1xuICAgIGNvbnN0IG1vdXNlTW92ZU9ic2VydmFibGUgPSB0aGlzLmV2ZW50QnVpbGRlci5nZXQoQ2VzaXVtRXZlbnQuTU9VU0VfTU9WRSk7XG5cbiAgICBjb25zdCBtb3VzZURvd25SZWdpc3RyYXRpb24gPSB0aGlzLmNyZWF0ZUV2ZW50UmVnaXN0cmF0aW9uKHtcbiAgICAgIGV2ZW50OiBtb3VzZURvd25FdmVudCxcbiAgICAgIG1vZGlmaWVyLFxuICAgICAgZW50aXR5VHlwZSxcbiAgICAgIHBpY2s6IHBpY2tPcHRpb24sXG4gICAgICBwcmlvcml0eSxcbiAgICAgIHBpY2tGaWx0ZXIsXG4gICAgICBwaWNrQ29uZmlnLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZHJvcFN1YmplY3QgPSBuZXcgU3ViamVjdDxFdmVudFJlc3VsdD4oKTtcbiAgICBjb25zdCBkcmFnT2JzZXJ2ZXIgPSBtb3VzZURvd25SZWdpc3RyYXRpb24ub2JzZXJ2YWJsZS5waXBlKG1lcmdlTWFwKGUgPT4ge1xuICAgICAgbGV0IGxhc3RNb3ZlOiBhbnkgPSBudWxsO1xuICAgICAgY29uc3QgZHJhZ1N0YXJ0UG9zaXRpb25YID0gZS5tb3ZlbWVudC5zdGFydFBvc2l0aW9uLng7XG4gICAgICBjb25zdCBkcmFnU3RhcnRQb3NpdGlvblkgPSBlLm1vdmVtZW50LnN0YXJ0UG9zaXRpb24ueTtcbiAgICAgIHJldHVybiBtb3VzZU1vdmVPYnNlcnZhYmxlLnBpcGUobWFwKChtb3ZlbWVudCkgPT4ge1xuICAgICAgICBsYXN0TW92ZSA9IHtcbiAgICAgICAgICBtb3ZlbWVudDoge1xuICAgICAgICAgICAgZHJvcDogZmFsc2UsXG4gICAgICAgICAgICBzdGFydFBvc2l0aW9uOiB7XG4gICAgICAgICAgICAgIHg6IGRyYWdTdGFydFBvc2l0aW9uWCxcbiAgICAgICAgICAgICAgeTogZHJhZ1N0YXJ0UG9zaXRpb25ZLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVuZFBvc2l0aW9uOiBtb3ZlbWVudC5lbmRQb3NpdGlvbixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVudGl0aWVzOiBlLmVudGl0aWVzLFxuICAgICAgICAgIGNlc2l1bUVudGl0aWVzOiBlLmNlc2l1bUVudGl0aWVzXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBsYXN0TW92ZTtcbiAgICAgIH0pLCB0YWtlVW50aWwobW91c2VVcE9ic2VydmFibGUpLCB0YXAoe1xuICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgIC8vIE9uIGNvbXBsZXRlXG4gICAgICAgICAgaWYgKGxhc3RNb3ZlKSB7XG4gICAgICAgICAgICBjb25zdCBkcm9wRXZlbnQgPSBPYmplY3QuYXNzaWduKHt9LCBsYXN0TW92ZSk7XG4gICAgICAgICAgICBkcm9wRXZlbnQubW92ZW1lbnQuZHJvcCA9IHRydWU7XG4gICAgICAgICAgICBkcm9wU3ViamVjdC5uZXh0KGRyb3BFdmVudCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIG1lcmdlKGRyYWdPYnNlcnZlciwgZHJvcFN1YmplY3QpO1xuXG4gIH1cblxuICBwcml2YXRlIHRyaWdnZXJQaWNrKG1vdmVtZW50OiBhbnksIHBpY2tPcHRpb25zOiBQaWNrT3B0aW9ucywgcGlja0NvbmZpZzogUGlja0NvbmZpZ3VyYXRpb24pIHtcbiAgICBsZXQgcGlja3M6IGFueSA9IFtdO1xuICAgIHN3aXRjaCAocGlja09wdGlvbnMpIHtcbiAgICAgIGNhc2UgUGlja09wdGlvbnMuUElDS19PTkU6XG4gICAgICBjYXNlIFBpY2tPcHRpb25zLlBJQ0tfQUxMOlxuICAgICAgICBwaWNrcyA9IHRoaXMuc2NlbmUuZHJpbGxQaWNrKG1vdmVtZW50LmVuZFBvc2l0aW9uLCBwaWNrQ29uZmlnLmRyaWxsUGlja0xpbWl0LCBwaWNrQ29uZmlnLnBpY2tXaWR0aCwgcGlja0NvbmZpZy5waWNrSGVpZ2h0KTtcbiAgICAgICAgcGlja3MgPSBwaWNrcy5sZW5ndGggPT09IDAgPyBudWxsIDogcGlja3M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQaWNrT3B0aW9ucy5QSUNLX0ZJUlNUOlxuICAgICAgICBjb25zdCBwaWNrID0gdGhpcy5zY2VuZS5waWNrKG1vdmVtZW50LmVuZFBvc2l0aW9uLCBwaWNrQ29uZmlnLnBpY2tXaWR0aCwgcGlja0NvbmZpZy5waWNrSGVpZ2h0KTtcbiAgICAgICAgcGlja3MgPSBwaWNrID09PSB1bmRlZmluZWQgPyBudWxsIDogW3BpY2tdO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGlja09wdGlvbnMuTk9fUElDSzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICAvLyBQaWNrcyBjYW4gYmUgY2VzaXVtIGVudGl0eSBvciBjZXNpdW0gcHJpbWl0aXZlXG4gICAgaWYgKHBpY2tzKSB7XG4gICAgICBwaWNrcyA9IHBpY2tzLm1hcCgocGljazogYW55KSA9PiBwaWNrLmlkICYmIHBpY2suaWQgaW5zdGFuY2VvZiBFbnRpdHkgPyBwaWNrLmlkIDogcGljay5wcmltaXRpdmUpO1xuICAgIH1cblxuICAgIHJldHVybiB7IG1vdmVtZW50OiBtb3ZlbWVudCwgY2VzaXVtRW50aXRpZXM6IHBpY2tzIH07XG4gIH1cblxuICBwcml2YXRlIGFkZEVudGl0aWVzKHBpY2tzQW5kTW92ZW1lbnQ6IGFueSwgZW50aXR5VHlwZTogYW55LCBwaWNrT3B0aW9uOiBQaWNrT3B0aW9ucywgcGlja0ZpbHRlcj86IChhbnkpID0+IGJvb2xlYW4pOiBFdmVudFJlc3VsdCB7XG5cbiAgICBpZiAocGlja3NBbmRNb3ZlbWVudC5jZXNpdW1FbnRpdGllcyA9PT0gbnVsbCkge1xuICAgICAgcGlja3NBbmRNb3ZlbWVudC5lbnRpdGllcyA9IG51bGw7XG4gICAgICByZXR1cm4gcGlja3NBbmRNb3ZlbWVudDtcbiAgICB9XG4gICAgbGV0IGVudGl0aWVzID0gW107XG4gICAgaWYgKHBpY2tPcHRpb24gIT09IFBpY2tPcHRpb25zLk5PX1BJQ0spIHtcbiAgICAgIGlmIChlbnRpdHlUeXBlKSB7XG4gICAgICAgIGVudGl0aWVzID0gcGlja3NBbmRNb3ZlbWVudC5jZXNpdW1FbnRpdGllcy5tYXAoKHBpY2s6IGFueSkgPT4gcGljay5hY0VudGl0eSkuZmlsdGVyKChhY0VudGl0eTogYW55KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGFjRW50aXR5ICYmIGFjRW50aXR5IGluc3RhbmNlb2YgZW50aXR5VHlwZTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnRpdGllcyA9IHBpY2tzQW5kTW92ZW1lbnQuY2VzaXVtRW50aXRpZXMubWFwKChwaWNrOiBhbnkpID0+IHBpY2suYWNFbnRpdHkpO1xuICAgICAgfVxuXG4gICAgICBlbnRpdGllcyA9IFV0aWxzU2VydmljZS51bmlxdWUoZW50aXRpZXMpO1xuICAgICAgZW50aXRpZXMgPSAocGlja0ZpbHRlciAmJiBlbnRpdGllcykgPyBlbnRpdGllcy5maWx0ZXIocGlja0ZpbHRlcikgOiBlbnRpdGllcztcbiAgICAgIGlmIChlbnRpdGllcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgZW50aXRpZXMgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBpY2tzQW5kTW92ZW1lbnQuZW50aXRpZXMgPSBlbnRpdGllcztcblxuICAgIHJldHVybiBwaWNrc0FuZE1vdmVtZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBwbG9udGVyKGVudGl0aWVzQW5kTW92ZW1lbnQ6IEV2ZW50UmVzdWx0LCBwaWNrT3B0aW9uOiBQaWNrT3B0aW9ucyk6IE9ic2VydmFibGU8RXZlbnRSZXN1bHQ+IHtcbiAgICBpZiAocGlja09wdGlvbiA9PT0gUGlja09wdGlvbnMuUElDS19PTkUgJiYgZW50aXRpZXNBbmRNb3ZlbWVudC5lbnRpdGllcyAhPT0gbnVsbCAmJiBlbnRpdGllc0FuZE1vdmVtZW50LmVudGl0aWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHJldHVybiB0aGlzLnBsb250ZXJTZXJ2aWNlLnBsb250ZXJJdChlbnRpdGllc0FuZE1vdmVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG9ic2VydmFibGVPZihlbnRpdGllc0FuZE1vdmVtZW50KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==