@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
JavaScript
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLWNlc2l1bS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXAtY2VzaXVtL3NyYy9saWIvbWFwLWNlc2l1bS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9tYXAtY2VzaXVtL3NyYy9saWIvbWFwLWNlc2l1bS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLGlCQUFpQixFQUFFLEtBQUssRUFBNEIsU0FBUyxFQUFjLE1BQU0sZUFBZSxDQUFDO0FBRTdILE9BQU8sRUFBb0IsUUFBUSxFQUFtQixNQUFNLDZCQUE2QixDQUFDO0FBQzFGLE9BQU8sRUFBZ0IsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUl0QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBb0NsRyxNQUFNLE9BQU8sa0JBQWtCO0lBZ0I3QixZQUFvQixNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQUo1QyxTQUFJLEdBQW1CLEVBQUUsQ0FBQztRQUMxQixlQUFVLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUNwQyxjQUFTLEdBQUcsSUFBSSxDQUFDO0lBRStCLENBQUM7SUFFakQsUUFBUTtRQUNOLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sQ0FBQyxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxp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LENBQUUsQ0FBQztRQUMzRCxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7SUFDL0IsQ0FBQzs4R0EzVFUsa0JBQWtCO2tHQUFsQixrQkFBa0IsZ2VDNUMvQiwrVkFRQTs7MkZEb0NhLGtCQUFrQjtrQkFQOUIsU0FBUzsrQkFDSSxpQkFBaUIsaUJBR1osaUJBQWlCLENBQUMsSUFBSSxjQUN6QixJQUFJO3FGQUlTLFVBQVU7c0JBQXBDLFNBQVM7dUJBQUMsY0FBYztnQkFDSyxhQUFhO3NCQUExQyxTQUFTO3VCQUFDLGlCQUFpQjtnQkFDSixhQUFhO3NCQUFwQyxLQUFLO3VCQUFDLGVBQWU7Z0JBQ0ksZUFBZTtzQkFBeEMsS0FBSzt1QkFBQyxpQkFBaUI7Z0JBQ0wsV0FBVztzQkFBN0IsS0FBSzt1QkFBQyxVQUFVO2dCQUNFLFFBQVE7c0JBQTFCLEtBQUs7dUJBQUMsVUFBVTtnQkFDTSxZQUFZO3NCQUFsQyxLQUFLO3VCQUFDLGNBQWM7Z0JBQ0QsU0FBUztzQkFBNUIsS0FBSzt1QkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9uLCBJbnB1dCwgT25EZXN0cm95LCBBZnRlclZpZXdJbml0LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IElNYXBTdGF0ZU9wdGlvbnMsIE1hcFN0YXRlLCBNYXBTdGF0ZVNlcnZpY2UgfSBmcm9tICdAZGxyLWVvYy9zZXJ2aWNlcy1tYXAtc3RhdGUnO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgc2tpcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgTWFwQ2VzaXVtU2VydmljZSB9IGZyb20gJy4vbWFwLWNlc2l1bS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTGF5ZXJzU2VydmljZSwgTGF5ZXIsIFRGaWx0ZXJ0eXBlcywgVEZpbHRlcnR5cGVzVW5jYXAgfSBmcm9tICdAZGxyLWVvYy9zZXJ2aWNlcy1sYXllcnMnO1xyXG5pbXBvcnQgeyBWaWV3ZXIgfSBmcm9tICdAY2VzaXVtL3dpZGdldHMnO1xyXG5pbXBvcnQgeyBTY3JlZW5TcGFjZUV2ZW50SGFuZGxlciwgU2NyZWVuU3BhY2VFdmVudFR5cGUsIEdlb0pzb25EYXRhU291cmNlIH0gZnJvbSAnQGNlc2l1bS9lbmdpbmUnO1xyXG5cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUNlc2l1bUNvbnRyb2xzIHtcclxuICAvL1NlZTogaHR0cHM6Ly9jZXNpdW0uY29tL2xlYXJuL2Nlc2l1bWpzL3JlZi1kb2MvVmlld2VyLmh0bWwjLkNvbnN0cnVjdG9yT3B0aW9uc1xyXG4gIHRpbWVsaW5lPzogYm9vbGVhbjtcclxuICBhbmltYXRpb24/OiBib29sZWFuO1xyXG4gIHNjZW5lTW9kZVBpY2tlcj86IGJvb2xlYW47XHJcbiAgaG9tZUJ1dHRvbj86IGJvb2xlYW47XHJcbiAgYmFzZUxheWVyUGlja2VyPzogYm9vbGVhbjtcclxuICBnZW9jb2Rlcj86IGJvb2xlYW47XHJcbiAgbmF2aWdhdGlvbkhlbHBCdXR0b24/OiBib29sZWFuO1xyXG4gIG5hdmlnYXRpb25JbnN0cnVjdGlvbnNJbml0aWFsbHlWaXNpYmxlPzogYm9vbGVhbjtcclxuICBmdWxsc2NyZWVuQnV0dG9uPzogYm9vbGVhbjtcclxuICBzY2VuZTNET25seT86IGJvb2xlYW47XHJcbiAgaW5mb0JveD86IGJvb2xlYW47XHJcbiAgc2VsZWN0aW9uSW5kaWNhdG9yPzogYm9vbGVhbjtcclxuICBlbmFibGVQb3B1cHM/OiBib29sZWFuO1xyXG4gIC8vQWxzbyB5b3UgY2FuIGRlZmluZSBhbiBDZXNpdW0gaW9uIEFjY2VzcyBUb2tlbiwgaHR0cHM6Ly9jZXNpdW0uY29tL2xlYXJuL2lvbi9jZXNpdW0taW9uLWFjY2Vzcy10b2tlbnMvXHJcbiAgaW9uQWNjZXNzVG9rZW4/OiBzdHJpbmc7XHJcbiAgLy9JbiB0aGUgc2FtZSB3YXkgeW91IGNhbiBwcm92aWRlIGEgcGVyc29uYWwga2V5IGZvciBHb29nbGUgTWFwcywgaHR0cHM6Ly9jZXNpdW0uY29tL2xlYXJuL2Nlc2l1bWpzLWxlYXJuL2Nlc2l1bWpzLXBob3RvcmVhbGlzdGljLTNkLXRpbGVzL1xyXG4gIEdvb2dsZU1hcHNBcGlLZXk/OiBzdHJpbmc7XHJcbiAgLy9kZWZhdWx0IGdsb2JlIGNvbG9yIGFzIGhleCBzdHJpbmdcclxuICBnbG9iZUNvbG9yPzogc3RyaW5nO1xyXG59XHJcblxyXG5kZWNsYXJlIHR5cGUgVGdyb3VwZmlsdGVydHlwZSA9IFRGaWx0ZXJ0eXBlc1VuY2FwIHwgVEZpbHRlcnR5cGVzO1xyXG5cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICd1a2lzLW1hcC1jZXNpdW0nLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL21hcC1jZXNpdW0uY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vbWFwLWNlc2l1bS5jb21wb25lbnQuc2NzcyddLFxyXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcclxuICAgIHN0YW5kYWxvbmU6IHRydWVcclxufSlcclxuZXhwb3J0IGNsYXNzIE1hcENlc2l1bUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgQFZpZXdDaGlsZCgnY2VzaXVtTWFwRGl2JykgbWFwRGl2VmlldyE6IEVsZW1lbnRSZWY7XHJcbiAgQFZpZXdDaGlsZCgnY2VzaXVtQ3JlZGl0RGl2JykgY3JlZGl0RGl2VmlldyE6IEVsZW1lbnRSZWY7XHJcbiAgQElucHV0KCd0d29EbGF5ZXJzU3ZjJykgdHdvRGxheWVyc1N2YyE6IExheWVyc1NlcnZpY2U7XHJcbiAgQElucHV0KCd0aHJlZURsYXllcnNTdmMnKSB0aHJlZURsYXllcnNTdmMhOiBMYXllcnNTZXJ2aWNlO1xyXG4gIEBJbnB1dCgnbWFwU3RhdGUnKSBtYXBTdGF0ZVN2YyE6IE1hcFN0YXRlU2VydmljZTtcclxuICBASW5wdXQoJ2NvbnRyb2xzJykgY29udHJvbHMhOiBJQ2VzaXVtQ29udHJvbHM7XHJcbiAgQElucHV0KCd0aW1lSW50ZXJ2YWwnKSB0aW1lSW50ZXJ2YWw/OiBzdHJpbmdbXTtcclxuICBASW5wdXQoJ3N0YXJ0VGltZScpIHN0YXJ0VGltZT86IHN0cmluZyB8IG51bGw7XHJcblxyXG4gIHZpZXdlciE6IFZpZXdlcjtcclxuICBzdWJzOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xyXG4gIG1hcENyZWF0ZWQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xyXG4gIGluaXRTdGF0ZSA9IHRydWU7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbWFwU3ZjOiBNYXBDZXNpdW1TZXJ2aWNlKSB7IH1cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMudHdvRGxheWVyc1N2Yykge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBwcm92aWRlIGEgTGF5ZXJzU2VydmljZSBhcyBJbnB1dCB0byB1a2lzLW1hcC1jZXNpdW1gKTtcclxuICAgIH1cclxuICAgIGlmICghdGhpcy5tYXBTdGF0ZVN2Yykge1xyXG4gICAgICBjb25zb2xlLmVycm9yKGBwcm92aWRlIGEgTWFwU3RhdGVTZXJ2aWNlIGFzIElucHV0IHRvIHVraXMtbWFwLWNlc2l1bWApO1xyXG4gICAgfVxyXG4gICAgdGhpcy5tYXBTdmMucmVtb3ZlQWxsMkRMYXllcnMoKTtcclxuXHJcbiAgICAvL1NldCBzdGFydCB0aW1lLCBpZiBhdmFpbGFibGVcclxuICAgIGlmICh0aGlzLnN0YXJ0VGltZSkge1xyXG4gICAgICB0aGlzLm1hcFN2Yy5pbml0VGltZSh0aGlzLnN0YXJ0VGltZSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaW5pdE1hcCgpO1xyXG4gICAgdGhpcy5zdWJzY3JpYmVUb0xheWVycygpO1xyXG5cclxuXHJcbiAgICAvKiogR2V0IGxhc3Qgc3RhdGUgZnJvbSBtYXBTdGF0ZVN2YyBhbmQgc2V0IGl0LCBzbyBhIFVzZXIgY2FuIHNldCB0aGUgaW5pdGlhbCBNYXBTdGF0ZSBpbiBhIGNvbXBvbmVudCAqL1xyXG4gICAgY29uc3Qgb2xkTWFwU3RhdGUgPSB0aGlzLm1hcFN0YXRlU3ZjLmdldE1hcFN0YXRlKCkuZ2V0VmFsdWUoKTtcclxuICAgIHRoaXMuc2V0TWFwU3RhdGUob2xkTWFwU3RhdGUpO1xyXG4gICAgLy8gc2V0IHZpZXdBbmdsZSBhbmQgcm90YXRpb24gc2VwZXJhdGx5IGFnYWluLCBhcyB0aGVpciB2YWx1ZXMgYXJlIG5vdCBzZXQgYnkgdGhlIHZpZXdlciB0aGUgZmlyc3QgdGltZVxyXG4gICAgdGhpcy5tYXBTdmMuc2V0Vmlld0FuZ2xlKG9sZE1hcFN0YXRlLnZpZXdBbmdsZSk7XHJcbiAgICB0aGlzLm1hcFN2Yy5zZXRSb3RhdGlvbihvbGRNYXBTdGF0ZS5yb3RhdGlvbik7XHJcbiAgICAvKiogU3Vic2NyaWJlIHRvIG1hcCBldmVudHMgd2hlbiB0aGUgbWFwIGlzIGNvbXBsZXRlbHkgY3JlYXRlZCAgKi9cclxuICAgIHRoaXMuc3Vic2NyaWJlVG9NYXBFdmVudHMoKTtcclxuICAgIC8qKiBTdWJzY3JpYmUgdG8gbWFwU3RhdGVTdmMgKi9cclxuICAgIHRoaXMuc3Vic2NyaWJlVG9NYXBTdGF0ZSgpO1xyXG5cclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhlIGxhc3QgTWFwU3RhdGUgb24gRGVzdHJveS4gV2hlbiB0aGUgY29tcG9uZW50IGlzIHJlaW5pdGlhbGl6ZWQsIHRoaXMgTWFwU3RhdGUgaXMgdXNlZFxyXG4gICAgICovXHJcbiAgICBjb25zdCBsYXN0TWFwU3RhdGUgPSB0aGlzLmNhbGNNYXBTdGF0ZUZyb21DYW1lcmEoJ3VzZXInKTtcclxuICAgIHRoaXMubWFwU3RhdGVTdmMuc2V0TWFwU3RhdGUobGFzdE1hcFN0YXRlKTtcclxuXHJcbiAgICAvKiogY2xlYW4gdXAgYWxsIGV2ZW50cyBvbiBkZXN0cm95ICovXHJcbiAgICB0aGlzLnN1YnMuZm9yRWFjaChzID0+IHMudW5zdWJzY3JpYmUoKSk7XHJcbiAgICBpZiAodGhpcy52aWV3ZXI/LnNjZW5lPy5wcmltaXRpdmVzKSB7XHJcbiAgICAgIHRoaXMudmlld2VyLmltYWdlcnlMYXllcnMucmVtb3ZlQWxsKCk7XHJcbiAgICAgIHRoaXMudmlld2VyLmRhdGFTb3VyY2VzLnJlbW92ZUFsbCgpO1xyXG4gICAgICB0aGlzLnZpZXdlci5zY2VuZS5wcmltaXRpdmVzLnJlbW92ZUFsbCgpO1xyXG4gICAgICB0aGlzLnZpZXdlci5zY2VuZS5wcmltaXRpdmVzLmRlc3Ryb3koKTtcclxuICAgIH1cclxuICAgIHRoaXMubWFwU3ZjLmRlc3Ryb3lMYXllckdycG91cHMoKTtcclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIGluaXRNYXAoKSB7XHJcbiAgICBpZiAodGhpcy50aW1lSW50ZXJ2YWwpIHtcclxuICAgICAgdGhpcy5tYXBTdmMuc2V0VGltZUludGVydmFsKHRoaXMudGltZUludGVydmFsKTtcclxuICAgIH1cclxuICAgIHRoaXMubWFwU3ZjLnNldENvbnRyb2xzKHRoaXMuY29udHJvbHMpO1xyXG4gICAgY29uc3QgY2VzaXVtVmlldyA9IHRoaXMubWFwU3ZjLmNyZWF0ZU1hcCh0aGlzLm1hcERpdlZpZXcubmF0aXZlRWxlbWVudCk7XHJcbiAgICB0aGlzLnZpZXdlciA9IGNlc2l1bVZpZXcudmlld2VyO1xyXG4gICAgdGhpcy5tYXBDcmVhdGVkLm5leHQodHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN1YnNjcmliZVRvTGF5ZXJzKCkge1xyXG5cclxuICAgIC8vIDJEIGxheWVyXHJcbiAgICBpZiAodGhpcy50d29EbGF5ZXJzU3ZjKSB7XHJcbiAgICAgIGNvbnN0IG9uQmFzZWxheWVycyA9IHRoaXMudHdvRGxheWVyc1N2Yy5nZXRCYXNlTGF5ZXJzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZUJhc2VMYXllcnMobGF5ZXJzKSk7XHJcbiAgICAgIHRoaXMuc3Vicy5wdXNoKG9uQmFzZWxheWVycyk7XHJcblxyXG4gICAgICBjb25zdCBvbkxheWVycyA9IHRoaXMudHdvRGxheWVyc1N2Yy5nZXRMYXllcnMoKS5zdWJzY3JpYmUobGF5ZXJzID0+IHRoaXMuYWRkVXBkYXRlMkRMYXllcnMobGF5ZXJzLCAnbGF5ZXJzJykpO1xyXG4gICAgICB0aGlzLnN1YnMucHVzaChvbkxheWVycyk7XHJcblxyXG4gICAgICBjb25zdCBvbk92ZXJsYXlzID0gdGhpcy50d29EbGF5ZXJzU3ZjLmdldE92ZXJsYXlzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZTJETGF5ZXJzKGxheWVycywgJ292ZXJsYXlzJykpO1xyXG4gICAgICB0aGlzLnN1YnMucHVzaChvbk92ZXJsYXlzKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAzRCBsYXllclxyXG4gICAgaWYgKHRoaXMudGhyZWVEbGF5ZXJzU3ZjKSB7XHJcblxyXG4gICAgICBjb25zdCBvblRlcnJhaW5MYXllcnMgPSB0aGlzLnRocmVlRGxheWVyc1N2Yy5nZXRCYXNlTGF5ZXJzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZVRlcnJhaW5MYXllcnMobGF5ZXJzKSk7XHJcbiAgICAgIHRoaXMuc3Vicy5wdXNoKG9uVGVycmFpbkxheWVycyk7XHJcblxyXG4gICAgICBjb25zdCBvbjNETGF5ZXJzID0gdGhpcy50aHJlZURsYXllcnNTdmMuZ2V0TGF5ZXJzKCkuc3Vic2NyaWJlKGxheWVycyA9PiB0aGlzLmFkZFVwZGF0ZTNETGF5ZXJzKGxheWVycywgJ2xheWVycycpKTtcclxuICAgICAgdGhpcy5zdWJzLnB1c2gob24zRExheWVycyk7XHJcblxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb01hcFN0YXRlKCkge1xyXG4gICAgaWYgKHRoaXMubWFwU3RhdGVTdmMpIHtcclxuICAgICAgY29uc3QgbWFwU3RhdGVPbiA9IHRoaXMubWFwU3RhdGVTdmMuZ2V0TWFwU3RhdGUoKS5waXBlKHNraXAoMSkpLnN1YnNjcmliZShzdGF0ZSA9PiB0aGlzLnNldE1hcFN0YXRlKHN0YXRlKSk7XHJcbiAgICAgIHRoaXMuc3Vicy5wdXNoKG1hcFN0YXRlT24pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZXRNYXBTdGF0ZShtYXBTdGF0ZTogTWFwU3RhdGUpIHtcclxuICAgIGNvbnN0IGxhc3RBY3Rpb24gPSB0aGlzLm1hcFN0YXRlU3ZjLmdldExhc3RBY3Rpb24oKS5nZXRWYWx1ZSgpO1xyXG4gICAgaWYgKG1hcFN0YXRlLm9wdGlvbnMubm90aWZpZXIgPT09ICd1c2VyJykge1xyXG4gICAgICBpZiAobGFzdEFjdGlvbiA9PT0gJ3NldEV4dGVudCcpIHtcclxuICAgICAgICB0aGlzLm1hcFN2Yy5zZXRFeHRlbnQobWFwU3RhdGUuZXh0ZW50LCB0cnVlKTtcclxuICAgICAgfSBlbHNlIGlmIChsYXN0QWN0aW9uID09PSAnc2V0U3RhdGUnKSB7XHJcbiAgICAgICAgdGhpcy5tYXBTdmMuc2V0Wm9vbShtYXBTdGF0ZS56b29tKTtcclxuICAgICAgICB0aGlzLm1hcFN2Yy5zZXRDZW50ZXIobWFwU3RhdGUuY2VudGVyKTtcclxuICAgICAgICB0aGlzLm1hcFN2Yy5zZXRSb3RhdGlvbihtYXBTdGF0ZS5yb3RhdGlvbik7XHJcbiAgICAgICAgdGhpcy5tYXBTdmMuc2V0Vmlld0FuZ2xlKG1hcFN0YXRlLnZpZXdBbmdsZSk7XHJcbiAgICAgIH0gZWxzZSBpZiAobGFzdEFjdGlvbiA9PT0gJ3NldFJvdGF0aW9uJykge1xyXG4gICAgICAgIHRoaXMubWFwU3ZjLnNldFJvdGF0aW9uKG1hcFN0YXRlLnJvdGF0aW9uKTtcclxuICAgICAgfSBlbHNlIGlmIChsYXN0QWN0aW9uID09PSAnc2V0QW5nbGUnKSB7XHJcbiAgICAgICAgdGhpcy5tYXBTdmMuc2V0Vmlld0FuZ2xlKG1hcFN0YXRlLnZpZXdBbmdsZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKG1hcFN0YXRlLm9wdGlvbnMubm90aWZpZXIgPT09ICdtYXAnKSB7XHJcbiAgICAgIHRoaXMubWFwU3ZjLnVwZGF0ZVRpbWUobWFwU3RhdGUudGltZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNhbGNNYXBTdGF0ZUZyb21DYW1lcmEobm90aWZpZXI6IElNYXBTdGF0ZU9wdGlvbnNbJ25vdGlmaWVyJ10pe1xyXG4gICAgY29uc3QgdGltZSA9IHRoaXMubWFwU3RhdGVTdmMuZ2V0TWFwU3RhdGUoKS5nZXRWYWx1ZSgpLnRpbWU7XHJcbiAgICBjb25zdCB6b29tID0gdGhpcy5tYXBTdmMuZ2V0Wm9vbSgpO1xyXG4gICAgY29uc3QgbmV3Q2VudGVyID0gdGhpcy5tYXBTdmMuZ2V0Q2VudGVyKCk7XHJcbiAgICBjb25zdCBleHRlbnQgPSB0aGlzLm1hcFN2Yy5nZXRDdXJyZW50RXh0ZW50KCk7XHJcbiAgICBjb25zdCB2aWV3QW5nbGUgPSB0aGlzLm1hcFN2Yy5nZXRWaWV3QW5nbGUoKTtcclxuICAgIGNvbnN0IHJvdGF0aW9uID0gdGhpcy5tYXBTdmMuZ2V0Um90YXRpb24oKTtcclxuICAgIHJldHVybiBuZXcgTWFwU3RhdGUoem9vbSwgbmV3Q2VudGVyLCB7IG5vdGlmaWVyIH0sIGV4dGVudCwgdGltZSwgdmlld0FuZ2xlLCByb3RhdGlvbik7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN1YnNjcmliZVRvTWFwRXZlbnRzKCkge1xyXG4gICAgdGhpcy52aWV3ZXIuY2FtZXJhLmNoYW5nZWQuYWRkRXZlbnRMaXN0ZW5lcigoZXZ0KSA9PiB7XHJcbiAgICAgIGNvbnN0IG1zID0gdGhpcy5jYWxjTWFwU3RhdGVGcm9tQ2FtZXJhKCdtYXAnKTtcclxuICAgICAgdGhpcy5tYXBTdGF0ZVN2Yy5zZXRNYXBTdGF0ZShtcyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZih0aGlzLmNvbnRyb2xzLmluZm9Cb3gpe1xyXG4gICAgICAvL0NoYW5naW5nIGVudGl0aXkgcGFyYW1ldGVycyBmb3IgdGhlIGRpc3BsYXkgaW4gaGUgaW5mb0JveCB3aW5kb3dcclxuICAgIHRoaXMudmlld2VyLnNlbGVjdGVkRW50aXR5Q2hhbmdlZC5hZGRFdmVudExpc3RlbmVyKCgpID0+IHtcclxuICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy52aWV3ZXIuc2VsZWN0ZWRFbnRpdHk7XHJcbiAgICAgIC8vY2hhbmdlIGluZm9Cb3ggdGl0bGVcclxuICAgICAgY29uc3QgdGl0bGVEaXYgPSB0aGlzLnZpZXdlci5pbmZvQm94LmNvbnRhaW5lci5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdjZXNpdW0taW5mb0JveC10aXRsZScpWzBdO1xyXG4gICAgICB0aXRsZURpdi5pbm5lckhUTUwgPSAnTGF5ZXIgQXR0cmlidXRlcyc7XHJcbiAgICAgIGlmIChlbnRpdHkpIHtcclxuICAgICAgICBpZihlbnRpdHkuZW50aXR5Q29sbGVjdGlvbj8ub3duZXIgaW5zdGFuY2VvZiBHZW9Kc29uRGF0YVNvdXJjZSl7XHJcbiAgICAgICAgICB0aXRsZURpdi5pbm5lckhUTUwgPSBlbnRpdHkuZW50aXR5Q29sbGVjdGlvbi5vd25lci5uYW1lO1xyXG4gICAgICAgICAgZW50aXR5Lm5hbWUgPSBlbnRpdHkuZW50aXR5Q29sbGVjdGlvbi5vd25lci5uYW1lO1xyXG4gICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgZW50aXR5Lm5hbWUgPSAnTGF5ZXIgQXR0cmlidXRlcyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChlbnRpdHkuZGVzY3JpcHRpb24pIHtcclxuICAgICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZW50aXR5LmRlc2NyaXB0aW9uLmdldFZhbHVlKHRoaXMubWFwU3ZjLmNlc2l1bUN1cnJlbnRUaW1lKTtcclxuICAgICAgICAgIGNvbnN0IGNvbnRlbnREaXYgPSB0aGlzLnZpZXdlci5pbmZvQm94LmNvbnRhaW5lci5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdjZXNpdW0taW5mb0JveC1jb250ZW50JylbMF07XHJcbiAgICAgICAgICBjb250ZW50RGl2LmlubmVySFRNTCA9IGRlc2NyaXB0aW9uO1xyXG4gICAgICAgICAgZW50aXR5Lm5hbWUgPSAnTGF5ZXIgQXR0cmlidXRlcyc7XHJcblxyXG4gICAgICAgICAgLy9UT0RPOiBGZXRjaCBsYXllciBpbmZvIGZvciBmb3JtYXR0aW5nIHRoZSBnZXRGZWF0dXJlSW5mbyBkYXRhLCBsaWtlIHNwZWNpZmljIHVuaXRzIG9yIHZhbHVlIHJvdW5kaW5nLlxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy9TaG93IHRoZSBwb3B1cCBvbiBjbGlja1xyXG4gICAgaWYodGhpcy5jb250cm9scy5lbmFibGVQb3B1cHMpe1xyXG4gICAgICBjb25zdCBjZXNpdW1FdmVudEhhbmRsZXIgPSBuZXcgU2NyZWVuU3BhY2VFdmVudEhhbmRsZXIodGhpcy52aWV3ZXIuc2NlbmUuY2FudmFzKTtcclxuICAgICAgY2VzaXVtRXZlbnRIYW5kbGVyLnNldElucHV0QWN0aW9uKChlOmFueSkgPT4ge1xyXG4gICAgICAgIC8vZ2V0IGNhbWVyYSByYXkgYXQgcGlja2VkIHBvc2l0aW9uIGFuZCBnZXQgbGF5ZXIgZmVhdHVyZXMgYXQgcGlja2VkIGxvY2F0aW9uXHJcbiAgICAgICAgY29uc3QgcmF5ID0gdGhpcy52aWV3ZXIuY2FtZXJhLmdldFBpY2tSYXkoZS5wb3NpdGlvbikhO1xyXG4gICAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMudmlld2VyLnNjZW5lLmltYWdlcnlMYXllcnMucGlja0ltYWdlcnlMYXllckZlYXR1cmVzKHJheSwgdGhpcy52aWV3ZXIuc2NlbmUpO1xyXG4gICAgICAgIGlmKGVudGl0eSl7XHJcbiAgICAgICAgY29uc3QgcG9wdXBDb250ZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJtYXBfY2VzaXVtX3BvcHVwX2NvbnRlbnRcIikhO1xyXG4gICAgICAgIGNvbnN0IHBvcHVwRGl2ID0gcG9wdXBDb250ZW50LnBhcmVudEVsZW1lbnQ7XHJcbiAgICAgICAgY29uc3QgZW50aXR5X3ggPSBlLnBvc2l0aW9uLng7XHJcbiAgICAgICAgY29uc3QgZW50aXR5X3kgPSBlLnBvc2l0aW9uLnlcclxuXHJcbiAgICAgICAgLy9oaWRlIHBvcHVwIHdoaWxlIHdhaXRpbmcgZm9yIHRoZSBjb250ZW50IHRvIGxvYWRcclxuICAgICAgICBwb3B1cERpdi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xyXG5cclxuICAgICAgICBlbnRpdHk/LnRoZW4oZSA9PntcclxuICAgICAgICAgIC8vd3JpdGUgZGVzY3JpcHRpb24gdGV4dCB0byBwb3B1cFxyXG4gICAgICAgICAgcG9wdXBDb250ZW50LmlubmVySFRNTCA9IGVbMF0uZGVzY3JpcHRpb24hO1xyXG4gICAgICAgICAgcG9wdXBEaXYuc3R5bGUubGVmdCA9IChlbnRpdHlfeC01OCkgKyAncHgnO1xyXG4gICAgICAgICAgcG9wdXBEaXYuc3R5bGUudG9wID0gKGVudGl0eV95LTc4KSArICdweCc7XHJcbiAgICAgICAgICBwb3B1cERpdi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIFNjcmVlblNwYWNlRXZlbnRUeXBlLkxFRlRfQ0xJQ0spO1xyXG5cclxuICAgICAgLy9IaWRlIHRoZSBwb3B1cFxyXG4gICAgICBjZXNpdW1FdmVudEhhbmRsZXIuc2V0SW5wdXRBY3Rpb24oKGU6YW55KSA9PiB7XHJcbiAgICAgICAgY29uc3QgcG9wdXAgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNlc2l1bV9wb3B1cF9kaXZcIikhO1xyXG4gICAgICAgIHBvcHVwLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgIH0sIFNjcmVlblNwYWNlRXZlbnRUeXBlLlJJR0hUX0RPV04pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIHByaXZhdGUgYWRkVXBkYXRlQmFzZUxheWVycyhsYXllcnM6IExheWVyW10pIHtcclxuICAgIC8qKiBpZiBsZW5ndGggb2YgbGF5ZXJzIGZvbSBMYXllcnNTZXJ2aWNlIGhhcyBjaGFuZ2VkIGFkZCBuZXcgbGF5ZXJzICovXHJcbiAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgaWYgKGxheWVycy5sZW5ndGggIT09IHRoaXMubWFwU3ZjLmdldEFsbDJETGF5ZXJzU2l6ZSgnYmFzZWxheWVycycpKSB7XHJcbiAgICAgICAgdGhpcy5hZGQyREJhc2VMYXllcnMobGF5ZXJzKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvKiogaWYgbGF5ZXJzIGFscmVhZHkgb24gdGhlIG1hcCAtIGxlbmd0aCBub3QgY2hhbmdlZCAtIHVwZGF0ZSB0aGVtICovXHJcbiAgICAgICAgdGhpcy51cGRhdGUyREJhc2VMYXllcnMobGF5ZXJzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGQyREJhc2VMYXllcnMobGF5ZXJzOiBMYXllcltdKSB7XHJcbiAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgLy8gc2V0IG9ubHkgb25lIHZpc2libGUgYXQgc3RhcnRcclxuICAgICAgY29uc3QgdmlzaWJsZWxheWVycyA9IGxheWVycy5maWx0ZXIobCA9PiBsLnZpc2libGUgPT09IHRydWUpO1xyXG4gICAgICBpZiAodmlzaWJsZWxheWVycy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICBsYXllcnNbMF0udmlzaWJsZSA9IHRydWU7XHJcbiAgICAgIH0gZWxzZSBpZiAodmlzaWJsZWxheWVycy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgbGF5ZXJzLmZvckVhY2gobCA9PiBsLnZpc2libGUgPSBmYWxzZSk7XHJcbiAgICAgICAgbGF5ZXJzWzBdLnZpc2libGUgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMubWFwU3ZjLnNldDJEVWtpc0xheWVycyhsYXllcnMsICdiYXNlbGF5ZXJzJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZTJEQmFzZUxheWVycyhsYXllcnM6IExheWVyW10pIHtcclxuICAgIHRoaXMubWFwU3ZjLnVwZGF0ZTJETGF5ZXJWaXNpYmlsaXR5KGxheWVycywgJ2Jhc2VsYXllcnMnKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYWRkVXBkYXRlVGVycmFpbkxheWVycyhsYXllcnM6IExheWVyW10pIHtcclxuICAgIC8qKiBpZiBsZW5ndGggb2YgbGF5ZXJzIGZvbSBMYXllcnNTZXJ2aWNlIGhhcyBjaGFuZ2VkIGFkZCBuZXcgbGF5ZXJzICovXHJcbiAgICBpZiAobGF5ZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgLyogaWYgKGxheWVycy5sZW5ndGggIT09IHRoaXMubWFwU3ZjLmdldDNETGF5