kwikid-agent-dashboard 0.0.21 → 0.0.23

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.
@@ -1,62 +1,162 @@
1
1
  import { __awaiter } from "tslib";
2
2
  import { Injectable, ViewChildren } from '@angular/core';
3
- import { map } from 'rxjs/operators';
3
+ import * as L from 'leaflet';
4
+ import 'leaflet-routing-machine';
5
+ import { checkObjectPathExists, getObjectValueFromPath } from 'kwikid-toolkit';
4
6
  import * as i0 from "@angular/core";
5
- import * as i1 from "@angular/google-maps";
7
+ import * as i1 from "./agent.service";
6
8
  export class MapService {
7
- constructor(mapDirectionsService) {
8
- this.mapDirectionsService = mapDirectionsService;
9
- this.markers = [];
10
- this.directionsRenderOption = {};
11
- }
12
- getMarkers() {
13
- return this.markers;
14
- }
15
- setMarkers(markers) {
16
- this.markers = markers;
9
+ constructor(agentService) {
10
+ this.agentService = agentService;
11
+ this.allMarkers = [];
17
12
  }
13
+ // To Initialize Map
18
14
  initMap() {
19
15
  return __awaiter(this, void 0, void 0, function* () {
20
16
  this.myPosition = yield this.getPosition();
21
- this.map = {
22
- zoom: 10,
23
- center: this.myPosition,
24
- streetViewControl: false,
25
- mapTypeControl: false,
26
- fullscreenControl: false,
27
- zoomControl: false
28
- };
17
+ this.map = L.map('map', {
18
+ center: [this.myPosition.lat, this.myPosition.lng],
19
+ zoom: 13
20
+ });
21
+ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);
29
22
  });
30
23
  }
31
- plotMarkers(customers) {
32
- this.markers = [];
33
- let path = [];
34
- this.markers.push(this.myPosition);
35
- const request = {
36
- origin: this.myPosition,
37
- destination: this.myPosition,
38
- waypoints: path,
39
- optimizeWaypoints: true,
40
- travelMode: google.maps.TravelMode.DRIVING
41
- };
42
- this.directionsRenderOption = {
43
- suppressMarkers: true
44
- };
45
- this.directionsResults$ = this.mapDirectionsService
46
- .route(request)
47
- .pipe(map((response) => response.result));
48
- this.directionsResults$.subscribe((val) => {
49
- customers = this.sortList(val.routes[0].waypoint_order, customers);
50
- customers.map((customer) => {
51
- path.push({
52
- location: this.getLatLng(customer.task_details.customer_details.location),
53
- stopover: true
54
- });
55
- this.markers.push(this.getLatLng(customer.task_details.customer_details.location));
24
+ // To Add Marker in Map
25
+ addMarker({ lat, lng, title, color }) {
26
+ L.marker([lat, lng], {
27
+ icon: L.icon({
28
+ iconUrl: color == 'red'
29
+ ? 'https://kwikid.s3.ap-south-1.amazonaws.com/CONFIG/USER/assets/map-marker-0.png'
30
+ : 'https://kwikid.s3.ap-south-1.amazonaws.com/CONFIG/USER/assets/map-marker-1.png'
31
+ })
32
+ })
33
+ .addTo(this.map)
34
+ .bindPopup(title);
35
+ }
36
+ // To Plot Directions for All Tasks
37
+ plotDirectionsForAllTasks(tasks) {
38
+ if (this.map) {
39
+ this.allMarkers = [];
40
+ // Create Agent Marker & Plot It.
41
+ const myMarker = {
42
+ lat: this.myPosition.lat,
43
+ lng: this.myPosition.lng,
44
+ title: 0,
45
+ color: 'red'
46
+ };
47
+ this.addMarker(myMarker);
48
+ this.allMarkers.push(myMarker);
49
+ // Create Markers for all Tasks
50
+ tasks.map((task, index) => {
51
+ const marker = this.getLatLng(this.getLocation(task), index);
52
+ this.allMarkers.push(marker);
56
53
  });
54
+ // Run Algorithm to get optimized Routes
55
+ const startingPoint = this.allMarkers[0];
56
+ const unvisitedWaypoints = this.allMarkers.slice(1);
57
+ const optimizedRoute = this.nearestNeighborAlgorithm(startingPoint, unvisitedWaypoints);
58
+ // Sort All Markers as per optimized routes
59
+ this.allMarkers = this.sortTasksAsPerDistance(optimizedRoute, this.allMarkers, true);
60
+ // Sort All Tasks as per optimized routes
61
+ tasks = this.sortTasksAsPerDistance(optimizedRoute.slice(1), tasks, false);
62
+ // Plot Markers for All Tasks
63
+ tasks.map((task, index) => {
64
+ const marker = this.getLatLng(this.getLocation(task), index);
65
+ this.addMarker(marker);
66
+ });
67
+ // Set Styles for all Task Routes
68
+ const styles = [
69
+ { color: 'blue', opacity: 1, weight: 8 },
70
+ { color: 'white', opacity: 0.6, weight: 12 }
71
+ ];
72
+ // Set Routes for all Tasks
73
+ this.allTasksRoutes = this.setRoutes(this.allMarkers, styles);
74
+ this.fitMapBounds();
75
+ }
76
+ return tasks;
77
+ }
78
+ // To plot Direction for selected Task
79
+ plotDirectionsForSelectedTask(index) {
80
+ if (index !== null) {
81
+ // Remove Previously Selected Task Route
82
+ if (this.selectedTaskRoutes) {
83
+ this.map.removeControl(this.selectedTaskRoutes);
84
+ }
85
+ // Remove All Tasks Routes
86
+ if (this.allTasksRoutes) {
87
+ this.map.removeControl(this.allTasksRoutes);
88
+ }
89
+ const taskMarker = this.allMarkers[index + 1];
90
+ // If Location is Available in Task Details
91
+ if (taskMarker.color != 'red') {
92
+ const markers = [this.allMarkers[0], taskMarker];
93
+ const styles = [
94
+ { color: 'green', opacity: 1, weight: 8 },
95
+ { color: 'white', opacity: 0.4, weight: 12 }
96
+ ];
97
+ this.selectedTaskRoutes = this.setRoutes(markers, styles);
98
+ this.setSelectedTaskDistanceAndTime();
99
+ }
100
+ else {
101
+ alert('No Location Available');
102
+ }
103
+ }
104
+ // Set All Tasks Routes Again & Remove Selected Tasks route
105
+ else {
106
+ if (this.selectedTaskRoutes) {
107
+ this.map.removeControl(this.selectedTaskRoutes);
108
+ }
109
+ this.map.addControl(this.allTasksRoutes);
110
+ this.selectedTaskRoutes = undefined;
111
+ }
112
+ this.fitMapBounds();
113
+ }
114
+ // Get Distance & Time of Selected Task
115
+ getSelectedTaskDistanceAndTime() {
116
+ return this.selectedTaskDistanceAndTime;
117
+ }
118
+ // Set Distance & Time of Selected Task
119
+ setSelectedTaskDistanceAndTime() {
120
+ this.selectedTaskRoutes.on('routesfound', function (e) {
121
+ let routes = e.routes;
122
+ let summary = routes[0].summary;
123
+ const distance = summary.totalDistance / 1000;
124
+ const time = Math.round((summary.totalTime % 3600) / 60);
125
+ this.selectedTaskDistanceAndTime = {
126
+ distance: distance,
127
+ time: time
128
+ };
57
129
  });
58
- return this.directionsResults$;
59
130
  }
131
+ // To sort Task as per nearest distance
132
+ sortTasksAsPerDistance(order, tasks, isMarker) {
133
+ let sortedTasks = [];
134
+ for (let i = 0; i < tasks.length; i++) {
135
+ const title = isMarker ? order[i].title : order[i].title - 1;
136
+ let task = tasks[title];
137
+ sortedTasks.push(task);
138
+ }
139
+ return sortedTasks;
140
+ }
141
+ // To set routes in the maps
142
+ setRoutes(markers, styles) {
143
+ return L.Routing.control({
144
+ waypoints: markers,
145
+ lineOptions: {
146
+ styles: styles
147
+ },
148
+ createMarker: function () {
149
+ return null;
150
+ },
151
+ routeWhileDragging: true
152
+ }).addTo(this.map);
153
+ }
154
+ // To set view point on the map
155
+ fitMapBounds() {
156
+ const markerLatLngs = this.allMarkers.map((marker) => L.latLng(marker.lat, marker.lng));
157
+ this.map.fitBounds(markerLatLngs);
158
+ }
159
+ // To get Current Position
60
160
  getPosition() {
61
161
  return new Promise((resolve, reject) => {
62
162
  navigator.geolocation.watchPosition((resp) => {
@@ -69,31 +169,86 @@ export class MapService {
69
169
  });
70
170
  });
71
171
  }
72
- getLatLng(data) {
73
- let url = data.split('@');
74
- let lat_long_match = url[1].split(',');
75
- let lat = Number(lat_long_match[0]);
76
- let long = Number(lat_long_match[1]);
77
- return { lat: lat, lng: long };
172
+ // To extract Location from the Task Details
173
+ getLocation(task) {
174
+ var _a, _b, _c, _d, _e, _f;
175
+ if (checkObjectPathExists(this.agentService.config, 'dashboard.taskLocationPath')) {
176
+ const location = getObjectValueFromPath(task, this.agentService.config.dashboard.taskLocationPath);
177
+ return location;
178
+ }
179
+ else {
180
+ return ((_d = (_c = (_b = (_a = task === null || task === void 0 ? void 0 : task.extras) === null || _a === void 0 ? void 0 : _a.task_details) === null || _b === void 0 ? void 0 : _b.customer_details) === null || _c === void 0 ? void 0 : _c.location) !== null && _d !== void 0 ? _d : (_f = (_e = task === null || task === void 0 ? void 0 : task.task_details) === null || _e === void 0 ? void 0 : _e.customer_details) === null || _f === void 0 ? void 0 : _f.location);
181
+ }
182
+ }
183
+ // To get Latitude & Longitude from Task Location
184
+ getLatLng(data, index) {
185
+ try {
186
+ const url = data.split('@');
187
+ const lat_long_match = url[1].split(',');
188
+ const lat = Number(lat_long_match[0]);
189
+ const long = Number(lat_long_match[1]);
190
+ return { lat: lat, lng: long, title: index + 1, color: 'blue' };
191
+ }
192
+ catch (_a) {
193
+ // If could not find Google Maps Location URL in Task
194
+ return {
195
+ lat: this.myPosition.lat,
196
+ lng: this.myPosition.lng,
197
+ title: index + 1,
198
+ color: 'red'
199
+ };
200
+ }
201
+ }
202
+ // To Calculate Distance between two markers
203
+ calculateDistance(point1, point2) {
204
+ const lat1 = point1.lat;
205
+ const lng1 = point1.lng;
206
+ const lat2 = point2.lat;
207
+ const lng2 = point2.lng;
208
+ const R = 6371; // Earth radius in kilometers
209
+ const dLat = (lat2 - lat1) * (Math.PI / 180);
210
+ const dLng = (lng2 - lng1) * (Math.PI / 180);
211
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
212
+ Math.cos((lat1 * Math.PI) / 180) *
213
+ Math.cos((lat2 * Math.PI) / 180) *
214
+ Math.sin(dLng / 2) *
215
+ Math.sin(dLng / 2);
216
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
217
+ const distance = R * c;
218
+ return distance;
78
219
  }
79
- sortList(order, customersData) {
80
- let c = [];
81
- for (let i = 0; i < customersData.length; i++) {
82
- let customer = customersData[order[i]];
83
- c.push(customer);
220
+ // To calculate nearest distance from marker
221
+ nearestNeighborAlgorithm(startingPoint, unvisitedPoints) {
222
+ let currentPoint = startingPoint;
223
+ const path = [currentPoint];
224
+ const visitedPoints = new Set([currentPoint]);
225
+ while (unvisitedPoints.length > 0) {
226
+ let nearestPoint = null;
227
+ let minDistance = Number.POSITIVE_INFINITY;
228
+ for (const point of unvisitedPoints) {
229
+ const distance = this.calculateDistance(currentPoint, point);
230
+ if (distance < minDistance) {
231
+ minDistance = distance;
232
+ nearestPoint = point;
233
+ }
234
+ }
235
+ path.push(nearestPoint);
236
+ visitedPoints.add(nearestPoint);
237
+ currentPoint = nearestPoint;
238
+ unvisitedPoints = unvisitedPoints.filter((point) => !visitedPoints.has(point));
84
239
  }
85
- return c;
240
+ return path;
86
241
  }
87
242
  }
88
- /** @nocollapse */ MapService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: MapService, deps: [{ token: i1.MapDirectionsService }], target: i0.ɵɵFactoryTarget.Injectable });
243
+ /** @nocollapse */ MapService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: MapService, deps: [{ token: i1.AgentService }], target: i0.ɵɵFactoryTarget.Injectable });
89
244
  /** @nocollapse */ MapService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: MapService, providedIn: 'root' });
90
245
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: MapService, decorators: [{
91
246
  type: Injectable,
92
247
  args: [{
93
248
  providedIn: 'root'
94
249
  }]
95
- }], ctorParameters: function () { return [{ type: i1.MapDirectionsService }]; }, propDecorators: { directionsRenders: [{
250
+ }], ctorParameters: function () { return [{ type: i1.AgentService }]; }, propDecorators: { directionsRenders: [{
96
251
  type: ViewChildren,
97
252
  args: ['directionsRender']
98
253
  }] } });
99
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lraWQtYWdlbnQtZGFzaGJvYXJkL3NyYy9saWIvc2VydmljZXMvbWFwLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBYyxVQUFVLEVBQWEsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRWhGLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBU3JDLE1BQU0sT0FBTyxVQUFVO0lBYXJCLFlBQW1CLG9CQUEwQztRQUExQyx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBVDdELFlBQU8sR0FBUSxFQUFFLENBQUM7UUFHbEIsMkJBQXNCLEdBQUcsRUFBRSxDQUFDO0lBTW9DLENBQUM7SUFFakUsVUFBVTtRQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRUQsVUFBVSxDQUFDLE9BQU87UUFDaEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVLLE9BQU87O1lBQ1gsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUUzQyxJQUFJLENBQUMsR0FBRyxHQUFHO2dCQUNULElBQUksRUFBRSxFQUFFO2dCQUNSLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVTtnQkFDdkIsaUJBQWlCLEVBQUUsS0FBSztnQkFDeEIsY0FBYyxFQUFFLEtBQUs7Z0JBQ3JCLGlCQUFpQixFQUFFLEtBQUs7Z0JBQ3hCLFdBQVcsRUFBRSxLQUFLO2FBQ25CLENBQUM7UUFDSixDQUFDO0tBQUE7SUFFRCxXQUFXLENBQUMsU0FBUztRQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNsQixJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7UUFFZCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUks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QUM3QyxJQUFJLFFBQVEsR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUNsQjtRQUVELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQzs7MkhBN0dVLFVBQVU7K0hBQVYsVUFBVSxjQUZULE1BQU07NEZBRVAsVUFBVTtrQkFIdEIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7MkdBVW1DLGlCQUFpQjtzQkFBbEQsWUFBWTt1QkFBQyxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbGVtZW50UmVmLCBJbmplY3RhYmxlLCBRdWVyeUxpc3QsIFZpZXdDaGlsZHJlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgbG9nTWV0aG9kIH0gZnJvbSAna3dpa2lkLXRvb2xraXQnO1xuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBNYXBEaXJlY3Rpb25zU2VydmljZSB9IGZyb20gJ0Bhbmd1bGFyL2dvb2dsZS1tYXBzJztcblxuZGVjbGFyZSBjb25zdCBnb29nbGU6IGFueTtcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTWFwU2VydmljZSB7XG4gIG15UG9zaXRpb247XG4gIG1hcDogYW55O1xuXG4gIG1hcmtlcnM6IGFueSA9IFtdO1xuXG4gIGRpcmVjdGlvbnNSZXN1bHRzJDtcbiAgZGlyZWN0aW9uc1JlbmRlck9wdGlvbiA9IHt9O1xuXG4gIEBWaWV3Q2hpbGRyZW4oJ2RpcmVjdGlvbnNSZW5kZXInKSBkaXJlY3Rpb25zUmVuZGVyczogUXVlcnlMaXN0PFxuICAgIEVsZW1lbnRSZWY8Z29vZ2xlLm1hcHMuRGlyZWN0aW9uc1JlbmRlcmVyPlxuICA+O1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBtYXBEaXJlY3Rpb25zU2VydmljZTogTWFwRGlyZWN0aW9uc1NlcnZpY2UpIHt9XG5cbiAgZ2V0TWFya2VycygpIHtcbiAgICByZXR1cm4gdGhpcy5tYXJrZXJzO1xuICB9XG5cbiAgc2V0TWFya2VycyhtYXJrZXJzKSB7XG4gICAgdGhpcy5tYXJrZXJzID0gbWFya2VycztcbiAgfVxuXG4gIGFzeW5jIGluaXRNYXAoKSB7XG4gICAgdGhpcy5teVBvc2l0aW9uID0gYXdhaXQgdGhpcy5nZXRQb3NpdGlvbigpO1xuXG4gICAgdGhpcy5tYXAgPSB7XG4gICAgICB6b29tOiAxMCxcbiAgICAgIGNlbnRlcjogdGhpcy5teVBvc2l0aW9uLFxuICAgICAgc3RyZWV0Vmlld0NvbnRyb2w6IGZhbHNlLFxuICAgICAgbWFwVHlwZUNvbnRyb2w6IGZhbHNlLFxuICAgICAgZnVsbHNjcmVlbkNvbnRyb2w6IGZhbHNlLFxuICAgICAgem9vbUNvbnRyb2w6IGZhbHNlXG4gICAgfTtcbiAgfVxuXG4gIHBsb3RNYXJrZXJzKGN1c3RvbWVycykge1xuICAgIHRoaXMubWFya2VycyA9IFtdO1xuICAgIGxldCBwYXRoID0gW107XG5cbiAgICB0aGlzLm1hcmtlcnMucHVzaCh0aGlzLm15UG9zaXRpb24pO1xuXG4gICAgY29uc3QgcmVxdWVzdDogZ29vZ2xlLm1hcHMuRGlyZWN0aW9uc1JlcXVlc3QgPSB7XG4gICAgICBvcmlnaW46IHRoaXMubXlQb3NpdGlvbixcbiAgICAgIGRlc3RpbmF0aW9uOiB0aGlzLm15UG9zaXRpb24sXG4gICAgICB3YXlwb2ludHM6IHBhdGgsXG4gICAgICBvcHRpbWl6ZVdheXBvaW50czogdHJ1ZSxcbiAgICAgIHRyYXZlbE1vZGU6IGdvb2dsZS5tYXBzLlRyYXZlbE1vZGUuRFJJVklOR1xuICAgIH07XG5cbiAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJPcHRpb24gPSB7XG4gICAgICBzdXBwcmVzc01hcmtlcnM6IHRydWVcbiAgICB9O1xuXG4gICAgdGhpcy5kaXJlY3Rpb25zUmVzdWx0cyQgPSB0aGlzLm1hcERpcmVjdGlvbnNTZXJ2aWNlXG4gICAgICAucm91dGUocmVxdWVzdClcbiAgICAgIC5waXBlKG1hcCgocmVzcG9uc2UpID0+IHJlc3BvbnNlLnJlc3VsdCkpO1xuXG4gICAgdGhpcy5kaXJlY3Rpb25zUmVzdWx0cyQuc3Vic2NyaWJlKCh2YWwpID0+IHtcbiAgICAgIGN1c3RvbWVycyA9IHRoaXMuc29ydExpc3QodmFsLnJvdXRlc1swXS53YXlwb2ludF9vcmRlciwgY3VzdG9tZXJzKTtcbiAgICAgIGN1c3RvbWVycy5tYXAoKGN1c3RvbWVyKSA9PiB7XG4gICAgICAgIHBhdGgucHVzaCh7XG4gICAgICAgICAgbG9jYXRpb246IHRoaXMuZ2V0TGF0TG5nKFxuICAgICAgICAgICAgY3VzdG9tZXIudGFza19kZXRhaWxzLmN1c3RvbWVyX2RldGFpbHMubG9jYXRpb25cbiAgICAgICAgICApLFxuICAgICAgICAgIHN0b3BvdmVyOiB0cnVlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubWFya2Vycy5wdXNoKFxuICAgICAgICAgIHRoaXMuZ2V0TGF0TG5nKGN1c3RvbWVyLnRhc2tfZGV0YWlscy5jdXN0b21lcl9kZXRhaWxzLmxvY2F0aW9uKVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5kaXJlY3Rpb25zUmVzdWx0cyQ7XG4gIH1cblxuICBnZXRQb3NpdGlvbigpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IuZ2VvbG9jYXRpb24ud2F0Y2hQb3NpdGlvbihcbiAgICAgICAgKHJlc3ApID0+IHtcbiAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgIGxuZzogcmVzcC5jb29yZHMubG9uZ2l0dWRlLFxuICAgICAgICAgICAgbGF0OiByZXNwLmNvb3Jkcy5sYXRpdHVkZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRMYXRMbmcoZGF0YSkge1xuICAgIGxldCB1cmwgPSBkYXRhLnNwbGl0KCdAJyk7XG4gICAgbGV0IGxhdF9sb25nX21hdGNoID0gdXJsWzFdLnNwbGl0KCcsJyk7XG4gICAgbGV0IGxhdCA9IE51bWJlcihsYXRfbG9uZ19tYXRjaFswXSk7XG4gICAgbGV0IGxvbmcgPSBOdW1iZXIobGF0X2xvbmdfbWF0Y2hbMV0pO1xuICAgIHJldHVybiB7IGxhdDogbGF0LCBsbmc6IGxvbmcgfTtcbiAgfVxuXG4gIHNvcnRMaXN0KG9yZGVyLCBjdXN0b21lcnNEYXRhKSB7XG4gICAgbGV0IGMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1c3RvbWVyc0RhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBjdXN0b21lciA9IGN1c3RvbWVyc0RhdGFbb3JkZXJbaV1dO1xuICAgICAgYy5wdXNoKGN1c3RvbWVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYztcbiAgfVxufVxuIl19
254
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lraWQtYWdlbnQtZGFzaGJvYXJkL3NyYy9saWIvc2VydmljZXMvbWFwLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBYyxVQUFVLEVBQWEsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hGLE9BQU8sS0FBSyxDQUFDLE1BQU0sU0FBUyxDQUFDO0FBQzdCLE9BQU8seUJBQXlCLENBQUM7QUFFakMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQUsvRSxNQUFNLE9BQU8sVUFBVTtJQWFyQixZQUFvQixZQUEwQjtRQUExQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQVY5QyxlQUFVLEdBQVEsRUFBRSxDQUFDO0lBVTRCLENBQUM7SUFFbEQsb0JBQW9CO0lBQ2QsT0FBTzs7WUFDWCxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzNDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUU7Z0JBQ3RCLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO2dCQUNsRCxJQUFJLEVBQUUsRUFBRTthQUNULENBQUMsQ0FBQztZQUNILENBQUMsQ0FBQyxTQUFTLENBQUMsb0RBQW9ELENBQUMsQ0FBQyxLQUFLLENBQ3JFLElBQUksQ0FBQyxHQUFHLENBQ1QsQ0FBQztRQUNKLENBQUM7S0FBQTtJQUVELHVCQUF1QjtJQUN2QixTQUFTLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7UUFDbEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFB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QUcsV0FBVyxFQUFFO29CQUMxQixXQUFXLEdBQUcsUUFBUSxDQUFDO29CQUN2QixZQUFZLEdBQUcsS0FBSyxDQUFDO2lCQUN0QjthQUNGO1lBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN4QixhQUFhLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2hDLFlBQVksR0FBRyxZQUFZLENBQUM7WUFFNUIsZUFBZSxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQ3RDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQ3JDLENBQUM7U0FDSDtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQzs7MkhBL1NVLFVBQVU7K0hBQVYsVUFBVSxjQUZULE1BQU07NEZBRVAsVUFBVTtrQkFIdEIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7bUdBVW1DLGlCQUFpQjtzQkFBbEQsWUFBWTt1QkFBQyxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbGVtZW50UmVmLCBJbmplY3RhYmxlLCBRdWVyeUxpc3QsIFZpZXdDaGlsZHJlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgTCBmcm9tICdsZWFmbGV0JztcbmltcG9ydCAnbGVhZmxldC1yb3V0aW5nLW1hY2hpbmUnO1xuaW1wb3J0IHsgQWdlbnRTZXJ2aWNlIH0gZnJvbSAnLi9hZ2VudC5zZXJ2aWNlJztcbmltcG9ydCB7IGNoZWNrT2JqZWN0UGF0aEV4aXN0cywgZ2V0T2JqZWN0VmFsdWVGcm9tUGF0aCB9IGZyb20gJ2t3aWtpZC10b29sa2l0JztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgTWFwU2VydmljZSB7XG4gIG15UG9zaXRpb247XG4gIG1hcDogYW55O1xuICBhbGxNYXJrZXJzOiBhbnkgPSBbXTtcblxuICBhbGxUYXNrc1JvdXRlczogYW55O1xuICBzZWxlY3RlZFRhc2tSb3V0ZXM6IGFueTtcbiAgc2VsZWN0ZWRUYXNrRGlzdGFuY2VBbmRUaW1lOiBhbnk7XG5cbiAgQFZpZXdDaGlsZHJlbignZGlyZWN0aW9uc1JlbmRlcicpIGRpcmVjdGlvbnNSZW5kZXJzOiBRdWVyeUxpc3Q8XG4gICAgRWxlbWVudFJlZjxnb29nbGUubWFwcy5EaXJlY3Rpb25zUmVuZGVyZXI+XG4gID47XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBhZ2VudFNlcnZpY2U6IEFnZW50U2VydmljZSkge31cblxuICAvLyBUbyBJbml0aWFsaXplIE1hcFxuICBhc3luYyBpbml0TWFwKCkge1xuICAgIHRoaXMubXlQb3NpdGlvbiA9IGF3YWl0IHRoaXMuZ2V0UG9zaXRpb24oKTtcbiAgICB0aGlzLm1hcCA9IEwubWFwKCdtYXAnLCB7XG4gICAgICBjZW50ZXI6IFt0aGlzLm15UG9zaXRpb24ubGF0LCB0aGlzLm15UG9zaXRpb24ubG5nXSxcbiAgICAgIHpvb206IDEzXG4gICAgfSk7XG4gICAgTC50aWxlTGF5ZXIoJ2h0dHBzOi8ve3N9LnRpbGUub3BlbnN0cmVldG1hcC5vcmcve3p9L3t4fS97eX0ucG5nJykuYWRkVG8oXG4gICAgICB0aGlzLm1hcFxuICAgICk7XG4gIH1cblxuICAvLyBUbyBBZGQgTWFya2VyIGluIE1hcFxuICBhZGRNYXJrZXIoeyBsYXQsIGxuZywgdGl0bGUsIGNvbG9yIH0pIHtcbiAgICBMLm1hcmtlcihbbGF0LCBsbmddLCB7XG4gICAgICBpY29uOiBMLmljb24oe1xuICAgICAgICBpY29uVXJsOlxuICAgICAgICAgIGNvbG9yID09ICdyZWQnXG4gICAgICAgICAgICA/ICdodHRwczovL2t3aWtpZC5zMy5hcC1zb3V0aC0xLmFtYXpvbmF3cy5jb20vQ09ORklHL1VTRVIvYXNzZXRzL21hcC1tYXJrZXItMC5wbmcnXG4gICAgICAgICAgICA6ICdodHRwczovL2t3aWtpZC5zMy5hcC1zb3V0aC0xLmFtYXpvbmF3cy5jb20vQ09ORklHL1VTRVIvYXNzZXRzL21hcC1tYXJrZXItMS5wbmcnXG4gICAgICB9KVxuICAgIH0pXG4gICAgICAuYWRkVG8odGhpcy5tYXApXG4gICAgICAuYmluZFBvcHVwKHRpdGxlKTtcbiAgfVxuXG4gIC8vIFRvIFBsb3QgRGlyZWN0aW9ucyBmb3IgQWxsIFRhc2tzXG4gIHBsb3REaXJlY3Rpb25zRm9yQWxsVGFza3ModGFza3MpIHtcbiAgICBpZiAodGhpcy5tYXApIHtcbiAgICAgIHRoaXMuYWxsTWFya2VycyA9IFtdO1xuXG4gICAgICAvLyBDcmVhdGUgQWdlbnQgTWFya2VyICYgUGxvdCBJdC5cbiAgICAgIGNvbnN0IG15TWFya2VyID0ge1xuICAgICAgICBsYXQ6IHRoaXMubXlQb3NpdGlvbi5sYXQsXG4gICAgICAgIGxuZzogdGhpcy5teVBvc2l0aW9uLmxuZyxcbiAgICAgICAgdGl0bGU6IDAsXG4gICAgICAgIGNvbG9yOiAncmVkJ1xuICAgICAgfTtcbiAgICAgIHRoaXMuYWRkTWFya2VyKG15TWFya2VyKTtcbiAgICAgIHRoaXMuYWxsTWFya2Vycy5wdXNoKG15TWFya2VyKTtcblxuICAgICAgLy8gQ3JlYXRlIE1hcmtlcnMgZm9yIGFsbCBUYXNrc1xuICAgICAgdGFza3MubWFwKCh0YXNrLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBtYXJrZXIgPSB0aGlzLmdldExhdExuZyh0aGlzLmdldExvY2F0aW9uKHRhc2spLCBpbmRleCk7XG4gICAgICAgIHRoaXMuYWxsTWFya2Vycy5wdXNoKG1hcmtlcik7XG4gICAgICB9KTtcblxuICAgICAgLy8gUnVuIEFsZ29yaXRobSB0byBnZXQgb3B0aW1pemVkIFJvdXRlc1xuICAgICAgY29uc3Qgc3RhcnRpbmdQb2ludCA9IHRoaXMuYWxsTWFya2Vyc1swXTtcbiAgICAgIGNvbnN0IHVudmlzaXRlZFdheXBvaW50cyA9IHRoaXMuYWxsTWFya2Vycy5zbGljZSgxKTtcbiAgICAgIGNvbnN0IG9wdGltaXplZFJvdXRlID0gdGhpcy5uZWFyZXN0TmVpZ2hib3JBbGdvcml0aG0oXG4gICAgICAgIHN0YXJ0aW5nUG9pbnQsXG4gICAgICAgIHVudmlzaXRlZFdheXBvaW50c1xuICAgICAgKTtcblxuICAgICAgLy8gU29ydCBBbGwgTWFya2VycyBhcyBwZXIgb3B0aW1pemVkIHJvdXRlc1xuICAgICAgdGhpcy5hbGxNYXJrZXJzID0gdGhpcy5zb3J0VGFza3NBc1BlckRpc3RhbmNlKFxuICAgICAgICBvcHRpbWl6ZWRSb3V0ZSxcbiAgICAgICAgdGhpcy5hbGxNYXJrZXJzLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuXG4gICAgICAvLyBTb3J0IEFsbCBUYXNrcyBhcyBwZXIgb3B0aW1pemVkIHJvdXRlc1xuICAgICAgdGFza3MgPSB0aGlzLnNvcnRUYXNrc0FzUGVyRGlzdGFuY2UoXG4gICAgICAgIG9wdGltaXplZFJvdXRlLnNsaWNlKDEpLFxuICAgICAgICB0YXNrcyxcbiAgICAgICAgZmFsc2VcbiAgICAgICk7XG5cbiAgICAgIC8vIFBsb3QgTWFya2VycyBmb3IgQWxsIFRhc2tzXG4gICAgICB0YXNrcy5tYXAoKHRhc2ssIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IG1hcmtlciA9IHRoaXMuZ2V0TGF0TG5nKHRoaXMuZ2V0TG9jYXRpb24odGFzayksIGluZGV4KTtcbiAgICAgICAgdGhpcy5hZGRNYXJrZXIobWFya2VyKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTZXQgU3R5bGVzIGZvciBhbGwgVGFzayBSb3V0ZXNcbiAgICAgIGNvbnN0IHN0eWxlcyA9IFtcbiAgICAgICAgeyBjb2xvcjogJ2JsdWUnLCBvcGFjaXR5OiAxLCB3ZWlnaHQ6IDggfSxcbiAgICAgICAgeyBjb2xvcjogJ3doaXRlJywgb3BhY2l0eTogMC42LCB3ZWlnaHQ6IDEyIH1cbiAgICAgIF07XG5cbiAgICAgIC8vIFNldCBSb3V0ZXMgZm9yIGFsbCBUYXNrc1xuICAgICAgdGhpcy5hbGxUYXNrc1JvdXRlcyA9IHRoaXMuc2V0Um91dGVzKHRoaXMuYWxsTWFya2Vycywgc3R5bGVzKTtcbiAgICAgIHRoaXMuZml0TWFwQm91bmRzKCk7XG4gICAgfVxuICAgIHJldHVybiB0YXNrcztcbiAgfVxuXG4gIC8vIFRvIHBsb3QgRGlyZWN0aW9uIGZvciBzZWxlY3RlZCBUYXNrXG4gIHBsb3REaXJlY3Rpb25zRm9yU2VsZWN0ZWRUYXNrKGluZGV4KSB7XG4gICAgaWYgKGluZGV4ICE9PSBudWxsKSB7XG4gICAgICAvLyBSZW1vdmUgUHJldmlvdXNseSBTZWxlY3RlZCBUYXNrIFJvdXRlXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZFRhc2tSb3V0ZXMpIHtcbiAgICAgICAgdGhpcy5tYXAucmVtb3ZlQ29udHJvbCh0aGlzLnNlbGVjdGVkVGFza1JvdXRlcyk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbW92ZSBBbGwgVGFza3MgUm91dGVzXG4gICAgICBpZiAodGhpcy5hbGxUYXNrc1JvdXRlcykge1xuICAgICAgICB0aGlzLm1hcC5yZW1vdmVDb250cm9sKHRoaXMuYWxsVGFza3NSb3V0ZXMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0YXNrTWFya2VyID0gdGhpcy5hbGxNYXJrZXJzW2luZGV4ICsgMV07XG5cbiAgICAgIC8vIElmIExvY2F0aW9uIGlzIEF2YWlsYWJsZSBpbiBUYXNrIERldGFpbHNcbiAgICAgIGlmICh0YXNrTWFya2VyLmNvbG9yICE9ICdyZWQnKSB7XG4gICAgICAgIGNvbnN0IG1hcmtlcnMgPSBbdGhpcy5hbGxNYXJrZXJzWzBdLCB0YXNrTWFya2VyXTtcbiAgICAgICAgY29uc3Qgc3R5bGVzID0gW1xuICAgICAgICAgIHsgY29sb3I6ICdncmVlbicsIG9wYWNpdHk6IDEsIHdlaWdodDogOCB9LFxuICAgICAgICAgIHsgY29sb3I6ICd3aGl0ZScsIG9wYWNpdHk6IDAuNCwgd2VpZ2h0OiAxMiB9XG4gICAgICAgIF07XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYXNrUm91dGVzID0gdGhpcy5zZXRSb3V0ZXMobWFya2Vycywgc3R5bGVzKTtcbiAgICAgICAgdGhpcy5zZXRTZWxlY3RlZFRhc2tEaXN0YW5jZUFuZFRpbWUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsZXJ0KCdObyBMb2NhdGlvbiBBdmFpbGFibGUnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gU2V0IEFsbCBUYXNrcyBSb3V0ZXMgQWdhaW4gJiBSZW1vdmUgU2VsZWN0ZWQgVGFza3Mgcm91dGVcbiAgICBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkVGFza1JvdXRlcykge1xuICAgICAgICB0aGlzLm1hcC5yZW1vdmVDb250cm9sKHRoaXMuc2VsZWN0ZWRUYXNrUm91dGVzKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWFwLmFkZENvbnRyb2wodGhpcy5hbGxUYXNrc1JvdXRlcyk7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFza1JvdXRlcyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5maXRNYXBCb3VuZHMoKTtcbiAgfVxuXG4gIC8vIEdldCBEaXN0YW5jZSAmIFRpbWUgb2YgU2VsZWN0ZWQgVGFza1xuICBnZXRTZWxlY3RlZFRhc2tEaXN0YW5jZUFuZFRpbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRUYXNrRGlzdGFuY2VBbmRUaW1lO1xuICB9XG5cbiAgLy8gU2V0IERpc3RhbmNlICYgVGltZSBvZiBTZWxlY3RlZCBUYXNrXG4gIHNldFNlbGVjdGVkVGFza0Rpc3RhbmNlQW5kVGltZSgpIHtcbiAgICB0aGlzLnNlbGVjdGVkVGFza1JvdXRlcy5vbigncm91dGVzZm91bmQnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgbGV0IHJvdXRlcyA9IGUucm91dGVzO1xuICAgICAgbGV0IHN1bW1hcnkgPSByb3V0ZXNbMF0uc3VtbWFyeTtcblxuICAgICAgY29uc3QgZGlzdGFuY2UgPSBzdW1tYXJ5LnRvdGFsRGlzdGFuY2UgLyAxMDAwO1xuICAgICAgY29uc3QgdGltZSA9IE1hdGgucm91bmQoKHN1bW1hcnkudG90YWxUaW1lICUgMzYwMCkgLyA2MCk7XG5cbiAgICAgIHRoaXMuc2VsZWN0ZWRUYXNrRGlzdGFuY2VBbmRUaW1lID0ge1xuICAgICAgICBkaXN0YW5jZTogZGlzdGFuY2UsXG4gICAgICAgIHRpbWU6IHRpbWVcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICAvLyBUbyBzb3J0IFRhc2sgYXMgcGVyIG5lYXJlc3QgZGlzdGFuY2VcbiAgc29ydFRhc2tzQXNQZXJEaXN0YW5jZShvcmRlciwgdGFza3MsIGlzTWFya2VyKSB7XG4gICAgbGV0IHNvcnRlZFRhc2tzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdGl0bGUgPSBpc01hcmtlciA/IG9yZGVyW2ldLnRpdGxlIDogb3JkZXJbaV0udGl0bGUgLSAxO1xuICAgICAgbGV0IHRhc2sgPSB0YXNrc1t0aXRsZV07XG4gICAgICBzb3J0ZWRUYXNrcy5wdXNoKHRhc2spO1xuICAgIH1cbiAgICByZXR1cm4gc29ydGVkVGFza3M7XG4gIH1cblxuICAvLyBUbyBzZXQgcm91dGVzIGluIHRoZSBtYXBzXG4gIHNldFJvdXRlcyhtYXJrZXJzLCBzdHlsZXMpIHtcbiAgICByZXR1cm4gTC5Sb3V0aW5nLmNvbnRyb2woe1xuICAgICAgd2F5cG9pbnRzOiBtYXJrZXJzLFxuICAgICAgbGluZU9wdGlvbnM6IHtcbiAgICAgICAgc3R5bGVzOiBzdHlsZXNcbiAgICAgIH0sXG4gICAgICBjcmVhdGVNYXJrZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9LFxuICAgICAgcm91dGVXaGlsZURyYWdnaW5nOiB0cnVlXG4gICAgfSkuYWRkVG8odGhpcy5tYXApO1xuICB9XG5cbiAgLy8gVG8gc2V0IHZpZXcgcG9pbnQgb24gdGhlIG1hcFxuICBmaXRNYXBCb3VuZHMoKSB7XG4gICAgY29uc3QgbWFya2VyTGF0TG5ncyA9IHRoaXMuYWxsTWFya2Vycy5tYXAoKG1hcmtlcikgPT5cbiAgICAgIEwubGF0TG5nKG1hcmtlci5sYXQsIG1hcmtlci5sbmcpXG4gICAgKTtcbiAgICB0aGlzLm1hcC5maXRCb3VuZHMobWFya2VyTGF0TG5ncyk7XG4gIH1cblxuICAvLyBUbyBnZXQgQ3VycmVudCBQb3NpdGlvblxuICBnZXRQb3NpdGlvbigpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBuYXZpZ2F0b3IuZ2VvbG9jYXRpb24ud2F0Y2hQb3NpdGlvbihcbiAgICAgICAgKHJlc3ApID0+IHtcbiAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgIGxuZzogcmVzcC5jb29yZHMubG9uZ2l0dWRlLFxuICAgICAgICAgICAgbGF0OiByZXNwLmNvb3Jkcy5sYXRpdHVkZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBUbyBleHRyYWN0IExvY2F0aW9uIGZyb20gdGhlIFRhc2sgRGV0YWlsc1xuICBnZXRMb2NhdGlvbih0YXNrKSB7XG4gICAgaWYgKFxuICAgICAgY2hlY2tPYmplY3RQYXRoRXhpc3RzKFxuICAgICAgICB0aGlzLmFnZW50U2VydmljZS5jb25maWcsXG4gICAgICAgICdkYXNoYm9hcmQudGFza0xvY2F0aW9uUGF0aCdcbiAgICAgIClcbiAgICApIHtcbiAgICAgIGNvbnN0IGxvY2F0aW9uID0gZ2V0T2JqZWN0VmFsdWVGcm9tUGF0aChcbiAgICAgICAgdGFzayxcbiAgICAgICAgdGhpcy5hZ2VudFNlcnZpY2UuY29uZmlnLmRhc2hib2FyZC50YXNrTG9jYXRpb25QYXRoXG4gICAgICApO1xuICAgICAgcmV0dXJuIGxvY2F0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICB0YXNrPy5leHRyYXM/LnRhc2tfZGV0YWlscz8uY3VzdG9tZXJfZGV0YWlscz8ubG9jYXRpb24gPz9cbiAgICAgICAgdGFzaz8udGFza19kZXRhaWxzPy5jdXN0b21lcl9kZXRhaWxzPy5sb2NhdGlvblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBUbyBnZXQgTGF0aXR1ZGUgJiBMb25naXR1ZGUgZnJvbSBUYXNrIExvY2F0aW9uXG4gIGdldExhdExuZyhkYXRhLCBpbmRleCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB1cmwgPSBkYXRhLnNwbGl0KCdAJyk7XG4gICAgICBjb25zdCBsYXRfbG9uZ19tYXRjaCA9IHVybFsxXS5zcGxpdCgnLCcpO1xuICAgICAgY29uc3QgbGF0ID0gTnVtYmVyKGxhdF9sb25nX21hdGNoWzBdKTtcbiAgICAgIGNvbnN0IGxvbmcgPSBOdW1iZXIobGF0X2xvbmdfbWF0Y2hbMV0pO1xuICAgICAgcmV0dXJuIHsgbGF0OiBsYXQsIGxuZzogbG9uZywgdGl0bGU6IGluZGV4ICsgMSwgY29sb3I6ICdibHVlJyB9O1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gSWYgY291bGQgbm90IGZpbmQgR29vZ2xlIE1hcHMgTG9jYXRpb24gVVJMIGluIFRhc2tcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGxhdDogdGhpcy5teVBvc2l0aW9uLmxhdCxcbiAgICAgICAgbG5nOiB0aGlzLm15UG9zaXRpb24ubG5nLFxuICAgICAgICB0aXRsZTogaW5kZXggKyAxLFxuICAgICAgICBjb2xvcjogJ3JlZCdcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLy8gVG8gQ2FsY3VsYXRlIERpc3RhbmNlIGJldHdlZW4gdHdvIG1hcmtlcnNcbiAgY2FsY3VsYXRlRGlzdGFuY2UocG9pbnQxOiBhbnksIHBvaW50MjogYW55KTogbnVtYmVyIHtcbiAgICBjb25zdCBsYXQxID0gcG9pbnQxLmxhdDtcbiAgICBjb25zdCBsbmcxID0gcG9pbnQxLmxuZztcbiAgICBjb25zdCBsYXQyID0gcG9pbnQyLmxhdDtcbiAgICBjb25zdCBsbmcyID0gcG9pbnQyLmxuZztcblxuICAgIGNvbnN0IFIgPSA2MzcxOyAvLyBFYXJ0aCByYWRpdXMgaW4ga2lsb21ldGVyc1xuICAgIGNvbnN0IGRMYXQgPSAobGF0MiAtIGxhdDEpICogKE1hdGguUEkgLyAxODApO1xuICAgIGNvbnN0IGRMbmcgPSAobG5nMiAtIGxuZzEpICogKE1hdGguUEkgLyAxODApO1xuICAgIGNvbnN0IGEgPVxuICAgICAgTWF0aC5zaW4oZExhdCAvIDIpICogTWF0aC5zaW4oZExhdCAvIDIpICtcbiAgICAgIE1hdGguY29zKChsYXQxICogTWF0aC5QSSkgLyAxODApICpcbiAgICAgICAgTWF0aC5jb3MoKGxhdDIgKiBNYXRoLlBJKSAvIDE4MCkgKlxuICAgICAgICBNYXRoLnNpbihkTG5nIC8gMikgKlxuICAgICAgICBNYXRoLnNpbihkTG5nIC8gMik7XG4gICAgY29uc3QgYyA9IDIgKiBNYXRoLmF0YW4yKE1hdGguc3FydChhKSwgTWF0aC5zcXJ0KDEgLSBhKSk7XG4gICAgY29uc3QgZGlzdGFuY2UgPSBSICogYztcblxuICAgIHJldHVybiBkaXN0YW5jZTtcbiAgfVxuXG4gIC8vIFRvIGNhbGN1bGF0ZSBuZWFyZXN0IGRpc3RhbmNlIGZyb20gbWFya2VyXG4gIG5lYXJlc3ROZWlnaGJvckFsZ29yaXRobShzdGFydGluZ1BvaW50OiBhbnksIHVudmlzaXRlZFBvaW50czogYW55W10pOiBhbnlbXSB7XG4gICAgbGV0IGN1cnJlbnRQb2ludCA9IHN0YXJ0aW5nUG9pbnQ7XG4gICAgY29uc3QgcGF0aDogYW55W10gPSBbY3VycmVudFBvaW50XTtcbiAgICBjb25zdCB2aXNpdGVkUG9pbnRzOiBTZXQ8YW55PiA9IG5ldyBTZXQoW2N1cnJlbnRQb2ludF0pO1xuXG4gICAgd2hpbGUgKHVudmlzaXRlZFBvaW50cy5sZW5ndGggPiAwKSB7XG4gICAgICBsZXQgbmVhcmVzdFBvaW50ID0gbnVsbDtcbiAgICAgIGxldCBtaW5EaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcblxuICAgICAgZm9yIChjb25zdCBwb2ludCBvZiB1bnZpc2l0ZWRQb2ludHMpIHtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSB0aGlzLmNhbGN1bGF0ZURpc3RhbmNlKGN1cnJlbnRQb2ludCwgcG9pbnQpO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPCBtaW5EaXN0YW5jZSkge1xuICAgICAgICAgIG1pbkRpc3RhbmNlID0gZGlzdGFuY2U7XG4gICAgICAgICAgbmVhcmVzdFBvaW50ID0gcG9pbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcGF0aC5wdXNoKG5lYXJlc3RQb2ludCk7XG4gICAgICB2aXNpdGVkUG9pbnRzLmFkZChuZWFyZXN0UG9pbnQpO1xuICAgICAgY3VycmVudFBvaW50ID0gbmVhcmVzdFBvaW50O1xuXG4gICAgICB1bnZpc2l0ZWRQb2ludHMgPSB1bnZpc2l0ZWRQb2ludHMuZmlsdGVyKFxuICAgICAgICAocG9pbnQpID0+ICF2aXNpdGVkUG9pbnRzLmhhcyhwb2ludClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGg7XG4gIH1cbn1cbiJdfQ==