UNPKG

@dlr-eoc/map-cesium

Version:

This is a angular module that exports a cesium component that can handle UKIS layers. See @dlr-eoc/services-layers for supported types.

310 lines 54.1 kB
import { Component, ViewEncapsulation, Input, ViewChild } from '@angular/core'; import { MapState } from '@dlr-eoc/services-map-state'; import { Subject } from 'rxjs'; import { skip } from 'rxjs/operators'; import { ScreenSpaceEventHandler, ScreenSpaceEventType, GeoJsonDataSource } from '@cesium/engine'; import * as i0 from "@angular/core"; import * as i1 from "./map-cesium.service"; export class MapCesiumComponent { constructor(mapSvc) { this.mapSvc = mapSvc; this.subs = []; this.mapCreated = new Subject(); this.initState = true; } ngOnInit() { if (!this.twoDlayersSvc) { console.error(`provide a LayersService as Input to ukis-map-cesium`); } if (!this.mapStateSvc) { console.error(`provide a MapStateService as Input to ukis-map-cesium`); } this.mapSvc.removeAll2DLayers(); //Set start time, if available if (this.startTime) { this.mapSvc.initTime(this.startTime); } } ngAfterViewInit() { this.initMap(); this.subscribeToLayers(); /** Get last state from mapStateSvc and set it, so a User can set the initial MapState in a component */ const oldMapState = this.mapStateSvc.getMapState().getValue(); this.setMapState(oldMapState); // set viewAngle and rotation seperatly again, as their values are not set by the viewer the first time this.mapSvc.setViewAngle(oldMapState.viewAngle); this.mapSvc.setRotation(oldMapState.rotation); /** Subscribe to map events when the map is completely created */ this.subscribeToMapEvents(); /** Subscribe to mapStateSvc */ this.subscribeToMapState(); } ngOnDestroy() { /** * Set the last MapState on Destroy. When the component is reinitialized, this MapState is used */ const lastMapState = this.calcMapStateFromCamera('user'); this.mapStateSvc.setMapState(lastMapState); /** clean up all events on destroy */ this.subs.forEach(s => s.unsubscribe()); if (this.viewer?.scene?.primitives) { this.viewer.imageryLayers.removeAll(); this.viewer.dataSources.removeAll(); this.viewer.scene.primitives.removeAll(); this.viewer.scene.primitives.destroy(); } this.mapSvc.destroyLayerGrpoups(); } initMap() { if (this.timeInterval) { this.mapSvc.setTimeInterval(this.timeInterval); } this.mapSvc.setControls(this.controls); const cesiumView = this.mapSvc.createMap(this.mapDivView.nativeElement); this.viewer = cesiumView.viewer; this.mapCreated.next(true); } subscribeToLayers() { // 2D layer if (this.twoDlayersSvc) { const onBaselayers = this.twoDlayersSvc.getBaseLayers().subscribe(layers => this.addUpdateBaseLayers(layers)); this.subs.push(onBaselayers); const onLayers = this.twoDlayersSvc.getLayers().subscribe(layers => this.addUpdate2DLayers(layers, 'layers')); this.subs.push(onLayers); const onOverlays = this.twoDlayersSvc.getOverlays().subscribe(layers => this.addUpdate2DLayers(layers, 'overlays')); this.subs.push(onOverlays); } // 3D layer if (this.threeDlayersSvc) { const onTerrainLayers = this.threeDlayersSvc.getBaseLayers().subscribe(layers => this.addUpdateTerrainLayers(layers)); this.subs.push(onTerrainLayers); const on3DLayers = this.threeDlayersSvc.getLayers().subscribe(layers => this.addUpdate3DLayers(layers, 'layers')); this.subs.push(on3DLayers); } } subscribeToMapState() { if (this.mapStateSvc) { const mapStateOn = this.mapStateSvc.getMapState().pipe(skip(1)).subscribe(state => this.setMapState(state)); this.subs.push(mapStateOn); } } setMapState(mapState) { const lastAction = this.mapStateSvc.getLastAction().getValue(); if (mapState.options.notifier === 'user') { if (lastAction === 'setExtent') { this.mapSvc.setExtent(mapState.extent, true); } else if (lastAction === 'setState') { this.mapSvc.setZoom(mapState.zoom); this.mapSvc.setCenter(mapState.center); this.mapSvc.setRotation(mapState.rotation); this.mapSvc.setViewAngle(mapState.viewAngle); } else if (lastAction === 'setRotation') { this.mapSvc.setRotation(mapState.rotation); } else if (lastAction === 'setAngle') { this.mapSvc.setViewAngle(mapState.viewAngle); } } else if (mapState.options.notifier === 'map') { this.mapSvc.updateTime(mapState.time); } } calcMapStateFromCamera(notifier) { const time = this.mapStateSvc.getMapState().getValue().time; const zoom = this.mapSvc.getZoom(); const newCenter = this.mapSvc.getCenter(); const extent = this.mapSvc.getCurrentExtent(); const viewAngle = this.mapSvc.getViewAngle(); const rotation = this.mapSvc.getRotation(); return new MapState(zoom, newCenter, { notifier }, extent, time, viewAngle, rotation); } subscribeToMapEvents() { this.viewer.camera.changed.addEventListener((evt) => { const ms = this.calcMapStateFromCamera('map'); this.mapStateSvc.setMapState(ms); }); if (this.controls.infoBox) { //Changing entitiy parameters for the display in he infoBox window this.viewer.selectedEntityChanged.addEventListener(() => { const entity = this.viewer.selectedEntity; //change infoBox title const titleDiv = this.viewer.infoBox.container.getElementsByClassName('cesium-infoBox-title')[0]; titleDiv.innerHTML = 'Layer Attributes'; if (entity) { if (entity.entityCollection?.owner instanceof GeoJsonDataSource) { titleDiv.innerHTML = entity.entityCollection.owner.name; entity.name = entity.entityCollection.owner.name; } else { entity.name = 'Layer Attributes'; } if (entity.description) { const description = entity.description.getValue(this.mapSvc.cesiumCurrentTime); const contentDiv = this.viewer.infoBox.container.getElementsByClassName('cesium-infoBox-content')[0]; contentDiv.innerHTML = description; entity.name = 'Layer Attributes'; //TODO: Fetch layer info for formatting the getFeatureInfo data, like specific units or value rounding. } } }); } //Show the popup on click if (this.controls.enablePopups) { const cesiumEventHandler = new ScreenSpaceEventHandler(this.viewer.scene.canvas); cesiumEventHandler.setInputAction((e) => { //get camera ray at picked position and get layer features at picked location const ray = this.viewer.camera.getPickRay(e.position); const entity = this.viewer.scene.imageryLayers.pickImageryLayerFeatures(ray, this.viewer.scene); if (entity) { const popupContent = document.getElementById("map_cesium_popup_content"); const popupDiv = popupContent.parentElement; const entity_x = e.position.x; const entity_y = e.position.y; //hide popup while waiting for the content to load popupDiv.style.display = 'none'; entity?.then(e => { //write description text to popup popupContent.innerHTML = e[0].description; popupDiv.style.left = (entity_x - 58) + 'px'; popupDiv.style.top = (entity_y - 78) + 'px'; popupDiv.style.display = 'block'; }); } }, ScreenSpaceEventType.LEFT_CLICK); //Hide the popup cesiumEventHandler.setInputAction((e) => { const popup = document.getElementById("cesium_popup_div"); popup.style.display = 'none'; }, ScreenSpaceEventType.RIGHT_DOWN); } } addUpdateBaseLayers(layers) { /** if length of layers fom LayersService has changed add new layers */ if (layers.length > 0) { if (layers.length !== this.mapSvc.getAll2DLayersSize('baselayers')) { this.add2DBaseLayers(layers); } else { /** if layers already on the map - length not changed - update them */ this.update2DBaseLayers(layers); } } } add2DBaseLayers(layers) { if (layers.length > 0) { // set only one visible at start const visiblelayers = layers.filter(l => l.visible === true); if (visiblelayers.length === 0) { layers[0].visible = true; } else if (visiblelayers.length > 1) { layers.forEach(l => l.visible = false); layers[0].visible = true; } this.mapSvc.set2DUkisLayers(layers, 'baselayers'); } } update2DBaseLayers(layers) { this.mapSvc.update2DLayerVisibility(layers, 'baselayers'); } addUpdateTerrainLayers(layers) { /** if length of layers fom LayersService has changed add new layers */ if (layers.length > 0) { /* if (layers.length !== this.mapSvc.get3DLayersSize('baselayers')) { this.addTerrainLayers(layers); } else { */ /** if layers already on the map - length not changed - update them */ this.mapSvc.update3DLayerVisibility(layers, 'baselayers'); //} } } addTerrainLayers(layers) { if (layers.length > 0) { // set only one visible at start const visiblelayers = layers.filter(l => l.visible === true); if (visiblelayers.length === 0) { layers[0].visible = true; } else if (visiblelayers.length > 1) { layers.forEach(l => l.visible = false); layers[0].visible = true; } this.mapSvc.set3DUkisLayers(layers, 'baselayers'); } } addUpdate2DLayers(layers, filtertype) { /** if length of layers (visible) has changed add new layers */ if (layers.length !== this.mapSvc.getAll2DLayersSize(filtertype)) { this.addLayers(layers, filtertype); } else { /** if layers already on the map - length not changed - update them */ this.updateLayers(layers, filtertype); } } addLayers(layers, filtertype) { this.mapSvc.set2DUkisLayers(layers, filtertype); } updateLayers(layers, filtertype) { // handle layer Visible change this.mapSvc.update2DLayerVisibility(layers, filtertype); this.mapSvc.update2DLayerOpacity(layers, filtertype); this.mapSvc.update2DLayerZIndex(layers, filtertype); this.mapSvc.updateDataSourceZIndex(layers, filtertype); } addUpdate3DLayers(layers, filtertype) { /** if length of layers (visible) has changed add new layers */ if (layers.length !== this.mapSvc.get3DLayersSize(filtertype)) { this.add3DLayers(layers, filtertype); } else { /** if layers already on the map - length not changed - update them */ this.update3DLayers(layers, filtertype); } } add3DLayers(layers, filtertype) { this.mapSvc.set3DUkisLayers(layers, filtertype); } update3DLayers(layers, filtertype) { // handle layer Visible change this.mapSvc.update3DLayerVisibility(layers, filtertype); this.mapSvc.update3DLayerOpacity(layers, filtertype); } closeCesiumPopup() { const popup = document.getElementById("cesium_popup_div"); popup.style.display = 'none'; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: MapCesiumComponent, deps: [{ token: i1.MapCesiumService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: MapCesiumComponent, isStandalone: true, selector: "ukis-map-cesium", inputs: { twoDlayersSvc: "twoDlayersSvc", threeDlayersSvc: "threeDlayersSvc", mapStateSvc: ["mapState", "mapStateSvc"], controls: "controls", timeInterval: "timeInterval", startTime: "startTime" }, viewQueries: [{ propertyName: "mapDivView", first: true, predicate: ["cesiumMapDiv"], descendants: true }, { propertyName: "creditDivView", first: true, predicate: ["cesiumCreditDiv"], descendants: true }], ngImport: i0, template: "<div #cesiumMapDiv class=\"map cesiumMap\">\r\n <div class=\"cesium-popup\" id=\"cesium_popup_div\">\r\n <a class=\"cesium-popup-closer\" (click)=\"closeCesiumPopup()\"></a>\r\n <div class=\"cesium-popup-content\" id=\"map_cesium_popup_content\">\r\n </div>\r\n </div>\r\n</div>\r\n<div #cesiumCreditDiv class=\"cesiumCredits\"></div>\r\n", styles: ["@charset \"UTF-8\";:root{--ukis-crosshair-color: #ff0004;--ukis-popup-bg-color: rgb(238, 238, 238);--ukis-drop-shadow: drop-shadow(0 1px 4px rgba(0, 0, 0, .2))}.cesium-viewer .cesium-viewer-cesiumWidgetContainer{height:100%}.cesiumMap{width:100%;height:100%;position:relative;overflow:hidden}.cesium-viewer-bottom .cesium-credit-logoContainer{display:none!important}.cesium-credit-lightbox ul{padding-left:20px}.cesium-infoBox{top:0;left:0;margin:.5rem;background-color:var(--ukis-popup-bg-color);filter:var(--ukis-drop-shadow);border:none;border-radius:0;box-shadow:none;z-index:1000000}.cesium-infoBox .cesium-infoBox-title{background-color:var(--ukis-popup-bg-color);border-bottom-left-radius:0;color:var(--clr-global-font-color);height:30px;font-weight:600;padding-top:.5rem}.cesium-infoBox button.cesium-infoBox-camera{display:none}.cesium-infoBox button.cesium-infoBox-close{color:var(--clr-global-font-color)}.cesium-infoBox-content{padding:.75rem;color:var(--clr-global-font-color)}.cesium-infoBox-defaultTable{background-color:var(--ukis-popup-bg-color);color:var(--clr-global-font-color)}.cesium-infoBox-defaultTable tr td:first-child{font-weight:600}.cesium-selection-wrapper svg{fill:var(--ukis-popup-bg-color);stroke:#0072a3;stroke-width:1.1px}.cesium-popup{position:absolute;background-color:var(--ukis-popup-bg-color);-webkit-filter:var(--ukis-drop-shadow);filter:var(--ukis-drop-shadow);padding:15px;border-radius:2px;top:0;left:0;margin:.5rem;min-width:280px;display:none;z-index:1000000}.cesium-popup .cesium-popup-closer{text-decoration:none;position:absolute;top:0;right:8px;cursor:pointer}.cesium-popup .cesium-popup-closer:after{content:\"\\2716\"}.cesium-popup:after,.cesium-popup:before{top:100%;border:solid transparent;content:\" \";height:0;width:0;position:absolute;pointer-events:none}.cesium-popup:after{border-top-color:var(--ukis-popup-bg-color);border-width:10px;left:48px;margin-left:-10px}.cesium-popup:before{border-width:11px;left:48px;margin-left:-11px}.cesium-popup.hidden{visibility:hidden}\n"], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: MapCesiumComponent, decorators: [{ type: Component, args: [{ selector: 'ukis-map-cesium', encapsulation: ViewEncapsulation.None, standalone: true, template: "<div #cesiumMapDiv class=\"map cesiumMap\">\r\n <div class=\"cesium-popup\" id=\"cesium_popup_div\">\r\n <a class=\"cesium-popup-closer\" (click)=\"closeCesiumPopup()\"></a>\r\n <div class=\"cesium-popup-content\" id=\"map_cesium_popup_content\">\r\n </div>\r\n </div>\r\n</div>\r\n<div #cesiumCreditDiv class=\"cesiumCredits\"></div>\r\n", styles: ["@charset \"UTF-8\";:root{--ukis-crosshair-color: #ff0004;--ukis-popup-bg-color: rgb(238, 238, 238);--ukis-drop-shadow: drop-shadow(0 1px 4px rgba(0, 0, 0, .2))}.cesium-viewer .cesium-viewer-cesiumWidgetContainer{height:100%}.cesiumMap{width:100%;height:100%;position:relative;overflow:hidden}.cesium-viewer-bottom .cesium-credit-logoContainer{display:none!important}.cesium-credit-lightbox ul{padding-left:20px}.cesium-infoBox{top:0;left:0;margin:.5rem;background-color:var(--ukis-popup-bg-color);filter:var(--ukis-drop-shadow);border:none;border-radius:0;box-shadow:none;z-index:1000000}.cesium-infoBox .cesium-infoBox-title{background-color:var(--ukis-popup-bg-color);border-bottom-left-radius:0;color:var(--clr-global-font-color);height:30px;font-weight:600;padding-top:.5rem}.cesium-infoBox button.cesium-infoBox-camera{display:none}.cesium-infoBox button.cesium-infoBox-close{color:var(--clr-global-font-color)}.cesium-infoBox-content{padding:.75rem;color:var(--clr-global-font-color)}.cesium-infoBox-defaultTable{background-color:var(--ukis-popup-bg-color);color:var(--clr-global-font-color)}.cesium-infoBox-defaultTable tr td:first-child{font-weight:600}.cesium-selection-wrapper svg{fill:var(--ukis-popup-bg-color);stroke:#0072a3;stroke-width:1.1px}.cesium-popup{position:absolute;background-color:var(--ukis-popup-bg-color);-webkit-filter:var(--ukis-drop-shadow);filter:var(--ukis-drop-shadow);padding:15px;border-radius:2px;top:0;left:0;margin:.5rem;min-width:280px;display:none;z-index:1000000}.cesium-popup .cesium-popup-closer{text-decoration:none;position:absolute;top:0;right:8px;cursor:pointer}.cesium-popup .cesium-popup-closer:after{content:\"\\2716\"}.cesium-popup:after,.cesium-popup:before{top:100%;border:solid transparent;content:\" \";height:0;width:0;position:absolute;pointer-events:none}.cesium-popup:after{border-top-color:var(--ukis-popup-bg-color);border-width:10px;left:48px;margin-left:-10px}.cesium-popup:before{border-width:11px;left:48px;margin-left:-11px}.cesium-popup.hidden{visibility:hidden}\n"] }] }], ctorParameters: () => [{ type: i1.MapCesiumService }], propDecorators: { mapDivView: [{ type: ViewChild, args: ['cesiumMapDiv'] }], creditDivView: [{ type: ViewChild, args: ['cesiumCreditDiv'] }], twoDlayersSvc: [{ type: Input, args: ['twoDlayersSvc'] }], threeDlayersSvc: [{ type: Input, args: ['threeDlayersSvc'] }], mapStateSvc: [{ type: Input, args: ['mapState'] }], controls: [{ type: Input, args: ['controls'] }], timeInterval: [{ type: Input, args: ['timeInterval'] }], startTime: [{ type: Input, args: ['startTime'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLWNlc2l1bS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXAtY2VzaXVtL3NyYy9saWIvbWFwLWNlc2l1bS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXAtY2VzaXVtL3NyYy9saWIvbWFwLWNlc2l1bS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLGlCQUFpQixFQUFFLEtBQUssRUFBNEIsU0FBUyxFQUFjLE1BQU0sZUFBZSxDQUFDO0FBRTdILE9BQU8sRUFBb0IsUUFBUSxFQUFtQixNQUFNLDZCQUE2QixDQUFDO0FBQzFGLE9BQU8sRUFBZ0IsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUl0QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBb0NsRyxNQUFNLE9BQU8sa0JBQWtCO0lBZ0I3QixZQUFvQixNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQUo1QyxTQUFJLEdBQW1CLEVBQUUsQ0FBQztRQUMxQixlQUFVLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUNwQyxjQUFTLEdBQUcsSUFBSSxDQUFDO0lBRStCLENBQUM7SUFFakQsUUFBUTtRQUNOLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sQ0FBQyxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBRWhDLDhCQUE4QjtRQUM5QixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7SUFDRCxlQUFlO1FBQ2IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFHekIsd0dBQXdHO1FBQ3hHLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDOUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM5Qix1R0FBdUc7UUFDdkcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QyxrRUFBa0U7UUFDbEUsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBRTdCLENBQUM7SUFFRCxXQUFXO1FBQ1Q7O1dBRUc7UUFDSCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFM0MscUNBQXFDO1FBQ3JDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDeEMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDekMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3pDLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUdPLE9BQU87UUFDYixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3hFLElBQUksQ0FBQyxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQUNoQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRU8saUJBQWlCO1FBRXZCLFdBQVc7UUFDWCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzlHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTdCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzlHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRXpCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ3BILElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFFRCxXQUFXO1FBQ1gsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFFekIsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN0SCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUVoQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNsSCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUU3QixDQUFDO0lBQ0gsQ0FBQztJQUVPLG1CQUFtQjtRQUN6QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDNUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFTyxXQUFXLENBQUMsUUFBa0I7UUFDcEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMvRCxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ3pDLElBQUksVUFBVSxLQUFLLFdBQVcsRUFBRSxDQUFDO2dCQUMvQixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQy9DLENBQUM7aUJBQU0sSUFBSSxVQUFVLEtBQUssVUFBVSxFQUFFLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMvQyxDQUFDO2lCQUFNLElBQUksVUFBVSxLQUFLLGFBQWEsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0MsQ0FBQztpQkFBTSxJQUFJLFVBQVUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9DLENBQUM7UUFDSCxDQUFDO2FBQ0ksSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLFFBQVEsS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsQ0FBQztJQUNILENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxRQUFzQztRQUNuRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQztRQUM1RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzlDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDN0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMzQyxPQUFPLElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN4RixDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ2xELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUMsQ0FBQztZQUN4QixrRUFBa0U7WUFDcEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3RELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDO2dCQUMxQyxzQkFBc0I7Z0JBQ3RCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqRyxRQUFRLENBQUMsU0FBUyxHQUFHLGtCQUFrQixDQUFDO2dCQUN4QyxJQUFJLE1BQU0sRUFBRSxDQUFDO29CQUNYLElBQUcsTUFBTSxDQUFDLGdCQUFnQixFQUFFLEtBQUssWUFBWSxpQkFBaUIsRUFBQyxDQUFDO3dCQUM5RCxRQUFRLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO3dCQUN4RCxNQUFNLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO29CQUNuRCxDQUFDO3lCQUFJLENBQUM7d0JBQ0osTUFBTSxDQUFDLElBQUksR0FBRyxrQkFBa0IsQ0FBQztvQkFDbkMsQ0FBQztvQkFDRCxJQUFJLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQzt3QkFDdkIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO3dCQUMvRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsc0JBQXNCLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDckcsVUFBVSxDQUFDLFNBQVMsR0FBRyxXQUFXLENBQUM7d0JBQ25DLE1BQU0sQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7d0JBRWpDLHVHQUF1RztvQkFDekcsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxDQUFDO1FBRUQseUJBQXlCO1FBQ3pCLElBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUMsQ0FBQztZQUM3QixNQUFNLGtCQUFrQixHQUFHLElBQUksdUJBQXVCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakYsa0JBQWtCLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBSyxFQUFFLEVBQUU7Z0JBQzFDLDZFQUE2RTtnQkFDN0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUUsQ0FBQztnQkFDdkQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNoRyxJQUFHLE1BQU0sRUFBQyxDQUFDO29CQUNYLE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsMEJBQTBCLENBQUUsQ0FBQztvQkFDMUUsTUFBTSxRQUFRLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQztvQkFDNUMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7b0JBQzlCLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBO29CQUU3QixrREFBa0Q7b0JBQ2xELFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztvQkFFaEMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTt3QkFDZixpQ0FBaUM7d0JBQ2pDLFlBQVksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVksQ0FBQzt3QkFDM0MsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQyxRQUFRLEdBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO3dCQUMzQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDLFFBQVEsR0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7d0JBQzFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztvQkFDbkMsQ0FBQyxDQUNBLENBQUM7Z0JBQ0YsQ0FBQztZQUNILENBQUMsRUFBRSxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUVwQyxnQkFBZ0I7WUFDaEIsa0JBQWtCLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBSyxFQUFFLEVBQUU7Z0JBQzFDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQUUsQ0FBQztnQkFDM0QsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1lBQy9CLENBQUMsRUFBRSxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN0QyxDQUFDO0lBQ0gsQ0FBQztJQUdPLG1CQUFtQixDQUFDLE1BQWU7UUFDekMsdUVBQXVFO1FBQ3ZFLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QixJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO2dCQUNuRSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9CLENBQUM7aUJBQU0sQ0FBQztnQkFDTixzRUFBc0U7Z0JBQ3RFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNsQyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFTyxlQUFlLENBQUMsTUFBZTtRQUNyQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEIsZ0NBQWdDO1lBQ2hDLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDO1lBQzdELElBQUksYUFBYSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7WUFDM0IsQ0FBQztpQkFBTSxJQUFJLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxDQUFDO2dCQUN2QyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztZQUMzQixDQUFDO1lBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3BELENBQUM7SUFDSCxDQUFDO0lBRU8sa0JBQWtCLENBQUMsTUFBZTtRQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRU8sc0JBQXNCLENBQUMsTUFBZTtRQUM1Qyx1RUFBdUU7UUFDdkUsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RCOzt1QkFFVztZQUNYLHNFQUFzRTtZQUN0RSxJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztZQUMxRCxHQUFHO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxNQUFlO1FBQ3RDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QixnQ0FBZ0M7WUFDaEMsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLENBQUM7WUFDN0QsSUFBSSxhQUFhLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMvQixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztZQUMzQixDQUFDO2lCQUFNLElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLENBQUM7Z0JBQ3ZDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQzNCLENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDcEQsQ0FBQztJQUNILENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxNQUFlLEVBQUUsVUFBNEI7UUFFckUsK0RBQStEO1FBQy9ELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDakUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQzthQUFNLENBQUM7WUFDTixzRUFBc0U7WUFDdEUsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDeEMsQ0FBQztJQUNILENBQUM7SUFFTyxTQUFTLENBQUMsTUFBZSxFQUFFLFVBQTRCO1FBQzdELElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRU8sWUFBWSxDQUFDLE1BQWUsRUFBRSxVQUE0QjtRQUNoRSw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFFekQsQ0FBQztJQUVPLGlCQUFpQixDQUFDLE1BQWUsRUFBRSxVQUE0QjtRQUVyRSwrREFBK0Q7UUFDL0QsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDOUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDdkMsQ0FBQzthQUFNLENBQUM7WUFDTixzRUFBc0U7WUFDdEUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDMUMsQ0FBQztJQUNILENBQUM7SUFFTyxXQUFXLENBQUMsTUFBZSxFQUFFLFVBQTRCO1FBQy9ELElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRU8sY0FBYyxDQUFDLE1BQWUsRUFBRSxVQUE0QjtRQUNsRSw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVELGdCQUFnQjtRQUNkLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQUUsQ0FBQztRQUMzRCxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7SUFDL0IsQ0FBQzs4R0EzVFUsa0JBQWtCO2tHQUFsQixrQkFBa0IsZ2VDNUMvQiwrVkFRQTs7MkZEb0NhLGtCQUFrQjtrQkFQOUIsU0FBUzsrQkFDSSxpQkFBaUIsaUJBR1osaUJBQWlCLENBQUMsSUFBSSxjQUN6QixJQUFJO3FGQUlTLFVBQVU7c0JBQXBDLFNBQVM7dUJBQUMsY0FBYztnQkFDSyxhQUFhO3NCQUExQyxTQUFTO3VCQUFDLGlCQUFpQjtnQkFDSixhQUFhO3NCQUFwQyxLQUFLO3VCQUFDLGVBQWU7Z0JBQ0ksZUFBZTtzQkFBeEMsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBQ0wsV0FBVztzQkFBN0IsS0FBSzt1QkFBQyxVQUFVO2dCQUNFLFFBQVE7c0JBQTFCLEtBQUs7dUJBQUMsVUFBVTtnQkFDTSxZQUFZO3NCQUFsQyxLQUFLO3VCQUFDLGNBQWM7Z0JBQ0QsU0FBUztzQkFBNUIsS0FBSzt1QkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9uLCBJbnB1dCwgT25EZXN0cm95LCBBZnRlclZpZXdJbml0LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IElNYXBTdGF0ZU9wdGlvbnMsIE1hcFN0YXRlLCBNYXBTdGF0ZVNlcnZpY2UgfSBmcm9tICdAZGxyLWVvYy9zZXJ2aWNlcy1tYXAtc3RhdGUnO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgc2tpcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgTWFwQ2VzaXVtU2VydmljZSB9IGZyb20gJy4vbWFwLWNlc2l1bS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTGF5ZXJzU2VydmljZSwgTGF5ZXIsIFRGaWx0ZXJ0eXBlcywgVEZpbHRlcnR5cGVzVW5jYXAgfSBmcm9tICdAZGxyLWVvYy9zZXJ2aWNlcy1sYXllcnMnO1xyXG5pbXBvcnQgeyBWaWV3ZXIgfSBmcm9tICdAY2VzaXVtL3dpZGdldHMnO1xyXG5pbXBvcnQgeyBTY3JlZW5TcGFjZUV2ZW50SGFuZGxlciwgU2NyZWVuU3BhY2VFdmVudFR5cGUsIEdlb0pzb25EYXRhU291cmNlIH0gZnJvbSAnQGNlc2l1bS9lbmdpbmUnO1xyXG5cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUNlc2l1bUNvbnRyb2xzIHtcclxuICAvL1NlZTogaHR0cHM6Ly9jZXNpdW0uY29tL2xlYXJuL2Nlc2l1bWpzL3JlZi1kb2MvVmlld2VyLmh0bWwjLkNvbnN0cnVjdG9yT3B0aW9uc1xyXG4gIHRpbWVsaW5lPzogYm9vbGVhbjtcclxuICBhbmltYXRpb24/OiBib29sZWFuO1xyXG4gIHNjZW5lTW9kZVBpY2tlcj86IGJvb2xlYW47XHJcbiAgaG9tZUJ1dHRvbj86IGJvb2xlYW47XHJcbiAgYmFzZUxheWVyUGlja2VyPzogYm9vbGVhbjtcclxuICBnZW9jb2Rlcj86IGJvb2xlYW47XHJcbiAgbmF2aWdhdGlvbkhlbHBCdXR0b24/OiBib29sZWFuO1xyXG4gIG5hdmlnYXRpb25JbnN0cnVjdGlvbnNJbml0aWFsbHlWaXNpYmxlPzogYm9vbGVhbjtcclxuICBmdWxsc2NyZWVuQnV0dG9uPzogYm9vbGVhbjtcclxuICBzY2VuZTNET25seT86IGJvb2xlYW47XHJcbiAgaW5mb0JveD86IGJvb2xlYW47XHJcbiAgc2VsZWN0aW9uSW5kaWNhdG9yPzogYm9vbGVhbjtcclxuICBlbmFibGVQb3B1cHM/OiBib29sZWFuO1xyXG4gIC8vQWxzbyB5b3UgY2FuIGRlZmluZSBhbiBDZXNpdW0gaW9uIEFjY2VzcyBUb2tlbiwgaHR0cHM6Ly9jZXNpdW0uY29tL2xlYXJuL2lvbi9jZXNpdW0taW9uLWFjY2Vzcy10b2tlbnMvXHJcbiAgaW9uQWNjZXNzVG9rZW4/OiBzdHJpbmc7XHJcbiAgLy9JbiB0aGUgc2FtZSB3YXkgeW91IGNhbiBwcm92aWRlIGEgcGVyc29uYWwga2V5IGZvciBHb29nbGUgTWFwcywgaHR0cHM6Ly9jZXNpdW0uY29tL2xlYXJuL2Nlc2l1bWpzLWxlYXJuL2Nlc2l1bWpzLXBob3RvcmVhbGlzdGljLTNkLXRpbGVzL1xyXG4gIEdvb2dsZU1hcHNBcGlLZXk/OiBzdHJpbmc7XHJcbiAgLy9kZWZhdWx0IGdsb2JlIGNvbG9yIGFzIGhleCBzdHJpbmdcclxuICBnbG9iZUNvbG9yPzogc3RyaW5nO1xyXG59XHJcblxyXG5kZWNsYXJlIHR5cGUgVGdyb3VwZmlsdGVydHlwZSA9IFRGaWx0ZXJ0eXBlc1VuY2FwIHwgVEZpbHRlcnR5cGVzO1xyXG5cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICd1a2lzLW1hcC1jZXNpdW0nLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL21hcC1jZXNpdW0uY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vbWFwLWNlc2l1bS5jb21wb25lbnQuc2NzcyddLFxyXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcclxuICAgIHN0YW5kYWxvbmU6IHRydWVcclxufSlcclxuZXhwb3J0IGNsYXNzIE1hcENlc2l1bUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgQFZpZXdDaGlsZCgnY2VzaXVtTWFwRGl2JykgbWFwRGl2VmlldyE6IEVsZW1lbnRSZWY7XHJcbiAgQFZpZXdDaGlsZCgnY2VzaXVtQ3JlZGl0RGl2JykgY3JlZGl0RGl2VmlldyE6IEVsZW1lbnRSZWY7XHJcbiAgQElucHV0KCd0d29EbGF5ZXJzU3ZjJykgdHdvRGxheWVyc1N2YyE6IExheWVyc1NlcnZpY2U7XHJcbiAgQElucHV0KCd0aHJlZURsYXllcnNTdmMnKSB0aHJlZURsYXllcnNTdmMhOiBMYXllcnNTZXJ2aWNlO1xyXG4gIEBJbnB1dCgnbWFwU3RhdGUnKSBtYXBTdGF0ZVN2YyE6IE1hcFN0YXRlU2VydmljZTtcclxuICBASW5wdXQoJ2NvbnRyb2xzJykgY29udHJvbHMhOiBJQ2VzaXVtQ29udHJvbHM7XHJcbiAgQElucHV0KCd0aW1lSW50ZXJ2YWwnKSB0aW1lSW50ZXJ2YWw/OiBzdHJpbmdbXTtcclxuICBASW5wdXQoJ3N0YXJ0VGltZScpIHN0YXJ0VGltZT86IHN0cmluZyB8IG51bGw7XHJcblxyXG4gIHZpZXdlciE6IFZpZXdlcjtcclxuICBzdWJzOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xyXG4gIG1hcENyZWF0ZWQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xyXG4gIGluaXRTdGF0ZSA9IHRydWU7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbWFwU3ZjOiBNYXBDZXNpdW1TZXJ2aWNlKSB7IH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMudHdvRGxheWVyc1N2Yykge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBwcm92aWRlIGEgTGF5ZXJzU2VydmljZSBhcyBJbnB1dCB0byB1a2lzLW1hcC1jZXNpdW1gKTtcclxuICAgIH1cclxuICAgIGlmICghdGhpcy5tYXBTdGF0ZVN2Yykge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBwcm92aWRlIGEgTWFwU3RhdGVTZXJ2aWNlIGFzIElucHV0IHRvIHVraXMtbWFwLWNlc2l1bWApO1xyXG4gICAgfVxyXG4gICAgdGhpcy5tYXBTdmMucmVtb3ZlQWxsMkRMYXllcnMoKTtcclxuXHJcbiAgICAvL1NldCBzdGFydCB0aW1lLCBpZiBhdmFpbGFibGVcclxuICAgIGlmICh0aGlzLnN0YXJ0VGltZSkge1xyXG4gICAgICB0aGlzLm1hcFN2Yy5pbml0VGltZSh0aGlzLnN0YXJ0VGltZSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaW5pdE1hcCgpO1xyXG4gICAgdGhpcy5zdWJzY3JpYmVUb0xheWVycygpO1xyXG5cclxuXHJcbiAgICAvKiogR2V0IGxhc3Qgc3RhdGUgZnJvbSBtYXBTdGF0ZVN2YyBhbmQgc2V0IGl0LCBzbyBhIFVzZXIgY2FuIHNldCB0aGUgaW5pdGlhbCBNYXBTdGF0ZSBpbiBhIGNvbXBvbmVudCAqL1xyXG4gICAgY29uc3Qgb2xkTWFwU3RhdGUgPSB0aGlzLm1hcFN0YXRlU3ZjLmdldE1hcFN0YXRlKCkuZ2V0VmFsdWUoKTtcclxuICAgIHRoaXMuc2V0TWFwU3RhdGUob2xkTWFwU3RhdGUpO1xyXG4gICAgLy8gc2V0IHZpZXdBbmdsZSBhbmQgcm90YXRpb24gc2VwZXJhdGx5IGFnYWluLCBhcyB0aGVpciB2YWx1ZXMgYXJlIG5vdCBzZXQgYnkgdGhlIHZpZXdlciB0aGUgZmlyc3QgdGltZVxyXG4gICAgdGhpcy5tYXBTdmMuc2V0Vmlld0FuZ2xlKG9sZE1hcFN0YXRlLnZpZXdBbmdsZSk7XHJcbiAgICB0aGlzLm1hcFN2Yy5zZXRSb3RhdGlvbihvbGRNYXBTdGF0ZS5yb3RhdGlvbik7XHJcbiAgICAvKiogU3Vic2NyaWJlIHRvIG1hcCBldmVudHMgd2hlbiB0aGUgbWFwIGlzIGNvbXBsZXRlbHkgY3JlYXRlZCAgKi9cclxuICAgIHRoaXMuc3Vic2NyaWJlVG9NYXBFdmVudHMoKTtcclxuICAgIC8qKiBTdWJzY3JpYmUgdG8gbWFwU3RhdGVTdmMgKi9cclxuICAgIHRoaXMuc3Vic2NyaWJlVG9NYXBTdGF0ZSgpO1xyXG5cclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhlIGxhc3QgTWFwU3RhdGUgb24gRGVzdHJveS4gV2hlbiB0aGUgY29tcG9uZW50IGlzIHJlaW5pdGlhbGl6ZWQsIHRoaXMgTWFwU3RhdGUgaXMgdXNlZFxyXG4gICAgICovXHJcbiAgICBjb25zdCBsYXN0TWFwU3RhdGUgPSB0aGlzLmNhbGNNYXBTdGF0ZUZyb21DYW1lcmEoJ3VzZXInKTtcclxuICAgIHRoaXMubWFwU3RhdGVTdmMuc2V0TWFwU3RhdGUobGFzdE1hcFN0YXRlKTtcclxuXHJcbiAgICAvKiogY2xlYW4gdXAgYWxsIGV2ZW50cyBvbiBkZXN0cm95ICovXHJcbiAgICB0aGlzLnN1YnMuZm9yRWFjaChzID0+IHMudW5zdWJzY3JpYmUoKSk7XHJcbiAgICBpZiAodGhpcy52aWV3ZXI/LnNjZW5lPy5wcmltaXRpdmVzKSB7XHJcbiAgICAgIHRoaXMudmlld2VyLmltYWdlcnlMYXllcnMucmVtb3ZlQWxsKCk7XHJcbiAgICAgIHRoaXMudmlld2VyLmRhdGFTb3VyY2VzLnJlbW92ZUFsbCgpO1xyXG4gICAgICB0aGlzLnZpZXdlci5zY2VuZS5wcmltaXRpdmVzLnJlbW92ZUFsbCgpO1xyXG4gICAgICB0aGlzLnZpZXdlci5zY2VuZS5wcmltaXRpdmVzLmRlc3Ryb3koKTtcclxuICAgIH1cclxuICAgIHRoaXMubWFwU3ZjLmRlc3Ryb3lMYXllckdycG91cHMoKTtcclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIGluaXRNYXAoKSB7XHJcbiAgICBpZiAodGhpcy50aW1lSW50ZXJ2YWwpIHtcclxuICAgICAgdGhpcy5tYXBTdmMuc2V0VGltZUludGVydmFsKHRoaXMudGltZUludGVydmFsKTtcclxuICAgIH1cclxuICAgIHRoaXMubWFwU3ZjLnNldENvbnRyb2xzKHRoaXMuY29udHJvbHMpO1xyXG4gICAgY29uc3QgY2VzaXVtVmlldyA9IHRoaXMubWFwU3ZjLmNyZWF0ZU1hcCh0aGlzLm1hcERpdlZpZXcubmF0aXZlRWxlbWVudCk7XHJcbiAgICB0aGlzLnZpZXdlciA9IGNlc2l1bVZpZXcudmlld2VyO1xyXG4gICAgdGhpcy5tYXBDcmVhdGVkLm5leHQodHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN1YnNjcmliZVRvTGF5ZXJzKCkge1xyXG5cclxuICAgIC8vIDJEIGxheWVyXHJcbiAgICBpZiAodGhpcy50d29EbGF5ZXJzU3ZjKSB7XHJcbiAgICAgIGNvbnN0IG9uQmFzZWxheWVycyA9IHRoaXMudHdvRGxheWVyc1N2Yy5nZXRCYXNlTGF5ZXJzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZUJhc2VMYXllcnMobGF5ZXJzKSk7XHJcbiAgICAgIHRoaXMuc3Vicy5wdXNoKG9uQmFzZWxheWVycyk7XHJcblxyXG4gICAgICBjb25zdCBvbkxheWVycyA9IHRoaXMudHdvRGxheWVyc1N2Yy5nZXRMYXllcnMoKS5zdWJzY3JpYmUobGF5ZXJzID0+IHRoaXMuYWRkVXBkYXRlMkRMYXllcnMobGF5ZXJzLCAnbGF5ZXJzJykpO1xyXG4gICAgICB0aGlzLnN1YnMucHVzaChvbkxheWVycyk7XHJcblxyXG4gICAgICBjb25zdCBvbk92ZXJsYXlzID0gdGhpcy50d29EbGF5ZXJzU3ZjLmdldE92ZXJsYXlzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZTJETGF5ZXJzKGxheWVycywgJ292ZXJsYXlzJykpO1xyXG4gICAgICB0aGlzLnN1YnMucHVzaChvbk92ZXJsYXlzKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAzRCBsYXllclxyXG4gICAgaWYgKHRoaXMudGhyZWVEbGF5ZXJzU3ZjKSB7XHJcblxyXG4gICAgICBjb25zdCBvblRlcnJhaW5MYXllcnMgPSB0aGlzLnRocmVlRGxheWVyc1N2Yy5nZXRCYXNlTGF5ZXJzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZVRlcnJhaW5MYXllcnMobGF5ZXJzKSk7XHJcbiAgICAgIHRoaXMuc3Vicy5wdXNoKG9uVGVycmFpbkxheWVycyk7XHJcblxyXG4gICAgICBjb25zdCBvbjNETGF5ZXJzID0gdGhpcy50aHJlZURsYXllcnNTdmMuZ2V0TGF5ZXJzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZTNETGF5ZXJzKGxheWVycywgJ2xheWVycycpKTtcclxuICAgICAgdGhpcy5zdWJzLnB1c2gob24zRExheWVycyk7XHJcblxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb01hcFN0YXRlKCkge1xyXG4gICAgaWYgKHRoaXMubWFwU3RhdGVTdmMpIHtcclxuICAgICAgY29uc3QgbWFwU3RhdGVPbiA9IHRoaXMubWFwU3RhdGVTdmMuZ2V0TWFwU3RhdGUoKS5waXBlKHNraXAoMSkpLnN1YnNjcmliZShzdGF0ZSA9PiB0aGlzLnNldE1hcFN0YXRlKHN0YXRlKSk7XHJcbiAgICAgIHRoaXMuc3Vicy5wdXNoKG1hcFN0YXRlT24pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZXRNYXBTdGF0ZShtYXBTdGF0ZTogTWFwU3RhdGUpIHtcclxuICAgIGNvbnN0IGxhc3RBY3Rpb24gPSB0aGlzLm1hcFN0YXRlU3ZjLmdldExhc3RBY3Rpb24oKS5nZXRWYWx1ZSgpO1xyXG4gICAgaWYgKG1hcFN0YXRlLm9wdGlvbnMubm90aWZpZXIgPT09ICd1c2VyJykge1xyXG4gICAgICBpZiAobGFzdEFjdGlvbiA9PT0gJ3NldEV4dGVudCcpIHtcclxuICAgICAgICB0aGlzLm1hcFN2Yy5zZXRFeHRlbnQobWFwU3RhdGUuZXh0ZW50LCB0cnVlKTtcclxuICAgICAgfSBlbHNlIGlmIChsYXN0QWN0aW9uID09PSAnc2V0U3RhdGUnKSB7XHJcbiAgICAgICAgdGhpcy5tYXBTdmMuc2V0Wm9vbShtYXBTdGF0ZS56b29tKTtcclxuICAgICAgICB0aGlzLm1hcFN2Yy5zZXRDZW50ZXIobWFwU3RhdGUuY2VudGVyKTtcclxuICAgICAgICB0aGlzLm1hcFN2Yy5zZXRSb3RhdGlvbihtYXBTdGF0ZS5yb3RhdGlvbik7XHJcbiAgICAgICAgdGhpcy5tYXBTdmMuc2V0Vmlld0FuZ2xlKG1hcFN0YXRlLnZpZXdBbmdsZSk7XHJcbiAgICAgIH0gZWxzZSBpZiAobGFzdEFjdGlvbiA9PT0gJ3NldFJvdGF0aW9uJykge1xyXG4gICAgICAgIHRoaXMubWFwU3ZjLnNldFJvdGF0aW9uKG1hcFN0YXRlLnJvdGF0aW9uKTtcclxuICAgICAgfSBlbHNlIGlmIChsYXN0QWN0aW9uID09PSAnc2V0QW5nbGUnKSB7XHJcbiAgICAgICAgdGhpcy5tYXBTdmMuc2V0Vmlld0FuZ2xlKG1hcFN0YXRlLnZpZXdBbmdsZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKG1hcFN0YXRlLm9wdGlvbnMubm90aWZpZXIgPT09ICdtYXAnKSB7XHJcbiAgICAgIHRoaXMubWFwU3ZjLnVwZGF0ZVRpbWUobWFwU3RhdGUudGltZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNhbGNNYXBTdGF0ZUZyb21DYW1lcmEobm90aWZpZXI6IElNYXBTdGF0ZU9wdGlvbnNbJ25vdGlmaWVyJ10pe1xyXG4gICAgY29uc3QgdGltZSA9IHRoaXMubWFwU3RhdGVTdmMuZ2V0TWFwU3RhdGUoKS5nZXRWYWx1ZSgpLnRpbWU7XHJcbiAgICBjb25zdCB6b29tID0gdGhpcy5tYXBTdmMuZ2V0Wm9vbSgpO1xyXG4gICAgY29uc3QgbmV3Q2VudGVyID0gdGhpcy5tYXBTdmMuZ2V0Q2VudGVyKCk7XHJcbiAgICBjb25zdCBleHRlbnQgPSB0aGlzLm1hcFN2Yy5nZXRDdXJyZW50RXh0ZW50KCk7XHJcbiAgICBjb25zdCB2aWV3QW5nbGUgPSB0aGlzLm1hcFN2Yy5nZXRWaWV3QW5nbGUoKTtcclxuICAgIGNvbnN0IHJvdGF0aW9uID0gdGhpcy5tYXBTdmMuZ2V0Um90YXRpb24oKTtcclxuICAgIHJldHVybiBuZXcgTWFwU3RhdGUoem9vbSwgbmV3Q2VudGVyLCB7IG5vdGlmaWVyIH0sIGV4dGVudCwgdGltZSwgdmlld0FuZ2xlLCByb3RhdGlvbik7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN1YnNjcmliZVRvTWFwRXZlbnRzKCkge1xyXG4gICAgdGhpcy52aWV3ZXIuY2FtZXJhLmNoYW5nZWQuYWRkRXZlbnRMaXN0ZW5lcigoZXZ0KSA9PiB7XHJcbiAgICAgIGNvbnN0IG1zID0gdGhpcy5jYWxjTWFwU3RhdGVGcm9tQ2FtZXJhKCdtYXAnKTtcclxuICAgICAgdGhpcy5tYXBTdGF0ZVN2Yy5zZXRNYXBTdGF0ZShtcyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZih0aGlzLmNvbnRyb2xzLmluZm9Cb3gpe1xyXG4gICAgICAvL0NoYW5naW5nIGVudGl0aXkgcGFyYW1ldGVycyBmb3IgdGhlIGRpc3BsYXkgaW4gaGUgaW5mb0JveCB3aW5kb3dcclxuICAgIHRoaXMudmlld2VyLnNlbGVjdGVkRW50aXR5Q2hhbmdlZC5hZGRFdmVudExpc3RlbmVyKCgpID0+IHtcclxuICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy52aWV3ZXIuc2VsZWN0ZWRFbnRpdHk7XHJcbiAgICAgIC8vY2hhbmdlIGluZm9Cb3ggdGl0bGVcclxuICAgICAgY29uc3QgdGl0bGVEaXYgPSB0aGlzLnZpZXdlci5pbmZvQm94LmNvbnRhaW5lci5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdjZXNpdW0taW5mb0JveC10aXRsZScpWzBdO1xyXG4gICAgICB0aXRsZURpdi5pbm5lckhUTUwgPSAnTGF5ZXIgQXR0cmlidXRlcyc7XHJcbiAgICAgIGlmIChlbnRpdHkpIHtcclxuICAgICAgICBpZihlbnRpdHkuZW50aXR5Q29sbGVjdGlvbj8ub3duZXIgaW5zdGFuY2VvZiBHZW9Kc29uRGF0YVNvdXJjZSl7XHJcbiAgICAgICAgICB0aXRsZURpdi5pbm5lckhUTUwgPSBlbnRpdHkuZW50aXR5Q29sbGVjdGlvbi5vd25lci5uYW1lO1xyXG4gICAgICAgICAgZW50aXR5Lm5hbWUgPSBlbnRpdHkuZW50aXR5Q29sbGVjdGlvbi5vd25lci5uYW1lO1xyXG4gICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgZW50aXR5Lm5hbWUgPSAnTGF5ZXIgQXR0cmlidXRlcyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbnRpdHkuZGVzY3JpcHRpb24pIHtcclxuICAgICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZW50aXR5LmRlc2NyaXB0aW9uLmdldFZhbHVlKHRoaXMubWFwU3ZjLmNlc2l1bUN1cnJlbnRUaW1lKTtcclxuICAgICAgICAgIGNvbnN0IGNvbnRlbnREaXYgPSB0aGlzLnZpZXdlci5pbmZvQm94LmNvbnRhaW5lci5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdjZXNpdW0taW5mb0JveC1jb250ZW50JylbMF07XHJcbiAgICAgICAgICBjb250ZW50RGl2LmlubmVySFRNTCA9IGRlc2NyaXB0aW9uO1xyXG4gICAgICAgICAgZW50aXR5Lm5hbWUgPSAnTGF5ZXIgQXR0cmlidXRlcyc7XHJcblxyXG4gICAgICAgICAgLy9UT0RPOiBGZXRjaCBsYXllciBpbmZvIGZvciBmb3JtYXR0aW5nIHRoZSBnZXRGZWF0dXJlSW5mbyBkYXRhLCBsaWtlIHNwZWNpZmljIHVuaXRzIG9yIHZhbHVlIHJvdW5kaW5nLlxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy9TaG93IHRoZSBwb3B1cCBvbiBjbGlja1xyXG4gICAgaWYodGhpcy5jb250cm9scy5lbmFibGVQb3B1cHMpe1xyXG4gICAgICBjb25zdCBjZXNpdW1FdmVudEhhbmRsZXIgPSBuZXcgU2NyZWVuU3BhY2VFdmVudEhhbmRsZXIodGhpcy52aWV3ZXIuc2NlbmUuY2FudmFzKTtcclxuICAgICAgY2VzaXVtRXZlbnRIYW5kbGVyLnNldElucHV0QWN0aW9uKChlOmFueSkgPT4ge1xyXG4gICAgICAgIC8vZ2V0IGNhbWVyYSByYXkgYXQgcGlja2VkIHBvc2l0aW9uIGFuZCBnZXQgbGF5ZXIgZmVhdHVyZXMgYXQgcGlja2VkIGxvY2F0aW9uXHJcbiAgICAgICAgY29uc3QgcmF5ID0gdGhpcy52aWV3ZXIuY2FtZXJhLmdldFBpY2tSYXkoZS5wb3NpdGlvbikhO1xyXG4gICAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMudmlld2VyLnNjZW5lLmltYWdlcnlMYXllcnMucGlja0ltYWdlcnlMYXllckZlYXR1cmVzKHJheSwgdGhpcy52aWV3ZXIuc2NlbmUpO1xyXG4gICAgICAgIGlmKGVudGl0eSl7XHJcbiAgICAgICAgY29uc3QgcG9wdXBDb250ZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtYXBfY2VzaXVtX3BvcHVwX2NvbnRlbnRcIikhO1xyXG4gICAgICAgIGNvbnN0IHBvcHVwRGl2ID0gcG9wdXBDb250ZW50LnBhcmVudEVsZW1lbnQ7XHJcbiAgICAgICAgY29uc3QgZW50aXR5X3ggPSBlLnBvc2l0aW9uLng7XHJcbiAgICAgICAgY29uc3QgZW50aXR5X3kgPSBlLnBvc2l0aW9uLnlcclxuXHJcbiAgICAgICAgLy9oaWRlIHBvcHVwIHdoaWxlIHdhaXRpbmcgZm9yIHRoZSBjb250ZW50IHRvIGxvYWRcclxuICAgICAgICBwb3B1cERpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG5cclxuICAgICAgICBlbnRpdHk/LnRoZW4oZSA9PntcclxuICAgICAgICAgIC8vd3JpdGUgZGVzY3JpcHRpb24gdGV4dCB0byBwb3B1cFxyXG4gICAgICAgICAgcG9wdXBDb250ZW50LmlubmVySFRNTCA9IGVbMF0uZGVzY3JpcHRpb24hO1xyXG4gICAgICAgICAgcG9wdXBEaXYuc3R5bGUubGVmdCA9IChlbnRpdHlfeC01OCkgKyAncHgnO1xyXG4gICAgICAgICAgcG9wdXBEaXYuc3R5bGUudG9wID0gKGVudGl0eV95LTc4KSArICdweCc7XHJcbiAgICAgICAgICBwb3B1cERpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIFNjcmVlblNwYWNlRXZlbnRUeXBlLkxFRlRfQ0xJQ0spO1xyXG5cclxuICAgICAgLy9IaWRlIHRoZSBwb3B1cFxyXG4gICAgICBjZXNpdW1FdmVudEhhbmRsZXIuc2V0SW5wdXRBY3Rpb24oKGU6YW55KSA9PiB7XHJcbiAgICAgICAgY29uc3QgcG9wdXAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlc2l1bV9wb3B1cF9kaXZcIikhO1xyXG4gICAgICAgIHBvcHVwLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgIH0sIFNjcmVlblNwYWNlRXZlbnRUeXBlLlJJR0hUX0RPV04pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIHByaXZhdGUgYWRkVXBkYXRlQmFzZUxheWVycyhsYXllcnM6IExheWVyW10pIHtcclxuICAgIC8qKiBpZiBsZW5ndGggb2YgbGF5ZXJzIGZvbSBMYXllcnNTZXJ2aWNlIGhhcyBjaGFuZ2VkIGFkZCBuZXcgbGF5ZXJzICovXHJcbiAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgaWYgKGxheWVycy5sZW5ndGggIT09IHRoaXMubWFwU3ZjLmdldEFsbDJETGF5ZXJzU2l6ZSgnYmFzZWxheWVycycpKSB7XHJcbiAgICAgICAgdGhpcy5hZGQyREJhc2VMYXllcnMobGF5ZXJzKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvKiogaWYgbGF5ZXJzIGFscmVhZHkgb24gdGhlIG1hcCAtIGxlbmd0aCBub3QgY2hhbmdlZCAtIHVwZGF0ZSB0aGVtICovXHJcbiAgICAgICAgdGhpcy51cGRhdGUyREJhc2VMYXllcnMobGF5ZXJzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGQyREJhc2VMYXllcnMobGF5ZXJzOiBMYXllcltdKSB7XHJcbiAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgLy8gc2V0IG9ubHkgb25lIHZpc2libGUgYXQgc3RhcnRcclxuICAgICAgY29uc3QgdmlzaWJsZWxheWVycyA9IGxheWVycy5maWx0ZXIobCA9PiBsLnZpc2libGUgPT09IHRydWUpO1xyXG4gICAgICBpZiAodmlzaWJsZWxheWVycy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICBsYXllcnNbMF0udmlzaWJsZSA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSBpZiAodmlzaWJsZWxheWVycy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgbGF5ZXJzLmZvckVhY2gobCA9PiBsLnZpc2libGUgPSBmYWxzZSk7XHJcbiAgICAgICAgbGF5ZXJzWzBdLnZpc2libGUgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMubWFwU3ZjLnNldDJEVWtpc0xheWVycyhsYXllcnMsICdiYXNlbGF5ZXJzJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZTJEQmFzZUxheWVycyhsYXllcnM6IExheWVyW10pIHtcclxuICAgIHRoaXMubWFwU3ZjLnVwZGF0ZTJETGF5ZXJWaXNpYmlsaXR5KGxheWVycywgJ2Jhc2VsYXllcnMnKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRkVXBkYXRlVGVycmFpbkxheWVycyhsYXllcnM6IExheWVyW10pIHtcclxuICAgIC8qKiBpZiBsZW5ndGggb2YgbGF5ZXJzIGZvbSBMYXllcnNTZXJ2aWNlIGhhcyBjaGFuZ2VkIGFkZCBuZXcgbGF5ZXJzICovXHJcbiAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgLyogaWYgKGxheWVycy5sZW5ndGggIT09IHRoaXMubWFwU3ZjLmdldDNETGF5