ca-components 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/esm2022/lib/ca-components.module.mjs +12 -6
  2. package/esm2022/lib/components/ca-dots-menu/ca-dots-menu.component.mjs +33 -0
  3. package/esm2022/lib/components/ca-dropdown/ca-dropdown.component.mjs +3 -3
  4. package/esm2022/lib/components/ca-input/components/ca-input-placeholder-icon/ca-input-placeholder-icon.component.mjs +3 -3
  5. package/esm2022/lib/components/ca-map/ca-map.component.mjs +270 -187
  6. package/esm2022/lib/components/ca-map/models/map.model.mjs +1 -1
  7. package/esm2022/lib/components/ca-map/utils/constants/map-info-window-options.constants.mjs +2 -2
  8. package/esm2022/lib/components/ca-map/utils/constants/map-options.constants.mjs +15 -1
  9. package/esm2022/lib/components/ca-map-dropdown/ca-map-dropdown.component.mjs +43 -14
  10. package/esm2022/lib/components/ca-map-dropdown/models/index.mjs +2 -0
  11. package/esm2022/lib/components/ca-map-dropdown/models/map-dropdown-content.model.mjs +2 -0
  12. package/esm2022/lib/components/ca-map-dropdown/pipes/index.mjs +3 -0
  13. package/esm2022/lib/components/ca-map-dropdown/pipes/map-dropdown-cluster-content-type.pipe.mjs +19 -0
  14. package/esm2022/lib/components/ca-map-dropdown/pipes/map-dropdown-content-type.pipe.mjs +19 -0
  15. package/esm2022/lib/components/ca-map-dropdown/utils/svg-routes/map-dropdown-svg-routes.mjs +4 -1
  16. package/esm2022/lib/components/ca-period-content/components/ca-period-content-payment/ca-period-content-payment.component.mjs +8 -4
  17. package/esm2022/lib/components/ca-progress-bar/ca-progress-bar.component.mjs +1 -1
  18. package/esm2022/public-api.mjs +2 -1
  19. package/fesm2022/ca-components.mjs +403 -212
  20. package/fesm2022/ca-components.mjs.map +1 -1
  21. package/lib/ca-components.module.d.ts +2 -1
  22. package/lib/components/ca-dots-menu/ca-dots-menu.component.d.ts +12 -0
  23. package/lib/components/ca-map/ca-map.component.d.ts +48 -16
  24. package/lib/components/ca-map/models/map.model.d.ts +15 -3
  25. package/lib/components/ca-map/utils/constants/map-options.constants.d.ts +18 -0
  26. package/lib/components/ca-map-dropdown/ca-map-dropdown.component.d.ts +13 -6
  27. package/lib/components/ca-map-dropdown/models/index.d.ts +1 -0
  28. package/lib/components/ca-map-dropdown/models/map-dropdown-content.model.d.ts +28 -0
  29. package/lib/components/ca-map-dropdown/pipes/index.d.ts +2 -0
  30. package/lib/components/ca-map-dropdown/pipes/map-dropdown-cluster-content-type.pipe.d.ts +8 -0
  31. package/lib/components/ca-map-dropdown/pipes/map-dropdown-content-type.pipe.d.ts +8 -0
  32. package/lib/components/ca-map-dropdown/utils/svg-routes/map-dropdown-svg-routes.d.ts +3 -0
  33. package/package.json +1 -1
  34. package/public-api.d.ts +1 -0
  35. package/src/assets/ca-components/svg/map/ic_date_checked.svg +1 -0
  36. package/src/assets/ca-components/svg/map/ic_date_deactivated.svg +3 -0
  37. package/src/assets/ca-components/svg/map/ic_favorite.svg +3 -0
  38. package/src/assets/ca-components/svg/map/ic_permanently_closed.svg +4 -0
@@ -1,17 +1,13 @@
1
1
  import { CommonModule } from '@angular/common';
2
- import { Component, EventEmitter, Input, Output, ViewChild, ViewChildren, ViewEncapsulation, } from '@angular/core';
3
- //Modules
2
+ import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
4
3
  import { GoogleMap, GoogleMapsModule, MapInfoWindow, } from '@angular/google-maps';
5
- //icon
6
4
  import { AngularSvgIconModule } from 'angular-svg-icon';
7
- //Components
5
+ // Components
8
6
  import { CaMapDropdownComponent } from '../ca-map-dropdown/ca-map-dropdown.component';
9
- //Enums
7
+ // Enums
10
8
  import { GoogleMapEnum } from '../ca-map/enums/google-map.enum';
11
- //HelperFuntion
9
+ // Helpers
12
10
  import { MapHelper } from '../ca-map/utils/helpers/map.helper';
13
- //svg-routes
14
- import { MapSvgRoutes } from '../ca-map/utils/map-svg-routes/map-svg-routes';
15
11
  // Constants
16
12
  import { MapInfoWindowOptionsConstants, MapOptionsConstants, } from './utils/constants';
17
13
  import { MapConstants } from '../../constants/map.constant';
