UNPKG

@asymmetrik/ngx-leaflet

Version:
330 lines 40.5 kB
import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core'; import { latLng, map } from 'leaflet'; import { LeafletUtil } from './leaflet.util'; import * as i0 from "@angular/core"; export class LeafletDirective { constructor(element, zone) { this.element = element; this.zone = zone; this.DEFAULT_ZOOM = 1; this.DEFAULT_CENTER = latLng(38.907192, -77.036871); this.DEFAULT_FPZ_OPTIONS = {}; this.fitBoundsOptions = this.DEFAULT_FPZ_OPTIONS; this.panOptions = this.DEFAULT_FPZ_OPTIONS; this.zoomOptions = this.DEFAULT_FPZ_OPTIONS; this.zoomPanOptions = this.DEFAULT_FPZ_OPTIONS; // Default configuration this.options = {}; // Configure callback function for the map this.mapReady = new EventEmitter(); this.zoomChange = new EventEmitter(); this.centerChange = new EventEmitter(); // Mouse Map Events this.onClick = new EventEmitter(); this.onDoubleClick = new EventEmitter(); this.onMouseDown = new EventEmitter(); this.onMouseUp = new EventEmitter(); this.onMouseMove = new EventEmitter(); this.onMouseOver = new EventEmitter(); this.onMouseOut = new EventEmitter(); // Map Move Events this.onMapMove = new EventEmitter(); this.onMapMoveStart = new EventEmitter(); this.onMapMoveEnd = new EventEmitter(); // Map Zoom Events this.onMapZoom = new EventEmitter(); this.onMapZoomStart = new EventEmitter(); this.onMapZoomEnd = new EventEmitter(); // Nothing here } ngOnInit() { // Create the map outside of angular so the various map events don't trigger change detection this.zone.runOutsideAngular(() => { // Create the map with some reasonable defaults this.map = map(this.element.nativeElement, this.options); this.addMapEventListeners(); }); // Only setView if there is a center/zoom if (null != this.center && null != this.zoom) { this.setView(this.center, this.zoom); } // Set up all the initial settings if (null != this.fitBounds) { this.setFitBounds(this.fitBounds); } if (null != this.maxBounds) { this.setMaxBounds(this.maxBounds); } if (null != this.minZoom) { this.setMinZoom(this.minZoom); } if (null != this.maxZoom) { this.setMaxZoom(this.maxZoom); } this.doResize(); // Fire map ready event this.mapReady.emit(this.map); } ngOnChanges(changes) { /* * The following code is to address an issue with our (basic) implementation of * zooming and panning. From our testing, it seems that a pan operation followed * by a zoom operation in the same thread will interfere with eachother. The zoom * operation interrupts/cancels the pan, resulting in a final center point that is * inaccurate. The solution seems to be to either separate them with a timeout or * to collapse them into a setView call. */ // Zooming and Panning if (changes['zoom'] && changes['center'] && null != this.zoom && null != this.center) { this.setView(changes['center'].currentValue, changes['zoom'].currentValue); } // Set the zoom level else if (changes['zoom']) { this.setZoom(changes['zoom'].currentValue); } // Set the map center else if (changes['center']) { this.setCenter(changes['center'].currentValue); } // Other options if (changes['fitBounds']) { this.setFitBounds(changes['fitBounds'].currentValue); } if (changes['maxBounds']) { this.setMaxBounds(changes['maxBounds'].currentValue); } if (changes['minZoom']) { this.setMinZoom(changes['minZoom'].currentValue); } if (changes['maxZoom']) { this.setMaxZoom(changes['maxZoom'].currentValue); } } ngOnDestroy() { // If this directive is destroyed, the map is too if (null != this.map) { this.map.remove(); } } getMap() { return this.map; } onResize() { this.delayResize(); } addMapEventListeners() { const registerEventHandler = (eventName, handler) => { this.map.on(eventName, handler); }; // Add all the pass-through mouse event handlers registerEventHandler('click', (e) => LeafletUtil.handleEvent(this.zone, this.onClick, e)); registerEventHandler('dblclick', (e) => LeafletUtil.handleEvent(this.zone, this.onDoubleClick, e)); registerEventHandler('mousedown', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseDown, e)); registerEventHandler('mouseup', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseUp, e)); registerEventHandler('mouseover', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseOver, e)); registerEventHandler('mouseout', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseOut, e)); registerEventHandler('mousemove', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseMove, e)); registerEventHandler('zoomstart', (e) => LeafletUtil.handleEvent(this.zone, this.onMapZoomStart, e)); registerEventHandler('zoom', (e) => LeafletUtil.handleEvent(this.zone, this.onMapZoom, e)); registerEventHandler('zoomend', (e) => LeafletUtil.handleEvent(this.zone, this.onMapZoomEnd, e)); registerEventHandler('movestart', (e) => LeafletUtil.handleEvent(this.zone, this.onMapMoveStart, e)); registerEventHandler('move', (e) => LeafletUtil.handleEvent(this.zone, this.onMapMove, e)); registerEventHandler('moveend', (e) => LeafletUtil.handleEvent(this.zone, this.onMapMoveEnd, e)); // Update any things for which we provide output bindings const outputUpdateHandler = () => { const zoom = this.map.getZoom(); if (zoom !== this.zoom) { this.zoom = zoom; LeafletUtil.handleEvent(this.zone, this.zoomChange, zoom); } const center = this.map.getCenter(); if (null != center || null != this.center) { if (((null == center || null == this.center) && center !== this.center) || (center.lat !== this.center.lat || center.lng !== this.center.lng)) { this.center = center; LeafletUtil.handleEvent(this.zone, this.centerChange, center); } } }; registerEventHandler('moveend', outputUpdateHandler); registerEventHandler('zoomend', outputUpdateHandler); } /** * Resize the map to fit it's parent container */ doResize() { // Run this outside of angular so the map events stay outside of angular this.zone.runOutsideAngular(() => { // Invalidate the map size to trigger it to update itself if (null != this.map) { this.map.invalidateSize({}); } }); } /** * Manage a delayed resize of the component */ delayResize() { if (null != this.resizeTimer) { clearTimeout(this.resizeTimer); } this.resizeTimer = setTimeout(this.doResize.bind(this), 200); } /** * Set the view (center/zoom) all at once * @param center The new center * @param zoom The new zoom level */ setView(center, zoom) { if (null != this.map && null != center && null != zoom) { this.map.setView(center, zoom, this.zoomPanOptions); } } /** * Set the map zoom level * @param zoom the new zoom level for the map */ setZoom(zoom) { if (null != this.map && null != zoom) { this.map.setZoom(zoom, this.zoomOptions); } } /** * Set the center of the map * @param center the center point */ setCenter(center) { if (null != this.map && null != center) { this.map.panTo(center, this.panOptions); } } /** * Fit the map to the bounds * @param latLngBounds the boundary to set */ setFitBounds(latLngBounds) { if (null != this.map && null != latLngBounds) { this.map.fitBounds(latLngBounds, this.fitBoundsOptions); } } /** * Set the map's max bounds * @param latLngBounds the boundary to set */ setMaxBounds(latLngBounds) { if (null != this.map && null != latLngBounds) { this.map.setMaxBounds(latLngBounds); } } /** * Set the map's min zoom * @param number the new min zoom */ setMinZoom(zoom) { if (null != this.map && null != zoom) { this.map.setMinZoom(zoom); } } /** * Set the map's min zoom * @param number the new min zoom */ setMaxZoom(zoom) { if (null != this.map && null != zoom) { this.map.setMaxZoom(zoom); } } } LeafletDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: LeafletDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); LeafletDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.1", type: LeafletDirective, selector: "[leaflet]", inputs: { fitBoundsOptions: ["leafletFitBoundsOptions", "fitBoundsOptions"], panOptions: ["leafletPanOptions", "panOptions"], zoomOptions: ["leafletZoomOptions", "zoomOptions"], zoomPanOptions: ["leafletZoomPanOptions", "zoomPanOptions"], options: ["leafletOptions", "options"], zoom: ["leafletZoom", "zoom"], center: ["leafletCenter", "center"], fitBounds: ["leafletFitBounds", "fitBounds"], maxBounds: ["leafletMaxBounds", "maxBounds"], minZoom: ["leafletMinZoom", "minZoom"], maxZoom: ["leafletMaxZoom", "maxZoom"] }, outputs: { mapReady: "leafletMapReady", zoomChange: "leafletZoomChange", centerChange: "leafletCenterChange", onClick: "leafletClick", onDoubleClick: "leafletDoubleClick", onMouseDown: "leafletMouseDown", onMouseUp: "leafletMouseUp", onMouseMove: "leafletMouseMove", onMouseOver: "leafletMouseOver", onMouseOut: "leafletMouseOut", onMapMove: "leafletMapMove", onMapMoveStart: "leafletMapMoveStart", onMapMoveEnd: "leafletMapMoveEnd", onMapZoom: "leafletMapZoom", onMapZoomStart: "leafletMapZoomStart", onMapZoomEnd: "leafletMapZoomEnd" }, host: { listeners: { "window:resize": "onResize()" } }, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.1", ngImport: i0, type: LeafletDirective, decorators: [{ type: Directive, args: [{ selector: '[leaflet]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { fitBoundsOptions: [{ type: Input, args: ['leafletFitBoundsOptions'] }], panOptions: [{ type: Input, args: ['leafletPanOptions'] }], zoomOptions: [{ type: Input, args: ['leafletZoomOptions'] }], zoomPanOptions: [{ type: Input, args: ['leafletZoomPanOptions'] }], options: [{ type: Input, args: ['leafletOptions'] }], mapReady: [{ type: Output, args: ['leafletMapReady'] }], zoom: [{ type: Input, args: ['leafletZoom'] }], zoomChange: [{ type: Output, args: ['leafletZoomChange'] }], center: [{ type: Input, args: ['leafletCenter'] }], centerChange: [{ type: Output, args: ['leafletCenterChange'] }], fitBounds: [{ type: Input, args: ['leafletFitBounds'] }], maxBounds: [{ type: Input, args: ['leafletMaxBounds'] }], minZoom: [{ type: Input, args: ['leafletMinZoom'] }], maxZoom: [{ type: Input, args: ['leafletMaxZoom'] }], onClick: [{ type: Output, args: ['leafletClick'] }], onDoubleClick: [{ type: Output, args: ['leafletDoubleClick'] }], onMouseDown: [{ type: Output, args: ['leafletMouseDown'] }], onMouseUp: [{ type: Output, args: ['leafletMouseUp'] }], onMouseMove: [{ type: Output, args: ['leafletMouseMove'] }], onMouseOver: [{ type: Output, args: ['leafletMouseOver'] }], onMouseOut: [{ type: Output, args: ['leafletMouseOut'] }], onMapMove: [{ type: Output, args: ['leafletMapMove'] }], onMapMoveStart: [{ type: Output, args: ['leafletMapMoveStart'] }], onMapMoveEnd: [{ type: Output, args: ['leafletMapMoveEnd'] }], onMapZoom: [{ type: Output, args: ['leafletMapZoom'] }], onMapZoomStart: [{ type: Output, args: ['leafletMapZoomStart'] }], onMapZoomEnd: [{ type: Output, args: ['leafletMapZoomEnd'] }], onResize: [{ type: HostListener, args: ['window:resize', []] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVhZmxldC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbGVhZmxldC9zcmMvbGliL2NvcmUvbGVhZmxldC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNOLFNBQVMsRUFBYyxZQUFZLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBd0MsTUFBTSxFQUV0RyxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsTUFBTSxFQUF5RCxHQUFHLEVBQW1CLE1BQU0sU0FBUyxDQUFDO0FBRTlHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFLN0MsTUFBTSxPQUFPLGdCQUFnQjtJQWdFNUIsWUFBb0IsT0FBbUIsRUFBVSxJQUFZO1FBQXpDLFlBQU8sR0FBUCxPQUFPLENBQVk7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFRO1FBN0RwRCxpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUNqQixtQkFBYyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMvQyx3QkFBbUIsR0FBRyxFQUFFLENBQUM7UUFPQSxxQkFBZ0IsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFDbEQsZUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUNyQyxnQkFBVyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUNwQyxtQkFBYyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUcxRSx3QkFBd0I7UUFDQyxZQUFPLEdBQWUsRUFBRSxDQUFDO1FBRWxELDBDQUEwQztRQUNmLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBSWpDLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBSXRDLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQWV6RSxtQkFBbUI7UUFDSyxZQUFPLEdB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QW1CO2dCQXNHM0IsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGVBQWUsRUFBRSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0RGlyZWN0aXZlLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE5nWm9uZSwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LFxuXHRTaW1wbGVDaGFuZ2Vcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IGxhdExuZywgTGF0TG5nLCBMYXRMbmdCb3VuZHMsIExlYWZsZXRFdmVudCwgTGVhZmxldE1vdXNlRXZlbnQsIG1hcCwgTWFwLCBNYXBPcHRpb25zIH0gZnJvbSAnbGVhZmxldCc7XG5cbmltcG9ydCB7IExlYWZsZXRVdGlsIH0gZnJvbSAnLi9sZWFmbGV0LnV0aWwnO1xuXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdbbGVhZmxldF0nXG59KVxuZXhwb3J0IGNsYXNzIExlYWZsZXREaXJlY3RpdmVcblx0aW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0IHtcblxuXHRyZWFkb25seSBERUZBVUxUX1pPT00gPSAxO1xuXHRyZWFkb25seSBERUZBVUxUX0NFTlRFUiA9IGxhdExuZygzOC45MDcxOTIsIC03Ny4wMzY4NzEpO1xuXHRyZWFkb25seSBERUZBVUxUX0ZQWl9PUFRJT05TID0ge307XG5cblx0cmVzaXplVGltZXI6IGFueTtcblxuXHQvLyBSZWZlcmVuY2UgdG8gdGhlIHByaW1hcnkgbWFwIG9iamVjdFxuXHRtYXA6IE1hcDtcblxuXHRASW5wdXQoJ2xlYWZsZXRGaXRCb3VuZHNPcHRpb25zJykgZml0Qm91bmRzT3B0aW9ucyA9IHRoaXMuREVGQVVMVF9GUFpfT1BUSU9OUztcblx0QElucHV0KCdsZWFmbGV0UGFuT3B0aW9ucycpIHBhbk9wdGlvbnMgPSB0aGlzLkRFRkFVTFRfRlBaX09QVElPTlM7XG5cdEBJbnB1dCgnbGVhZmxldFpvb21PcHRpb25zJykgem9vbU9wdGlvbnMgPSB0aGlzLkRFRkFVTFRfRlBaX09QVElPTlM7XG5cdEBJbnB1dCgnbGVhZmxldFpvb21QYW5PcHRpb25zJykgem9vbVBhbk9wdGlvbnMgPSB0aGlzLkRFRkFVTFRfRlBaX09QVElPTlM7XG5cblxuXHQvLyBEZWZhdWx0IGNvbmZpZ3VyYXRpb25cblx0QElucHV0KCdsZWFmbGV0T3B0aW9ucycpIG9wdGlvbnM6IE1hcE9wdGlvbnMgPSB7fTtcblxuXHQvLyBDb25maWd1cmUgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSBtYXBcblx0QE91dHB1dCgnbGVhZmxldE1hcFJlYWR5JykgbWFwUmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPE1hcD4oKTtcblxuXHQvLyBab29tIGxldmVsIGZvciB0aGUgbWFwXG5cdEBJbnB1dCgnbGVhZmxldFpvb20nKSB6b29tOiBudW1iZXI7XG5cdEBPdXRwdXQoJ2xlYWZsZXRab29tQ2hhbmdlJykgem9vbUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG5cdC8vIENlbnRlciBvZiB0aGUgbWFwXG5cdEBJbnB1dCgnbGVhZmxldENlbnRlcicpIGNlbnRlcjogTGF0TG5nO1xuXHRAT3V0cHV0KCdsZWFmbGV0Q2VudGVyQ2hhbmdlJykgY2VudGVyQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxMYXRMbmc+KCk7XG5cblx0Ly8gU2V0IGZpdCBib3VuZHMgZm9yIG1hcFxuXHRASW5wdXQoJ2xlYWZsZXRGaXRCb3VuZHMnKSBmaXRCb3VuZHM6IExhdExuZ0JvdW5kcztcblxuXHQvLyBTZXQgdGhlIG1heCBib3VuZHMgZm9yIHRoZSBtYXBcblx0QElucHV0KCdsZWFmbGV0TWF4Qm91bmRzJykgbWF4Qm91bmRzOiBMYXRMbmdCb3VuZHM7XG5cblx0Ly8gU2V0IHRoZSBtaW4gem9vbSBmb3IgdGhlIG1hcFxuXHRASW5wdXQoJ2xlYWZsZXRNaW5ab29tJykgbWluWm9vbTogbnVtYmVyO1xuXG5cdC8vIFNldCB0aGUgbWF4IHpvb20gZm9yIHRoZSBtYXBcblx0QElucHV0KCdsZWFmbGV0TWF4Wm9vbScpIG1heFpvb206IG51bWJlcjtcblxuXG5cdC8vIE1vdXNlIE1hcCBFdmVudHNcblx0QE91dHB1dCgnbGVhZmxldENsaWNrJykgb25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXREb3VibGVDbGljaycpIG9uRG91YmxlQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRNb3VzZUV2ZW50PigpO1xuXHRAT3V0cHV0KCdsZWFmbGV0TW91c2VEb3duJykgb25Nb3VzZURvd24gPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRNb3VzZUV2ZW50PigpO1xuXHRAT3V0cHV0KCdsZWFmbGV0TW91c2VVcCcpIG9uTW91c2VVcCA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNb3VzZU1vdmUnKSBvbk1vdXNlTW92ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNb3VzZU92ZXInKSBvbk1vdXNlT3ZlciA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNb3VzZU91dCcpIG9uTW91c2VPdXQgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRNb3VzZUV2ZW50PigpO1xuXG5cdC8vIE1hcCBNb3ZlIEV2ZW50c1xuXHRAT3V0cHV0KCdsZWFmbGV0TWFwTW92ZScpIG9uTWFwTW92ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldEV2ZW50PigpO1xuXHRAT3V0cHV0KCdsZWFmbGV0TWFwTW92ZVN0YXJ0Jykgb25NYXBNb3ZlU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRFdmVudD4oKTtcblx0QE91dHB1dCgnbGVhZmxldE1hcE1vdmVFbmQnKSBvbk1hcE1vdmVFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRFdmVudD4oKTtcblxuXHQvLyBNYXAgWm9vbSBFdmVudHNcblx0QE91dHB1dCgnbGVhZmxldE1hcFpvb20nKSBvbk1hcFpvb20gPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRFdmVudD4oKTtcblx0QE91dHB1dCgnbGVhZmxldE1hcFpvb21TdGFydCcpIG9uTWFwWm9vbVN0YXJ0ID0gbmV3IEV2ZW50RW1pdHRlcjxMZWFmbGV0RXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNYXBab29tRW5kJykgb25NYXBab29tRW5kID0gbmV3IEV2ZW50RW1pdHRlcjxMZWFmbGV0RXZlbnQ+KCk7XG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmLCBwcml2YXRlIHpvbmU6IE5nWm9uZSkge1xuXHRcdC8vIE5vdGhpbmcgaGVyZVxuXHR9XG5cblx0bmdPbkluaXQoKSB7XG5cblx0XHQvLyBDcmVhdGUgdGhlIG1hcCBvdXRzaWRlIG9mIGFuZ3VsYXIgc28gdGhlIHZhcmlvdXMgbWFwIGV2ZW50cyBkb24ndCB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cblx0XHR0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuXG5cdFx0XHQvLyBDcmVhdGUgdGhlIG1hcCB3aXRoIHNvbWUgcmVhc29uYWJsZSBkZWZhdWx0c1xuXHRcdFx0dGhpcy5tYXAgPSBtYXAodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIHRoaXMub3B0aW9ucyk7XG5cdFx0XHR0aGlzLmFkZE1hcEV2ZW50TGlzdGVuZXJzKCk7XG5cblx0XHR9KTtcblxuXHRcdC8vIE9ubHkgc2V0VmlldyBpZiB0aGVyZSBpcyBhIGNlbnRlci96b29tXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5jZW50ZXIgJiYgbnVsbCAhPSB0aGlzLnpvb20pIHtcblx0XHRcdHRoaXMuc2V0Vmlldyh0aGlzLmNlbnRlciwgdGhpcy56b29tKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdXAgYWxsIHRoZSBpbml0aWFsIHNldHRpbmdzXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5maXRCb3VuZHMpIHtcblx0XHRcdHRoaXMuc2V0Rml0Qm91bmRzKHRoaXMuZml0Qm91bmRzKTtcblx0XHR9XG5cblx0XHRpZiAobnVsbCAhPSB0aGlzLm1heEJvdW5kcykge1xuXHRcdFx0dGhpcy5zZXRNYXhCb3VuZHModGhpcy5tYXhCb3VuZHMpO1xuXHRcdH1cblxuXHRcdGlmIChudWxsICE9IHRoaXMubWluWm9vbSkge1xuXHRcdFx0dGhpcy5zZXRNaW5ab29tKHRoaXMubWluWm9vbSk7XG5cdFx0fVxuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXhab29tKSB7XG5cdFx0XHR0aGlzLnNldE1heFpvb20odGhpcy5tYXhab29tKTtcblx0XHR9XG5cblx0XHR0aGlzLmRvUmVzaXplKCk7XG5cblx0XHQvLyBGaXJlIG1hcCByZWFkeSBldmVudFxuXHRcdHRoaXMubWFwUmVhZHkuZW1pdCh0aGlzLm1hcCk7XG5cblx0fVxuXG5cdG5nT25DaGFuZ2VzKGNoYW5nZXM6IHsgW2tleTogc3RyaW5nXTogU2ltcGxlQ2hhbmdlIH0pIHtcblxuXHRcdC8qXG5cdFx0ICogVGhlIGZvbGxvd2luZyBjb2RlIGlzIHRvIGFkZHJlc3MgYW4gaXNzdWUgd2l0aCBvdXIgKGJhc2ljKSBpbXBsZW1lbnRhdGlvbiBvZlxuXHRcdCAqIHpvb21pbmcgYW5kIHBhbm5pbmcuIEZyb20gb3VyIHRlc3RpbmcsIGl0IHNlZW1zIHRoYXQgYSBwYW4gb3BlcmF0aW9uIGZvbGxvd2VkXG5cdFx0ICogYnkgYSB6b29tIG9wZXJhdGlvbiBpbiB0aGUgc2FtZSB0aHJlYWQgd2lsbCBpbnRlcmZlcmUgd2l0aCBlYWNob3RoZXIuIFRoZSB6b29tXG5cdFx0ICogb3BlcmF0aW9uIGludGVycnVwdHMvY2FuY2VscyB0aGUgcGFuLCByZXN1bHRpbmcgaW4gYSBmaW5hbCBjZW50ZXIgcG9pbnQgdGhhdCBpc1xuXHRcdCAqIGluYWNjdXJhdGUuIFRoZSBzb2x1dGlvbiBzZWVtcyB0byBiZSB0byBlaXRoZXIgc2VwYXJhdGUgdGhlbSB3aXRoIGEgdGltZW91dCBvclxuXHRcdCAgKiB0byBjb2xsYXBzZSB0aGVtIGludG8gYSBzZXRWaWV3IGNhbGwuXG5cdFx0ICovXG5cblx0XHQvLyBab29taW5nIGFuZCBQYW5uaW5nXG5cdFx0aWYgKGNoYW5nZXNbJ3pvb20nXSAmJiBjaGFuZ2VzWydjZW50ZXInXSAmJiBudWxsICE9IHRoaXMuem9vbSAmJiBudWxsICE9IHRoaXMuY2VudGVyKSB7XG5cdFx0XHR0aGlzLnNldFZpZXcoY2hhbmdlc1snY2VudGVyJ10uY3VycmVudFZhbHVlLCBjaGFuZ2VzWyd6b29tJ10uY3VycmVudFZhbHVlKTtcblx0XHR9XG5cdFx0Ly8gU2V0IHRoZSB6b29tIGxldmVsXG5cdFx0ZWxzZSBpZiAoY2hhbmdlc1snem9vbSddKSB7XG5cdFx0XHR0aGlzLnNldFpvb20oY2hhbmdlc1snem9vbSddLmN1cnJlbnRWYWx1ZSk7XG5cdFx0fVxuXHRcdC8vIFNldCB0aGUgbWFwIGNlbnRlclxuXHRcdGVsc2UgaWYgKGNoYW5nZXNbJ2NlbnRlciddKSB7XG5cdFx0XHR0aGlzLnNldENlbnRlcihjaGFuZ2VzWydjZW50ZXInXS5jdXJyZW50VmFsdWUpO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyIG9wdGlvbnNcblx0XHRpZiAoY2hhbmdlc1snZml0Qm91bmRzJ10pIHtcblx0XHRcdHRoaXMuc2V0Rml0Qm91bmRzKGNoYW5nZXNbJ2ZpdEJvdW5kcyddLmN1cnJlbnRWYWx1ZSk7XG5cdFx0fVxuXG5cdFx0aWYgKGNoYW5nZXNbJ21heEJvdW5kcyddKSB7XG5cdFx0XHR0aGlzLnNldE1heEJvdW5kcyhjaGFuZ2VzWydtYXhCb3VuZHMnXS5jdXJyZW50VmFsdWUpO1xuXHRcdH1cblxuXHRcdGlmIChjaGFuZ2VzWydtaW5ab29tJ10pIHtcblx0XHRcdHRoaXMuc2V0TWluWm9vbShjaGFuZ2VzWydtaW5ab29tJ10uY3VycmVudFZhbHVlKTtcblx0XHR9XG5cblx0XHRpZiAoY2hhbmdlc1snbWF4Wm9vbSddKSB7XG5cdFx0XHR0aGlzLnNldE1heFpvb20oY2hhbmdlc1snbWF4Wm9vbSddLmN1cnJlbnRWYWx1ZSk7XG5cdFx0fVxuXG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHQvLyBJZiB0aGlzIGRpcmVjdGl2ZSBpcyBkZXN0cm95ZWQsIHRoZSBtYXAgaXMgdG9vXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXApIHtcblx0XHRcdHRoaXMubWFwLnJlbW92ZSgpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBnZXRNYXAoKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFwO1xuXHR9XG5cblxuXHRASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgW10pXG5cdG9uUmVzaXplKCkge1xuXHRcdHRoaXMuZGVsYXlSZXNpemUoKTtcblx0fVxuXG5cdHByaXZhdGUgYWRkTWFwRXZlbnRMaXN0ZW5lcnMoKSB7XG5cblx0XHRjb25zdCByZWdpc3RlckV2ZW50SGFuZGxlciA9IChldmVudE5hbWU6IHN0cmluZywgaGFuZGxlcjogKGU6IExlYWZsZXRFdmVudCkgPT4gYW55KSA9PiB7XG5cdFx0XHR0aGlzLm1hcC5vbihldmVudE5hbWUsIGhhbmRsZXIpO1xuXHRcdH07XG5cblxuXHRcdC8vIEFkZCBhbGwgdGhlIHBhc3MtdGhyb3VnaCBtb3VzZSBldmVudCBoYW5kbGVyc1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCdjbGljaycsIChlOiBMZWFmbGV0TW91c2VFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uQ2xpY2ssIGUpKTtcblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignZGJsY2xpY2snLCAoZTogTGVhZmxldE1vdXNlRXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbkRvdWJsZUNsaWNrLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdXNlZG93bicsIChlOiBMZWFmbGV0TW91c2VFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTW91c2VEb3duLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdXNldXAnLCAoZTogTGVhZmxldE1vdXNlRXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbk1vdXNlVXAsIGUpKTtcblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignbW91c2VvdmVyJywgKGU6IExlYWZsZXRNb3VzZUV2ZW50KSA9PiBMZWFmbGV0VXRpbC5oYW5kbGVFdmVudCh0aGlzLnpvbmUsIHRoaXMub25Nb3VzZU92ZXIsIGUpKTtcblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignbW91c2VvdXQnLCAoZTogTGVhZmxldE1vdXNlRXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbk1vdXNlT3V0LCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdXNlbW92ZScsIChlOiBMZWFmbGV0TW91c2VFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTW91c2VNb3ZlLCBlKSk7XG5cblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignem9vbXN0YXJ0JywgKGU6IExlYWZsZXRFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTWFwWm9vbVN0YXJ0LCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ3pvb20nLCAoZTogTGVhZmxldEV2ZW50KSA9PiBMZWFmbGV0VXRpbC5oYW5kbGVFdmVudCh0aGlzLnpvbmUsIHRoaXMub25NYXBab29tLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ3pvb21lbmQnLCAoZTogTGVhZmxldEV2ZW50KSA9PiBMZWFmbGV0VXRpbC5oYW5kbGVFdmVudCh0aGlzLnpvbmUsIHRoaXMub25NYXBab29tRW5kLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdmVzdGFydCcsIChlOiBMZWFmbGV0RXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbk1hcE1vdmVTdGFydCwgZSkpO1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCdtb3ZlJywgKGU6IExlYWZsZXRFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTWFwTW92ZSwgZSkpO1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCdtb3ZlZW5kJywgKGU6IExlYWZsZXRFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTWFwTW92ZUVuZCwgZSkpO1xuXG5cblx0XHQvLyBVcGRhdGUgYW55IHRoaW5ncyBmb3Igd2hpY2ggd2UgcHJvdmlkZSBvdXRwdXQgYmluZGluZ3Ncblx0XHRjb25zdCBvdXRwdXRVcGRhdGVIYW5kbGVyID0gKCkgPT4ge1xuXHRcdFx0Y29uc3Qgem9vbSA9IHRoaXMubWFwLmdldFpvb20oKTtcblx0XHRcdGlmICh6b29tICE9PSB0aGlzLnpvb20pIHtcblx0XHRcdFx0dGhpcy56b29tID0gem9vbTtcblx0XHRcdFx0TGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLnpvb21DaGFuZ2UsIHpvb20pO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBjZW50ZXIgPSB0aGlzLm1hcC5nZXRDZW50ZXIoKTtcblx0XHRcdGlmIChudWxsICE9IGNlbnRlciB8fCBudWxsICE9IHRoaXMuY2VudGVyKSB7XG5cblx0XHRcdFx0aWYgKCgobnVsbCA9PSBjZW50ZXIgfHwgbnVsbCA9PSB0aGlzLmNlbnRlcikgJiYgY2VudGVyICE9PSB0aGlzLmNlbnRlcilcblx0XHRcdFx0XHR8fCAoY2VudGVyLmxhdCAhPT0gdGhpcy5jZW50ZXIubGF0IHx8IGNlbnRlci5sbmcgIT09IHRoaXMuY2VudGVyLmxuZykpIHtcblxuXHRcdFx0XHRcdHRoaXMuY2VudGVyID0gY2VudGVyO1xuXHRcdFx0XHRcdExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5jZW50ZXJDaGFuZ2UsIGNlbnRlcik7XG5cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignbW92ZWVuZCcsIG91dHB1dFVwZGF0ZUhhbmRsZXIpO1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCd6b29tZW5kJywgb3V0cHV0VXBkYXRlSGFuZGxlcik7XG5cdH1cblxuXHQvKipcblx0ICogUmVzaXplIHRoZSBtYXAgdG8gZml0IGl0J3MgcGFyZW50IGNvbnRhaW5lclxuXHQgKi9cblx0cHJpdmF0ZSBkb1Jlc2l6ZSgpIHtcblxuXHRcdC8vIFJ1biB0aGlzIG91dHNpZGUgb2YgYW5ndWxhciBzbyB0aGUgbWFwIGV2ZW50cyBzdGF5IG91dHNpZGUgb2YgYW5ndWxhclxuXHRcdHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG5cblx0XHRcdC8vIEludmFsaWRhdGUgdGhlIG1hcCBzaXplIHRvIHRyaWdnZXIgaXQgdG8gdXBkYXRlIGl0c2VsZlxuXHRcdFx0aWYgKG51bGwgIT0gdGhpcy5tYXApIHtcblx0XHRcdFx0dGhpcy5tYXAuaW52YWxpZGF0ZVNpemUoe30pO1xuXHRcdFx0fVxuXG5cdFx0fSk7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBNYW5hZ2UgYSBkZWxheWVkIHJlc2l6ZSBvZiB0aGUgY29tcG9uZW50XG5cdCAqL1xuXHRwcml2YXRlIGRlbGF5UmVzaXplKCkge1xuXHRcdGlmIChudWxsICE9IHRoaXMucmVzaXplVGltZXIpIHtcblx0XHRcdGNsZWFyVGltZW91dCh0aGlzLnJlc2l6ZVRpbWVyKTtcblx0XHR9XG5cdFx0dGhpcy5yZXNpemVUaW1lciA9IHNldFRpbWVvdXQodGhpcy5kb1Jlc2l6ZS5iaW5kKHRoaXMpLCAyMDApO1xuXHR9XG5cblxuXHQvKipcblx0ICogU2V0IHRoZSB2aWV3IChjZW50ZXIvem9vbSkgYWxsIGF0IG9uY2Vcblx0ICogQHBhcmFtIGNlbnRlciBUaGUgbmV3IGNlbnRlclxuXHQgKiBAcGFyYW0gem9vbSBUaGUgbmV3IHpvb20gbGV2ZWxcblx0ICovXG5cdHByaXZhdGUgc2V0VmlldyhjZW50ZXI6IExhdExuZywgem9vbTogbnVtYmVyKSB7XG5cblx0XHRpZiAobnVsbCAhPSB0aGlzLm1hcCAmJiBudWxsICE9IGNlbnRlciAmJiBudWxsICE9IHpvb20pIHtcblx0XHRcdHRoaXMubWFwLnNldFZpZXcoY2VudGVyLCB6b29tLCB0aGlzLnpvb21QYW5PcHRpb25zKTtcblx0XHR9XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIG1hcCB6b29tIGxldmVsXG5cdCAqIEBwYXJhbSB6b29tIHRoZSBuZXcgem9vbSBsZXZlbCBmb3IgdGhlIG1hcFxuXHQgKi9cblx0cHJpdmF0ZSBzZXRab29tKHpvb206IG51bWJlcikge1xuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXAgJiYgbnVsbCAhPSB6b29tKSB7XG5cdFx0XHR0aGlzLm1hcC5zZXRab29tKHpvb20sIHRoaXMuem9vbU9wdGlvbnMpO1xuXHRcdH1cblxuXHR9XG5cblx0LyoqXG5cdCAqIFNldCB0aGUgY2VudGVyIG9mIHRoZSBtYXBcblx0ICogQHBhcmFtIGNlbnRlciB0aGUgY2VudGVyIHBvaW50XG5cdCAqL1xuXHRwcml2YXRlIHNldENlbnRlcihjZW50ZXI6IExhdExuZykge1xuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXAgJiYgbnVsbCAhPSBjZW50ZXIpIHtcblx0XHRcdHRoaXMubWFwLnBhblRvKGNlbnRlciwgdGhpcy5wYW5PcHRpb25zKTtcblx0XHR9XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBGaXQgdGhlIG1hcCB0byB0aGUgYm91bmRzXG5cdCAqIEBwYXJhbSBsYXRMbmdCb3VuZHMgdGhlIGJvdW5kYXJ5IHRvIHNldFxuXHQgKi9cblx0cHJpdmF0ZSBzZXRGaXRCb3VuZHMobGF0TG5nQm91bmRzOiBMYXRMbmdCb3VuZHMpIHtcblxuXHRcdGlmIChudWxsICE9IHRoaXMubWFwICYmIG51bGwgIT0gbGF0TG5nQm91bmRzKSB7XG5cdFx0XHR0aGlzLm1hcC5maXRCb3VuZHMobGF0TG5nQm91bmRzLCB0aGlzLmZpdEJvdW5kc09wdGlvbnMpO1xuXHRcdH1cblxuXHR9XG5cblx0LyoqXG5cdCAqIFNldCB0aGUgbWFwJ3MgbWF4IGJvdW5kc1xuXHQgKiBAcGFyYW0gbGF0TG5nQm91bmRzIHRoZSBib3VuZGFyeSB0byBzZXRcblx0ICovXG5cdHByaXZhdGUgc2V0TWF4Qm91bmRzKGxhdExuZ0JvdW5kczogTGF0TG5nQm91bmRzKSB7XG5cblx0XHRpZiAobnVsbCAhPSB0aGlzLm1hcCAmJiBudWxsICE9IGxhdExuZ0JvdW5kcykge1xuXHRcdFx0dGhpcy5tYXAuc2V0TWF4Qm91bmRzKGxhdExuZ0JvdW5kcyk7XG5cdFx0fVxuXG5cdH1cblxuXHQvKipcblx0ICogU2V0IHRoZSBtYXAncyBtaW4gem9vbVxuXHQgKiBAcGFyYW0gbnVtYmVyIHRoZSBuZXcgbWluIHpvb21cblx0ICovXG5cdHByaXZhdGUgc2V0TWluWm9vbSh6b29tOiBudW1iZXIpIHtcblxuXHRcdGlmIChudWxsICE9IHRoaXMubWFwICYmIG51bGwgIT0gem9vbSkge1xuXHRcdFx0dGhpcy5tYXAuc2V0TWluWm9vbSh6b29tKTtcblx0XHR9XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIG1hcCdzIG1pbiB6b29tXG5cdCAqIEBwYXJhbSBudW1iZXIgdGhlIG5ldyBtaW4gem9vbVxuXHQgKi9cblx0cHJpdmF0ZSBzZXRNYXhab29tKHpvb206IG51bWJlcikge1xuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXAgJiYgbnVsbCAhPSB6b29tKSB7XG5cdFx0XHR0aGlzLm1hcC5zZXRNYXhab29tKHpvb20pO1xuXHRcdH1cblxuXHR9XG5cbn1cbiJdfQ==