UNPKG

angular-cesium

Version:
225 lines 36.1 kB
import { merge, of as observableOf, Subject } from 'rxjs'; import { filter, map, mergeMap, switchMap, takeUntil, tap } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { CesiumService } from '../cesium/cesium.service'; import { CesiumEventBuilder } from './cesium-event-builder'; import { PickOptions } from './consts/pickOptions.enum'; import { CesiumEvent } from './consts/cesium-event.enum'; import { PlonterService } from '../plonter/plonter.service'; import { UtilsService } from '../../utils/utils.service'; import { CesiumDragDropHelper } from './event-observers/cesium-drag-drop-helper'; 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 Cesium.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.decorators = [ { type: Injectable } ]; MapEventsManagerService.ctorParameters = () => [ { type: CesiumService }, { type: CesiumEventBuilder }, { type: PlonterService } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLWV2ZW50cy1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jZXNpdW0vc3JjL2xpYi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9tYXAtZXZlbnRzLW1hbmFuZ2VyL21hcC1ldmVudHMtbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFjLEVBQUUsSUFBSSxZQUFZLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXRFLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzVELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzVELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUVqRixNQUFNLFlBQVk7SUFDaEIsWUFBbUIsVUFBbUMsRUFDbEMsT0FBcUIsRUFDckIsUUFBZ0IsRUFDaEIsUUFBaUI7UUFIbEIsZUFBVSxHQUFWLFVBQVUsQ0FBeUI7UUFDbEMsWUFBTyxHQUFQLE9BQU8sQ0FBYztRQUNyQixhQUFRLEdBQVIsUUFBUSxDQUFRO1FBQ2hCLGFBQVEsR0FBUixRQUFRLENBQVM7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QU8sUUFBUSxJQUFJLFFBQVEsWUFBWSxVQUFVLENBQUM7Z0JBQ3BELENBQUMsQ0FBQyxDQUFDO2FBQ0o7aUJBQU07Z0JBQ0wsUUFBUSxHQUFHLGdCQUFnQixDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUM5RTtZQUVELFFBQVEsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3pDLFFBQVEsR0FBRyxDQUFDLFVBQVUsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQzdFLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQ3pCLFFBQVEsR0FBRyxJQUFJLENBQUM7YUFDakI7U0FDRjtRQUVELGdCQUFnQixDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFFckMsT0FBTyxnQkFBZ0IsQ0FBQztJQUMxQixDQUFDO0lBRU8sT0FBTyxDQUFDLG1CQUFnQyxFQUFFLFVBQXVCO1FBQ3ZFLElBQUksVUFBVSxLQUFLLFdBQVcsQ0FBQyxRQUFRLElBQUksbUJBQW1CLENBQUMsUUFBUSxLQUFLLElBQUksSUFBSSxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUMzSCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDLENBQUM7U0FDM0Q7YUFBTTtZQUNMLE9BQU8sWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7U0FDMUM7SUFDSCxDQUFDOzs7WUEzT0YsVUFBVTs7O1lBaERGLGFBQWE7WUFDYixrQkFBa0I7WUFLbEIsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1lcmdlLCBPYnNlcnZhYmxlLCBvZiBhcyBvYnNlcnZhYmxlT2YsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IGZpbHRlciwgbWFwLCBtZXJnZU1hcCwgc3dpdGNoTWFwLCB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDZXNpdW1TZXJ2aWNlIH0gZnJvbSAnLi4vY2VzaXVtL2Nlc2l1bS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ2VzaXVtRXZlbnRCdWlsZGVyIH0gZnJvbSAnLi9jZXNpdW0tZXZlbnQtYnVpbGRlcic7XHJcbmltcG9ydCB7IEV2ZW50UmVnaXN0cmF0aW9uSW5wdXQsIFBpY2tDb25maWd1cmF0aW9uIH0gZnJvbSAnLi9ldmVudC1yZWdpc3RyYXRpb24taW5wdXQnO1xyXG5pbXBvcnQgeyBEaXNwb3NhYmxlT2JzZXJ2YWJsZSB9IGZyb20gJy4vZGlzcG9zYWJsZS1vYnNlcnZhYmxlJztcclxuaW1wb3J0IHsgUGlja09wdGlvbnMgfSBmcm9tICcuL2NvbnN0cy9waWNrT3B0aW9ucy5lbnVtJztcclxuaW1wb3J0IHsgQ2VzaXVtRXZlbnQgfSBmcm9tICcuL2NvbnN0cy9jZXNpdW0tZXZlbnQuZW51bSc7XHJcbmltcG9ydCB7IFBsb250ZXJTZXJ2aWNlIH0gZnJvbSAnLi4vcGxvbnRlci9wbG9udGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBVdGlsc1NlcnZpY2UgfSBmcm9tICcuLi8uLi91dGlscy91dGlscy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ2VzaXVtRHJhZ0Ryb3BIZWxwZXIgfSBmcm9tICcuL2V2ZW50LW9ic2VydmVycy9jZXNpdW0tZHJhZy1kcm9wLWhlbHBlcic7XHJcblxyXG5jbGFzcyBSZWdpc3RyYXRpb24ge1xyXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBvYnNlcnZhYmxlOiBPYnNlcnZhYmxlPEV2ZW50UmVzdWx0PixcclxuICAgICAgICAgICAgICBwdWJsaWMgIHN0b3BwZXI6IFN1YmplY3Q8YW55PixcclxuICAgICAgICAgICAgICBwdWJsaWMgIHByaW9yaXR5OiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgcHVibGljICBpc1BhdXNlZDogYm9vbGVhbikge1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgc2NyZWVuIHBvc2l0aW9uLCBkcmFnIGJvb2xlYW4gZm9yIGRyYWcgZXZlbnRzIG9ubHlcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgTW92ZW1lbnQge1xyXG4gIHN0YXJ0UG9zaXRpb246IHsgeDogbnVtYmVyLCB5OiBudW1iZXIgfTtcclxuICBlbmRQb3NpdGlvbjogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9O1xyXG4gIGRyb3A/OiBib29sZWFuO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEV2ZW50UmVzdWx0IHtcclxuICBtb3ZlbWVudDogTW92ZW1lbnQ7XHJcbiAgY2VzaXVtRW50aXRpZXM6IGFueVtdO1xyXG4gIGVudGl0aWVzOiBhbnlbXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIE1hbmFnZXMgYWxsIG1hcCBldmVudHMuIE5vdGljZSBldmVudHMgd2lsbCBydW4gb3V0c2lkZSBvZiBBbmd1bGFyIHpvbmUuXHJcbiAqIFByb3ZpZGVkIGJ5IGA8YWMtbWFwLz5gIGNvbXBvbmVudCB0aGVyZSBmb3IgY291bGQgYmUgaW5qZWN0ZWQgYXQgYW55IGNvbXBvbmVudCB1bmRlciBgPGFjLW1hcC8+YCBoaWVyYXJjaHlcclxuICogb3IgZnJvbSB0aGUgYDxhYy1tYXAvPmAgY29tcG9uZW50IHJlZmVyZW5jZSBgYWNNYXBDb21wb25lbnQuZ2V0TWFwRXZlbnRzTWFuYWdlcigpYFxyXG4gKlxyXG4gKiBfX3VzYWdlOl9fXHJcbiAqIGBgYFxyXG4gKiBNYXBFdmVudHNNYW5hZ2VyU2VydmljZS5yZWdpc3Rlcih7ZXZlbnQsIG1vZGlmaWVyLCBwcmlvcml0eSwgZW50aXR5VHlwZSwgcGlja09wdGlvbn0pLnN1YnNjcmliZSgpXHJcbiAqIGBgYFxyXG4gKiBfX3BhcmFtOl9fIHtDZXNpdW1FdmVudH0gZXZlbnRcclxuICogX19wYXJhbTpfXyB7Q2VzaXVtRXZlbnRNb2RpZmllcn0gbW9kaWZpZXJcclxuICogX19wYXJhbTpfXyBwcmlvcml0eSAtIHRoZSBiaWdnZXIgdGhlIG51bWJlciB0aGUgYmlnZ2VyIHRoZSBwcmlvcml0eS4gZGVmYXVsdCA6IDAuXHJcbiAqIF9fcGFyYW06X18gZW50aXR5VHlwZSAtIGVudGl0eSB0eXBlIGNsYXNzIHRoYXQgeW91IGFyZSBpbnRlcmVzdGVkIGxpa2UgKFRyYWNrKS4gdGhlIGNsYXNzIG11c3QgZXh0ZW5kcyBBY0VudGl0eVxyXG4gKiBfX3BhcmFtOl9fIHBpY2tPcHRpb24gLSBzZWxmIGV4cGxhaW5lZFxyXG4gKi9cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgTWFwRXZlbnRzTWFuYWdlclNlcnZpY2Uge1xyXG5cclxuICBwcml2YXRlIHNjZW5lOiBhbnk7XHJcbiAgcHJpdmF0ZSBldmVudFJlZ2lzdHJhdGlvbnMgPSBuZXcgTWFwPHN0cmluZywgUmVnaXN0cmF0aW9uW10+KCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2VzaXVtU2VydmljZTogQ2VzaXVtU2VydmljZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIGV2ZW50QnVpbGRlcjogQ2VzaXVtRXZlbnRCdWlsZGVyLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgcGxvbnRlclNlcnZpY2U6IFBsb250ZXJTZXJ2aWNlKSB7XHJcbiAgfVxyXG5cclxuICBpbml0KCkge1xyXG4gICAgdGhpcy5ldmVudEJ1aWxkZXIuaW5pdCgpO1xyXG4gICAgdGhpcy5zY2VuZSA9IHRoaXMuY2VzaXVtU2VydmljZS5nZXRTY2VuZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVnaXN0ZXIgdG8gbWFwIGV2ZW50XHJcbiAgICogQHBhcmFtIGlucHV0IEV2ZW50IFJlZ2lzdHJhdGlvbiBJbnB1dFxyXG4gICAqXHJcbiAgICogQHJldHVybnMgRGlzcG9zYWJsZU9ic2VydmFibGU8RXZlbnRSZXN1bHQ+XHJcbiAgICovXHJcbiAgcmVnaXN0ZXIoaW5wdXQ6IEV2ZW50UmVnaXN0cmF0aW9uSW5wdXQpOiBEaXNwb3NhYmxlT2JzZXJ2YWJsZTxFdmVudFJlc3VsdD4ge1xyXG4gICAgaWYgKHRoaXMuc2NlbmUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nlc2l1bVNlcnZpY2UgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldCAtIE1hcEV2ZW50c01hbmFnZXJTZXJ2aWNlIG11c3QgYmUgaW5qZWN0ZWQgIHVuZGVyIGFjLW1hcCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlucHV0LnBpY2sgPSBpbnB1dC5waWNrIHx8IFBpY2tPcHRpb25zLk5PX1BJQ0s7XHJcbiAgICBpbnB1dC5wcmlvcml0eSA9IGlucHV0LnByaW9yaXR5IHx8IDA7XHJcbiAgICBpbnB1dC5waWNrQ29uZmlnID0gaW5wdXQucGlja0NvbmZpZyB8fCB7fTtcclxuXHJcbiAgICBpZiAoaW5wdXQuZW50aXR5VHlwZSAmJiBpbnB1dC5waWNrID09PSBQaWNrT3B0aW9ucy5OT19QSUNLKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWFwRXZlbnRzTWFuYWdlclNlcnZpY2U6IGNhblxcJ3QgcmVnaXN0ZXIgYW4gZXZlbnQgJyArXHJcbiAgICAgICAgJ3dpdGggZW50aXR5VHlwZSBhbmQgUGlja09wdGlvbnMuTk9fUElDSyAtIEl0IGRvZXNuXFwndCBtYWtlIHNlbnNlICcpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGV2ZW50TmFtZSA9IENlc2l1bUV2ZW50QnVpbGRlci5nZXRFdmVudEZ1bGxOYW1lKGlucHV0LmV2ZW50LCBpbnB1dC5tb2RpZmllcik7XHJcblxyXG4gICAgaWYgKCF0aGlzLmV2ZW50UmVnaXN0cmF0aW9ucy5oYXMoZXZlbnROYW1lKSkge1xyXG4gICAgICB0aGlzLmV2ZW50UmVnaXN0cmF0aW9ucy5zZXQoZXZlbnROYW1lLCBbXSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZXZlbnRSZWdpc3RyYXRpb24gPSB0aGlzLmNyZWF0ZUV2ZW50UmVnaXN0cmF0aW9uKGlucHV0KTtcclxuICAgIGNvbnN0IHJlZ2lzdHJhdGlvbk9ic2VydmFibGU6IGFueSA9IGV2ZW50UmVnaXN0cmF0aW9uLm9ic2VydmFibGU7XHJcbiAgICByZWdpc3RyYXRpb25PYnNlcnZhYmxlLmRpc3Bvc2UgPSAoKSA9PiB0aGlzLmRpc3Bvc2VPYnNlcnZhYmxlKGV2ZW50UmVnaXN0cmF0aW9uLCBldmVudE5hbWUpO1xyXG4gICAgdGhpcy5ldmVudFJlZ2lzdHJhdGlvbnMuZ2V0KGV2ZW50TmFtZSkucHVzaChldmVudFJlZ2lzdHJhdGlvbik7XHJcblxyXG4gICAgdGhpcy5zb3J0UmVnaXN0cmF0aW9uc0J5UHJpb3JpdHkoZXZlbnROYW1lKTtcclxuICAgIHJldHVybiA8RGlzcG9zYWJsZU9ic2VydmFibGU8RXZlbnRSZXN1bHQ+PnJlZ2lzdHJhdGlvbk9ic2VydmFibGU7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRpc3Bvc2VPYnNlcnZhYmxlKGV2ZW50UmVnaXN0cmF0aW9uOiBSZWdpc3RyYXRpb24sIGV2ZW50TmFtZTogc3RyaW5nKSB7XHJcbiAgICBldmVudFJlZ2lzdHJhdGlvbi5zdG9wcGVyLm5leHQoMSk7XHJcbiAgICBjb25zdCByZWdpc3RyYXRpb25zID0gdGhpcy5ldmVudFJlZ2lzdHJhdGlvbnMuZ2V0KGV2ZW50TmFtZSk7XHJcbiAgICBjb25zdCBpbmRleCA9IHJlZ2lzdHJhdGlvbnMuaW5kZXhPZihldmVudFJlZ2lzdHJhdGlvbik7XHJcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XHJcbiAgICAgIHJlZ2lzdHJhdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIH1cclxuICAgIHRoaXMuc29ydFJlZ2lzdHJhdGlvbnNCeVByaW9yaXR5KGV2ZW50TmFtZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNvcnRSZWdpc3RyYXRpb25zQnlQcmlvcml0eShldmVudE5hbWU6IHN0cmluZykge1xyXG4gICAgY29uc3QgcmVnaXN0cmF0aW9ucyA9IHRoaXMuZXZlbnRSZWdpc3RyYXRpb25zLmdldChldmVudE5hbWUpO1xyXG4gICAgcmVnaXN0cmF0aW9ucy5zb3J0KChhLCBiKSA9PiBiLnByaW9yaXR5IC0gYS5wcmlvcml0eSk7XHJcbiAgICBpZiAocmVnaXN0cmF0aW9ucy5sZW5ndGggPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEFjdGl2ZSByZWdpc3RyYXRpb25zIGJ5IHByaW9yaXR5XHJcbiAgICBjb25zdCBjdXJyZW50UHJpb3JpdHkgPSByZWdpc3RyYXRpb25zWzBdLnByaW9yaXR5O1xyXG4gICAgcmVnaXN0cmF0aW9ucy5mb3JFYWNoKChyZWdpc3RyYXRpb24pID0+IHtcclxuICAgICAgcmVnaXN0cmF0aW9uLmlzUGF1c2VkID0gcmVnaXN0cmF0aW9uLnByaW9yaXR5IDwgY3VycmVudFByaW9yaXR5O1xyXG4gICAgfSk7XHJcblxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjcmVhdGVFdmVudFJlZ2lzdHJhdGlvbih7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXR5VHlwZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGljazogcGlja09wdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3JpdHksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpY2tGaWx0ZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpY2tDb25maWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OiBFdmVudFJlZ2lzdHJhdGlvbklucHV0KTogUmVnaXN0cmF0aW9uIHtcclxuICAgIGNvbnN0IGNlc2l1bUV2ZW50T2JzZXJ2YWJsZSA9IHRoaXMuZXZlbnRCdWlsZGVyLmdldChldmVudCwgbW9kaWZpZXIpO1xyXG4gICAgY29uc3Qgc3RvcHBlciA9IG5ldyBTdWJqZWN0PGFueT4oKTtcclxuXHJcbiAgICBjb25zdCByZWdpc3RyYXRpb24gPSBuZXcgUmVnaXN0cmF0aW9uKHVuZGVmaW5lZCwgc3RvcHBlciwgcHJpb3JpdHksIGZhbHNlKTtcclxuICAgIGxldCBvYnNlcnZhYmxlOiBPYnNlcnZhYmxlPEV2ZW50UmVzdWx0PjtcclxuXHJcbiAgICBpZiAoIUNlc2l1bURyYWdEcm9wSGVscGVyLmRyYWdFdmVudHMuaGFzKGV2ZW50KSkge1xyXG4gICAgICBvYnNlcnZhYmxlID0gY2VzaXVtRXZlbnRPYnNlcnZhYmxlLnBpcGUoXHJcbiAgICAgICAgZmlsdGVyKCgpID0+ICFyZWdpc3RyYXRpb24uaXNQYXVzZWQpLFxyXG4gICAgICAgIG1hcCgobW92ZW1lbnQpID0+IHRoaXMudHJpZ2dlclBpY2sobW92ZW1lbnQsIHBpY2tPcHRpb24sIHBpY2tDb25maWcpKSxcclxuICAgICAgICBmaWx0ZXIoKHJlc3VsdCkgPT4gcmVzdWx0LmNlc2l1bUVudGl0aWVzICE9PSBudWxsIHx8IGVudGl0eVR5cGUgPT09IHVuZGVmaW5lZCksXHJcbiAgICAgICAgbWFwKChwaWNrc0FuZE1vdmVtZW50KSA9PiB0aGlzLmFkZEVudGl0aWVzKHBpY2tzQW5kTW92ZW1lbnQsIGVudGl0eVR5cGUsIHBpY2tPcHRpb24sIHBpY2tGaWx0ZXIpKSxcclxuICAgICAgICBmaWx0ZXIoKHJlc3VsdCkgPT4gcmVzdWx0LmVudGl0aWVzICE9PSBudWxsIHx8IChlbnRpdHlUeXBlID09PSB1bmRlZmluZWQgJiYgIXBpY2tGaWx0ZXIpKSxcclxuICAgICAgICBzd2l0Y2hNYXAoKGVudGl0aWVzQW5kTW92ZW1lbnQpID0+IHRoaXMucGxvbnRlcihlbnRpdGllc0FuZE1vdmVtZW50LCBwaWNrT3B0aW9uKSksXHJcbiAgICAgICAgdGFrZVVudGlsKHN0b3BwZXIpKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG9ic2VydmFibGUgPSB0aGlzLmNyZWF0ZURyYWdFdmVudCh7XHJcbiAgICAgICAgZXZlbnQsXHJcbiAgICAgICAgbW9kaWZpZXIsXHJcbiAgICAgICAgZW50aXR5VHlwZSxcclxuICAgICAgICBwaWNrOiBwaWNrT3B0aW9uLFxyXG4gICAgICAgIHByaW9yaXR5LFxyXG4gICAgICAgIHBpY2tGaWx0ZXIsXHJcbiAgICAgICAgcGlja0NvbmZpZ1xyXG4gICAgICB9KS5waXBlKHRha2VVbnRpbChzdG9wcGVyKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVnaXN0cmF0aW9uLm9ic2VydmFibGUgPSBvYnNlcnZhYmxlO1xyXG4gICAgcmV0dXJuIHJlZ2lzdHJhdGlvbjtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY3JlYXRlRHJhZ0V2ZW50KHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRpdHlUeXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGljazogcGlja09wdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yaXR5LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGlja0ZpbHRlcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpY2tDb25maWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfTogRXZlbnRSZWdpc3RyYXRpb25JbnB1dCk6IE9ic2VydmFibGU8RXZlbnRSZXN1bHQ+IHtcclxuICAgIGNvbnN0IHsgbW91c2VEb3duRXZlbnQsIG1vdXNlVXBFdmVudCB9ID0gQ2VzaXVtRHJhZ0Ryb3BIZWxwZXIuZ2V0RHJhZ0V2ZW50VHlwZXMoZXZlbnQpO1xyXG5cclxuICAgIGNvbnN0IG1vdXNlVXBPYnNlcnZhYmxlID0gdGhpcy5ldmVudEJ1aWxkZXIuZ2V0KG1vdXNlVXBFdmVudCk7XHJcbiAgICBjb25zdCBtb3VzZU1vdmVPYnNlcnZhYmxlID0gdGhpcy5ldmVudEJ1aWxkZXIuZ2V0KENlc2l1bUV2ZW50Lk1PVVNFX01PVkUpO1xyXG5cclxuICAgIGNvbnN0IG1vdXNlRG93blJlZ2lzdHJhdGlvbiA9IHRoaXMuY3JlYXRlRXZlbnRSZWdpc3RyYXRpb24oe1xyXG4gICAgICBldmVudDogbW91c2VEb3duRXZlbnQsXHJcbiAgICAgIG1vZGlmaWVyLFxyXG4gICAgICBlbnRpdHlUeXBlLFxyXG4gICAgICBwaWNrOiBwaWNrT3B0aW9uLFxyXG4gICAgICBwcmlvcml0eSxcclxuICAgICAgcGlja0ZpbHRlcixcclxuICAgICAgcGlja0NvbmZpZyxcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IGRyb3BTdWJqZWN0ID0gbmV3IFN1YmplY3Q8RXZlbnRSZXN1bHQ+KCk7XHJcbiAgICBjb25zdCBkcmFnT2JzZXJ2ZXIgPSBtb3VzZURvd25SZWdpc3RyYXRpb24ub2JzZXJ2YWJsZS5waXBlKG1lcmdlTWFwKGUgPT4ge1xyXG4gICAgICBsZXQgbGFzdE1vdmU6IGFueSA9IG51bGw7XHJcbiAgICAgIGNvbnN0IGRyYWdTdGFydFBvc2l0aW9uWCA9IGUubW92ZW1lbnQuc3RhcnRQb3NpdGlvbi54O1xyXG4gICAgICBjb25zdCBkcmFnU3RhcnRQb3NpdGlvblkgPSBlLm1vdmVtZW50LnN0YXJ0UG9zaXRpb24ueTtcclxuICAgICAgcmV0dXJuIG1vdXNlTW92ZU9ic2VydmFibGUucGlwZShtYXAoKG1vdmVtZW50KSA9PiB7XHJcbiAgICAgICAgbGFzdE1vdmUgPSB7XHJcbiAgICAgICAgICBtb3ZlbWVudDoge1xyXG4gICAgICAgICAgICBkcm9wOiBmYWxzZSxcclxuICAgICAgICAgICAgc3RhcnRQb3NpdGlvbjoge1xyXG4gICAgICAgICAgICAgIHg6IGRyYWdTdGFydFBvc2l0aW9uWCxcclxuICAgICAgICAgICAgICB5OiBkcmFnU3RhcnRQb3NpdGlvblksXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGVuZFBvc2l0aW9uOiBtb3ZlbWVudC5lbmRQb3NpdGlvbixcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBlbnRpdGllczogZS5lbnRpdGllcyxcclxuICAgICAgICAgIGNlc2l1bUVudGl0aWVzOiBlLmNlc2l1bUVudGl0aWVzXHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gbGFzdE1vdmU7XHJcbiAgICAgIH0pLCB0YWtlVW50aWwobW91c2VVcE9ic2VydmFibGUpLCB0YXAoe1xyXG4gICAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XHJcbiAgICAgICAgICAvLyBPbiBjb21wbGV0ZVxyXG4gICAgICAgICAgaWYgKGxhc3RNb3ZlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGRyb3BFdmVudCA9IE9iamVjdC5hc3NpZ24oe30sIGxhc3RNb3ZlKTtcclxuICAgICAgICAgICAgZHJvcEV2ZW50Lm1vdmVtZW50LmRyb3AgPSB0cnVlO1xyXG4gICAgICAgICAgICBkcm9wU3ViamVjdC5uZXh0KGRyb3BFdmVudCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KSk7XHJcbiAgICB9KSk7XHJcblxyXG4gICAgcmV0dXJuIG1lcmdlKGRyYWdPYnNlcnZlciwgZHJvcFN1YmplY3QpO1xyXG5cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdHJpZ2dlclBpY2sobW92ZW1lbnQ6IGFueSwgcGlja09wdGlvbnM6IFBpY2tPcHRpb25zLCBwaWNrQ29uZmlnOiBQaWNrQ29uZmlndXJhdGlvbikge1xyXG4gICAgbGV0IHBpY2tzOiBhbnkgPSBbXTtcclxuICAgIHN3aXRjaCAocGlja09wdGlvbnMpIHtcclxuICAgICAgY2FzZSBQaWNrT3B0aW9ucy5QSUNLX09ORTpcclxuICAgICAgY2FzZSBQaWNrT3B0aW9ucy5QSUNLX0FMTDpcclxuICAgICAgICBwaWNrcyA9IHRoaXMuc2NlbmUuZHJpbGxQaWNrKG1vdmVtZW50LmVuZFBvc2l0aW9uLCBwaWNrQ29uZmlnLmRyaWxsUGlja0xpbWl0LCBwaWNrQ29uZmlnLnBpY2tXaWR0aCwgcGlja0NvbmZpZy5waWNrSGVpZ2h0KTtcclxuICAgICAgICBwaWNrcyA9IHBpY2tzLmxlbmd0aCA9PT0gMCA/IG51bGwgOiBwaWNrcztcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSBQaWNrT3B0aW9ucy5QSUNLX0ZJUlNUOlxyXG4gICAgICAgIGNvbnN0IHBpY2sgPSB0aGlzLnNjZW5lLnBpY2sobW92ZW1lbnQuZW5kUG9zaXRpb24sIHBpY2tDb25maWcucGlja1dpZHRoLCBwaWNrQ29uZmlnLnBpY2tIZWlnaHQpO1xyXG4gICAgICAgIHBpY2tzID0gcGljayA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IFtwaWNrXTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSBQaWNrT3B0aW9ucy5OT19QSUNLOlxyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFBpY2tzIGNhbiBiZSBjZXNpdW0gZW50aXR5IG9yIGNlc2l1bSBwcmltaXRpdmVcclxuICAgIGlmIChwaWNrcykge1xyXG4gICAgICBwaWNrcyA9IHBpY2tzLm1hcCgocGljazogYW55KSA9PiBwaWNrLmlkICYmIHBpY2suaWQgaW5zdGFuY2VvZiBDZXNpdW0uRW50aXR5ID8gcGljay5pZCA6IHBpY2sucHJpbWl0aXZlKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyBtb3ZlbWVudDogbW92ZW1lbnQsIGNlc2l1bUVudGl0aWVzOiBwaWNrcyB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGRFbnRpdGllcyhwaWNrc0FuZE1vdmVtZW50OiBhbnksIGVudGl0eVR5cGU6IGFueSwgcGlja09wdGlvbjogUGlja09wdGlvbnMsIHBpY2tGaWx0ZXI/OiAoYW55KSA9PiBib29sZWFuKTogRXZlbnRSZXN1bHQge1xyXG5cclxuICAgIGlmIChwaWNrc0FuZE1vdmVtZW50LmNlc2l1bUVudGl0aWVzID09PSBudWxsKSB7XHJcbiAgICAgIHBpY2tzQW5kTW92ZW1lbnQuZW50aXRpZXMgPSBudWxsO1xyXG4gICAgICByZXR1cm4gcGlja3NBbmRNb3ZlbWVudDtcclxuICAgIH1cclxuICAgIGxldCBlbnRpdGllcyA9IFtdO1xyXG4gICAgaWYgKHBpY2tPcHRpb24gIT09IFBpY2tPcHRpb25zLk5PX1BJQ0spIHtcclxuICAgICAgaWYgKGVudGl0eVR5cGUpIHtcclxuICAgICAgICBlbnRpdGllcyA9IHBpY2tzQW5kTW92ZW1lbnQuY2VzaXVtRW50aXRpZXMubWFwKChwaWNrOiBhbnkpID0+IHBpY2suYWNFbnRpdHkpLmZpbHRlcigoYWNFbnRpdHk6IGFueSkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIGFjRW50aXR5ICYmIGFjRW50aXR5IGluc3RhbmNlb2YgZW50aXR5VHlwZTtcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBlbnRpdGllcyA9IHBpY2tzQW5kTW92ZW1lbnQuY2VzaXVtRW50aXRpZXMubWFwKChwaWNrOiBhbnkpID0+IHBpY2suYWNFbnRpdHkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlbnRpdGllcyA9IFV0aWxzU2VydmljZS51bmlxdWUoZW50aXRpZXMpO1xyXG4gICAgICBlbnRpdGllcyA9IChwaWNrRmlsdGVyICYmIGVudGl0aWVzKSA/IGVudGl0aWVzLmZpbHRlcihwaWNrRmlsdGVyKSA6IGVudGl0aWVzO1xyXG4gICAgICBpZiAoZW50aXRpZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgZW50aXRpZXMgPSBudWxsO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcGlja3NBbmRNb3ZlbWVudC5lbnRpdGllcyA9IGVudGl0aWVzO1xyXG5cclxuICAgIHJldHVybiBwaWNrc0FuZE1vdmVtZW50O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBwbG9udGVyKGVudGl0aWVzQW5kTW92ZW1lbnQ6IEV2ZW50UmVzdWx0LCBwaWNrT3B0aW9uOiBQaWNrT3B0aW9ucyk6IE9ic2VydmFibGU8RXZlbnRSZXN1bHQ+IHtcclxuICAgIGlmIChwaWNrT3B0aW9uID09PSBQaWNrT3B0aW9ucy5QSUNLX09ORSAmJiBlbnRpdGllc0FuZE1vdmVtZW50LmVudGl0aWVzICE9PSBudWxsICYmIGVudGl0aWVzQW5kTW92ZW1lbnQuZW50aXRpZXMubGVuZ3RoID4gMSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5wbG9udGVyU2VydmljZS5wbG9udGVySXQoZW50aXRpZXNBbmRNb3ZlbWVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gb2JzZXJ2YWJsZU9mKGVudGl0aWVzQW5kTW92ZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=