1 | import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
|
2 | import { latLng, map } from 'leaflet';
|
3 | import { LeafletUtil } from './leaflet.util';
|
4 | import * as i0 from "@angular/core";
|
5 | export class LeafletDirective {
|
6 | constructor(element, zone) {
|
7 | this.element = element;
|
8 | this.zone = zone;
|
9 | this.DEFAULT_ZOOM = 1;
|
10 | this.DEFAULT_CENTER = latLng(38.907192, -77.036871);
|
11 | this.DEFAULT_FPZ_OPTIONS = {};
|
12 | this.fitBoundsOptions = this.DEFAULT_FPZ_OPTIONS;
|
13 | this.panOptions = this.DEFAULT_FPZ_OPTIONS;
|
14 | this.zoomOptions = this.DEFAULT_FPZ_OPTIONS;
|
15 | this.zoomPanOptions = this.DEFAULT_FPZ_OPTIONS;
|
16 | // Default configuration
|
17 | this.options = {};
|
18 | // Configure callback function for the map
|
19 | this.mapReady = new EventEmitter();
|
20 | this.zoomChange = new EventEmitter();
|
21 | this.centerChange = new EventEmitter();
|
22 | // Mouse Map Events
|
23 | this.onClick = new EventEmitter();
|
24 | this.onDoubleClick = new EventEmitter();
|
25 | this.onMouseDown = new EventEmitter();
|
26 | this.onMouseUp = new EventEmitter();
|
27 | this.onMouseMove = new EventEmitter();
|
28 | this.onMouseOver = new EventEmitter();
|
29 | this.onMouseOut = new EventEmitter();
|
30 | // Map Move Events
|
31 | this.onMapMove = new EventEmitter();
|
32 | this.onMapMoveStart = new EventEmitter();
|
33 | this.onMapMoveEnd = new EventEmitter();
|
34 | // Map Zoom Events
|
35 | this.onMapZoom = new EventEmitter();
|
36 | this.onMapZoomStart = new EventEmitter();
|
37 | this.onMapZoomEnd = new EventEmitter();
|
38 | // Nothing here
|
39 | }
|
40 | ngOnInit() {
|
41 | // Create the map outside of angular so the various map events don't trigger change detection
|
42 | this.zone.runOutsideAngular(() => {
|
43 | // Create the map with some reasonable defaults
|
44 | this.map = map(this.element.nativeElement, this.options);
|
45 | this.addMapEventListeners();
|
46 | });
|
47 | // Only setView if there is a center/zoom
|
48 | if (null != this.center && null != this.zoom) {
|
49 | this.setView(this.center, this.zoom);
|
50 | }
|
51 | // Set up all the initial settings
|
52 | if (null != this.fitBounds) {
|
53 | this.setFitBounds(this.fitBounds);
|
54 | }
|
55 | if (null != this.maxBounds) {
|
56 | this.setMaxBounds(this.maxBounds);
|
57 | }
|
58 | if (null != this.minZoom) {
|
59 | this.setMinZoom(this.minZoom);
|
60 | }
|
61 | if (null != this.maxZoom) {
|
62 | this.setMaxZoom(this.maxZoom);
|
63 | }
|
64 | this.doResize();
|
65 | // Fire map ready event
|
66 | this.mapReady.emit(this.map);
|
67 | }
|
68 | ngOnChanges(changes) {
|
69 | /*
|
70 | * The following code is to address an issue with our (basic) implementation of
|
71 | * zooming and panning. From our testing, it seems that a pan operation followed
|
72 | * by a zoom operation in the same thread will interfere with eachother. The zoom
|
73 | * operation interrupts/cancels the pan, resulting in a final center point that is
|
74 | * inaccurate. The solution seems to be to either separate them with a timeout or
|
75 | * to collapse them into a setView call.
|
76 | */
|
77 | // Zooming and Panning
|
78 | if (changes['zoom'] && changes['center'] && null != this.zoom && null != this.center) {
|
79 | this.setView(changes['center'].currentValue, changes['zoom'].currentValue);
|
80 | }
|
81 | // Set the zoom level
|
82 | else if (changes['zoom']) {
|
83 | this.setZoom(changes['zoom'].currentValue);
|
84 | }
|
85 | // Set the map center
|
86 | else if (changes['center']) {
|
87 | this.setCenter(changes['center'].currentValue);
|
88 | }
|
89 | // Other options
|
90 | if (changes['fitBounds']) {
|
91 | this.setFitBounds(changes['fitBounds'].currentValue);
|
92 | }
|
93 | if (changes['maxBounds']) {
|
94 | this.setMaxBounds(changes['maxBounds'].currentValue);
|
95 | }
|
96 | if (changes['minZoom']) {
|
97 | this.setMinZoom(changes['minZoom'].currentValue);
|
98 | }
|
99 | if (changes['maxZoom']) {
|
100 | this.setMaxZoom(changes['maxZoom'].currentValue);
|
101 | }
|
102 | }
|
103 | ngOnDestroy() {
|
104 | // If this directive is destroyed, the map is too
|
105 | if (null != this.map) {
|
106 | this.map.remove();
|
107 | }
|
108 | }
|
109 | getMap() {
|
110 | return this.map;
|
111 | }
|
112 | onResize() {
|
113 | this.delayResize();
|
114 | }
|
115 | addMapEventListeners() {
|
116 | const registerEventHandler = (eventName, handler) => {
|
117 | this.map.on(eventName, handler);
|
118 | };
|
119 | // Add all the pass-through mouse event handlers
|
120 | registerEventHandler('click', (e) => LeafletUtil.handleEvent(this.zone, this.onClick, e));
|
121 | registerEventHandler('dblclick', (e) => LeafletUtil.handleEvent(this.zone, this.onDoubleClick, e));
|
122 | registerEventHandler('mousedown', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseDown, e));
|
123 | registerEventHandler('mouseup', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseUp, e));
|
124 | registerEventHandler('mouseover', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseOver, e));
|
125 | registerEventHandler('mouseout', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseOut, e));
|
126 | registerEventHandler('mousemove', (e) => LeafletUtil.handleEvent(this.zone, this.onMouseMove, e));
|
127 | registerEventHandler('zoomstart', (e) => LeafletUtil.handleEvent(this.zone, this.onMapZoomStart, e));
|
128 | registerEventHandler('zoom', (e) => LeafletUtil.handleEvent(this.zone, this.onMapZoom, e));
|
129 | registerEventHandler('zoomend', (e) => LeafletUtil.handleEvent(this.zone, this.onMapZoomEnd, e));
|
130 | registerEventHandler('movestart', (e) => LeafletUtil.handleEvent(this.zone, this.onMapMoveStart, e));
|
131 | registerEventHandler('move', (e) => LeafletUtil.handleEvent(this.zone, this.onMapMove, e));
|
132 | registerEventHandler('moveend', (e) => LeafletUtil.handleEvent(this.zone, this.onMapMoveEnd, e));
|
133 | // Update any things for which we provide output bindings
|
134 | const outputUpdateHandler = () => {
|
135 | const zoom = this.map.getZoom();
|
136 | if (zoom !== this.zoom) {
|
137 | this.zoom = zoom;
|
138 | LeafletUtil.handleEvent(this.zone, this.zoomChange, zoom);
|
139 | }
|
140 | const center = this.map.getCenter();
|
141 | if (null != center || null != this.center) {
|
142 | if (((null == center || null == this.center) && center !== this.center)
|
143 | || (center.lat !== this.center.lat || center.lng !== this.center.lng)) {
|
144 | this.center = center;
|
145 | LeafletUtil.handleEvent(this.zone, this.centerChange, center);
|
146 | }
|
147 | }
|
148 | };
|
149 | registerEventHandler('moveend', outputUpdateHandler);
|
150 | registerEventHandler('zoomend', outputUpdateHandler);
|
151 | }
|
152 | /**
|
153 | * Resize the map to fit it's parent container
|
154 | */
|
155 | doResize() {
|
156 | // Run this outside of angular so the map events stay outside of angular
|
157 | this.zone.runOutsideAngular(() => {
|
158 | // Invalidate the map size to trigger it to update itself
|
159 | if (null != this.map) {
|
160 | this.map.invalidateSize({});
|
161 | }
|
162 | });
|
163 | }
|
164 | /**
|
165 | * Manage a delayed resize of the component
|
166 | */
|
167 | delayResize() {
|
168 | if (null != this.resizeTimer) {
|
169 | clearTimeout(this.resizeTimer);
|
170 | }
|
171 | this.resizeTimer = setTimeout(this.doResize.bind(this), 200);
|
172 | }
|
173 | /**
|
174 | * Set the view (center/zoom) all at once
|
175 | * @param center The new center
|
176 | * @param zoom The new zoom level
|
177 | */
|
178 | setView(center, zoom) {
|
179 | if (null != this.map && null != center && null != zoom) {
|
180 | this.map.setView(center, zoom, this.zoomPanOptions);
|
181 | }
|
182 | }
|
183 | /**
|
184 | * Set the map zoom level
|
185 | * @param zoom the new zoom level for the map
|
186 | */
|
187 | setZoom(zoom) {
|
188 | if (null != this.map && null != zoom) {
|
189 | this.map.setZoom(zoom, this.zoomOptions);
|
190 | }
|
191 | }
|
192 | /**
|
193 | * Set the center of the map
|
194 | * @param center the center point
|
195 | */
|
196 | setCenter(center) {
|
197 | if (null != this.map && null != center) {
|
198 | this.map.panTo(center, this.panOptions);
|
199 | }
|
200 | }
|
201 | /**
|
202 | * Fit the map to the bounds
|
203 | * @param latLngBounds the boundary to set
|
204 | */
|
205 | setFitBounds(latLngBounds) {
|
206 | if (null != this.map && null != latLngBounds) {
|
207 | this.map.fitBounds(latLngBounds, this.fitBoundsOptions);
|
208 | }
|
209 | }
|
210 | /**
|
211 | * Set the map's max bounds
|
212 | * @param latLngBounds the boundary to set
|
213 | */
|
214 | setMaxBounds(latLngBounds) {
|
215 | if (null != this.map && null != latLngBounds) {
|
216 | this.map.setMaxBounds(latLngBounds);
|
217 | }
|
218 | }
|
219 | /**
|
220 | * Set the map's min zoom
|
221 | * @param number the new min zoom
|
222 | */
|
223 | setMinZoom(zoom) {
|
224 | if (null != this.map && null != zoom) {
|
225 | this.map.setMinZoom(zoom);
|
226 | }
|
227 | }
|
228 | /**
|
229 | * Set the map's min zoom
|
230 | * @param number the new min zoom
|
231 | */
|
232 | setMaxZoom(zoom) {
|
233 | if (null != this.map && null != zoom) {
|
234 | this.map.setMaxZoom(zoom);
|
235 | }
|
236 | }
|
237 | }
|
238 | LeafletDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: LeafletDirective, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
|
239 | LeafletDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.4", 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 });
|
240 | i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: LeafletDirective, decorators: [{
|
241 | type: Directive,
|
242 | args: [{
|
243 | selector: '[leaflet]'
|
244 | }]
|
245 | }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { fitBoundsOptions: [{
|
246 | type: Input,
|
247 | args: ['leafletFitBoundsOptions']
|
248 | }], panOptions: [{
|
249 | type: Input,
|
250 | args: ['leafletPanOptions']
|
251 | }], zoomOptions: [{
|
252 | type: Input,
|
253 | args: ['leafletZoomOptions']
|
254 | }], zoomPanOptions: [{
|
255 | type: Input,
|
256 | args: ['leafletZoomPanOptions']
|
257 | }], options: [{
|
258 | type: Input,
|
259 | args: ['leafletOptions']
|
260 | }], mapReady: [{
|
261 | type: Output,
|
262 | args: ['leafletMapReady']
|
263 | }], zoom: [{
|
264 | type: Input,
|
265 | args: ['leafletZoom']
|
266 | }], zoomChange: [{
|
267 | type: Output,
|
268 | args: ['leafletZoomChange']
|
269 | }], center: [{
|
270 | type: Input,
|
271 | args: ['leafletCenter']
|
272 | }], centerChange: [{
|
273 | type: Output,
|
274 | args: ['leafletCenterChange']
|
275 | }], fitBounds: [{
|
276 | type: Input,
|
277 | args: ['leafletFitBounds']
|
278 | }], maxBounds: [{
|
279 | type: Input,
|
280 | args: ['leafletMaxBounds']
|
281 | }], minZoom: [{
|
282 | type: Input,
|
283 | args: ['leafletMinZoom']
|
284 | }], maxZoom: [{
|
285 | type: Input,
|
286 | args: ['leafletMaxZoom']
|
287 | }], onClick: [{
|
288 | type: Output,
|
289 | args: ['leafletClick']
|
290 | }], onDoubleClick: [{
|
291 | type: Output,
|
292 | args: ['leafletDoubleClick']
|
293 | }], onMouseDown: [{
|
294 | type: Output,
|
295 | args: ['leafletMouseDown']
|
296 | }], onMouseUp: [{
|
297 | type: Output,
|
298 | args: ['leafletMouseUp']
|
299 | }], onMouseMove: [{
|
300 | type: Output,
|
301 | args: ['leafletMouseMove']
|
302 | }], onMouseOver: [{
|
303 | type: Output,
|
304 | args: ['leafletMouseOver']
|
305 | }], onMouseOut: [{
|
306 | type: Output,
|
307 | args: ['leafletMouseOut']
|
308 | }], onMapMove: [{
|
309 | type: Output,
|
310 | args: ['leafletMapMove']
|
311 | }], onMapMoveStart: [{
|
312 | type: Output,
|
313 | args: ['leafletMapMoveStart']
|
314 | }], onMapMoveEnd: [{
|
315 | type: Output,
|
316 | args: ['leafletMapMoveEnd']
|
317 | }], onMapZoom: [{
|
318 | type: Output,
|
319 | args: ['leafletMapZoom']
|
320 | }], onMapZoomStart: [{
|
321 | type: Output,
|
322 | args: ['leafletMapZoomStart']
|
323 | }], onMapZoomEnd: [{
|
324 | type: Output,
|
325 | args: ['leafletMapZoomEnd']
|
326 | }], onResize: [{
|
327 | type: HostListener,
|
328 | args: ['window:resize', []]
|
329 | }] } });
|
330 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVhZmxldC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbGVhZmxldC9zcmMvbGliL2NvcmUvbGVhZmxldC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNOLFNBQVMsRUFBYyxZQUFZLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBd0MsTUFBTSxFQUV0RyxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsTUFBTSxFQUF5RCxHQUFHLEVBQW1CLE1BQU0sU0FBUyxDQUFDO0FBRTlHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFLN0MsTUFBTSxPQUFPLGdCQUFnQjtJQWdFNUIsWUFBb0IsT0FBbUIsRUFBVSxJQUFZO1FBQXpDLFlBQU8sR0FBUCxPQUFPLENBQVk7UUFBVSxTQUFJLEdBQUosSUFBSSxDQUFRO1FBN0RwRCxpQkFBWSxHQUFHLENBQUMsQ0FBQztRQUNqQixtQkFBYyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMvQyx3QkFBbUIsR0FBRyxFQUFFLENBQUM7UUFPQSxxQkFBZ0IsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFDbEQsZUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUNyQyxnQkFBVyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUNwQyxtQkFBYyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztRQUcxRSx3QkFBd0I7UUFDQyxZQUFPLEdBQWUsRUFBRSxDQUFDO1FBRWxELDBDQUEwQztRQUNmLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBSWpDLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBSXRDLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQWV6RSxtQkFBbUI7UUFDSyxZQUFPLEdB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QW1CO2dCQXNHM0IsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGVBQWUsRUFBRSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0RGlyZWN0aXZlLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE5nWm9uZSwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LFxuXHRTaW1wbGVDaGFuZ2Vcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IGxhdExuZywgTGF0TG5nLCBMYXRMbmdCb3VuZHMsIExlYWZsZXRFdmVudCwgTGVhZmxldE1vdXNlRXZlbnQsIG1hcCwgTWFwLCBNYXBPcHRpb25zIH0gZnJvbSAnbGVhZmxldCc7XG5cbmltcG9ydCB7IExlYWZsZXRVdGlsIH0gZnJvbSAnLi9sZWFmbGV0LnV0aWwnO1xuXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdbbGVhZmxldF0nXG59KVxuZXhwb3J0IGNsYXNzIExlYWZsZXREaXJlY3RpdmVcblx0aW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0IHtcblxuXHRyZWFkb25seSBERUZBVUxUX1pPT00gPSAxO1xuXHRyZWFkb25seSBERUZBVUxUX0NFTlRFUiA9IGxhdExuZygzOC45MDcxOTIsIC03Ny4wMzY4NzEpO1xuXHRyZWFkb25seSBERUZBVUxUX0ZQWl9PUFRJT05TID0ge307XG5cblx0cmVzaXplVGltZXI6IGFueTtcblxuXHQvLyBSZWZlcmVuY2UgdG8gdGhlIHByaW1hcnkgbWFwIG9iamVjdFxuXHRtYXA6IE1hcDtcblxuXHRASW5wdXQoJ2xlYWZsZXRGaXRCb3VuZHNPcHRpb25zJykgZml0Qm91bmRzT3B0aW9ucyA9IHRoaXMuREVGQVVMVF9GUFpfT1BUSU9OUztcblx0QElucHV0KCdsZWFmbGV0UGFuT3B0aW9ucycpIHBhbk9wdGlvbnMgPSB0aGlzLkRFRkFVTFRfRlBaX09QVElPTlM7XG5cdEBJbnB1dCgnbGVhZmxldFpvb21PcHRpb25zJykgem9vbU9wdGlvbnMgPSB0aGlzLkRFRkFVTFRfRlBaX09QVElPTlM7XG5cdEBJbnB1dCgnbGVhZmxldFpvb21QYW5PcHRpb25zJykgem9vbVBhbk9wdGlvbnMgPSB0aGlzLkRFRkFVTFRfRlBaX09QVElPTlM7XG5cblxuXHQvLyBEZWZhdWx0IGNvbmZpZ3VyYXRpb25cblx0QElucHV0KCdsZWFmbGV0T3B0aW9ucycpIG9wdGlvbnM6IE1hcE9wdGlvbnMgPSB7fTtcblxuXHQvLyBDb25maWd1cmUgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSBtYXBcblx0QE91dHB1dCgnbGVhZmxldE1hcFJlYWR5JykgbWFwUmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPE1hcD4oKTtcblxuXHQvLyBab29tIGxldmVsIGZvciB0aGUgbWFwXG5cdEBJbnB1dCgnbGVhZmxldFpvb20nKSB6b29tOiBudW1iZXI7XG5cdEBPdXRwdXQoJ2xlYWZsZXRab29tQ2hhbmdlJykgem9vbUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG5cdC8vIENlbnRlciBvZiB0aGUgbWFwXG5cdEBJbnB1dCgnbGVhZmxldENlbnRlcicpIGNlbnRlcjogTGF0TG5nO1xuXHRAT3V0cHV0KCdsZWFmbGV0Q2VudGVyQ2hhbmdlJykgY2VudGVyQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxMYXRMbmc+KCk7XG5cblx0Ly8gU2V0IGZpdCBib3VuZHMgZm9yIG1hcFxuXHRASW5wdXQoJ2xlYWZsZXRGaXRCb3VuZHMnKSBmaXRCb3VuZHM6IExhdExuZ0JvdW5kcztcblxuXHQvLyBTZXQgdGhlIG1heCBib3VuZHMgZm9yIHRoZSBtYXBcblx0QElucHV0KCdsZWFmbGV0TWF4Qm91bmRzJykgbWF4Qm91bmRzOiBMYXRMbmdCb3VuZHM7XG5cblx0Ly8gU2V0IHRoZSBtaW4gem9vbSBmb3IgdGhlIG1hcFxuXHRASW5wdXQoJ2xlYWZsZXRNaW5ab29tJykgbWluWm9vbTogbnVtYmVyO1xuXG5cdC8vIFNldCB0aGUgbWF4IHpvb20gZm9yIHRoZSBtYXBcblx0QElucHV0KCdsZWFmbGV0TWF4Wm9vbScpIG1heFpvb206IG51bWJlcjtcblxuXG5cdC8vIE1vdXNlIE1hcCBFdmVudHNcblx0QE91dHB1dCgnbGVhZmxldENsaWNrJykgb25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXREb3VibGVDbGljaycpIG9uRG91YmxlQ2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRNb3VzZUV2ZW50PigpO1xuXHRAT3V0cHV0KCdsZWFmbGV0TW91c2VEb3duJykgb25Nb3VzZURvd24gPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRNb3VzZUV2ZW50PigpO1xuXHRAT3V0cHV0KCdsZWFmbGV0TW91c2VVcCcpIG9uTW91c2VVcCA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNb3VzZU1vdmUnKSBvbk1vdXNlTW92ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNb3VzZU92ZXInKSBvbk1vdXNlT3ZlciA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldE1vdXNlRXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNb3VzZU91dCcpIG9uTW91c2VPdXQgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRNb3VzZUV2ZW50PigpO1xuXG5cdC8vIE1hcCBNb3ZlIEV2ZW50c1xuXHRAT3V0cHV0KCdsZWFmbGV0TWFwTW92ZScpIG9uTWFwTW92ZSA9IG5ldyBFdmVudEVtaXR0ZXI8TGVhZmxldEV2ZW50PigpO1xuXHRAT3V0cHV0KCdsZWFmbGV0TWFwTW92ZVN0YXJ0Jykgb25NYXBNb3ZlU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRFdmVudD4oKTtcblx0QE91dHB1dCgnbGVhZmxldE1hcE1vdmVFbmQnKSBvbk1hcE1vdmVFbmQgPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRFdmVudD4oKTtcblxuXHQvLyBNYXAgWm9vbSBFdmVudHNcblx0QE91dHB1dCgnbGVhZmxldE1hcFpvb20nKSBvbk1hcFpvb20gPSBuZXcgRXZlbnRFbWl0dGVyPExlYWZsZXRFdmVudD4oKTtcblx0QE91dHB1dCgnbGVhZmxldE1hcFpvb21TdGFydCcpIG9uTWFwWm9vbVN0YXJ0ID0gbmV3IEV2ZW50RW1pdHRlcjxMZWFmbGV0RXZlbnQ+KCk7XG5cdEBPdXRwdXQoJ2xlYWZsZXRNYXBab29tRW5kJykgb25NYXBab29tRW5kID0gbmV3IEV2ZW50RW1pdHRlcjxMZWFmbGV0RXZlbnQ+KCk7XG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmLCBwcml2YXRlIHpvbmU6IE5nWm9uZSkge1xuXHRcdC8vIE5vdGhpbmcgaGVyZVxuXHR9XG5cblx0bmdPbkluaXQoKSB7XG5cblx0XHQvLyBDcmVhdGUgdGhlIG1hcCBvdXRzaWRlIG9mIGFuZ3VsYXIgc28gdGhlIHZhcmlvdXMgbWFwIGV2ZW50cyBkb24ndCB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cblx0XHR0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuXG5cdFx0XHQvLyBDcmVhdGUgdGhlIG1hcCB3aXRoIHNvbWUgcmVhc29uYWJsZSBkZWZhdWx0c1xuXHRcdFx0dGhpcy5tYXAgPSBtYXAodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIHRoaXMub3B0aW9ucyk7XG5cdFx0XHR0aGlzLmFkZE1hcEV2ZW50TGlzdGVuZXJzKCk7XG5cblx0XHR9KTtcblxuXHRcdC8vIE9ubHkgc2V0VmlldyBpZiB0aGVyZSBpcyBhIGNlbnRlci96b29tXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5jZW50ZXIgJiYgbnVsbCAhPSB0aGlzLnpvb20pIHtcblx0XHRcdHRoaXMuc2V0Vmlldyh0aGlzLmNlbnRlciwgdGhpcy56b29tKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdXAgYWxsIHRoZSBpbml0aWFsIHNldHRpbmdzXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5maXRCb3VuZHMpIHtcblx0XHRcdHRoaXMuc2V0Rml0Qm91bmRzKHRoaXMuZml0Qm91bmRzKTtcblx0XHR9XG5cblx0XHRpZiAobnVsbCAhPSB0aGlzLm1heEJvdW5kcykge1xuXHRcdFx0dGhpcy5zZXRNYXhCb3VuZHModGhpcy5tYXhCb3VuZHMpO1xuXHRcdH1cblxuXHRcdGlmIChudWxsICE9IHRoaXMubWluWm9vbSkge1xuXHRcdFx0dGhpcy5zZXRNaW5ab29tKHRoaXMubWluWm9vbSk7XG5cdFx0fVxuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXhab29tKSB7XG5cdFx0XHR0aGlzLnNldE1heFpvb20odGhpcy5tYXhab29tKTtcblx0XHR9XG5cblx0XHR0aGlzLmRvUmVzaXplKCk7XG5cblx0XHQvLyBGaXJlIG1hcCByZWFkeSBldmVudFxuXHRcdHRoaXMubWFwUmVhZHkuZW1pdCh0aGlzLm1hcCk7XG5cblx0fVxuXG5cdG5nT25DaGFuZ2VzKGNoYW5nZXM6IHsgW2tleTogc3RyaW5nXTogU2ltcGxlQ2hhbmdlIH0pIHtcblxuXHRcdC8qXG5cdFx0ICogVGhlIGZvbGxvd2luZyBjb2RlIGlzIHRvIGFkZHJlc3MgYW4gaXNzdWUgd2l0aCBvdXIgKGJhc2ljKSBpbXBsZW1lbnRhdGlvbiBvZlxuXHRcdCAqIHpvb21pbmcgYW5kIHBhbm5pbmcuIEZyb20gb3VyIHRlc3RpbmcsIGl0IHNlZW1zIHRoYXQgYSBwYW4gb3BlcmF0aW9uIGZvbGxvd2VkXG5cdFx0ICogYnkgYSB6b29tIG9wZXJhdGlvbiBpbiB0aGUgc2FtZSB0aHJlYWQgd2lsbCBpbnRlcmZlcmUgd2l0aCBlYWNob3RoZXIuIFRoZSB6b29tXG5cdFx0ICogb3BlcmF0aW9uIGludGVycnVwdHMvY2FuY2VscyB0aGUgcGFuLCByZXN1bHRpbmcgaW4gYSBmaW5hbCBjZW50ZXIgcG9pbnQgdGhhdCBpc1xuXHRcdCAqIGluYWNjdXJhdGUuIFRoZSBzb2x1dGlvbiBzZWVtcyB0byBiZSB0byBlaXRoZXIgc2VwYXJhdGUgdGhlbSB3aXRoIGEgdGltZW91dCBvclxuXHRcdCAgKiB0byBjb2xsYXBzZSB0aGVtIGludG8gYSBzZXRWaWV3IGNhbGwuXG5cdFx0ICovXG5cblx0XHQvLyBab29taW5nIGFuZCBQYW5uaW5nXG5cdFx0aWYgKGNoYW5nZXNbJ3pvb20nXSAmJiBjaGFuZ2VzWydjZW50ZXInXSAmJiBudWxsICE9IHRoaXMuem9vbSAmJiBudWxsICE9IHRoaXMuY2VudGVyKSB7XG5cdFx0XHR0aGlzLnNldFZpZXcoY2hhbmdlc1snY2VudGVyJ10uY3VycmVudFZhbHVlLCBjaGFuZ2VzWyd6b29tJ10uY3VycmVudFZhbHVlKTtcblx0XHR9XG5cdFx0Ly8gU2V0IHRoZSB6b29tIGxldmVsXG5cdFx0ZWxzZSBpZiAoY2hhbmdlc1snem9vbSddKSB7XG5cdFx0XHR0aGlzLnNldFpvb20oY2hhbmdlc1snem9vbSddLmN1cnJlbnRWYWx1ZSk7XG5cdFx0fVxuXHRcdC8vIFNldCB0aGUgbWFwIGNlbnRlclxuXHRcdGVsc2UgaWYgKGNoYW5nZXNbJ2NlbnRlciddKSB7XG5cdFx0XHR0aGlzLnNldENlbnRlcihjaGFuZ2VzWydjZW50ZXInXS5jdXJyZW50VmFsdWUpO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyIG9wdGlvbnNcblx0XHRpZiAoY2hhbmdlc1snZml0Qm91bmRzJ10pIHtcblx0XHRcdHRoaXMuc2V0Rml0Qm91bmRzKGNoYW5nZXNbJ2ZpdEJvdW5kcyddLmN1cnJlbnRWYWx1ZSk7XG5cdFx0fVxuXG5cdFx0aWYgKGNoYW5nZXNbJ21heEJvdW5kcyddKSB7XG5cdFx0XHR0aGlzLnNldE1heEJvdW5kcyhjaGFuZ2VzWydtYXhCb3VuZHMnXS5jdXJyZW50VmFsdWUpO1xuXHRcdH1cblxuXHRcdGlmIChjaGFuZ2VzWydtaW5ab29tJ10pIHtcblx0XHRcdHRoaXMuc2V0TWluWm9vbShjaGFuZ2VzWydtaW5ab29tJ10uY3VycmVudFZhbHVlKTtcblx0XHR9XG5cblx0XHRpZiAoY2hhbmdlc1snbWF4Wm9vbSddKSB7XG5cdFx0XHR0aGlzLnNldE1heFpvb20oY2hhbmdlc1snbWF4Wm9vbSddLmN1cnJlbnRWYWx1ZSk7XG5cdFx0fVxuXG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHQvLyBJZiB0aGlzIGRpcmVjdGl2ZSBpcyBkZXN0cm95ZWQsIHRoZSBtYXAgaXMgdG9vXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXApIHtcblx0XHRcdHRoaXMubWFwLnJlbW92ZSgpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBnZXRNYXAoKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFwO1xuXHR9XG5cblxuXHRASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgW10pXG5cdG9uUmVzaXplKCkge1xuXHRcdHRoaXMuZGVsYXlSZXNpemUoKTtcblx0fVxuXG5cdHByaXZhdGUgYWRkTWFwRXZlbnRMaXN0ZW5lcnMoKSB7XG5cblx0XHRjb25zdCByZWdpc3RlckV2ZW50SGFuZGxlciA9IChldmVudE5hbWU6IHN0cmluZywgaGFuZGxlcjogKGU6IExlYWZsZXRFdmVudCkgPT4gYW55KSA9PiB7XG5cdFx0XHR0aGlzLm1hcC5vbihldmVudE5hbWUsIGhhbmRsZXIpO1xuXHRcdH07XG5cblxuXHRcdC8vIEFkZCBhbGwgdGhlIHBhc3MtdGhyb3VnaCBtb3VzZSBldmVudCBoYW5kbGVyc1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCdjbGljaycsIChlOiBMZWFmbGV0TW91c2VFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uQ2xpY2ssIGUpKTtcblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignZGJsY2xpY2snLCAoZTogTGVhZmxldE1vdXNlRXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbkRvdWJsZUNsaWNrLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdXNlZG93bicsIChlOiBMZWFmbGV0TW91c2VFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTW91c2VEb3duLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdXNldXAnLCAoZTogTGVhZmxldE1vdXNlRXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbk1vdXNlVXAsIGUpKTtcblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignbW91c2VvdmVyJywgKGU6IExlYWZsZXRNb3VzZUV2ZW50KSA9PiBMZWFmbGV0VXRpbC5oYW5kbGVFdmVudCh0aGlzLnpvbmUsIHRoaXMub25Nb3VzZU92ZXIsIGUpKTtcblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignbW91c2VvdXQnLCAoZTogTGVhZmxldE1vdXNlRXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbk1vdXNlT3V0LCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdXNlbW92ZScsIChlOiBMZWFmbGV0TW91c2VFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTW91c2VNb3ZlLCBlKSk7XG5cblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignem9vbXN0YXJ0JywgKGU6IExlYWZsZXRFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTWFwWm9vbVN0YXJ0LCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ3pvb20nLCAoZTogTGVhZmxldEV2ZW50KSA9PiBMZWFmbGV0VXRpbC5oYW5kbGVFdmVudCh0aGlzLnpvbmUsIHRoaXMub25NYXBab29tLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ3pvb21lbmQnLCAoZTogTGVhZmxldEV2ZW50KSA9PiBMZWFmbGV0VXRpbC5oYW5kbGVFdmVudCh0aGlzLnpvbmUsIHRoaXMub25NYXBab29tRW5kLCBlKSk7XG5cdFx0cmVnaXN0ZXJFdmVudEhhbmRsZXIoJ21vdmVzdGFydCcsIChlOiBMZWFmbGV0RXZlbnQpID0+IExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5vbk1hcE1vdmVTdGFydCwgZSkpO1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCdtb3ZlJywgKGU6IExlYWZsZXRFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTWFwTW92ZSwgZSkpO1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCdtb3ZlZW5kJywgKGU6IExlYWZsZXRFdmVudCkgPT4gTGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLm9uTWFwTW92ZUVuZCwgZSkpO1xuXG5cblx0XHQvLyBVcGRhdGUgYW55IHRoaW5ncyBmb3Igd2hpY2ggd2UgcHJvdmlkZSBvdXRwdXQgYmluZGluZ3Ncblx0XHRjb25zdCBvdXRwdXRVcGRhdGVIYW5kbGVyID0gKCkgPT4ge1xuXHRcdFx0Y29uc3Qgem9vbSA9IHRoaXMubWFwLmdldFpvb20oKTtcblx0XHRcdGlmICh6b29tICE9PSB0aGlzLnpvb20pIHtcblx0XHRcdFx0dGhpcy56b29tID0gem9vbTtcblx0XHRcdFx0TGVhZmxldFV0aWwuaGFuZGxlRXZlbnQodGhpcy56b25lLCB0aGlzLnpvb21DaGFuZ2UsIHpvb20pO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBjZW50ZXIgPSB0aGlzLm1hcC5nZXRDZW50ZXIoKTtcblx0XHRcdGlmIChudWxsICE9IGNlbnRlciB8fCBudWxsICE9IHRoaXMuY2VudGVyKSB7XG5cblx0XHRcdFx0aWYgKCgobnVsbCA9PSBjZW50ZXIgfHwgbnVsbCA9PSB0aGlzLmNlbnRlcikgJiYgY2VudGVyICE9PSB0aGlzLmNlbnRlcilcblx0XHRcdFx0XHR8fCAoY2VudGVyLmxhdCAhPT0gdGhpcy5jZW50ZXIubGF0IHx8IGNlbnRlci5sbmcgIT09IHRoaXMuY2VudGVyLmxuZykpIHtcblxuXHRcdFx0XHRcdHRoaXMuY2VudGVyID0gY2VudGVyO1xuXHRcdFx0XHRcdExlYWZsZXRVdGlsLmhhbmRsZUV2ZW50KHRoaXMuem9uZSwgdGhpcy5jZW50ZXJDaGFuZ2UsIGNlbnRlcik7XG5cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZWdpc3RlckV2ZW50SGFuZGxlcignbW92ZWVuZCcsIG91dHB1dFVwZGF0ZUhhbmRsZXIpO1xuXHRcdHJlZ2lzdGVyRXZlbnRIYW5kbGVyKCd6b29tZW5kJywgb3V0cHV0VXBkYXRlSGFuZGxlcik7XG5cdH1cblxuXHQvKipcblx0ICogUmVzaXplIHRoZSBtYXAgdG8gZml0IGl0J3MgcGFyZW50IGNvbnRhaW5lclxuXHQgKi9cblx0cHJpdmF0ZSBkb1Jlc2l6ZSgpIHtcblxuXHRcdC8vIFJ1biB0aGlzIG91dHNpZGUgb2YgYW5ndWxhciBzbyB0aGUgbWFwIGV2ZW50cyBzdGF5IG91dHNpZGUgb2YgYW5ndWxhclxuXHRcdHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG5cblx0XHRcdC8vIEludmFsaWRhdGUgdGhlIG1hcCBzaXplIHRvIHRyaWdnZXIgaXQgdG8gdXBkYXRlIGl0c2VsZlxuXHRcdFx0aWYgKG51bGwgIT0gdGhpcy5tYXApIHtcblx0XHRcdFx0dGhpcy5tYXAuaW52YWxpZGF0ZVNpemUoe30pO1xuXHRcdFx0fVxuXG5cdFx0fSk7XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBNYW5hZ2UgYSBkZWxheWVkIHJlc2l6ZSBvZiB0aGUgY29tcG9uZW50XG5cdCAqL1xuXHRwcml2YXRlIGRlbGF5UmVzaXplKCkge1xuXHRcdGlmIChudWxsICE9IHRoaXMucmVzaXplVGltZXIpIHtcblx0XHRcdGNsZWFyVGltZW91dCh0aGlzLnJlc2l6ZVRpbWVyKTtcblx0XHR9XG5cdFx0dGhpcy5yZXNpemVUaW1lciA9IHNldFRpbWVvdXQodGhpcy5kb1Jlc2l6ZS5iaW5kKHRoaXMpLCAyMDApO1xuXHR9XG5cblxuXHQvKipcblx0ICogU2V0IHRoZSB2aWV3IChjZW50ZXIvem9vbSkgYWxsIGF0IG9uY2Vcblx0ICogQHBhcmFtIGNlbnRlciBUaGUgbmV3IGNlbnRlclxuXHQgKiBAcGFyYW0gem9vbSBUaGUgbmV3IHpvb20gbGV2ZWxcblx0ICovXG5cdHByaXZhdGUgc2V0VmlldyhjZW50ZXI6IExhdExuZywgem9vbTogbnVtYmVyKSB7XG5cblx0XHRpZiAobnVsbCAhPSB0aGlzLm1hcCAmJiBudWxsICE9IGNlbnRlciAmJiBudWxsICE9IHpvb20pIHtcblx0XHRcdHRoaXMubWFwLnNldFZpZXcoY2VudGVyLCB6b29tLCB0aGlzLnpvb21QYW5PcHRpb25zKTtcblx0XHR9XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIG1hcCB6b29tIGxldmVsXG5cdCAqIEBwYXJhbSB6b29tIHRoZSBuZXcgem9vbSBsZXZlbCBmb3IgdGhlIG1hcFxuXHQgKi9cblx0cHJpdmF0ZSBzZXRab29tKHpvb206IG51bWJlcikge1xuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXAgJiYgbnVsbCAhPSB6b29tKSB7XG5cdFx0XHR0aGlzLm1hcC5zZXRab29tKHpvb20sIHRoaXMuem9vbU9wdGlvbnMpO1xuXHRcdH1cblxuXHR9XG5cblx0LyoqXG5cdCAqIFNldCB0aGUgY2VudGVyIG9mIHRoZSBtYXBcblx0ICogQHBhcmFtIGNlbnRlciB0aGUgY2VudGVyIHBvaW50XG5cdCAqL1xuXHRwcml2YXRlIHNldENlbnRlcihjZW50ZXI6IExhdExuZykge1xuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXAgJiYgbnVsbCAhPSBjZW50ZXIpIHtcblx0XHRcdHRoaXMubWFwLnBhblRvKGNlbnRlciwgdGhpcy5wYW5PcHRpb25zKTtcblx0XHR9XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBGaXQgdGhlIG1hcCB0byB0aGUgYm91bmRzXG5cdCAqIEBwYXJhbSBsYXRMbmdCb3VuZHMgdGhlIGJvdW5kYXJ5IHRvIHNldFxuXHQgKi9cblx0cHJpdmF0ZSBzZXRGaXRCb3VuZHMobGF0TG5nQm91bmRzOiBMYXRMbmdCb3VuZHMpIHtcblxuXHRcdGlmIChudWxsICE9IHRoaXMubWFwICYmIG51bGwgIT0gbGF0TG5nQm91bmRzKSB7XG5cdFx0XHR0aGlzLm1hcC5maXRCb3VuZHMobGF0TG5nQm91bmRzLCB0aGlzLmZpdEJvdW5kc09wdGlvbnMpO1xuXHRcdH1cblxuXHR9XG5cblx0LyoqXG5cdCAqIFNldCB0aGUgbWFwJ3MgbWF4IGJvdW5kc1xuXHQgKiBAcGFyYW0gbGF0TG5nQm91bmRzIHRoZSBib3VuZGFyeSB0byBzZXRcblx0ICovXG5cdHByaXZhdGUgc2V0TWF4Qm91bmRzKGxhdExuZ0JvdW5kczogTGF0TG5nQm91bmRzKSB7XG5cblx0XHRpZiAobnVsbCAhPSB0aGlzLm1hcCAmJiBudWxsICE9IGxhdExuZ0JvdW5kcykge1xuXHRcdFx0dGhpcy5tYXAuc2V0TWF4Qm91bmRzKGxhdExuZ0JvdW5kcyk7XG5cdFx0fVxuXG5cdH1cblxuXHQvKipcblx0ICogU2V0IHRoZSBtYXAncyBtaW4gem9vbVxuXHQgKiBAcGFyYW0gbnVtYmVyIHRoZSBuZXcgbWluIHpvb21cblx0ICovXG5cdHByaXZhdGUgc2V0TWluWm9vbSh6b29tOiBudW1iZXIpIHtcblxuXHRcdGlmIChudWxsICE9IHRoaXMubWFwICYmIG51bGwgIT0gem9vbSkge1xuXHRcdFx0dGhpcy5tYXAuc2V0TWluWm9vbSh6b29tKTtcblx0XHR9XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIG1hcCdzIG1pbiB6b29tXG5cdCAqIEBwYXJhbSBudW1iZXIgdGhlIG5ldyBtaW4gem9vbVxuXHQgKi9cblx0cHJpdmF0ZSBzZXRNYXhab29tKHpvb206IG51bWJlcikge1xuXG5cdFx0aWYgKG51bGwgIT0gdGhpcy5tYXAgJiYgbnVsbCAhPSB6b29tKSB7XG5cdFx0XHR0aGlzLm1hcC5zZXRNYXhab29tKHpvb20pO1xuXHRcdH1cblxuXHR9XG5cbn1cbiJdfQ== |
\ | No newline at end of file |