@@ -21,11 +17,11 @@ import * as i2 from "@angular/common";
21
17
  export class CaMapComponent {
22
18
  constructor(cd) {
23
19
  this.cd = cd;
24
- this.markerClick = new EventEmitter();
25
- this.currentlyOpenWindowIndex = null;
26
- this.currentlyOpenWindowIndexRouting = null;
27
- this.showLabel = true;
28
- this.focusedIcon = null;
20
+ this.resetSelectedMarkerItem = new EventEmitter();
21
+ this.clusterMarkerClick = new EventEmitter();
22
+ this.clusterListScrollEvent = new EventEmitter();
23
+ this.getInfoWindowData = new EventEmitter();
24
+ this.boundsChanged = new EventEmitter();
29
25
  this.directionService = new google.maps.DirectionsService();
30
26
  this.directionsRenderers = [];
31
27
  this.initialIcons = [];
@@ -35,6 +31,16 @@ export class CaMapComponent {
35
31
  this.mapZoom = MapOptionsConstants.defaultMapZoom;
36
32
  this.mapCenter = MapOptionsConstants.defaultMapCenter;
37
33
  this.map = null;
34
+ this.isMapCenterSet = false;
35
+ this.clusterMarkersData = [];
36
+ this.markersData = [];
37
+ this.mapData = {};
38
+ this.openedInfoWindowData = null;
39
+ this.areaFilterData = MapOptionsConstants.areaFilterData;
40
+ this.isAreaFilterActive = false;
41
+ }
42
+ set data(values) {
43
+ this.handleMapData(values);
38
44
  }
39
45
  ngOnInit() {
40
46
  this.storeInitialIconForMarker();
@@ -45,78 +51,41 @@ export class CaMapComponent {
45
51
  //Display routes for routingMarkers
46
52
  this.calculateAndDisplayRoute();
47
53
  }
48
- ngOnChanges(changes) {
49
- if (changes['routingMarkers']) {
50
- this.data.routingMarkers = changes['routingMarkers'].currentValue;
51
- }
52
- }
53
54
  storeInitialIconForMarker() {
54
- this.data.markers?.forEach((marker, index) => {
55
+ this.initialMarkerIcons = [];
56
+ this.mapData.markers?.forEach((marker, index) => {
55
57
  this.initialMarkerIcons[index] = {
56
58
  url: marker.icon.url,
57
59
  labelOrigin: marker.icon.labelOrigin,
60
+ zIndex: marker.options?.zIndex ?? 1,
58
61
  };
59
62
  });
60
63
  }
61
64
  storeInitialIconForRoutingMarker() {
62
- this.data.routingMarkers?.forEach((marker, index) => {
65
+ this.mapData.routingMarkers?.forEach((marker, index) => {
63
66
  this.initialIcons[index] = {
64
67
  url: marker.icon.url,
65
68
  labelOrigin: marker.icon.labelOrigin,
66
69
  };
67
70
  });
68
71
  }
69
- onMarkerClick(i, event, markeritem) {
70
- if (markeritem?.infoWindowContent) {
71
- if (this.currentlyOpenWindowIndex === i && this.currentlyOpenWindow) {
72
- const infoWindow = this.infoWindowsView.toArray()[i];
73
- // Close the currently open info window and reset the index
74
- this.data.markers.map((item, index) => {
75
- if (index === i) {
76
- item.icon = {
77
- url: this.initialMarkerIcons[index].url,
78
- labelOrigin: this.initialMarkerIcons[index].labelOrigin,
79
- };
80
- }
81
- });
82
- infoWindow.close();
83
- this.currentlyOpenWindowIndex = null;
84
- this.focusedIcon = null;
85
- }
86
- else {
87
- const markerIndex = this.marker.toArray()[i];
88
- const infoWindow = this.infoWindowsView.toArray()[i];
89
- if (this.currentlyOpenWindow) {
90
- this.currentlyOpenWindow.close();
91
- }
92
- if (infoWindow) {
93
- this.data.markers.map((item, index) => {
94
- if (index === i) {
95
- this.focusedIcon = i;
96
- this.showLabel = false;
97
- item.icon = {
98
- url: this.initialMarkerIcons[index].url,
99
- scaledSize: new google.maps.Size(55, 55),
100
- };
101
- }
102
- else {
103
- this.showLabel = true;
104
- item.icon = {
105
- url: this.initialMarkerIcons[index].url,
106
- labelOrigin: this.initialMarkerIcons[index].labelOrigin,
107
- };
108
- }
109
- });
110
- infoWindow.open(markerIndex);
111
- this.currentlyOpenWindow = infoWindow;
112
- this.currentlyOpenWindowIndex = i;
113
- this.markerClick.emit(event);
114
- }
115
- }
116
- }
117
- else {
118
- return;
119
- }
72
+ onClusterMarkerClick(markerItem) {
73
+ const isInfoWindowOpened = this.checkInfoWindowPosition(markerItem, this.openedInfoWindowData);
74
+ if (!isInfoWindowOpened)
75
+ this.clusterMarkerClick.emit(markerItem);
76
+ else
77
+ this.closeInfoWindow();
78
+ }
79
+ getMarkerInfoWindow(markerId) {
80
+ if (markerId)
81
+ this.getInfoWindowData.emit(markerId);
82
+ }
83
+ onMarkerClick(markerItem) {
84
+ const isInfoWindowOpened = this.checkInfoWindowPosition(markerItem, this.openedInfoWindowData);
85
+ if (!isInfoWindowOpened)
86
+ this.getMarkerInfoWindow(markerItem.data.id);
87
+ else
88
+ this.closeInfoWindow();
120
89
  }
121
90
  setDirectionsOnMap() {
122
91
  if (this.maps?.googleMap) {
@@ -124,11 +93,11 @@ export class CaMapComponent {
124
93
  }
125
94
  }
126
95
  calculateAndDisplayRoute() {
127
- if (this.data.routePaths) {
96
+ if (this.mapData.routePaths) {
128
97
  // Clear previous directions renderers
129
98
  this.directionsRenderers.forEach((renderer) => renderer.setMap(null));
130
99
  this.directionsRenderers = [];
131
- this.data.routePaths.forEach((route) => {
100
+ this.mapData.routePaths.forEach((route) => {
132
101
  const request = {
133
102
  origin: route.path[0],
134
103
  destination: route.path[route.path.length - 1],
@@ -161,88 +130,77 @@ export class CaMapComponent {
161
130
  }
162
131
  }
163
132
  onRoutingMarkerClick(i, event, markeritem) {
164
- if (markeritem?.infoWindowContent) {
165
- if (this.currentlyOpenWindowIndexRouting === i &&
166
- this.currentlyOpenWindowRouting) {
167
- const infoWindow = this.infoWindowsViewRouting.toArray()[i];
168
- // Close the currently open info window and reset the index
169
- this.data.routingMarkers.map((item, index) => {
170
- if (index === i) {
171
- item.icon = {
172
- url: this.initialIcons[index].url,
173
- labelOrigin: this.initialIcons[index].labelOrigin,
174
- };
175
- }
176
- });
177
- infoWindow.close();
178
- this.currentlyOpenWindowIndexRouting = null;
179
- }
180
- else {
181
- const markerIndex = this.markerRouting.toArray()[i];
182
- const infoWindow = this.infoWindowsViewRouting.toArray()[i];
183
- if (this.currentlyOpenWindowRouting) {
184
- this.currentlyOpenWindowRouting.close();
185
- }
186
- if (infoWindow) {
187
- // Restore the previous icon for the previously focused routing marker
188
- if (this.focusedIconRouting !== undefined &&
189
- this.focusedIconRouting !== i) {
190
- const previousFocusedItem = this.data.routingMarkers[this.focusedIconRouting];
191
- if (previousFocusedItem) {
192
- previousFocusedItem.icon = {
193
- url: this.initialIcons[this.focusedIconRouting].url,
194
- labelOrigin: this.initialIcons[this.focusedIconRouting].labelOrigin,
195
- };
196
- }
197
- }
198
- // Update the current marker
199
- this.data.routingMarkers.map((item, index) => {
200
- if (index === i) {
201
- this.previousIconUrlRouting = item.icon ? item.icon.url : '';
202
- this.focusedIconRouting = i;
203
- this.showLabel = false;
204
- item.icon = {
205
- url: this.data.isUnitViewStops || this.data.isDriverMiles
206
- ? item.icon.url
207
- : MapSvgRoutes.markerSvgRoute,
208
- };
209
- }
210
- else {
211
- this.showLabel = true;
212
- }
213
- });
214
- infoWindow.open(markerIndex);
215
- this.currentlyOpenWindowRouting = infoWindow;
216
- this.currentlyOpenWindowIndexRouting = i;
217
- this.markerClick.emit(event);
218
- }
219
- }
220
- }
221
- else {
222
- return;
223
- }
133
+ // if (markeritem?.infoWindowContent) {
134
+ // if (
135
+ // this.currentlyOpenWindowIndexRouting === i &&
136
+ // this.currentlyOpenWindowRouting
137
+ // ) {
138
+ // const infoWindow = this.infoWindowsViewRouting.toArray()[i];
139
+ // // Close the currently open info window and reset the index
140
+ // this.mapData.routingMarkers!.map((item: IMapMarkers, index: number) => {
141
+ // if (index === i) {
142
+ // item.icon = {
143
+ // url: this.initialIcons[index]!.url,
144
+ // labelOrigin: this.initialIcons[index]!.labelOrigin,
145
+ // };
146
+ // }
147
+ // });
148
+ // infoWindow.close();
149
+ // this.currentlyOpenWindowIndexRouting = null;
150
+ // } else {
151
+ // const markerIndex = this.markerRouting.toArray()[i];
152
+ // const infoWindow = this.infoWindowsViewRouting.toArray()[i];
153
+ // if (this.currentlyOpenWindowRouting) {
154
+ // this.currentlyOpenWindowRouting.close();
155
+ // }
156
+ // if (infoWindow) {
157
+ // // Restore the previous icon for the previously focused routing marker
158
+ // if (
159
+ // this.focusedIconRouting !== undefined &&
160
+ // this.focusedIconRouting !== i
161
+ // ) {
162
+ // const previousFocusedItem =
163
+ // this.mapData.routingMarkers![this.focusedIconRouting];
164
+ // if (previousFocusedItem) {
165
+ // previousFocusedItem.icon = {
166
+ // url: this.initialIcons[this.focusedIconRouting].url,
167
+ // labelOrigin:
168
+ // this.initialIcons[this.focusedIconRouting].labelOrigin,
169
+ // };
170
+ // }
171
+ // }
172
+ // // Update the current marker
173
+ // this.mapData.routingMarkers!.map(
174
+ // (item: IMapMarkers, index: number) => {
175
+ // if (index === i) {
176
+ // this.previousIconUrlRouting = item.icon ? item.icon.url : '';
177
+ // this.focusedIconRouting = i;
178
+ // this.showLabel = false;
179
+ // item.icon = {
180
+ // url:
181
+ // this.mapData.isUnitViewStops || this.mapData.isDriverMiles
182
+ // ? item.icon!.url
183
+ // : MapSvgRoutes.markerSvgRoute,
184
+ // };
185
+ // } else {
186
+ // this.showLabel = true;
187
+ // }
188
+ // }
189
+ // );
190
+ // infoWindow.open(markerIndex);
191
+ // this.currentlyOpenWindowRouting = infoWindow;
192
+ // this.currentlyOpenWindowIndexRouting = i;
193
+ // }
194
+ // }
195
+ // this.markerClick.emit(markeritem);
196
+ // } else {
197
+ // return;
198
+ // }
224
199
  }
225
200
  ngAfterViewInit() {
226
201
  this.maps.googleMap?.addListener('click', () => {
227
- this.infoWindowsView.forEach((window) => {
228
- window.close();
229
- this.currentlyOpenWindow = null;
230
- });
231
- this.infoWindowsViewRouting.forEach((window) => {
232
- window.close();
233
- this.currentlyOpenWindowRouting = null;
234
- });
235
- this.data.markers?.forEach((item, i) => {
236
- if (i === this.focusedIcon) {
237
- item.icon = {
238
- url: this.initialMarkerIcons[i].url,
239
- labelOrigin: this.initialMarkerIcons[i].labelOrigin,
240
- };
241
- this.focusedIcon = null;
242
- this.cd.detectChanges();
243
- }
244
- });
245
- this.data.routingMarkers?.map((item, i) => {
202
+ this.closeInfoWindow();
203
+ this.mapData.routingMarkers?.map((item, i) => {
246
204
  if (i === this.focusedIconRouting) {
247
205
  item.icon = {
248
206
  url: this.initialIcons[i].url,
@@ -253,16 +211,20 @@ export class CaMapComponent {
253
211
  });
254
212
  }
255
213
  resetMarkersIcons() {
256
- this.data.markers?.forEach((marker, index) => {
257
- marker.icon = {
258
- url: this.initialMarkerIcons[index].url,
259
- labelOrigin: this.initialMarkerIcons[index].labelOrigin,
214
+ this.mapData.markers?.map((marker, index) => {
215
+ return {
216
+ ...marker,
217
+ icon: {
218
+ ...marker.icon,
219
+ scaledSize: MapOptionsConstants.defaultMarkerSize,
220
+ },
221
+ options: { zIndex: index + 1 },
260
222
  };
261
223
  });
262
224
  this.cd.detectChanges();
263
225
  }
264
226
  resetRoutingMarkers() {
265
- this.data.routingMarkers?.forEach((marker, index) => {
227
+ this.mapData.routingMarkers?.forEach((marker, index) => {
266
228
  marker.icon = {
267
229
  url: marker.icon.url,
268
230
  labelOrigin: marker.icon.labelOrigin,
@@ -271,12 +233,12 @@ export class CaMapComponent {
271
233
  }
272
234
  onMapReady(mapInstance) {
273
235
  this.map = mapInstance;
274
- if (this.data.stateBoundariesUrl) {
275
- const stateBoundariesUrl = this.data.stateBoundariesUrl.url;
236
+ if (this.mapData.stateBoundariesUrl) {
237
+ const stateBoundariesUrl = this.mapData.stateBoundariesUrl.url;
276
238
  this.maps.googleMap?.data.loadGeoJson(stateBoundariesUrl);
277
239
  this.maps.googleMap?.data.setStyle((feature) => {
278
240
  const stateDensity = feature.getProperty('density');
279
- const { fillColor, fillOpacity } = MapHelper.getFillColorForState(stateDensity, this.data.view || '');
241
+ const { fillColor, fillOpacity } = MapHelper.getFillColorForState(stateDensity, this.mapData.view || '');
280
242
  return {
281
243
  fillColor: fillColor,
282
244
  strokeColor: '#EEEEEE',
@@ -285,22 +247,144 @@ export class CaMapComponent {
285
247
  };
286
248
  });
287
249
  }
250
+ this.sendBoundsChangedEvent();
288
251
  this.setMapStyles();
252
+ this.getMapIdleEvent(mapInstance);
289
253
  }
290
254
  setMapStyles() {
291
- if (this.data?.darkMode)
255
+ if (this.mapData?.darkMode)
292
256
  this.mapOptions = {
293
257
  ...this.mapOptions,
294
258
  styles: MapConstants.GOOGLE_MAP_DARK_STYLES,
295
259
  };
296
260
  const allMarkersCombined = [
297
- ...(this.data.routingMarkers ?? []),
298
- ...(this.data.clusterMarkers ?? []),
299
- ...(this.data.markers ?? []),
261
+ ...(this.mapData.routingMarkers ?? []),
262
+ ...(this.mapData.clusterMarkers ?? []),
263
+ ...(this.mapData.markers ?? []),
300
264
  ];
301
- const mapCenterAndBounds = MapHelper.getMapCenterAndZoom(allMarkersCombined);
302
- this.mapCenter = mapCenterAndBounds.mapCenter;
303
- this.map?.fitBounds(mapCenterAndBounds.bounds);
265
+ if (allMarkersCombined?.length) {
266
+ const mapCenterAndBounds = MapHelper.getMapCenterAndZoom(allMarkersCombined);
267
+ this.map.panTo(mapCenterAndBounds.mapCenter);
268
+ this.map?.fitBounds(mapCenterAndBounds.bounds);
269
+ this.isMapCenterSet = true;
270
+ }
271
+ }
272
+ getMapIdleEvent(map) {
273
+ map.addListener('idle', () => {
274
+ this.sendBoundsChangedEvent();
275
+ });
276
+ }
277
+ sendBoundsChangedEvent() {
278
+ if (this.map) {
279
+ const mapBounds = this.map.getBounds();
280
+ const mapZoom = this.map.getZoom();
281
+ if (mapBounds && mapZoom) {
282
+ const boundsObject = { bounds: mapBounds, zoom: mapZoom };
283
+ this.boundsChanged.emit(boundsObject);
284
+ }
285
+ }
286
+ }
287
+ onClusterBackButtonClick() {
288
+ this.resetSelectedMarkerItem.emit(true);
289
+ }
290
+ getNewData(data) {
291
+ const newMarkers = data?.markers?.map((marker) => {
292
+ const isSelectedMarker = this.checkInfoWindowPosition(marker, this.openedInfoWindowData);
293
+ if (isSelectedMarker) {
294
+ const newMarkerData = {
295
+ ...marker,
296
+ icon: {
297
+ ...marker.icon,
298
+ scaledSize: MapOptionsConstants.largeMarkerSize,
299
+ },
300
+ options: { zIndex: 999 },
301
+ };
302
+ return newMarkerData;
303
+ }
304
+ return marker;
305
+ });
306
+ return {
307
+ ...data,
308
+ markers: newMarkers,
309
+ };
310
+ }
311
+ openMarkerInfoWindow(markerItem) {
312
+ const isInfoWindowOpened = this.checkInfoWindowPosition(markerItem, this.openedInfoWindowData);
313
+ const isClusterItemChanged = this.checkClusterDataChanges(markerItem, this.openedInfoWindowData);
314
+ if (this.infoWindowsView && (!isInfoWindowOpened || isClusterItemChanged)) {
315
+ this.mapData.markers.map((item, index) => {
316
+ const isSelectedMarker = this.checkInfoWindowPosition(item, markerItem);
317
+ if (isSelectedMarker) {
318
+ item.icon = {
319
+ ...item.icon,
320
+ scaledSize: MapOptionsConstants.largeMarkerSize,
321
+ };
322
+ item.options = { zIndex: 999 };
323
+ }
324
+ else {
325
+ item.icon = {
326
+ ...item.icon,
327
+ scaledSize: MapOptionsConstants.defaultMarkerSize,
328
+ };
329
+ item.options = { zIndex: index + 1 };
330
+ }
331
+ });
332
+ this.currentlyOpenWindow = this.infoWindowsView;
333
+ this.openedInfoWindowData = markerItem;
334
+ if (!isInfoWindowOpened) {
335
+ this.map.panTo(markerItem.position);
336
+ setTimeout(() => {
337
+ this.infoWindowOptions = {
338
+ ...this.infoWindowOptions,
339
+ position: markerItem.position,
340
+ };
341
+ this.infoWindowsView.open();
342
+ }, 0);
343
+ }
344
+ }
345
+ }
346
+ checkInfoWindowPosition(markerItem, markerItem2) {
347
+ return (markerItem.position.lat === markerItem2?.position?.lat &&
348
+ markerItem.position.lng === markerItem2?.position?.lng);
349
+ }
350
+ closeInfoWindow() {
351
+ this.resetMarkersIcons();
352
+ this.openedInfoWindowData = null;
353
+ this.currentlyOpenWindow = null;
354
+ this.infoWindowsView.close();
355
+ this.resetSelectedMarkerItem.emit();
356
+ }
357
+ handleMapData(newData) {
358
+ this.mapData = this.getNewData(newData);
359
+ if (this.mapData.selectedMarkerData)
360
+ this.openMarkerInfoWindow(this.mapData.selectedMarkerData);
361
+ else if (this.currentlyOpenWindow)
362
+ this.closeInfoWindow();
363
+ if (newData && !this.isMapCenterSet && this.map) {
364
+ if (newData.markers?.length ||
365
+ newData.clusterMarkers?.length ||
366
+ newData.routingMarkers?.length)
367
+ this.setMapStyles();
368
+ }
369
+ this.cd.detectChanges();
370
+ }
371
+ onClusterListScrollToEnd() {
372
+ if (this.openedInfoWindowData)
373
+ this.clusterListScrollEvent.emit(this.openedInfoWindowData);
374
+ }
375
+ checkClusterDataChanges(newData, previousData) {
376
+ return newData.infoWindowContent?.clusterData
377
+ ? newData.infoWindowContent?.selectedClusterItemData?.data?.id !==
378
+ previousData?.infoWindowContent?.selectedClusterItemData?.data?.id ||
379
+ newData.infoWindowContent?.clusterData?.length !==
380
+ previousData?.infoWindowContent?.clusterData?.length
381
+ : false;
382
+ }
383
+ trackById(index, marker) {
384
+ return marker.data.id;
385
+ }
386
+ trackByPosition(index, marker) {
387
+ return marker.position.lat + marker.position.lng;
304
388
  }
305
389
  identity(index) {
306
390
  return index;
@@ -309,40 +393,39 @@ export class CaMapComponent {
309
393
  this.directionsRenderers.forEach((renderer) => renderer.setMap(null));
310
394
  }
311
395
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CaMapComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
312
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CaMapComponent, isStandalone: true, selector: "app-ca-map", inputs: { data: "data" }, outputs: { markerClick: "markerClick" }, viewQueries: [{ propertyName: "maps", first: true, predicate: GoogleMap, descendants: true }, { propertyName: "marker", predicate: ["marker"], descendants: true }, { propertyName: "infoWindowsView", predicate: MapInfoWindow, descendants: true }, { propertyName: "markerRouting", predicate: ["markerRouting"], descendants: true }, { propertyName: "infoWindowsViewRouting", predicate: MapInfoWindow, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<google-map\n height=\"100%\"\n width=\"100%\"\n [zoom]=\"mapZoom\"\n [center]=\"mapCenter\"\n [options]=\"mapOptions\"\n (mapInitialized)=\"onMapReady($event)\"\n>\n <map-marker\n #marker=\"mapMarker\"\n *ngFor=\"let markeritem of data.markers; let i = index; trackBy: identity\"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"focusedIcon !== i ? markeritem.label! : ''\"\n [title]=\"markeritem.title!\"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onMarkerClick(i, $event, markeritem)\"\n >\n <map-info-window\n #infoWindowsView=\"mapInfoWindow\"\n [options]=\"infoWindowOptions\"\n >\n <app-ca-map-dropdown\n [item]=\"data?.viewData?.[i]\"\n [isAccidentMap]=\"data.isAccidentMap ?? false\"\n ></app-ca-map-dropdown>\n </map-info-window>\n </map-marker>\n <map-marker\n *ngFor=\"let marker of data.clusterMarkers; let i = index; trackBy: identity\"\n [position]=\"marker.position\"\n [icon]=\"marker.icon\"\n [label]=\"marker.label!\"\n [title]=\"marker?.title!\"\n >\n </map-marker>\n\n <map-marker\n #markerRouting=\"mapMarker\"\n *ngFor=\"\n let markeritem of data.routingMarkers;\n let i = index;\n trackBy: identity\n \"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"focusedIconRouting !== i ? markeritem.label! : ''\"\n [title]=\"markeritem.title!\"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onRoutingMarkerClick(i, $event, markeritem)\"\n >\n <map-info-window #infoWindowsViewRouting=\"mapInfoWindow\">\n <app-ca-map-dropdown [isAccidentMap]=\"false\"></app-ca-map-dropdown>\n </map-info-window>\n </map-marker>\n</google-map>\n", styles: [".gm-style-iw-a .gm-style-iw-t .gm-style-iw.gm-style-iw-c{padding:0!important;border-radius:3px!important;top:70px!important;transform:translate(-50%)!important}.gm-style-iw-a .gm-style-iw-t .gm-style-iw-tc{display:none!important}\n"], dependencies: [{ kind: "ngmodule", type:
313
- //Modules
314
- GoogleMapsModule }, { kind: "component", type: i1.GoogleMap, selector: "google-map", inputs: ["height", "width", "mapTypeId", "center", "zoom", "options"], outputs: ["mapInitialized", "authFailure", "boundsChanged", "centerChanged", "mapClick", "mapDblclick", "mapDrag", "mapDragend", "mapDragstart", "headingChanged", "idle", "maptypeidChanged", "mapMousemove", "mapMouseout", "mapMouseover", "projectionChanged", "mapRightclick", "tilesloaded", "tiltChanged", "zoomChanged"], exportAs: ["googleMap"] }, { kind: "directive", type: i1.MapInfoWindow, selector: "map-info-window", inputs: ["options", "position"], outputs: ["closeclick", "contentChanged", "domready", "positionChanged", "zindexChanged"], exportAs: ["mapInfoWindow"] }, { kind: "directive", type: i1.MapMarker, selector: "map-marker", inputs: ["title", "position", "label", "clickable", "options", "icon", "visible"], outputs: ["animationChanged", "mapClick", "clickableChanged", "cursorChanged", "mapDblclick", "mapDrag", "mapDragend", "draggableChanged", "mapDragstart", "flatChanged", "iconChanged", "mapMousedown", "mapMouseout", "mapMouseover", "mapMouseup", "positionChanged", "mapRightclick", "shapeChanged", "titleChanged", "visibleChanged", "zindexChanged"], exportAs: ["mapMarker"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: AngularSvgIconModule }, { kind: "component", type:
315
- //Components
316
- CaMapDropdownComponent, selector: "app-ca-map-dropdown", inputs: ["isAccidentMap", "item"], outputs: ["bodyActions"] }], encapsulation: i0.ViewEncapsulation.None }); }
396
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CaMapComponent, isStandalone: true, selector: "app-ca-map", inputs: { data: "data" }, outputs: { resetSelectedMarkerItem: "resetSelectedMarkerItem", clusterMarkerClick: "clusterMarkerClick", clusterListScrollEvent: "clusterListScrollEvent", getInfoWindowData: "getInfoWindowData", boundsChanged: "boundsChanged" }, viewQueries: [{ propertyName: "maps", first: true, predicate: GoogleMap, descendants: true }, { propertyName: "infoWindowsView", first: true, predicate: MapInfoWindow, descendants: true }], ngImport: i0, template: "<google-map\n height=\"100%\"\n width=\"100%\"\n [zoom]=\"mapZoom\"\n [center]=\"mapCenter\"\n [options]=\"mapOptions\"\n (mapInitialized)=\"onMapReady($event)\"\n>\n <map-marker\n #marker=\"mapMarker\"\n *ngFor=\"let markeritem of mapData.markers; let i = index; trackBy: trackById\"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"\n openedInfoWindowData?.position?.lat === markeritem?.position?.lat &&\n openedInfoWindowData?.position?.lng === markeritem?.position?.lng\n ? ''\n : markeritem.label!\n \"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onMarkerClick(markeritem)\"\n >\n </map-marker>\n\n <map-info-window\n #infoWindowsView=\"mapInfoWindow\"\n [options]=\"infoWindowOptions\"\n >\n <ng-container *ngIf=\"openedInfoWindowData !== null\">\n <app-ca-map-dropdown\n [infoWindowContent]=\"openedInfoWindowData.infoWindowContent\"\n [markerData]=\"openedInfoWindowData.data\"\n (onClusterItemClick)=\"getMarkerInfoWindow($event)\"\n (onClusterListScrollToEnd)=\"onClusterListScrollToEnd()\"\n (onBackButtonClick)=\"onClusterBackButtonClick()\"\n ></app-ca-map-dropdown>\n </ng-container>\n </map-info-window>\n\n <map-marker\n #markerCluster=\"mapMarker\"\n *ngFor=\"\n let marker of mapData.clusterMarkers;\n let i = index;\n trackBy: trackByPosition\n \"\n [position]=\"marker.position\"\n [icon]=\"marker.icon\"\n (mapClick)=\"onClusterMarkerClick(marker)\"\n >\n </map-marker>\n\n <ng-container *ngIf=\"isAreaFilterActive\">\n <map-circle\n [options]=\"areaFilterData.options\"\n [center]=\"areaFilterData.center\"\n [radius]=\"areaFilterData.radius\"\n ></map-circle>\n </ng-container>\n\n <map-marker\n #markerRouting=\"mapMarker\"\n *ngFor=\"\n let markeritem of mapData.routingMarkers;\n let i = index;\n trackBy: identity\n \"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"focusedIconRouting !== i ? markeritem.label! : ''\"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onRoutingMarkerClick(i, $event, markeritem)\"\n >\n <map-info-window #infoWindowsViewRouting=\"mapInfoWindow\">\n <app-ca-map-dropdown></app-ca-map-dropdown>\n </map-info-window>\n </map-marker>\n</google-map>\n", styles: ["@keyframes dropdown{0%{margin-top:20px;visibility:hidden;opacity:0}to{opacity:1;margin-top:10px;visibility:visible!important}}@keyframes dropup{0%{margin-top:-19px;visibility:hidden;opacity:0}to{margin-top:inherit;visibility:visible!important}}.gm-style-iw-a .gm-style-iw-t .gm-style-iw.gm-style-iw-c{padding:0!important;border-radius:3px!important;top:70px!important;transform:translate(-50%)!important}.gm-style-iw-a .gm-style-iw-t .gm-style-iw-tc{display:none!important}.gm-style div[aria-hidden=true]{width:90px;text-shadow:1px 1px 0px #ffffff,1px -1px 0px #ffffff,-1px -1px 0px #ffffff,-1px 1px 0px #ffffff;text-transform:uppercase;font-size:11px;line-height:12px;text-align:left;font-weight:500;font-family:Montserrat,sans-serif;color:#424242;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-webkit-user-select:none;user-select:none}@supports (-webkit-line-clamp: 2){.gm-style div[aria-hidden=true]{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}\n"], dependencies: [{ kind: "ngmodule", type:
397
+ // Modules
398
+ GoogleMapsModule }, { kind: "component", type: i1.GoogleMap, selector: "google-map", inputs: ["height", "width", "mapTypeId", "center", "zoom", "options"], outputs: ["mapInitialized", "authFailure", "boundsChanged", "centerChanged", "mapClick", "mapDblclick", "mapDrag", "mapDragend", "mapDragstart", "headingChanged", "idle", "maptypeidChanged", "mapMousemove", "mapMouseout", "mapMouseover", "projectionChanged", "mapRightclick", "tilesloaded", "tiltChanged", "zoomChanged"], exportAs: ["googleMap"] }, { kind: "directive", type: i1.MapCircle, selector: "map-circle", inputs: ["options", "center", "radius"], outputs: ["centerChanged", "circleClick", "circleDblclick", "circleDrag", "circleDragend", "circleDragstart", "circleMousedown", "circleMousemove", "circleMouseout", "circleMouseover", "circleMouseup", "radiusChanged", "circleRightclick"], exportAs: ["mapCircle"] }, { kind: "directive", type: i1.MapInfoWindow, selector: "map-info-window", inputs: ["options", "position"], outputs: ["closeclick", "contentChanged", "domready", "positionChanged", "zindexChanged"], exportAs: ["mapInfoWindow"] }, { kind: "directive", type: i1.MapMarker, selector: "map-marker", inputs: ["title", "position", "label", "clickable", "options", "icon", "visible"], outputs: ["animationChanged", "mapClick", "clickableChanged", "cursorChanged", "mapDblclick", "mapDrag", "mapDragend", "draggableChanged", "mapDragstart", "flatChanged", "iconChanged", "mapMousedown", "mapMouseout", "mapMouseover", "mapMouseup", "positionChanged", "mapRightclick", "shapeChanged", "titleChanged", "visibleChanged", "zindexChanged"], exportAs: ["mapMarker"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: AngularSvgIconModule }, { kind: "component", type:
399
+ // Components
400
+ CaMapDropdownComponent, selector: "app-ca-map-dropdown", inputs: ["infoWindowContent", "markerData"], outputs: ["onClusterItemClick", "onClusterListScrollToEnd", "onBackButtonClick", "bodyActions"] }], encapsulation: i0.ViewEncapsulation.None }); }
317
401
  }
318
402
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CaMapComponent, decorators: [{
319
403
  type: Component,
320
404
  args: [{ selector: 'app-ca-map', standalone: true, imports: [
321
- //Modules
405
+ // Modules
322
406
  GoogleMapsModule,
323
407
  CommonModule,
324
408
  AngularSvgIconModule,
325
- //Components
409
+ // Components
326
410
  CaMapDropdownComponent,
327
- ], encapsulation: ViewEncapsulation.None, template: "<google-map\n height=\"100%\"\n width=\"100%\"\n [zoom]=\"mapZoom\"\n [center]=\"mapCenter\"\n [options]=\"mapOptions\"\n (mapInitialized)=\"onMapReady($event)\"\n>\n <map-marker\n #marker=\"mapMarker\"\n *ngFor=\"let markeritem of data.markers; let i = index; trackBy: identity\"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"focusedIcon !== i ? markeritem.label! : ''\"\n [title]=\"markeritem.title!\"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onMarkerClick(i, $event, markeritem)\"\n >\n <map-info-window\n #infoWindowsView=\"mapInfoWindow\"\n [options]=\"infoWindowOptions\"\n >\n <app-ca-map-dropdown\n [item]=\"data?.viewData?.[i]\"\n [isAccidentMap]=\"data.isAccidentMap ?? false\"\n ></app-ca-map-dropdown>\n </map-info-window>\n </map-marker>\n <map-marker\n *ngFor=\"let marker of data.clusterMarkers; let i = index; trackBy: identity\"\n [position]=\"marker.position\"\n [icon]=\"marker.icon\"\n [label]=\"marker.label!\"\n [title]=\"marker?.title!\"\n >\n </map-marker>\n\n <map-marker\n #markerRouting=\"mapMarker\"\n *ngFor=\"\n let markeritem of data.routingMarkers;\n let i = index;\n trackBy: identity\n \"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"focusedIconRouting !== i ? markeritem.label! : ''\"\n [title]=\"markeritem.title!\"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onRoutingMarkerClick(i, $event, markeritem)\"\n >\n <map-info-window #infoWindowsViewRouting=\"mapInfoWindow\">\n <app-ca-map-dropdown [isAccidentMap]=\"false\"></app-ca-map-dropdown>\n </map-info-window>\n </map-marker>\n</google-map>\n", styles: [".gm-style-iw-a .gm-style-iw-t .gm-style-iw.gm-style-iw-c{padding:0!important;border-radius:3px!important;top:70px!important;transform:translate(-50%)!important}.gm-style-iw-a .gm-style-iw-t .gm-style-iw-tc{display:none!important}\n"] }]
411
+ ], encapsulation: ViewEncapsulation.None, template: "<google-map\n height=\"100%\"\n width=\"100%\"\n [zoom]=\"mapZoom\"\n [center]=\"mapCenter\"\n [options]=\"mapOptions\"\n (mapInitialized)=\"onMapReady($event)\"\n>\n <map-marker\n #marker=\"mapMarker\"\n *ngFor=\"let markeritem of mapData.markers; let i = index; trackBy: trackById\"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"\n openedInfoWindowData?.position?.lat === markeritem?.position?.lat &&\n openedInfoWindowData?.position?.lng === markeritem?.position?.lng\n ? ''\n : markeritem.label!\n \"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onMarkerClick(markeritem)\"\n >\n </map-marker>\n\n <map-info-window\n #infoWindowsView=\"mapInfoWindow\"\n [options]=\"infoWindowOptions\"\n >\n <ng-container *ngIf=\"openedInfoWindowData !== null\">\n <app-ca-map-dropdown\n [infoWindowContent]=\"openedInfoWindowData.infoWindowContent\"\n [markerData]=\"openedInfoWindowData.data\"\n (onClusterItemClick)=\"getMarkerInfoWindow($event)\"\n (onClusterListScrollToEnd)=\"onClusterListScrollToEnd()\"\n (onBackButtonClick)=\"onClusterBackButtonClick()\"\n ></app-ca-map-dropdown>\n </ng-container>\n </map-info-window>\n\n <map-marker\n #markerCluster=\"mapMarker\"\n *ngFor=\"\n let marker of mapData.clusterMarkers;\n let i = index;\n trackBy: trackByPosition\n \"\n [position]=\"marker.position\"\n [icon]=\"marker.icon\"\n (mapClick)=\"onClusterMarkerClick(marker)\"\n >\n </map-marker>\n\n <ng-container *ngIf=\"isAreaFilterActive\">\n <map-circle\n [options]=\"areaFilterData.options\"\n [center]=\"areaFilterData.center\"\n [radius]=\"areaFilterData.radius\"\n ></map-circle>\n </ng-container>\n\n <map-marker\n #markerRouting=\"mapMarker\"\n *ngFor=\"\n let markeritem of mapData.routingMarkers;\n let i = index;\n trackBy: identity\n \"\n [position]=\"markeritem.position\"\n [icon]=\"markeritem.icon!\"\n [label]=\"focusedIconRouting !== i ? markeritem.label! : ''\"\n [options]=\"markeritem.options!\"\n (mapClick)=\"onRoutingMarkerClick(i, $event, markeritem)\"\n >\n <map-info-window #infoWindowsViewRouting=\"mapInfoWindow\">\n <app-ca-map-dropdown></app-ca-map-dropdown>\n </map-info-window>\n </map-marker>\n</google-map>\n", styles: ["@keyframes dropdown{0%{margin-top:20px;visibility:hidden;opacity:0}to{opacity:1;margin-top:10px;visibility:visible!important}}@keyframes dropup{0%{margin-top:-19px;visibility:hidden;opacity:0}to{margin-top:inherit;visibility:visible!important}}.gm-style-iw-a .gm-style-iw-t .gm-style-iw.gm-style-iw-c{padding:0!important;border-radius:3px!important;top:70px!important;transform:translate(-50%)!important}.gm-style-iw-a .gm-style-iw-t .gm-style-iw-tc{display:none!important}.gm-style div[aria-hidden=true]{width:90px;text-shadow:1px 1px 0px #ffffff,1px -1px 0px #ffffff,-1px -1px 0px #ffffff,-1px 1px 0px #ffffff;text-transform:uppercase;font-size:11px;line-height:12px;text-align:left;font-weight:500;font-family:Montserrat,sans-serif;color:#424242;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-webkit-user-select:none;user-select:none}@supports (-webkit-line-clamp: 2){.gm-style div[aria-hidden=true]{overflow:hidden;text-overflow:ellipsis;white-space:initial;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}}\n"] }]
328
412
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { data: [{
329
413
  type: Input
330
- }], markerClick: [{
414
+ }], resetSelectedMarkerItem: [{
415
+ type: Output
416
+ }], clusterMarkerClick: [{
417
+ type: Output
418
+ }], clusterListScrollEvent: [{
419
+ type: Output
420
+ }], getInfoWindowData: [{
421
+ type: Output
422
+ }], boundsChanged: [{
331
423
  type: Output
332
424
  }], maps: [{
333
425
  type: ViewChild,
334
426
  args: [GoogleMap, { static: false }]
335
- }], marker: [{
336
- type: ViewChildren,
337
- args: ['marker']
338
427
  }], infoWindowsView: [{
339
- type: ViewChildren,
340
- args: [MapInfoWindow]
341
- }], markerRouting: [{
342
- type: ViewChildren,
343
- args: ['markerRouting']
344
- }], infoWindowsViewRouting: [{
345
- type: ViewChildren,
428
+ type: ViewChild,
346
429
  args: [MapInfoWindow]
347
430
  }] } });
348
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2EtbWFwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NhLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL2NhLW1hcC9jYS1tYXAuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2EtY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvY2EtbWFwL2NhLW1hcC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFHTixTQUFTLEVBQ1QsWUFBWSxFQUNaLGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixTQUFTO0FBQ1QsT0FBTyxFQUNMLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsYUFBYSxHQUVkLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsTUFBTTtBQUNOLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXhELFlBQVk7QUFDWixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUV0RixPQUFPO0FBQ1AsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBU2hFLGVBQWU7QUFDZixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDL0QsWUFBWTtBQUNaLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUU3RSxZQUFZO0FBQ1osT0FBTyxFQUNMLDZCQUE2QixFQUM3QixtQkFBbUIsR0FDcEIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sOEJBQThCLENBQUM7Ozs7QUFpQjVELE1BQU0sT0FBTyxjQUFj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QUFTO3dCQUNULGdCQUFnQjt3QkFDaEIsWUFBWTt3QkFDWixvQkFBb0I7d0JBQ3BCLFlBQVk7d0JBQ1osc0JBQXNCO3FCQUN2QixpQkFDYyxpQkFBaUIsQ0FBQyxJQUFJO3dHQUk1QixJQUFJO3NCQUFaLEtBQUs7Z0JBQ0ksV0FBVztzQkFBcEIsTUFBTTtnQkFDa0MsSUFBSTtzQkFBNUMsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUNmLE1BQU07c0JBQTdCLFlBQVk7dUJBQUMsUUFBUTtnQkFDTyxlQUFlO3NCQUEzQyxZQUFZO3VCQUFDLGFBQWE7Z0JBQ0ksYUFBYTtzQkFBM0MsWUFBWTt1QkFBQyxlQUFlO2dCQUV0QixzQkFBc0I7c0JBRDVCLFlBQVk7dUJBQUMsYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3Q2hpbGRyZW4sXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLy9Nb2R1bGVzXG5pbXBvcnQge1xuICBHb29nbGVNYXAsXG4gIEdvb2dsZU1hcHNNb2R1bGUsXG4gIE1hcEluZm9XaW5kb3csXG4gIE1hcE1hcmtlcixcbn0gZnJvbSAnQGFuZ3VsYXIvZ29vZ2xlLW1hcHMnO1xuXG4vL2ljb25cbmltcG9ydCB7IEFuZ3VsYXJTdmdJY29uTW9kdWxlIH0gZnJvbSAnYW5ndWxhci1zdmctaWNvbic7XG5cbi8vQ29tcG9uZW50c1xuaW1wb3J0IHsgQ2FNYXBEcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4uL2NhLW1hcC1kcm9wZG93bi9jYS1tYXAtZHJvcGRvd24uY29tcG9uZW50JztcblxuLy9FbnVtc1xuaW1wb3J0IHsgR29vZ2xlTWFwRW51bSB9IGZyb20gJy4uL2NhLW1hcC9lbnVtcy9nb29nbGUtbWFwLmVudW0nO1xuLy9tb2RlbHNcbmltcG9ydCB7XG4gIElNYXBNYXJrZXJzLFxuICBJTWFwUm91dGVQYXRoLFxuICBJQ2FNYXBQcm9wcyxcbiAgSU1hcE9wdGlvbnMsXG4gIElSb3V0ZVBhdGgsXG59IGZyb20gJy4uL2NhLW1hcC9tb2RlbHMvbWFwLm1vZGVsJztcbi8vSGVscGVyRnVudGlvblxuaW1wb3J0IHsgTWFwSGVscGVyIH0gZnJvbSAnLi4vY2EtbWFwL3V0aWxzL2hlbHBlcnMvbWFwLmhlbHBlcic7XG4vL3N2Zy1yb3V0ZXNcbmltcG9ydCB7IE1hcFN2Z1JvdXRlcyB9IGZyb20gJy4uL2NhLW1hcC91dGlscy9tYXAtc3ZnLXJvdXRlcy9tYXAtc3ZnLXJvdXRlcyc7XG5cbi8vIENvbnN0YW50c1xuaW1wb3J0IHtcbiAgTWFwSW5mb1dpbmRvd09wdGlvbnNDb25zdGFudHMsXG4gIE1hcE9wdGlvbnNDb25zdGFudHMsXG59IGZyb20gJy4vdXRpbHMvY29uc3RhbnRzJztcbmltcG9ydCB7IE1hcENvbnN0YW50cyB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9tYXAuY29uc3RhbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtY2EtbWFwJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhLW1hcC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NhLW1hcC5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgLy9Nb2R1bGVzXG4gICAgR29vZ2xlTWFwc01vZHVsZSxcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgQW5ndWxhclN2Z0ljb25Nb2R1bGUsXG4gICAgLy9Db21wb25lbnRzXG4gICAgQ2FNYXBEcm9wZG93bkNvbXBvbmVudCxcbiAgXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgQ2FNYXBDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgY2Q6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuICBASW5wdXQoKSBkYXRhITogSUNhTWFwUHJvcHMgfCBhbnk7XG4gIEBPdXRwdXQoKSBtYXJrZXJDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8Z29vZ2xlLm1hcHMuTWFwTW91c2VFdmVudD4oKTtcbiAgQFZpZXdDaGlsZChHb29nbGVNYXAsIHsgc3RhdGljOiBmYWxzZSB9KSBtYXBzITogR29vZ2xlTWFwO1xuICBAVmlld0NoaWxkcmVuKCdtYXJrZXInKSBtYXJrZXIhOiBRdWVyeUxpc3Q8TWFwTWFya2VyPjtcbiAgQFZpZXdDaGlsZHJlbihNYXBJbmZvV2luZG93KSBpbmZvV2luZG93c1ZpZXchOiBRdWVyeUxpc3Q8TWFwSW5mb1dpbmRvdz47XG4gIEBWaWV3Q2hpbGRyZW4oJ21hcmtlclJvdXRpbmcnKSBtYXJrZXJSb3V0aW5nITogUXVlcnlMaXN0PE1hcE1hcmtlcj47XG4gIEBWaWV3Q2hpbGRyZW4oTWFwSW5mb1dpbmRvdylcbiAgcHVibGljIGluZm9XaW5kb3dzVmlld1JvdXRpbmchOiBRdWVyeUxpc3Q8TWFwSW5mb1dpbmRvdz47XG4gIHB1YmxpYyBjdXJyZW50bHlPcGVuV2luZG93ITogTWFwSW5mb1dpbmRvdyB8IG51bGw7XG4gIHB1YmxpYyBjdXJyZW50bHlPcGVuV2luZG93SW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgY3VycmVudGx5T3BlbldpbmRvd1JvdXRpbmchOiBNYXBJbmZvV2luZG93IHwgbnVsbDtcbiAgcHVibGljIGN1cnJlbnRseU9wZW5XaW5kb3dJbmRleFJvdXRpbmc6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgc2hvd0xhYmVsOiBib29sZWFuID0gdHJ1ZTtcbiAgcHVibGljIHByZXZpb3VzSWNvblVybCE6IHN0cmluZztcbiAgcHVibGljIGZvY3VzZWRJY29uOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIHByZXZpb3VzSWNvblVybFJvdXRpbmchOiBzdHJpbmc7XG4gIHB1YmxpYyBmb2N1c2VkSWNvblJvdXRpbmchOiBudW1iZXI7XG4gIHByaXZhdGUgZGlyZWN0aW9uU2VydmljZSA9IG5ldyBnb29nbGUubWFwcy5EaXJlY3Rpb25zU2VydmljZSgpO1xuICBwdWJsaWMgZGlyZWN0aW9uc1JlbmRlcmVyczogZ29vZ2xlLm1hcHMuRGlyZWN0aW9uc1JlbmRlcmVyW10gPSBbXTtcbiAgcHVibGljIGluaXRpYWxJY29uczoge1xuICAgIHVybDogc3RyaW5nO1xuICAgIGxhYmVsT3JpZ2luPzogZ29vZ2xlLm1hcHMuUG9pbnQ7XG4gIH1bXSA9IFtdO1xuICBwdWJsaWMgaW5pdGlhbE1hcmtlckljb25zOiB7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgbGFiZWxPcmlnaW4/OiBnb29nbGUubWFwcy5Qb2ludDtcbiAgfVtdID0gW107XG4gIHB1YmxpYyBpbmZvV2luZG93T3B0aW9uczogZ29vZ2xlLm1hcHMuSW5mb1dpbmRvd09wdGlvbnMgPVxuICAgIE1hcEluZm9XaW5kb3dPcHRpb25zQ29uc3RhbnRzLm1hcEluZm9XaW5kb3dPcHRpb25zO1xuICBwdWJsaWMgbWFwT3B0aW9uczogSU1hcE9wdGlvbnMgPSBNYXBPcHRpb25zQ29uc3RhbnRzLmRlZmF1bHRNYXBPcHRpb25zO1xuICBwdWJsaWMgbWFwWm9vbTogbnVtYmVyID0gTWFwT3B0aW9uc0NvbnN0YW50cy5kZWZhdWx0TWFwWm9vbTtcbiAgcHVibGljIG1hcENlbnRlcjogSVJvdXRlUGF0aCA9IE1hcE9wdGlvbnNDb25zdGFudHMuZGVmYXVsdE1hcENlbnRlcjtcbiAgcHVibGljIG1hcDogZ29vZ2xlLm1hcHMuTWFwIHwgbnVsbCA9IG51bGw7XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5zdG9yZUluaXRpYWxJY29uRm9yTWFya2VyKCk7XG4gICAgdGhpcy5zdG9yZUluaXRpYWxJY29uRm9yUm91dGluZ01hcmtlcigpO1xuICAgIC8vIFJlc2V0IGFsbCBpY29ucyB0byB0aGVpciBpbml0aWFsIHN0YXRlIG9uIHBhZ2UgbG9hZFxuICAgIHRoaXMucmVzZXRNYXJrZXJzSWNvbnMoKTtcbiAgICB0aGlzLnJlc2V0Um91dGluZ01hcmtlcnMoKTtcbiAgICAvL0Rpc3BsYXkgcm91dGVzIGZvciByb3V0aW5nTWFya2Vyc1xuICAgIHRoaXMuY2FsY3VsYXRlQW5kRGlzcGxheVJvdXRlKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKGNoYW5nZXNbJ3JvdXRpbmdNYXJrZXJzJ10pIHtcbiAgICAgIHRoaXMuZGF0YS5yb3V0aW5nTWFya2VycyA9IGNoYW5nZXNbJ3JvdXRpbmdNYXJrZXJzJ10uY3VycmVudFZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdG9yZUluaXRpYWxJY29uRm9yTWFya2VyKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0YSEubWFya2Vycz8uZm9yRWFjaCgobWFya2VyOiBJTWFwTWFya2VycywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgdGhpcy5pbml0aWFsTWFya2VySWNvbnNbaW5kZXhdID0ge1xuICAgICAgICB1cmw6IG1hcmtlci5pY29uIS51cmwsXG4gICAgICAgIGxhYmVsT3JpZ2luOiBtYXJrZXIuaWNvbiEubGFiZWxPcmlnaW4sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHN0b3JlSW5pdGlhbEljb25Gb3JSb3V0aW5nTWFya2VyKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0YS5yb3V0aW5nTWFya2Vycz8uZm9yRWFjaCgobWFya2VyOiBJTWFwTWFya2VycywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgdGhpcy5pbml0aWFsSWNvbnNbaW5kZXhdID0ge1xuICAgICAgICB1cmw6IG1hcmtlci5pY29uIS51cmwsXG4gICAgICAgIGxhYmVsT3JpZ2luOiBtYXJrZXIuaWNvbiEubGFiZWxPcmlnaW4sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uTWFya2VyQ2xpY2soXG4gICAgaTogbnVtYmVyLFxuICAgIGV2ZW50OiBnb29nbGUubWFwcy5NYXBNb3VzZUV2ZW50LFxuICAgIG1hcmtlcml0ZW06IElNYXBNYXJrZXJzXG4gICk6IHZvaWQge1xuICAgIGlmIChtYXJrZXJpdGVtPy5pbmZvV2luZG93Q29udGVudCkge1xuICAgICAgaWYgKHRoaXMuY3VycmVudGx5T3BlbldpbmRvd0luZGV4ID09PSBpICYmIHRoaXMuY3VycmVudGx5T3BlbldpbmRvdykge1xuICAgICAgICBjb25zdCBpbmZvV2luZG93ID0gdGhpcy5pbmZvV2luZG93c1ZpZXcudG9BcnJheSgpW2ldO1xuICAgICAgICAvLyBDbG9zZSB0aGUgY3VycmVudGx5IG9wZW4gaW5mbyB3aW5kb3cgYW5kIHJlc2V0IHRoZSBpbmRleFxuICAgICAgICB0aGlzLmRhdGEubWFya2VycyEubWFwKChpdGVtOiBJTWFwTWFya2VycywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGlmIChpbmRleCA9PT0gaSkge1xuICAgICAgICAgICAgaXRlbS5pY29uID0ge1xuICAgICAgICAgICAgICB1cmw6IHRoaXMuaW5pdGlhbE1hcmtlckljb25zW2luZGV4XSEudXJsLFxuICAgICAgICAgICAgICBsYWJlbE9yaWdpbjogdGhpcy5pbml0aWFsTWFya2VySWNvbnNbaW5kZXhdIS5sYWJlbE9yaWdpbiEsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaW5mb1dpbmRvdy5jbG9zZSgpO1xuICAgICAgICB0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3dJbmRleCA9IG51bGw7XG4gICAgICAgIHRoaXMuZm9jdXNlZEljb24gPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWFya2VySW5kZXggPSB0aGlzLm1hcmtlci50b0FycmF5KClbaV07XG4gICAgICAgIGNvbnN0IGluZm9XaW5kb3cgPSB0aGlzLmluZm9XaW5kb3dzVmlldy50b0FycmF5KClbaV07XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3cpIHtcbiAgICAgICAgICB0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3cuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5mb1dpbmRvdykge1xuICAgICAgICAgIHRoaXMuZGF0YS5tYXJrZXJzIS5tYXAoKGl0ZW06IElNYXBNYXJrZXJzLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IGkpIHtcbiAgICAgICAgICAgICAgdGhpcy5mb2N1c2VkSWNvbiA9IGk7XG4gICAgICAgICAgICAgIHRoaXMuc2hvd0xhYmVsID0gZmFsc2U7XG4gICAgICAgICAgICAgIGl0ZW0uaWNvbiA9IHtcbiAgICAgICAgICAgICAgICB1cmw6IHRoaXMuaW5pdGlhbE1hcmtlckljb25zW2luZGV4XSEudXJsLFxuICAgICAgICAgICAgICAgIHNjYWxlZFNpemU6IG5ldyBnb29nbGUubWFwcy5TaXplKDU1LCA1NSksXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLnNob3dMYWJlbCA9IHRydWU7XG4gICAgICAgICAgICAgIGl0ZW0uaWNvbiA9IHtcbiAgICAgICAgICAgICAgICB1cmw6IHRoaXMuaW5pdGlhbE1hcmtlckljb25zW2luZGV4XSEudXJsLFxuICAgICAgICAgICAgICAgIGxhYmVsT3JpZ2luOiB0aGlzLmluaXRpYWxNYXJrZXJJY29uc1tpbmRleF0hLmxhYmVsT3JpZ2luLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaW5mb1dpbmRvdy5vcGVuKG1hcmtlckluZGV4KTtcbiAgICAgICAgICB0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3cgPSBpbmZvV2luZG93O1xuICAgICAgICAgIHRoaXMuY3VycmVudGx5T3BlbldpbmRvd0luZGV4ID0gaTtcbiAgICAgICAgICB0aGlzLm1hcmtlckNsaWNrLmVtaXQoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0RGlyZWN0aW9uc09uTWFwKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1hcHM/Lmdvb2dsZU1hcCkge1xuICAgICAgdGhpcy5kaXJlY3Rpb25zUmVuZGVyZXJzLmZvckVhY2goKHJlbmRlcmVyKSA9PlxuICAgICAgICByZW5kZXJlci5zZXRNYXAodGhpcy5tYXBzPy5nb29nbGVNYXAhKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY2FsY3VsYXRlQW5kRGlzcGxheVJvdXRlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRhdGEucm91dGVQYXRocykge1xuICAgICAgLy8gQ2xlYXIgcHJldmlvdXMgZGlyZWN0aW9ucyByZW5kZXJlcnNcbiAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVycy5mb3JFYWNoKChyZW5kZXJlcikgPT4gcmVuZGVyZXIuc2V0TWFwKG51bGwpKTtcbiAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVycyA9IFtdO1xuXG4gICAgICB0aGlzLmRhdGEucm91dGVQYXRocyEuZm9yRWFjaCgocm91dGU6IElNYXBSb3V0ZVBhdGgpID0+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdDogZ29vZ2xlLm1hcHMuRGlyZWN0aW9uc1JlcXVlc3QgPSB7XG4gICAgICAgICAgb3JpZ2luOiByb3V0ZS5wYXRoWzBdLFxuICAgICAgICAgIGRlc3RpbmF0aW9uOiByb3V0ZS5wYXRoW3JvdXRlLnBhdGgubGVuZ3RoIC0gMV0sXG4gICAgICAgICAgd2F5cG9pbnRzOiByb3V0ZS5wYXRoXG4gICAgICAgICAgICAuc2xpY2UoMSwgcm91dGUucGF0aC5sZW5ndGggLSAxKVxuICAgICAgICAgICAgLm1hcCgocG9zaXRpb24pID0+ICh7IGxvY2F0aW9uOiBwb3NpdGlvbiB9KSksXG4gICAgICAgICAgdHJhdmVsTW9kZTogZ29vZ2xlLm1hcHMuVHJhdmVsTW9kZS5CSUNZQ0xJTkcsXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5kaXJlY3Rpb25TZXJ2aWNlLnJvdXRlKHJlcXVlc3QsIChyZXN1bHQsIHN0YXR1cykgPT4ge1xuICAgICAgICAgIGlmIChzdGF0dXMgPT09IGdvb2dsZS5tYXBzLkRpcmVjdGlvbnNTdGF0dXMuT0sgJiYgcmVzdWx0Py5yb3V0ZXNbMF0pIHtcbiAgICAgICAgICAgIGNvbnN0IGRpcmVjdGlvbnNSZW5kZXJlciA9IG5ldyBnb29nbGUubWFwcy5EaXJlY3Rpb25zUmVuZGVyZXIoe1xuICAgICAgICAgICAgICBzdXBwcmVzc0luZm9XaW5kb3dzOiB0cnVlLFxuICAgICAgICAgICAgICBzdXBwcmVzc01hcmtlcnM6IHRydWUsXG4gICAgICAgICAgICAgIHByZXNlcnZlVmlld3BvcnQ6IHRydWUsXG4gICAgICAgICAgICAgIHBvbHlsaW5lT3B0aW9uczoge1xuICAgICAgICAgICAgICAgIHN0cm9rZUNvbG9yOiByb3V0ZS5zdHJva2VDb2xvciB8fCBHb29nbGVNYXBFbnVtLlNUUk9LRV9DT0xPUixcbiAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OlxuICAgICAgICAgICAgICAgICAgcm91dGUuc3Ryb2tlT3BhY2l0eSB8fCBHb29nbGVNYXBFbnVtLlNUUk9LRV9PUEFDSVRZLFxuICAgICAgICAgICAgICAgIHN0cm9rZVdlaWdodDogcm91dGUuc3Ryb2tlV2VpZ2h0IHx8IEdvb2dsZU1hcEVudW0uU1RST0tFX1dFSUdIVCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGlyZWN0aW9uc1JlbmRlcmVyLnNldERpcmVjdGlvbnMocmVzdWx0KTtcbiAgICAgICAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVycy5wdXNoKGRpcmVjdGlvbnNSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLnNldERpcmVjdGlvbnNPbk1hcCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvblJvdXRpbmdNYXJrZXJDbGljayhcbiAgICBpOiBudW1iZXIsXG4gICAgZXZlbnQ6IGdvb2dsZS5tYXBzLk1hcE1vdXNlRXZlbnQsXG4gICAgbWFya2VyaXRlbTogSU1hcE1hcmtlcnNcbiAgKTogdm9pZCB7XG4gICAgaWYgKG1hcmtlcml0ZW0/LmluZm9XaW5kb3dDb250ZW50KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuY3VycmVudGx5T3BlbldpbmRvd0luZGV4Um91dGluZyA9PT0gaSAmJlxuICAgICAgICB0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3dSb3V0aW5nXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgaW5mb1dpbmRvdyA9IHRoaXMuaW5mb1dpbmRvd3NWaWV3Um91dGluZy50b0FycmF5KClbaV07XG4gICAgICAgIC8vIENsb3NlIHRoZSBjdXJyZW50bHkgb3BlbiBpbmZvIHdpbmRvdyBhbmQgcmVzZXQgdGhlIGluZGV4XG4gICAgICAgIHRoaXMuZGF0YS5yb3V0aW5nTWFya2VycyEubWFwKChpdGVtOiBJTWFwTWFya2VycywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGlmIChpbmRleCA9PT0gaSkge1xuICAgICAgICAgICAgaXRlbS5pY29uID0ge1xuICAgICAgICAgICAgICB1cmw6IHRoaXMuaW5pdGlhbEljb25zW2luZGV4XSEudXJsLFxuICAgICAgICAgICAgICBsYWJlbE9yaWdpbjogdGhpcy5pbml0aWFsSWNvbnNbaW5kZXhdIS5sYWJlbE9yaWdpbixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpbmZvV2luZG93LmNsb3NlKCk7XG4gICAgICAgIHRoaXMuY3VycmVudGx5T3BlbldpbmRvd0luZGV4Um91dGluZyA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBtYXJrZXJJbmRleCA9IHRoaXMubWFya2VyUm91dGluZy50b0FycmF5KClbaV07XG4gICAgICAgIGNvbnN0IGluZm9XaW5kb3cgPSB0aGlzLmluZm9XaW5kb3dzVmlld1JvdXRpbmcudG9BcnJheSgpW2ldO1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50bHlPcGVuV2luZG93Um91dGluZykge1xuICAgICAgICAgIHRoaXMuY3VycmVudGx5T3BlbldpbmRvd1JvdXRpbmcuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5mb1dpbmRvdykge1xuICAgICAgICAgIC8vIFJlc3RvcmUgdGhlIHByZXZpb3VzIGljb24gZm9yIHRoZSBwcmV2aW91c2x5IGZvY3VzZWQgcm91dGluZyBtYXJrZXJcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLmZvY3VzZWRJY29uUm91dGluZyAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICB0aGlzLmZvY3VzZWRJY29uUm91dGluZyAhPT0gaVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNGb2N1c2VkSXRlbSA9XG4gICAgICAgICAgICAgIHRoaXMuZGF0YS5yb3V0aW5nTWFya2VycyFbdGhpcy5mb2N1c2VkSWNvblJvdXRpbmddO1xuICAgICAgICAgICAgaWYgKHByZXZpb3VzRm9jdXNlZEl0ZW0pIHtcbiAgICAgICAgICAgICAgcHJldmlvdXNGb2N1c2VkSXRlbS5pY29uID0ge1xuICAgICAgICAgICAgICAgIHVybDogdGhpcy5pbml0aWFsSWNvbnNbdGhpcy5mb2N1c2VkSWNvblJvdXRpbmddLnVybCxcbiAgICAgICAgICAgICAgICBsYWJlbE9yaWdpbjpcbiAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbEljb25zW3RoaXMuZm9jdXNlZEljb25Sb3V0aW5nXS5sYWJlbE9yaWdpbixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBVcGRhdGUgdGhlIGN1cnJlbnQgbWFya2VyXG4gICAgICAgICAgdGhpcy5kYXRhLnJvdXRpbmdNYXJrZXJzIS5tYXAoKGl0ZW06IElNYXBNYXJrZXJzLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IGkpIHtcbiAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ljb25VcmxSb3V0aW5nID0gaXRlbS5pY29uID8gaXRlbS5pY29uLnVybCA6ICcnO1xuICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRJY29uUm91dGluZyA9IGk7XG4gICAgICAgICAgICAgIHRoaXMuc2hvd0xhYmVsID0gZmFsc2U7XG4gICAgICAgICAgICAgIGl0ZW0uaWNvbiA9IHtcbiAgICAgICAgICAgICAgICB1cmw6XG4gICAgICAgICAgICAgICAgICB0aGlzLmRhdGEuaXNVbml0Vmlld1N0b3BzIHx8IHRoaXMuZGF0YS5pc0RyaXZlck1pbGVzXG4gICAgICAgICAgICAgICAgICAgID8gaXRlbS5pY29uIS51cmxcbiAgICAgICAgICAgICAgICAgICAgOiBNYXBTdmdSb3V0ZXMubWFya2VyU3ZnUm91dGUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLnNob3dMYWJlbCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpbmZvV2luZG93Lm9wZW4obWFya2VySW5kZXgpO1xuICAgICAgICAgIHRoaXMuY3VycmVudGx5T3BlbldpbmRvd1JvdXRpbmcgPSBpbmZvV2luZG93O1xuICAgICAgICAgIHRoaXMuY3VycmVudGx5T3BlbldpbmRvd0luZGV4Um91dGluZyA9IGk7XG4gICAgICAgICAgdGhpcy5tYXJrZXJDbGljay5lbWl0KGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMubWFwcy5nb29nbGVNYXA/LmFkZExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgIHRoaXMuaW5mb1dpbmRvd3NWaWV3LmZvckVhY2goKHdpbmRvdzogTWFwSW5mb1dpbmRvdykgPT4ge1xuICAgICAgICB3aW5kb3cuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5jdXJyZW50bHlPcGVuV2luZG93ID0gbnVsbDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5pbmZvV2luZG93c1ZpZXdSb3V0aW5nLmZvckVhY2goKHdpbmRvdzogTWFwSW5mb1dpbmRvdykgPT4ge1xuICAgICAgICB3aW5kb3cuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5jdXJyZW50bHlPcGVuV2luZG93Um91dGluZyA9IG51bGw7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuZGF0YS5tYXJrZXJzPy5mb3JFYWNoKChpdGVtOiBJTWFwTWFya2VycywgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgIGlmIChpID09PSB0aGlzLmZvY3VzZWRJY29uKSB7XG4gICAgICAgICAgaXRlbS5pY29uID0ge1xuICAgICAgICAgICAgdXJsOiB0aGlzLmluaXRpYWxNYXJrZXJJY29uc1tpXS51cmwsXG4gICAgICAgICAgICBsYWJlbE9yaWdpbjogdGhpcy5pbml0aWFsTWFya2VySWNvbnNbaV0ubGFiZWxPcmlnaW4sXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLmZvY3VzZWRJY29uID0gbnVsbDtcbiAgICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuZGF0YS5yb3V0aW5nTWFya2Vycz8ubWFwKChpdGVtOiBJTWFwTWFya2VycywgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgIGlmIChpID09PSB0aGlzLmZvY3VzZWRJY29uUm91dGluZykge1xuICAgICAgICAgIGl0ZW0uaWNvbiA9IHtcbiAgICAgICAgICAgIHVybDogdGhpcy5pbml0aWFsSWNvbnNbaV0udXJsLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHJlc2V0TWFya2Vyc0ljb25zKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0YS5tYXJrZXJzPy5mb3JFYWNoKChtYXJrZXI6IElNYXBNYXJrZXJzLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICBtYXJrZXIuaWNvbiA9IHtcbiAgICAgICAgdXJsOiB0aGlzLmluaXRpYWxNYXJrZXJJY29uc1tpbmRleF0udXJsLFxuICAgICAgICBsYWJlbE9yaWdpbjogdGhpcy5pbml0aWFsTWFya2VySWNvbnNbaW5kZXhdLmxhYmVsT3JpZ2luLFxuICAgICAgfTtcbiAgICB9KTtcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyByZXNldFJvdXRpbmdNYXJrZXJzKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0YS5yb3V0aW5nTWFya2Vycz8uZm9yRWFjaCgobWFya2VyOiBJTWFwTWFya2VycywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgbWFya2VyLmljb24gPSB7XG4gICAgICAgIHVybDogbWFya2VyLmljb24hLnVybCxcbiAgICAgICAgbGFiZWxPcmlnaW46IG1hcmtlci5pY29uIS5sYWJlbE9yaWdpbixcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgb25NYXBSZWFkeShtYXBJbnN0YW5jZTogZ29vZ2xlLm1hcHMuTWFwKToge1xuICAgIGZpbGxDb2xvcj86IHN0cmluZztcbiAgICBzdHJva2VDb2xvcj86IHN0cmluZztcbiAgICBzdHJva2VXZWlnaHQ/OiBudW1iZXI7XG4gICAgZmlsbE9wYWNpdHk/OiBudW1iZXI7XG4gIH0gfCB2b2lkIHtcbiAgICB0aGlzLm1hcCA9IG1hcEluc3RhbmNlO1xuXG4gICAgaWYgKHRoaXMuZGF0YS5zdGF0ZUJvdW5kYXJpZXNVcmwpIHtcbiAgICAgIGNvbnN0IHN0YXRlQm91bmRhcmllc1VybCA9IHRoaXMuZGF0YS5zdGF0ZUJvdW5kYXJpZXNVcmwudXJsO1xuICAgICAgdGhpcy5tYXBzLmdvb2dsZU1hcD8uZGF0YS5sb2FkR2VvSnNvbihzdGF0ZUJvdW5kYXJpZXNVcmwpO1xuXG4gICAgICB0aGlzLm1hcHMuZ29vZ2xlTWFwPy5kYXRhLnNldFN0eWxlKChmZWF0dXJlKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXRlRGVuc2l0eSA9IGZlYXR1cmUuZ2V0UHJvcGVydHkoJ2RlbnNpdHknKTtcbiAgICAgICAgY29uc3QgeyBmaWxsQ29sb3IsIGZpbGxPcGFjaXR5IH0gPSBNYXBIZWxwZXIuZ2V0RmlsbENvbG9yRm9yU3RhdGUoXG4gICAgICAgICAgc3RhdGVEZW5zaXR5IGFzIG51bWJlcixcbiAgICAgICAgICB0aGlzLmRhdGEudmlldyB8fCAnJ1xuICAgICAgICApO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGZpbGxDb2xvcjogZmlsbENvbG9yLFxuICAgICAgICAgIHN0cm9rZUNvbG9yOiAnI0VFRUVFRScsXG4gICAgICAgICAgc3Ryb2tlV2VpZ2h0OiAwLjYsXG4gICAgICAgICAgZmlsbE9wYWNpdHk6IGZpbGxPcGFjaXR5LFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXRNYXBTdHlsZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRNYXBTdHlsZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGF0YT8uZGFya01vZGUpXG4gICAgICB0aGlzLm1hcE9wdGlvbnMgPSB7XG4gICAgICAgIC4uLnRoaXMubWFwT3B0aW9ucyxcbiAgICAgICAgc3R5bGVzOiBNYXBDb25zdGFudHMuR09PR0xFX01BUF9EQVJLX1NUWUxFUyxcbiAgICAgIH07XG5cbiAgICBjb25zdCBhbGxNYXJrZXJzQ29tYmluZWQgPSBbXG4gICAgICAuLi4odGhpcy5kYXRhLnJvdXRpbmdNYXJrZXJzID8/IFtdKSxcbiAgICAgIC4uLih0aGlzLmRhdGEuY2x1c3Rlck1hcmtlcnMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMuZGF0YS5tYXJrZXJzID8/IFtdKSxcbiAgICBdO1xuXG4gICAgY29uc3QgbWFwQ2VudGVyQW5kQm91bmRzID1cbiAgICAgIE1hcEhlbHBlci5nZXRNYXBDZW50ZXJBbmRab29tKGFsbE1hcmtlcnNDb21iaW5lZCk7XG5cbiAgICB0aGlzLm1hcENlbnRlciA9IG1hcENlbnRlckFuZEJvdW5kcy5tYXBDZW50ZXI7XG4gICAgdGhpcy5tYXA/LmZpdEJvdW5kcyhtYXBDZW50ZXJBbmRCb3VuZHMuYm91bmRzKTtcbiAgfVxuXG4gIHB1YmxpYyBpZGVudGl0eShpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlcnMuZm9yRWFjaCgocmVuZGVyZXIpID0+IHJlbmRlcmVyLnNldE1hcChudWxsKSk7XG4gIH1cbn1cbiIsIjxnb29nbGUtbWFwXG4gIGhlaWdodD1cIjEwMCVcIlxuICB3aWR0aD1cIjEwMCVcIlxuICBbem9vbV09XCJtYXBab29tXCJcbiAgW2NlbnRlcl09XCJtYXBDZW50ZXJcIlxuICBbb3B0aW9uc109XCJtYXBPcHRpb25zXCJcbiAgKG1hcEluaXRpYWxpemVkKT1cIm9uTWFwUmVhZHkoJGV2ZW50KVwiXG4+XG4gIDxtYXAtbWFya2VyXG4gICAgI21hcmtlcj1cIm1hcE1hcmtlclwiXG4gICAgKm5nRm9yPVwibGV0IG1hcmtlcml0ZW0gb2YgZGF0YS5tYXJrZXJzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiBpZGVudGl0eVwiXG4gICAgW3Bvc2l0aW9uXT1cIm1hcmtlcml0ZW0ucG9zaXRpb25cIlxuICAgIFtpY29uXT1cIm1hcmtlcml0ZW0uaWNvbiFcIlxuICAgIFtsYWJlbF09XCJmb2N1c2VkSWNvbiAhPT0gaSA/IG1hcmtlcml0ZW0ubGFiZWwhIDogJydcIlxuICAgIFt0aXRsZV09XCJtYXJrZXJpdGVtLnRpdGxlIVwiXG4gICAgW29wdGlvbnNdPVwibWFya2VyaXRlbS5vcHRpb25zIVwiXG4gICAgKG1hcENsaWNrKT1cIm9uTWFya2VyQ2xpY2soaSwgJGV2ZW50LCBtYXJrZXJpdGVtKVwiXG4gID5cbiAgICA8bWFwLWluZm8td2luZG93XG4gICAgICAjaW5mb1dpbmRvd3NWaWV3PVwibWFwSW5mb1dpbmRvd1wiXG4gICAgICBbb3B0aW9uc109XCJpbmZvV2luZG93T3B0aW9uc1wiXG4gICAgPlxuICAgICAgPGFwcC1jYS1tYXAtZHJvcGRvd25cbiAgICAgICAgW2l0ZW1dPVwiZGF0YT8udmlld0RhdGE/LltpXVwiXG4gICAgICAgIFtpc0FjY2lkZW50TWFwXT1cImRhdGEuaXNBY2NpZGVudE1hcCA/PyBmYWxzZVwiXG4gICAgICA+PC9hcHAtY2EtbWFwLWRyb3Bkb3duPlxuICAgIDwvbWFwLWluZm8td2luZG93PlxuICA8L21hcC1tYXJrZXI+XG4gIDxtYXAtbWFya2VyXG4gICAgKm5nRm9yPVwibGV0IG1hcmtlciBvZiBkYXRhLmNsdXN0ZXJNYXJrZXJzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiBpZGVudGl0eVwiXG4gICAgW3Bvc2l0aW9uXT1cIm1hcmtlci5wb3NpdGlvblwiXG4gICAgW2ljb25dPVwibWFya2VyLmljb25cIlxuICAgIFtsYWJlbF09XCJtYXJrZXIubGFiZWwhXCJcbiAgICBbdGl0bGVdPVwibWFya2VyPy50aXRsZSFcIlxuICA+XG4gIDwvbWFwLW1hcmtlcj5cblxuICA8bWFwLW1hcmtlclxuICAgICNtYXJrZXJSb3V0aW5nPVwibWFwTWFya2VyXCJcbiAgICAqbmdGb3I9XCJcbiAgICAgIGxldCBtYXJrZXJpdGVtIG9mIGRhdGEucm91dGluZ01hcmtlcnM7XG4gICAgICBsZXQgaSA9IGluZGV4O1xuICAgICAgdHJhY2tCeTogaWRlbnRpdHlcbiAgICBcIlxuICAgIFtwb3NpdGlvbl09XCJtYXJrZXJpdGVtLnBvc2l0aW9uXCJcbiAgICBbaWNvbl09XCJtYXJrZXJpdGVtLmljb24hXCJcbiAgICBbbGFiZWxdPVwiZm9jdXNlZEljb25Sb3V0aW5nICE9PSBpID8gbWFya2VyaXRlbS5sYWJlbCEgOiAnJ1wiXG4gICAgW3RpdGxlXT1cIm1hcmtlcml0ZW0udGl0bGUhXCJcbiAgICBbb3B0aW9uc109XCJtYXJrZXJpdGVtLm9wdGlvbnMhXCJcbiAgICAobWFwQ2xpY2spPVwib25Sb3V0aW5nTWFya2VyQ2xpY2soaSwgJGV2ZW50LCBtYXJrZXJpdGVtKVwiXG4gID5cbiAgICA8bWFwLWluZm8td2luZG93ICNpbmZvV2luZG93c1ZpZXdSb3V0aW5nPVwibWFwSW5mb1dpbmRvd1wiPlxuICAgICAgPGFwcC1jYS1tYXAtZHJvcGRvd24gW2lzQWNjaWRlbnRNYXBdPVwiZmFsc2VcIj48L2FwcC1jYS1tYXAtZHJvcGRvd24+XG4gICAgPC9tYXAtaW5mby13aW5kb3c+XG4gIDwvbWFwLW1hcmtlcj5cbjwvZ29vZ2xlLW1hcD5cbiJdfQ==
431
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2EtbWFwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NhLWNvbXBvbmVudHMvc3JjL2xpYi9jb21wb25lbnRzL2NhLW1hcC9jYS1tYXAuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2EtY29tcG9uZW50cy9zcmMvbGliL2NvbXBvbmVudHMvY2EtbWFwL2NhLW1hcC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFFTixTQUFTLEVBRVQsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLGFBQWEsR0FHZCxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXhELGFBQWE7QUFDYixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUV0RixRQUFRO0FBQ1IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBYWhFLFVBQVU7QUFDVixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFLL0QsWUFBWTtBQUNaLE9BQU8sRUFDTCw2QkFBNkIsRUFDN0IsbUJBQW1CLEdBQ3BCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7O0FBa0I1RCxNQUFNLE9BQU8sY0FBYztJQUN6QixZQUFtQixFQUFxQjtRQUFyQixPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUk5Qiw0QkFBdUIsR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFD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QUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDOytHQWxlVSxjQUFjO21HQUFkLGNBQWMsMldBVWQsU0FBUyxrRkFDVCxhQUFhLGdEQzlFMUIsdTJFQThFQTtnQkRyQkksVUFBVTtnQkFDVixnQkFBZ0IsMG1EQUNoQixZQUFZLCtQQUNaLG9CQUFvQjtnQkFFcEIsYUFBYTtnQkFDYixzQkFBc0I7OzRGQUliLGNBQWM7a0JBaEIxQixTQUFTOytCQUNFLFlBQVksY0FHVixJQUFJLFdBQ1A7d0JBQ1AsVUFBVTt3QkFDVixnQkFBZ0I7d0JBQ2hCLFlBQVk7d0JBQ1osb0JBQW9CO3dCQUVwQixhQUFhO3dCQUNiLHNCQUFzQjtxQkFDdkIsaUJBQ2MsaUJBQWlCLENBQUMsSUFBSTt3R0FJeEIsSUFBSTtzQkFBaEIsS0FBSztnQkFHSSx1QkFBdUI7c0JBQWhDLE1BQU07Z0JBQ0csa0JBQWtCO3NCQUEzQixNQUFNO2dCQUNHLHNCQUFzQjtzQkFBL0IsTUFBTTtnQkFDRyxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFDa0MsSUFBSTtzQkFBNUMsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUNiLGVBQWU7c0JBQXhDLFNBQVM7dUJBQUMsYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVmlld0NoaWxkLFxuICBWaWV3Q2hpbGRyZW4sXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEdvb2dsZU1hcCxcbiAgR29vZ2xlTWFwc01vZHVsZSxcbiAgTWFwSW5mb1dpbmRvdyxcbiAgTWFwTWFya2VyLFxuICBNYXBDaXJjbGUsXG59IGZyb20gJ0Bhbmd1bGFyL2dvb2dsZS1tYXBzJztcbmltcG9ydCB7IEFuZ3VsYXJTdmdJY29uTW9kdWxlIH0gZnJvbSAnYW5ndWxhci1zdmctaWNvbic7XG5cbi8vIENvbXBvbmVudHNcbmltcG9ydCB7IENhTWFwRHJvcGRvd25Db21wb25lbnQgfSBmcm9tICcuLi9jYS1tYXAtZHJvcGRvd24vY2EtbWFwLWRyb3Bkb3duLmNvbXBvbmVudCc7XG5cbi8vIEVudW1zXG5pbXBvcnQgeyBHb29nbGVNYXBFbnVtIH0gZnJvbSAnLi4vY2EtbWFwL2VudW1zL2dvb2dsZS1tYXAuZW51bSc7XG5cbi8vIE1vZGVsc1xuaW1wb3J0IHtcbiAgSU1hcE1hcmtlcnMsXG4gIElNYXBSb3V0ZVBhdGgsXG4gIElDYU1hcFByb3BzLFxuICBJTWFwT3B0aW9ucyxcbiAgSVJvdXRlUGF0aCxcbiAgSU1hcEJvdW5kc1pvb20sXG4gIElNYXBTZWxlY3RlZE1hcmtlckRhdGEsXG59IGZyb20gJy4uL2NhLW1hcC9tb2RlbHMvbWFwLm1vZGVsJztcblxuLy8gSGVscGVyc1xuaW1wb3J0IHsgTWFwSGVscGVyIH0gZnJvbSAnLi4vY2EtbWFwL3V0aWxzL2hlbHBlcnMvbWFwLmhlbHBlcic7XG5cbi8vIFN2Zy1yb3V0ZXNcbmltcG9ydCB7IE1hcFN2Z1JvdXRlcyB9IGZyb20gJy4uL2NhLW1hcC91dGlscy9tYXAtc3ZnLXJvdXRlcy9tYXAtc3ZnLXJvdXRlcyc7XG5cbi8vIENvbnN0YW50c1xuaW1wb3J0IHtcbiAgTWFwSW5mb1dpbmRvd09wdGlvbnNDb25zdGFudHMsXG4gIE1hcE9wdGlvbnNDb25zdGFudHMsXG59IGZyb20gJy4vdXRpbHMvY29uc3RhbnRzJztcbmltcG9ydCB7IE1hcENvbnN0YW50cyB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9tYXAuY29uc3RhbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtY2EtbWFwJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhLW1hcC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NhLW1hcC5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgLy8gTW9kdWxlc1xuICAgIEdvb2dsZU1hcHNNb2R1bGUsXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEFuZ3VsYXJTdmdJY29uTW9kdWxlLFxuXG4gICAgLy8gQ29tcG9uZW50c1xuICAgIENhTWFwRHJvcGRvd25Db21wb25lbnQsXG4gIF0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIENhTWFwQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IocHVibGljIGNkOiBDaGFuZ2VEZXRlY3RvclJlZikge31cbiAgQElucHV0KCkgc2V0IGRhdGEodmFsdWVzOiBJQ2FNYXBQcm9wcykge1xuICAgIHRoaXMuaGFuZGxlTWFwRGF0YSh2YWx1ZXMpO1xuICB9XG4gIEBPdXRwdXQoKSByZXNldFNlbGVjdGVkTWFya2VySXRlbSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIGNsdXN0ZXJNYXJrZXJDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8SU1hcE1hcmtlcnM+KCk7XG4gIEBPdXRwdXQoKSBjbHVzdGVyTGlzdFNjcm9sbEV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxJTWFwTWFya2Vycz4oKTtcbiAgQE91dHB1dCgpIGdldEluZm9XaW5kb3dEYXRhID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gIEBPdXRwdXQoKSBib3VuZHNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxJTWFwQm91bmRzWm9vbT4oKTtcbiAgQFZpZXdDaGlsZChHb29nbGVNYXAsIHsgc3RhdGljOiBmYWxzZSB9KSBtYXBzITogR29vZ2xlTWFwO1xuICBAVmlld0NoaWxkKE1hcEluZm9XaW5kb3cpIGluZm9XaW5kb3dzVmlldyE6IE1hcEluZm9XaW5kb3c7XG4gIHB1YmxpYyBjdXJyZW50bHlPcGVuV2luZG93ITogTWFwSW5mb1dpbmRvdyB8IG51bGw7XG4gIHB1YmxpYyBjdXJyZW50bHlPcGVuV2luZG93Um91dGluZyE6IE1hcEluZm9XaW5kb3cgfCBudWxsO1xuICBwdWJsaWMgcHJldmlvdXNJY29uVXJsITogc3RyaW5nO1xuICBwdWJsaWMgcHJldmlvdXNJY29uVXJsUm91dGluZyE6IHN0cmluZztcbiAgcHVibGljIGZvY3VzZWRJY29uUm91dGluZyE6IG51bWJlcjtcbiAgcHJpdmF0ZSBkaXJlY3Rpb25TZXJ2aWNlID0gbmV3IGdvb2dsZS5tYXBzLkRpcmVjdGlvbnNTZXJ2aWNlKCk7XG4gIHB1YmxpYyBkaXJlY3Rpb25zUmVuZGVyZXJzOiBnb29nbGUubWFwcy5EaXJlY3Rpb25zUmVuZGVyZXJbXSA9IFtdO1xuICBwdWJsaWMgaW5pdGlhbEljb25zOiB7XG4gICAgdXJsOiBzdHJpbmc7XG4gICAgbGFiZWxPcmlnaW4/OiBnb29nbGUubWFwcy5Qb2ludDtcbiAgfVtdID0gW107XG4gIHB1YmxpYyBpbml0aWFsTWFya2VySWNvbnM6IHtcbiAgICB1cmw6IHN0cmluZztcbiAgICBsYWJlbE9yaWdpbj86IGdvb2dsZS5tYXBzLlBvaW50O1xuICAgIHpJbmRleD86IG51bWJlcjtcbiAgfVtdID0gW107XG4gIHB1YmxpYyBpbmZvV2luZG93T3B0aW9uczogZ29vZ2xlLm1hcHMuSW5mb1dpbmRvd09wdGlvbnMgPVxuICAgIE1hcEluZm9XaW5kb3dPcHRpb25zQ29uc3RhbnRzLm1hcEluZm9XaW5kb3dPcHRpb25zO1xuICBwdWJsaWMgbWFwT3B0aW9uczogSU1hcE9wdGlvbnMgPSBNYXBPcHRpb25zQ29uc3RhbnRzLmRlZmF1bHRNYXBPcHRpb25zO1xuICBwdWJsaWMgbWFwWm9vbTogbnVtYmVyID0gTWFwT3B0aW9uc0NvbnN0YW50cy5kZWZhdWx0TWFwWm9vbTtcbiAgcHVibGljIG1hcENlbnRlcjogSVJvdXRlUGF0aCA9IE1hcE9wdGlvbnNDb25zdGFudHMuZGVmYXVsdE1hcENlbnRlcjtcbiAgcHVibGljIG1hcDogZ29vZ2xlLm1hcHMuTWFwIHwgbnVsbCA9IG51bGw7XG4gIHB1YmxpYyBpc01hcENlbnRlclNldDogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgY2x1c3Rlck1hcmtlcnNEYXRhOiBJTWFwTWFya2Vyc1tdID0gW107XG4gIHB1YmxpYyBtYXJrZXJzRGF0YTogSU1hcE1hcmtlcnNbXSA9IFtdO1xuICBwdWJsaWMgbWFwRGF0YTogSUNhTWFwUHJvcHMgPSB7fTtcbiAgcHVibGljIG9wZW5lZEluZm9XaW5kb3dEYXRhOiBJTWFwTWFya2VycyB8IG51bGwgPSBudWxsO1xuICBwdWJsaWMgYXJlYUZpbHRlckRhdGEgPSBNYXBPcHRpb25zQ29uc3RhbnRzLmFyZWFGaWx0ZXJEYXRhO1xuICBwdWJsaWMgaXNBcmVhRmlsdGVyQWN0aXZlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5zdG9yZUluaXRpYWxJY29uRm9yTWFya2VyKCk7XG4gICAgdGhpcy5zdG9yZUluaXRpYWxJY29uRm9yUm91dGluZ01hcmtlcigpO1xuICAgIC8vIFJlc2V0IGFsbCBpY29ucyB0byB0aGVpciBpbml0aWFsIHN0YXRlIG9uIHBhZ2UgbG9hZFxuICAgIHRoaXMucmVzZXRNYXJrZXJzSWNvbnMoKTtcbiAgICB0aGlzLnJlc2V0Um91dGluZ01hcmtlcnMoKTtcbiAgICAvL0Rpc3BsYXkgcm91dGVzIGZvciByb3V0aW5nTWFya2Vyc1xuICAgIHRoaXMuY2FsY3VsYXRlQW5kRGlzcGxheVJvdXRlKCk7XG4gIH1cblxuICBwdWJsaWMgc3RvcmVJbml0aWFsSWNvbkZvck1hcmtlcigpOiB2b2lkIHtcbiAgICB0aGlzLmluaXRpYWxNYXJrZXJJY29ucyA9IFtdO1xuXG4gICAgdGhpcy5tYXBEYXRhIS5tYXJrZXJzPy5mb3JFYWNoKChtYXJrZXI6IElNYXBNYXJrZXJzLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICB0aGlzLmluaXRpYWxNYXJrZXJJY29uc1tpbmRleF0gPSB7XG4gICAgICAgIHVybDogbWFya2VyLmljb24hLnVybCxcbiAgICAgICAgbGFiZWxPcmlnaW46IG1hcmtlci5pY29uIS5sYWJlbE9yaWdpbixcbiAgICAgICAgekluZGV4OiBtYXJrZXIub3B0aW9ucz8uekluZGV4ID8/IDEsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHN0b3JlSW5pdGlhbEljb25Gb3JSb3V0aW5nTWFya2VyKCk6IHZvaWQge1xuICAgIHRoaXMubWFwRGF0YS5yb3V0aW5nTWFya2Vycz8uZm9yRWFjaChcbiAgICAgIChtYXJrZXI6IElNYXBNYXJrZXJzLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIHRoaXMuaW5pdGlhbEljb25zW2luZGV4XSA9IHtcbiAgICAgICAgICB1cmw6IG1hcmtlci5pY29uIS51cmwsXG4gICAgICAgICAgbGFiZWxPcmlnaW46IG1hcmtlci5pY29uIS5sYWJlbE9yaWdpbixcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcHVibGljIG9uQ2x1c3Rlck1hcmtlckNsaWNrKG1hcmtlckl0ZW06IElNYXBNYXJrZXJzKTogdm9pZCB7XG4gICAgY29uc3QgaXNJbmZvV2luZG93T3BlbmVkID0gdGhpcy5jaGVja0luZm9XaW5kb3dQb3NpdGlvbihcbiAgICAgIG1hcmtlckl0ZW0sXG4gICAgICB0aGlzLm9wZW5lZEluZm9XaW5kb3dEYXRhXG4gICAgKTtcblxuICAgIGlmICghaXNJbmZvV2luZG93T3BlbmVkKSB0aGlzLmNsdXN0ZXJNYXJrZXJDbGljay5lbWl0KG1hcmtlckl0ZW0pO1xuICAgIGVsc2UgdGhpcy5jbG9zZUluZm9XaW5kb3coKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRNYXJrZXJJbmZvV2luZG93KG1hcmtlcklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAobWFya2VySWQpIHRoaXMuZ2V0SW5mb1dpbmRvd0RhdGEuZW1pdChtYXJrZXJJZCk7XG4gIH1cblxuICBwdWJsaWMgb25NYXJrZXJDbGljayhtYXJrZXJJdGVtOiBJTWFwTWFya2Vycyk6IHZvaWQge1xuICAgIGNvbnN0IGlzSW5mb1dpbmRvd09wZW5lZCA9IHRoaXMuY2hlY2tJbmZvV2luZG93UG9zaXRpb24oXG4gICAgICBtYXJrZXJJdGVtLFxuICAgICAgdGhpcy5vcGVuZWRJbmZvV2luZG93RGF0YVxuICAgICk7XG5cbiAgICBpZiAoIWlzSW5mb1dpbmRvd09wZW5lZCkgdGhpcy5nZXRNYXJrZXJJbmZvV2luZG93KG1hcmtlckl0ZW0uZGF0YS5pZCk7XG4gICAgZWxzZSB0aGlzLmNsb3NlSW5mb1dpbmRvdygpO1xuICB9XG5cbiAgcHVibGljIHNldERpcmVjdGlvbnNPbk1hcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tYXBzPy5nb29nbGVNYXApIHtcbiAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVycy5mb3JFYWNoKChyZW5kZXJlcikgPT5cbiAgICAgICAgcmVuZGVyZXIuc2V0TWFwKHRoaXMubWFwcz8uZ29vZ2xlTWFwISlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNhbGN1bGF0ZUFuZERpc3BsYXlSb3V0ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tYXBEYXRhLnJvdXRlUGF0aHMpIHtcbiAgICAgIC8vIENsZWFyIHByZXZpb3VzIGRpcmVjdGlvbnMgcmVuZGVyZXJzXG4gICAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlcnMuZm9yRWFjaCgocmVuZGVyZXIpID0+IHJlbmRlcmVyLnNldE1hcChudWxsKSk7XG4gICAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlcnMgPSBbXTtcblxuICAgICAgdGhpcy5tYXBEYXRhLnJvdXRlUGF0aHMhLmZvckVhY2goKHJvdXRlOiBJTWFwUm91dGVQYXRoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlcXVlc3Q6IGdvb2dsZS5tYXBzLkRpcmVjdGlvbnNSZXF1ZXN0ID0ge1xuICAgICAgICAgIG9yaWdpbjogcm91dGUucGF0aFswXSxcbiAgICAgICAgICBkZXN0aW5hdGlvbjogcm91dGUucGF0aFtyb3V0ZS5wYXRoLmxlbmd0aCAtIDFdLFxuICAgICAgICAgIHdheXBvaW50czogcm91dGUucGF0aFxuICAgICAgICAgICAgLnNsaWNlKDEsIHJvdXRlLnBhdGgubGVuZ3RoIC0gMSlcbiAgICAgICAgICAgIC5tYXAoKHBvc2l0aW9uKSA9PiAoeyBsb2NhdGlvbjogcG9zaXRpb24gfSkpLFxuICAgICAgICAgIHRyYXZlbE1vZGU6IGdvb2dsZS5tYXBzLlRyYXZlbE1vZGUuQklDWUNMSU5HLFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZGlyZWN0aW9uU2VydmljZS5yb3V0ZShyZXF1ZXN0LCAocmVzdWx0LCBzdGF0dXMpID0+IHtcbiAgICAgICAgICBpZiAoc3RhdHVzID09PSBnb29nbGUubWFwcy5EaXJlY3Rpb25zU3RhdHVzLk9LICYmIHJlc3VsdD8ucm91dGVzWzBdKSB7XG4gICAgICAgICAgICBjb25zdCBkaXJlY3Rpb25zUmVuZGVyZXIgPSBuZXcgZ29vZ2xlLm1hcHMuRGlyZWN0aW9uc1JlbmRlcmVyKHtcbiAgICAgICAgICAgICAgc3VwcHJlc3NJbmZvV2luZG93czogdHJ1ZSxcbiAgICAgICAgICAgICAgc3VwcHJlc3NNYXJrZXJzOiB0cnVlLFxuICAgICAgICAgICAgICBwcmVzZXJ2ZVZpZXdwb3J0OiB0cnVlLFxuICAgICAgICAgICAgICBwb2x5bGluZU9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBzdHJva2VDb2xvcjogcm91dGUuc3Ryb2tlQ29sb3IgfHwgR29vZ2xlTWFwRW51bS5TVFJPS0VfQ09MT1IsXG4gICAgICAgICAgICAgICAgc3Ryb2tlT3BhY2l0eTpcbiAgICAgICAgICAgICAgICAgIHJvdXRlLnN0cm9rZU9wYWNpdHkgfHwgR29vZ2xlTWFwRW51bS5TVFJPS0VfT1BBQ0lUWSxcbiAgICAgICAgICAgICAgICBzdHJva2VXZWlnaHQ6IHJvdXRlLnN0cm9rZVdlaWdodCB8fCBHb29nbGVNYXBFbnVtLlNUUk9LRV9XRUlHSFQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRpcmVjdGlvbnNSZW5kZXJlci5zZXREaXJlY3Rpb25zKHJlc3VsdCk7XG4gICAgICAgICAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlcnMucHVzaChkaXJlY3Rpb25zUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5zZXREaXJlY3Rpb25zT25NYXAoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgb25Sb3V0aW5nTWFya2VyQ2xpY2soXG4gICAgaTogbnVtYmVyLFxuICAgIGV2ZW50OiBnb29nbGUubWFwcy5NYXBNb3VzZUV2ZW50LFxuICAgIG1hcmtlcml0ZW06IElNYXBNYXJrZXJzXG4gICk6IHZvaWQge1xuICAgIC8vIGlmIChtYXJrZXJpdGVtPy5pbmZvV2luZG93Q29udGVudCkge1xuICAgIC8vICAgaWYgKFxuICAgIC8vICAgICB0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3dJbmRleFJvdXRpbmcgPT09IGkgJiZcbiAgICAvLyAgICAgdGhpcy5jdXJyZW50bHlPcGVuV2luZG93Um91dGluZ1xuICAgIC8vICAgKSB7XG4gICAgLy8gICAgIGNvbnN0IGluZm9XaW5kb3cgPSB0aGlzLmluZm9XaW5kb3dzVmlld1JvdXRpbmcudG9BcnJheSgpW2ldO1xuICAgIC8vICAgICAvLyBDbG9zZSB0aGUgY3VycmVudGx5IG9wZW4gaW5mbyB3aW5kb3cgYW5kIHJlc2V0IHRoZSBpbmRleFxuICAgIC8vICAgICB0aGlzLm1hcERhdGEucm91dGluZ01hcmtlcnMhLm1hcCgoaXRlbTogSU1hcE1hcmtlcnMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAvLyAgICAgICBpZiAoaW5kZXggPT09IGkpIHtcbiAgICAvLyAgICAgICAgIGl0ZW0uaWNvbiA9IHtcbiAgICAvLyAgICAgICAgICAgdXJsOiB0aGlzLmluaXRpYWxJY29uc1tpbmRleF0hLnVybCxcbiAgICAvLyAgICAgICAgICAgbGFiZWxPcmlnaW46IHRoaXMuaW5pdGlhbEljb25zW2luZGV4XSEubGFiZWxPcmlnaW4sXG4gICAgLy8gICAgICAgICB9O1xuICAgIC8vICAgICAgIH1cbiAgICAvLyAgICAgfSk7XG4gICAgLy8gICAgIGluZm9XaW5kb3cuY2xvc2UoKTtcbiAgICAvLyAgICAgdGhpcy5jdXJyZW50bHlPcGVuV2luZG93SW5kZXhSb3V0aW5nID0gbnVsbDtcbiAgICAvLyAgIH0gZWxzZSB7XG4gICAgLy8gICAgIGNvbnN0IG1hcmtlckluZGV4ID0gdGhpcy5tYXJrZXJSb3V0aW5nLnRvQXJyYXkoKVtpXTtcbiAgICAvLyAgICAgY29uc3QgaW5mb1dpbmRvdyA9IHRoaXMuaW5mb1dpbmRvd3NWaWV3Um91dGluZy50b0FycmF5KClbaV07XG4gICAgLy8gICAgIGlmICh0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3dSb3V0aW5nKSB7XG4gICAgLy8gICAgICAgdGhpcy5jdXJyZW50bHlPcGVuV2luZG93Um91dGluZy5jbG9zZSgpO1xuICAgIC8vICAgICB9XG4gICAgLy8gICAgIGlmIChpbmZvV2luZG93KSB7XG4gICAgLy8gICAgICAgLy8gUmVzdG9yZSB0aGUgcHJldmlvdXMgaWNvbiBmb3IgdGhlIHByZXZpb3VzbHkgZm9jdXNlZCByb3V0aW5nIG1hcmtlclxuICAgIC8vICAgICAgIGlmIChcbiAgICAvLyAgICAgICAgIHRoaXMuZm9jdXNlZEljb25Sb3V0aW5nICE9PSB1bmRlZmluZWQgJiZcbiAgICAvLyAgICAgICAgIHRoaXMuZm9jdXNlZEljb25Sb3V0aW5nICE9PSBpXG4gICAgLy8gICAgICAgKSB7XG4gICAgLy8gICAgICAgICBjb25zdCBwcmV2aW91c0ZvY3VzZWRJdGVtID1cbiAgICAvLyAgICAgICAgICAgdGhpcy5tYXBEYXRhLnJvdXRpbmdNYXJrZXJzIVt0aGlzLmZvY3VzZWRJY29uUm91dGluZ107XG4gICAgLy8gICAgICAgICBpZiAocHJldmlvdXNGb2N1c2VkSXRlbSkge1xuICAgIC8vICAgICAgICAgICBwcmV2aW91c0ZvY3VzZWRJdGVtLmljb24gPSB7XG4gICAgLy8gICAgICAgICAgICAgdXJsOiB0aGlzLmluaXRpYWxJY29uc1t0aGlzLmZvY3VzZWRJY29uUm91dGluZ10udXJsLFxuICAgIC8vICAgICAgICAgICAgIGxhYmVsT3JpZ2luOlxuICAgIC8vICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsSWNvbnNbdGhpcy5mb2N1c2VkSWNvblJvdXRpbmddLmxhYmVsT3JpZ2luLFxuICAgIC8vICAgICAgICAgICB9O1xuICAgIC8vICAgICAgICAgfVxuICAgIC8vICAgICAgIH1cbiAgICAvLyAgICAgICAvLyBVcGRhdGUgdGhlIGN1cnJlbnQgbWFya2VyXG4gICAgLy8gICAgICAgdGhpcy5tYXBEYXRhLnJvdXRpbmdNYXJrZXJzIS5tYXAoXG4gICAgLy8gICAgICAgICAoaXRlbTogSU1hcE1hcmtlcnMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAvLyAgICAgICAgICAgaWYgKGluZGV4ID09PSBpKSB7XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ljb25VcmxSb3V0aW5nID0gaXRlbS5pY29uID8gaXRlbS5pY29uLnVybCA6ICcnO1xuICAgIC8vICAgICAgICAgICAgIHRoaXMuZm9jdXNlZEljb25Sb3V0aW5nID0gaTtcbiAgICAvLyAgICAgICAgICAgICB0aGlzLnNob3dMYWJlbCA9IGZhbHNlO1xuICAgIC8vICAgICAgICAgICAgIGl0ZW0uaWNvbiA9IHtcbiAgICAvLyAgICAgICAgICAgICAgIHVybDpcbiAgICAvLyAgICAgICAgICAgICAgICAgdGhpcy5tYXBEYXRhLmlzVW5pdFZpZXdTdG9wcyB8fCB0aGlzLm1hcERhdGEuaXNEcml2ZXJNaWxlc1xuICAgIC8vICAgICAgICAgICAgICAgICAgID8gaXRlbS5pY29uIS51cmxcbiAgICAvLyAgICAgICAgICAgICAgICAgICA6IE1hcFN2Z1JvdXRlcy5tYXJrZXJTdmdSb3V0ZSxcbiAgICAvLyAgICAgICAgICAgICB9O1xuICAgIC8vICAgICAgICAgICB9IGVsc2Uge1xuICAgIC8vICAgICAgICAgICAgIHRoaXMuc2hvd0xhYmVsID0gdHJ1ZTtcbiAgICAvLyAgICAgICAgICAgfVxuICAgIC8vICAgICAgICAgfVxuICAgIC8vICAgICAgICk7XG4gICAgLy8gICAgICAgaW5mb1dpbmRvdy5vcGVuKG1hcmtlckluZGV4KTtcbiAgICAvLyAgICAgICB0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3dSb3V0aW5nID0gaW5mb1dpbmRvdztcbiAgICAvLyAgICAgICB0aGlzLmN1cnJlbnRseU9wZW5XaW5kb3dJbmRleFJvdXRpbmcgPSBpO1xuICAgIC8vICAgICB9XG4gICAgLy8gICB9XG4gICAgLy8gICB0aGlzLm1hcmtlckNsaWNrLmVtaXQobWFya2VyaXRlbSk7XG4gICAgLy8gfSBlbHNlIHtcbiAgICAvLyAgIHJldHVybjtcbiAgICAvLyB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5tYXBzLmdvb2dsZU1hcD8uYWRkTGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgdGhpcy5jbG9zZUluZm9XaW5kb3coKTtcblxuICAgICAgdGhpcy5tYXBEYXRhLnJvdXRpbmdNYXJrZXJzPy5tYXAoKGl0ZW06IElNYXBNYXJrZXJzLCBpOiBudW1iZXIpID0+IHtcbiAgICAgICAgaWYgKGkgPT09IHRoaXMuZm9jdXNlZEljb25Sb3V0aW5nKSB7XG4gICAgICAgICAgaXRlbS5pY29uID0ge1xuICAgICAgICAgICAgdXJsOiB0aGlzLmluaXRpYWxJY29uc1tpXS51cmwsXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVzZXRNYXJrZXJzSWNvbnMoKTogdm9pZCB7XG4gICAgdGhpcy5tYXBEYXRhLm1hcmtlcnM/Lm1hcCgobWFya2VyOiBJTWFwTWFya2VycywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWFya2VyLFxuICAgICAgICBpY29uOiB7XG4gICAgICAgICAgLi4ubWFya2VyLmljb24sXG4gICAgICAgICAgc2NhbGVkU2l6ZTogTWFwT3B0aW9uc0NvbnN0YW50cy5kZWZhdWx0TWFya2VyU2l6ZSxcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uczogeyB6SW5kZXg6IGluZGV4ICsgMSB9LFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIHJlc2V0Um91dGluZ01hcmtlcnMoKTogdm9pZCB7XG4gICAgdGhpcy5tYXBEYXRhLnJvdXRpbmdNYXJrZXJzPy5mb3JFYWNoKFxuICAgICAgKG1hcmtlcjogSU1hcE1hcmtlcnMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgbWFya2VyLmljb24gPSB7XG4gICAgICAgICAgdXJsOiBtYXJrZXIuaWNvbiEudXJsLFxuICAgICAgICAgIGxhYmVsT3JpZ2luOiBtYXJrZXIuaWNvbiEubGFiZWxPcmlnaW4sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBvbk1hcFJlYWR5KG1hcEluc3RhbmNlOiBnb29nbGUubWFwcy5NYXApOiB7XG4gICAgZmlsbENvbG9yPzogc3RyaW5nO1xuICAgIHN0cm9rZUNvbG9yPzogc3RyaW5nO1xuICAgIHN0cm9rZVdlaWdodD86IG51bWJlcjtcbiAgICBmaWxsT3BhY2l0eT86IG51bWJlcjtcbiAgfSB8IHZvaWQge1xuICAgIHRoaXMubWFwID0gbWFwSW5zdGFuY2U7XG5cbiAgICBpZiAodGhpcy5tYXBEYXRhLnN0YXRlQm91bmRhcmllc1VybCkge1xuICAgICAgY29uc3Qgc3RhdGVCb3VuZGFyaWVzVXJsID0gdGhpcy5tYXBEYXRhLnN0YXRlQm91bmRhcmllc1VybC51cmw7XG4gICAgICB0aGlzLm1hcHMuZ29vZ2xlTWFwPy5kYXRhLmxvYWRHZW9Kc29uKHN0YXRlQm91bmRhcmllc1VybCk7XG5cbiAgICAgIHRoaXMubWFwcy5nb29nbGVNYXA/LmRhdGEuc2V0U3R5bGUoKGZlYXR1cmUpID0+IHtcbiAgICAgICAgY29uc3Qgc3RhdGVEZW5zaXR5ID0gZmVhdHVyZS5nZXRQcm9wZXJ0eSgnZGVuc2l0eScpO1xuICAgICAgICBjb25zdCB7IGZpbGxDb2xvciwgZmlsbE9wYWNpdHkgfSA9IE1hcEhlbHBlci5nZXRGaWxsQ29sb3JGb3JTdGF0ZShcbiAgICAgICAgICBzdGF0ZURlbnNpdHkgYXMgbnVtYmVyLFxuICAgICAgICAgIHRoaXMubWFwRGF0YS52aWV3IHx8ICcnXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZmlsbENvbG9yOiBmaWxsQ29sb3IsXG4gICAgICAgICAgc3Ryb2tlQ29sb3I6ICcjRUVFRUVFJyxcbiAgICAgICAgICBzdHJva2VXZWlnaHQ6IDAuNixcbiAgICAgICAgICBmaWxsT3BhY2l0eTogZmlsbE9wYWNpdHksXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnNlbmRCb3VuZHNDaGFuZ2VkRXZlbnQoKTtcbiAgICB0aGlzLnNldE1hcFN0eWxlcygpO1xuICAgIHRoaXMuZ2V0TWFwSWRsZUV2ZW50KG1hcEluc3RhbmNlKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRNYXBTdHlsZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubWFwRGF0YT8uZGFya01vZGUpXG4gICAgICB0aGlzLm1hcE9wdGlvbnMgPSB7XG4gICAgICAgIC4uLnRoaXMubWFwT3B0aW9ucyxcbiAgICAgICAgc3R5bGVzOiBNYXBDb25zdGFudHMuR09PR0xFX01BUF9EQVJLX1NUWUxFUyxcbiAgICAgIH07XG5cbiAgICBjb25zdCBhbGxNYXJrZXJzQ29tYmluZWQgPSBbXG4gICAgICAuLi4odGhpcy5tYXBEYXRhLnJvdXRpbmdNYXJrZXJzID8/IFtdKSxcbiAgICAgIC4uLih0aGlzLm1hcERhdGEuY2x1c3Rlck1hcmtlcnMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMubWFwRGF0YS5tYXJrZXJzID8/IFtdKSxcbiAgICBdO1xuXG4gICAgaWYgKGFsbE1hcmtlcnNDb21iaW5lZD8ubGVuZ3RoKSB7XG4gICAgICBjb25zdCBtYXBDZW50ZXJBbmRCb3VuZHMgPVxuICAgICAgICBNYXBIZWxwZXIuZ2V0TWFwQ2VudGVyQW5kWm9vbShhbGxNYXJrZXJzQ29tYmluZWQpO1xuXG4gICAgICB0aGlzLm1hcCEucGFuVG8obWFwQ2VudGVyQW5kQm91bmRzLm1hcENlbnRlcik7XG4gICAgICB0aGlzLm1hcD8uZml0Qm91bmRzKG1hcENlbnRlckFuZEJvdW5kcy5ib3VuZHMpO1xuICAgICAgdGhpcy5pc01hcENlbnRlclNldCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldE1hcElkbGVFdmVudChtYXA6IGdvb2dsZS5tYXBzLk1hcCk6IHZvaWQge1xuICAgIG1hcC5hZGRMaXN0ZW5lcignaWRsZScsICgpID0+IHtcbiAgICAgIHRoaXMuc2VuZEJvdW5kc0NoYW5nZWRFdmVudCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHNlbmRCb3VuZHNDaGFuZ2VkRXZlbnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubWFwKSB7XG4gICAgICBjb25zdCBtYXBCb3VuZHMgPSB0aGlzLm1hcC5nZXRCb3VuZHMoKTtcbiAgICAgIGNvbnN0IG1hcFpvb20gPSB0aGlzLm1hcC5nZXRab29tKCk7XG5cbiAgICAgIGlmIChtYXBCb3VuZHMgJiYgbWFwWm9vbSkge1xuICAgICAgICBjb25zdCBib3VuZHNPYmplY3QgPSB7IGJvdW5kczogbWFwQm91bmRzLCB6b29tOiBtYXBab29tIH07XG4gICAgICAgIHRoaXMuYm91bmRzQ2hhbmdlZC5lbWl0KGJvdW5kc09iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG9uQ2x1c3RlckJhY2tCdXR0b25DbGljaygpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2V0U2VsZWN0ZWRNYXJrZXJJdGVtLmVtaXQodHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIGdldE5ld0RhdGEoZGF0YTogSUNhTWFwUHJvcHMpOiBJQ2FNYXBQcm9wcyB7XG4gICAgY29uc3QgbmV3TWFya2VycyA9IGRhdGE/Lm1hcmtlcnM/Lm1hcCgobWFya2VyOiBJTWFwTWFya2VycykgPT4ge1xuICAgICAgY29uc3QgaXNTZWxlY3RlZE1hcmtlciA9IHRoaXMuY2hlY2tJbmZvV2luZG93UG9zaXRpb24oXG4gICAgICAgIG1hcmtlcixcbiAgICAgICAgdGhpcy5vcGVuZWRJbmZvV2luZG93RGF0YVxuICAgICAgKTtcblxuICAgICAgaWYgKGlzU2VsZWN0ZWRNYXJrZXIpIHtcbiAgICAgICAgY29uc3QgbmV3TWFya2VyRGF0YSA9IHtcbiAgICAgICAgICAuLi5tYXJrZXIsXG4gICAgICAgICAgaWNvbjoge1xuICAgICAgICAgICAgLi4ubWFya2VyLmljb24sXG4gICAgICAgICAgICBzY2FsZWRTaXplOiBNYXBPcHRpb25zQ29uc3RhbnRzLmxhcmdlTWFya2VyU2l6ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9wdGlvbnM6IHsgekluZGV4OiA5OTkgfSxcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gbmV3TWFya2VyRGF0YTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1hcmtlcjtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5kYXRhLFxuICAgICAgbWFya2VyczogbmV3TWFya2VycyxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIG9wZW5NYXJrZXJJbmZvV2luZG93KG1hcmtlckl0ZW06IElNYXBTZWxlY3RlZE1hcmtlckRhdGEpOiB2b2lkIHtcbiAgICBjb25zdCBpc0luZm9XaW5kb3dPcGVuZWQgPSB0aGlzLmNoZWNrSW5mb1dpbmRvd1Bvc2l0aW9uKFxuICAgICAgbWFya2VySXRlbSxcbiAgICAgIHRoaXMub3BlbmVkSW5mb1dpbmRvd0RhdGFcbiAgICApO1xuXG4gICAgY29uc3QgaXNDbHVzdGVySXRlbUNoYW5nZWQgPSB0aGlzLmNoZWNrQ2x1c3RlckRhdGFDaGFuZ2VzKFxuICAgICAgbWFya2VySXRlbSxcbiAgICAgIHRoaXMub3BlbmVkSW5mb1dpbmRvd0RhdGFcbiAgICApO1xuXG4gICAgaWYgKHRoaXMuaW5mb1dpbmRvd3NWaWV3ICYmICghaXNJbmZvV2luZG93T3BlbmVkIHx8IGlzQ2x1c3Rlckl0ZW1DaGFuZ2VkKSkge1xuICAgICAgdGhpcy5tYXBEYXRhLm1hcmtlcnMhLm1hcCgoaXRlbTogSU1hcE1hcmtlcnMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgY29uc3QgaXNTZWxlY3RlZE1hcmtlciA9IHRoaXMuY2hlY2tJbmZvV2luZG93UG9zaXRpb24oaXRlbSwgbWFya2VySXRlbSk7XG4gICAgICAgIGlmIChpc1NlbGVjdGVkTWFya2VyKSB7XG4gICAgICAgICAgaXRlbS5pY29uID0ge1xuICAgICAgICAgICAgLi4uaXRlbS5pY29uLFxuICAgICAgICAgICAgc2NhbGVkU2l6ZTogTWFwT3B0aW9uc0NvbnN0YW50cy5sYXJnZU1hcmtlclNpemUsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpdGVtLm9wdGlvbnMgPSB7IHpJbmRleDogOTk5IH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbS5pY29uID0ge1xuICAgICAgICAgICAgLi4uaXRlbS5pY29uLFxuICAgICAgICAgICAgc2NhbGVkU2l6ZTogTWFwT3B0aW9uc0NvbnN0YW50cy5kZWZhdWx0TWFya2VyU2l6ZSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGl0ZW0ub3B0aW9ucyA9IHsgekluZGV4OiBpbmRleCArIDEgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMuY3VycmVudGx5T3BlbldpbmRvdyA9IHRoaXMuaW5mb1dpbmRvd3NWaWV3O1xuICAgICAgdGhpcy5vcGVuZWRJbmZvV2luZG93RGF0YSA9IG1hcmtlckl0ZW07XG5cbiAgICAgIGlmICghaXNJbmZvV2luZG93T3BlbmVkKSB7XG4gICAgICAgIHRoaXMubWFwIS5wYW5UbyhtYXJrZXJJdGVtLnBvc2l0aW9uKTtcblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLmluZm9XaW5kb3dPcHRpb25zID0ge1xuICAgICAgICAgICAgLi4udGhpcy5pbmZvV2luZG93T3B0aW9ucyxcbiAgICAgICAgICAgIHBvc2l0aW9uOiBtYXJrZXJJdGVtLnBvc2l0aW9uLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5pbmZvV2luZG93c1ZpZXcub3BlbigpO1xuICAgICAgICB9LCAwKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY2hlY2tJbmZvV2luZG93UG9zaXRpb24oXG4gICAgbWFya2VySXRlbTogSU1hcE1hcmtlcnMsXG4gICAgbWFya2VySXRlbTI/OiBJTWFwTWFya2VycyB8IG51bGxcbiAgKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIG1hcmtlckl0ZW0ucG9zaXRpb24ubGF0ID09PSBtYXJrZXJJdGVtMj8ucG9zaXRpb24/LmxhdCAmJlxuICAgICAgbWFya2VySXRlbS5wb3NpdGlvbi5sbmcgPT09IG1hcmtlckl0ZW0yPy5wb3NpdGlvbj8ubG5nXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBjbG9zZUluZm9XaW5kb3coKTogdm9pZCB7XG4gICAgdGhpcy5yZXNldE1hcmtlcnNJY29ucygpO1xuXG4gICAgdGhpcy5vcGVuZWRJbmZvV2luZG93RGF0YSA9IG51bGw7XG4gICAgdGhpcy5jdXJyZW50bHlPcGVuV2luZG93ID0gbnVsbDtcbiAgICB0aGlzLmluZm9XaW5kb3dzVmlldy5jbG9zZSgpO1xuICAgIHRoaXMucmVzZXRTZWxlY3RlZE1hcmtlckl0ZW0uZW1pdCgpO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZU1hcERhdGEobmV3RGF0YTogSUNhTWFwUHJvcHMpOiB2b2lkIHtcbiAgICB0aGlzLm1hcERhdGEgPSB0aGlzLmdldE5ld0RhdGEobmV3RGF0YSk7XG5cbiAgICBpZiAodGhpcy5tYXBEYXRhLnNlbGVjdGVkTWFya2VyRGF0YSlcbiAgICAgIHRoaXMub3Blbk1hcmtlckluZm9XaW5kb3codGhpcy5tYXBEYXRhLnNlbGVjdGVkTWFya2VyRGF0YSk7XG4gICAgZWxzZSBpZiAodGhpcy5jdXJyZW50bHlPcGVuV2luZG93KSB0aGlzLmNsb3NlSW5mb1dpbmRvdygpO1xuXG4gICAgaWYgKG5ld0RhdGEgJiYgIXRoaXMuaXNNYXBDZW50ZXJTZXQgJiYgdGhpcy5tYXApIHtcbiAgICAgIGlmIChcbiAgICAgICAgbmV3RGF0YS5tYXJrZXJzPy5sZW5ndGggfHxcbiAgICAgICAgbmV3RGF0YS5jbHVzdGVyTWFya2Vycz8ubGVuZ3RoIHx8XG4gICAgICAgIG5ld0RhdGEucm91dGluZ01hcmtlcnM/Lmxlbmd0aFxuICAgICAgKVxuICAgICAgICB0aGlzLnNldE1hcFN0eWxlcygpO1xuICAgIH1cblxuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHVibGljIG9uQ2x1c3Rlckxpc3RTY3JvbGxUb0VuZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vcGVuZWRJbmZvV2luZG93RGF0YSlcbiAgICAgIHRoaXMuY2x1c3Rlckxpc3RTY3JvbGxFdmVudC5lbWl0KHRoaXMub3BlbmVkSW5mb1dpbmRvd0RhdGEpO1xuICB9XG5cbiAgcHVibGljIGNoZWNrQ2x1c3RlckRhdGFDaGFuZ2VzKFxuICAgIG5ld0RhdGE6IElNYXBNYXJrZXJzLFxuICAgIHByZXZpb3VzRGF0YT86IElNYXBNYXJrZXJzIHwgbnVsbFxuICApOiBib29sZWFuIHtcbiAgICByZXR1cm4gbmV3RGF0YS5pbmZvV2luZG93Q29udGVudD8uY2x1c3RlckRhdGFcbiAgICAgID8gbmV3RGF0YS5pbmZvV2luZG93Q29udGVudD8uc2VsZWN0ZWRDbHVzdGVySXRlbURhdGE/LmRhdGE/LmlkICE9PVxuICAgICAgICAgIHByZXZpb3VzRGF0YT8uaW5mb1dpbmRvd0NvbnRlbnQ/LnNlbGVjdGVkQ2x1c3Rlckl0ZW1EYXRhPy5kYXRhPy5pZCB8fFxuICAgICAgICAgIG5ld0RhdGEuaW5mb1dpbmRvd0NvbnRlbnQ/LmNsdXN0ZXJEYXRhPy5sZW5ndGggIT09XG4gICAgICAgICAgICBwcmV2aW91c0RhdGE/LmluZm9XaW5kb3dDb250ZW50Py5jbHVzdGVyRGF0YT8ubGVuZ3RoXG4gICAgICA6IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIHRyYWNrQnlJZChpbmRleDogbnVtYmVyLCBtYXJrZXI6IElNYXBNYXJrZXJzKTogbnVtYmVyIHtcbiAgICByZXR1cm4gbWFya2VyLmRhdGEuaWQ7XG4gIH1cblxuICBwdWJsaWMgdHJhY2tCeVBvc2l0aW9uKGluZGV4OiBudW1iZXIsIG1hcmtlcjogSU1hcE1hcmtlcnMpOiBudW1iZXIge1xuICAgIHJldHVybiBtYXJrZXIucG9zaXRpb24ubGF0ICsgbWFya2VyLnBvc2l0aW9uLmxuZztcbiAgfVxuXG4gIHB1YmxpYyBpZGVudGl0eShpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlcnMuZm9yRWFjaCgocmVuZGVyZXIpID0+IHJlbmRlcmVyLnNldE1hcChudWxsKSk7XG4gIH1cbn1cbiIsIjxnb29nbGUtbWFwXG4gIGhlaWdodD1cIjEwMCVcIlxuICB3aWR0aD1cIjEwMCVcIlxuICBbem9vbV09XCJtYXBab29tXCJcbiAgW2NlbnRlcl09XCJtYXBDZW50ZXJcIlxuICBbb3B0aW9uc109XCJtYXBPcHRpb25zXCJcbiAgKG1hcEluaXRpYWxpemVkKT1cIm9uTWFwUmVhZHkoJGV2ZW50KVwiXG4+XG4gIDxtYXAtbWFya2VyXG4gICAgI21hcmtlcj1cIm1hcE1hcmtlclwiXG4gICAgKm5nRm9yPVwibGV0IG1hcmtlcml0ZW0gb2YgbWFwRGF0YS5tYXJrZXJzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5SWRcIlxuICAgIFtwb3NpdGlvbl09XCJtYXJrZXJpdGVtLnBvc2l0aW9uXCJcbiAgICBbaWNvbl09XCJtYXJrZXJpdGVtLmljb24hXCJcbiAgICBbbGFiZWxdPVwiXG4gICAgICBvcGVuZWRJbmZvV2luZG93RGF0YT8ucG9zaXRpb24/LmxhdCA9PT0gbWFya2VyaXRlbT8ucG9zaXRpb24/LmxhdCAmJlxuICAgICAgb3BlbmVkSW5mb1dpbmRvd0RhdGE/LnBvc2l0aW9uPy5sbmcgPT09IG1hcmtlcml0ZW0/LnBvc2l0aW9uPy5sbmdcbiAgICAgICAgPyAnJ1xuICAgICAgICA6IG1hcmtlcml0ZW0ubGFiZWwhXG4gICAgXCJcbiAgICBbb3B0aW9uc109XCJtYXJrZXJpdGVtLm9wdGlvbnMhXCJcbiAgICAobWFwQ2xpY2spPVwib25NYXJrZXJDbGljayhtYXJrZXJpdGVtKVwiXG4gID5cbiAgPC9tYXAtbWFya2VyPlxuXG4gIDxtYXAtaW5mby13aW5kb3dcbiAgICAjaW5mb1dpbmRvd3NWaWV3PVwibWFwSW5mb1dpbmRvd1wiXG4gICAgW29wdGlvbnNdPVwiaW5mb1dpbmRvd09wdGlvbnNcIlxuICA+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm9wZW5lZEluZm9XaW5kb3dEYXRhICE9PSBudWxsXCI+XG4gICAgICA8YXBwLWNhLW1hcC1kcm9wZG93blxuICAgICAgICBbaW5mb1dpbmRvd0NvbnRlbnRdPVwib3BlbmVkSW5mb1dpbmRvd0RhdGEuaW5mb1dpbmRvd0NvbnRlbnRcIlxuICAgICAgICBbbWFya2VyRGF0YV09XCJvcGVuZWRJbmZvV2luZG93RGF0YS5kYXRhXCJcbiAgICAgICAgKG9uQ2x1c3Rlckl0ZW1DbGljayk9XCJnZXRNYXJrZXJJbmZvV2luZG93KCRldmVudClcIlxuICAgICAgICAob25DbHVzdGVyTGlzdFNjcm9sbFRvRW5kKT1cIm9uQ2x1c3Rlckxpc3RTY3JvbGxUb0VuZCgpXCJcbiAgICAgICAgKG9uQmFja0J1dHRvbkNsaWNrKT1cIm9uQ2x1c3RlckJhY2tCdXR0b25DbGljaygpXCJcbiAgICAgID48L2FwcC1jYS1tYXAtZHJvcGRvd24+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbWFwLWluZm8td2luZG93PlxuXG4gIDxtYXAtbWFya2VyXG4gICAgI21hcmtlckNsdXN0ZXI9XCJtYXBNYXJrZXJcIlxuICAgICpuZ0Zvcj1cIlxuICAgICAgbGV0IG1hcmtlciBvZiBtYXBEYXRhLmNsdXN0ZXJNYXJrZXJzO1xuICAgICAgbGV0IGkgPSBpbmRleDtcbiAgICAgIHRyYWNrQnk6IHRyYWNrQnlQb3NpdGlvblxuICAgIFwiXG4gICAgW3Bvc2l0aW9uXT1cIm1hcmtlci5wb3NpdGlvblwiXG4gICAgW2ljb25dPVwibWFya2VyLmljb25cIlxuICAgIChtYXBDbGljayk9XCJvbkNsdXN0ZXJNYXJrZXJDbGljayhtYXJrZXIpXCJcbiAgPlxuICA8L21hcC1tYXJrZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzQXJlYUZpbHRlckFjdGl2ZVwiPlxuICAgIDxtYXAtY2lyY2xlXG4gICAgICBbb3B0aW9uc109XCJhcmVhRmlsdGVyRGF0YS5vcHRpb25zXCJcbiAgICAgIFtjZW50ZXJdPVwiYXJlYUZpbHRlckRhdGEuY2VudGVyXCJcbiAgICAgIFtyYWRpdXNdPVwiYXJlYUZpbHRlckRhdGEucmFkaXVzXCJcbiAgICA+PC9tYXAtY2lyY2xlPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8bWFwLW1hcmtlclxuICAgICNtYXJrZXJSb3V0aW5nPVwibWFwTWFya2VyXCJcbiAgICAqbmdGb3I9XCJcbiAgICAgIGxldCBtYXJrZXJpdGVtIG9mIG1hcERhdGEucm91dGluZ01hcmtlcnM7XG4gICAgICBsZXQgaSA9IGluZGV4O1xuICAgICAgdHJhY2tCeTogaWRlbnRpdHlcbiAgICBcIlxuICAgIFtwb3NpdGlvbl09XCJtYXJrZXJpdGVtLnBvc2l0aW9uXCJcbiAgICBbaWNvbl09XCJtYXJrZXJpdGVtLmljb24hXCJcbiAgICBbbGFiZWxdPVwiZm9jdXNlZEljb25Sb3V0aW5nICE9PSBpID8gbWFya2VyaXRlbS5sYWJlbCEgOiAnJ1wiXG4gICAgW29wdGlvbnNdPVwibWFya2VyaXRlbS5vcHRpb25zIVwiXG4gICAgKG1hcENsaWNrKT1cIm9uUm91dGluZ01hcmtlckNsaWNrKGksICRldmVudCwgbWFya2VyaXRlbSlcIlxuICA+XG4gICAgPG1hcC1pbmZvLXdpbmRvdyAjaW5mb1dpbmRvd3NWaWV3Um91dGluZz1cIm1hcEluZm9XaW5kb3dcIj5cbiAgICAgIDxhcHAtY2EtbWFwLWRyb3Bkb3duPjwvYXBwLWNhLW1hcC1kcm9wZG93bj5cbiAgICA8L21hcC1pbmZvLXdpbmRvdz5cbiAgPC9tYXAtbWFya2VyPlxuPC9nb29nbGUtbWFwPlxuIl19