@flowmap.gl/data 8.0.0-alpha.2 → 8.0.0-alpha.20

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 (63) hide show
  1. package/dist/FlowmapAggregateAccessors.d.ts +16 -0
  2. package/dist/FlowmapAggregateAccessors.d.ts.map +1 -0
  3. package/dist/FlowmapAggregateAccessors.js +46 -0
  4. package/dist/{FlowMapSelectors.d.ts → FlowmapSelectors.d.ts} +87 -70
  5. package/dist/FlowmapSelectors.d.ts.map +1 -0
  6. package/dist/FlowmapSelectors.js +888 -0
  7. package/dist/{FlowMapState.d.ts → FlowmapState.d.ts} +11 -8
  8. package/dist/FlowmapState.d.ts.map +1 -0
  9. package/dist/FlowmapState.js +2 -0
  10. package/dist/cluster/cluster.d.ts +6 -5
  11. package/dist/cluster/cluster.d.ts.map +1 -1
  12. package/dist/cluster/cluster.js +76 -20
  13. package/dist/colors.d.ts +7 -7
  14. package/dist/colors.d.ts.map +1 -1
  15. package/dist/colors.js +55 -20
  16. package/dist/getViewStateForLocations.d.ts +18 -11
  17. package/dist/getViewStateForLocations.d.ts.map +1 -1
  18. package/dist/getViewStateForLocations.js +37 -23
  19. package/dist/index.d.ts +9 -6
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +9 -6
  22. package/dist/provider/FlowmapDataProvider.d.ts +21 -0
  23. package/dist/provider/FlowmapDataProvider.d.ts.map +1 -0
  24. package/dist/provider/FlowmapDataProvider.js +17 -0
  25. package/dist/provider/LocalFlowmapDataProvider.d.ts +21 -0
  26. package/dist/provider/LocalFlowmapDataProvider.d.ts.map +1 -0
  27. package/dist/provider/LocalFlowmapDataProvider.js +104 -0
  28. package/dist/selector-functions.d.ts +4 -0
  29. package/dist/selector-functions.d.ts.map +1 -0
  30. package/dist/selector-functions.js +20 -0
  31. package/dist/types.d.ts +12 -9
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/types.js +4 -4
  34. package/dist/util.d.ts +0 -1
  35. package/dist/util.d.ts.map +1 -1
  36. package/dist/util.js +1 -4
  37. package/package.json +10 -12
  38. package/src/{FlowMapAggregateAccessors.ts → FlowmapAggregateAccessors.ts} +14 -9
  39. package/src/{FlowMapSelectors.ts → FlowmapSelectors.ts} +349 -282
  40. package/src/{FlowMapState.ts → FlowmapState.ts} +10 -7
  41. package/src/cluster/cluster.ts +95 -34
  42. package/src/colors.ts +70 -28
  43. package/src/getViewStateForLocations.ts +56 -40
  44. package/src/index.ts +9 -6
  45. package/src/provider/{FlowMapDataProvider.ts → FlowmapDataProvider.ts} +27 -17
  46. package/src/provider/LocalFlowmapDataProvider.ts +129 -0
  47. package/src/selector-functions.ts +34 -0
  48. package/src/types.ts +15 -12
  49. package/src/util.ts +0 -4
  50. package/dist/FlowMapAggregateAccessors.d.ts +0 -15
  51. package/dist/FlowMapAggregateAccessors.d.ts.map +0 -1
  52. package/dist/FlowMapAggregateAccessors.js +0 -43
  53. package/dist/FlowMapSelectors.d.ts.map +0 -1
  54. package/dist/FlowMapSelectors.js +0 -834
  55. package/dist/FlowMapState.d.ts.map +0 -1
  56. package/dist/FlowMapState.js +0 -2
  57. package/dist/provider/FlowMapDataProvider.d.ts +0 -16
  58. package/dist/provider/FlowMapDataProvider.d.ts.map +0 -1
  59. package/dist/provider/FlowMapDataProvider.js +0 -17
  60. package/dist/provider/LocalFlowMapDataProvider.d.ts +0 -20
  61. package/dist/provider/LocalFlowMapDataProvider.d.ts.map +0 -1
  62. package/dist/provider/LocalFlowMapDataProvider.js +0 -87
  63. package/src/provider/LocalFlowMapDataProvider.ts +0 -105
