UNPKG

@eliorar/angular-cesium

Version:

Angular library for working with Cesium.

237 lines 34.1 kB
import { Injectable, Optional } from '@angular/core'; import { Cartographic, Rectangle } from 'cesium'; import * as i0 from "@angular/core"; import * as i1 from "../../angular-cesium/services/maps-manager/maps-manager.service"; import * as i2 from "../../angular-cesium/services/camera/camera.service"; import * as i3 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 (!mapId) { map = this.mapsManager.getMap(); if (!map) { throw new Error(`Map not found`); } mapId = map.getId(); mapContainer = this.cesiumService.getViewer().container; } else { 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, 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.mapsManager && !mapId) { throw new Error('If the service was not initialized with MapsManager, mapId must be provided'); } if (!mapId) { const map = this.mapsManager.getMap(); mapId = map.getId(); } const data = this.mapsZoomElements.get(mapId); 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 = Cartographic.fromCartesian(cartesian1); const cartographic2 = Cartographic.fromCartesian(cartesian2); cameraService.cameraFlyTo({ destination: new 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.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ZoomToRectangleService, deps: [{ token: i1.MapsManagerService }, { token: i2.CameraService, optional: true }, { token: i3.CesiumService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); ZoomToRectangleService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ZoomToRectangleService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ZoomToRectangleService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.MapsManagerService }, { type: i2.CameraService, decorators: [{ type: Optional }] }, { type: i3.CesiumService, decorators: [{ type: Optional }] }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9vbS10by1yZWN0YW5nbGUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItY2VzaXVtL3NyYy9saWIvYW5ndWxhci1jZXNpdW0td2lkZ2V0cy9zZXJ2aWNlcy96b29tLXRvLXJlY3RhbmdsZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxVQUFVLEVBQUUsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBQyxZQUFZLEVBQUUsU0FBUyxFQUFDLE1BQU0sUUFBUSxDQUFDOzs7OztBQVkvQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFDRztBQUVILE1BQU0sQ0FBTixJQUFZLFlBSVg7QUFKRCxXQUFZLFlBQVk7SUFDdEIsK0NBQVEsQ0FBQTtJQUNSLG1EQUFVLENBQUE7SUFDVixpREFBUyxDQUFBO0FBQ1gsQ0FBQyxFQUpXLFlBQVksS0FBWixZQUFZLFFBSXZCO0FBR0QsTUFBTSxPQUFPLHNCQUFzQjtJQUNqQyxZQUNVLFdBQStCLEVBQzNCLGFBQTRCLEVBQzVCLGFBQTRCO1FBRmhDLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQVFqQyxxQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztRQUMvQyxtQkFBYyxHQUFHO1lBQ3ZCLDBCQUEwQixFQUFFLEdBQUc7WUFDL0IsWUFBWSxFQUFFLEVBQUU7WUFDaEIsV0FBVyxFQUFFLDJCQUEyQjtZQUN4QyxlQUFlLEVBQUUsaUJBQWlCO1lBQ2xDLGlCQUFpQixFQUFFLElBQUk7WUFDdkIsU0FBUyxFQUFFLENBQUM7WUFDWixZQUFZLEVBQUUsSUFBSTtZQUNsQixXQUFXLEVBQUUsWUFBWSxDQUFDLElBQUk7U0FDL0IsQ0FBQztJQWZDLENBQUM7SUFpQkosSUFBSSxDQUFDLGFBQTRCLEVBQUUsYUFBNEI7UUFDN0QsSUFBSSxDQUFDLGFBQWEs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UixRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3RhYmxlLCBPcHRpb25hbH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0NhcnRvZ3JhcGhpYywgUmVjdGFuZ2xlfSBmcm9tICdjZXNpdW0nO1xuaW1wb3J0IHtNYXBzTWFuYWdlclNlcnZpY2V9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL21hcHMtbWFuYWdlci9tYXBzLW1hbmFnZXIuc2VydmljZSc7XG5pbXBvcnQge0NhbWVyYVNlcnZpY2V9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL2NhbWVyYS9jYW1lcmEuc2VydmljZSc7XG5pbXBvcnQge0Nlc2l1bVNlcnZpY2V9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL2Nlc2l1bS9jZXNpdW0uc2VydmljZSc7XG5pbXBvcnQge0FjTWFwQ29tcG9uZW50fSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9jb21wb25lbnRzL2FjLW1hcC9hYy1tYXAuY29tcG9uZW50JztcblxuaW50ZXJmYWNlIFpvb21EYXRhIHtcbiAgY29udGFpbmVyOiBIVE1MRWxlbWVudDtcbiAgYm9yZGVyRWxlbWVudD86IEhUTUxFbGVtZW50O1xuICByZXNldE9uRXNjYXBlUHJlc3NGdW5jPzogRXZlbnRMaXN0ZW5lck9yRXZlbnRMaXN0ZW5lck9iamVjdDtcbn1cblxuLyoqXG4gKiBUaGUgU2VydmljZSBpcyBhcyBhIFwiem9vbSB0byByZWN0YW5nbGVcIiB0b29sXG4gKlxuICogZXhhbXBsZTpcbiAqIGBgYFxuICogY29uc3RydWN0b3IoXG4gKiAgIHByaXZhdGUgY2FtZXJhU2VydmljZTogQ2FtZXJhU2VydmljZSxcbiAqICAgcHJpdmF0ZSBjZXNpdW1TZXJ2aWNlOiBDZXNpdW1TZXJ2aWNlLFxuICogICBwcml2YXRlIHpvb21Ub1JlY3RhbmdsZVNlcnZpY2U6IFpvb21Ub1JlY3RhbmdsZVNlcnZpY2UsXG4gKiApIHtcbiAqICAgdGhpcy56b29tVG9SZWN0YW5nbGVTZXJ2aWNlLmluaXQoY2VzaXVtU2VydmljZSwgY2FtZXJhU2VydmljZSk7XG4gKiB9XG4gKiAuLi5cbiAqIHRoaXMuem9vbVRvUmVjdGFuZ2xlU2VydmljZS5hY3RpdmF0ZSh7b25Db21wbGV0ZTogKCkgPT4gdGhpcy56b29tVG9SZWN0YW5nbGVTZXJ2aWNlLmRpc2FibGUoKX0pO1xuICogYGBgXG4gKlxuICogYGluaXQoKWAgLSBpbml0aWFsaXplIHRoZSBzZXJ2aWNlIHdpdGggQ2FtZXJhU2VydmljZSBhbmQgQ2VzaXVtU2VydmljZS5cbiAqIElmIG5vIG1hcElkIGlzIHByb3ZpZGVkIHRvIGFjdGl2YXRlKCkgLSBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgY2FsbGluZyBgYWN0aXZhdGUoKWAuXG4gKlxuICogYGRpc2FibGUoKWAgLSBkaXNhYmxlcyB0aGUgdG9vbC5cbiAqXG4gKiBgYWN0aXZhdGUoKWAgLVxuICogQHBhcmFtIG9wdGlvbnNcbiAqIHtcbiAqICBvblN0YXJ0IC0gb3B0aW9uYWwgLSBhIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgdXNlciBzdGFydCBkcmF3aW5nIHRoZSByZWN0YW5nbGVcbiAqICBvbkNvbXBsZXRlIC0gb3B0aW9uYWwgLSBhIGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgdG9vbCB6b29tIGluXG4gKiAgYXV0b0Rpc2FibGVPblpvb20gLSBvcHRpb25hbCAtIGRldGVybWluZXMgaWYgdGhlIHRvb2wgc2hvdWxkIGF1dG8gZGlzYWJsZSBhZnRlciB6b29tIC0gZGVmYXVsdDogdHJ1ZVxuICogIGFuaW1hdGlvbkR1cmF0aW9uSW5TZWNvbmRzIC0gb3B0aW9uYWwgLSB6b29tIGFuaW1hdGlvbiBkdXJhdGlvbiBpbiBzZWNvbmRzIC0gZGVmYXVsdDogMC41XG4gKiAgYm9yZGVyU3R5bGUgLSBvcHRpb25hbCAtIHRoZSBzdHlsZSBvZiB0aGUgcmVjdGFuZ2xlIGVsZW1lbnQgYm9yZGVyIC0gZGVmYXVsdDogJzNweCBkYXNoZWQgI0ZGRkZGRidcbiAqICBiYWNrZ3JvdW5kQ29sb3IgLSBvcHRpb25hbCAtIHRoZSBiYWNrZ3JvdW5kIGNvbG9yIG9mIHRoZSByZWN0YW5nbGUgZWxlbWVudCAtIGRlZmF1bHQ6ICd0cmFuc3BhcmVudCdcbiAqICByZXNldEtleUNvZGUgLSBvcHRpb25hbCAtIHRoZSBrZXkgY29kZSBvZiB0aGUga2V5IHRoYXQgaXMgdXNlZCB0byByZXNldCB0aGUgZHJhd2luZyBvZiB0aGUgcmVjdGFuZ2xlIC0gZGVmYXVsdDogMjcgKEVTQyBrZXkpXG4gKiAgdGhyZXNob2xkIC0gb3B0aW9uYWwgLSB0aGUgbWluaW11bSBhcmVhIG9mIHRoZSBzY3JlZW4gcmVjdGFuZ2xlIChpbiBwaXhlbHMpIHRoYXQgaXMgcmVxdWlyZWQgdG8gcGVyZm9ybSB6b29tIC0gZGVmYXVsdDogOVxuICogIGtlZXBSb3RhdGlvbiAtIG9wdGlvbmFsIC0gd2hldGhlciBvciBub3QgdG8ga2VlcCB0aGUgcm90YXRpb24gd2hlbiB6b29taW5nIGluIC0gZGVmYXVsdDogdHJ1ZVxuICogIG1vdXNlQnV0dG9uIC0gb3B0aW9uYWwgLSBzZXRzIHRoZSBtb3VzZSBidXR0b24gZm9yIGRyYXdpbmcgdGhlIHJlY3RhbmdsZSAtIGRlZmF1bHQ6IGxlZnQgbW91c2UgYnV0dG9uICgwKVxuICogfVxuICogQHBhcmFtIG1hcElkIC0gb3B0aW9uYWwgLSB0aGUgbWFwSWQgb2YgdGhlIG1hcCB0aGF0IHRoZSB0b29sIHdpbGwgYmUgdXNlZCBpbi5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTW91c2VCdXR0b25zIHtcbiAgTEVGVCA9IDAsXG4gIE1JRERMRSA9IDEsXG4gIFJJR0hUID0gMixcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFpvb21Ub1JlY3RhbmdsZVNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG1hcHNNYW5hZ2VyOiBNYXBzTWFuYWdlclNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgY2FtZXJhU2VydmljZTogQ2FtZXJhU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBjZXNpdW1TZXJ2aWNlOiBDZXNpdW1TZXJ2aWNlLFxuICApIHt9XG5cbiAgcHJpdmF0ZSBjYW1lcmFTZXJ2aWNlOiBDYW1lcmFTZXJ2aWNlO1xuICBwcml2YXRlIGNlc2l1bVNlcnZpY2U6IENlc2l1bVNlcnZpY2U7XG5cbiAgcHJpdmF0ZSBtYXBzWm9vbUVsZW1lbnRzID0gbmV3IE1hcDxzdHJpbmcsIFpvb21EYXRhPigpO1xuICBwcml2YXRlIGRlZmF1bHRPcHRpb25zID0ge1xuICAgIGFuaW1hdGlvbkR1cmF0aW9uSW5TZWNvbmRzOiAwLjUsXG4gICAgcmVzZXRLZXlDb2RlOiAyNyxcbiAgICBib3JkZXJTdHlsZTogJzJweCBzb2xpZCByZ2JhKDAsMCwwLDAuNSknLFxuICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwwLDAsMC4yKScsXG4gICAgYXV0b0Rpc2FibGVPblpvb206IHRydWUsXG4gICAgdGhyZXNob2xkOiA5LFxuICAgIGtlZXBSb3RhdGlvbjogdHJ1ZSxcbiAgICBtb3VzZUJ1dHRvbjogTW91c2VCdXR0b25zLkxFRlQsXG4gIH07XG5cbiAgaW5pdChjZXNpdW1TZXJ2aWNlOiBDZXNpdW1TZXJ2aWNlLCBjYW1lcmFTZXJ2aWNlOiBDYW1lcmFTZXJ2aWNlKSB7XG4gICAgdGhpcy5jYW1lcmFTZXJ2aWNlID0gY2FtZXJhU2VydmljZTtcbiAgICB0aGlzLmNlc2l1bVNlcnZpY2UgPSBjZXNpdW1TZXJ2aWNlO1xuICB9XG5cbiAgYWN0aXZhdGUoXG4gICAgb3B0aW9uczoge1xuICAgICAgb25TdGFydD86IChhY01hcD86IEFjTWFwQ29tcG9uZW50KSA9PiBhbnk7XG4gICAgICBvbkNvbXBsZXRlPzogKGFjTWFwPzogQWNNYXBDb21wb25lbnQpID0+IGFueTtcbiAgICAgIG1vdXNlQnV0dG9uPzogTW91c2VCdXR0b25zO1xuICAgICAgYXV0b0Rpc2FibGVPblpvb20/OiBib29sZWFuO1xuICAgICAgYW5pbWF0aW9uRHVyYXRpb25JblNlY29uZHM/OiBudW1iZXI7XG4gICAgICB0aHJlc2hvbGQ/OiBudW1iZXI7XG4gICAgICBrZWVwUm90YXRpb24/OiBib29sZWFuO1xuICAgICAgYm9yZGVyU3R5bGU/OiBzdHJpbmc7XG4gICAgICBiYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmc7XG4gICAgICByZXNldEtleUNvZGU/OiBudW1iZXI7XG4gICAgfSA9IHt9LFxuICAgIG1hcElkPzogc3RyaW5nLFxuICApIHtcbiAgICBpZiAoKCF0aGlzLmNhbWVyYVNlcnZpY2UgfHwgIXRoaXMuY2VzaXVtU2VydmljZSkgJiYgIW1hcElkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSBmdW5jdGlvbiBtdXN0IHJlY2VpdmUgYSBtYXBJZCBpZiB0aGUgc2VydmljZSB3YXNuJ3QgaW5pdGlhbGl6ZWRgKTtcbiAgICB9XG4gICAgY29uc3QgZmluYWxPcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5kZWZhdWx0T3B0aW9ucywgb3B0aW9ucyk7XG4gICAgbGV0IGNhbWVyYVNlcnZpY2UgPSB0aGlzLmNhbWVyYVNlcnZpY2U7XG4gICAgbGV0IG1hcENvbnRhaW5lcjtcbiAgICBsZXQgbWFwO1xuICAgIGlmICghbWFwSWQpIHtcbiAgICAgIG1hcCA9IHRoaXMubWFwc01hbmFnZXIuZ2V0TWFwKCk7XG4gICAgICBpZiAoIW1hcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1hcCBub3QgZm91bmRgKTtcbiAgICAgIH1cbiAgICAgIG1hcElkID0gbWFwLmdldElkKCk7XG4gICAgICBtYXBDb250YWluZXIgPSB0aGlzLmNlc2l1bVNlcnZpY2UuZ2V0Vmlld2VyKCkuY29udGFpbmVyO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXAgPSB0aGlzLm1hcHNNYW5hZ2VyLmdldE1hcChtYXBJZCk7XG4gICAgICBpZiAoIW1hcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1hcCBub3QgZm91bmQgd2l0aCBpZDogJHttYXBJZH1gKTtcbiAgICAgIH1cbiAgICAgIGNhbWVyYVNlcnZpY2UgPSBtYXAuZ2V0Q2FtZXJhU2VydmljZSgpO1xuICAgICAgbWFwQ29udGFpbmVyID0gbWFwLmdldENlc2l1bVZpZXdlcigpLmNvbnRhaW5lcjtcbiAgICB9XG5cbiAgICBpZiAoIWNhbWVyYVNlcnZpY2UgfHwgIW1hcENvbnRhaW5lcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgZnVuY3Rpb24gbXVzdCByZWNlaXZlIGEgbWFwSWQgaWYgdGhlIHNlcnZpY2Ugd2Fzbid0IGluaXRpYWxpemVkYCk7XG4gICAgfVxuICAgIHRoaXMuZGlzYWJsZShtYXBJZCk7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgbWFwQ29udGFpbmVyLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICBjb250YWluZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIGNvbnRhaW5lci5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICBjb250YWluZXIuc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIGNvbnRhaW5lci5zdHlsZS50b3AgPSAnMCc7XG4gICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSAnMCc7XG4gICAgbWFwQ29udGFpbmVyLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gICAgY29uc3QgbWFwWm9vbURhdGE6IFpvb21EYXRhID0geyBjb250YWluZXIgfTtcbiAgICB0aGlzLm1hcHNab29tRWxlbWVudHMuc2V0KG1hcElkLCBtYXBab29tRGF0YSk7XG4gICAgbGV0IG1vdXNlID0ge1xuICAgICAgZW5kWDogMCxcbiAgICAgIGVuZFk6IDAsXG4gICAgICBzdGFydFg6IDAsXG4gICAgICBzdGFydFk6IDAsXG4gICAgfTtcbiAgICBsZXQgYm9yZGVyRWxlbWVudDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQ7XG5cbiAgICBjb250YWluZXIub25tb3VzZWRvd24gPSBlID0+IHtcbiAgICAgIGlmIChlLmJ1dHRvbiAhPT0gZmluYWxPcHRpb25zLm1vdXNlQnV0dG9uKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghYm9yZGVyRWxlbWVudCkge1xuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLm9uU3RhcnQpIHtcbiAgICAgICAgICBvcHRpb25zLm9uU3RhcnQobWFwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlY3QgPSAoZS5jdXJyZW50VGFyZ2V0IGFzIGFueSkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IG9mZnNldFggPSBlLmNsaWVudFggLSByZWN0LmxlZnQ7XG4gICAgICAgIGNvbnN0IG9mZnNldFkgPSBlLmNsaWVudFkgLSByZWN0LnRvcDtcbiAgICAgICAgbW91c2Uuc3RhcnRYID0gb2Zmc2V0WDtcbiAgICAgICAgbW91c2Uuc3RhcnRZID0gb2Zmc2V0WTtcbiAgICAgICAgYm9yZGVyRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBib3JkZXJFbGVtZW50LmNsYXNzTmFtZSA9ICd6b29tLXRvLXJlY3RhbmdsZS1ib3JkZXInO1xuICAgICAgICBib3JkZXJFbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS5ib3JkZXIgPSBmaW5hbE9wdGlvbnMuYm9yZGVyU3R5bGU7XG4gICAgICAgIGJvcmRlckVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gZmluYWxPcHRpb25zLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS5sZWZ0ID0gbW91c2Uuc3RhcnRYICsgJ3B4JztcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS50b3AgPSBtb3VzZS5zdGFydFkgKyAncHgnO1xuICAgICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoYm9yZGVyRWxlbWVudCk7XG4gICAgICAgIG1hcFpvb21EYXRhLmJvcmRlckVsZW1lbnQgPSBib3JkZXJFbGVtZW50O1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb250YWluZXIub25tb3VzZXVwID0gZSA9PiB7XG4gICAgICBpZiAoYm9yZGVyRWxlbWVudCkge1xuICAgICAgICBsZXQgem9vbUFwcGxpZWQ7XG4gICAgICAgIGlmIChtb3VzZSAmJiBNYXRoLmFicyhtb3VzZS5lbmRYIC0gbW91c2Uuc3RhcnRYKSAqIE1hdGguYWJzKG1vdXNlLmVuZFkgLSBtb3VzZS5zdGFydFkpID4gZmluYWxPcHRpb25zLnRocmVzaG9sZCkge1xuICAgICAgICAgIHpvb21BcHBsaWVkID0gdGhpcy56b29tQ2FtZXJhVG9SZWN0YW5nbGUoXG4gICAgICAgICAgICBjYW1lcmFTZXJ2aWNlLFxuICAgICAgICAgICAgbW91c2UsXG4gICAgICAgICAgICBmaW5hbE9wdGlvbnMuYW5pbWF0aW9uRHVyYXRpb25JblNlY29uZHMsXG4gICAgICAgICAgICBmaW5hbE9wdGlvbnMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBib3JkZXJFbGVtZW50LnJlbW92ZSgpO1xuICAgICAgICBib3JkZXJFbGVtZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICBtYXBab29tRGF0YS5ib3JkZXJFbGVtZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICBtb3VzZSA9IHtcbiAgICAgICAgICBlbmRYOiAwLFxuICAgICAgICAgIGVuZFk6IDAsXG4gICAgICAgICAgc3RhcnRYOiAwLFxuICAgICAgICAgIHN0YXJ0WTogMCxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKCEhZmluYWxPcHRpb25zLm9uQ29tcGxldGUpIHtcbiAgICAgICAgICBmaW5hbE9wdGlvbnMub25Db21wbGV0ZShtYXApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaW5hbE9wdGlvbnMuYXV0b0Rpc2FibGVPblpvb20gJiYgem9vbUFwcGxpZWQpIHtcbiAgICAgICAgICB0aGlzLmRpc2FibGUobWFwSWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnRhaW5lci5vbm1vdXNlbW92ZSA9IGUgPT4ge1xuICAgICAgaWYgKGJvcmRlckVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgcmVjdCA9IChlLmN1cnJlbnRUYXJnZXQgYXMgYW55KS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3Qgb2Zmc2V0WCA9IGUuY2xpZW50WCAtIHJlY3QubGVmdDtcbiAgICAgICAgY29uc3Qgb2Zmc2V0WSA9IGUuY2xpZW50WSAtIHJlY3QudG9wO1xuICAgICAgICBtb3VzZS5lbmRYID0gb2Zmc2V0WDtcbiAgICAgICAgbW91c2UuZW5kWSA9IG9mZnNldFk7XG4gICAgICAgIGJvcmRlckVsZW1lbnQuc3R5bGUud2lkdGggPSBNYXRoLmFicyhtb3VzZS5lbmRYIC0gbW91c2Uuc3RhcnRYKSArICdweCc7XG4gICAgICAgIGJvcmRlckVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gTWF0aC5hYnMobW91c2UuZW5kWSAtIG1vdXNlLnN0YXJ0WSkgKyAncHgnO1xuICAgICAgICBib3JkZXJFbGVtZW50LnN0eWxlLmxlZnQgPSBNYXRoLm1pbihtb3VzZS5zdGFydFgsIG1vdXNlLmVuZFgpICsgJ3B4JztcbiAgICAgICAgYm9yZGVyRWxlbWVudC5zdHlsZS50b3AgPSBNYXRoLm1pbihtb3VzZS5zdGFydFksIG1vdXNlLmVuZFkpICsgJ3B4JztcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgcmVzZXRPbkVzY2FwZVByZXNzID0gZSA9PiB7XG4gICAgICBpZiAoZS5rZXlDb2RlID09PSBmaW5hbE9wdGlvbnMucmVzZXRLZXlDb2RlICYmIGJvcmRlckVsZW1lbnQpIHtcbiAgICAgICAgYm9yZGVyRWxlbWVudC5yZW1vdmUoKTtcbiAgICAgICAgYm9yZGVyRWxlbWVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgbWFwWm9vbURhdGEuYm9yZGVyRWxlbWVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgbW91c2UgPSB7XG4gICAgICAgICAgZW5kWDogMCxcbiAgICAgICAgICBlbmRZOiAwLFxuICAgICAgICAgIHN0YXJ0WDogMCxcbiAgICAgICAgICBzdGFydFk6IDAsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgcmVzZXRPbkVzY2FwZVByZXNzKTtcbiAgICBtYXBab29tRGF0YS5yZXNldE9uRXNjYXBlUHJlc3NGdW5jID0gcmVzZXRPbkVzY2FwZVByZXNzO1xuICB9XG5cbiAgcHVibGljIGRpc2FibGUobWFwSWQ/OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMubWFwc01hbmFnZXIgJiYgIW1hcElkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lmIHRoZSBzZXJ2aWNlIHdhcyBub3QgaW5pdGlhbGl6ZWQgd2l0aCBNYXBzTWFuYWdlciwgbWFwSWQgbXVzdCBiZSBwcm92aWRlZCcpO1xuICAgIH1cbiAgICBpZiAoIW1hcElkKSB7XG4gICAgICBjb25zdCBtYXAgPSB0aGlzLm1hcHNNYW5hZ2VyLmdldE1hcCgpO1xuICAgICAgbWFwSWQgPSBtYXAuZ2V0SWQoKTtcbiAgICB9XG4gICAgY29uc3QgZGF0YSA9IHRoaXMubWFwc1pvb21FbGVtZW50cy5nZXQobWFwSWQpO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBkYXRhLmNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgIGlmIChkYXRhLmJvcmRlckVsZW1lbnQpIHtcbiAgICAgICAgZGF0YS5ib3JkZXJFbGVtZW50LnJlbW92ZSgpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGEucmVzZXRPbkVzY2FwZVByZXNzRnVuYykge1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgZGF0YS5yZXNldE9uRXNjYXBlUHJlc3NGdW5jKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5tYXBzWm9vbUVsZW1lbnRzLmRlbGV0ZShtYXBJZCk7XG4gIH1cblxuICBwcml2YXRlIHpvb21DYW1lcmFUb1JlY3RhbmdsZShcbiAgICBjYW1lcmFTZXJ2aWNlOiBDYW1lcmFTZXJ2aWNlLFxuICAgIHBvc2l0aW9uczogeyBlbmRYOiBudW1iZXI7IGVuZFk6IG51bWJlcjsgc3RhcnRYOiBudW1iZXI7IHN0YXJ0WTogbnVtYmVyIH0sXG4gICAgYW5pbWF0aW9uRHVyYXRpb24sXG4gICAgb3B0aW9ucyxcbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY2FtZXJhID0gY2FtZXJhU2VydmljZS5nZXRDYW1lcmEoKTtcbiAgICBjb25zdCBjYXJ0ZXNpYW4xID0gY2FtZXJhLnBpY2tFbGxpcHNvaWQoeyB4OiBwb3NpdGlvbnMuc3RhcnRYLCB5OiBwb3NpdGlvbnMuc3RhcnRZIH0pO1xuICAgIGNvbnN0IGNhcnRlc2lhbjIgPSBjYW1lcmEucGlja0VsbGlwc29pZCh7IHg6IHBvc2l0aW9ucy5lbmRYLCB5OiBwb3NpdGlvbnMuZW5kWSB9KTtcbiAgICBpZiAoIWNhcnRlc2lhbjEgfHwgIWNhcnRlc2lhbjIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgY2FydG9ncmFwaGljMSA9IENhcnRvZ3JhcGhpYy5mcm9tQ2FydGVzaWFuKGNhcnRlc2lhbjEpO1xuICAgIGNvbnN0IGNhcnRvZ3JhcGhpYzIgPSBDYXJ0b2dyYXBoaWMuZnJvbUNhcnRlc2lhbihjYXJ0ZXNpYW4yKTtcbiAgICBjYW1lcmFTZXJ2aWNlLmNhbWVyYUZseVRvKHtcbiAgICAgIGRlc3RpbmF0aW9uOiBuZXcgUmVjdGFuZ2xlKFxuICAgICAgICBNYXRoLm1pbihjYXJ0b2dyYXBoaWMxLmxvbmdpdHVkZSwgY2FydG9ncmFwaGljMi5sb25naXR1ZGUpLFxuICAgICAgICBNYXRoLm1pbihjYXJ0b2dyYXBoaWMxLmxhdGl0dWRlLCBjYXJ0b2dyYXBoaWMyLmxhdGl0dWRlKSxcbiAgICAgICAgTWF0aC5tYXgoY2FydG9ncmFwaGljMS5sb25naXR1ZGUsIGNhcnRvZ3JhcGhpYzIubG9uZ2l0dWRlKSxcbiAgICAgICAgTWF0aC5tYXgoY2FydG9ncmFwaGljMS5sYXRpdHVkZSwgY2FydG9ncmFwaGljMi5sYXRpdHVkZSksXG4gICAgICApLFxuICAgICAgb3JpZW50YXRpb246IG9wdGlvbnMua2VlcFJvdGF0aW9uID8geyBoZWFkaW5nOiBjYW1lcmEuaGVhZGluZyB9IDogdW5kZWZpbmVkLFxuICAgICAgZHVyYXRpb246IGFuaW1hdGlvbkR1cmF0aW9uLFxuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG4iXX0=