angular-cesium
Version:
Angular library for working with Cesium.
226 lines • 34.1 kB
JavaScript
import { Injectable, Optional } from '@angular/core';
import { MapsManagerService } from '../../angular-cesium/services/maps-manager/maps-manager.service';
import { CameraService } from '../../angular-cesium/services/camera/camera.service';
import { CesiumService } from '../../angular-cesium/services/cesium/cesium.service';
/**
* The Service is as a "zoom to rectangle" tool
*
* example:
* ```
* constructor(
* private cameraService: CameraService,
* private cesiumService: CesiumService,
* private zoomToRectangleService: ZoomToRectangleService,
* ) {
* this.zoomToRectangleService.init(cesiumService, cameraService);
* }
* ...
* this.zoomToRectangleService.activate({onComplete: () => this.zoomToRectangleService.disable()});
* ```
*
* `init()` - initialize the service with CameraService and CesiumService.
* If no mapId is provided to activate() - must be called before calling `activate()`.
*
* `disable()` - disables the tool.
*
* `activate()` -
* @param options
* {
* onStart - optional - a callback that will be called when the user start drawing the rectangle
* onComplete - optional - a callback that will be called when the tool zoom in
* autoDisableOnZoom - optional - determines if the tool should auto disable after zoom - default: true
* animationDurationInSeconds - optional - zoom animation duration in seconds - default: 0.5
* borderStyle - optional - the style of the rectangle element border - default: '3px dashed #FFFFFF'
* backgroundColor - optional - the background color of the rectangle element - default: 'transparent'
* resetKeyCode - optional - the key code of the key that is used to reset the drawing of the rectangle - default: 27 (ESC key)
* threshold - optional - the minimum area of the screen rectangle (in pixels) that is required to perform zoom - default: 9
* keepRotation - optional - whether or not to keep the rotation when zooming in - default: true
* mouseButton - optional - sets the mouse button for drawing the rectangle - default: left mouse button (0)
* }
* @param mapId - optional - the mapId of the map that the tool will be used in.
*
*/
export var MouseButtons;
(function (MouseButtons) {
MouseButtons[MouseButtons["LEFT"] = 0] = "LEFT";
MouseButtons[MouseButtons["MIDDLE"] = 1] = "MIDDLE";
MouseButtons[MouseButtons["RIGHT"] = 2] = "RIGHT";
})(MouseButtons || (MouseButtons = {}));
export class ZoomToRectangleService {
constructor(mapsManager, cameraService, cesiumService) {
this.mapsManager = mapsManager;
this.mapsZoomElements = new Map();
this.defaultOptions = {
animationDurationInSeconds: 0.5,
resetKeyCode: 27,
borderStyle: '2px solid rgba(0,0,0,0.5)',
backgroundColor: 'rgba(0,0,0,0.2)',
autoDisableOnZoom: true,
threshold: 9,
keepRotation: true,
mouseButton: MouseButtons.LEFT,
};
}
init(cesiumService, cameraService) {
this.cameraService = cameraService;
this.cesiumService = cesiumService;
}
activate(options = {}, mapId) {
if ((!this.cameraService || !this.cesiumService) && !mapId) {
throw new Error(`The function must receive a mapId if the service wasn't initialized`);
}
const finalOptions = Object.assign({}, this.defaultOptions, options);
let cameraService = this.cameraService;
let mapContainer;
let map;
if (this.cesiumService) {
mapContainer = this.cesiumService.getViewer().container;
map = this.cesiumService.getMap();
}
if (mapId) {
map = this.mapsManager.getMap(mapId);
if (!map) {
throw new Error(`Map not found with id: ${mapId}`);
}
cameraService = map.getCameraService();
mapContainer = map.getCesiumViewer().container;
}
if (!cameraService || !mapContainer) {
throw new Error(`The function must receive a mapId if the service wasn't initialized`);
}
this.disable(mapId);
const container = document.createElement('div');
mapContainer.style.position = 'relative';
container.style.position = 'absolute';
container.style.width = '100%';
container.style.height = '100%';
container.style.top = '0';
container.style.left = '0';
mapContainer.appendChild(container);
const mapZoomData = { container };
this.mapsZoomElements.set(mapId || this.cesiumService.getMap().getId(), mapZoomData);
let mouse = {
endX: 0,
endY: 0,
startX: 0,
startY: 0,
};
let borderElement;
container.onmousedown = e => {
if (e.button !== finalOptions.mouseButton) {
return;
}
if (!borderElement) {
if (options && options.onStart) {
options.onStart(map);
}
const rect = e.currentTarget.getBoundingClientRect();
const offsetX = e.clientX - rect.left;
const offsetY = e.clientY - rect.top;
mouse.startX = offsetX;
mouse.startY = offsetY;
borderElement = document.createElement('div');
borderElement.className = 'zoom-to-rectangle-border';
borderElement.style.position = 'absolute';
borderElement.style.border = finalOptions.borderStyle;
borderElement.style.backgroundColor = finalOptions.backgroundColor;
borderElement.style.left = mouse.startX + 'px';
borderElement.style.top = mouse.startY + 'px';
container.appendChild(borderElement);
mapZoomData.borderElement = borderElement;
}
};
container.onmouseup = e => {
if (borderElement) {
let zoomApplied;
if (mouse && Math.abs(mouse.endX - mouse.startX) * Math.abs(mouse.endY - mouse.startY) > finalOptions.threshold) {
zoomApplied = this.zoomCameraToRectangle(cameraService, mouse, finalOptions.animationDurationInSeconds, finalOptions);
}
borderElement.remove();
borderElement = undefined;
mapZoomData.borderElement = undefined;
mouse = {
endX: 0,
endY: 0,
startX: 0,
startY: 0,
};
if (!!finalOptions.onComplete) {
finalOptions.onComplete(map);
}
if (finalOptions.autoDisableOnZoom && zoomApplied) {
this.disable(mapId);
}
}
};
container.onmousemove = e => {
if (borderElement) {
const rect = e.currentTarget.getBoundingClientRect();
const offsetX = e.clientX - rect.left;
const offsetY = e.clientY - rect.top;
mouse.endX = offsetX;
mouse.endY = offsetY;
borderElement.style.width = Math.abs(mouse.endX - mouse.startX) + 'px';
borderElement.style.height = Math.abs(mouse.endY - mouse.startY) + 'px';
borderElement.style.left = Math.min(mouse.startX, mouse.endX) + 'px';
borderElement.style.top = Math.min(mouse.startY, mouse.endY) + 'px';
}
};
const resetOnEscapePress = e => {
if (e.keyCode === finalOptions.resetKeyCode && borderElement) {
borderElement.remove();
borderElement = undefined;
mapZoomData.borderElement = undefined;
mouse = {
endX: 0,
endY: 0,
startX: 0,
startY: 0,
};
}
};
document.addEventListener('keydown', resetOnEscapePress);
mapZoomData.resetOnEscapePressFunc = resetOnEscapePress;
}
disable(mapId) {
if (!this.cesiumService && !mapId) {
throw new Error('If the service was not initialized with CesiumService, mapId must be provided');
}
const data = this.mapsZoomElements.get(mapId || this.cesiumService.getMap().getId());
if (data) {
data.container.remove();
if (data.borderElement) {
data.borderElement.remove();
}
if (data.resetOnEscapePressFunc) {
document.removeEventListener('keydown', data.resetOnEscapePressFunc);
}
}
this.mapsZoomElements.delete(mapId);
}
zoomCameraToRectangle(cameraService, positions, animationDuration, options) {
const camera = cameraService.getCamera();
const cartesian1 = camera.pickEllipsoid({ x: positions.startX, y: positions.startY });
const cartesian2 = camera.pickEllipsoid({ x: positions.endX, y: positions.endY });
if (!cartesian1 || !cartesian2) {
return false;
}
const cartographic1 = Cesium.Cartographic.fromCartesian(cartesian1);
const cartographic2 = Cesium.Cartographic.fromCartesian(cartesian2);
cameraService.cameraFlyTo({
destination: new Cesium.Rectangle(Math.min(cartographic1.longitude, cartographic2.longitude), Math.min(cartographic1.latitude, cartographic2.latitude), Math.max(cartographic1.longitude, cartographic2.longitude), Math.max(cartographic1.latitude, cartographic2.latitude)),
orientation: options.keepRotation ? { heading: camera.heading } : undefined,
duration: animationDuration,
});
return true;
}
}
ZoomToRectangleService.decorators = [
{ type: Injectable }
];
ZoomToRectangleService.ctorParameters = () => [
{ type: MapsManagerService },
{ type: CameraService, decorators: [{ type: Optional }] },
{ type: CesiumService, decorators: [{ type: Optional }] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9vbS10by1yZWN0YW5nbGUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY2VzaXVtL3NyYy9saWIvYW5ndWxhci1jZXNpdW0td2lkZ2V0cy9zZXJ2aWNlcy96b29tLXRvLXJlY3RhbmdsZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGlFQUFpRSxDQUFDO0FBQ3JHLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUNwRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scURBQXFELENBQUM7QUFTcEY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQ0c7QUFFSCxNQUFNLENBQU4sSUFBWSxZQUlYO0FBSkQsV0FBWSxZQUFZO0lBQ3RCLCtDQUFRLENBQUE7SUFDUixtREFBVSxDQUFBO0lBQ1YsaURBQVMsQ0FBQTtBQUNYLENBQUMsRUFKVyxZQUFZLEtBQVosWUFBWSxRQUl2QjtBQUdELE1BQU0sT0FBTyxzQkFBc0I7SUFDakMsWUFDVSxXQUErQixFQUMzQixhQUE0QixFQUM1QixhQUE0QjtRQUZoQyxnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFRakMscUJBQWdCLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUM7UUFDL0MsbUJBQWMsR0FBRztZQUN2QiwwQkFBMEIsRUFBRSxHQUFHO1lBQy9CLFlBQVksRUFBRSxFQUFFO1lBQ2hCLFdBQVcsRUFBRSwyQkFBMkI7WUFDeEMsZUFBZSxFQUFFLGlCQUFpQjtZQUNsQyxpQkFBaUIsRUFBRSxJQUFJO1lBQ3ZCLFNBQVMsRUFBRSxDQUFDO1lBQ1osWUFBWSxFQUFFLElBQUk7WUFDbEIsV0FBVyxFQUFFLFlBQVksQ0FBQyxJQUFJ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Q29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBNYXBzTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9tYXBzLW1hbmFnZXIvbWFwcy1tYW5hZ2VyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDYW1lcmFTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vc2VydmljZXMvY2FtZXJhL2NhbWVyYS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ2VzaXVtU2VydmljZSB9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL2Nlc2l1bS9jZXNpdW0uc2VydmljZSc7XHJcbmltcG9ydCB7IEFjTWFwQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vY29tcG9uZW50cy9hYy1tYXAvYWMtbWFwLmNvbXBvbmVudCc7XHJcblxyXG5pbnRlcmZhY2UgWm9vbURhdGEge1xyXG4gIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQ7XHJcbiAgYm9yZGVyRWxlbWVudD86IEhUTUxFbGVtZW50O1xyXG4gIHJlc2V0T25Fc2NhcGVQcmVzc0Z1bmM/OiBFdmVudExpc3RlbmVyT3JFdmVudExpc3RlbmVyT2JqZWN0O1xyXG59XHJcblxyXG4vKipcclxuICogVGhlIFNlcnZpY2UgaXMgYXMgYSBcInpvb20gdG8gcmVjdGFuZ2xlXCIgdG9vbFxyXG4gKlxyXG4gKiBleGFtcGxlOlxyXG4gKiBgYGBcclxuICogY29uc3RydWN0b3IoXHJcbiAqICAgcHJpdmF0ZSBjYW1lcmFTZXJ2aWNlOiBDYW1lcmFTZXJ2aWNlLFxyXG4gKiAgIHByaXZhdGUgY2VzaXVtU2VydmljZTogQ2VzaXVtU2VydmljZSxcclxuICogICBwcml2YXRlIHpvb21Ub1JlY3RhbmdsZVNlcnZpY2U6IFpvb21Ub1JlY3RhbmdsZVNlcnZpY2UsXHJcbiAqICkge1xyXG4gKiAgIHRoaXMuem9vbVRvUmVjdGFuZ2xlU2VydmljZS5pbml0KGNlc2l1bVNlcnZpY2UsIGNhbWVyYVNlcnZpY2UpO1xyXG4gKiB9XHJcbiAqIC4uLlxyXG4gKiB0aGlzLnpvb21Ub1JlY3RhbmdsZVNlcnZpY2UuYWN0aXZhdGUoe29uQ29tcGxldGU6ICgpID0+IHRoaXMuem9vbVRvUmVjdGFuZ2xlU2VydmljZS5kaXNhYmxlKCl9KTtcclxuICogYGBgXHJcbiAqXHJcbiAqIGBpbml0KClgIC0gaW5pdGlhbGl6ZSB0aGUgc2VydmljZSB3aXRoIENhbWVyYVNlcnZpY2UgYW5kIENlc2l1bVNlcnZpY2UuXHJcbiAqIElmIG5vIG1hcElkIGlzIHByb3ZpZGVkIHRvIGFjdGl2YXRlKCkgLSBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgY2FsbGluZyBgYWN0aXZhdGUoKWAuXHJcbiAqXHJcbiAqIGBkaXNhYmxlKClgIC0gZGlzYWJsZXMgdGhlIHRvb2wuXHJcbiAqXHJcbiAqIGBhY3RpdmF0ZSgpYCAtXHJcbiAqIEBwYXJhbSBvcHRpb25zXHJcbiAqIHtcclxuICogIG9uU3RhcnQgLSBvcHRpb25hbCAtIGEgY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSB1c2VyIHN0YXJ0IGRyYXdpbmcgdGhlIHJlY3RhbmdsZVxyXG4gKiAgb25Db21wbGV0ZSAtIG9wdGlvbmFsIC0gYSBjYWxsYmFjayB0aGF0IHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIHRvb2wgem9vbSBpblxyXG4gKiAgYXV0b0Rpc2FibGVPblpvb20gLSBvcHRpb25hbCAtIGRldGVybWluZXMgaWYgdGhlIHRvb2wgc2hvdWxkIGF1dG8gZGlzYWJsZSBhZnRlciB6b29tIC0gZGVmYXVsdDogdHJ1ZVxyXG4gKiAgYW5pbWF0aW9uRHVyYXRpb25JblNlY29uZHMgLSBvcHRpb25hbCAtIHpvb20gYW5pbWF0aW9uIGR1cmF0aW9uIGluIHNlY29uZHMgLSBkZWZhdWx0OiAwLjVcclxuICogIGJvcmRlclN0eWxlIC0gb3B0aW9uYWwgLSB0aGUgc3R5bGUgb2YgdGhlIHJlY3RhbmdsZSBlbGVtZW50IGJvcmRlciAtIGRlZmF1bHQ6ICczcHggZGFzaGVkICNGRkZGRkYnXHJcbiAqICBiYWNrZ3JvdW5kQ29sb3IgLSBvcHRpb25hbCAtIHRoZSBiYWNrZ3JvdW5kIGNvbG9yIG9mIHRoZSByZWN0YW5nbGUgZWxlbWVudCAtIGRlZmF1bHQ6ICd0cmFuc3BhcmVudCdcclxuICogIHJlc2V0S2V5Q29kZSAtIG9wdGlvbmFsIC0gdGhlIGtleSBjb2RlIG9mIHRoZSBrZXkgdGhhdCBpcyB1c2VkIHRvIHJlc2V0IHRoZSBkcmF3aW5nIG9mIHRoZSByZWN0YW5nbGUgLSBkZWZhdWx0OiAyNyAoRVNDIGtleSlcclxuICogIHRocmVzaG9sZCAtIG9wdGlvbmFsIC0gdGhlIG1pbmltdW0gYXJlYSBvZiB0aGUgc2NyZWVuIHJlY3RhbmdsZSAoaW4gcGl4ZWxzKSB0aGF0IGlzIHJlcXVpcmVkIHRvIHBlcmZvcm0gem9vbSAtIGRlZmF1bHQ6IDlcclxuICogIGtlZXBSb3RhdGlvbiAtIG9wdGlvbmFsIC0gd2hldGhlciBvciBub3QgdG8ga2VlcCB0aGUgcm90YXRpb24gd2hlbiB6b29taW5nIGluIC0gZGVmYXVsdDogdHJ1ZVxyXG4gKiAgbW91c2VCdXR0b24gLSBvcHRpb25hbCAtIHNldHMgdGhlIG1vdXNlIGJ1dHRvbiBmb3IgZHJhd2luZyB0aGUgcmVjdGFuZ2xlIC0gZGVmYXVsdDogbGVmdCBtb3VzZSBidXR0b24gKDApXHJcbiAqIH1cclxuICogQHBhcmFtIG1hcElkIC0gb3B0aW9uYWwgLSB0aGUgbWFwSWQgb2YgdGhlIG1hcCB0aGF0IHRoZSB0b29sIHdpbGwgYmUgdXNlZCBpbi5cclxuICpcclxuICovXHJcblxyXG5leHBvcnQgZW51bSBNb3VzZUJ1dHRvbnMge1xyXG4gIExFRlQgPSAwLFxyXG4gIE1JRERMRSA9IDEsXHJcbiAgUklHSFQgPSAyLFxyXG59XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBab29tVG9SZWN0YW5nbGVTZXJ2aWNlIHtcclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgbWFwc01hbmFnZXI6IE1hcHNNYW5hZ2VyU2VydmljZSxcclxuICAgIEBPcHRpb25hbCgpIGNhbWVyYVNlcnZpY2U6IENhbWVyYVNlcnZpY2UsXHJcbiAgICBAT3B0aW9uYWwoKSBjZXNpdW1TZXJ2aWNlOiBDZXNpdW1TZXJ2aWNlLFxyXG4gICkge31cclxuXHJcbiAgcHJpdmF0ZSBjYW1lcmFTZXJ2aWNlOiBDYW1lcmFTZXJ2aWNlO1xyXG4gIHByaXZhdGUgY2VzaXVtU2VydmljZTogQ2VzaXVtU2VydmljZTtcclxuXHJcbiAgcHJpdmF0ZSBtYXBzWm9vbUVsZW1lbnRzID0gbmV3IE1hcDxzdHJpbmcsIFpvb21EYXRhPigpO1xyXG4gIHByaXZhdGUgZGVmYXVsdE9wdGlvbnMgPSB7XHJcbiAgICBhbmltYXRpb25EdXJhdGlvbkluU2Vjb25kczogMC41LFxyXG4gICAgcmVzZXRLZXlDb2RlOiAyNyxcclxuICAgIGJvcmRlclN0eWxlOiAnMnB4IHNvbGlkIHJnYmEoMCwwLDAsMC41KScsXHJcbiAgICBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDAsMCwwLDAuMiknLFxyXG4gICAgYXV0b0Rpc2FibGVPblpvb206IHRydWUsXHJcbiAgICB0aHJlc2hvbGQ6IDksXHJcbiAgICBrZWVwUm90YXRpb246IHRydWUsXHJcbiAgICBtb3VzZUJ1dHRvbjogTW91c2VCdXR0b25zLkxFRlQsXHJcbiAgfTtcclxuXHJcbiAgaW5pdChjZXNpdW1TZXJ2aWNlOiBDZXNpdW1TZXJ2aWNlLCBjYW1lcmFTZXJ2aWNlOiBDYW1lcmFTZXJ2aWNlKSB7XHJcbiAgICB0aGlzLmNhbWVyYVNlcnZpY2UgPSBjYW1lcmFTZXJ2aWNlO1xyXG4gICAgdGhpcy5jZXNpdW1TZXJ2aWNlID0gY2VzaXVtU2VydmljZTtcclxuICB9XHJcblxyXG4gIGFjdGl2YXRlKFxyXG4gICAgb3B0aW9uczoge1xyXG4gICAgICBvblN0YXJ0PzogKGFjTWFwPzogQWNNYXBDb21wb25lbnQpID0+IGFueTtcclxuICAgICAgb25Db21wbGV0ZT86IChhY01hcD86IEFjTWFwQ29tcG9uZW50KSA9PiBhbnk7XHJcbiAgICAgIG1vdXNlQnV0dG9uPzogTW91c2VCdXR0b25zO1xyXG4gICAgICBhdXRvRGlzYWJsZU9uWm9vbT86IGJvb2xlYW47XHJcbiAgICAgIGFuaW1hdGlvbkR1cmF0aW9uSW5TZWNvbmRzPzogbnVtYmVyO1xyXG4gICAgICB0aHJlc2hvbGQ/OiBudW1iZXI7XHJcbiAgICAgIGtlZXBSb3RhdGlvbj86IGJvb2xlYW47XHJcbiAgICAgIGJvcmRlclN0eWxlPzogc3RyaW5nO1xyXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmc7XHJcbiAgICAgIHJlc2V0S2V5Q29kZT86IG51bWJlcjtcclxuICAgIH0gPSB7fSxcclxuICAgIG1hcElkPzogc3RyaW5nLFxyXG4gICkge1xyXG4gICAgaWYgKCghdGhpcy5jYW1lcmFTZXJ2aWNlIHx8ICF0aGlzLmNlc2l1bVNlcnZpY2UpICYmICFtYXBJZCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBmdW5jdGlvbiBtdXN0IHJlY2VpdmUgYSBtYXBJZCBpZiB0aGUgc2VydmljZSB3YXNuJ3QgaW5pdGlhbGl6ZWRgKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGZpbmFsT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpO1xyXG4gICAgbGV0IGNhbWVyYVNlcnZpY2UgPSB0aGlzLmNhbWVyYVNlcnZpY2U7XHJcbiAgICBsZXQgbWFwQ29udGFpbmVyO1xyXG4gICAgbGV0IG1hcDtcclxuICAgIGlmICh0aGlzLmNlc2l1bVNlcnZpY2UpIHtcclxuICAgICAgbWFwQ29udGFpbmVyID0gdGhpcy5jZXNpdW1TZXJ2aWNlLmdldFZpZXdlcigpLmNvbnRhaW5lcjtcclxuICAgICAgbWFwID0gdGhpcy5jZXNpdW1TZXJ2aWNlLmdldE1hcCgpO1xyXG4gICAgfVxyXG4gICAgaWYgKG1hcElkKSB7XHJcbiAgICAgIG1hcCA9IHRoaXMubWFwc01hbmFnZXIuZ2V0TWFwKG1hcElkKTtcclxuICAgICAgaWYgKCFtYXApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1hcCBub3QgZm91bmQgd2l0aCBpZDogJHttYXBJZH1gKTtcclxuICAgICAgfVxyXG4gICAgICBjYW1lcmFTZXJ2aWNlID0gbWFwLmdldENhbWVyYVNlcnZpY2UoKTtcclxuICAgICAgbWFwQ29udGFpbmVyID0gbWFwLmdldENlc2l1bVZpZXdlcigpLmNvbnRhaW5lcjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWNhbWVyYVNlcnZpY2UgfHwgIW1hcENvbnRhaW5lcikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBmdW5jdGlvbiBtdXN0IHJlY2VpdmUgYSBtYXBJZCBpZiB0aGUgc2VydmljZSB3YXNuJ3QgaW5pdGlhbGl6ZWRgKTtcclxuICAgIH1cclxuICAgIHRoaXMuZGlzYWJsZShtYXBJZCk7XHJcbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgIG1hcENvbnRhaW5lci5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XHJcbiAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xyXG4gICAgY29udGFpbmVyLnN0eWxlLndpZHRoID0gJzEwMCUnO1xyXG4gICAgY29udGFpbmVyLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcclxuICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSAnMCc7XHJcbiAgICBjb250YWluZXIuc3R5bGUubGVmdCA9ICcwJztcclxuICAgIG1hcENvbnRhaW5lci5hcHBlbmRDaGlsZChjb250YWluZXIpO1xyXG4gICAgY29uc3QgbWFwWm9vbURhdGE6IFpvb21EYXRhID0geyBjb250YWluZXIgfTtcclxuICAgIHRoaXMubWFwc1pvb21FbGVtZW50cy5zZXQobWFwSWQgfHwgdGhpcy5jZXNpdW1TZXJ2aWNlLmdldE1hcCgpLmdldElkKCksIG1hcFpvb21EYXRhKTtcclxuICAgIGxldCBtb3VzZSA9IHtcclxuICAgICAgZW5kWDogMCxcclxuICAgICAgZW5kWTogMCxcclxuICAgICAgc3RhcnRYOiAwLFxyXG4gICAgICBzdGFydFk6IDAsXHJcbiAgICB9O1xyXG4gICAgbGV0IGJvcmRlckVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkO1xyXG5cclxuICAgIGNvbnRhaW5lci5vbm1vdXNlZG93biA9IGUgPT4ge1xyXG4gICAgICBpZiAoZS5idXR0b24gIT09IGZpbmFsT3B0aW9ucy5tb3VzZUJ1dHRvbikge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICBpZiAoIWJvcmRlckVsZW1lbnQpIHtcclxuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLm9uU3RhcnQpIHtcclxuICAgICAgICAgIG9wdGlvbnMub25TdGFydChtYXApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgcmVjdCA9IChlLmN1cnJlbnRUYXJnZXQgYXMgYW55KS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICBjb25zdCBvZmZzZXRYID0gZS5jbGllbnRYIC0gcmVjdC5sZWZ0O1xyXG4gICAgICAgIGNvbnN0IG9mZnNldFkgPSBlLmNsaWVudFkgLSByZWN0LnRvcDtcclxuICAgICAgICBtb3VzZS5zdGFydFggPSBvZmZzZXRYO1xyXG4gICAgICAgIG1vdXNlLnN0YXJ0WSA9IG9mZnNldFk7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgICAgIGJvcmRlckVsZW1lbnQuY2xhc3NOYW1lID0gJ3pvb20tdG8tcmVjdGFuZ2xlLWJvcmRlcic7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS5ib3JkZXIgPSBmaW5hbE9wdGlvbnMuYm9yZGVyU3R5bGU7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBmaW5hbE9wdGlvbnMuYmFja2dyb3VuZENvbG9yO1xyXG4gICAgICAgIGJvcmRlckVsZW1lbnQuc3R5bGUubGVmdCA9IG1vdXNlLnN0YXJ0WCArICdweCc7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS50b3AgPSBtb3VzZS5zdGFydFkgKyAncHgnO1xyXG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChib3JkZXJFbGVtZW50KTtcclxuICAgICAgICBtYXBab29tRGF0YS5ib3JkZXJFbGVtZW50ID0gYm9yZGVyRWxlbWVudDtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBjb250YWluZXIub25tb3VzZXVwID0gZSA9PiB7XHJcbiAgICAgIGlmIChib3JkZXJFbGVtZW50KSB7XHJcbiAgICAgICAgbGV0IHpvb21BcHBsaWVkO1xyXG4gICAgICAgIGlmIChtb3VzZSAmJiBNYXRoLmFicyhtb3VzZS5lbmRYIC0gbW91c2Uuc3RhcnRYKSAqIE1hdGguYWJzKG1vdXNlLmVuZFkgLSBtb3VzZS5zdGFydFkpID4gZmluYWxPcHRpb25zLnRocmVzaG9sZCkge1xyXG4gICAgICAgICAgem9vbUFwcGxpZWQgPSB0aGlzLnpvb21DYW1lcmFUb1JlY3RhbmdsZShcclxuICAgICAgICAgICAgY2FtZXJhU2VydmljZSxcclxuICAgICAgICAgICAgbW91c2UsXHJcbiAgICAgICAgICAgIGZpbmFsT3B0aW9ucy5hbmltYXRpb25EdXJhdGlvbkluU2Vjb25kcyxcclxuICAgICAgICAgICAgZmluYWxPcHRpb25zLFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5yZW1vdmUoKTtcclxuICAgICAgICBib3JkZXJFbGVtZW50ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIG1hcFpvb21EYXRhLmJvcmRlckVsZW1lbnQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgbW91c2UgPSB7XHJcbiAgICAgICAgICBlbmRYOiAwLFxyXG4gICAgICAgICAgZW5kWTogMCxcclxuICAgICAgICAgIHN0YXJ0WDogMCxcclxuICAgICAgICAgIHN0YXJ0WTogMCxcclxuICAgICAgICB9O1xyXG4gICAgICAgIGlmICghIWZpbmFsT3B0aW9ucy5vbkNvbXBsZXRlKSB7XHJcbiAgICAgICAgICBmaW5hbE9wdGlvbnMub25Db21wbGV0ZShtYXApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZmluYWxPcHRpb25zLmF1dG9EaXNhYmxlT25ab29tICYmIHpvb21BcHBsaWVkKSB7XHJcbiAgICAgICAgICB0aGlzLmRpc2FibGUobWFwSWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBjb250YWluZXIub25tb3VzZW1vdmUgPSBlID0+IHtcclxuICAgICAgaWYgKGJvcmRlckVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCByZWN0ID0gKGUuY3VycmVudFRhcmdldCBhcyBhbnkpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIGNvbnN0IG9mZnNldFggPSBlLmNsaWVudFggLSByZWN0LmxlZnQ7XHJcbiAgICAgICAgY29uc3Qgb2Zmc2V0WSA9IGUuY2xpZW50WSAtIHJlY3QudG9wO1xyXG4gICAgICAgIG1vdXNlLmVuZFggPSBvZmZzZXRYO1xyXG4gICAgICAgIG1vdXNlLmVuZFkgPSBvZmZzZXRZO1xyXG4gICAgICAgIGJvcmRlckVsZW1lbnQuc3R5bGUud2lkdGggPSBNYXRoLmFicyhtb3VzZS5lbmRYIC0gbW91c2Uuc3RhcnRYKSArICdweCc7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS5oZWlnaHQgPSBNYXRoLmFicyhtb3VzZS5lbmRZIC0gbW91c2Uuc3RhcnRZKSArICdweCc7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS5sZWZ0ID0gTWF0aC5taW4obW91c2Uuc3RhcnRYLCBtb3VzZS5lbmRYKSArICdweCc7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS50b3AgPSBNYXRoLm1pbihtb3VzZS5zdGFydFksIG1vdXNlLmVuZFkpICsgJ3B4JztcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCByZXNldE9uRXNjYXBlUHJlc3MgPSBlID0+IHtcclxuICAgICAgaWYgKGUua2V5Q29kZSA9PT0gZmluYWxPcHRpb25zLnJlc2V0S2V5Q29kZSAmJiBib3JkZXJFbGVtZW50KSB7XHJcbiAgICAgICAgYm9yZGVyRWxlbWVudC5yZW1vdmUoKTtcclxuICAgICAgICBib3JkZXJFbGVtZW50ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIG1hcFpvb21EYXRhLmJvcmRlckVsZW1lbnQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgbW91c2UgPSB7XHJcbiAgICAgICAgICBlbmRYOiAwLFxyXG4gICAgICAgICAgZW5kWTogMCxcclxuICAgICAgICAgIHN0YXJ0WDogMCxcclxuICAgICAgICAgIHN0YXJ0WTogMCxcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHJlc2V0T25Fc2NhcGVQcmVzcyk7XHJcbiAgICBtYXBab29tRGF0YS5yZXNldE9uRXNjYXBlUHJlc3NGdW5jID0gcmVzZXRPbkVzY2FwZVByZXNzO1xyXG4gIH1cclxuXHJcbiAgZGlzYWJsZShtYXBJZD86IHN0cmluZykge1xyXG4gICAgaWYgKCF0aGlzLmNlc2l1bVNlcnZpY2UgJiYgIW1hcElkKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignSWYgdGhlIHNlcnZpY2Ugd2FzIG5vdCBpbml0aWFsaXplZCB3aXRoIENlc2l1bVNlcnZpY2UsIG1hcElkIG11c3QgYmUgcHJvdmlkZWQnKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGRhdGEgPSB0aGlzLm1hcHNab29tRWxlbWVudHMuZ2V0KG1hcElkIHx8IHRoaXMuY2VzaXVtU2VydmljZS5nZXRNYXAoKS5nZXRJZCgpKTtcclxuICAgIGlmIChkYXRhKSB7XHJcbiAgICAgIGRhdGEuY29udGFpbmVyLnJlbW92ZSgpO1xyXG4gICAgICBpZiAoZGF0YS5ib3JkZXJFbGVtZW50KSB7XHJcbiAgICAgICAgZGF0YS5ib3JkZXJFbGVtZW50LnJlbW92ZSgpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChkYXRhLnJlc2V0T25Fc2NhcGVQcmVzc0Z1bmMpIHtcclxuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZGF0YS5yZXNldE9uRXNjYXBlUHJlc3NGdW5jKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5tYXBzWm9vbUVsZW1lbnRzLmRlbGV0ZShtYXBJZCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHpvb21DYW1lcmFUb1JlY3RhbmdsZShcclxuICAgIGNhbWVyYVNlcnZpY2U6IENhbWVyYVNlcnZpY2UsXHJcbiAgICBwb3NpdGlvbnM6IHsgZW5kWDogbnVtYmVyOyBlbmRZOiBudW1iZXI7IHN0YXJ0WDogbnVtYmVyOyBzdGFydFk6IG51bWJlciB9LFxyXG4gICAgYW5pbWF0aW9uRHVyYXRpb24sXHJcbiAgICBvcHRpb25zLFxyXG4gICk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgY2FtZXJhID0gY2FtZXJhU2VydmljZS5nZXRDYW1lcmEoKTtcclxuICAgIGNvbnN0IGNhcnRlc2lhbjEgPSBjYW1lcmEucGlja0VsbGlwc29pZCh7IHg6IHBvc2l0aW9ucy5zdGFydFgsIHk6IHBvc2l0aW9ucy5zdGFydFkgfSk7XHJcbiAgICBjb25zdCBjYXJ0ZXNpYW4yID0gY2FtZXJhLnBpY2tFbGxpcHNvaWQoeyB4OiBwb3NpdGlvbnMuZW5kWCwgeTogcG9zaXRpb25zLmVuZFkgfSk7XHJcbiAgICBpZiAoIWNhcnRlc2lhbjEgfHwgIWNhcnRlc2lhbjIpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgY29uc3QgY2FydG9ncmFwaGljMSA9IENlc2l1bS5DYXJ0b2dyYXBoaWMuZnJvbUNhcnRlc2lhbihjYXJ0ZXNpYW4xKTtcclxuICAgIGNvbnN0IGNhcnRvZ3JhcGhpYzIgPSBDZXNpdW0uQ2FydG9ncmFwaGljLmZyb21DYXJ0ZXNpYW4oY2FydGVzaWFuMik7XHJcbiAgICBjYW1lcmFTZXJ2aWNlLmNhbWVyYUZseVRvKHtcclxuICAgICAgZGVzdGluYXRpb246IG5ldyBDZXNpdW0uUmVjdGFuZ2xlKFxyXG4gICAgICAgIE1hdGgubWluKGNhcnRvZ3JhcGhpYzEubG9uZ2l0dWRlLCBjYXJ0b2dyYXBoaWMyLmxvbmdpdHVkZSksXHJcbiAgICAgICAgTWF0aC5taW4oY2FydG9ncmFwaGljMS5sYXRpdHVkZSwgY2FydG9ncmFwaGljMi5sYXRpdHVkZSksXHJcbiAgICAgICAgTWF0aC5tYXgoY2FydG9ncmFwaGljMS5sb25naXR1ZGUsIGNhcnRvZ3JhcGhpYzIubG9uZ2l0dWRlKSxcclxuICAgICAgICBNYXRoLm1heChjYXJ0b2dyYXBoaWMxLmxhdGl0dWRlLCBjYXJ0b2dyYXBoaWMyLmxhdGl0dWRlKSxcclxuICAgICAgKSxcclxuICAgICAgb3JpZW50YXRpb246IG9wdGlvbnMua2VlcFJvdGF0aW9uID8geyBoZWFkaW5nOiBjYW1lcmEuaGVhZGluZyB9IDogdW5kZWZpbmVkLFxyXG4gICAgICBkdXJhdGlvbjogYW5pbWF0aW9uRHVyYXRpb24sXHJcbiAgICB9KTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxufVxyXG4iXX0=