@@ -0,0 +1,888 @@
1
+ /*
2
+ * Copyright 2022 FlowmapBlue
3
+ * Copyright 2018-2020 Teralytics, modified by FlowmapBlue
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+ import { ascending, descending, extent, min, rollup } from 'd3-array';
19
+ import { scaleSqrt } from 'd3-scale';
20
+ import KDBush from 'kdbush';
21
+ import { createSelector, createSelectorCreator, defaultMemoize, } from 'reselect';
22
+ import { alea } from 'seedrandom';
23
+ import { clusterLocations } from './cluster/cluster';
24
+ import { buildIndex, findAppropriateZoomLevel, makeLocationWeightGetter, } from './cluster/ClusterIndex';
25
+ import getColors, { getColorsRGBA, getDiffColorsRGBA, getFlowColorScale, isDiffColors, isDiffColorsRGBA, } from './colors';
26
+ import FlowmapAggregateAccessors from './FlowmapAggregateAccessors';
27
+ import { getFlowThicknessScale, getViewportBoundingBox, } from './selector-functions';
28
+ import { getTimeGranularityByKey, getTimeGranularityByOrder, getTimeGranularityForDate, } from './time';
29
+ import { isCluster, isLocationClusterNode, LocationFilterMode, } from './types';
30
+ const MAX_CLUSTER_ZOOM_LEVEL = 20;
31
+ export default class FlowmapSelectors {
32
+ constructor(accessors) {
33
+ this.getFlowsFromProps = (state, props) => props.flows;
34
+ this.getLocationsFromProps = (state, props) => props.locations;
35
+ this.getClusterLevelsFromProps = (state, props) => {
36
+ return props.clusterLevels;
37
+ };
38
+ this.getMaxTopFlowsDisplayNum = (state, props) => state.settings.maxTopFlowsDisplayNum;
39
+ this.getSelectedLocations = (state, props) => { var _a; return (_a = state.filter) === null || _a === void 0 ? void 0 : _a.selectedLocations; };
40
+ this.getLocationFilterMode = (state, props) => { var _a; return (_a = state.filter) === null || _a === void 0 ? void 0 : _a.locationFilterMode; };
41
+ this.getClusteringEnabled = (state, props) => state.settings.clusteringEnabled;
42
+ this.getLocationTotalsEnabled = (state, props) => state.settings.locationTotalsEnabled;
43
+ this.getZoom = (state, props) => state.viewport.zoom;
44
+ this.getViewport = (state, props) => state.viewport;
45
+ this.getSelectedTimeRange = (state, props) => { var _a; return (_a = state.filter) === null || _a === void 0 ? void 0 : _a.selectedTimeRange; };
46
+ this.getColorScheme = (state, props) => state.settings.colorScheme;
47
+ this.getDarkMode = (state, props) => state.settings.darkMode;
48
+ this.getFadeEnabled = (state, props) => state.settings.fadeEnabled;
49
+ this.getFadeOpacityEnabled = (state, props) => state.settings.fadeOpacityEnabled;
50
+ this.getFadeAmount = (state, props) => state.settings.fadeAmount;
51
+ this.getAnimate = (state, props) => state.settings.animationEnabled;
52
+ this.getInvalidLocationIds = createSelector(this.getLocationsFromProps, (locations) => {
53
+ if (!locations)
54
+ return undefined;
55
+ const invalid = [];
56
+ for (const location of locations) {
57
+ const id = this.accessors.getLocationId(location);
58
+ const lon = this.accessors.getLocationLon(location);
59
+ const lat = this.accessors.getLocationLat(location);
60
+ if (!(-90 <= lat && lat <= 90) || !(-180 <= lon && lon <= 180)) {
61
+ invalid.push(id);
62
+ }
63
+ }
64
+ return invalid.length > 0 ? invalid : undefined;
65
+ });
66
+ this.getLocations = createSelector(this.getLocationsFromProps, this.getInvalidLocationIds, (locations, invalidIds) => {
67
+ if (!locations)
68
+ return undefined;
69
+ if (!invalidIds || invalidIds.length === 0)
70
+ return locations;
71
+ const invalid = new Set(invalidIds);
72
+ const filtered = [];
73
+ for (const location of locations) {
74
+ const id = this.accessors.getLocationId(location);
75
+ if (!invalid.has(id)) {
76
+ filtered.push(location);
77
+ }
78
+ }
79
+ return filtered;
80
+ });
81
+ this.getLocationIds = createSelector(this.getLocations, (locations) => {
82
+ if (!locations)
83
+ return undefined;
84
+ const ids = new Set();
85
+ for (const id of locations) {
86
+ ids.add(this.accessors.getLocationId(id));
87
+ }
88
+ return ids;
89
+ });
90
+ this.getSelectedLocationsSet = createSelector(this.getSelectedLocations, (ids) => ids && ids.length > 0 ? new Set(ids) : undefined);
91
+ this.getSortedFlowsForKnownLocations = createSelector(this.getFlowsFromProps, this.getLocationIds, (flows, ids) => {
92
+ if (!ids || !flows)
93
+ return undefined;
94
+ const filtered = [];
95
+ for (const flow of flows) {
96
+ const srcId = this.accessors.getFlowOriginId(flow);
97
+ const dstId = this.accessors.getFlowDestId(flow);
98
+ if (ids.has(srcId) && ids.has(dstId)) {
99
+ filtered.push(flow);
100
+ }
101
+ }
102
+ return filtered.sort((a, b) => descending(Math.abs(this.accessors.getFlowMagnitude(a)), Math.abs(this.accessors.getFlowMagnitude(b))));
103
+ });
104
+ this.getActualTimeExtent = createSelector(this.getSortedFlowsForKnownLocations, (flows) => {
105
+ if (!flows)
106
+ return undefined;
107
+ let start = null;
108
+ let end = null;
109
+ for (const flow of flows) {
110
+ const time = this.accessors.getFlowTime(flow);
111
+ if (time) {
112
+ if (start == null || start > time)
113
+ start = time;
114
+ if (end == null || end < time)
115
+ end = time;
116
+ }
117
+ }
118
+ if (!start || !end)
119
+ return undefined;
120
+ return [start, end];
121
+ });
122
+ this.getTimeGranularityKey = createSelector(this.getSortedFlowsForKnownLocations, this.getActualTimeExtent, (flows, timeExtent) => {
123
+ if (!flows || !timeExtent)
124
+ return undefined;
125
+ const minOrder = min(flows, (d) => {
126
+ const t = this.accessors.getFlowTime(d);
127
+ return t ? getTimeGranularityForDate(t).order : null;
128
+ });
129
+ if (minOrder == null)
130
+ return undefined;
131
+ const timeGranularity = getTimeGranularityByOrder(minOrder);
132
+ return timeGranularity ? timeGranularity.key : undefined;
133
+ });
134
+ this.getTimeExtent = createSelector(this.getActualTimeExtent, this.getTimeGranularityKey, (timeExtent, timeGranularityKey) => {
135
+ const timeGranularity = timeGranularityKey
136
+ ? getTimeGranularityByKey(timeGranularityKey)
137
+ : undefined;
138
+ if (!timeExtent || !(timeGranularity === null || timeGranularity === void 0 ? void 0 : timeGranularity.interval))
139
+ return undefined;
140
+ const { interval } = timeGranularity;
141
+ return [timeExtent[0], interval.offset(interval.floor(timeExtent[1]), 1)];
142
+ });
143
+ this.getSortedFlowsForKnownLocationsFilteredByTime = createSelector(this.getSortedFlowsForKnownLocations, this.getTimeExtent, this.getSelectedTimeRange, (flows, timeExtent, timeRange) => {
144
+ if (!flows)
145
+ return undefined;
146
+ if (!timeExtent ||
147
+ !timeRange ||
148
+ (timeExtent[0] === timeRange[0] && timeExtent[1] === timeRange[1])) {
149
+ return flows;
150
+ }
151
+ return flows.filter((flow) => {
152
+ const time = this.accessors.getFlowTime(flow);
153
+ return time && timeRange[0] <= time && time < timeRange[1];
154
+ });
155
+ });
156
+ this.getLocationsHavingFlows = createSelector(this.getSortedFlowsForKnownLocations, this.getLocations, (flows, locations) => {
157
+ if (!locations || !flows)
158
+ return locations;
159
+ const withFlows = new Set();
160
+ for (const flow of flows) {
161
+ withFlows.add(this.accessors.getFlowOriginId(flow));
162
+ withFlows.add(this.accessors.getFlowDestId(flow));
163
+ }
164
+ const filtered = [];
165
+ for (const location of locations) {
166
+ if (withFlows.has(this.accessors.getLocationId(location))) {
167
+ filtered.push(location);
168
+ }
169
+ }
170
+ return filtered;
171
+ });
172
+ this.getLocationsById = createSelector(this.getLocationsHavingFlows, (locations) => {
173
+ if (!locations)
174
+ return undefined;
175
+ const locationsById = new Map();
176
+ for (const location of locations) {
177
+ locationsById.set(this.accessors.getLocationId(location), location);
178
+ }
179
+ return locationsById;
180
+ });
181
+ this.getLocationWeightGetter = createSelector(this.getSortedFlowsForKnownLocations, (flows) => {
182
+ if (!flows)
183
+ return undefined;
184
+ const getLocationWeight = makeLocationWeightGetter(flows, this.accessors.getFlowmapDataAccessors());
185
+ return getLocationWeight;
186
+ });
187
+ this.getClusterLevels = createSelector(this.getClusterLevelsFromProps, this.getLocationsHavingFlows, this.getLocationWeightGetter, (clusterLevelsFromProps, locations, getLocationWeight) => {
188
+ if (clusterLevelsFromProps)
189
+ return clusterLevelsFromProps;
190
+ if (!locations || !getLocationWeight)
191
+ return undefined;
192
+ const clusterLevels = clusterLocations(locations, this.accessors.getFlowmapDataAccessors(), getLocationWeight, {
193
+ maxZoom: MAX_CLUSTER_ZOOM_LEVEL,
194
+ });
195
+ return clusterLevels;
196
+ });
197
+ this.getClusterIndex = createSelector(this.getLocationsById, this.getLocationWeightGetter, this.getClusterLevels, (locationsById, getLocationWeight, clusterLevels) => {
198
+ if (!locationsById || !getLocationWeight || !clusterLevels)
199
+ return undefined;
200
+ const clusterIndex = buildIndex(clusterLevels);
201
+ const { getLocationName, getLocationClusterName } = this.accessors.getFlowmapDataAccessors();
202
+ // Adding meaningful names
203
+ const getName = (id) => {
204
+ const loc = locationsById.get(id);
205
+ if (loc) {
206
+ return getLocationName
207
+ ? getLocationName(loc)
208
+ : this.accessors.getLocationId(loc) || id;
209
+ }
210
+ return `"${id}"`;
211
+ };
212
+ for (const level of clusterLevels) {
213
+ for (const node of level.nodes) {
214
+ // Here mutating the nodes (adding names)
215
+ if (isCluster(node)) {
216
+ const leaves = clusterIndex.expandCluster(node);
217
+ leaves.sort((a, b) => descending(getLocationWeight(a), getLocationWeight(b)));
218
+ if (getLocationClusterName) {
219
+ node.name = getLocationClusterName(leaves);
220
+ }
221
+ else {
222
+ const topId = leaves[0];
223
+ const otherId = leaves.length === 2 ? leaves[1] : undefined;
224
+ node.name = `"${getName(topId)}" and ${otherId
225
+ ? `"${getName(otherId)}"`
226
+ : `${leaves.length - 1} others`}`;
227
+ }
228
+ }
229
+ else {
230
+ node.name = getName(node.id);
231
+ }
232
+ }
233
+ }
234
+ return clusterIndex;
235
+ });
236
+ this.getAvailableClusterZoomLevels = createSelector(this.getClusterIndex, this.getSelectedLocations, (clusterIndex, selectedLocations) => {
237
+ if (!clusterIndex) {
238
+ return undefined;
239
+ }
240
+ let maxZoom = Number.POSITIVE_INFINITY;
241
+ let minZoom = Number.NEGATIVE_INFINITY;
242
+ const adjust = (zoneId) => {
243
+ const cluster = clusterIndex.getClusterById(zoneId);
244
+ if (cluster) {
245
+ minZoom = Math.max(minZoom, cluster.zoom);
246
+ maxZoom = Math.min(maxZoom, cluster.zoom);
247
+ }
248
+ else {
249
+ const zoom = clusterIndex.getMinZoomForLocation(zoneId);
250
+ minZoom = Math.max(minZoom, zoom);
251
+ }
252
+ };
253
+ if (selectedLocations) {
254
+ for (const id of selectedLocations) {
255
+ adjust(id);
256
+ }
257
+ }
258
+ return clusterIndex.availableZoomLevels.filter((level) => minZoom <= level && level <= maxZoom);
259
+ });
260
+ this._getClusterZoom = createSelector(this.getClusterIndex, this.getZoom, this.getAvailableClusterZoomLevels, (clusterIndex, mapZoom, availableClusterZoomLevels) => {
261
+ if (!clusterIndex)
262
+ return undefined;
263
+ if (!availableClusterZoomLevels || mapZoom == null) {
264
+ return undefined;
265
+ }
266
+ const clusterZoom = findAppropriateZoomLevel(availableClusterZoomLevels, mapZoom);
267
+ return clusterZoom;
268
+ });
269
+ this.getClusterZoom = (state, props) => {
270
+ const { settings } = state;
271
+ if (!settings.clusteringEnabled)
272
+ return undefined;
273
+ if (settings.clusteringAuto || settings.clusteringLevel == null) {
274
+ return this._getClusterZoom(state, props);
275
+ }
276
+ return settings.clusteringLevel;
277
+ };
278
+ this.getLocationsForSearchBox = createSelector(this.getClusteringEnabled, this.getLocationsHavingFlows, this.getSelectedLocations, this.getClusterZoom, this.getClusterIndex, (clusteringEnabled, locations, selectedLocations, clusterZoom, clusterIndex) => {
279
+ if (!locations)
280
+ return undefined;
281
+ let result = Array.from(locations);
282
+ // if (clusteringEnabled) {
283
+ // if (clusterIndex) {
284
+ // const zoomItems = clusterIndex.getClusterNodesFor(clusterZoom);
285
+ // if (zoomItems) {
286
+ // result = result.concat(zoomItems.filter(isCluster));
287
+ // }
288
+ // }
289
+ // }
290
+ if (clusterIndex && selectedLocations) {
291
+ const toAppend = [];
292
+ for (const id of selectedLocations) {
293
+ const cluster = clusterIndex.getClusterById(id);
294
+ if (cluster &&
295
+ !result.find((d) => (isLocationClusterNode(d)
296
+ ? d.id
297
+ : this.accessors.getLocationId(d)) === id)) {
298
+ toAppend.push(cluster);
299
+ }
300
+ }
301
+ if (toAppend.length > 0) {
302
+ result = result.concat(toAppend);
303
+ }
304
+ }
305
+ return result;
306
+ });
307
+ this.getDiffMode = createSelector(this.getFlowsFromProps, (flows) => {
308
+ if (flows) {
309
+ for (const f of flows) {
310
+ if (this.accessors.getFlowMagnitude(f) < 0) {
311
+ return true;
312
+ }
313
+ }
314
+ }
315
+ return false;
316
+ });
317
+ this._getFlowmapColors = createSelector(this.getDiffMode, this.getColorScheme, this.getDarkMode, this.getFadeEnabled, this.getFadeOpacityEnabled, this.getFadeAmount, this.getAnimate, getColors);
318
+ this.getFlowmapColorsRGBA = createSelector(this._getFlowmapColors, (flowmapColors) => {
319
+ return isDiffColors(flowmapColors)
320
+ ? getDiffColorsRGBA(flowmapColors)
321
+ : getColorsRGBA(flowmapColors);
322
+ });
323
+ this.getUnknownLocations = createSelector(this.getLocationIds, this.getFlowsFromProps, this.getSortedFlowsForKnownLocations, (ids, flows, flowsForKnownLocations) => {
324
+ if (!ids || !flows)
325
+ return undefined;
326
+ if (flowsForKnownLocations
327
+ // && flows.length === flowsForKnownLocations.length
328
+ )
329
+ return undefined;
330
+ const missing = new Set();
331
+ for (const flow of flows) {
332
+ if (!ids.has(this.accessors.getFlowOriginId(flow)))
333
+ missing.add(this.accessors.getFlowOriginId(flow));
334
+ if (!ids.has(this.accessors.getFlowDestId(flow)))
335
+ missing.add(this.accessors.getFlowDestId(flow));
336
+ }
337
+ return missing;
338
+ });
339
+ this.getSortedAggregatedFilteredFlows = createSelector(this.getClusterIndex, this.getClusteringEnabled, this.getSortedFlowsForKnownLocationsFilteredByTime, this.getClusterZoom, this.getTimeExtent, (clusterTree, isClusteringEnabled, flows, clusterZoom, timeExtent) => {
340
+ if (!flows)
341
+ return undefined;
342
+ let aggregated;
343
+ if (isClusteringEnabled && clusterTree && clusterZoom != null) {
344
+ aggregated = clusterTree.aggregateFlows(
345
+ // TODO: aggregate across time
346
+ // timeExtent != null
347
+ // ? aggregateFlows(flows) // clusterTree.aggregateFlows won't aggregate unclustered across time
348
+ // : flows,
349
+ flows, clusterZoom, this.accessors.getFlowmapDataAccessors());
350
+ }
351
+ else {
352
+ aggregated = aggregateFlows(flows, this.accessors.getFlowmapDataAccessors());
353
+ }
354
+ aggregated.sort((a, b) => descending(Math.abs(this.accessors.getFlowMagnitude(a)), Math.abs(this.accessors.getFlowMagnitude(b))));
355
+ return aggregated;
356
+ });
357
+ this.getExpandedSelectedLocationsSet = createSelector(this.getClusteringEnabled, this.getSelectedLocationsSet, this.getClusterIndex, (clusteringEnabled, selectedLocations, clusterIndex) => {
358
+ if (!selectedLocations || !clusterIndex) {
359
+ return selectedLocations;
360
+ }
361
+ const result = new Set();
362
+ for (const locationId of selectedLocations) {
363
+ const cluster = clusterIndex.getClusterById(locationId);
364
+ if (cluster) {
365
+ const expanded = clusterIndex.expandCluster(cluster);
366
+ for (const id of expanded) {
367
+ result.add(id);
368
+ }
369
+ }
370
+ else {
371
+ result.add(locationId);
372
+ }
373
+ }
374
+ return result;
375
+ });
376
+ this.getTotalCountsByTime = createSelector(this.getSortedFlowsForKnownLocations, this.getTimeGranularityKey, this.getTimeExtent, this.getExpandedSelectedLocationsSet, this.getLocationFilterMode, (flows, timeGranularityKey, timeExtent, selectedLocationSet, locationFilterMode) => {
377
+ const timeGranularity = timeGranularityKey
378
+ ? getTimeGranularityByKey(timeGranularityKey)
379
+ : undefined;
380
+ if (!flows || !timeGranularity || !timeExtent)
381
+ return undefined;
382
+ const byTime = flows.reduce((m, flow) => {
383
+ var _a;
384
+ if (this.isFlowInSelection(flow, selectedLocationSet, locationFilterMode)) {
385
+ const key = timeGranularity
386
+ .interval(this.accessors.getFlowTime(flow))
387
+ .getTime();
388
+ m.set(key, ((_a = m.get(key)) !== null && _a !== void 0 ? _a : 0) + this.accessors.getFlowMagnitude(flow));
389
+ }
390
+ return m;
391
+ }, new Map());
392
+ return Array.from(byTime.entries()).map(([millis, count]) => ({
393
+ time: new Date(millis),
394
+ count,
395
+ }));
396
+ });
397
+ this.getMaxLocationCircleSize = createSelector(this.getLocationTotalsEnabled, (locationTotalsEnabled) => (locationTotalsEnabled ? 17 : 1));
398
+ this.getViewportBoundingBox = createSelector(this.getViewport, this.getMaxLocationCircleSize, getViewportBoundingBox);
399
+ this.getLocationsForZoom = createSelector(this.getClusteringEnabled, this.getLocationsHavingFlows, this.getClusterIndex, this.getClusterZoom, (clusteringEnabled, locationsHavingFlows, clusterIndex, clusterZoom) => {
400
+ if (clusteringEnabled && clusterIndex) {
401
+ return clusterIndex.getClusterNodesFor(clusterZoom);
402
+ }
403
+ else {
404
+ return locationsHavingFlows;
405
+ }
406
+ });
407
+ this.getLocationTotals = createSelector(this.getLocationsForZoom, this.getSortedAggregatedFilteredFlows, this.getSelectedLocationsSet, this.getLocationFilterMode, (locations, flows, selectedLocationsSet, locationFilterMode) => {
408
+ if (!flows)
409
+ return undefined;
410
+ const totals = new Map();
411
+ const add = (id, d) => {
412
+ var _a;
413
+ const rv = (_a = totals.get(id)) !== null && _a !== void 0 ? _a : {
414
+ incomingCount: 0,
415
+ outgoingCount: 0,
416
+ internalCount: 0,
417
+ };
418
+ if (d.incomingCount != null)
419
+ rv.incomingCount += d.incomingCount;
420
+ if (d.outgoingCount != null)
421
+ rv.outgoingCount += d.outgoingCount;
422
+ if (d.internalCount != null)
423
+ rv.internalCount += d.internalCount;
424
+ return rv;
425
+ };
426
+ for (const f of flows) {
427
+ if (this.isFlowInSelection(f, selectedLocationsSet, locationFilterMode)) {
428
+ const originId = this.accessors.getFlowOriginId(f);
429
+ const destId = this.accessors.getFlowDestId(f);
430
+ const count = this.accessors.getFlowMagnitude(f);
431
+ if (originId === destId) {
432
+ totals.set(originId, add(originId, { internalCount: count }));
433
+ }
434
+ else {
435
+ totals.set(originId, add(originId, { outgoingCount: count }));
436
+ totals.set(destId, add(destId, { incomingCount: count }));
437
+ }
438
+ }
439
+ }
440
+ return totals;
441
+ });
442
+ this.getLocationsTree = createSelector(this.getLocationsForZoom, (locations) => {
443
+ if (!locations) {
444
+ return undefined;
445
+ }
446
+ return new KDBush(
447
+ // @ts-ignore
448
+ locations, (location) => lngX(this.accessors.getLocationLon(location)), (location) => latY(this.accessors.getLocationLat(location)));
449
+ });
450
+ this._getLocationIdsInViewport = createSelector(this.getLocationsTree, this.getViewportBoundingBox, (tree, bbox) => {
451
+ const ids = this._getLocationsInBboxIndices(tree, bbox);
452
+ if (ids) {
453
+ return new Set(ids.map((idx) => tree.points[idx].id));
454
+ }
455
+ return undefined;
456
+ });
457
+ this.getLocationIdsInViewport = createSelectorCreator(defaultMemoize,
458
+ // @ts-ignore
459
+ (s1, s2, index) => {
460
+ if (s1 === s2)
461
+ return true;
462
+ if (s1 == null || s2 == null)
463
+ return false;
464
+ if (s1.size !== s2.size)
465
+ return false;
466
+ for (const item of s1)
467
+ if (!s2.has(item))
468
+ return false;
469
+ return true;
470
+ })(this._getLocationIdsInViewport, (locationIds) => {
471
+ if (!locationIds)
472
+ return undefined;
473
+ return locationIds;
474
+ });
475
+ this.getTotalUnfilteredCount = createSelector(this.getSortedFlowsForKnownLocations, (flows) => {
476
+ if (!flows)
477
+ return undefined;
478
+ return flows.reduce((m, flow) => m + this.accessors.getFlowMagnitude(flow), 0);
479
+ });
480
+ this.getTotalFilteredCount = createSelector(this.getSortedAggregatedFilteredFlows, this.getSelectedLocationsSet, this.getLocationFilterMode, (flows, selectedLocationSet, locationFilterMode) => {
481
+ if (!flows)
482
+ return undefined;
483
+ const count = flows.reduce((m, flow) => {
484
+ if (this.isFlowInSelection(flow, selectedLocationSet, locationFilterMode)) {
485
+ return m + this.accessors.getFlowMagnitude(flow);
486
+ }
487
+ return m;
488
+ }, 0);
489
+ return count;
490
+ });
491
+ this._getLocationTotalsExtent = createSelector(this.getLocationTotals, (locationTotals) => calcLocationTotalsExtent(locationTotals, undefined));
492
+ this._getLocationTotalsForViewportExtent = createSelector(this.getLocationTotals, this.getLocationIdsInViewport, (locationTotals, locationsInViewport) => calcLocationTotalsExtent(locationTotals, locationsInViewport));
493
+ this.getLocationTotalsExtent = (state, props) => {
494
+ if (state.settings.adaptiveScalesEnabled) {
495
+ return this._getLocationTotalsForViewportExtent(state, props);
496
+ }
497
+ else {
498
+ return this._getLocationTotalsExtent(state, props);
499
+ }
500
+ };
501
+ this.getFlowsForFlowmapLayer = createSelector(this.getSortedAggregatedFilteredFlows, this.getLocationIdsInViewport, this.getSelectedLocationsSet, this.getLocationFilterMode, this.getMaxTopFlowsDisplayNum, (flows, locationIdsInViewport, selectedLocationsSet, locationFilterMode, maxTopFlowsDisplayNum) => {
502
+ if (!flows || !locationIdsInViewport)
503
+ return undefined;
504
+ const picked = [];
505
+ let pickedCount = 0;
506
+ for (const flow of flows) {
507
+ const origin = this.accessors.getFlowOriginId(flow);
508
+ const dest = this.accessors.getFlowDestId(flow);
509
+ if (locationIdsInViewport.has(origin) ||
510
+ locationIdsInViewport.has(dest)) {
511
+ if (this.isFlowInSelection(flow, selectedLocationsSet, locationFilterMode)) {
512
+ if (origin !== dest) {
513
+ // exclude self-loops
514
+ picked.push(flow);
515
+ pickedCount++;
516
+ }
517
+ }
518
+ }
519
+ // Only keep top
520
+ if (pickedCount > maxTopFlowsDisplayNum)
521
+ break;
522
+ }
523
+ // assuming they are sorted in descending order,
524
+ // we need ascending for rendering
525
+ return picked.reverse();
526
+ });
527
+ this._getFlowMagnitudeExtent = createSelector(this.getSortedAggregatedFilteredFlows, this.getSelectedLocationsSet, this.getLocationFilterMode, (flows, selectedLocationsSet, locationFilterMode) => {
528
+ if (!flows)
529
+ return undefined;
530
+ let rv = undefined;
531
+ for (const f of flows) {
532
+ if (this.accessors.getFlowOriginId(f) !==
533
+ this.accessors.getFlowDestId(f) &&
534
+ this.isFlowInSelection(f, selectedLocationsSet, locationFilterMode)) {
535
+ const count = this.accessors.getFlowMagnitude(f);
536
+ if (rv == null) {
537
+ rv = [count, count];
538
+ }
539
+ else {
540
+ if (count < rv[0])
541
+ rv[0] = count;
542
+ if (count > rv[1])
543
+ rv[1] = count;
544
+ }
545
+ }
546
+ }
547
+ return rv;
548
+ });
549
+ this._getAdaptiveFlowMagnitudeExtent = createSelector(this.getFlowsForFlowmapLayer, (flows) => {
550
+ if (!flows)
551
+ return undefined;
552
+ const rv = extent(flows, this.accessors.getFlowMagnitude);
553
+ return rv[0] !== undefined && rv[1] !== undefined ? rv : undefined;
554
+ });
555
+ this.getFlowMagnitudeExtent = (state, props) => {
556
+ if (state.settings.adaptiveScalesEnabled) {
557
+ return this._getAdaptiveFlowMagnitudeExtent(state, props);
558
+ }
559
+ else {
560
+ return this._getFlowMagnitudeExtent(state, props);
561
+ }
562
+ };
563
+ this.getLocationMaxAbsTotalGetter = createSelector(this.getLocationTotals, (locationTotals) => {
564
+ return (locationId) => {
565
+ const total = locationTotals === null || locationTotals === void 0 ? void 0 : locationTotals.get(locationId);
566
+ if (!total)
567
+ return undefined;
568
+ return Math.max(Math.abs(total.incomingCount + total.internalCount), Math.abs(total.outgoingCount + total.internalCount));
569
+ };
570
+ });
571
+ this.getFlowThicknessScale = createSelector(this.getFlowMagnitudeExtent, getFlowThicknessScale);
572
+ this.getCircleSizeScale = createSelector(this.getMaxLocationCircleSize, this.getLocationTotalsEnabled, this.getLocationTotalsExtent, (maxLocationCircleSize, locationTotalsEnabled, locationTotalsExtent) => {
573
+ if (!locationTotalsEnabled) {
574
+ return () => maxLocationCircleSize;
575
+ }
576
+ if (!locationTotalsExtent)
577
+ return undefined;
578
+ return scaleSqrt()
579
+ .range([0, maxLocationCircleSize])
580
+ .domain([
581
+ 0,
582
+ // should support diff mode too
583
+ Math.max.apply(null, locationTotalsExtent.map((x) => Math.abs(x || 0))),
584
+ ]);
585
+ });
586
+ this.getInCircleSizeGetter = createSelector(this.getCircleSizeScale, this.getLocationTotals, (circleSizeScale, locationTotals) => {
587
+ return (locationId) => {
588
+ const total = locationTotals === null || locationTotals === void 0 ? void 0 : locationTotals.get(locationId);
589
+ if (total && circleSizeScale) {
590
+ return (circleSizeScale(Math.abs(total.incomingCount + total.internalCount)) || 0);
591
+ }
592
+ return 0;
593
+ };
594
+ });
595
+ this.getOutCircleSizeGetter = createSelector(this.getCircleSizeScale, this.getLocationTotals, (circleSizeScale, locationTotals) => {
596
+ return (locationId) => {
597
+ const total = locationTotals === null || locationTotals === void 0 ? void 0 : locationTotals.get(locationId);
598
+ if (total && circleSizeScale) {
599
+ return (circleSizeScale(Math.abs(total.outgoingCount + total.internalCount)) || 0);
600
+ }
601
+ return 0;
602
+ };
603
+ });
604
+ this.getSortedLocationsForZoom = createSelector(this.getLocationsForZoom, this.getInCircleSizeGetter, this.getOutCircleSizeGetter, (locations, getInCircleSize, getOutCircleSize) => {
605
+ if (!locations)
606
+ return undefined;
607
+ const nextLocations = [...locations];
608
+ return nextLocations.sort((a, b) => {
609
+ const idA = this.accessors.getLocationId(a);
610
+ const idB = this.accessors.getLocationId(b);
611
+ return ascending(Math.max(getInCircleSize(idA), getOutCircleSize(idA)), Math.max(getInCircleSize(idB), getOutCircleSize(idB)));
612
+ });
613
+ });
614
+ this.getLocationsForFlowmapLayer = createSelector(this.getSortedLocationsForZoom,
615
+ // this.getLocationIdsInViewport,
616
+ (locations) => {
617
+ // if (!locations) return undefined;
618
+ // if (!locationIdsInViewport) return locations;
619
+ // if (locationIdsInViewport.size === locations.length) return locations;
620
+ // const filtered = [];
621
+ // for (const loc of locations) {
622
+ // if (locationIdsInViewport.has(loc.id)) {
623
+ // filtered.push(loc);
624
+ // }
625
+ // }
626
+ // return filtered;
627
+ // @ts-ignore
628
+ // return locations.filter(
629
+ // (loc: L | ClusterNode) => locationIdsInViewport!.has(loc.id)
630
+ // );
631
+ // TODO: return location in viewport + "connected" ones
632
+ return locations;
633
+ });
634
+ this.getLocationsForFlowmapLayerById = createSelector(this.getLocationsForFlowmapLayer, (locations) => {
635
+ if (!locations)
636
+ return undefined;
637
+ return locations.reduce((m, d) => (m.set(this.accessors.getLocationId(d), d), m), new Map());
638
+ });
639
+ this.getLayersData = createSelector(this.getLocationsForFlowmapLayer, this.getFlowsForFlowmapLayer, this.getFlowmapColorsRGBA, this.getLocationsForFlowmapLayerById, this.getLocationIdsInViewport, this.getInCircleSizeGetter, this.getOutCircleSizeGetter, this.getFlowThicknessScale, this.getAnimate, (locations, flows, flowmapColors, locationsById, locationIdsInViewport, getInCircleSize, getOutCircleSize, flowThicknessScale, animationEnabled) => {
640
+ return this._prepareLayersData(locations, flows, flowmapColors, locationsById, locationIdsInViewport, getInCircleSize, getOutCircleSize, flowThicknessScale, animationEnabled);
641
+ });
642
+ this.accessors = new FlowmapAggregateAccessors(accessors);
643
+ this.setAccessors(accessors);
644
+ }
645
+ setAccessors(accessors) {
646
+ this.accessors = new FlowmapAggregateAccessors(accessors);
647
+ }
648
+ prepareLayersData(state, props) {
649
+ const locations = this.getLocationsForFlowmapLayer(state, props) || [];
650
+ const flows = this.getFlowsForFlowmapLayer(state, props) || [];
651
+ const flowmapColors = this.getFlowmapColorsRGBA(state, props);
652
+ const locationsById = this.getLocationsForFlowmapLayerById(state, props);
653
+ const locationIdsInViewport = this.getLocationIdsInViewport(state, props);
654
+ const getInCircleSize = this.getInCircleSizeGetter(state, props);
655
+ const getOutCircleSize = this.getOutCircleSizeGetter(state, props);
656
+ const flowThicknessScale = this.getFlowThicknessScale(state, props);
657
+ return this._prepareLayersData(locations, flows, flowmapColors, locationsById, locationIdsInViewport, getInCircleSize, getOutCircleSize, flowThicknessScale, state.settings.animationEnabled);
658
+ }
659
+ _prepareLayersData(locations, flows, flowmapColors, locationsById, locationIdsInViewport, getInCircleSize, getOutCircleSize, flowThicknessScale, animationEnabled) {
660
+ if (!locations)
661
+ locations = [];
662
+ if (!flows)
663
+ flows = [];
664
+ const { getFlowOriginId, getFlowDestId, getFlowMagnitude, getLocationId, getLocationLon, getLocationLat, } = this.accessors;
665
+ const flowMagnitudeExtent = extent(flows, (f) => getFlowMagnitude(f));
666
+ const flowColorScale = getFlowColorScale(flowmapColors, flowMagnitudeExtent, false);
667
+ // Using a generator here helps to avoid creating intermediary arrays
668
+ const circlePositions = Float32Array.from((function* () {
669
+ for (const location of locations) {
670
+ yield getLocationLon(location);
671
+ yield getLocationLat(location);
672
+ }
673
+ })());
674
+ // TODO: diff mode
675
+ const circleColor = isDiffColorsRGBA(flowmapColors)
676
+ ? flowmapColors.positive.locationCircles.inner
677
+ : flowmapColors.locationCircles.inner;
678
+ const circleColors = Uint8Array.from((function* () {
679
+ for (const location of locations) {
680
+ yield* circleColor;
681
+ }
682
+ })());
683
+ const inCircleRadii = Float32Array.from((function* () {
684
+ for (const location of locations) {
685
+ const id = getLocationId(location);
686
+ yield (locationIdsInViewport === null || locationIdsInViewport === void 0 ? void 0 : locationIdsInViewport.has(id)) ? getInCircleSize(id) : 1.0;
687
+ }
688
+ })());
689
+ const outCircleRadii = Float32Array.from((function* () {
690
+ for (const location of locations) {
691
+ const id = getLocationId(location);
692
+ yield (locationIdsInViewport === null || locationIdsInViewport === void 0 ? void 0 : locationIdsInViewport.has(id)) ? getOutCircleSize(id) : 1.0;
693
+ }
694
+ })());
695
+ const sourcePositions = Float32Array.from((function* () {
696
+ for (const flow of flows) {
697
+ const loc = locationsById === null || locationsById === void 0 ? void 0 : locationsById.get(getFlowOriginId(flow));
698
+ yield loc ? getLocationLon(loc) : 0;
699
+ yield loc ? getLocationLat(loc) : 0;
700
+ }
701
+ })());
702
+ const targetPositions = Float32Array.from((function* () {
703
+ for (const flow of flows) {
704
+ const loc = locationsById === null || locationsById === void 0 ? void 0 : locationsById.get(getFlowDestId(flow));
705
+ yield loc ? getLocationLon(loc) : 0;
706
+ yield loc ? getLocationLat(loc) : 0;
707
+ }
708
+ })());
709
+ const thicknesses = Float32Array.from((function* () {
710
+ for (const flow of flows) {
711
+ yield flowThicknessScale
712
+ ? flowThicknessScale(getFlowMagnitude(flow)) || 0
713
+ : 0;
714
+ }
715
+ })());
716
+ const endpointOffsets = Float32Array.from((function* () {
717
+ for (const flow of flows) {
718
+ const originId = getFlowOriginId(flow);
719
+ const destId = getFlowDestId(flow);
720
+ yield Math.max(getInCircleSize(originId), getOutCircleSize(originId));
721
+ yield Math.max(getInCircleSize(destId), getOutCircleSize(destId));
722
+ }
723
+ })());
724
+ const flowLineColors = Uint8Array.from((function* () {
725
+ for (const flow of flows) {
726
+ yield* flowColorScale(getFlowMagnitude(flow));
727
+ }
728
+ })());
729
+ const staggeringValues = animationEnabled
730
+ ? Float32Array.from((function* () {
731
+ for (const f of flows) {
732
+ // @ts-ignore
733
+ yield new alea(`${getFlowOriginId(f)}-${getFlowDestId(f)}`)();
734
+ }
735
+ })())
736
+ : undefined;
737
+ return {
738
+ circleAttributes: {
739
+ length: locations.length,
740
+ attributes: {
741
+ getPosition: { value: circlePositions, size: 2 },
742
+ getColor: { value: circleColors, size: 4 },
743
+ getInRadius: { value: inCircleRadii, size: 1 },
744
+ getOutRadius: { value: outCircleRadii, size: 1 },
745
+ },
746
+ },
747
+ lineAttributes: {
748
+ length: flows.length,
749
+ attributes: Object.assign({ getSourcePosition: { value: sourcePositions, size: 2 }, getTargetPosition: { value: targetPositions, size: 2 }, getThickness: { value: thicknesses, size: 1 }, getColor: { value: flowLineColors, size: 4 }, getEndpointOffsets: { value: endpointOffsets, size: 2 } }, (staggeringValues
750
+ ? { getStaggering: { value: staggeringValues, size: 1 } }
751
+ : {})),
752
+ },
753
+ };
754
+ }
755
+ getLocationsInBbox(tree, bbox) {
756
+ if (!tree)
757
+ return undefined;
758
+ return this._getLocationsInBboxIndices(tree, bbox).map((idx) => tree.points[idx]);
759
+ }
760
+ _getLocationsInBboxIndices(tree, bbox) {
761
+ if (!tree)
762
+ return undefined;
763
+ const [lon1, lat1, lon2, lat2] = bbox;
764
+ const [x1, y1, x2, y2] = [lngX(lon1), latY(lat1), lngX(lon2), latY(lat2)];
765
+ return tree.range(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2));
766
+ }
767
+ isFlowInSelection(flow, selectedLocationsSet, locationFilterMode) {
768
+ const origin = this.accessors.getFlowOriginId(flow);
769
+ const dest = this.accessors.getFlowDestId(flow);
770
+ if (selectedLocationsSet) {
771
+ switch (locationFilterMode) {
772
+ case LocationFilterMode.ALL:
773
+ return (selectedLocationsSet.has(origin) || selectedLocationsSet.has(dest));
774
+ case LocationFilterMode.BETWEEN:
775
+ return (selectedLocationsSet.has(origin) && selectedLocationsSet.has(dest));
776
+ case LocationFilterMode.INCOMING:
777
+ return selectedLocationsSet.has(dest);
778
+ case LocationFilterMode.OUTGOING:
779
+ return selectedLocationsSet.has(origin);
780
+ }
781
+ }
782
+ return true;
783
+ }
784
+ }
785
+ function calcLocationTotalsExtent(locationTotals, locationIdsInViewport) {
786
+ if (!locationTotals)
787
+ return undefined;
788
+ let rv = undefined;
789
+ for (const [id, { incomingCount, outgoingCount, internalCount },] of locationTotals.entries()) {
790
+ if (locationIdsInViewport == null || locationIdsInViewport.has(id)) {
791
+ const lo = Math.min(incomingCount + internalCount, outgoingCount + internalCount, internalCount);
792
+ const hi = Math.max(incomingCount + internalCount, outgoingCount + internalCount, internalCount);
793
+ if (!rv) {
794
+ rv = [lo, hi];
795
+ }
796
+ else {
797
+ if (lo < rv[0])
798
+ rv[0] = lo;
799
+ if (hi > rv[1])
800
+ rv[1] = hi;
801
+ }
802
+ }
803
+ }
804
+ return rv;
805
+ }
806
+ // longitude/latitude to spherical mercator in [0..1] range
807
+ function lngX(lng) {
808
+ return lng / 360 + 0.5;
809
+ }
810
+ function latY(lat) {
811
+ const sin = Math.sin((lat * Math.PI) / 180);
812
+ const y = 0.5 - (0.25 * Math.log((1 + sin) / (1 - sin))) / Math.PI;
813
+ return y < 0 ? 0 : y > 1 ? 1 : y;
814
+ }
815
+ function aggregateFlows(flows, flowAccessors) {
816
+ // Sum up flows with same origin, dest
817
+ const byOriginDest = rollup(flows, (ff) => {
818
+ const origin = flowAccessors.getFlowOriginId(ff[0]);
819
+ const dest = flowAccessors.getFlowDestId(ff[0]);
820
+ // const color = ff[0].color;
821
+ const rv = {
822
+ aggregate: true,
823
+ origin,
824
+ dest,
825
+ count: ff.reduce((m, f) => {
826
+ const count = flowAccessors.getFlowMagnitude(f);
827
+ if (count) {
828
+ if (!isNaN(count) && isFinite(count))
829
+ return m + count;
830
+ }
831
+ return m;
832
+ }, 0),
833
+ // time: undefined,
834
+ };
835
+ // if (color) rv.color = color;
836
+ return rv;
837
+ }, flowAccessors.getFlowOriginId, flowAccessors.getFlowDestId);
838
+ const rv = [];
839
+ for (const values of byOriginDest.values()) {
840
+ for (const value of values.values()) {
841
+ rv.push(value);
842
+ }
843
+ }
844
+ return rv;
845
+ }
846
+ /**
847
+ * This is used to augment hover picking info so that we can displace location tooltip
848
+ * @param circleAttributes
849
+ * @param index
850
+ */
851
+ export function getOuterCircleRadiusByIndex(circleAttributes, index) {
852
+ const { getInRadius, getOutRadius } = circleAttributes.attributes;
853
+ return Math.max(getInRadius.value[index], getOutRadius.value[index]);
854
+ }
855
+ export function getLocationCoordsByIndex(circleAttributes, index) {
856
+ const { getPosition } = circleAttributes.attributes;
857
+ return [getPosition.value[index * 2], getPosition.value[index * 2 + 1]];
858
+ }
859
+ export function getFlowLineAttributesByIndex(lineAttributes, index) {
860
+ const { getColor, getEndpointOffsets, getSourcePosition, getTargetPosition, getThickness, getStaggering, } = lineAttributes.attributes;
861
+ return {
862
+ length: 1,
863
+ attributes: Object.assign({ getColor: {
864
+ value: getColor.value.subarray(index * 4, (index + 1) * 4),
865
+ size: 4,
866
+ }, getEndpointOffsets: {
867
+ value: getEndpointOffsets.value.subarray(index * 2, (index + 1) * 2),
868
+ size: 2,
869
+ }, getSourcePosition: {
870
+ value: getSourcePosition.value.subarray(index * 2, (index + 1) * 2),
871
+ size: 2,
872
+ }, getTargetPosition: {
873
+ value: getTargetPosition.value.subarray(index * 2, (index + 1) * 2),
874
+ size: 2,
875
+ }, getThickness: {
876
+ value: getThickness.value.subarray(index, index + 1),
877
+ size: 1,
878
+ } }, (getStaggering
879
+ ? {
880
+ getStaggering: {
881
+ value: getStaggering.value.subarray(index, index + 1),
882
+ size: 1,
883
+ },
884
+ }
885
+ : undefined)),
886
+ };
887
+ }
888
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxvd21hcFNlbGVjdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9GbG93bWFwU2VsZWN0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDcEUsT0FBTyxFQUFjLFNBQVMsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNoRCxPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxFQUNMLGNBQWMsRUFDZCxxQkFBcUIsRUFDckIsY0FBYyxHQUVmLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDaEMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUNMLFVBQVUsRUFFVix3QkFBd0IsRUFFeEIsd0JBQXdCLEdBQ3pCLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxTQUFTLEVBQUUsRUFHaEIsYUFBYSxFQUNiLGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIsWUFBWSxFQUNaLGdCQUFnQixHQUNqQixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLHlCQUF5QixNQUFNLDZCQUE2QixDQUFDO0FBRXBFLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsc0JBQXNCLEdBQ3ZCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUNMLHVCQUF1QixFQUN2Qix5QkFBeUIsRUFDekIseUJBQXlCLEdBRTFCLE1BQU0sUUFBUSxDQUFDO0FBQ2hCLE9BQU8sRUFXTCxTQUFTLEVBQ1QscUJBQXFCLEVBRXJCLGtCQUFrQixHQUVuQixNQUFNLFNBQVMsQ0FBQztBQUVqQixNQUFNLHNCQUFzQixHQUFHLEVBQUUsQ0FBQztBQVNsQyxNQUFNLENBQUMsT0FBTyxPQUFPLGdCQUFnQjtJQUduQyxZQUFZLFNBQXFDO1FBU2pELHNCQUFpQixHQUFHLENBQUMsS0FBbUIsRUFBRSxLQUF3QixFQUFFLEVBQUUsQ0FDcEUsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUNkLDBCQUFxQixHQUFHLENBQUMsS0FBbUIsRUFBRSxLQUF3QixFQUFFLEVBQUUsQ0FDeEUsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUNsQiw4QkFBeUIsR0FBRyxDQUMxQixLQUFtQixFQUNuQixLQUF3QixFQUN4QixFQUFFO1lBQ0YsT0FBTyxLQUFLLENBQUMsYUFBYSxDQUFDO1FBQzdCLENBQUMsQ0FBQztRQUNGLDZCQUF3QixHQUFHLENBQUMsS0FBbUIsRUFBRSxLQUF3QixFQUFFLEVBQUUsQ0FDM0UsS0FBSyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQztRQUN2Qyx5QkFBb0IsR0FBRyxDQUFDLEtBQW1CLEVBQUUsS0FBd0IsRUFBRSxFQUFFLFdBQ3ZFLE9BQUEsTUFBQSxLQUFLLENBQUMsTUFBTSwwQ0FBRSxpQkFBaUIsQ0FBQSxFQUFBLENBQUM7UUFDbEMsMEJBQXFCLEdBQUcsQ0FBQyxLQUFtQixFQUFFLEtBQXdCLEVBQUUsRUFBRSxXQUN4RSxPQUFBLE1BQUEsS0FBSyxDQUFDLE1BQU0sMENBQUUsa0JBQWtCLENBQUEsRUFBQSxDQUFDO1FBQ25DLHlCQUFvQixHQUFHLENBQUMsS0FBbUIsRUFBRSxLQUF3QixFQUFFLEVBQUUsQ0FDdkUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQztRQUNuQyw2QkFBd0IsR0FBRyxDQUFDLEtBQW1CLEVBQUUsS0FBd0IsRUFBRSxFQUFFLENBQzNFLEtBQUssQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUM7UUFDdkMsWUFBTyxHQUFHLENBQUMsS0FBbUIsRUFBRSxLQUF3QixFQUFFLEVBQUUsQ0FDMUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFDdEIsZ0JBQVcsR0FBRyxDQUFDLEtBQW1CLEVBQUUsS0FBd0IsRUFBRSxFQUFFLENBQzlELEtBQUssQ0FBQyxRQUFRLENBQUM7UUFDakIseUJBQW9CLEdBQUcsQ0FBQyxLQUFtQixFQUFFLEtBQXdCLEVBQUUsRUFBRSxXQUN2RSxPQUFBLE1BQUEsS0FBSyxDQUFDLE1BQU0sMENBQUUsaUJBQWlCLENBQUEsRUFBQSxDQUFDO1FBRWxDLG1CQUFjLEdBQWtELENBQzlELEtBQW1CLEVBQ25CLEtBQXdCLEVBQ3hCLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztRQUVoQyxnQkFBVyxHQUE0QixDQUNyQyxLQUFtQixFQUNuQixLQUF3QixFQUN4QixFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFFN0IsbUJBQWMsR0FBNEIsQ0FDeEMsS0FBbUIsRUFDbkIsS0FBd0IsRUFDeEIsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDO1FBRWhDLDBCQUFxQixHQUE0QixDQUMvQyxLQUFtQixFQUNuQixLQUF3QixFQUN4QixFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztRQUV2QyxrQkFBYSxHQUEyQixDQUN0QyxLQUFtQixFQUNuQixLQUF3QixFQUN4QixFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7UUFFL0IsZUFBVSxHQUE0QixDQUNwQyxLQUFtQixFQUNuQixLQUF3QixFQUN4QixFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQztRQUVyQywwQkFBcUIsR0FBeUMsY0FBYyxDQUMxRSxJQUFJLENBQUMscUJBQXFCLEVBQzFCLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDWixJQUFJLENBQUMsU0FBUztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUNqQyxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDbkIsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUU7Z0JBQ2hDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNsRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDcEQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLEVBQUU7b0JBQzlELE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7aUJBQ2xCO2FBQ0Y7WUFDRCxPQUFPLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNsRCxDQUFDLENBQ0YsQ0FBQztRQUVGLGlCQUFZLEdBQTRDLGNBQWMsQ0FDcEUsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixJQUFJLENBQUMscUJBQXFCLEVBQzFCLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxFQUFFO1lBQ3hCLElBQUksQ0FBQyxTQUFTO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQzdELE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxHQUFRLEVBQUUsQ0FBQztZQUN6QixLQUFLLE1BQU0sUUFBUSxJQUFJLFNBQVMsRUFBRTtnQkFDaEMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFO29CQUNwQixRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUN6QjthQUNGO1lBQ0QsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQyxDQUNGLENBQUM7UUFFRixtQkFBYyxHQUE0QyxjQUFjLENBQ3RFLElBQUksQ0FBQyxZQUFZLEVBQ2pCLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDWixJQUFJLENBQUMsU0FBUztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUNqQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1lBQzlCLEtBQUssTUFBTSxFQUFFLElBQUksU0FBUyxFQUFFO2dCQUMxQixHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDM0M7WUFDRCxPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUMsQ0FDRixDQUFDO1FBRUYsNEJBQXVCLEdBQ3JCLGNBQWMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUNoRCxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQ2pELENBQUM7UUFFSixvQ0FBK0IsR0FDN0IsY0FBYyxDQUNaLElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsSUFBSSxDQUFDLGNBQWMsRUFDbkIsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDYixJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUNyQyxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7WUFDcEIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNuRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDakQsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUU7b0JBQ3BDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQ3JCO2FBQ0Y7WUFDRCxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFJLEVBQUUsQ0FBSSxFQUFFLEVBQUUsQ0FDbEMsVUFBVSxDQUNSLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUM1QyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDN0MsQ0FDRixDQUFDO1FBQ0osQ0FBQyxDQUNGLENBQUM7UUFFSix3QkFBbUIsR0FDakIsY0FBYyxDQUFDLElBQUksQ0FBQywrQkFBK0IsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzdELElBQUksQ0FBQyxLQUFLO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQzdCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQztZQUNqQixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUM7WUFDZixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtnQkFDeEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzlDLElBQUksSUFBSSxFQUFFO29CQUNSLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSTt3QkFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDO29CQUNoRCxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxHQUFHLElBQUk7d0JBQUUsR0FBRyxHQUFHLElBQUksQ0FBQztpQkFDM0M7YUFDRjtZQUNELElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxHQUFHO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ3JDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFFTCwwQkFBcUIsR0FDbkIsY0FBYyxDQUNaLElBQUksQ0FBQywrQkFBK0IsRUFDcEMsSUFBSSxDQUFDLG1CQUFtQixFQUN4QixDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtZQUNwQixJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsVUFBVTtnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUU1QyxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2hDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDdkQsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLFFBQVEsSUFBSSxJQUFJO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ3ZDLE1BQU0sZUFBZSxHQUFHLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVELE9BQU8sZUFBZSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDM0QsQ0FBQyxDQUNGLENBQUM7UUFFSixrQkFBYSxHQUE2QyxjQUFjLENBQ3RFLElBQUksQ0FBQyxtQkFBbUIsRUFDeEIsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixDQUFDLFVBQVUsRUFBRSxrQkFBa0IsRUFBRSxFQUFFO1lBQ2pDLE1BQU0sZUFBZSxHQUFHLGtCQUFrQjtnQkFDeEMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDLGtCQUFrQixDQUFDO2dCQUM3QyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2QsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUEsZUFBZSxhQUFmLGVBQWUsdUJBQWYsZUFBZSxDQUFFLFFBQVEsQ0FBQTtnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUNoRSxNQUFNLEVBQUMsUUFBUSxFQUFDLEdBQUcsZUFBZSxDQUFDO1lBQ25DLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUUsQ0FBQyxDQUNGLENBQUM7UUFFRixrREFBNkMsR0FJekMsY0FBYyxDQUNoQixJQUFJLENBQUMsK0JBQStCLEVBQ3BDLElBQUksQ0FBQyxhQUFhLEVBQ2xCLElBQUksQ0FBQyxvQkFBb0IsRUFDekIsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBQy9CLElBQUksQ0FBQyxLQUFLO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQzdCLElBQ0UsQ0FBQyxVQUFVO2dCQUNYLENBQUMsU0FBUztnQkFDVixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUNsRTtnQkFDQSxPQUFPLEtBQUssQ0FBQzthQUNkO1lBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQzNCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUM5QyxPQUFPLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLElBQUksR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0QsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQ0YsQ0FBQztRQUVGLDRCQUF1QixHQUNyQixjQUFjLENBQ1osSUFBSSxDQUFDLCtCQUErQixFQUNwQyxJQUFJLENBQUMsWUFBWSxFQUNqQixDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsRUFBRTtZQUNuQixJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsS0FBSztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUMzQyxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQzVCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO2dCQUN4QixTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzthQUNuRDtZQUNELE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQztZQUNwQixLQUFLLE1BQU0sUUFBUSxJQUFJLFNBQVMsRUFBRTtnQkFDaEMsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUU7b0JBQ3pELFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ3pCO2FBQ0Y7WUFDRCxPQUFPLFFBQVEsQ0FBQztRQUNsQixDQUFDLENBQ0YsQ0FBQztRQUVKLHFCQUFnQixHQUErQyxjQUFjLENBQzNFLElBQUksQ0FBQyx1QkFBdUIsRUFDNUIsQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUNaLElBQUksQ0FBQyxTQUFTO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ2pDLE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxFQUFhLENBQUM7WUFDM0MsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUU7Z0JBQ2hDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7YUFDckU7WUFDRCxPQUFPLGFBQWEsQ0FBQztRQUN2QixDQUFDLENBQ0YsQ0FBQztRQUVGLDRCQUF1QixHQUNyQixjQUFjLENBQUMsSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDN0QsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDN0IsTUFBTSxpQkFBaUIsR0FBRyx3QkFBd0IsQ0FDaEQsS0FBSyxFQUNMLElBQUksQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FDekMsQ0FBQztZQUNGLE9BQU8saUJBQWlCLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFFTCxxQkFBZ0IsR0FBOEMsY0FBYyxDQUMxRSxJQUFJLENBQUMseUJBQXlCLEVBQzlCLElBQUksQ0FBQyx1QkFBdUIsRUFDNUIsSUFBSSxDQUFDLHVCQUF1QixFQUM1QixDQUFDLHNCQUFzQixFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxFQUFFO1lBQ3ZELElBQUksc0JBQXNCO2dCQUFFLE9BQU8sc0JBQXNCLENBQUM7WUFDMUQsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLGlCQUFpQjtnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUN2RCxNQUFNLGFBQWEsR0FBRyxnQkFBZ0IsQ0FDcEMsU0FBUyxFQUNULElBQUksQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsRUFDeEMsaUJBQWlCLEVBQ2pCO2dCQUNFLE9BQU8sRUFBRSxzQkFBc0I7YUFDaEMsQ0FDRixDQUFDO1lBQ0YsT0FBTyxhQUFhLENBQUM7UUFDdkIsQ0FBQyxDQUNGLENBQUM7UUFFRixvQkFBZSxHQUFnRCxjQUFjLENBQzNFLElBQUksQ0FBQyxnQkFBZ0IsRUFDckIsSUFBSSxDQUFDLHVCQUF1QixFQUM1QixJQUFJLENBQUMsZ0JBQWdCLEVBQ3JCLENBQUMsYUFBYSxFQUFFLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxFQUFFO1lBQ2xELElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLGFBQWE7Z0JBQ3hELE9BQU8sU0FBUyxDQUFDO1lBRW5CLE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBSSxhQUFhLENBQUMsQ0FBQztZQUNsRCxNQUFNLEVBQUMsZUFBZSxFQUFFLHNCQUFzQixFQUFDLEdBQzdDLElBQUksQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztZQUUzQywwQkFBMEI7WUFDMUIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxFQUFVLEVBQUUsRUFBRTtnQkFDN0IsTUFBTSxHQUFHLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDbEMsSUFBSSxHQUFHLEVBQUU7b0JBQ1AsT0FBTyxlQUFlO3dCQUNwQixDQUFDLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQzt3QkFDdEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztpQkFDN0M7Z0JBQ0QsT0FBTyxJQUFJLEVBQUUsR0FBRyxDQUFDO1lBQ25CLENBQUMsQ0FBQztZQUNGLEtBQUssTUFBTSxLQUFLLElBQUksYUFBYSxFQUFFO2dCQUNqQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUU7b0JBQzlCLHlDQUF5QztvQkFDekMsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQ25CLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBRWhELE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FDbkIsVUFBVSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ3ZELENBQUM7d0JBRUYsSUFBSSxzQkFBc0IsRUFBRTs0QkFDMUIsSUFBSSxDQUFDLElBQUksR0FBRyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsQ0FBQzt5QkFDNUM7NkJBQU07NEJBQ0wsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUN4QixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7NEJBQzVELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQzVCLE9BQU87Z0NBQ0wsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHO2dDQUN6QixDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsU0FDMUIsRUFBRSxDQUFDO3lCQUNKO3FCQUNGO3lCQUFNO3dCQUNKLElBQVksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztxQkFDdkM7aUJBQ0Y7YUFDRjtZQUVELE9BQU8sWUFBWSxDQUFDO1FBQ3RCLENBQUMsQ0FDRixDQUFDO1FBRUYsa0NBQTZCLEdBQUcsY0FBYyxDQUM1QyxJQUFJLENBQUMsZUFBZSxFQUNwQixJQUFJLENBQUMsb0JBQW9CLEVBQ3pCLENBQUMsWUFBWSxFQUFFLGlCQUFpQixFQUF3QixFQUFFO1lBQ3hELElBQUksQ0FBQyxZQUFZLEVBQUU7Z0JBQ2pCLE9BQU8sU0FBUyxDQUFDO2FBQ2xCO1lBRUQsSUFBSSxPQUFPLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDO1lBQ3ZDLElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztZQUV2QyxNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQWMsRUFBRSxFQUFFO2dCQUNoQyxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNwRCxJQUFJLE9BQU8sRUFBRTtvQkFDWCxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUMxQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUMzQztxQkFBTTtvQkFDTCxNQUFNLElBQUksR0FBRyxZQUFZLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ3hELE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztpQkFDbkM7WUFDSCxDQUFDLENBQUM7WUFFRixJQUFJLGlCQUFpQixFQUFFO2dCQUNyQixLQUFLLE1BQU0sRUFBRSxJQUFJLGlCQUFpQixFQUFFO29CQUNsQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7aUJBQ1o7YUFDRjtZQUVELE9BQU8sWUFBWSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FDNUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLE9BQU8sSUFBSSxLQUFLLElBQUksS0FBSyxJQUFJLE9BQU8sQ0FDaEQsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO1FBRUYsb0JBQWUsR0FBdUMsY0FBYyxDQUNsRSxJQUFJLENBQUMsZUFBZSxFQUNwQixJQUFJLENBQUMsT0FBTyxFQUNaLElBQUksQ0FBQyw2QkFBNkIsRUFDbEMsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLEVBQUU7WUFDcEQsSUFBSSxDQUFDLFlBQVk7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDcEMsSUFBSSxDQUFDLDBCQUEwQixJQUFJLE9BQU8sSUFBSSxJQUFJLEVBQUU7Z0JBQ2xELE9BQU8sU0FBUyxDQUFDO2FBQ2xCO1lBRUQsTUFBTSxXQUFXLEdBQUcsd0JBQXdCLENBQzFDLDBCQUEwQixFQUMxQixPQUFPLENBQ1IsQ0FBQztZQUNGLE9BQU8sV0FBVyxDQUFDO1FBQ3JCLENBQUMsQ0FDRixDQUFDO1FBRUYsbUJBQWMsR0FBRyxDQUFDLEtBQW1CLEVBQUUsS0FBd0IsRUFBRSxFQUFFO1lBQ2pFLE1BQU0sRUFBQyxRQUFRLEVBQUMsR0FBRyxLQUFLLENBQUM7WUFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUI7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDbEQsSUFBSSxRQUFRLENBQUMsY0FBYyxJQUFJLFFBQVEsQ0FBQyxlQUFlLElBQUksSUFBSSxFQUFFO2dCQUMvRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzNDO1lBQ0QsT0FBTyxRQUFRLENBQUMsZUFBZSxDQUFDO1FBQ2xDLENBQUMsQ0FBQztRQUVGLDZCQUF3QixHQUN0QixjQUFjLENBQ1osSUFBSSxDQUFDLG9CQUFvQixFQUN6QixJQUFJLENBQUMsdUJBQXVCLEVBQzVCLElBQUksQ0FBQyxvQkFBb0IsRUFDekIsSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLGVBQWUsRUFDcEIsQ0FDRSxpQkFBaUIsRUFDakIsU0FBUyxFQUNULGlCQUFpQixFQUNqQixXQUFXLEVBQ1gsWUFBWSxFQUNaLEVBQUU7WUFDRixJQUFJLENBQUMsU0FBUztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUNqQyxJQUFJLE1BQU0sR0FBb0IsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNwRCwyQkFBMkI7WUFDM0Isd0JBQXdCO1lBQ3hCLHNFQUFzRTtZQUN0RSx1QkFBdUI7WUFDdkIsNkRBQTZEO1lBQzdELFFBQVE7WUFDUixNQUFNO1lBQ04sSUFBSTtZQUVKLElBQUksWUFBWSxJQUFJLGlCQUFpQixFQUFFO2dCQUNyQyxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7Z0JBQ3BCLEtBQUssTUFBTSxFQUFFLElBQUksaUJBQWlCLEVBQUU7b0JBQ2xDLE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ2hELElBQ0UsT0FBTzt3QkFDUCxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ1YsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNKLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDOzRCQUN2QixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7NEJBQ04sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUM5QyxFQUNEO3dCQUNBLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7cUJBQ3hCO2lCQUNGO2dCQUNELElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7b0JBQ3ZCLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUNsQzthQUNGO1lBQ0QsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQyxDQUNGLENBQUM7UUFFSixnQkFBVyxHQUE0QixjQUFjLENBQ25ELElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNSLElBQUksS0FBSyxFQUFFO2dCQUNULEtBQUssTUFBTSxDQUFDLElBQUksS0FBSyxFQUFFO29CQUNyQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFO3dCQUMxQyxPQUFPLElBQUksQ0FBQztxQkFDYjtpQkFDRjthQUNGO1lBQ0QsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDLENBQ0YsQ0FBQztRQUVGLHNCQUFpQixHQUFHLGNBQWMsQ0FDaEMsSUFBSSxDQUFDLFdBQVcsRUFDaEIsSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLFdBQVcsRUFDaEIsSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixJQUFJLENBQUMsYUFBYSxFQUNsQixJQUFJLENBQUMsVUFBVSxFQUNmLFNBQVMsQ0FDVixDQUFDO1FBRUYseUJBQW9CLEdBQUcsY0FBYyxDQUNuQyxJQUFJLENBQUMsaUJBQWlCLEVBQ3RCLENBQUMsYUFBYSxFQUFFLEVBQUU7WUFDaEIsT0FBTyxZQUFZLENBQUMsYUFBYSxDQUFDO2dCQUNoQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDO2dCQUNsQyxDQUFDLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FDRixDQUFDO1FBRUYsd0JBQW1CLEdBQTRDLGNBQWMsQ0FDM0UsSUFBSSxDQUFDLGNBQWMsRUFDbkIsSUFBSSxDQUFDLGlCQUFpQixFQUN0QixJQUFJLENBQUMsK0JBQStCLEVBQ3BDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ3JDLElBQ0Usc0JBQXNCO1lBQ3RCLG9EQUFvRDs7Z0JBRXBELE9BQU8sU0FBUyxDQUFDO1lBQ25CLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7WUFDbEMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNoRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUM5QyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7YUFDbkQ7WUFDRCxPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDLENBQ0YsQ0FBQztRQUVGLHFDQUFnQyxHQUk1QixjQUFjLENBQ2hCLElBQUksQ0FBQyxlQUFlLEVBQ3BCLElBQUksQ0FBQyxvQkFBb0IsRUFDekIsSUFBSSxDQUFDLDZDQUE2QyxFQUNsRCxJQUFJLENBQUMsY0FBYyxFQUNuQixJQUFJLENBQUMsYUFBYSxFQUNsQixDQUFDLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxFQUFFO1lBQ25FLElBQUksQ0FBQyxLQUFLO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQzdCLElBQUksVUFBaUMsQ0FBQztZQUN0QyxJQUFJLG1CQUFtQixJQUFJLFdBQVcsSUFBSSxXQUFXLElBQUksSUFBSSxFQUFFO2dCQUM3RCxVQUFVLEdBQUcsV0FBVyxDQUFDLGNBQWM7Z0JBQ3JDLDhCQUE4QjtnQkFDOUIscUJBQXFCO2dCQUNyQixrR0FBa0c7Z0JBQ2xHLGFBQWE7Z0JBQ2IsS0FBSyxFQUNMLFdBQVcsRUFDWCxJQUFJLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQ3pDLENBQUM7YUFDSDtpQkFBTTtnQkFDTCxVQUFVLEdBQUcsY0FBYyxDQUN6QixLQUFLLEVBQ0wsSUFBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRSxDQUN6QyxDQUFDO2FBQ0g7WUFDRCxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQ3ZCLFVBQVUsQ0FDUixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDNUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQzdDLENBQ0YsQ0FBQztZQUNGLE9BQU8sVUFBVSxDQUFDO1FBQ3BCLENBQUMsQ0FDRixDQUFDO1FBRUYsb0NBQStCLEdBQzdCLGNBQWMsQ0FDWixJQUFJLENBQUMsb0JBQW9CLEVBQ3pCLElBQUksQ0FBQyx1QkFBdUIsRUFDNUIsSUFBSSxDQUFDLGVBQWUsRUFDcEIsQ0FBQyxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsRUFBRTtZQUNyRCxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxZQUFZLEVBQUU7Z0JBQ3ZDLE9BQU8saUJBQWlCLENBQUM7YUFDMUI7WUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1lBQ2pDLEtBQUssTUFBTSxVQUFVLElBQUksaUJBQWlCLEVBQUU7Z0JBQzFDLE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ3hELElBQUksT0FBTyxFQUFFO29CQUNYLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3JELEtBQUssTUFBTSxFQUFFLElBQUksUUFBUSxFQUFFO3dCQUN6QixNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3FCQUNoQjtpQkFDRjtxQkFBTTtvQkFDTCxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2lCQUN4QjthQUNGO1lBQ0QsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQyxDQUNGLENBQUM7UUFFSix5QkFBb0IsR0FDbEIsY0FBYyxDQUNaLElBQUksQ0FBQywrQkFBK0IsRUFDcEMsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixJQUFJLENBQUMsYUFBYSxFQUNsQixJQUFJLENBQUMsK0JBQStCLEVBQ3BDLElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsQ0FDRSxLQUFLLEVBQ0wsa0JBQWtCLEVBQ2xCLFVBQVUsRUFDVixtQkFBbUIsRUFDbkIsa0JBQWtCLEVBQ2xCLEVBQUU7WUFDRixNQUFNLGVBQWUsR0FBRyxrQkFBa0I7Z0JBQ3hDLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDN0MsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNkLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxlQUFlLElBQUksQ0FBQyxVQUFVO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ2hFLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUU7O2dCQUN0QyxJQUNFLElBQUksQ0FBQyxpQkFBaUIsQ0FDcEIsSUFBSSxFQUNKLG1CQUFtQixFQUNuQixrQkFBa0IsQ0FDbkIsRUFDRDtvQkFDQSxNQUFNLEdBQUcsR0FBRyxlQUFlO3lCQUN4QixRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7eUJBQzFDLE9BQU8sRUFBRSxDQUFDO29CQUNiLENBQUMsQ0FBQyxHQUFHLENBQ0gsR0FBRyxFQUNILENBQUMsTUFBQSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxtQ0FBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUMxRCxDQUFDO2lCQUNIO2dCQUNELE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQyxFQUFFLElBQUksR0FBRyxFQUFrQixDQUFDLENBQUM7WUFFOUIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM1RCxJQUFJLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO2dCQUN0QixLQUFLO2FBQ04sQ0FBQyxDQUFDLENBQUM7UUFDTixDQUFDLENBQ0YsQ0FBQztRQUVKLDZCQUF3QixHQUEyQixjQUFjLENBQy9ELElBQUksQ0FBQyx3QkFBd0IsRUFDN0IsQ0FBQyxxQkFBcUIsRUFBRSxFQUFFLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDNUQsQ0FBQztRQUVGLDJCQUFzQixHQUNwQixjQUFjLENBQ1osSUFBSSxDQUFDLFdBQVcsRUFDaEIsSUFBSSxDQUFDLHdCQUF3QixFQUM3QixzQkFBc0IsQ0FDdkIsQ0FBQztRQUVKLHdCQUFtQixHQUNqQixjQUFjLENBQ1osSUFBSSxDQUFDLG9CQUFvQixFQUN6QixJQUFJLENBQUMsdUJBQXVCLEVBQzVCLElBQUksQ0FBQyxlQUFlLEVBQ3BCLElBQUksQ0FBQyxjQUFjLEVBQ25CLENBQUMsaUJBQWlCLEVBQUUsb0JBQW9CLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxFQUFFO1lBQ3JFLElBQUksaUJBQWlCLElBQUksWUFBWSxFQUFFO2dCQUNyQyxPQUFPLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUNyRDtpQkFBTTtnQkFDTCxPQUFPLG9CQUFvQixDQUFDO2FBQzdCO1FBQ0gsQ0FBQyxDQUNGLENBQUM7UUFFSixzQkFBaUIsR0FDZixjQUFjLENBQ1osSUFBSSxDQUFDLG1CQUFtQixFQUN4QixJQUFJLENBQUMsZ0NBQWdDLEVBQ3JDLElBQUksQ0FBQyx1QkFBdUIsRUFDNUIsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLEVBQUUsRUFBRTtZQUM3RCxJQUFJLENBQUMsS0FBSztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUM3QixNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBMEIsQ0FBQztZQUNqRCxNQUFNLEdBQUcsR0FBRyxDQUNWLEVBQVUsRUFDVixDQUEwQixFQUNWLEVBQUU7O2dCQUNsQixNQUFNLEVBQUUsR0FBRyxNQUFBLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLG1DQUFJO29CQUMzQixhQUFhLEVBQUUsQ0FBQztvQkFDaEIsYUFBYSxFQUFFLENBQUM7b0JBQ2hCLGFBQWEsRUFBRSxDQUFDO2lCQUNqQixDQUFDO2dCQUNGLElBQUksQ0FBQyxDQUFDLGFBQWEsSUFBSSxJQUFJO29CQUFFLEVBQUUsQ0FBQyxhQUFhLElBQUksQ0FBQyxDQUFDLGFBQWEsQ0FBQztnQkFDakUsSUFBSSxDQUFDLENBQUMsYUFBYSxJQUFJLElBQUk7b0JBQUUsRUFBRSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsYUFBYSxDQUFDO2dCQUNqRSxJQUFJLENBQUMsQ0FBQyxhQUFhLElBQUksSUFBSTtvQkFBRSxFQUFFLENBQUMsYUFBYSxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUM7Z0JBQ2pFLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxDQUFDO1lBQ0YsS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLEVBQUU7Z0JBQ3JCLElBQ0UsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxrQkFBa0IsQ0FBQyxFQUNuRTtvQkFDQSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbkQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQy9DLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ2pELElBQUksUUFBUSxLQUFLLE1BQU0sRUFBRTt3QkFDdkIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVEsRUFBRSxFQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDLENBQUM7cUJBQzdEO3lCQUFNO3dCQUNMLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBQyxhQUFhLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUM1RCxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUMsYUFBYSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUMsQ0FBQztxQkFDekQ7aUJBQ0Y7YUFDRjtZQUNELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUMsQ0FDRixDQUFDO1FBRUoscUJBQWdCLEdBQStCLGNBQWMsQ0FDM0QsSUFBSSxDQUFDLG1CQUFtQixFQUN4QixDQUFDLFNBQVMsRUFBRSxFQUFFO1lBQ1osSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDZCxPQUFPLFNBQVMsQ0FBQzthQUNsQjtZQUNELE9BQU8sSUFBSSxNQUFNO1lBQ2YsYUFBYTtZQUNiLFNBQVMsRUFDVCxDQUFDLFFBQXlCLEVBQUUsRUFBRSxDQUM1QixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUMsRUFDL0MsQ0FBQyxRQUF5QixFQUFFLEVBQUUsQ0FDNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQ2hELENBQUM7UUFDSixDQUFDLENBQ0YsQ0FBQztRQUVGLDhCQUF5QixHQUN2QixjQUFjLENBQ1osSUFBSSxDQUFDLGdCQUFnQixFQUNyQixJQUFJLENBQUMsc0JBQXNCLEVBQzNCLENBQUMsSUFBZ0IsRUFBRSxJQUFzQyxFQUFFLEVBQUU7WUFDM0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLDBCQUEwQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN4RCxJQUFJLEdBQUcsRUFBRTtnQkFDUCxPQUFPLElBQUksR0FBRyxDQUNaLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFXLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFrQixDQUMvRCxDQUFDO2FBQ0g7WUFDRCxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDLENBQ0YsQ0FBQztRQUVKLDZCQUF3QixHQUN0QixxQkFBcUIsQ0FDbkIsY0FBYztRQUNkLGFBQWE7UUFDYixDQUNFLEVBQTJCLEVBQzNCLEVBQTJCLEVBQzNCLEtBQWEsRUFDYixFQUFFO1lBQ0YsSUFBSSxFQUFFLEtBQUssRUFBRTtnQkFBRSxPQUFPLElBQUksQ0FBQztZQUMzQixJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksRUFBRSxJQUFJLElBQUk7Z0JBQUUsT0FBTyxLQUFLLENBQUM7WUFDM0MsSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxJQUFJO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBQ3RDLEtBQUssTUFBTSxJQUFJLElBQUksRUFBRTtnQkFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7b0JBQUUsT0FBTyxLQUFLLENBQUM7WUFDdkQsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDLENBQ0YsQ0FDQyxJQUFJLENBQUMseUJBQXlCLEVBQzlCLENBQUMsV0FBb0MsRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxXQUFXO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ25DLE9BQU8sV0FBVyxDQUFDO1FBQ3JCLENBQUMsQ0FDRixDQUFDO1FBRUosNEJBQXVCLEdBQXVDLGNBQWMsQ0FDMUUsSUFBSSxDQUFDLCtCQUErQixFQUNwQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ1IsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDN0IsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUNqQixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUN0RCxDQUFDLENBQ0YsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO1FBRUYsMEJBQXFCLEdBQXVDLGNBQWMsQ0FDeEUsSUFBSSxDQUFDLGdDQUFnQyxFQUNyQyxJQUFJLENBQUMsdUJBQXVCLEVBQzVCLElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsRUFBRTtZQUNqRCxJQUFJLENBQUMsS0FBSztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUM3QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFO2dCQUNyQyxJQUNFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLENBQUMsRUFDckU7b0JBQ0EsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztpQkFDbEQ7Z0JBQ0QsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDTixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsQ0FDRixDQUFDO1FBRUYsNkJBQXdCLEdBQ3RCLGNBQWMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUN4RCx3QkFBd0IsQ0FBQyxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQ3BELENBQUM7UUFFSix3Q0FBbUMsR0FJL0IsY0FBYyxDQUNoQixJQUFJLENBQUMsaUJBQWlCLEVBQ3RCLElBQUksQ0FBQyx3QkFBd0IsRUFDN0IsQ0FBQyxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsRUFBRSxDQUN0Qyx3QkFBd0IsQ0FBQyxjQUFjLEVBQUUsbUJBQW1CLENBQUMsQ0FDaEUsQ0FBQztRQUVGLDRCQUF1QixHQUFHLENBQ3hCLEtBQW1CLEVBQ25CLEtBQXdCLEVBQ00sRUFBRTtZQUNoQyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMscUJBQXFCLEVBQUU7Z0JBQ3hDLE9BQU8sSUFBSSxDQUFDLG1DQUFtQyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQzthQUMvRDtpQkFBTTtnQkFDTCxPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDcEQ7UUFDSCxDQUFDLENBQUM7UUFFRiw0QkFBdUIsR0FDckIsY0FBYyxDQUNaLElBQUksQ0FBQyxnQ0FBZ0MsRUFDckMsSUFBSSxDQUFDLHdCQUF3QixFQUM3QixJQUFJLENBQUMsdUJBQXVCLEVBQzVCLElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsSUFBSSxDQUFDLHdCQUF3QixFQUM3QixDQUNFLEtBQUssRUFDTCxxQkFBcUIsRUFDckIsb0JBQW9CLEVBQ3BCLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsRUFBRTtZQUNGLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxxQkFBcUI7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDdkQsTUFBTSxNQUFNLEdBQTBCLEVBQUUsQ0FBQztZQUN6QyxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUM7WUFDcEIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNwRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDaEQsSUFDRSxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDO29CQUNqQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQy9CO29CQUNBLElBQ0UsSUFBSSxDQUFDLGlCQUFpQixDQUNwQixJQUFJLEVBQ0osb0JBQW9CLEVBQ3BCLGtCQUFrQixDQUNuQixFQUNEO3dCQUNBLElBQUksTUFBTSxLQUFLLElBQUksRUFBRTs0QkFDbkIscUJBQXFCOzRCQUNyQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDOzRCQUNsQixXQUFXLEVBQUUsQ0FBQzt5QkFDZjtxQkFDRjtpQkFDRjtnQkFDRCxnQkFBZ0I7Z0JBQ2hCLElBQUksV0FBVyxHQUFHLHFCQUFxQjtvQkFBRSxNQUFNO2FBQ2hEO1lBQ0QsZ0RBQWdEO1lBQ2hELGtDQUFrQztZQUNsQyxPQUFPLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQ0YsQ0FBQztRQUVKLDRCQUF1QixHQUNyQixjQUFjLENBQ1osSUFBSSxDQUFDLGdDQUFnQyxFQUNyQyxJQUFJLENBQUMsdUJBQXVCLEVBQzVCLElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsQ0FBQyxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLEVBQUUsRUFBRTtZQUNsRCxJQUFJLENBQUMsS0FBSztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUM3QixJQUFJLEVBQUUsR0FBaUMsU0FBUyxDQUFDO1lBQ2pELEtBQUssTUFBTSxDQUFDLElBQUksS0FBSyxFQUFFO2dCQUNyQixJQUNFLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztvQkFDL0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO29CQUNqQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixDQUFDLEVBQ25FO29CQUNBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ2pELElBQUksRUFBRSxJQUFJLElBQUksRUFBRTt3QkFDZCxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7cUJBQ3JCO3lCQUFNO3dCQUNMLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7NEJBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQzt3QkFDakMsSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQzs0QkFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO3FCQUNsQztpQkFDRjthQUNGO1lBQ0QsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDLENBQ0YsQ0FBQztRQUVKLG9DQUErQixHQUkzQixjQUFjLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDekQsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDN0IsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDMUQsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3JFLENBQUMsQ0FBQyxDQUFDO1FBRUgsMkJBQXNCLEdBQUcsQ0FDdkIsS0FBbUIsRUFDbkIsS0FBd0IsRUFDTSxFQUFFO1lBQ2hDLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtnQkFDeEMsT0FBTyxJQUFJLENBQUMsK0JBQStCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzNEO2lCQUFNO2dCQUNMLE9BQU8sSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNuRDtRQUNILENBQUMsQ0FBQztRQUVGLGlDQUE0QixHQUFHLGNBQWMsQ0FDM0MsSUFBSSxDQUFDLGlCQUFpQixFQUN0QixDQUFDLGNBQWMsRUFBRSxFQUFFO1lBQ2pCLE9BQU8sQ0FBQyxVQUFrQixFQUFFLEVBQUU7Z0JBQzVCLE1BQU0sS0FBSyxHQUFHLGNBQWMsYUFBZCxjQUFjLHVCQUFkLGNBQWMsQ0FBRSxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQzlDLElBQUksQ0FBQyxLQUFLO29CQUFFLE9BQU8sU0FBUyxDQUFDO2dCQUM3QixPQUFPLElBQUksQ0FBQyxHQUFHLENBQ2IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsRUFDbkQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FDcEQsQ0FBQztZQUNKLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO1FBRUYsMEJBQXFCLEdBQUcsY0FBYyxDQUNwQyxJQUFJLENBQUMsc0JBQXNCLEVBQzNCLHFCQUFxQixDQUN0QixDQUFDO1FBRUYsdUJBQWtCLEdBQUcsY0FBYyxDQUNqQyxJQUFJLENBQUMsd0JBQXdCLEVBQzdCLElBQUksQ0FBQyx3QkFBd0IsRUFDN0IsSUFBSSxDQUFDLHVCQUF1QixFQUM1QixDQUFDLHFCQUFxQixFQUFFLHFCQUFxQixFQUFFLG9CQUFvQixFQUFFLEVBQUU7WUFDckUsSUFBSSxDQUFDLHFCQUFxQixFQUFFO2dCQUMxQixPQUFPLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDO2FBQ3BDO1lBQ0QsSUFBSSxDQUFDLG9CQUFvQjtnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUM1QyxPQUFPLFNBQVMsRUFBRTtpQkFDZixLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUscUJBQXFCLENBQUMsQ0FBQztpQkFDakMsTUFBTSxDQUFDO2dCQUNOLENBQUM7Z0JBQ0QsK0JBQStCO2dCQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixJQUFJLEVBQ0osb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBcUIsRUFBRSxFQUFFLENBQ2pELElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUNqQixDQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUNGLENBQUM7UUFFRiwwQkFBcUIsR0FBRyxjQUFjLENBQ3BDLElBQUksQ0FBQyxrQkFBa0IsRUFDdkIsSUFBSSxDQUFDLGlCQUFpQixFQUN0QixDQUFDLGVBQWUsRUFBRSxjQUFjLEVBQUUsRUFBRTtZQUNsQyxPQUFPLENBQUMsVUFBa0IsRUFBRSxFQUFFO2dCQUM1QixNQUFNLEtBQUssR0FBRyxjQUFjLGFBQWQsY0FBYyx1QkFBZCxjQUFjLENBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUM5QyxJQUFJLEtBQUssSUFBSSxlQUFlLEVBQUU7b0JBQzVCLE9BQU8sQ0FDTCxlQUFlLENBQ2IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FDcEQsSUFBSSxDQUFDLENBQ1AsQ0FBQztpQkFDSDtnQkFDRCxPQUFPLENBQUMsQ0FBQztZQUNYLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO1FBRUYsMkJBQXNCLEdBQUcsY0FBYyxDQUNyQyxJQUFJLENBQUMsa0JBQWtCLEVBQ3ZCLElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsQ0FBQyxlQUFlLEVBQUUsY0FBYyxFQUFFLEVBQUU7WUFDbEMsT0FBTyxDQUFDLFVBQWtCLEVBQUUsRUFBRTtnQkFDNUIsTUFBTSxLQUFLLEdBQUcsY0FBYyxhQUFkLGNBQWMsdUJBQWQsY0FBYyxDQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDOUMsSUFBSSxLQUFLLElBQUksZUFBZSxFQUFFO29CQUM1QixPQUFPLENBQ0wsZUFBZSxDQUNiLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQ3BELElBQUksQ0FBQyxDQUNQLENBQUM7aUJBQ0g7Z0JBQ0QsT0FBTyxDQUFDLENBQUM7WUFDWCxDQUFDLENBQUM7UUFDSixDQUFDLENBQ0YsQ0FBQztRQUVGLDhCQUF5QixHQUN2QixjQUFjLENBQ1osSUFBSSxDQUFDLG1CQUFtQixFQUN4QixJQUFJLENBQUMscUJBQXFCLEVBQzFCLElBQUksQ0FBQyxzQkFBc0IsRUFDM0IsQ0FBQyxTQUFTLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLEVBQUU7WUFDL0MsSUFBSSxDQUFDLFNBQVM7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDakMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBd0IsQ0FBQztZQUM1RCxPQUFPLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM1QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDNUMsT0FBTyxTQUFTLENBQ2QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsRUFDckQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FDdEQsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUNGLENBQUM7UUFFSixnQ0FBMkIsR0FJdkIsY0FBYyxDQUNoQixJQUFJLENBQUMseUJBQXlCO1FBQzlCLGlDQUFpQztRQUNqQyxDQUNFLFNBQVMsRUFFVCxFQUFFO1lBQ0Ysb0NBQW9DO1lBQ3BDLGdEQUFnRDtZQUNoRCx5RUFBeUU7WUFDekUsdUJBQXVCO1lBQ3ZCLGlDQUFpQztZQUNqQyw2Q0FBNkM7WUFDN0MsMEJBQTBCO1lBQzFCLE1BQU07WUFDTixJQUFJO1lBQ0osbUJBQW1CO1lBQ25CLGFBQWE7WUFDYiwyQkFBMkI7WUFDM0IsaUVBQWlFO1lBQ2pFLEtBQUs7WUFDTCx1REFBdUQ7WUFDdkQsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQyxDQUNGLENBQUM7UUFFRixvQ0FBK0IsR0FJM0IsY0FBYyxDQUFDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDLFNBQVMsRUFBRSxFQUFFO1lBQ2pFLElBQUksQ0FBQyxTQUFTO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQ2pDLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FDckIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQ3hELElBQUksR0FBRyxFQUFFLENBQ1YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsa0JBQWEsR0FBK0IsY0FBYyxDQUN4RCxJQUFJLENBQUMsMkJBQTJCLEVBQ2hDLElBQUksQ0FBQyx1QkFBdUIsRUFDNUIsSUFBSSxDQUFDLG9CQUFvQixFQUN6QixJQUFJLENBQUMsK0JBQStCLEVBQ3BDLElBQUksQ0FBQyx3QkFBd0IsRUFDN0IsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixJQUFJLENBQUMsc0JBQXNCLEVBQzNCLElBQUksQ0FBQyxxQkFBcUIsRUFDMUIsSUFBSSxDQUFDLFVBQVUsRUFDZixDQUNFLFNBQVMsRUFDVCxLQUFLLEVBQ0wsYUFBYSxFQUNiLGFBQWEsRUFDYixxQkFBcUIsRUFDckIsZUFBZSxFQUNmLGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsZ0JBQWdCLEVBQ2hCLEVBQUU7WUFDRixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FDNUIsU0FBUyxFQUNULEtBQUssRUFDTCxhQUFhLEVBQ2IsYUFBYSxFQUNiLHFCQUFxQixFQUNyQixlQUFlLEVBQ2YsZ0JBQWdCLEVBQ2hCLGtCQUFrQixFQUNsQixnQkFBZ0IsQ0FDakIsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO1FBeGhDQSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUkseUJBQXlCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQsWUFBWSxDQUFDLFNBQXFDO1FBQ2hELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSx5QkFBeUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBb2hDRCxpQkFBaUIsQ0FBQyxLQUFtQixFQUFFLEtBQXdCO1FBQzdELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZFLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQy9ELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDOUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLCtCQUErQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6RSxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDMUUsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNqRSxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbkUsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3BFLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUM1QixTQUFTLEVBQ1QsS0FBSyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IscUJBQXFCLEVBQ3JCLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsa0JBQWtCLEVBQ2xCLEtBQUssQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQ2hDLENBQUM7SUFDSixDQUFDO0lBRUQsa0JBQWtCLENBQ2hCLFNBQTBDLEVBQzFDLEtBQXdDLEVBQ3hDLGFBQTBDLEVBQzFDLGFBQXVELEVBQ3ZELHFCQUE4QyxFQUM5QyxlQUErQyxFQUMvQyxnQkFBZ0QsRUFDaEQsa0JBQWtFLEVBQ2xFLGdCQUF5QjtRQUV6QixJQUFJLENBQUMsU0FBUztZQUFFLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLEtBQUs7WUFBRSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sRUFDSixlQUFlLEVBQ2YsYUFBYSxFQUNiLGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsY0FBYyxFQUNkLGNBQWMsR0FDZixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFFbkIsTUFBTSxtQkFBbUIsR0FBRyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FHbkUsQ0FBQztRQUNGLE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUN0QyxhQUFhLEVBQ2IsbUJBQW1CLEVBQ25CLEtBQUssQ0FDTixDQUFDO1FBRUYscUVBQXFFO1FBQ3JFLE1BQU0sZUFBZSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQ3ZDLENBQUMsUUFBUSxDQUFDO1lBQ1IsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUU7Z0JBQ2hDLE1BQU0sY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUMvQixNQUFNLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNoQztRQUNILENBQUMsQ0FBQyxFQUFFLENBQ0wsQ0FBQztRQUVGLGtCQUFrQjtRQUNsQixNQUFNLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUM7WUFDakQsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEtBQUs7WUFDOUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDO1FBRXhDLE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQ2xDLENBQUMsUUFBUSxDQUFDO1lBQ1IsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUU7Z0JBQ2hDLEtBQUssQ0FBQyxDQUFDLFdBQVcsQ0FBQzthQUNwQjtRQUNILENBQUMsQ0FBQyxFQUFFLENBQ0wsQ0FBQztRQUVGLE1BQU0sYUFBYSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQ3JDLENBQUMsUUFBUSxDQUFDO1lBQ1IsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUU7Z0JBQ2hDLE1BQU0sRUFBRSxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDbkMsTUFBTSxDQUFBLHFCQUFxQixhQUFyQixxQkFBcUIsdUJBQXJCLHFCQUFxQixDQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7YUFDbEU7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUNMLENBQUM7UUFDRixNQUFNLGNBQWMsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUN0QyxDQUFDLFFBQVEsQ0FBQztZQUNSLEtBQUssTUFBTSxRQUFRLElBQUksU0FBUyxFQUFFO2dCQUNoQyxNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ25DLE1BQU0sQ0FBQSxxQkFBcUIsYUFBckIscUJBQXFCLHVCQUFyQixxQkFBcUIsQ0FBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7YUFDbkU7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUNMLENBQUM7UUFFRixNQUFNLGVBQWUsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUN2QyxDQUFDLFFBQVEsQ0FBQztZQUNSLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO2dCQUN4QixNQUFNLEdBQUcsR0FBRyxhQUFhLGFBQWIsYUFBYSx1QkFBYixhQUFhLENBQUUsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUN0RCxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNyQztRQUNILENBQUMsQ0FBQyxFQUFFLENBQ0wsQ0FBQztRQUNGLE1BQU0sZUFBZSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQ3ZDLENBQUMsUUFBUSxDQUFDO1lBQ1IsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLE1BQU0sR0FBRyxHQUFHLGFBQWEsYUFBYixhQUFhLHVCQUFiLGFBQWEsQ0FBRSxHQUFHLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDcEMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3JDO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FDTCxDQUFDO1FBQ0YsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FDbkMsQ0FBQyxRQUFRLENBQUM7WUFDUixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtnQkFDeEIsTUFBTSxrQkFBa0I7b0JBQ3RCLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ2pELENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDUDtRQUNILENBQUMsQ0FBQyxFQUFFLENBQ0wsQ0FBQztRQUNGLE1BQU0sZUFBZSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQ3ZDLENBQUMsUUFBUSxDQUFDO1lBQ1IsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLE1BQU0sUUFBUSxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDdkMsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNuQyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RFLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzthQUNuRTtRQUNILENBQUMsQ0FBQyxFQUFFLENBQ0wsQ0FBQztRQUNGLE1BQU0sY0FBYyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQ3BDLENBQUMsUUFBUSxDQUFDO1lBQ1IsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7Z0JBQ3hCLEtBQUssQ0FBQyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQy9DO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FDTCxDQUFDO1FBRUYsTUFBTSxnQkFBZ0IsR0FBRyxnQkFBZ0I7WUFDdkMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQ2YsQ0FBQyxRQUFRLENBQUM7Z0JBQ1IsS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLEVBQUU7b0JBQ3JCLGFBQWE7b0JBQ2IsTUFBTSxJQUFJLElBQUksQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxhQUFhLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7aUJBQy9EO1lBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FDTDtZQUNILENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFZCxPQUFPO1lBQ0wsZ0JBQWdCLEVBQUU7Z0JBQ2hCLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTTtnQkFDeEIsVUFBVSxFQUFFO29CQUNWLFdBQVcsRUFBRSxFQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBQztvQkFDOUMsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFDO29CQUN4QyxXQUFXLEVBQUUsRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUM7b0JBQzVDLFlBQVksRUFBRSxFQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBQztpQkFDL0M7YUFDRjtZQUNELGNBQWMsRUFBRTtnQkFDZCxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07Z0JBQ3BCLFVBQVUsa0JBQ1IsaUJBQWlCLEVBQUUsRUFBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUMsRUFDcEQsaUJBQWlCLEVBQUUsRUFBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUMsRUFDcEQsWUFBWSxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFDLEVBQzNDLFFBQVEsRUFBRSxFQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBQyxFQUMxQyxrQkFBa0IsRUFBRSxFQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBQyxJQUNsRCxDQUFDLGdCQUFnQjtvQkFDbEIsQ0FBQyxDQUFDLEVBQUMsYUFBYSxFQUFFLEVBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFFLElBQUksRUFBRSxDQUFDLEVBQUMsRUFBQztvQkFDckQsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUNSO2FBQ0Y7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELGtCQUFrQixDQUNoQixJQUFnQixFQUNoQixJQUFzQztRQUV0QyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQzVCLE9BQU8sSUFBSSxDQUFDLDBCQUEwQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQ3BELENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUN0QixDQUFDO0lBQ2hCLENBQUM7SUFFRCwwQkFBMEIsQ0FDeEIsSUFBZ0IsRUFDaEIsSUFBc0M7UUFFdEMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUM1QixNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3RDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FDZixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFDaEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUNoQixJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FDakIsQ0FBQztJQUNKLENBQUM7SUFFRCxpQkFBaUIsQ0FDZixJQUF1QixFQUN2QixvQkFBNkMsRUFDN0Msa0JBQXVDO1FBRXZDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hELElBQUksb0JBQW9CLEVBQUU7WUFDeEIsUUFBUSxrQkFBa0IsRUFBRTtnQkFDMUIsS0FBSyxrQkFBa0IsQ0FBQyxHQUFHO29CQUN6QixPQUFPLENBQ0wsb0JBQW9CLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FDbkUsQ0FBQztnQkFDSixLQUFLLGtCQUFrQixDQUFDLE9BQU87b0JBQzdCLE9BQU8sQ0FDTCxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUNuRSxDQUFDO2dCQUNKLEtBQUssa0JBQWtCLENBQUMsUUFBUTtvQkFDOUIsT0FBTyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3hDLEtBQUssa0JBQWtCLENBQUMsUUFBUTtvQkFDOUIsT0FBTyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDM0M7U0FDRjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztDQXNCRjtBQUVELFNBQVMsd0JBQXdCLENBQy9CLGNBQXVELEVBQ3ZELHFCQUE4QztJQUU5QyxJQUFJLENBQUMsY0FBYztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3RDLElBQUksRUFBRSxHQUFpQyxTQUFTLENBQUM7SUFDakQsS0FBSyxNQUFNLENBQ1QsRUFBRSxFQUNGLEVBQUMsYUFBYSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUMsRUFDOUMsSUFBSSxjQUFjLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDN0IsSUFBSSxxQkFBcUIsSUFBSSxJQUFJLElBQUkscUJBQXFCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ2xFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQ2pCLGFBQWEsR0FBRyxhQUFhLEVBQzdCLGFBQWEsR0FBRyxhQUFhLEVBQzdCLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FDakIsYUFBYSxHQUFHLGFBQWEsRUFDN0IsYUFBYSxHQUFHLGFBQWEsRUFDN0IsYUFBYSxDQUNkLENBQUM7WUFDRixJQUFJLENBQUMsRUFBRSxFQUFFO2dCQUNQLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQzthQUNmO2lCQUFNO2dCQUNMLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO2FBQzVCO1NBQ0Y7S0FDRjtJQUNELE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQztBQUVELDJEQUEyRDtBQUMzRCxTQUFTLElBQUksQ0FBQyxHQUFXO0lBQ3ZCLE9BQU8sR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDekIsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFDLEdBQVc7SUFDdkIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDNUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDbkUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FDckIsS0FBVSxFQUNWLGFBQStCO0lBRS9CLHNDQUFzQztJQUN0QyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQ3pCLEtBQUssRUFDTCxDQUFDLEVBQU8sRUFBRSxFQUFFO1FBQ1YsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRCxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELDZCQUE2QjtRQUM3QixNQUFNLEVBQUUsR0FBa0I7WUFDeEIsU0FBUyxFQUFFLElBQUk7WUFDZixNQUFNO1lBQ04sSUFBSTtZQUNKLEtBQUssRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUN4QixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hELElBQUksS0FBSyxFQUFFO29CQUNULElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQzt3QkFBRSxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUM7aUJBQ3hEO2dCQUNELE9BQU8sQ0FBQyxDQUFDO1lBQ1gsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNMLG1CQUFtQjtTQUNwQixDQUFDO1FBQ0YsK0JBQStCO1FBQy9CLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQyxFQUNELGFBQWEsQ0FBQyxlQUFlLEVBQzdCLGFBQWEsQ0FBQyxhQUFhLENBQzVCLENBQUM7SUFFRixNQUFNLEVBQUUsR0FBb0IsRUFBRSxDQUFDO0lBQy9CLEtBQUssTUFBTSxNQUFNLElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQzFDLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ25DLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDaEI7S0FDRjtJQUNELE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsMkJBQTJCLENBQ3pDLGdCQUE0QyxFQUM1QyxLQUFhO0lBRWIsTUFBTSxFQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7SUFDaEUsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsWUFBWSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFFRCxNQUFNLFVBQVUsd0JBQXdCLENBQ3RDLGdCQUE0QyxFQUM1QyxLQUFhO0lBRWIsTUFBTSxFQUFDLFdBQVcsRUFBQyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQztJQUNsRCxPQUFPLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUUsQ0FBQztBQUVELE1BQU0sVUFBVSw0QkFBNEIsQ0FDMUMsY0FBd0MsRUFDeEMsS0FBYTtJQUViLE1BQU0sRUFDSixRQUFRLEVBQ1Isa0JBQWtCLEVBQ2xCLGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIsWUFBWSxFQUNaLGFBQWEsR0FDZCxHQUFHLGNBQWMsQ0FBQyxVQUFVLENBQUM7SUFDOUIsT0FBTztRQUNMLE1BQU0sRUFBRSxDQUFDO1FBQ1QsVUFBVSxrQkFDUixRQUFRLEVBQUU7Z0JBQ1IsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMxRCxJQUFJLEVBQUUsQ0FBQzthQUNSLEVBQ0Qsa0JBQWtCLEVBQUU7Z0JBQ2xCLEtBQUssRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNwRSxJQUFJLEVBQUUsQ0FBQzthQUNSLEVBQ0QsaUJBQWlCLEVBQUU7Z0JBQ2pCLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNuRSxJQUFJLEVBQUUsQ0FBQzthQUNSLEVBQ0QsaUJBQWlCLEVBQUU7Z0JBQ2pCLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNuRSxJQUFJLEVBQUUsQ0FBQzthQUNSLEVBQ0QsWUFBWSxFQUFFO2dCQUNaLEtBQUssRUFBRSxZQUFZLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQztnQkFDcEQsSUFBSSxFQUFFLENBQUM7YUFDUixJQUNFLENBQUMsYUFBYTtZQUNmLENBQUMsQ0FBQztnQkFDRSxhQUFhLEVBQUU7b0JBQ2IsS0FBSyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDO29CQUNyRCxJQUFJLEVBQUUsQ0FBQztpQkFDUjthQUNGO1lBQ0gsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUNmO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMjIgRmxvd21hcEJsdWVcbiAqIENvcHlyaWdodCAyMDE4LTIwMjAgVGVyYWx5dGljcywgbW9kaWZpZWQgYnkgRmxvd21hcEJsdWVcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHthc2NlbmRpbmcsIGRlc2NlbmRpbmcsIGV4dGVudCwgbWluLCByb2xsdXB9IGZyb20gJ2QzLWFycmF5JztcbmltcG9ydCB7U2NhbGVMaW5lYXIsIHNjYWxlU3FydH0gZnJvbSAnZDMtc2NhbGUnO1xuaW1wb3J0IEtEQnVzaCBmcm9tICdrZGJ1c2gnO1xuaW1wb3J0IHtcbiAgY3JlYXRlU2VsZWN0b3IsXG4gIGNyZWF0ZVNlbGVjdG9yQ3JlYXRvcixcbiAgZGVmYXVsdE1lbW9pemUsXG4gIFBhcmFtZXRyaWNTZWxlY3Rvcixcbn0gZnJvbSAncmVzZWxlY3QnO1xuaW1wb3J0IHthbGVhfSBmcm9tICdzZWVkcmFuZG9tJztcbmltcG9ydCB7Y2x1c3RlckxvY2F0aW9uc30gZnJvbSAnLi9jbHVzdGVyL2NsdXN0ZXInO1xuaW1wb3J0IHtcbiAgYnVpbGRJbmRleCxcbiAgQ2x1c3RlckluZGV4LFxuICBmaW5kQXBwcm9wcmlhdGVab29tTGV2ZWwsXG4gIExvY2F0aW9uV2VpZ2h0R2V0dGVyLFxuICBtYWtlTG9jYXRpb25XZWlnaHRHZXR0ZXIsXG59IGZyb20gJy4vY2x1c3Rlci9DbHVzdGVySW5kZXgnO1xuaW1wb3J0IGdldENvbG9ycywge1xuICBDb2xvcnNSR0JBLFxuICBEaWZmQ29sb3JzUkdCQSxcbiAgZ2V0Q29sb3JzUkdCQSxcbiAgZ2V0RGlmZkNvbG9yc1JHQkEsXG4gIGdldEZsb3dDb2xvclNjYWxlLFxuICBpc0RpZmZDb2xvcnMsXG4gIGlzRGlmZkNvbG9yc1JHQkEsXG59IGZyb20gJy4vY29sb3JzJztcbmltcG9ydCBGbG93bWFwQWdncmVnYXRlQWNjZXNzb3JzIGZyb20gJy4vRmxvd21hcEFnZ3JlZ2F0ZUFjY2Vzc29ycyc7XG5pbXBvcnQge0Zsb3dtYXBTdGF0ZX0gZnJvbSAnLi9GbG93bWFwU3RhdGUnO1xuaW1wb3J0IHtcbiAgZ2V0Rmxvd1RoaWNrbmVzc1NjYWxlLFxuICBnZXRWaWV3cG9ydEJvdW5kaW5nQm94LFxufSBmcm9tICcuL3NlbGVjdG9yLWZ1bmN0aW9ucyc7XG5pbXBvcnQge1xuICBnZXRUaW1lR3JhbnVsYXJpdHlCeUtleSxcbiAgZ2V0VGltZUdyYW51bGFyaXR5QnlPcmRlcixcbiAgZ2V0VGltZUdyYW51bGFyaXR5Rm9yRGF0ZSxcbiAgVGltZUdyYW51bGFyaXR5S2V5LFxufSBmcm9tICcuL3RpbWUnO1xuaW1wb3J0IHtcbiAgQWdncmVnYXRlRmxvdyxcbiAgQ2x1c3RlcixcbiAgQ2x1c3RlckxldmVscyxcbiAgQ2x1c3Rlck5vZGUsXG4gIENvdW50QnlUaW1lLFxuICBGbG93QWNjZXNzb3JzLFxuICBGbG93Q2lyY2xlc0xheWVyQXR0cmlidXRlcyxcbiAgRmxvd0xpbmVzTGF5ZXJBdHRyaWJ1dGVzLFxuICBGbG93bWFwRGF0YSxcbiAgRmxvd21hcERhdGFBY2Nlc3NvcnMsXG4gIGlzQ2x1c3RlcixcbiAgaXNMb2NhdGlvbkNsdXN0ZXJOb2RlLFxuICBMYXllcnNEYXRhLFxuICBMb2NhdGlvbkZpbHRlck1vZGUsXG4gIExvY2F0aW9uVG90YWxzLFxufSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgTUFYX0NMVVNURVJfWk9PTV9MRVZFTCA9IDIwO1xudHlwZSBLREJ1c2hUcmVlID0gYW55O1xuXG5leHBvcnQgdHlwZSBTZWxlY3RvcjxMLCBGLCBUPiA9IFBhcmFtZXRyaWNTZWxlY3RvcjxcbiAgRmxvd21hcFN0YXRlLFxuICBGbG93bWFwRGF0YTxMLCBGPixcbiAgVFxuPjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRmxvd21hcFNlbGVjdG9yczxMLCBGPiB7XG4gIGFjY2Vzc29yczogRmxvd21hcEFnZ3JlZ2F0ZUFjY2Vzc29yczxMLCBGPjtcblxuICBjb25zdHJ1Y3RvcihhY2Nlc3NvcnM6IEZsb3dtYXBEYXRhQWNjZXNzb3JzPEwsIEY+KSB7XG4gICAgdGhpcy5hY2Nlc3NvcnMgPSBuZXcgRmxvd21hcEFnZ3JlZ2F0ZUFjY2Vzc29ycyhhY2Nlc3NvcnMpO1xuICAgIHRoaXMuc2V0QWNjZXNzb3JzKGFjY2Vzc29ycyk7XG4gIH1cblxuICBzZXRBY2Nlc3NvcnMoYWNjZXNzb3JzOiBGbG93bWFwRGF0YUFjY2Vzc29yczxMLCBGPikge1xuICAgIHRoaXMuYWNjZXNzb3JzID0gbmV3IEZsb3dtYXBBZ2dyZWdhdGVBY2Nlc3NvcnMoYWNjZXNzb3JzKTtcbiAgfVxuXG4gIGdldEZsb3dzRnJvbVByb3BzID0gKHN0YXRlOiBGbG93bWFwU3RhdGUsIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPikgPT5cbiAgICBwcm9wcy5mbG93cztcbiAgZ2V0TG9jYXRpb25zRnJvbVByb3BzID0gKHN0YXRlOiBGbG93bWFwU3RhdGUsIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPikgPT5cbiAgICBwcm9wcy5sb2NhdGlvbnM7XG4gIGdldENsdXN0ZXJMZXZlbHNGcm9tUHJvcHMgPSAoXG4gICAgc3RhdGU6IEZsb3dtYXBTdGF0ZSxcbiAgICBwcm9wczogRmxvd21hcERhdGE8TCwgRj4sXG4gICkgPT4ge1xuICAgIHJldHVybiBwcm9wcy5jbHVzdGVyTGV2ZWxzO1xuICB9O1xuICBnZXRNYXhUb3BGbG93c0Rpc3BsYXlOdW0gPSAoc3RhdGU6IEZsb3dtYXBTdGF0ZSwgcHJvcHM6IEZsb3dtYXBEYXRhPEwsIEY+KSA9PlxuICAgIHN0YXRlLnNldHRpbmdzLm1heFRvcEZsb3dzRGlzcGxheU51bTtcbiAgZ2V0U2VsZWN0ZWRMb2NhdGlvbnMgPSAoc3RhdGU6IEZsb3dtYXBTdGF0ZSwgcHJvcHM6IEZsb3dtYXBEYXRhPEwsIEY+KSA9PlxuICAgIHN0YXRlLmZpbHRlcj8uc2VsZWN0ZWRMb2NhdGlvbnM7XG4gIGdldExvY2F0aW9uRmlsdGVyTW9kZSA9IChzdGF0ZTogRmxvd21hcFN0YXRlLCBwcm9wczogRmxvd21hcERhdGE8TCwgRj4pID0+XG4gICAgc3RhdGUuZmlsdGVyPy5sb2NhdGlvbkZpbHRlck1vZGU7XG4gIGdldENsdXN0ZXJpbmdFbmFibGVkID0gKHN0YXRlOiBGbG93bWFwU3RhdGUsIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPikgPT5cbiAgICBzdGF0ZS5zZXR0aW5ncy5jbHVzdGVyaW5nRW5hYmxlZDtcbiAgZ2V0TG9jYXRpb25Ub3RhbHNFbmFibGVkID0gKHN0YXRlOiBGbG93bWFwU3RhdGUsIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPikgPT5cbiAgICBzdGF0ZS5zZXR0aW5ncy5sb2NhdGlvblRvdGFsc0VuYWJsZWQ7XG4gIGdldFpvb20gPSAoc3RhdGU6IEZsb3dtYXBTdGF0ZSwgcHJvcHM6IEZsb3dtYXBEYXRhPEwsIEY+KSA9PlxuICAgIHN0YXRlLnZpZXdwb3J0Lnpvb207XG4gIGdldFZpZXdwb3J0ID0gKHN0YXRlOiBGbG93bWFwU3RhdGUsIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPikgPT5cbiAgICBzdGF0ZS52aWV3cG9ydDtcbiAgZ2V0U2VsZWN0ZWRUaW1lUmFuZ2UgPSAoc3RhdGU6IEZsb3dtYXBTdGF0ZSwgcHJvcHM6IEZsb3dtYXBEYXRhPEwsIEY+KSA9PlxuICAgIHN0YXRlLmZpbHRlcj8uc2VsZWN0ZWRUaW1lUmFuZ2U7XG5cbiAgZ2V0Q29sb3JTY2hlbWU6IFNlbGVjdG9yPEwsIEYsIHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkPiA9IChcbiAgICBzdGF0ZTogRmxvd21hcFN0YXRlLFxuICAgIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPixcbiAgKSA9PiBzdGF0ZS5zZXR0aW5ncy5jb2xvclNjaGVtZTtcblxuICBnZXREYXJrTW9kZTogU2VsZWN0b3I8TCwgRiwgYm9vbGVhbj4gPSAoXG4gICAgc3RhdGU6IEZsb3dtYXBTdGF0ZSxcbiAgICBwcm9wczogRmxvd21hcERhdGE8TCwgRj4sXG4gICkgPT4gc3RhdGUuc2V0dGluZ3MuZGFya01vZGU7XG5cbiAgZ2V0RmFkZUVuYWJsZWQ6IFNlbGVjdG9yPEwsIEYsIGJvb2xlYW4+ID0gKFxuICAgIHN0YXRlOiBGbG93bWFwU3RhdGUsXG4gICAgcHJvcHM6IEZsb3dtYXBEYXRhPEwsIEY+LFxuICApID0+IHN0YXRlLnNldHRpbmdzLmZhZGVFbmFibGVkO1xuXG4gIGdldEZhZGVPcGFjaXR5RW5hYmxlZDogU2VsZWN0b3I8TCwgRiwgYm9vbGVhbj4gPSAoXG4gICAgc3RhdGU6IEZsb3dtYXBTdGF0ZSxcbiAgICBwcm9wczogRmxvd21hcERhdGE8TCwgRj4sXG4gICkgPT4gc3RhdGUuc2V0dGluZ3MuZmFkZU9wYWNpdHlFbmFibGVkO1xuXG4gIGdldEZhZGVBbW91bnQ6IFNlbGVjdG9yPEwsIEYsIG51bWJlcj4gPSAoXG4gICAgc3RhdGU6IEZsb3dtYXBTdGF0ZSxcbiAgICBwcm9wczogRmxvd21hcERhdGE8TCwgRj4sXG4gICkgPT4gc3RhdGUuc2V0dGluZ3MuZmFkZUFtb3VudDtcblxuICBnZXRBbmltYXRlOiBTZWxlY3RvcjxMLCBGLCBib29sZWFuPiA9IChcbiAgICBzdGF0ZTogRmxvd21hcFN0YXRlLFxuICAgIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPixcbiAgKSA9PiBzdGF0ZS5zZXR0aW5ncy5hbmltYXRpb25FbmFibGVkO1xuXG4gIGdldEludmFsaWRMb2NhdGlvbklkczogU2VsZWN0b3I8TCwgRiwgc3RyaW5nW10gfCB1bmRlZmluZWQ+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRMb2NhdGlvbnNGcm9tUHJvcHMsXG4gICAgKGxvY2F0aW9ucykgPT4ge1xuICAgICAgaWYgKCFsb2NhdGlvbnMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBpbnZhbGlkID0gW107XG4gICAgICBmb3IgKGNvbnN0IGxvY2F0aW9uIG9mIGxvY2F0aW9ucykge1xuICAgICAgICBjb25zdCBpZCA9IHRoaXMuYWNjZXNzb3JzLmdldExvY2F0aW9uSWQobG9jYXRpb24pO1xuICAgICAgICBjb25zdCBsb24gPSB0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbkxvbihsb2NhdGlvbik7XG4gICAgICAgIGNvbnN0IGxhdCA9IHRoaXMuYWNjZXNzb3JzLmdldExvY2F0aW9uTGF0KGxvY2F0aW9uKTtcbiAgICAgICAgaWYgKCEoLTkwIDw9IGxhdCAmJiBsYXQgPD0gOTApIHx8ICEoLTE4MCA8PSBsb24gJiYgbG9uIDw9IDE4MCkpIHtcbiAgICAgICAgICBpbnZhbGlkLnB1c2goaWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaW52YWxpZC5sZW5ndGggPiAwID8gaW52YWxpZCA6IHVuZGVmaW5lZDtcbiAgICB9LFxuICApO1xuXG4gIGdldExvY2F0aW9uczogU2VsZWN0b3I8TCwgRiwgSXRlcmFibGU8TD4gfCB1bmRlZmluZWQ+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRMb2NhdGlvbnNGcm9tUHJvcHMsXG4gICAgdGhpcy5nZXRJbnZhbGlkTG9jYXRpb25JZHMsXG4gICAgKGxvY2F0aW9ucywgaW52YWxpZElkcykgPT4ge1xuICAgICAgaWYgKCFsb2NhdGlvbnMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWludmFsaWRJZHMgfHwgaW52YWxpZElkcy5sZW5ndGggPT09IDApIHJldHVybiBsb2NhdGlvbnM7XG4gICAgICBjb25zdCBpbnZhbGlkID0gbmV3IFNldChpbnZhbGlkSWRzKTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkOiBMW10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgbG9jYXRpb24gb2YgbG9jYXRpb25zKSB7XG4gICAgICAgIGNvbnN0IGlkID0gdGhpcy5hY2Nlc3NvcnMuZ2V0TG9jYXRpb25JZChsb2NhdGlvbik7XG4gICAgICAgIGlmICghaW52YWxpZC5oYXMoaWQpKSB7XG4gICAgICAgICAgZmlsdGVyZWQucHVzaChsb2NhdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmaWx0ZXJlZDtcbiAgICB9LFxuICApO1xuXG4gIGdldExvY2F0aW9uSWRzOiBTZWxlY3RvcjxMLCBGLCBTZXQ8c3RyaW5nPiB8IHVuZGVmaW5lZD4gPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmdldExvY2F0aW9ucyxcbiAgICAobG9jYXRpb25zKSA9PiB7XG4gICAgICBpZiAoIWxvY2F0aW9ucykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IGlkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgZm9yIChjb25zdCBpZCBvZiBsb2NhdGlvbnMpIHtcbiAgICAgICAgaWRzLmFkZCh0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbklkKGlkKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaWRzO1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0U2VsZWN0ZWRMb2NhdGlvbnNTZXQ6IFNlbGVjdG9yPEwsIEYsIFNldDxzdHJpbmc+IHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IodGhpcy5nZXRTZWxlY3RlZExvY2F0aW9ucywgKGlkcykgPT5cbiAgICAgIGlkcyAmJiBpZHMubGVuZ3RoID4gMCA/IG5ldyBTZXQoaWRzKSA6IHVuZGVmaW5lZCxcbiAgICApO1xuXG4gIGdldFNvcnRlZEZsb3dzRm9yS25vd25Mb2NhdGlvbnM6IFNlbGVjdG9yPEwsIEYsIEZbXSB8IHVuZGVmaW5lZD4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy5nZXRGbG93c0Zyb21Qcm9wcyxcbiAgICAgIHRoaXMuZ2V0TG9jYXRpb25JZHMsXG4gICAgICAoZmxvd3MsIGlkcykgPT4ge1xuICAgICAgICBpZiAoIWlkcyB8fCAhZmxvd3MpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gW107XG4gICAgICAgIGZvciAoY29uc3QgZmxvdyBvZiBmbG93cykge1xuICAgICAgICAgIGNvbnN0IHNyY0lkID0gdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd09yaWdpbklkKGZsb3cpO1xuICAgICAgICAgIGNvbnN0IGRzdElkID0gdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd0Rlc3RJZChmbG93KTtcbiAgICAgICAgICBpZiAoaWRzLmhhcyhzcmNJZCkgJiYgaWRzLmhhcyhkc3RJZCkpIHtcbiAgICAgICAgICAgIGZpbHRlcmVkLnB1c2goZmxvdyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWx0ZXJlZC5zb3J0KChhOiBGLCBiOiBGKSA9PlxuICAgICAgICAgIGRlc2NlbmRpbmcoXG4gICAgICAgICAgICBNYXRoLmFicyh0aGlzLmFjY2Vzc29ycy5nZXRGbG93TWFnbml0dWRlKGEpKSxcbiAgICAgICAgICAgIE1hdGguYWJzKHRoaXMuYWNjZXNzb3JzLmdldEZsb3dNYWduaXR1ZGUoYikpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9LFxuICAgICk7XG5cbiAgZ2V0QWN0dWFsVGltZUV4dGVudDogU2VsZWN0b3I8TCwgRiwgW0RhdGUsIERhdGVdIHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IodGhpcy5nZXRTb3J0ZWRGbG93c0Zvcktub3duTG9jYXRpb25zLCAoZmxvd3MpID0+IHtcbiAgICAgIGlmICghZmxvd3MpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgbGV0IGVuZCA9IG51bGw7XG4gICAgICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MpIHtcbiAgICAgICAgY29uc3QgdGltZSA9IHRoaXMuYWNjZXNzb3JzLmdldEZsb3dUaW1lKGZsb3cpO1xuICAgICAgICBpZiAodGltZSkge1xuICAgICAgICAgIGlmIChzdGFydCA9PSBudWxsIHx8IHN0YXJ0ID4gdGltZSkgc3RhcnQgPSB0aW1lO1xuICAgICAgICAgIGlmIChlbmQgPT0gbnVsbCB8fCBlbmQgPCB0aW1lKSBlbmQgPSB0aW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXN0YXJ0IHx8ICFlbmQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gW3N0YXJ0LCBlbmRdO1xuICAgIH0pO1xuXG4gIGdldFRpbWVHcmFudWxhcml0eUtleTogU2VsZWN0b3I8TCwgRiwgVGltZUdyYW51bGFyaXR5S2V5IHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IoXG4gICAgICB0aGlzLmdldFNvcnRlZEZsb3dzRm9yS25vd25Mb2NhdGlvbnMsXG4gICAgICB0aGlzLmdldEFjdHVhbFRpbWVFeHRlbnQsXG4gICAgICAoZmxvd3MsIHRpbWVFeHRlbnQpID0+IHtcbiAgICAgICAgaWYgKCFmbG93cyB8fCAhdGltZUV4dGVudCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBtaW5PcmRlciA9IG1pbihmbG93cywgKGQpID0+IHtcbiAgICAgICAgICBjb25zdCB0ID0gdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd1RpbWUoZCk7XG4gICAgICAgICAgcmV0dXJuIHQgPyBnZXRUaW1lR3JhbnVsYXJpdHlGb3JEYXRlKHQpLm9yZGVyIDogbnVsbDtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChtaW5PcmRlciA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCB0aW1lR3JhbnVsYXJpdHkgPSBnZXRUaW1lR3JhbnVsYXJpdHlCeU9yZGVyKG1pbk9yZGVyKTtcbiAgICAgICAgcmV0dXJuIHRpbWVHcmFudWxhcml0eSA/IHRpbWVHcmFudWxhcml0eS5rZXkgOiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICk7XG5cbiAgZ2V0VGltZUV4dGVudDogU2VsZWN0b3I8TCwgRiwgW0RhdGUsIERhdGVdIHwgdW5kZWZpbmVkPiA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgIHRoaXMuZ2V0QWN0dWFsVGltZUV4dGVudCxcbiAgICB0aGlzLmdldFRpbWVHcmFudWxhcml0eUtleSxcbiAgICAodGltZUV4dGVudCwgdGltZUdyYW51bGFyaXR5S2V5KSA9PiB7XG4gICAgICBjb25zdCB0aW1lR3JhbnVsYXJpdHkgPSB0aW1lR3JhbnVsYXJpdHlLZXlcbiAgICAgICAgPyBnZXRUaW1lR3JhbnVsYXJpdHlCeUtleSh0aW1lR3JhbnVsYXJpdHlLZXkpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgaWYgKCF0aW1lRXh0ZW50IHx8ICF0aW1lR3JhbnVsYXJpdHk/LmludGVydmFsKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3Qge2ludGVydmFsfSA9IHRpbWVHcmFudWxhcml0eTtcbiAgICAgIHJldHVybiBbdGltZUV4dGVudFswXSwgaW50ZXJ2YWwub2Zmc2V0KGludGVydmFsLmZsb29yKHRpbWVFeHRlbnRbMV0pLCAxKV07XG4gICAgfSxcbiAgKTtcblxuICBnZXRTb3J0ZWRGbG93c0Zvcktub3duTG9jYXRpb25zRmlsdGVyZWRCeVRpbWU6IFNlbGVjdG9yPFxuICAgIEwsXG4gICAgRixcbiAgICBGW10gfCB1bmRlZmluZWRcbiAgPiA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgIHRoaXMuZ2V0U29ydGVkRmxvd3NGb3JLbm93bkxvY2F0aW9ucyxcbiAgICB0aGlzLmdldFRpbWVFeHRlbnQsXG4gICAgdGhpcy5nZXRTZWxlY3RlZFRpbWVSYW5nZSxcbiAgICAoZmxvd3MsIHRpbWVFeHRlbnQsIHRpbWVSYW5nZSkgPT4ge1xuICAgICAgaWYgKCFmbG93cykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIGlmIChcbiAgICAgICAgIXRpbWVFeHRlbnQgfHxcbiAgICAgICAgIXRpbWVSYW5nZSB8fFxuICAgICAgICAodGltZUV4dGVudFswXSA9PT0gdGltZVJhbmdlWzBdICYmIHRpbWVFeHRlbnRbMV0gPT09IHRpbWVSYW5nZVsxXSlcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gZmxvd3M7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmxvd3MuZmlsdGVyKChmbG93KSA9PiB7XG4gICAgICAgIGNvbnN0IHRpbWUgPSB0aGlzLmFjY2Vzc29ycy5nZXRGbG93VGltZShmbG93KTtcbiAgICAgICAgcmV0dXJuIHRpbWUgJiYgdGltZVJhbmdlWzBdIDw9IHRpbWUgJiYgdGltZSA8IHRpbWVSYW5nZVsxXTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0TG9jYXRpb25zSGF2aW5nRmxvd3M6IFNlbGVjdG9yPEwsIEYsIEl0ZXJhYmxlPEw+IHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IoXG4gICAgICB0aGlzLmdldFNvcnRlZEZsb3dzRm9yS25vd25Mb2NhdGlvbnMsXG4gICAgICB0aGlzLmdldExvY2F0aW9ucyxcbiAgICAgIChmbG93cywgbG9jYXRpb25zKSA9PiB7XG4gICAgICAgIGlmICghbG9jYXRpb25zIHx8ICFmbG93cykgcmV0dXJuIGxvY2F0aW9ucztcbiAgICAgICAgY29uc3Qgd2l0aEZsb3dzID0gbmV3IFNldCgpO1xuICAgICAgICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MpIHtcbiAgICAgICAgICB3aXRoRmxvd3MuYWRkKHRoaXMuYWNjZXNzb3JzLmdldEZsb3dPcmlnaW5JZChmbG93KSk7XG4gICAgICAgICAgd2l0aEZsb3dzLmFkZCh0aGlzLmFjY2Vzc29ycy5nZXRGbG93RGVzdElkKGZsb3cpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGxvY2F0aW9uIG9mIGxvY2F0aW9ucykge1xuICAgICAgICAgIGlmICh3aXRoRmxvd3MuaGFzKHRoaXMuYWNjZXNzb3JzLmdldExvY2F0aW9uSWQobG9jYXRpb24pKSkge1xuICAgICAgICAgICAgZmlsdGVyZWQucHVzaChsb2NhdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWx0ZXJlZDtcbiAgICAgIH0sXG4gICAgKTtcblxuICBnZXRMb2NhdGlvbnNCeUlkOiBTZWxlY3RvcjxMLCBGLCBNYXA8c3RyaW5nLCBMPiB8IHVuZGVmaW5lZD4gPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmdldExvY2F0aW9uc0hhdmluZ0Zsb3dzLFxuICAgIChsb2NhdGlvbnMpID0+IHtcbiAgICAgIGlmICghbG9jYXRpb25zKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgbG9jYXRpb25zQnlJZCA9IG5ldyBNYXA8c3RyaW5nLCBMPigpO1xuICAgICAgZm9yIChjb25zdCBsb2NhdGlvbiBvZiBsb2NhdGlvbnMpIHtcbiAgICAgICAgbG9jYXRpb25zQnlJZC5zZXQodGhpcy5hY2Nlc3NvcnMuZ2V0TG9jYXRpb25JZChsb2NhdGlvbiksIGxvY2F0aW9uKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsb2NhdGlvbnNCeUlkO1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0TG9jYXRpb25XZWlnaHRHZXR0ZXI6IFNlbGVjdG9yPEwsIEYsIExvY2F0aW9uV2VpZ2h0R2V0dGVyIHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IodGhpcy5nZXRTb3J0ZWRGbG93c0Zvcktub3duTG9jYXRpb25zLCAoZmxvd3MpID0+IHtcbiAgICAgIGlmICghZmxvd3MpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBnZXRMb2NhdGlvbldlaWdodCA9IG1ha2VMb2NhdGlvbldlaWdodEdldHRlcihcbiAgICAgICAgZmxvd3MsXG4gICAgICAgIHRoaXMuYWNjZXNzb3JzLmdldEZsb3dtYXBEYXRhQWNjZXNzb3JzKCksXG4gICAgICApO1xuICAgICAgcmV0dXJuIGdldExvY2F0aW9uV2VpZ2h0O1xuICAgIH0pO1xuXG4gIGdldENsdXN0ZXJMZXZlbHM6IFNlbGVjdG9yPEwsIEYsIENsdXN0ZXJMZXZlbHMgfCB1bmRlZmluZWQ+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRDbHVzdGVyTGV2ZWxzRnJvbVByb3BzLFxuICAgIHRoaXMuZ2V0TG9jYXRpb25zSGF2aW5nRmxvd3MsXG4gICAgdGhpcy5nZXRMb2NhdGlvbldlaWdodEdldHRlcixcbiAgICAoY2x1c3RlckxldmVsc0Zyb21Qcm9wcywgbG9jYXRpb25zLCBnZXRMb2NhdGlvbldlaWdodCkgPT4ge1xuICAgICAgaWYgKGNsdXN0ZXJMZXZlbHNGcm9tUHJvcHMpIHJldHVybiBjbHVzdGVyTGV2ZWxzRnJvbVByb3BzO1xuICAgICAgaWYgKCFsb2NhdGlvbnMgfHwgIWdldExvY2F0aW9uV2VpZ2h0KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY2x1c3RlckxldmVscyA9IGNsdXN0ZXJMb2NhdGlvbnMoXG4gICAgICAgIGxvY2F0aW9ucyxcbiAgICAgICAgdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd21hcERhdGFBY2Nlc3NvcnMoKSxcbiAgICAgICAgZ2V0TG9jYXRpb25XZWlnaHQsXG4gICAgICAgIHtcbiAgICAgICAgICBtYXhab29tOiBNQVhfQ0xVU1RFUl9aT09NX0xFVkVMLFxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICAgIHJldHVybiBjbHVzdGVyTGV2ZWxzO1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0Q2x1c3RlckluZGV4OiBTZWxlY3RvcjxMLCBGLCBDbHVzdGVySW5kZXg8Rj4gfCB1bmRlZmluZWQ+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRMb2NhdGlvbnNCeUlkLFxuICAgIHRoaXMuZ2V0TG9jYXRpb25XZWlnaHRHZXR0ZXIsXG4gICAgdGhpcy5nZXRDbHVzdGVyTGV2ZWxzLFxuICAgIChsb2NhdGlvbnNCeUlkLCBnZXRMb2NhdGlvbldlaWdodCwgY2x1c3RlckxldmVscykgPT4ge1xuICAgICAgaWYgKCFsb2NhdGlvbnNCeUlkIHx8ICFnZXRMb2NhdGlvbldlaWdodCB8fCAhY2x1c3RlckxldmVscylcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgY2x1c3RlckluZGV4ID0gYnVpbGRJbmRleDxGPihjbHVzdGVyTGV2ZWxzKTtcbiAgICAgIGNvbnN0IHtnZXRMb2NhdGlvbk5hbWUsIGdldExvY2F0aW9uQ2x1c3Rlck5hbWV9ID1cbiAgICAgICAgdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd21hcERhdGFBY2Nlc3NvcnMoKTtcblxuICAgICAgLy8gQWRkaW5nIG1lYW5pbmdmdWwgbmFtZXNcbiAgICAgIGNvbnN0IGdldE5hbWUgPSAoaWQ6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBsb2MgPSBsb2NhdGlvbnNCeUlkLmdldChpZCk7XG4gICAgICAgIGlmIChsb2MpIHtcbiAgICAgICAgICByZXR1cm4gZ2V0TG9jYXRpb25OYW1lXG4gICAgICAgICAgICA/IGdldExvY2F0aW9uTmFtZShsb2MpXG4gICAgICAgICAgICA6IHRoaXMuYWNjZXNzb3JzLmdldExvY2F0aW9uSWQobG9jKSB8fCBpZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYFwiJHtpZH1cImA7XG4gICAgICB9O1xuICAgICAgZm9yIChjb25zdCBsZXZlbCBvZiBjbHVzdGVyTGV2ZWxzKSB7XG4gICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBsZXZlbC5ub2Rlcykge1xuICAgICAgICAgIC8vIEhlcmUgbXV0YXRpbmcgdGhlIG5vZGVzIChhZGRpbmcgbmFtZXMpXG4gICAgICAgICAgaWYgKGlzQ2x1c3Rlcihub2RlKSkge1xuICAgICAgICAgICAgY29uc3QgbGVhdmVzID0gY2x1c3RlckluZGV4LmV4cGFuZENsdXN0ZXIobm9kZSk7XG5cbiAgICAgICAgICAgIGxlYXZlcy5zb3J0KChhLCBiKSA9PlxuICAgICAgICAgICAgICBkZXNjZW5kaW5nKGdldExvY2F0aW9uV2VpZ2h0KGEpLCBnZXRMb2NhdGlvbldlaWdodChiKSksXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoZ2V0TG9jYXRpb25DbHVzdGVyTmFtZSkge1xuICAgICAgICAgICAgICBub2RlLm5hbWUgPSBnZXRMb2NhdGlvbkNsdXN0ZXJOYW1lKGxlYXZlcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdCB0b3BJZCA9IGxlYXZlc1swXTtcbiAgICAgICAgICAgICAgY29uc3Qgb3RoZXJJZCA9IGxlYXZlcy5sZW5ndGggPT09IDIgPyBsZWF2ZXNbMV0gOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgIG5vZGUubmFtZSA9IGBcIiR7Z2V0TmFtZSh0b3BJZCl9XCIgYW5kICR7XG4gICAgICAgICAgICAgICAgb3RoZXJJZFxuICAgICAgICAgICAgICAgICAgPyBgXCIke2dldE5hbWUob3RoZXJJZCl9XCJgXG4gICAgICAgICAgICAgICAgICA6IGAke2xlYXZlcy5sZW5ndGggLSAxfSBvdGhlcnNgXG4gICAgICAgICAgICAgIH1gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAobm9kZSBhcyBhbnkpLm5hbWUgPSBnZXROYW1lKG5vZGUuaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2x1c3RlckluZGV4O1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0QXZhaWxhYmxlQ2x1c3Rlclpvb21MZXZlbHMgPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmdldENsdXN0ZXJJbmRleCxcbiAgICB0aGlzLmdldFNlbGVjdGVkTG9jYXRpb25zLFxuICAgIChjbHVzdGVySW5kZXgsIHNlbGVjdGVkTG9jYXRpb25zKTogbnVtYmVyW10gfCB1bmRlZmluZWQgPT4ge1xuICAgICAgaWYgKCFjbHVzdGVySW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgbGV0IG1heFpvb20gPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICBsZXQgbWluWm9vbSA9IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcblxuICAgICAgY29uc3QgYWRqdXN0ID0gKHpvbmVJZDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGNsdXN0ZXIgPSBjbHVzdGVySW5kZXguZ2V0Q2x1c3RlckJ5SWQoem9uZUlkKTtcbiAgICAgICAgaWYgKGNsdXN0ZXIpIHtcbiAgICAgICAgICBtaW5ab29tID0gTWF0aC5tYXgobWluWm9vbSwgY2x1c3Rlci56b29tKTtcbiAgICAgICAgICBtYXhab29tID0gTWF0aC5taW4obWF4Wm9vbSwgY2x1c3Rlci56b29tKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB6b29tID0gY2x1c3RlckluZGV4LmdldE1pblpvb21Gb3JMb2NhdGlvbih6b25lSWQpO1xuICAgICAgICAgIG1pblpvb20gPSBNYXRoLm1heChtaW5ab29tLCB6b29tKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgaWYgKHNlbGVjdGVkTG9jYXRpb25zKSB7XG4gICAgICAgIGZvciAoY29uc3QgaWQgb2Ygc2VsZWN0ZWRMb2NhdGlvbnMpIHtcbiAgICAgICAgICBhZGp1c3QoaWQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjbHVzdGVySW5kZXguYXZhaWxhYmxlWm9vbUxldmVscy5maWx0ZXIoXG4gICAgICAgIChsZXZlbCkgPT4gbWluWm9vbSA8PSBsZXZlbCAmJiBsZXZlbCA8PSBtYXhab29tLFxuICAgICAgKTtcbiAgICB9LFxuICApO1xuXG4gIF9nZXRDbHVzdGVyWm9vbTogU2VsZWN0b3I8TCwgRiwgbnVtYmVyIHwgdW5kZWZpbmVkPiA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgIHRoaXMuZ2V0Q2x1c3RlckluZGV4LFxuICAgIHRoaXMuZ2V0Wm9vbSxcbiAgICB0aGlzLmdldEF2YWlsYWJsZUNsdXN0ZXJab29tTGV2ZWxzLFxuICAgIChjbHVzdGVySW5kZXgsIG1hcFpvb20sIGF2YWlsYWJsZUNsdXN0ZXJab29tTGV2ZWxzKSA9PiB7XG4gICAgICBpZiAoIWNsdXN0ZXJJbmRleCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIGlmICghYXZhaWxhYmxlQ2x1c3Rlclpvb21MZXZlbHMgfHwgbWFwWm9vbSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNsdXN0ZXJab29tID0gZmluZEFwcHJvcHJpYXRlWm9vbUxldmVsKFxuICAgICAgICBhdmFpbGFibGVDbHVzdGVyWm9vbUxldmVscyxcbiAgICAgICAgbWFwWm9vbSxcbiAgICAgICk7XG4gICAgICByZXR1cm4gY2x1c3Rlclpvb207XG4gICAgfSxcbiAgKTtcblxuICBnZXRDbHVzdGVyWm9vbSA9IChzdGF0ZTogRmxvd21hcFN0YXRlLCBwcm9wczogRmxvd21hcERhdGE8TCwgRj4pID0+IHtcbiAgICBjb25zdCB7c2V0dGluZ3N9ID0gc3RhdGU7XG4gICAgaWYgKCFzZXR0aW5ncy5jbHVzdGVyaW5nRW5hYmxlZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoc2V0dGluZ3MuY2x1c3RlcmluZ0F1dG8gfHwgc2V0dGluZ3MuY2x1c3RlcmluZ0xldmVsID09IG51bGwpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRDbHVzdGVyWm9vbShzdGF0ZSwgcHJvcHMpO1xuICAgIH1cbiAgICByZXR1cm4gc2V0dGluZ3MuY2x1c3RlcmluZ0xldmVsO1xuICB9O1xuXG4gIGdldExvY2F0aW9uc0ZvclNlYXJjaEJveDogU2VsZWN0b3I8TCwgRiwgKEwgfCBDbHVzdGVyKVtdIHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IoXG4gICAgICB0aGlzLmdldENsdXN0ZXJpbmdFbmFibGVkLFxuICAgICAgdGhpcy5nZXRMb2NhdGlvbnNIYXZpbmdGbG93cyxcbiAgICAgIHRoaXMuZ2V0U2VsZWN0ZWRMb2NhdGlvbnMsXG4gICAgICB0aGlzLmdldENsdXN0ZXJab29tLFxuICAgICAgdGhpcy5nZXRDbHVzdGVySW5kZXgsXG4gICAgICAoXG4gICAgICAgIGNsdXN0ZXJpbmdFbmFibGVkLFxuICAgICAgICBsb2NhdGlvbnMsXG4gICAgICAgIHNlbGVjdGVkTG9jYXRpb25zLFxuICAgICAgICBjbHVzdGVyWm9vbSxcbiAgICAgICAgY2x1c3RlckluZGV4LFxuICAgICAgKSA9PiB7XG4gICAgICAgIGlmICghbG9jYXRpb25zKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgcmVzdWx0OiAoTCB8IENsdXN0ZXIpW10gPSBBcnJheS5mcm9tKGxvY2F0aW9ucyk7XG4gICAgICAgIC8vIGlmIChjbHVzdGVyaW5nRW5hYmxlZCkge1xuICAgICAgICAvLyAgIGlmIChjbHVzdGVySW5kZXgpIHtcbiAgICAgICAgLy8gICAgIGNvbnN0IHpvb21JdGVtcyA9IGNsdXN0ZXJJbmRleC5nZXRDbHVzdGVyTm9kZXNGb3IoY2x1c3Rlclpvb20pO1xuICAgICAgICAvLyAgICAgaWYgKHpvb21JdGVtcykge1xuICAgICAgICAvLyAgICAgICByZXN1bHQgPSByZXN1bHQuY29uY2F0KHpvb21JdGVtcy5maWx0ZXIoaXNDbHVzdGVyKSk7XG4gICAgICAgIC8vICAgICB9XG4gICAgICAgIC8vICAgfVxuICAgICAgICAvLyB9XG5cbiAgICAgICAgaWYgKGNsdXN0ZXJJbmRleCAmJiBzZWxlY3RlZExvY2F0aW9ucykge1xuICAgICAgICAgIGNvbnN0IHRvQXBwZW5kID0gW107XG4gICAgICAgICAgZm9yIChjb25zdCBpZCBvZiBzZWxlY3RlZExvY2F0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgY2x1c3RlciA9IGNsdXN0ZXJJbmRleC5nZXRDbHVzdGVyQnlJZChpZCk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIGNsdXN0ZXIgJiZcbiAgICAgICAgICAgICAgIXJlc3VsdC5maW5kKFxuICAgICAgICAgICAgICAgIChkKSA9PlxuICAgICAgICAgICAgICAgICAgKGlzTG9jYXRpb25DbHVzdGVyTm9kZShkKVxuICAgICAgICAgICAgICAgICAgICA/IGQuaWRcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbklkKGQpKSA9PT0gaWQsXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICB0b0FwcGVuZC5wdXNoKGNsdXN0ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodG9BcHBlbmQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0b0FwcGVuZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgICk7XG5cbiAgZ2V0RGlmZk1vZGU6IFNlbGVjdG9yPEwsIEYsIGJvb2xlYW4+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRGbG93c0Zyb21Qcm9wcyxcbiAgICAoZmxvd3MpID0+IHtcbiAgICAgIGlmIChmbG93cykge1xuICAgICAgICBmb3IgKGNvbnN0IGYgb2YgZmxvd3MpIHtcbiAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd01hZ25pdHVkZShmKSA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gICk7XG5cbiAgX2dldEZsb3dtYXBDb2xvcnMgPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmdldERpZmZNb2RlLFxuICAgIHRoaXMuZ2V0Q29sb3JTY2hlbWUsXG4gICAgdGhpcy5nZXREYXJrTW9kZSxcbiAgICB0aGlzLmdldEZhZGVFbmFibGVkLFxuICAgIHRoaXMuZ2V0RmFkZU9wYWNpdHlFbmFibGVkLFxuICAgIHRoaXMuZ2V0RmFkZUFtb3VudCxcbiAgICB0aGlzLmdldEFuaW1hdGUsXG4gICAgZ2V0Q29sb3JzLFxuICApO1xuXG4gIGdldEZsb3dtYXBDb2xvcnNSR0JBID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5fZ2V0Rmxvd21hcENvbG9ycyxcbiAgICAoZmxvd21hcENvbG9ycykgPT4ge1xuICAgICAgcmV0dXJuIGlzRGlmZkNvbG9ycyhmbG93bWFwQ29sb3JzKVxuICAgICAgICA/IGdldERpZmZDb2xvcnNSR0JBKGZsb3dtYXBDb2xvcnMpXG4gICAgICAgIDogZ2V0Q29sb3JzUkdCQShmbG93bWFwQ29sb3JzKTtcbiAgICB9LFxuICApO1xuXG4gIGdldFVua25vd25Mb2NhdGlvbnM6IFNlbGVjdG9yPEwsIEYsIFNldDxzdHJpbmc+IHwgdW5kZWZpbmVkPiA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgIHRoaXMuZ2V0TG9jYXRpb25JZHMsXG4gICAgdGhpcy5nZXRGbG93c0Zyb21Qcm9wcyxcbiAgICB0aGlzLmdldFNvcnRlZEZsb3dzRm9yS25vd25Mb2NhdGlvbnMsXG4gICAgKGlkcywgZmxvd3MsIGZsb3dzRm9yS25vd25Mb2NhdGlvbnMpID0+IHtcbiAgICAgIGlmICghaWRzIHx8ICFmbG93cykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIGlmIChcbiAgICAgICAgZmxvd3NGb3JLbm93bkxvY2F0aW9uc1xuICAgICAgICAvLyAmJiBmbG93cy5sZW5ndGggPT09IGZsb3dzRm9yS25vd25Mb2NhdGlvbnMubGVuZ3RoXG4gICAgICApXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBtaXNzaW5nID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MpIHtcbiAgICAgICAgaWYgKCFpZHMuaGFzKHRoaXMuYWNjZXNzb3JzLmdldEZsb3dPcmlnaW5JZChmbG93KSkpXG4gICAgICAgICAgbWlzc2luZy5hZGQodGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd09yaWdpbklkKGZsb3cpKTtcbiAgICAgICAgaWYgKCFpZHMuaGFzKHRoaXMuYWNjZXNzb3JzLmdldEZsb3dEZXN0SWQoZmxvdykpKVxuICAgICAgICAgIG1pc3NpbmcuYWRkKHRoaXMuYWNjZXNzb3JzLmdldEZsb3dEZXN0SWQoZmxvdykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1pc3Npbmc7XG4gICAgfSxcbiAgKTtcblxuICBnZXRTb3J0ZWRBZ2dyZWdhdGVkRmlsdGVyZWRGbG93czogU2VsZWN0b3I8XG4gICAgTCxcbiAgICBGLFxuICAgIChGIHwgQWdncmVnYXRlRmxvdylbXSB8IHVuZGVmaW5lZFxuICA+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRDbHVzdGVySW5kZXgsXG4gICAgdGhpcy5nZXRDbHVzdGVyaW5nRW5hYmxlZCxcbiAgICB0aGlzLmdldFNvcnRlZEZsb3dzRm9yS25vd25Mb2NhdGlvbnNGaWx0ZXJlZEJ5VGltZSxcbiAgICB0aGlzLmdldENsdXN0ZXJab29tLFxuICAgIHRoaXMuZ2V0VGltZUV4dGVudCxcbiAgICAoY2x1c3RlclRyZWUsIGlzQ2x1c3RlcmluZ0VuYWJsZWQsIGZsb3dzLCBjbHVzdGVyWm9vbSwgdGltZUV4dGVudCkgPT4ge1xuICAgICAgaWYgKCFmbG93cykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIGxldCBhZ2dyZWdhdGVkOiAoRiB8IEFnZ3JlZ2F0ZUZsb3cpW107XG4gICAgICBpZiAoaXNDbHVzdGVyaW5nRW5hYmxlZCAmJiBjbHVzdGVyVHJlZSAmJiBjbHVzdGVyWm9vbSAhPSBudWxsKSB7XG4gICAgICAgIGFnZ3JlZ2F0ZWQgPSBjbHVzdGVyVHJlZS5hZ2dyZWdhdGVGbG93cyhcbiAgICAgICAgICAvLyBUT0RPOiBhZ2dyZWdhdGUgYWNyb3NzIHRpbWVcbiAgICAgICAgICAvLyB0aW1lRXh0ZW50ICE9IG51bGxcbiAgICAgICAgICAvLyAgID8gYWdncmVnYXRlRmxvd3MoZmxvd3MpIC8vIGNsdXN0ZXJUcmVlLmFnZ3JlZ2F0ZUZsb3dzIHdvbid0IGFnZ3JlZ2F0ZSB1bmNsdXN0ZXJlZCBhY3Jvc3MgdGltZVxuICAgICAgICAgIC8vICAgOiBmbG93cyxcbiAgICAgICAgICBmbG93cyxcbiAgICAgICAgICBjbHVzdGVyWm9vbSxcbiAgICAgICAgICB0aGlzLmFjY2Vzc29ycy5nZXRGbG93bWFwRGF0YUFjY2Vzc29ycygpLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWdncmVnYXRlZCA9IGFnZ3JlZ2F0ZUZsb3dzKFxuICAgICAgICAgIGZsb3dzLFxuICAgICAgICAgIHRoaXMuYWNjZXNzb3JzLmdldEZsb3dtYXBEYXRhQWNjZXNzb3JzKCksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBhZ2dyZWdhdGVkLnNvcnQoKGEsIGIpID0+XG4gICAgICAgIGRlc2NlbmRpbmcoXG4gICAgICAgICAgTWF0aC5hYnModGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd01hZ25pdHVkZShhKSksXG4gICAgICAgICAgTWF0aC5hYnModGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd01hZ25pdHVkZShiKSksXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgcmV0dXJuIGFnZ3JlZ2F0ZWQ7XG4gICAgfSxcbiAgKTtcblxuICBnZXRFeHBhbmRlZFNlbGVjdGVkTG9jYXRpb25zU2V0OiBTZWxlY3RvcjxMLCBGLCBTZXQ8c3RyaW5nPiB8IHVuZGVmaW5lZD4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy5nZXRDbHVzdGVyaW5nRW5hYmxlZCxcbiAgICAgIHRoaXMuZ2V0U2VsZWN0ZWRMb2NhdGlvbnNTZXQsXG4gICAgICB0aGlzLmdldENsdXN0ZXJJbmRleCxcbiAgICAgIChjbHVzdGVyaW5nRW5hYmxlZCwgc2VsZWN0ZWRMb2NhdGlvbnMsIGNsdXN0ZXJJbmRleCkgPT4ge1xuICAgICAgICBpZiAoIXNlbGVjdGVkTG9jYXRpb25zIHx8ICFjbHVzdGVySW5kZXgpIHtcbiAgICAgICAgICByZXR1cm4gc2VsZWN0ZWRMb2NhdGlvbnM7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgICAgZm9yIChjb25zdCBsb2NhdGlvbklkIG9mIHNlbGVjdGVkTG9jYXRpb25zKSB7XG4gICAgICAgICAgY29uc3QgY2x1c3RlciA9IGNsdXN0ZXJJbmRleC5nZXRDbHVzdGVyQnlJZChsb2NhdGlvbklkKTtcbiAgICAgICAgICBpZiAoY2x1c3Rlcikge1xuICAgICAgICAgICAgY29uc3QgZXhwYW5kZWQgPSBjbHVzdGVySW5kZXguZXhwYW5kQ2x1c3RlcihjbHVzdGVyKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaWQgb2YgZXhwYW5kZWQpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LmFkZChpZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdC5hZGQobG9jYXRpb25JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgICk7XG5cbiAgZ2V0VG90YWxDb3VudHNCeVRpbWU6IFNlbGVjdG9yPEwsIEYsIENvdW50QnlUaW1lW10gfCB1bmRlZmluZWQ+ID1cbiAgICBjcmVhdGVTZWxlY3RvcihcbiAgICAgIHRoaXMuZ2V0U29ydGVkRmxvd3NGb3JLbm93bkxvY2F0aW9ucyxcbiAgICAgIHRoaXMuZ2V0VGltZUdyYW51bGFyaXR5S2V5LFxuICAgICAgdGhpcy5nZXRUaW1lRXh0ZW50LFxuICAgICAgdGhpcy5nZXRFeHBhbmRlZFNlbGVjdGVkTG9jYXRpb25zU2V0LFxuICAgICAgdGhpcy5nZXRMb2NhdGlvbkZpbHRlck1vZGUsXG4gICAgICAoXG4gICAgICAgIGZsb3dzLFxuICAgICAgICB0aW1lR3JhbnVsYXJpdHlLZXksXG4gICAgICAgIHRpbWVFeHRlbnQsXG4gICAgICAgIHNlbGVjdGVkTG9jYXRpb25TZXQsXG4gICAgICAgIGxvY2F0aW9uRmlsdGVyTW9kZSxcbiAgICAgICkgPT4ge1xuICAgICAgICBjb25zdCB0aW1lR3JhbnVsYXJpdHkgPSB0aW1lR3JhbnVsYXJpdHlLZXlcbiAgICAgICAgICA/IGdldFRpbWVHcmFudWxhcml0eUJ5S2V5KHRpbWVHcmFudWxhcml0eUtleSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCFmbG93cyB8fCAhdGltZUdyYW51bGFyaXR5IHx8ICF0aW1lRXh0ZW50KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBieVRpbWUgPSBmbG93cy5yZWR1Y2UoKG0sIGZsb3cpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLmlzRmxvd0luU2VsZWN0aW9uKFxuICAgICAgICAgICAgICBmbG93LFxuICAgICAgICAgICAgICBzZWxlY3RlZExvY2F0aW9uU2V0LFxuICAgICAgICAgICAgICBsb2NhdGlvbkZpbHRlck1vZGUsXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSB0aW1lR3JhbnVsYXJpdHlcbiAgICAgICAgICAgICAgLmludGVydmFsKHRoaXMuYWNjZXNzb3JzLmdldEZsb3dUaW1lKGZsb3cpKVxuICAgICAgICAgICAgICAuZ2V0VGltZSgpO1xuICAgICAgICAgICAgbS5zZXQoXG4gICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgKG0uZ2V0KGtleSkgPz8gMCkgKyB0aGlzLmFjY2Vzc29ycy5nZXRGbG93TWFnbml0dWRlKGZsb3cpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH0sIG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCkpO1xuXG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKGJ5VGltZS5lbnRyaWVzKCkpLm1hcCgoW21pbGxpcywgY291bnRdKSA9PiAoe1xuICAgICAgICAgIHRpbWU6IG5ldyBEYXRlKG1pbGxpcyksXG4gICAgICAgICAgY291bnQsXG4gICAgICAgIH0pKTtcbiAgICAgIH0sXG4gICAgKTtcblxuICBnZXRNYXhMb2NhdGlvbkNpcmNsZVNpemU6IFNlbGVjdG9yPEwsIEYsIG51bWJlcj4gPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmdldExvY2F0aW9uVG90YWxzRW5hYmxlZCxcbiAgICAobG9jYXRpb25Ub3RhbHNFbmFibGVkKSA9PiAobG9jYXRpb25Ub3RhbHNFbmFibGVkID8gMTcgOiAxKSxcbiAgKTtcblxuICBnZXRWaWV3cG9ydEJvdW5kaW5nQm94OiBTZWxlY3RvcjxMLCBGLCBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXT4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy5nZXRWaWV3cG9ydCxcbiAgICAgIHRoaXMuZ2V0TWF4TG9jYXRpb25DaXJjbGVTaXplLFxuICAgICAgZ2V0Vmlld3BvcnRCb3VuZGluZ0JveCxcbiAgICApO1xuXG4gIGdldExvY2F0aW9uc0Zvclpvb206IFNlbGVjdG9yPEwsIEYsIEl0ZXJhYmxlPEw+IHwgQ2x1c3Rlck5vZGVbXSB8IHVuZGVmaW5lZD4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy5nZXRDbHVzdGVyaW5nRW5hYmxlZCxcbiAgICAgIHRoaXMuZ2V0TG9jYXRpb25zSGF2aW5nRmxvd3MsXG4gICAgICB0aGlzLmdldENsdXN0ZXJJbmRleCxcbiAgICAgIHRoaXMuZ2V0Q2x1c3Rlclpvb20sXG4gICAgICAoY2x1c3RlcmluZ0VuYWJsZWQsIGxvY2F0aW9uc0hhdmluZ0Zsb3dzLCBjbHVzdGVySW5kZXgsIGNsdXN0ZXJab29tKSA9PiB7XG4gICAgICAgIGlmIChjbHVzdGVyaW5nRW5hYmxlZCAmJiBjbHVzdGVySW5kZXgpIHtcbiAgICAgICAgICByZXR1cm4gY2x1c3RlckluZGV4LmdldENsdXN0ZXJOb2Rlc0ZvcihjbHVzdGVyWm9vbSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGxvY2F0aW9uc0hhdmluZ0Zsb3dzO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG5cbiAgZ2V0TG9jYXRpb25Ub3RhbHM6IFNlbGVjdG9yPEwsIEYsIE1hcDxzdHJpbmcsIExvY2F0aW9uVG90YWxzPiB8IHVuZGVmaW5lZD4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy5nZXRMb2NhdGlvbnNGb3Jab29tLFxuICAgICAgdGhpcy5nZXRTb3J0ZWRBZ2dyZWdhdGVkRmlsdGVyZWRGbG93cyxcbiAgICAgIHRoaXMuZ2V0U2VsZWN0ZWRMb2NhdGlvbnNTZXQsXG4gICAgICB0aGlzLmdldExvY2F0aW9uRmlsdGVyTW9kZSxcbiAgICAgIChsb2NhdGlvbnMsIGZsb3dzLCBzZWxlY3RlZExvY2F0aW9uc1NldCwgbG9jYXRpb25GaWx0ZXJNb2RlKSA9PiB7XG4gICAgICAgIGlmICghZmxvd3MpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IHRvdGFscyA9IG5ldyBNYXA8c3RyaW5nLCBMb2NhdGlvblRvdGFscz4oKTtcbiAgICAgICAgY29uc3QgYWRkID0gKFxuICAgICAgICAgIGlkOiBzdHJpbmcsXG4gICAgICAgICAgZDogUGFydGlhbDxMb2NhdGlvblRvdGFscz4sXG4gICAgICAgICk6IExvY2F0aW9uVG90YWxzID0+IHtcbiAgICAgICAgICBjb25zdCBydiA9IHRvdGFscy5nZXQoaWQpID8/IHtcbiAgICAgICAgICAgIGluY29taW5nQ291bnQ6IDAsXG4gICAgICAgICAgICBvdXRnb2luZ0NvdW50OiAwLFxuICAgICAgICAgICAgaW50ZXJuYWxDb3VudDogMCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmIChkLmluY29taW5nQ291bnQgIT0gbnVsbCkgcnYuaW5jb21pbmdDb3VudCArPSBkLmluY29taW5nQ291bnQ7XG4gICAgICAgICAgaWYgKGQub3V0Z29pbmdDb3VudCAhPSBudWxsKSBydi5vdXRnb2luZ0NvdW50ICs9IGQub3V0Z29pbmdDb3VudDtcbiAgICAgICAgICBpZiAoZC5pbnRlcm5hbENvdW50ICE9IG51bGwpIHJ2LmludGVybmFsQ291bnQgKz0gZC5pbnRlcm5hbENvdW50O1xuICAgICAgICAgIHJldHVybiBydjtcbiAgICAgICAgfTtcbiAgICAgICAgZm9yIChjb25zdCBmIG9mIGZsb3dzKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5pc0Zsb3dJblNlbGVjdGlvbihmLCBzZWxlY3RlZExvY2F0aW9uc1NldCwgbG9jYXRpb25GaWx0ZXJNb2RlKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3Qgb3JpZ2luSWQgPSB0aGlzLmFjY2Vzc29ycy5nZXRGbG93T3JpZ2luSWQoZik7XG4gICAgICAgICAgICBjb25zdCBkZXN0SWQgPSB0aGlzLmFjY2Vzc29ycy5nZXRGbG93RGVzdElkKGYpO1xuICAgICAgICAgICAgY29uc3QgY291bnQgPSB0aGlzLmFjY2Vzc29ycy5nZXRGbG93TWFnbml0dWRlKGYpO1xuICAgICAgICAgICAgaWYgKG9yaWdpbklkID09PSBkZXN0SWQpIHtcbiAgICAgICAgICAgICAgdG90YWxzLnNldChvcmlnaW5JZCwgYWRkKG9yaWdpbklkLCB7aW50ZXJuYWxDb3VudDogY291bnR9KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0b3RhbHMuc2V0KG9yaWdpbklkLCBhZGQob3JpZ2luSWQsIHtvdXRnb2luZ0NvdW50OiBjb3VudH0pKTtcbiAgICAgICAgICAgICAgdG90YWxzLnNldChkZXN0SWQsIGFkZChkZXN0SWQsIHtpbmNvbWluZ0NvdW50OiBjb3VudH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvdGFscztcbiAgICAgIH0sXG4gICAgKTtcblxuICBnZXRMb2NhdGlvbnNUcmVlOiBTZWxlY3RvcjxMLCBGLCBLREJ1c2hUcmVlPiA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgIHRoaXMuZ2V0TG9jYXRpb25zRm9yWm9vbSxcbiAgICAobG9jYXRpb25zKSA9PiB7XG4gICAgICBpZiAoIWxvY2F0aW9ucykge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBLREJ1c2goXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgbG9jYXRpb25zLFxuICAgICAgICAobG9jYXRpb246IEwgfCBDbHVzdGVyTm9kZSkgPT5cbiAgICAgICAgICBsbmdYKHRoaXMuYWNjZXNzb3JzLmdldExvY2F0aW9uTG9uKGxvY2F0aW9uKSksXG4gICAgICAgIChsb2NhdGlvbjogTCB8IENsdXN0ZXJOb2RlKSA9PlxuICAgICAgICAgIGxhdFkodGhpcy5hY2Nlc3NvcnMuZ2V0TG9jYXRpb25MYXQobG9jYXRpb24pKSxcbiAgICAgICk7XG4gICAgfSxcbiAgKTtcblxuICBfZ2V0TG9jYXRpb25JZHNJblZpZXdwb3J0OiBTZWxlY3RvcjxMLCBGLCBTZXQ8c3RyaW5nPiB8IHVuZGVmaW5lZD4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy5nZXRMb2NhdGlvbnNUcmVlLFxuICAgICAgdGhpcy5nZXRWaWV3cG9ydEJvdW5kaW5nQm94LFxuICAgICAgKHRyZWU6IEtEQnVzaFRyZWUsIGJib3g6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdKSA9PiB7XG4gICAgICAgIGNvbnN0IGlkcyA9IHRoaXMuX2dldExvY2F0aW9uc0luQmJveEluZGljZXModHJlZSwgYmJveCk7XG4gICAgICAgIGlmIChpZHMpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNldChcbiAgICAgICAgICAgIGlkcy5tYXAoKGlkeDogbnVtYmVyKSA9PiB0cmVlLnBvaW50c1tpZHhdLmlkKSBhcyBBcnJheTxzdHJpbmc+LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgKTtcblxuICBnZXRMb2NhdGlvbklkc0luVmlld3BvcnQ6IFNlbGVjdG9yPEwsIEYsIFNldDxzdHJpbmc+IHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3JDcmVhdG9yKFxuICAgICAgZGVmYXVsdE1lbW9pemUsXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAoXG4gICAgICAgIHMxOiBTZXQ8c3RyaW5nPiB8IHVuZGVmaW5lZCxcbiAgICAgICAgczI6IFNldDxzdHJpbmc+IHwgdW5kZWZpbmVkLFxuICAgICAgICBpbmRleDogbnVtYmVyLFxuICAgICAgKSA9PiB7XG4gICAgICAgIGlmIChzMSA9PT0gczIpIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoczEgPT0gbnVsbCB8fCBzMiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChzMS5zaXplICE9PSBzMi5zaXplKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBzMSkgaWYgKCFzMi5oYXMoaXRlbSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9LFxuICAgICkoXG4gICAgICB0aGlzLl9nZXRMb2NhdGlvbklkc0luVmlld3BvcnQsXG4gICAgICAobG9jYXRpb25JZHM6IFNldDxzdHJpbmc+IHwgdW5kZWZpbmVkKSA9PiB7XG4gICAgICAgIGlmICghbG9jYXRpb25JZHMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiBsb2NhdGlvbklkcztcbiAgICAgIH0sXG4gICAgKTtcblxuICBnZXRUb3RhbFVuZmlsdGVyZWRDb3VudDogU2VsZWN0b3I8TCwgRiwgbnVtYmVyIHwgdW5kZWZpbmVkPiA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgIHRoaXMuZ2V0U29ydGVkRmxvd3NGb3JLbm93bkxvY2F0aW9ucyxcbiAgICAoZmxvd3MpID0+IHtcbiAgICAgIGlmICghZmxvd3MpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gZmxvd3MucmVkdWNlKFxuICAgICAgICAobSwgZmxvdykgPT4gbSArIHRoaXMuYWNjZXNzb3JzLmdldEZsb3dNYWduaXR1ZGUoZmxvdyksXG4gICAgICAgIDAsXG4gICAgICApO1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0VG90YWxGaWx0ZXJlZENvdW50OiBTZWxlY3RvcjxMLCBGLCBudW1iZXIgfCB1bmRlZmluZWQ+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRTb3J0ZWRBZ2dyZWdhdGVkRmlsdGVyZWRGbG93cyxcbiAgICB0aGlzLmdldFNlbGVjdGVkTG9jYXRpb25zU2V0LFxuICAgIHRoaXMuZ2V0TG9jYXRpb25GaWx0ZXJNb2RlLFxuICAgIChmbG93cywgc2VsZWN0ZWRMb2NhdGlvblNldCwgbG9jYXRpb25GaWx0ZXJNb2RlKSA9PiB7XG4gICAgICBpZiAoIWZsb3dzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgY291bnQgPSBmbG93cy5yZWR1Y2UoKG0sIGZsb3cpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuaXNGbG93SW5TZWxlY3Rpb24oZmxvdywgc2VsZWN0ZWRMb2NhdGlvblNldCwgbG9jYXRpb25GaWx0ZXJNb2RlKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gbSArIHRoaXMuYWNjZXNzb3JzLmdldEZsb3dNYWduaXR1ZGUoZmxvdyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG07XG4gICAgICB9LCAwKTtcbiAgICAgIHJldHVybiBjb3VudDtcbiAgICB9LFxuICApO1xuXG4gIF9nZXRMb2NhdGlvblRvdGFsc0V4dGVudDogU2VsZWN0b3I8TCwgRiwgW251bWJlciwgbnVtYmVyXSB8IHVuZGVmaW5lZD4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKHRoaXMuZ2V0TG9jYXRpb25Ub3RhbHMsIChsb2NhdGlvblRvdGFscykgPT5cbiAgICAgIGNhbGNMb2NhdGlvblRvdGFsc0V4dGVudChsb2NhdGlvblRvdGFscywgdW5kZWZpbmVkKSxcbiAgICApO1xuXG4gIF9nZXRMb2NhdGlvblRvdGFsc0ZvclZpZXdwb3J0RXh0ZW50OiBTZWxlY3RvcjxcbiAgICBMLFxuICAgIEYsXG4gICAgW251bWJlciwgbnVtYmVyXSB8IHVuZGVmaW5lZFxuICA+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRMb2NhdGlvblRvdGFscyxcbiAgICB0aGlzLmdldExvY2F0aW9uSWRzSW5WaWV3cG9ydCxcbiAgICAobG9jYXRpb25Ub3RhbHMsIGxvY2F0aW9uc0luVmlld3BvcnQpID0+XG4gICAgICBjYWxjTG9jYXRpb25Ub3RhbHNFeHRlbnQobG9jYXRpb25Ub3RhbHMsIGxvY2F0aW9uc0luVmlld3BvcnQpLFxuICApO1xuXG4gIGdldExvY2F0aW9uVG90YWxzRXh0ZW50ID0gKFxuICAgIHN0YXRlOiBGbG93bWFwU3RhdGUsXG4gICAgcHJvcHM6IEZsb3dtYXBEYXRhPEwsIEY+LFxuICApOiBbbnVtYmVyLCBudW1iZXJdIHwgdW5kZWZpbmVkID0+IHtcbiAgICBpZiAoc3RhdGUuc2V0dGluZ3MuYWRhcHRpdmVTY2FsZXNFbmFibGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0TG9jYXRpb25Ub3RhbHNGb3JWaWV3cG9ydEV4dGVudChzdGF0ZSwgcHJvcHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0TG9jYXRpb25Ub3RhbHNFeHRlbnQoc3RhdGUsIHByb3BzKTtcbiAgICB9XG4gIH07XG5cbiAgZ2V0Rmxvd3NGb3JGbG93bWFwTGF5ZXI6IFNlbGVjdG9yPEwsIEYsIChGIHwgQWdncmVnYXRlRmxvdylbXSB8IHVuZGVmaW5lZD4gPVxuICAgIGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgdGhpcy5nZXRTb3J0ZWRBZ2dyZWdhdGVkRmlsdGVyZWRGbG93cyxcbiAgICAgIHRoaXMuZ2V0TG9jYXRpb25JZHNJblZpZXdwb3J0LFxuICAgICAgdGhpcy5nZXRTZWxlY3RlZExvY2F0aW9uc1NldCxcbiAgICAgIHRoaXMuZ2V0TG9jYXRpb25GaWx0ZXJNb2RlLFxuICAgICAgdGhpcy5nZXRNYXhUb3BGbG93c0Rpc3BsYXlOdW0sXG4gICAgICAoXG4gICAgICAgIGZsb3dzLFxuICAgICAgICBsb2NhdGlvbklkc0luVmlld3BvcnQsXG4gICAgICAgIHNlbGVjdGVkTG9jYXRpb25zU2V0LFxuICAgICAgICBsb2NhdGlvbkZpbHRlck1vZGUsXG4gICAgICAgIG1heFRvcEZsb3dzRGlzcGxheU51bSxcbiAgICAgICkgPT4ge1xuICAgICAgICBpZiAoIWZsb3dzIHx8ICFsb2NhdGlvbklkc0luVmlld3BvcnQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IHBpY2tlZDogKEYgfCBBZ2dyZWdhdGVGbG93KVtdID0gW107XG4gICAgICAgIGxldCBwaWNrZWRDb3VudCA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgZmxvdyBvZiBmbG93cykge1xuICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IHRoaXMuYWNjZXNzb3JzLmdldEZsb3dPcmlnaW5JZChmbG93KTtcbiAgICAgICAgICBjb25zdCBkZXN0ID0gdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd0Rlc3RJZChmbG93KTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBsb2NhdGlvbklkc0luVmlld3BvcnQuaGFzKG9yaWdpbikgfHxcbiAgICAgICAgICAgIGxvY2F0aW9uSWRzSW5WaWV3cG9ydC5oYXMoZGVzdClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5pc0Zsb3dJblNlbGVjdGlvbihcbiAgICAgICAgICAgICAgICBmbG93LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkTG9jYXRpb25zU2V0LFxuICAgICAgICAgICAgICAgIGxvY2F0aW9uRmlsdGVyTW9kZSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGlmIChvcmlnaW4gIT09IGRlc3QpIHtcbiAgICAgICAgICAgICAgICAvLyBleGNsdWRlIHNlbGYtbG9vcHNcbiAgICAgICAgICAgICAgICBwaWNrZWQucHVzaChmbG93KTtcbiAgICAgICAgICAgICAgICBwaWNrZWRDb3VudCsrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE9ubHkga2VlcCB0b3BcbiAgICAgICAgICBpZiAocGlja2VkQ291bnQgPiBtYXhUb3BGbG93c0Rpc3BsYXlOdW0pIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vIGFzc3VtaW5nIHRoZXkgYXJlIHNvcnRlZCBpbiBkZXNjZW5kaW5nIG9yZGVyLFxuICAgICAgICAvLyB3ZSBuZWVkIGFzY2VuZGluZyBmb3IgcmVuZGVyaW5nXG4gICAgICAgIHJldHVybiBwaWNrZWQucmV2ZXJzZSgpO1xuICAgICAgfSxcbiAgICApO1xuXG4gIF9nZXRGbG93TWFnbml0dWRlRXh0ZW50OiBTZWxlY3RvcjxMLCBGLCBbbnVtYmVyLCBudW1iZXJdIHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IoXG4gICAgICB0aGlzLmdldFNvcnRlZEFnZ3JlZ2F0ZWRGaWx0ZXJlZEZsb3dzLFxuICAgICAgdGhpcy5nZXRTZWxlY3RlZExvY2F0aW9uc1NldCxcbiAgICAgIHRoaXMuZ2V0TG9jYXRpb25GaWx0ZXJNb2RlLFxuICAgICAgKGZsb3dzLCBzZWxlY3RlZExvY2F0aW9uc1NldCwgbG9jYXRpb25GaWx0ZXJNb2RlKSA9PiB7XG4gICAgICAgIGlmICghZmxvd3MpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBydjogW251bWJlciwgbnVtYmVyXSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCBmIG9mIGZsb3dzKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd09yaWdpbklkKGYpICE9PVxuICAgICAgICAgICAgICB0aGlzLmFjY2Vzc29ycy5nZXRGbG93RGVzdElkKGYpICYmXG4gICAgICAgICAgICB0aGlzLmlzRmxvd0luU2VsZWN0aW9uKGYsIHNlbGVjdGVkTG9jYXRpb25zU2V0LCBsb2NhdGlvbkZpbHRlck1vZGUpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMuYWNjZXNzb3JzLmdldEZsb3dNYWduaXR1ZGUoZik7XG4gICAgICAgICAgICBpZiAocnYgPT0gbnVsbCkge1xuICAgICAgICAgICAgICBydiA9IFtjb3VudCwgY291bnRdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKGNvdW50IDwgcnZbMF0pIHJ2WzBdID0gY291bnQ7XG4gICAgICAgICAgICAgIGlmIChjb3VudCA+IHJ2WzFdKSBydlsxXSA9IGNvdW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcnY7XG4gICAgICB9LFxuICAgICk7XG5cbiAgX2dldEFkYXB0aXZlRmxvd01hZ25pdHVkZUV4dGVudDogU2VsZWN0b3I8XG4gICAgTCxcbiAgICBGLFxuICAgIFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWRcbiAgPiA9IGNyZWF0ZVNlbGVjdG9yKHRoaXMuZ2V0Rmxvd3NGb3JGbG93bWFwTGF5ZXIsIChmbG93cykgPT4ge1xuICAgIGlmICghZmxvd3MpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcnYgPSBleHRlbnQoZmxvd3MsIHRoaXMuYWNjZXNzb3JzLmdldEZsb3dNYWduaXR1ZGUpO1xuICAgIHJldHVybiBydlswXSAhPT0gdW5kZWZpbmVkICYmIHJ2WzFdICE9PSB1bmRlZmluZWQgPyBydiA6IHVuZGVmaW5lZDtcbiAgfSk7XG5cbiAgZ2V0Rmxvd01hZ25pdHVkZUV4dGVudCA9IChcbiAgICBzdGF0ZTogRmxvd21hcFN0YXRlLFxuICAgIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPixcbiAgKTogW251bWJlciwgbnVtYmVyXSB8IHVuZGVmaW5lZCA9PiB7XG4gICAgaWYgKHN0YXRlLnNldHRpbmdzLmFkYXB0aXZlU2NhbGVzRW5hYmxlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldEFkYXB0aXZlRmxvd01hZ25pdHVkZUV4dGVudChzdGF0ZSwgcHJvcHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0Rmxvd01hZ25pdHVkZUV4dGVudChzdGF0ZSwgcHJvcHMpO1xuICAgIH1cbiAgfTtcblxuICBnZXRMb2NhdGlvbk1heEFic1RvdGFsR2V0dGVyID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRMb2NhdGlvblRvdGFscyxcbiAgICAobG9jYXRpb25Ub3RhbHMpID0+IHtcbiAgICAgIHJldHVybiAobG9jYXRpb25JZDogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHRvdGFsID0gbG9jYXRpb25Ub3RhbHM/LmdldChsb2NhdGlvbklkKTtcbiAgICAgICAgaWYgKCF0b3RhbCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KFxuICAgICAgICAgIE1hdGguYWJzKHRvdGFsLmluY29taW5nQ291bnQgKyB0b3RhbC5pbnRlcm5hbENvdW50KSxcbiAgICAgICAgICBNYXRoLmFicyh0b3RhbC5vdXRnb2luZ0NvdW50ICsgdG90YWwuaW50ZXJuYWxDb3VudCksXG4gICAgICAgICk7XG4gICAgICB9O1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0Rmxvd1RoaWNrbmVzc1NjYWxlID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRGbG93TWFnbml0dWRlRXh0ZW50LFxuICAgIGdldEZsb3dUaGlja25lc3NTY2FsZSxcbiAgKTtcblxuICBnZXRDaXJjbGVTaXplU2NhbGUgPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmdldE1heExvY2F0aW9uQ2lyY2xlU2l6ZSxcbiAgICB0aGlzLmdldExvY2F0aW9uVG90YWxzRW5hYmxlZCxcbiAgICB0aGlzLmdldExvY2F0aW9uVG90YWxzRXh0ZW50LFxuICAgIChtYXhMb2NhdGlvbkNpcmNsZVNpemUsIGxvY2F0aW9uVG90YWxzRW5hYmxlZCwgbG9jYXRpb25Ub3RhbHNFeHRlbnQpID0+IHtcbiAgICAgIGlmICghbG9jYXRpb25Ub3RhbHNFbmFibGVkKSB7XG4gICAgICAgIHJldHVybiAoKSA9PiBtYXhMb2NhdGlvbkNpcmNsZVNpemU7XG4gICAgICB9XG4gICAgICBpZiAoIWxvY2F0aW9uVG90YWxzRXh0ZW50KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHNjYWxlU3FydCgpXG4gICAgICAgIC5yYW5nZShbMCwgbWF4TG9jYXRpb25DaXJjbGVTaXplXSlcbiAgICAgICAgLmRvbWFpbihbXG4gICAgICAgICAgMCxcbiAgICAgICAgICAvLyBzaG91bGQgc3VwcG9ydCBkaWZmIG1vZGUgdG9vXG4gICAgICAgICAgTWF0aC5tYXguYXBwbHkoXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgbG9jYXRpb25Ub3RhbHNFeHRlbnQubWFwKCh4OiBudW1iZXIgfCB1bmRlZmluZWQpID0+XG4gICAgICAgICAgICAgIE1hdGguYWJzKHggfHwgMCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICksXG4gICAgICAgIF0pO1xuICAgIH0sXG4gICk7XG5cbiAgZ2V0SW5DaXJjbGVTaXplR2V0dGVyID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRDaXJjbGVTaXplU2NhbGUsXG4gICAgdGhpcy5nZXRMb2NhdGlvblRvdGFscyxcbiAgICAoY2lyY2xlU2l6ZVNjYWxlLCBsb2NhdGlvblRvdGFscykgPT4ge1xuICAgICAgcmV0dXJuIChsb2NhdGlvbklkOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgdG90YWwgPSBsb2NhdGlvblRvdGFscz8uZ2V0KGxvY2F0aW9uSWQpO1xuICAgICAgICBpZiAodG90YWwgJiYgY2lyY2xlU2l6ZVNjYWxlKSB7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGNpcmNsZVNpemVTY2FsZShcbiAgICAgICAgICAgICAgTWF0aC5hYnModG90YWwuaW5jb21pbmdDb3VudCArIHRvdGFsLmludGVybmFsQ291bnQpLFxuICAgICAgICAgICAgKSB8fCAwXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH07XG4gICAgfSxcbiAgKTtcblxuICBnZXRPdXRDaXJjbGVTaXplR2V0dGVyID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRDaXJjbGVTaXplU2NhbGUsXG4gICAgdGhpcy5nZXRMb2NhdGlvblRvdGFscyxcbiAgICAoY2lyY2xlU2l6ZVNjYWxlLCBsb2NhdGlvblRvdGFscykgPT4ge1xuICAgICAgcmV0dXJuIChsb2NhdGlvbklkOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgdG90YWwgPSBsb2NhdGlvblRvdGFscz8uZ2V0KGxvY2F0aW9uSWQpO1xuICAgICAgICBpZiAodG90YWwgJiYgY2lyY2xlU2l6ZVNjYWxlKSB7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGNpcmNsZVNpemVTY2FsZShcbiAgICAgICAgICAgICAgTWF0aC5hYnModG90YWwub3V0Z29pbmdDb3VudCArIHRvdGFsLmludGVybmFsQ291bnQpLFxuICAgICAgICAgICAgKSB8fCAwXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH07XG4gICAgfSxcbiAgKTtcblxuICBnZXRTb3J0ZWRMb2NhdGlvbnNGb3Jab29tOiBTZWxlY3RvcjxMLCBGLCBMW10gfCBDbHVzdGVyTm9kZVtdIHwgdW5kZWZpbmVkPiA9XG4gICAgY3JlYXRlU2VsZWN0b3IoXG4gICAgICB0aGlzLmdldExvY2F0aW9uc0Zvclpvb20sXG4gICAgICB0aGlzLmdldEluQ2lyY2xlU2l6ZUdldHRlcixcbiAgICAgIHRoaXMuZ2V0T3V0Q2lyY2xlU2l6ZUdldHRlcixcbiAgICAgIChsb2NhdGlvbnMsIGdldEluQ2lyY2xlU2l6ZSwgZ2V0T3V0Q2lyY2xlU2l6ZSkgPT4ge1xuICAgICAgICBpZiAoIWxvY2F0aW9ucykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgbmV4dExvY2F0aW9ucyA9IFsuLi5sb2NhdGlvbnNdIGFzIExbXSB8IENsdXN0ZXJOb2RlW107XG4gICAgICAgIHJldHVybiBuZXh0TG9jYXRpb25zLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICBjb25zdCBpZEEgPSB0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbklkKGEpO1xuICAgICAgICAgIGNvbnN0IGlkQiA9IHRoaXMuYWNjZXNzb3JzLmdldExvY2F0aW9uSWQoYik7XG4gICAgICAgICAgcmV0dXJuIGFzY2VuZGluZyhcbiAgICAgICAgICAgIE1hdGgubWF4KGdldEluQ2lyY2xlU2l6ZShpZEEpLCBnZXRPdXRDaXJjbGVTaXplKGlkQSkpLFxuICAgICAgICAgICAgTWF0aC5tYXgoZ2V0SW5DaXJjbGVTaXplKGlkQiksIGdldE91dENpcmNsZVNpemUoaWRCKSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICk7XG5cbiAgZ2V0TG9jYXRpb25zRm9yRmxvd21hcExheWVyOiBTZWxlY3RvcjxcbiAgICBMLFxuICAgIEYsXG4gICAgQXJyYXk8TCB8IENsdXN0ZXJOb2RlPiB8IHVuZGVmaW5lZFxuICA+ID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgdGhpcy5nZXRTb3J0ZWRMb2NhdGlvbnNGb3Jab29tLFxuICAgIC8vIHRoaXMuZ2V0TG9jYXRpb25JZHNJblZpZXdwb3J0LFxuICAgIChcbiAgICAgIGxvY2F0aW9ucyxcbiAgICAgIC8vIGxvY2F0aW9uSWRzSW5WaWV3cG9ydFxuICAgICkgPT4ge1xuICAgICAgLy8gaWYgKCFsb2NhdGlvbnMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAvLyBpZiAoIWxvY2F0aW9uSWRzSW5WaWV3cG9ydCkgcmV0dXJuIGxvY2F0aW9ucztcbiAgICAgIC8vIGlmIChsb2NhdGlvbklkc0luVmlld3BvcnQuc2l6ZSA9PT0gbG9jYXRpb25zLmxlbmd0aCkgcmV0dXJuIGxvY2F0aW9ucztcbiAgICAgIC8vIGNvbnN0IGZpbHRlcmVkID0gW107XG4gICAgICAvLyBmb3IgKGNvbnN0IGxvYyBvZiBsb2NhdGlvbnMpIHtcbiAgICAgIC8vICAgaWYgKGxvY2F0aW9uSWRzSW5WaWV3cG9ydC5oYXMobG9jLmlkKSkge1xuICAgICAgLy8gICAgIGZpbHRlcmVkLnB1c2gobG9jKTtcbiAgICAgIC8vICAgfVxuICAgICAgLy8gfVxuICAgICAgLy8gcmV0dXJuIGZpbHRlcmVkO1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgLy8gcmV0dXJuIGxvY2F0aW9ucy5maWx0ZXIoXG4gICAgICAvLyAgIChsb2M6IEwgfCBDbHVzdGVyTm9kZSkgPT4gbG9jYXRpb25JZHNJblZpZXdwb3J0IS5oYXMobG9jLmlkKVxuICAgICAgLy8gKTtcbiAgICAgIC8vIFRPRE86IHJldHVybiBsb2NhdGlvbiBpbiB2aWV3cG9ydCArIFwiY29ubmVjdGVkXCIgb25lc1xuICAgICAgcmV0dXJuIGxvY2F0aW9ucztcbiAgICB9LFxuICApO1xuXG4gIGdldExvY2F0aW9uc0ZvckZsb3dtYXBMYXllckJ5SWQ6IFNlbGVjdG9yPFxuICAgIEwsXG4gICAgRixcbiAgICBNYXA8c3RyaW5nLCBMIHwgQ2x1c3Rlck5vZGU+IHwgdW5kZWZpbmVkXG4gID4gPSBjcmVhdGVTZWxlY3Rvcih0aGlzLmdldExvY2F0aW9uc0ZvckZsb3dtYXBMYXllciwgKGxvY2F0aW9ucykgPT4ge1xuICAgIGlmICghbG9jYXRpb25zKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiBsb2NhdGlvbnMucmVkdWNlKFxuICAgICAgKG0sIGQpID0+IChtLnNldCh0aGlzLmFjY2Vzc29ycy5nZXRMb2NhdGlvbklkKGQpLCBkKSwgbSksXG4gICAgICBuZXcgTWFwKCksXG4gICAgKTtcbiAgfSk7XG5cbiAgZ2V0TGF5ZXJzRGF0YTogU2VsZWN0b3I8TCwgRiwgTGF5ZXJzRGF0YT4gPSBjcmVhdGVTZWxlY3RvcihcbiAgICB0aGlzLmdldExvY2F0aW9uc0ZvckZsb3dtYXBMYXllcixcbiAgICB0aGlzLmdldEZsb3dzRm9yRmxvd21hcExheWVyLFxuICAgIHRoaXMuZ2V0Rmxvd21hcENvbG9yc1JHQkEsXG4gICAgdGhpcy5nZXRMb2NhdGlvbnNGb3JGbG93bWFwTGF5ZXJCeUlkLFxuICAgIHRoaXMuZ2V0TG9jYXRpb25JZHNJblZpZXdwb3J0LFxuICAgIHRoaXMuZ2V0SW5DaXJjbGVTaXplR2V0dGVyLFxuICAgIHRoaXMuZ2V0T3V0Q2lyY2xlU2l6ZUdldHRlcixcbiAgICB0aGlzLmdldEZsb3dUaGlja25lc3NTY2FsZSxcbiAgICB0aGlzLmdldEFuaW1hdGUsXG4gICAgKFxuICAgICAgbG9jYXRpb25zLFxuICAgICAgZmxvd3MsXG4gICAgICBmbG93bWFwQ29sb3JzLFxuICAgICAgbG9jYXRpb25zQnlJZCxcbiAgICAgIGxvY2F0aW9uSWRzSW5WaWV3cG9ydCxcbiAgICAgIGdldEluQ2lyY2xlU2l6ZSxcbiAgICAgIGdldE91dENpcmNsZVNpemUsXG4gICAgICBmbG93VGhpY2tuZXNzU2NhbGUsXG4gICAgICBhbmltYXRpb25FbmFibGVkLFxuICAgICkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuX3ByZXBhcmVMYXllcnNEYXRhKFxuICAgICAgICBsb2NhdGlvbnMsXG4gICAgICAgIGZsb3dzLFxuICAgICAgICBmbG93bWFwQ29sb3JzLFxuICAgICAgICBsb2NhdGlvbnNCeUlkLFxuICAgICAgICBsb2NhdGlvbklkc0luVmlld3BvcnQsXG4gICAgICAgIGdldEluQ2lyY2xlU2l6ZSxcbiAgICAgICAgZ2V0T3V0Q2lyY2xlU2l6ZSxcbiAgICAgICAgZmxvd1RoaWNrbmVzc1NjYWxlLFxuICAgICAgICBhbmltYXRpb25FbmFibGVkLFxuICAgICAgKTtcbiAgICB9LFxuICApO1xuXG4gIHByZXBhcmVMYXllcnNEYXRhKHN0YXRlOiBGbG93bWFwU3RhdGUsIHByb3BzOiBGbG93bWFwRGF0YTxMLCBGPik6IExheWVyc0RhdGEge1xuICAgIGNvbnN0IGxvY2F0aW9ucyA9IHRoaXMuZ2V0TG9jYXRpb25zRm9yRmxvd21hcExheWVyKHN0YXRlLCBwcm9wcykgfHwgW107XG4gICAgY29uc3QgZmxvd3MgPSB0aGlzLmdldEZsb3dzRm9yRmxvd21hcExheWVyKHN0YXRlLCBwcm9wcykgfHwgW107XG4gICAgY29uc3QgZmxvd21hcENvbG9ycyA9IHRoaXMuZ2V0Rmxvd21hcENvbG9yc1JHQkEoc3RhdGUsIHByb3BzKTtcbiAgICBjb25zdCBsb2NhdGlvbnNCeUlkID0gdGhpcy5nZXRMb2NhdGlvbnNGb3JGbG93bWFwTGF5ZXJCeUlkKHN0YXRlLCBwcm9wcyk7XG4gICAgY29uc3QgbG9jYXRpb25JZHNJblZpZXdwb3J0ID0gdGhpcy5nZXRMb2NhdGlvbklkc0luVmlld3BvcnQoc3RhdGUsIHByb3BzKTtcbiAgICBjb25zdCBnZXRJbkNpcmNsZVNpemUgPSB0aGlzLmdldEluQ2lyY2xlU2l6ZUdldHRlcihzdGF0ZSwgcHJvcHMpO1xuICAgIGNvbnN0IGdldE91dENpcmNsZVNpemUgPSB0aGlzLmdldE91dENpcmNsZVNpemVHZXR0ZXIoc3RhdGUsIHByb3BzKTtcbiAgICBjb25zdCBmbG93VGhpY2tuZXNzU2NhbGUgPSB0aGlzLmdldEZsb3dUaGlja25lc3NTY2FsZShzdGF0ZSwgcHJvcHMpO1xuICAgIHJldHVybiB0aGlzLl9wcmVwYXJlTGF5ZXJzRGF0YShcbiAgICAgIGxvY2F0aW9ucyxcbiAgICAgIGZsb3dzLFxuICAgICAgZmxvd21hcENvbG9ycyxcbiAgICAgIGxvY2F0aW9uc0J5SWQsXG4gICAgICBsb2NhdGlvbklkc0luVmlld3BvcnQsXG4gICAgICBnZXRJbkNpcmNsZVNpemUsXG4gICAgICBnZXRPdXRDaXJjbGVTaXplLFxuICAgICAgZmxvd1RoaWNrbmVzc1NjYWxlLFxuICAgICAgc3RhdGUuc2V0dGluZ3MuYW5pbWF0aW9uRW5hYmxlZCxcbiAgICApO1xuICB9XG5cbiAgX3ByZXBhcmVMYXllcnNEYXRhKFxuICAgIGxvY2F0aW9uczogKEwgfCBDbHVzdGVyTm9kZSlbXSB8IHVuZGVmaW5lZCxcbiAgICBmbG93czogKEYgfCBBZ2dyZWdhdGVGbG93KVtdIHwgdW5kZWZpbmVkLFxuICAgIGZsb3dtYXBDb2xvcnM6IERpZmZDb2xvcnNSR0JBIHwgQ29sb3JzUkdCQSxcbiAgICBsb2NhdGlvbnNCeUlkOiBNYXA8c3RyaW5nLCBMIHwgQ2x1c3Rlck5vZGU+IHwgdW5kZWZpbmVkLFxuICAgIGxvY2F0aW9uSWRzSW5WaWV3cG9ydDogU2V0PHN0cmluZz4gfCB1bmRlZmluZWQsXG4gICAgZ2V0SW5DaXJjbGVTaXplOiAobG9jYXRpb25JZDogc3RyaW5nKSA9PiBudW1iZXIsXG4gICAgZ2V0T3V0Q2lyY2xlU2l6ZTogKGxvY2F0aW9uSWQ6IHN0cmluZykgPT4gbnVtYmVyLFxuICAgIGZsb3dUaGlja25lc3NTY2FsZTogU2NhbGVMaW5lYXI8bnVtYmVyLCBudW1iZXIsIG5ldmVyPiB8IHVuZGVmaW5lZCxcbiAgICBhbmltYXRpb25FbmFibGVkOiBib29sZWFuLFxuICApOiBMYXllcnNEYXRhIHtcbiAgICBpZiAoIWxvY2F0aW9ucykgbG9jYXRpb25zID0gW107XG4gICAgaWYgKCFmbG93cykgZmxvd3MgPSBbXTtcbiAgICBjb25zdCB7XG4gICAgICBnZXRGbG93T3JpZ2luSWQsXG4gICAgICBnZXRGbG93RGVzdElkLFxuICAgICAgZ2V0Rmxvd01hZ25pdHVkZSxcbiAgICAgIGdldExvY2F0aW9uSWQsXG4gICAgICBnZXRMb2NhdGlvbkxvbixcbiAgICAgIGdldExvY2F0aW9uTGF0LFxuICAgIH0gPSB0aGlzLmFjY2Vzc29ycztcblxuICAgIGNvbnN0IGZsb3dNYWduaXR1ZGVFeHRlbnQgPSBleHRlbnQoZmxvd3MsIChmKSA9PiBnZXRGbG93TWFnbml0dWRlKGYpKSBhcyBbXG4gICAgICBudW1iZXIsXG4gICAgICBudW1iZXIsXG4gICAgXTtcbiAgICBjb25zdCBmbG93Q29sb3JTY2FsZSA9IGdldEZsb3dDb2xvclNjYWxlKFxuICAgICAgZmxvd21hcENvbG9ycyxcbiAgICAgIGZsb3dNYWduaXR1ZGVFeHRlbnQsXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgLy8gVXNpbmcgYSBnZW5lcmF0b3IgaGVyZSBoZWxwcyB0byBhdm9pZCBjcmVhdGluZyBpbnRlcm1lZGlhcnkgYXJyYXlzXG4gICAgY29uc3QgY2lyY2xlUG9zaXRpb25zID0gRmxvYXQzMkFycmF5LmZyb20oXG4gICAgICAoZnVuY3Rpb24qICgpIHtcbiAgICAgICAgZm9yIChjb25zdCBsb2NhdGlvbiBvZiBsb2NhdGlvbnMpIHtcbiAgICAgICAgICB5aWVsZCBnZXRMb2NhdGlvbkxvbihsb2NhdGlvbik7XG4gICAgICAgICAgeWllbGQgZ2V0TG9jYXRpb25MYXQobG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICB9KSgpLFxuICAgICk7XG5cbiAgICAvLyBUT0RPOiBkaWZmIG1vZGVcbiAgICBjb25zdCBjaXJjbGVDb2xvciA9IGlzRGlmZkNvbG9yc1JHQkEoZmxvd21hcENvbG9ycylcbiAgICAgID8gZmxvd21hcENvbG9ycy5wb3NpdGl2ZS5sb2NhdGlvbkNpcmNsZXMuaW5uZXJcbiAgICAgIDogZmxvd21hcENvbG9ycy5sb2NhdGlvbkNpcmNsZXMuaW5uZXI7XG5cbiAgICBjb25zdCBjaXJjbGVDb2xvcnMgPSBVaW50OEFycmF5LmZyb20oXG4gICAgICAoZnVuY3Rpb24qICgpIHtcbiAgICAgICAgZm9yIChjb25zdCBsb2NhdGlvbiBvZiBsb2NhdGlvbnMpIHtcbiAgICAgICAgICB5aWVsZCogY2lyY2xlQ29sb3I7XG4gICAgICAgIH1cbiAgICAgIH0pKCksXG4gICAgKTtcblxuICAgIGNvbnN0IGluQ2lyY2xlUmFkaWkgPSBGbG9hdDMyQXJyYXkuZnJvbShcbiAgICAgIChmdW5jdGlvbiogKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGxvY2F0aW9uIG9mIGxvY2F0aW9ucykge1xuICAgICAgICAgIGNvbnN0IGlkID0gZ2V0TG9jYXRpb25JZChsb2NhdGlvbik7XG4gICAgICAgICAgeWllbGQgbG9jYXRpb25JZHNJblZpZXdwb3J0Py5oYXMoaWQpID8gZ2V0SW5DaXJjbGVTaXplKGlkKSA6IDEuMDtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICApO1xuICAgIGNvbnN0IG91dENpcmNsZVJhZGlpID0gRmxvYXQzMkFycmF5LmZyb20oXG4gICAgICAoZnVuY3Rpb24qICgpIHtcbiAgICAgICAgZm9yIChjb25zdCBsb2NhdGlvbiBvZiBsb2NhdGlvbnMpIHtcbiAgICAgICAgICBjb25zdCBpZCA9IGdldExvY2F0aW9uSWQobG9jYXRpb24pO1xuICAgICAgICAgIHlpZWxkIGxvY2F0aW9uSWRzSW5WaWV3cG9ydD8uaGFzKGlkKSA/IGdldE91dENpcmNsZVNpemUoaWQpIDogMS4wO1xuICAgICAgICB9XG4gICAgICB9KSgpLFxuICAgICk7XG5cbiAgICBjb25zdCBzb3VyY2VQb3NpdGlvbnMgPSBGbG9hdDMyQXJyYXkuZnJvbShcbiAgICAgIChmdW5jdGlvbiogKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MpIHtcbiAgICAgICAgICBjb25zdCBsb2MgPSBsb2NhdGlvbnNCeUlkPy5nZXQoZ2V0Rmxvd09yaWdpbklkKGZsb3cpKTtcbiAgICAgICAgICB5aWVsZCBsb2MgPyBnZXRMb2NhdGlvbkxvbihsb2MpIDogMDtcbiAgICAgICAgICB5aWVsZCBsb2MgPyBnZXRMb2NhdGlvbkxhdChsb2MpIDogMDtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICApO1xuICAgIGNvbnN0IHRhcmdldFBvc2l0aW9ucyA9IEZsb2F0MzJBcnJheS5mcm9tKFxuICAgICAgKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmxvdyBvZiBmbG93cykge1xuICAgICAgICAgIGNvbnN0IGxvYyA9IGxvY2F0aW9uc0J5SWQ/LmdldChnZXRGbG93RGVzdElkKGZsb3cpKTtcbiAgICAgICAgICB5aWVsZCBsb2MgPyBnZXRMb2NhdGlvbkxvbihsb2MpIDogMDtcbiAgICAgICAgICB5aWVsZCBsb2MgPyBnZXRMb2NhdGlvbkxhdChsb2MpIDogMDtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICApO1xuICAgIGNvbnN0IHRoaWNrbmVzc2VzID0gRmxvYXQzMkFycmF5LmZyb20oXG4gICAgICAoZnVuY3Rpb24qICgpIHtcbiAgICAgICAgZm9yIChjb25zdCBmbG93IG9mIGZsb3dzKSB7XG4gICAgICAgICAgeWllbGQgZmxvd1RoaWNrbmVzc1NjYWxlXG4gICAgICAgICAgICA/IGZsb3dUaGlja25lc3NTY2FsZShnZXRGbG93TWFnbml0dWRlKGZsb3cpKSB8fCAwXG4gICAgICAgICAgICA6IDA7XG4gICAgICAgIH1cbiAgICAgIH0pKCksXG4gICAgKTtcbiAgICBjb25zdCBlbmRwb2ludE9mZnNldHMgPSBGbG9hdDMyQXJyYXkuZnJvbShcbiAgICAgIChmdW5jdGlvbiogKCkge1xuICAgICAgICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MpIHtcbiAgICAgICAgICBjb25zdCBvcmlnaW5JZCA9IGdldEZsb3dPcmlnaW5JZChmbG93KTtcbiAgICAgICAgICBjb25zdCBkZXN0SWQgPSBnZXRGbG93RGVzdElkKGZsb3cpO1xuICAgICAgICAgIHlpZWxkIE1hdGgubWF4KGdldEluQ2lyY2xlU2l6ZShvcmlnaW5JZCksIGdldE91dENpcmNsZVNpemUob3JpZ2luSWQpKTtcbiAgICAgICAgICB5aWVsZCBNYXRoLm1heChnZXRJbkNpcmNsZVNpemUoZGVzdElkKSwgZ2V0T3V0Q2lyY2xlU2l6ZShkZXN0SWQpKTtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICApO1xuICAgIGNvbnN0IGZsb3dMaW5lQ29sb3JzID0gVWludDhBcnJheS5mcm9tKFxuICAgICAgKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmxvdyBvZiBmbG93cykge1xuICAgICAgICAgIHlpZWxkKiBmbG93Q29sb3JTY2FsZShnZXRGbG93TWFnbml0dWRlKGZsb3cpKTtcbiAgICAgICAgfVxuICAgICAgfSkoKSxcbiAgICApO1xuXG4gICAgY29uc3Qgc3RhZ2dlcmluZ1ZhbHVlcyA9IGFuaW1hdGlvbkVuYWJsZWRcbiAgICAgID8gRmxvYXQzMkFycmF5LmZyb20oXG4gICAgICAgICAgKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGYgb2YgZmxvd3MpIHtcbiAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICB5aWVsZCBuZXcgYWxlYShgJHtnZXRGbG93T3JpZ2luSWQoZil9LSR7Z2V0Rmxvd0Rlc3RJZChmKX1gKSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pKCksXG4gICAgICAgIClcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNpcmNsZUF0dHJpYnV0ZXM6IHtcbiAgICAgICAgbGVuZ3RoOiBsb2NhdGlvbnMubGVuZ3RoLFxuICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgZ2V0UG9zaXRpb246IHt2YWx1ZTogY2lyY2xlUG9zaXRpb25zLCBzaXplOiAyfSxcbiAgICAgICAgICBnZXRDb2xvcjoge3ZhbHVlOiBjaXJjbGVDb2xvcnMsIHNpemU6IDR9LFxuICAgICAgICAgIGdldEluUmFkaXVzOiB7dmFsdWU6IGluQ2lyY2xlUmFkaWksIHNpemU6IDF9LFxuICAgICAgICAgIGdldE91dFJhZGl1czoge3ZhbHVlOiBvdXRDaXJjbGVSYWRpaSwgc2l6ZTogMX0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbGluZUF0dHJpYnV0ZXM6IHtcbiAgICAgICAgbGVuZ3RoOiBmbG93cy5sZW5ndGgsXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICBnZXRTb3VyY2VQb3NpdGlvbjoge3ZhbHVlOiBzb3VyY2VQb3NpdGlvbnMsIHNpemU6IDJ9LFxuICAgICAgICAgIGdldFRhcmdldFBvc2l0aW9uOiB7dmFsdWU6IHRhcmdldFBvc2l0aW9ucywgc2l6ZTogMn0sXG4gICAgICAgICAgZ2V0VGhpY2tuZXNzOiB7dmFsdWU6IHRoaWNrbmVzc2VzLCBzaXplOiAxfSxcbiAgICAgICAgICBnZXRDb2xvcjoge3ZhbHVlOiBmbG93TGluZUNvbG9ycywgc2l6ZTogNH0sXG4gICAgICAgICAgZ2V0RW5kcG9pbnRPZmZzZXRzOiB7dmFsdWU6IGVuZHBvaW50T2Zmc2V0cywgc2l6ZTogMn0sXG4gICAgICAgICAgLi4uKHN0YWdnZXJpbmdWYWx1ZXNcbiAgICAgICAgICAgID8ge2dldFN0YWdnZXJpbmc6IHt2YWx1ZTogc3RhZ2dlcmluZ1ZhbHVlcywgc2l6ZTogMX19XG4gICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGdldExvY2F0aW9uc0luQmJveChcbiAgICB0cmVlOiBLREJ1c2hUcmVlLFxuICAgIGJib3g6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICApOiBBcnJheTxMPiB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0cmVlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiB0aGlzLl9nZXRMb2NhdGlvbnNJbkJib3hJbmRpY2VzKHRyZWUsIGJib3gpLm1hcChcbiAgICAgIChpZHg6IG51bWJlcikgPT4gdHJlZS5wb2ludHNbaWR4XSxcbiAgICApIGFzIEFycmF5PEw+O1xuICB9XG5cbiAgX2dldExvY2F0aW9uc0luQmJveEluZGljZXMoXG4gICAgdHJlZTogS0RCdXNoVHJlZSxcbiAgICBiYm94OiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSxcbiAgKSB7XG4gICAgaWYgKCF0cmVlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IFtsb24xLCBsYXQxLCBsb24yLCBsYXQyXSA9IGJib3g7XG4gICAgY29uc3QgW3gxLCB5MSwgeDIsIHkyXSA9IFtsbmdYKGxvbjEpLCBsYXRZKGxhdDEpLCBsbmdYKGxvbjIpLCBsYXRZKGxhdDIpXTtcbiAgICByZXR1cm4gdHJlZS5yYW5nZShcbiAgICAgIE1hdGgubWluKHgxLCB4MiksXG4gICAgICBNYXRoLm1pbih5MSwgeTIpLFxuICAgICAgTWF0aC5tYXgoeDEsIHgyKSxcbiAgICAgIE1hdGgubWF4KHkxLCB5MiksXG4gICAgKTtcbiAgfVxuXG4gIGlzRmxvd0luU2VsZWN0aW9uKFxuICAgIGZsb3c6IEYgfCBBZ2dyZWdhdGVGbG93LFxuICAgIHNlbGVjdGVkTG9jYXRpb25zU2V0OiBTZXQ8c3RyaW5nPiB8IHVuZGVmaW5lZCxcbiAgICBsb2NhdGlvbkZpbHRlck1vZGU/OiBMb2NhdGlvbkZpbHRlck1vZGUsXG4gICkge1xuICAgIGNvbnN0IG9yaWdpbiA9IHRoaXMuYWNjZXNzb3JzLmdldEZsb3dPcmlnaW5JZChmbG93KTtcbiAgICBjb25zdCBkZXN0ID0gdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd0Rlc3RJZChmbG93KTtcbiAgICBpZiAoc2VsZWN0ZWRMb2NhdGlvbnNTZXQpIHtcbiAgICAgIHN3aXRjaCAobG9jYXRpb25GaWx0ZXJNb2RlKSB7XG4gICAgICAgIGNhc2UgTG9jYXRpb25GaWx0ZXJNb2RlLkFMTDpcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgc2VsZWN0ZWRMb2NhdGlvbnNTZXQuaGFzKG9yaWdpbikgfHwgc2VsZWN0ZWRMb2NhdGlvbnNTZXQuaGFzKGRlc3QpXG4gICAgICAgICAgKTtcbiAgICAgICAgY2FzZSBMb2NhdGlvbkZpbHRlck1vZGUuQkVUV0VFTjpcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgc2VsZWN0ZWRMb2NhdGlvbnNTZXQuaGFzKG9yaWdpbikgJiYgc2VsZWN0ZWRMb2NhdGlvbnNTZXQuaGFzKGRlc3QpXG4gICAgICAgICAgKTtcbiAgICAgICAgY2FzZSBMb2NhdGlvbkZpbHRlck1vZGUuSU5DT01JTkc6XG4gICAgICAgICAgcmV0dXJuIHNlbGVjdGVkTG9jYXRpb25zU2V0LmhhcyhkZXN0KTtcbiAgICAgICAgY2FzZSBMb2NhdGlvbkZpbHRlck1vZGUuT1VUR09JTkc6XG4gICAgICAgICAgcmV0dXJuIHNlbGVjdGVkTG9jYXRpb25zU2V0LmhhcyhvcmlnaW4pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIGNhbGNMb2NhdGlvblRvdGFscyhcbiAgLy8gICBsb2NhdGlvbnM6IChMIHwgQ2x1c3Rlck5vZGUpW10sXG4gIC8vICAgZmxvd3M6IEZbXSxcbiAgLy8gKTogTG9jYXRpb25zVG90YWxzIHtcbiAgLy8gICByZXR1cm4gZmxvd3MucmVkdWNlKFxuICAvLyAgICAgKGFjYzogTG9jYXRpb25zVG90YWxzLCBjdXJyKSA9PiB7XG4gIC8vICAgICAgIGNvbnN0IG9yaWdpbklkID0gdGhpcy5hY2Nlc3NvcnMuZ2V0Rmxvd09yaWdpbklkKGN1cnIpO1xuICAvLyAgICAgICBjb25zdCBkZXN0SWQgPSB0aGlzLmFjY2Vzc29ycy5nZXRGbG93RGVzdElkKGN1cnIpO1xuICAvLyAgICAgICBjb25zdCBtYWduaXR1ZGUgPSB0aGlzLmFjY2Vzc29ycy5nZXRGbG93TWFnbml0dWRlKGN1cnIpO1xuICAvLyAgICAgICBpZiAob3JpZ2luSWQgPT09IGRlc3RJZCkge1xuICAvLyAgICAgICAgIGFjYy5pbnRlcm5hbFtvcmlnaW5JZF0gPSAoYWNjLmludGVybmFsW29yaWdpbklkXSB8fCAwKSArIG1hZ25pdHVkZTtcbiAgLy8gICAgICAgfSBlbHNlIHtcbiAgLy8gICAgICAgICBhY2Mub3V0Z29pbmdbb3JpZ2luSWRdID0gKGFjYy5vdXRnb2luZ1tvcmlnaW5JZF0gfHwgMCkgKyBtYWduaXR1ZGU7XG4gIC8vICAgICAgICAgYWNjLmluY29taW5nW2Rlc3RJZF0gPSAoYWNjLmluY29taW5nW2Rlc3RJZF0gfHwgMCkgKyBtYWduaXR1ZGU7XG4gIC8vICAgICAgIH1cbiAgLy8gICAgICAgcmV0dXJuIGFjYztcbiAgLy8gICAgIH0sXG4gIC8vICAgICB7aW5jb21pbmc6IHt9LCBvdXRnb2luZzoge30sIGludGVybmFsOiB7fX0sXG4gIC8vICAgKTtcbiAgLy8gfVxufVxuXG5mdW5jdGlvbiBjYWxjTG9jYXRpb25Ub3RhbHNFeHRlbnQoXG4gIGxvY2F0aW9uVG90YWxzOiBNYXA8c3RyaW5nLCBMb2NhdGlvblRvdGFscz4gfCB1bmRlZmluZWQsXG4gIGxvY2F0aW9uSWRzSW5WaWV3cG9ydDogU2V0PHN0cmluZz4gfCB1bmRlZmluZWQsXG4pIHtcbiAgaWYgKCFsb2NhdGlvblRvdGFscykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgbGV0IHJ2OiBbbnVtYmVyLCBudW1iZXJdIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICBmb3IgKGNvbnN0IFtcbiAgICBpZCxcbiAgICB7aW5jb21pbmdDb3VudCwgb3V0Z29pbmdDb3VudCwgaW50ZXJuYWxDb3VudH0sXG4gIF0gb2YgbG9jYXRpb25Ub3RhbHMuZW50cmllcygpKSB7XG4gICAgaWYgKGxvY2F0aW9uSWRzSW5WaWV3cG9ydCA9PSBudWxsIHx8IGxvY2F0aW9uSWRzSW5WaWV3cG9ydC5oYXMoaWQpKSB7XG4gICAgICBjb25zdCBsbyA9IE1hdGgubWluKFxuICAgICAgICBpbmNvbWluZ0NvdW50ICsgaW50ZXJuYWxDb3VudCxcbiAgICAgICAgb3V0Z29pbmdDb3VudCArIGludGVybmFsQ291bnQsXG4gICAgICAgIGludGVybmFsQ291bnQsXG4gICAgICApO1xuICAgICAgY29uc3QgaGkgPSBNYXRoLm1heChcbiAgICAgICAgaW5jb21pbmdDb3VudCArIGludGVybmFsQ291bnQsXG4gICAgICAgIG91dGdvaW5nQ291bnQgKyBpbnRlcm5hbENvdW50LFxuICAgICAgICBpbnRlcm5hbENvdW50LFxuICAgICAgKTtcbiAgICAgIGlmICghcnYpIHtcbiAgICAgICAgcnYgPSBbbG8sIGhpXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChsbyA8IHJ2WzBdKSBydlswXSA9IGxvO1xuICAgICAgICBpZiAoaGkgPiBydlsxXSkgcnZbMV0gPSBoaTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJ2O1xufVxuXG4vLyBsb25naXR1ZGUvbGF0aXR1ZGUgdG8gc3BoZXJpY2FsIG1lcmNhdG9yIGluIFswLi4xXSByYW5nZVxuZnVuY3Rpb24gbG5nWChsbmc6IG51bWJlcikge1xuICByZXR1cm4gbG5nIC8gMzYwICsgMC41O1xufVxuXG5mdW5jdGlvbiBsYXRZKGxhdDogbnVtYmVyKSB7XG4gIGNvbnN0IHNpbiA9IE1hdGguc2luKChsYXQgKiBNYXRoLlBJKSAvIDE4MCk7XG4gIGNvbnN0IHkgPSAwLjUgLSAoMC4yNSAqIE1hdGgubG9nKCgxICsgc2luKSAvICgxIC0gc2luKSkpIC8gTWF0aC5QSTtcbiAgcmV0dXJuIHkgPCAwID8gMCA6IHkgPiAxID8gMSA6IHk7XG59XG5cbmZ1bmN0aW9uIGFnZ3JlZ2F0ZUZsb3dzPEY+KFxuICBmbG93czogRltdLFxuICBmbG93QWNjZXNzb3JzOiBGbG93QWNjZXNzb3JzPEY+LFxuKTogQWdncmVnYXRlRmxvd1tdIHtcbiAgLy8gU3VtIHVwIGZsb3dzIHdpdGggc2FtZSBvcmlnaW4sIGRlc3RcbiAgY29uc3QgYnlPcmlnaW5EZXN0ID0gcm9sbHVwKFxuICAgIGZsb3dzLFxuICAgIChmZjogRltdKSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW4gPSBmbG93QWNjZXNzb3JzLmdldEZsb3dPcmlnaW5JZChmZlswXSk7XG4gICAgICBjb25zdCBkZXN0ID0gZmxvd0FjY2Vzc29ycy5nZXRGbG93RGVzdElkKGZmWzBdKTtcbiAgICAgIC8vIGNvbnN0IGNvbG9yID0gZmZbMF0uY29sb3I7XG4gICAgICBjb25zdCBydjogQWdncmVnYXRlRmxvdyA9IHtcbiAgICAgICAgYWdncmVnYXRlOiB0cnVlLFxuICAgICAgICBvcmlnaW4sXG4gICAgICAgIGRlc3QsXG4gICAgICAgIGNvdW50OiBmZi5yZWR1Y2UoKG0sIGYpID0+IHtcbiAgICAgICAgICBjb25zdCBjb3VudCA9IGZsb3dBY2Nlc3NvcnMuZ2V0Rmxvd01hZ25pdHVkZShmKTtcbiAgICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICAgIGlmICghaXNOYU4oY291bnQpICYmIGlzRmluaXRlKGNvdW50KSkgcmV0dXJuIG0gKyBjb3VudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH0sIDApLFxuICAgICAgICAvLyB0aW1lOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgICAgLy8gaWYgKGNvbG9yKSBydi5jb2xvciA9IGNvbG9yO1xuICAgICAgcmV0dXJuIHJ2O1xuICAgIH0sXG4gICAgZmxvd0FjY2Vzc29ycy5nZXRGbG93T3JpZ2luSWQsXG4gICAgZmxvd0FjY2Vzc29ycy5nZXRGbG93RGVzdElkLFxuICApO1xuXG4gIGNvbnN0IHJ2OiBBZ2dyZWdhdGVGbG93W10gPSBbXTtcbiAgZm9yIChjb25zdCB2YWx1ZXMgb2YgYnlPcmlnaW5EZXN0LnZhbHVlcygpKSB7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiB2YWx1ZXMudmFsdWVzKCkpIHtcbiAgICAgIHJ2LnB1c2godmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcnY7XG59XG5cbi8qKlxuICogVGhpcyBpcyB1c2VkIHRvIGF1Z21lbnQgaG92ZXIgcGlja2luZyBpbmZvIHNvIHRoYXQgd2UgY2FuIGRpc3BsYWNlIGxvY2F0aW9uIHRvb2x0aXBcbiAqIEBwYXJhbSBjaXJjbGVBdHRyaWJ1dGVzXG4gKiBAcGFyYW0gaW5kZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE91dGVyQ2lyY2xlUmFkaXVzQnlJbmRleChcbiAgY2lyY2xlQXR0cmlidXRlczogRmxvd0NpcmNsZXNMYXllckF0dHJpYnV0ZXMsXG4gIGluZGV4OiBudW1iZXIsXG4pOiBudW1iZXIge1xuICBjb25zdCB7Z2V0SW5SYWRpdXMsIGdldE91dFJhZGl1c30gPSBjaXJjbGVBdHRyaWJ1dGVzLmF0dHJpYnV0ZXM7XG4gIHJldHVybiBNYXRoLm1heChnZXRJblJhZGl1cy52YWx1ZVtpbmRleF0sIGdldE91dFJhZGl1cy52YWx1ZVtpbmRleF0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9jYXRpb25Db29yZHNCeUluZGV4KFxuICBjaXJjbGVBdHRyaWJ1dGVzOiBGbG93Q2lyY2xlc0xheWVyQXR0cmlidXRlcyxcbiAgaW5kZXg6IG51bWJlcixcbik6IFtudW1iZXIsIG51bWJlcl0ge1xuICBjb25zdCB7Z2V0UG9zaXRpb259ID0gY2lyY2xlQXR0cmlidXRlcy5hdHRyaWJ1dGVzO1xuICByZXR1cm4gW2dldFBvc2l0aW9uLnZhbHVlW2luZGV4ICogMl0sIGdldFBvc2l0aW9uLnZhbHVlW2luZGV4ICogMiArIDFdXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZsb3dMaW5lQXR0cmlidXRlc0J5SW5kZXgoXG4gIGxpbmVBdHRyaWJ1dGVzOiBGbG93TGluZXNMYXllckF0dHJpYnV0ZXMsXG4gIGluZGV4OiBudW1iZXIsXG4pOiBGbG93TGluZXNMYXllckF0dHJpYnV0ZXMge1xuICBjb25zdCB7XG4gICAgZ2V0Q29sb3IsXG4gICAgZ2V0RW5kcG9pbnRPZmZzZXRzLFxuICAgIGdldFNvdXJjZVBvc2l0aW9uLFxuICAgIGdldFRhcmdldFBvc2l0aW9uLFxuICAgIGdldFRoaWNrbmVzcyxcbiAgICBnZXRTdGFnZ2VyaW5nLFxuICB9ID0gbGluZUF0dHJpYnV0ZXMuYXR0cmlidXRlcztcbiAgcmV0dXJuIHtcbiAgICBsZW5ndGg6IDEsXG4gICAgYXR0cmlidXRlczoge1xuICAgICAgZ2V0Q29sb3I6IHtcbiAgICAgICAgdmFsdWU6IGdldENvbG9yLnZhbHVlLnN1YmFycmF5KGluZGV4ICogNCwgKGluZGV4ICsgMSkgKiA0KSxcbiAgICAgICAgc2l6ZTogNCxcbiAgICAgIH0sXG4gICAgICBnZXRFbmRwb2ludE9mZnNldHM6IHtcbiAgICAgICAgdmFsdWU6IGdldEVuZHBvaW50T2Zmc2V0cy52YWx1ZS5zdWJhcnJheShpbmRleCAqIDIsIChpbmRleCArIDEpICogMiksXG4gICAgICAgIHNpemU6IDIsXG4gICAgICB9LFxuICAgICAgZ2V0U291cmNlUG9zaXRpb246IHtcbiAgICAgICAgdmFsdWU6IGdldFNvdXJjZVBvc2l0aW9uLnZhbHVlLnN1YmFycmF5KGluZGV4ICogMiwgKGluZGV4ICsgMSkgKiAyKSxcbiAgICAgICAgc2l6ZTogMixcbiAgICAgIH0sXG4gICAgICBnZXRUYXJnZXRQb3NpdGlvbjoge1xuICAgICAgICB2YWx1ZTogZ2V0VGFyZ2V0UG9zaXRpb24udmFsdWUuc3ViYXJyYXkoaW5kZXggKiAyLCAoaW5kZXggKyAxKSAqIDIpLFxuICAgICAgICBzaXplOiAyLFxuICAgICAgfSxcbiAgICAgIGdldFRoaWNrbmVzczoge1xuICAgICAgICB2YWx1ZTogZ2V0VGhpY2tuZXNzLnZhbHVlLnN1YmFycmF5KGluZGV4LCBpbmRleCArIDEpLFxuICAgICAgICBzaXplOiAxLFxuICAgICAgfSxcbiAgICAgIC4uLihnZXRTdGFnZ2VyaW5nXG4gICAgICAgID8ge1xuICAgICAgICAgICAgZ2V0U3RhZ2dlcmluZzoge1xuICAgICAgICAgICAgICB2YWx1ZTogZ2V0U3RhZ2dlcmluZy52YWx1ZS5zdWJhcnJheShpbmRleCwgaW5kZXggKyAxKSxcbiAgICAgICAgICAgICAgc2l6ZTogMSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfVxuICAgICAgICA6IHVuZGVmaW5lZCksXG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==