@kepler.gl/utils 3.0.0 → 3.1.0-alpha.1
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.
- package/package.json +14 -10
- package/dist/aggregate-utils.d.ts +0 -3
- package/dist/aggregate-utils.js +0 -75
- package/dist/arrow-data-container.d.ts +0 -54
- package/dist/arrow-data-container.js +0 -360
- package/dist/color-utils.d.ts +0 -51
- package/dist/color-utils.js +0 -161
- package/dist/data-container-interface.d.ts +0 -133
- package/dist/data-container-interface.js +0 -6
- package/dist/data-container-utils.d.ts +0 -30
- package/dist/data-container-utils.js +0 -88
- package/dist/data-row.d.ts +0 -59
- package/dist/data-row.js +0 -126
- package/dist/data-scale-utils.d.ts +0 -23
- package/dist/data-scale-utils.js +0 -62
- package/dist/data-utils.d.ts +0 -103
- package/dist/data-utils.js +0 -502
- package/dist/dataset-utils.d.ts +0 -116
- package/dist/dataset-utils.js +0 -614
- package/dist/dom-to-image.d.ts +0 -73
- package/dist/dom-to-image.js +0 -489
- package/dist/dom-utils.d.ts +0 -23
- package/dist/dom-utils.js +0 -434
- package/dist/effect-utils.d.ts +0 -23
- package/dist/effect-utils.js +0 -196
- package/dist/export-map-html.d.ts +0 -9
- package/dist/export-map-html.js +0 -28
- package/dist/export-utils.d.ts +0 -53
- package/dist/export-utils.js +0 -262
- package/dist/filter-utils.d.ts +0 -326
- package/dist/filter-utils.js +0 -1333
- package/dist/format.d.ts +0 -1
- package/dist/format.js +0 -17
- package/dist/gl-utils.d.ts +0 -1
- package/dist/gl-utils.js +0 -35
- package/dist/h3-utils.d.ts +0 -21
- package/dist/h3-utils.js +0 -81
- package/dist/index.d.ts +0 -36
- package/dist/index.js +0 -772
- package/dist/indexed-data-container.d.ts +0 -34
- package/dist/indexed-data-container.js +0 -254
- package/dist/locale-utils.d.ts +0 -2
- package/dist/locale-utils.js +0 -54
- package/dist/map-info-utils.d.ts +0 -1
- package/dist/map-info-utils.js +0 -15
- package/dist/map-style-utils/mapbox-gl-style-editor.d.ts +0 -65
- package/dist/map-style-utils/mapbox-gl-style-editor.js +0 -218
- package/dist/map-style-utils/mapbox-utils.d.ts +0 -9
- package/dist/map-style-utils/mapbox-utils.js +0 -48
- package/dist/map-utils.d.ts +0 -9
- package/dist/map-utils.js +0 -65
- package/dist/mapbox-utils.d.ts +0 -7
- package/dist/mapbox-utils.js +0 -22
- package/dist/noop.d.ts +0 -1
- package/dist/noop.js +0 -11
- package/dist/notifications-utils.d.ts +0 -42
- package/dist/notifications-utils.js +0 -85
- package/dist/observe-dimensions.d.ts +0 -15
- package/dist/observe-dimensions.js +0 -151
- package/dist/plot.d.ts +0 -6
- package/dist/plot.js +0 -31
- package/dist/projection-utils.d.ts +0 -21
- package/dist/projection-utils.js +0 -100
- package/dist/row-data-container.d.ts +0 -31
- package/dist/row-data-container.js +0 -252
- package/dist/searcher-utils.d.ts +0 -1
- package/dist/searcher-utils.js +0 -28
- package/dist/split-map-utils.d.ts +0 -32
- package/dist/split-map-utils.js +0 -114
- package/dist/time.d.ts +0 -16
- package/dist/time.js +0 -89
- package/dist/utils.d.ts +0 -116
- package/dist/utils.js +0 -305
package/dist/filter-utils.js
DELETED
@@ -1,1333 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
4
|
-
|
5
|
-
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
6
|
-
|
7
|
-
Object.defineProperty(exports, "__esModule", {
|
8
|
-
value: true
|
9
|
-
});
|
10
|
-
exports.getDefaultFilter = getDefaultFilter;
|
11
|
-
exports.shouldApplyFilter = shouldApplyFilter;
|
12
|
-
exports.validatePolygonFilter = validatePolygonFilter;
|
13
|
-
exports.validateFilter = validateFilter;
|
14
|
-
exports.validateFilterWithData = validateFilterWithData;
|
15
|
-
exports.getFilterProps = getFilterProps;
|
16
|
-
exports.getFilterFunction = getFilterFunction;
|
17
|
-
exports.updateFilterDataId = updateFilterDataId;
|
18
|
-
exports.filterDataByFilterTypes = filterDataByFilterTypes;
|
19
|
-
exports.getFilterRecord = getFilterRecord;
|
20
|
-
exports.diffFilters = diffFilters;
|
21
|
-
exports.adjustValueToFilterDomain = adjustValueToFilterDomain;
|
22
|
-
exports.getNumericFieldDomain = getNumericFieldDomain;
|
23
|
-
exports.getNumericStepSize = getNumericStepSize;
|
24
|
-
exports.getTimestampFieldDomain = getTimestampFieldDomain;
|
25
|
-
exports.histogramConstruct = histogramConstruct;
|
26
|
-
exports.getHistogram = getHistogram;
|
27
|
-
exports.formatNumberByStep = formatNumberByStep;
|
28
|
-
exports.isInRange = isInRange;
|
29
|
-
exports.isInPolygon = isInPolygon;
|
30
|
-
exports.getTimeWidgetTitleFormatter = getTimeWidgetTitleFormatter;
|
31
|
-
exports.isFilterValidToSave = isFilterValidToSave;
|
32
|
-
exports.isValidFilterValue = isValidFilterValue;
|
33
|
-
exports.getColumnFilterProps = getColumnFilterProps;
|
34
|
-
exports.getDefaultFilterPlotType = getDefaultFilterPlotType;
|
35
|
-
exports.applyFiltersToDatasets = applyFiltersToDatasets;
|
36
|
-
exports.applyFilterFieldName = applyFilterFieldName;
|
37
|
-
exports.mergeFilterDomainStep = mergeFilterDomainStep;
|
38
|
-
exports.generatePolygonFilter = generatePolygonFilter;
|
39
|
-
exports.filterDatasetCPU = filterDatasetCPU;
|
40
|
-
exports.validateFiltersUpdateDatasets = validateFiltersUpdateDatasets;
|
41
|
-
exports.getFilterPlot = getFilterPlot;
|
42
|
-
exports.getIntervalBins = getIntervalBins;
|
43
|
-
exports.isValidTimeDomain = isValidTimeDomain;
|
44
|
-
exports.getTimeWidgetHintFormatter = getTimeWidgetHintFormatter;
|
45
|
-
exports.isSideFilter = isSideFilter;
|
46
|
-
exports.getFilterIdInFeature = exports.featureToFilterValue = exports.getPolygonFilterFunctor = exports.LAYER_FILTERS = exports.FILTER_ID_LENGTH = exports.DEFAULT_FILTER_STRUCTURE = exports.FILTER_COMPONENTS = exports.LIMITED_FILTER_EFFECT_PROPS = exports.FILTER_UPDATER_PROPS = exports.enlargedHistogramBins = exports.histogramBins = exports.TimestampStepMap = exports.durationYear = exports.durationWeek = exports.durationDay = exports.durationHour = exports.durationMinute = exports.durationSecond = void 0;
|
47
|
-
|
48
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
49
|
-
|
50
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
51
|
-
|
52
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
53
|
-
|
54
|
-
var _d3Array = require("d3-array");
|
55
|
-
|
56
|
-
var _keymirror = _interopRequireDefault(require("keymirror"));
|
57
|
-
|
58
|
-
var _console = _interopRequireDefault(require("global/console"));
|
59
|
-
|
60
|
-
var _lodash = _interopRequireDefault(require("lodash.get"));
|
61
|
-
|
62
|
-
var _lodash2 = _interopRequireDefault(require("lodash.isequal"));
|
63
|
-
|
64
|
-
var _booleanWithin = _interopRequireDefault(require("@turf/boolean-within"));
|
65
|
-
|
66
|
-
var _helpers = require("@turf/helpers");
|
67
|
-
|
68
|
-
var _decimal = require("decimal.js");
|
69
|
-
|
70
|
-
var _constants = require("@kepler.gl/constants");
|
71
|
-
|
72
|
-
var ScaleUtils = _interopRequireWildcard(require("./data-scale-utils"));
|
73
|
-
|
74
|
-
var _h3Js = require("h3-js");
|
75
|
-
|
76
|
-
var _utils = require("./utils");
|
77
|
-
|
78
|
-
var _dataUtils = require("./data-utils");
|
79
|
-
|
80
|
-
var _h3Utils = require("./h3-utils");
|
81
|
-
|
82
|
-
var _FILTER_TYPES$timeRan, _FILTER_TYPES$range, _SupportedPlotType, _FILTER_COMPONENTS;
|
83
|
-
|
84
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
85
|
-
|
86
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
87
|
-
|
88
|
-
var durationSecond = 1000;
|
89
|
-
exports.durationSecond = durationSecond;
|
90
|
-
var durationMinute = durationSecond * 60;
|
91
|
-
exports.durationMinute = durationMinute;
|
92
|
-
var durationHour = durationMinute * 60;
|
93
|
-
exports.durationHour = durationHour;
|
94
|
-
var durationDay = durationHour * 24;
|
95
|
-
exports.durationDay = durationDay;
|
96
|
-
var durationWeek = durationDay * 7;
|
97
|
-
exports.durationWeek = durationWeek;
|
98
|
-
var durationYear = durationDay * 365;
|
99
|
-
exports.durationYear = durationYear;
|
100
|
-
var TimestampStepMap = [{
|
101
|
-
max: 1,
|
102
|
-
step: 0.05
|
103
|
-
}, {
|
104
|
-
max: 10,
|
105
|
-
step: 0.1
|
106
|
-
}, {
|
107
|
-
max: 100,
|
108
|
-
step: 1
|
109
|
-
}, {
|
110
|
-
max: 500,
|
111
|
-
step: 5
|
112
|
-
}, {
|
113
|
-
max: 1000,
|
114
|
-
step: 10
|
115
|
-
}, {
|
116
|
-
max: 5000,
|
117
|
-
step: 50
|
118
|
-
}, {
|
119
|
-
max: Number.POSITIVE_INFINITY,
|
120
|
-
step: 1000
|
121
|
-
}];
|
122
|
-
exports.TimestampStepMap = TimestampStepMap;
|
123
|
-
var histogramBins = 30;
|
124
|
-
exports.histogramBins = histogramBins;
|
125
|
-
var enlargedHistogramBins = 100;
|
126
|
-
exports.enlargedHistogramBins = enlargedHistogramBins;
|
127
|
-
var FILTER_UPDATER_PROPS = (0, _keymirror["default"])({
|
128
|
-
dataId: null,
|
129
|
-
name: null,
|
130
|
-
layerId: null
|
131
|
-
});
|
132
|
-
exports.FILTER_UPDATER_PROPS = FILTER_UPDATER_PROPS;
|
133
|
-
var LIMITED_FILTER_EFFECT_PROPS = (0, _keymirror["default"])((0, _defineProperty2["default"])({}, FILTER_UPDATER_PROPS.name, null));
|
134
|
-
/**
|
135
|
-
* Max number of filter value buffers that deck.gl provides
|
136
|
-
*/
|
137
|
-
|
138
|
-
exports.LIMITED_FILTER_EFFECT_PROPS = LIMITED_FILTER_EFFECT_PROPS;
|
139
|
-
var SupportedPlotType = (_SupportedPlotType = {}, (0, _defineProperty2["default"])(_SupportedPlotType, _constants.FILTER_TYPES.timeRange, (_FILTER_TYPES$timeRan = {
|
140
|
-
"default": 'histogram'
|
141
|
-
}, (0, _defineProperty2["default"])(_FILTER_TYPES$timeRan, _constants.ALL_FIELD_TYPES.integer, 'lineChart'), (0, _defineProperty2["default"])(_FILTER_TYPES$timeRan, _constants.ALL_FIELD_TYPES.real, 'lineChart'), _FILTER_TYPES$timeRan)), (0, _defineProperty2["default"])(_SupportedPlotType, _constants.FILTER_TYPES.range, (_FILTER_TYPES$range = {
|
142
|
-
"default": 'histogram'
|
143
|
-
}, (0, _defineProperty2["default"])(_FILTER_TYPES$range, _constants.ALL_FIELD_TYPES.integer, 'lineChart'), (0, _defineProperty2["default"])(_FILTER_TYPES$range, _constants.ALL_FIELD_TYPES.real, 'lineChart'), _FILTER_TYPES$range)), _SupportedPlotType);
|
144
|
-
var FILTER_COMPONENTS = (_FILTER_COMPONENTS = {}, (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.select, 'SingleSelectFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.multiSelect, 'MultiSelectFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.timeRange, 'TimeRangeFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.range, 'RangeFilter'), (0, _defineProperty2["default"])(_FILTER_COMPONENTS, _constants.FILTER_TYPES.polygon, 'PolygonFilter'), _FILTER_COMPONENTS);
|
145
|
-
exports.FILTER_COMPONENTS = FILTER_COMPONENTS;
|
146
|
-
var DEFAULT_FILTER_STRUCTURE = {
|
147
|
-
dataId: [],
|
148
|
-
// [string]
|
149
|
-
freeze: false,
|
150
|
-
id: null,
|
151
|
-
enabled: true,
|
152
|
-
// time range filter specific
|
153
|
-
fixedDomain: false,
|
154
|
-
view: _constants.FILTER_VIEW_TYPES.side,
|
155
|
-
isAnimating: false,
|
156
|
-
animationWindow: _constants.ANIMATION_WINDOW.free,
|
157
|
-
speed: 1,
|
158
|
-
// field specific
|
159
|
-
name: [],
|
160
|
-
// string
|
161
|
-
type: null,
|
162
|
-
fieldIdx: [],
|
163
|
-
// [integer]
|
164
|
-
domain: null,
|
165
|
-
value: null,
|
166
|
-
// plot
|
167
|
-
plotType: _constants.PLOT_TYPES.histogram,
|
168
|
-
yAxis: null,
|
169
|
-
interval: null,
|
170
|
-
// mode
|
171
|
-
gpu: false
|
172
|
-
};
|
173
|
-
exports.DEFAULT_FILTER_STRUCTURE = DEFAULT_FILTER_STRUCTURE;
|
174
|
-
var FILTER_ID_LENGTH = 4;
|
175
|
-
exports.FILTER_ID_LENGTH = FILTER_ID_LENGTH;
|
176
|
-
var LAYER_FILTERS = [_constants.FILTER_TYPES.polygon];
|
177
|
-
/**
|
178
|
-
* Generates a filter with a dataset id as dataId
|
179
|
-
*/
|
180
|
-
|
181
|
-
exports.LAYER_FILTERS = LAYER_FILTERS;
|
182
|
-
|
183
|
-
function getDefaultFilter() {
|
184
|
-
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
185
|
-
dataId = _ref.dataId,
|
186
|
-
id = _ref.id;
|
187
|
-
|
188
|
-
return _objectSpread(_objectSpread({}, DEFAULT_FILTER_STRUCTURE), {}, {
|
189
|
-
// store it as dataId and it could be one or many
|
190
|
-
dataId: dataId ? (0, _utils.toArray)(dataId) : [],
|
191
|
-
id: id || (0, _utils.generateHashId)(FILTER_ID_LENGTH)
|
192
|
-
});
|
193
|
-
}
|
194
|
-
/**
|
195
|
-
* Check if a filter is valid based on the given dataId
|
196
|
-
* @param filter to validate
|
197
|
-
* @param datasetId id to validate filter against
|
198
|
-
* @return true if a filter is valid, false otherwise
|
199
|
-
*/
|
200
|
-
|
201
|
-
|
202
|
-
function shouldApplyFilter(filter, datasetId) {
|
203
|
-
var dataIds = (0, _utils.toArray)(filter.dataId);
|
204
|
-
return dataIds.includes(datasetId) && filter.value !== null;
|
205
|
-
}
|
206
|
-
|
207
|
-
/**
|
208
|
-
* Validates and modifies polygon filter structure
|
209
|
-
* @param dataset
|
210
|
-
* @param filter
|
211
|
-
* @param layers
|
212
|
-
* @return - {filter, dataset}
|
213
|
-
*/
|
214
|
-
function validatePolygonFilter(dataset, filter, layers) {
|
215
|
-
var failed = {
|
216
|
-
dataset: dataset,
|
217
|
-
filter: null
|
218
|
-
};
|
219
|
-
var value = filter.value,
|
220
|
-
layerId = filter.layerId,
|
221
|
-
type = filter.type,
|
222
|
-
dataId = filter.dataId;
|
223
|
-
|
224
|
-
if (!layerId || !isValidFilterValue(type, value)) {
|
225
|
-
return failed;
|
226
|
-
}
|
227
|
-
|
228
|
-
var isValidDataset = dataId.includes(dataset.id);
|
229
|
-
|
230
|
-
if (!isValidDataset) {
|
231
|
-
return failed;
|
232
|
-
}
|
233
|
-
|
234
|
-
var layer = layers.find(function (l) {
|
235
|
-
return layerId.includes(l.id);
|
236
|
-
});
|
237
|
-
|
238
|
-
if (!layer) {
|
239
|
-
return failed;
|
240
|
-
}
|
241
|
-
|
242
|
-
return {
|
243
|
-
filter: _objectSpread(_objectSpread({}, filter), {}, {
|
244
|
-
freeze: true,
|
245
|
-
fieldIdx: []
|
246
|
-
}),
|
247
|
-
dataset: dataset
|
248
|
-
};
|
249
|
-
}
|
250
|
-
/**
|
251
|
-
* Custom filter validators
|
252
|
-
*/
|
253
|
-
|
254
|
-
|
255
|
-
var filterValidators = (0, _defineProperty2["default"])({}, _constants.FILTER_TYPES.polygon, validatePolygonFilter);
|
256
|
-
/**
|
257
|
-
* Default validate filter function
|
258
|
-
* @param dataset
|
259
|
-
* @param filter
|
260
|
-
* @return - {filter, dataset}
|
261
|
-
*/
|
262
|
-
|
263
|
-
function validateFilter(dataset, filter) {
|
264
|
-
var _filter$view;
|
265
|
-
|
266
|
-
// match filter.dataId
|
267
|
-
var failed = {
|
268
|
-
dataset: dataset,
|
269
|
-
filter: null
|
270
|
-
};
|
271
|
-
var filterDataId = (0, _utils.toArray)(filter.dataId);
|
272
|
-
var filterDatasetIndex = filterDataId.indexOf(dataset.id);
|
273
|
-
|
274
|
-
if (filterDatasetIndex < 0 || !(0, _utils.toArray)(filter.name)[filterDatasetIndex]) {
|
275
|
-
// the current filter is not mapped against the current dataset
|
276
|
-
return failed;
|
277
|
-
}
|
278
|
-
|
279
|
-
var initializeFilter = _objectSpread(_objectSpread(_objectSpread({}, getDefaultFilter({
|
280
|
-
dataId: filter.dataId
|
281
|
-
})), filter), {}, {
|
282
|
-
dataId: filterDataId,
|
283
|
-
name: (0, _utils.toArray)(filter.name)
|
284
|
-
});
|
285
|
-
|
286
|
-
var fieldName = initializeFilter.name[filterDatasetIndex];
|
287
|
-
|
288
|
-
var _applyFilterFieldName = applyFilterFieldName(initializeFilter, dataset, fieldName, filterDatasetIndex, {
|
289
|
-
mergeDomain: true
|
290
|
-
}),
|
291
|
-
updatedFilter = _applyFilterFieldName.filter,
|
292
|
-
updatedDataset = _applyFilterFieldName.dataset;
|
293
|
-
|
294
|
-
if (!updatedFilter) {
|
295
|
-
return failed;
|
296
|
-
}
|
297
|
-
|
298
|
-
updatedFilter.value = adjustValueToFilterDomain(filter.value, updatedFilter);
|
299
|
-
updatedFilter.view = (_filter$view = filter.view) !== null && _filter$view !== void 0 ? _filter$view : updatedFilter.view;
|
300
|
-
|
301
|
-
if (updatedFilter.value === null) {
|
302
|
-
// cannot adjust saved value to filter
|
303
|
-
return failed;
|
304
|
-
}
|
305
|
-
|
306
|
-
return {
|
307
|
-
filter: validateFilterYAxis(updatedFilter, updatedDataset),
|
308
|
-
dataset: updatedDataset
|
309
|
-
};
|
310
|
-
}
|
311
|
-
/**
|
312
|
-
* Validate saved filter config with new data,
|
313
|
-
* calculate domain and fieldIdx based new fields and data
|
314
|
-
*
|
315
|
-
* @param dataset
|
316
|
-
* @param filter - filter to be validate
|
317
|
-
* @param layers - layers
|
318
|
-
* @return validated filter
|
319
|
-
*/
|
320
|
-
|
321
|
-
|
322
|
-
function validateFilterWithData(dataset, filter, layers) {
|
323
|
-
return filter.type && filterValidators.hasOwnProperty(filter.type) ? filterValidators[filter.type](dataset, filter, layers) : validateFilter(dataset, filter);
|
324
|
-
}
|
325
|
-
/**
|
326
|
-
* Validate YAxis
|
327
|
-
* @param filter
|
328
|
-
* @param dataset
|
329
|
-
* @return {*}
|
330
|
-
*/
|
331
|
-
|
332
|
-
|
333
|
-
function validateFilterYAxis(filter, dataset) {
|
334
|
-
// TODO: validate yAxis against other datasets
|
335
|
-
var fields = dataset.fields;
|
336
|
-
var _filter = filter,
|
337
|
-
yAxis = _filter.yAxis; // TODO: validate yAxis against other datasets
|
338
|
-
|
339
|
-
if (yAxis) {
|
340
|
-
var matchedAxis = fields.find(function (_ref2) {
|
341
|
-
var name = _ref2.name,
|
342
|
-
type = _ref2.type;
|
343
|
-
return name === yAxis.name && type === yAxis.type;
|
344
|
-
});
|
345
|
-
filter = matchedAxis ? _objectSpread(_objectSpread({}, filter), {}, {
|
346
|
-
yAxis: matchedAxis
|
347
|
-
}, getFilterPlot(_objectSpread(_objectSpread({}, filter), {}, {
|
348
|
-
yAxis: matchedAxis
|
349
|
-
}), dataset)) : filter;
|
350
|
-
}
|
351
|
-
|
352
|
-
return filter;
|
353
|
-
}
|
354
|
-
/**
|
355
|
-
* Get default filter prop based on field type
|
356
|
-
*
|
357
|
-
* @param field
|
358
|
-
* @param fieldDomain
|
359
|
-
* @returns default filter
|
360
|
-
*/
|
361
|
-
|
362
|
-
|
363
|
-
function getFilterProps(field, fieldDomain) {
|
364
|
-
var filterProps = _objectSpread(_objectSpread({}, fieldDomain), {}, {
|
365
|
-
fieldType: field.type,
|
366
|
-
view: _constants.FILTER_VIEW_TYPES.side
|
367
|
-
});
|
368
|
-
|
369
|
-
switch (field.type) {
|
370
|
-
case _constants.ALL_FIELD_TYPES.real:
|
371
|
-
case _constants.ALL_FIELD_TYPES.integer:
|
372
|
-
return _objectSpread(_objectSpread({}, filterProps), {}, {
|
373
|
-
value: fieldDomain.domain,
|
374
|
-
type: _constants.FILTER_TYPES.range,
|
375
|
-
// @ts-expect-error
|
376
|
-
typeOptions: [_constants.FILTER_TYPES.range],
|
377
|
-
gpu: true
|
378
|
-
});
|
379
|
-
|
380
|
-
case _constants.ALL_FIELD_TYPES["boolean"]:
|
381
|
-
// @ts-expect-error
|
382
|
-
return _objectSpread(_objectSpread({}, filterProps), {}, {
|
383
|
-
type: _constants.FILTER_TYPES.select,
|
384
|
-
value: true,
|
385
|
-
gpu: false
|
386
|
-
});
|
387
|
-
|
388
|
-
case _constants.ALL_FIELD_TYPES.string:
|
389
|
-
case _constants.ALL_FIELD_TYPES.date:
|
390
|
-
// @ts-expect-error
|
391
|
-
return _objectSpread(_objectSpread({}, filterProps), {}, {
|
392
|
-
type: _constants.FILTER_TYPES.multiSelect,
|
393
|
-
value: [],
|
394
|
-
gpu: false
|
395
|
-
});
|
396
|
-
|
397
|
-
case _constants.ALL_FIELD_TYPES.timestamp:
|
398
|
-
// @ts-expect-error
|
399
|
-
return _objectSpread(_objectSpread({}, filterProps), {}, {
|
400
|
-
type: _constants.FILTER_TYPES.timeRange,
|
401
|
-
view: _constants.FILTER_VIEW_TYPES.enlarged,
|
402
|
-
fixedDomain: true,
|
403
|
-
value: filterProps.domain,
|
404
|
-
gpu: true
|
405
|
-
});
|
406
|
-
|
407
|
-
default:
|
408
|
-
// @ts-expect-error
|
409
|
-
return {};
|
410
|
-
}
|
411
|
-
}
|
412
|
-
|
413
|
-
var getPolygonFilterFunctor = function getPolygonFilterFunctor(layer, filter, dataContainer) {
|
414
|
-
var getPosition = layer.getPositionAccessor(dataContainer);
|
415
|
-
|
416
|
-
switch (layer.type) {
|
417
|
-
case _constants.LAYER_TYPES.point:
|
418
|
-
case _constants.LAYER_TYPES.icon:
|
419
|
-
return function (data) {
|
420
|
-
var pos = getPosition(data);
|
421
|
-
return pos.every(Number.isFinite) && isInPolygon(pos, filter.value);
|
422
|
-
};
|
423
|
-
|
424
|
-
case _constants.LAYER_TYPES.arc:
|
425
|
-
case _constants.LAYER_TYPES.line:
|
426
|
-
return function (data) {
|
427
|
-
var pos = getPosition(data);
|
428
|
-
return pos.every(Number.isFinite) && [[pos[0], pos[1]], [pos[3], pos[4]]].every(function (point) {
|
429
|
-
return isInPolygon(point, filter.value);
|
430
|
-
});
|
431
|
-
};
|
432
|
-
|
433
|
-
case _constants.LAYER_TYPES.hexagonId:
|
434
|
-
if (layer.dataToFeature && layer.dataToFeature.centroids) {
|
435
|
-
return function (data) {
|
436
|
-
// null or getCentroid({id})
|
437
|
-
var centroid = layer.dataToFeature.centroids[data.index];
|
438
|
-
return centroid && isInPolygon(centroid, filter.value);
|
439
|
-
};
|
440
|
-
}
|
441
|
-
|
442
|
-
return function (data) {
|
443
|
-
var id = getPosition(data);
|
444
|
-
|
445
|
-
if (!(0, _h3Js.h3IsValid)(id)) {
|
446
|
-
return false;
|
447
|
-
}
|
448
|
-
|
449
|
-
var pos = (0, _h3Utils.getCentroid)({
|
450
|
-
id: id
|
451
|
-
});
|
452
|
-
return pos.every(Number.isFinite) && isInPolygon(pos, filter.value);
|
453
|
-
};
|
454
|
-
|
455
|
-
case _constants.LAYER_TYPES.geojson:
|
456
|
-
return function (data) {
|
457
|
-
return layer.isInPolygon(data, data.index, filter.value);
|
458
|
-
};
|
459
|
-
|
460
|
-
default:
|
461
|
-
return function () {
|
462
|
-
return true;
|
463
|
-
};
|
464
|
-
}
|
465
|
-
};
|
466
|
-
/**
|
467
|
-
* @param param An object that represents a row record.
|
468
|
-
* @param param.index Index of the row in data container.
|
469
|
-
* @returns Returns true to keep the element, or false otherwise.
|
470
|
-
*/
|
471
|
-
|
472
|
-
|
473
|
-
exports.getPolygonFilterFunctor = getPolygonFilterFunctor;
|
474
|
-
|
475
|
-
/**
|
476
|
-
* @param field dataset Field
|
477
|
-
* @param dataId Dataset id
|
478
|
-
* @param filter Filter object
|
479
|
-
* @param layers list of layers to filter upon
|
480
|
-
* @param dataContainer Data container
|
481
|
-
* @return filterFunction
|
482
|
-
*/
|
483
|
-
|
484
|
-
/* eslint-disable complexity */
|
485
|
-
function getFilterFunction(field, dataId, filter, layers, dataContainer) {
|
486
|
-
// field could be null in polygon filter
|
487
|
-
var valueAccessor = field ? field.valueAccessor : function (data) {
|
488
|
-
return null;
|
489
|
-
};
|
490
|
-
|
491
|
-
var defaultFunc = function defaultFunc(d) {
|
492
|
-
return true;
|
493
|
-
};
|
494
|
-
|
495
|
-
if (filter.enabled === false) {
|
496
|
-
return defaultFunc;
|
497
|
-
}
|
498
|
-
|
499
|
-
switch (filter.type) {
|
500
|
-
case _constants.FILTER_TYPES.range:
|
501
|
-
return function (data) {
|
502
|
-
return isInRange(valueAccessor(data), filter.value);
|
503
|
-
};
|
504
|
-
|
505
|
-
case _constants.FILTER_TYPES.multiSelect:
|
506
|
-
return function (data) {
|
507
|
-
return filter.value.includes(valueAccessor(data));
|
508
|
-
};
|
509
|
-
|
510
|
-
case _constants.FILTER_TYPES.select:
|
511
|
-
return function (data) {
|
512
|
-
return valueAccessor(data) === filter.value;
|
513
|
-
};
|
514
|
-
|
515
|
-
case _constants.FILTER_TYPES.timeRange:
|
516
|
-
if (!field) {
|
517
|
-
return defaultFunc;
|
518
|
-
}
|
519
|
-
|
520
|
-
var mappedValue = (0, _lodash["default"])(field, ['filterProps', 'mappedValue']);
|
521
|
-
var accessor = Array.isArray(mappedValue) ? function (data) {
|
522
|
-
return mappedValue[data.index];
|
523
|
-
} : function (data) {
|
524
|
-
return (0, _dataUtils.timeToUnixMilli)(valueAccessor(data), field.format);
|
525
|
-
};
|
526
|
-
return function (data) {
|
527
|
-
return isInRange(accessor(data), filter.value);
|
528
|
-
};
|
529
|
-
|
530
|
-
case _constants.FILTER_TYPES.polygon:
|
531
|
-
if (!layers || !layers.length || !filter.layerId) {
|
532
|
-
return defaultFunc;
|
533
|
-
}
|
534
|
-
|
535
|
-
var layerFilterFunctions = filter.layerId.map(function (id) {
|
536
|
-
return layers.find(function (l) {
|
537
|
-
return l.id === id;
|
538
|
-
});
|
539
|
-
}).filter(function (l) {
|
540
|
-
return l && l.config.dataId === dataId;
|
541
|
-
}).map(function (layer) {
|
542
|
-
return getPolygonFilterFunctor(layer, filter, dataContainer);
|
543
|
-
});
|
544
|
-
return function (data) {
|
545
|
-
return layerFilterFunctions.every(function (filterFunc) {
|
546
|
-
return filterFunc(data);
|
547
|
-
});
|
548
|
-
};
|
549
|
-
|
550
|
-
default:
|
551
|
-
return defaultFunc;
|
552
|
-
}
|
553
|
-
}
|
554
|
-
|
555
|
-
function updateFilterDataId(dataId) {
|
556
|
-
return getDefaultFilter({
|
557
|
-
dataId: dataId
|
558
|
-
});
|
559
|
-
}
|
560
|
-
|
561
|
-
function filterDataByFilterTypes(_ref3, dataContainer) {
|
562
|
-
var dynamicDomainFilters = _ref3.dynamicDomainFilters,
|
563
|
-
cpuFilters = _ref3.cpuFilters,
|
564
|
-
filterFuncs = _ref3.filterFuncs;
|
565
|
-
var filteredIndexForDomain = [];
|
566
|
-
var filteredIndex = [];
|
567
|
-
var filterContext = {
|
568
|
-
index: -1,
|
569
|
-
dataContainer: dataContainer
|
570
|
-
};
|
571
|
-
|
572
|
-
var filterFuncCaller = function filterFuncCaller(filter) {
|
573
|
-
return filterFuncs[filter.id](filterContext);
|
574
|
-
};
|
575
|
-
|
576
|
-
var numRows = dataContainer.numRows();
|
577
|
-
|
578
|
-
for (var i = 0; i < numRows; ++i) {
|
579
|
-
filterContext.index = i;
|
580
|
-
var matchForDomain = dynamicDomainFilters && dynamicDomainFilters.every(filterFuncCaller);
|
581
|
-
|
582
|
-
if (matchForDomain) {
|
583
|
-
filteredIndexForDomain.push(filterContext.index);
|
584
|
-
}
|
585
|
-
|
586
|
-
var matchForRender = cpuFilters && cpuFilters.every(filterFuncCaller);
|
587
|
-
|
588
|
-
if (matchForRender) {
|
589
|
-
filteredIndex.push(filterContext.index);
|
590
|
-
}
|
591
|
-
}
|
592
|
-
|
593
|
-
return _objectSpread(_objectSpread({}, dynamicDomainFilters ? {
|
594
|
-
filteredIndexForDomain: filteredIndexForDomain
|
595
|
-
} : {}), cpuFilters ? {
|
596
|
-
filteredIndex: filteredIndex
|
597
|
-
} : {});
|
598
|
-
}
|
599
|
-
/**
|
600
|
-
* Get a record of filters based on domain type and gpu / cpu
|
601
|
-
*/
|
602
|
-
|
603
|
-
|
604
|
-
function getFilterRecord(dataId, filters) {
|
605
|
-
var opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
606
|
-
var filterRecord = {
|
607
|
-
dynamicDomain: [],
|
608
|
-
fixedDomain: [],
|
609
|
-
cpu: [],
|
610
|
-
gpu: []
|
611
|
-
};
|
612
|
-
filters.forEach(function (f) {
|
613
|
-
if (isValidFilterValue(f.type, f.value) && (0, _utils.toArray)(f.dataId).includes(dataId)) {
|
614
|
-
(f.fixedDomain || opt.ignoreDomain ? filterRecord.fixedDomain : filterRecord.dynamicDomain).push(f);
|
615
|
-
(f.gpu && !opt.cpuOnly ? filterRecord.gpu : filterRecord.cpu).push(f);
|
616
|
-
}
|
617
|
-
});
|
618
|
-
return filterRecord;
|
619
|
-
}
|
620
|
-
/**
|
621
|
-
* Compare filter records to get what has changed
|
622
|
-
*/
|
623
|
-
|
624
|
-
|
625
|
-
function diffFilters(filterRecord) {
|
626
|
-
var oldFilterRecord = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
627
|
-
var filterChanged = {};
|
628
|
-
Object.entries(filterRecord).forEach(function (_ref4) {
|
629
|
-
var _ref5 = (0, _slicedToArray2["default"])(_ref4, 2),
|
630
|
-
record = _ref5[0],
|
631
|
-
items = _ref5[1];
|
632
|
-
|
633
|
-
items.forEach(function (filter) {
|
634
|
-
var oldFilter = (oldFilterRecord[record] || []).find(function (f) {
|
635
|
-
return f.id === filter.id;
|
636
|
-
});
|
637
|
-
|
638
|
-
if (!oldFilter) {
|
639
|
-
// added
|
640
|
-
filterChanged = (0, _utils.set)([record, filter.id], 'added', filterChanged);
|
641
|
-
} else {
|
642
|
-
// check what has changed
|
643
|
-
['name', 'value', 'dataId'].forEach(function (prop) {
|
644
|
-
if (filter[prop] !== oldFilter[prop]) {
|
645
|
-
filterChanged = (0, _utils.set)([record, filter.id], "".concat(prop, "_changed"), filterChanged);
|
646
|
-
}
|
647
|
-
});
|
648
|
-
}
|
649
|
-
});
|
650
|
-
(oldFilterRecord[record] || []).forEach(function (oldFilter) {
|
651
|
-
// deleted
|
652
|
-
if (!items.find(function (f) {
|
653
|
-
return f.id === oldFilter.id;
|
654
|
-
})) {
|
655
|
-
filterChanged = (0, _utils.set)([record, oldFilter.id], 'deleted', filterChanged);
|
656
|
-
}
|
657
|
-
});
|
658
|
-
});
|
659
|
-
return _objectSpread(_objectSpread({}, {
|
660
|
-
dynamicDomain: null,
|
661
|
-
fixedDomain: null,
|
662
|
-
cpu: null,
|
663
|
-
gpu: null
|
664
|
-
}), filterChanged);
|
665
|
-
}
|
666
|
-
/**
|
667
|
-
* Call by parsing filters from URL
|
668
|
-
* Check if value of filter within filter domain, if not adjust it to match
|
669
|
-
* filter domain
|
670
|
-
*
|
671
|
-
* @returns value - adjusted value to match filter or null to remove filter
|
672
|
-
*/
|
673
|
-
// eslint-disable-next-line complexity
|
674
|
-
|
675
|
-
|
676
|
-
function adjustValueToFilterDomain(value, _ref6) {
|
677
|
-
var domain = _ref6.domain,
|
678
|
-
type = _ref6.type;
|
679
|
-
|
680
|
-
if (!type) {
|
681
|
-
return false;
|
682
|
-
} // if the current filter is a polygon it will not have any domain
|
683
|
-
// all other filter types require domain
|
684
|
-
|
685
|
-
|
686
|
-
if (type !== _constants.FILTER_TYPES.polygon && !domain) {
|
687
|
-
return false;
|
688
|
-
}
|
689
|
-
|
690
|
-
switch (type) {
|
691
|
-
case _constants.FILTER_TYPES.range:
|
692
|
-
case _constants.FILTER_TYPES.timeRange:
|
693
|
-
if (!Array.isArray(value) || value.length !== 2) {
|
694
|
-
return domain.map(function (d) {
|
695
|
-
return d;
|
696
|
-
});
|
697
|
-
}
|
698
|
-
|
699
|
-
return value.map(function (d, i) {
|
700
|
-
return (0, _dataUtils.notNullorUndefined)(d) && isInRange(d, domain) ? d : domain[i];
|
701
|
-
});
|
702
|
-
|
703
|
-
case _constants.FILTER_TYPES.multiSelect:
|
704
|
-
if (!Array.isArray(value)) {
|
705
|
-
return [];
|
706
|
-
}
|
707
|
-
|
708
|
-
var filteredValue = value.filter(function (d) {
|
709
|
-
return domain.includes(d);
|
710
|
-
});
|
711
|
-
return filteredValue.length ? filteredValue : [];
|
712
|
-
|
713
|
-
case _constants.FILTER_TYPES.select:
|
714
|
-
return domain.includes(value) ? value : true;
|
715
|
-
|
716
|
-
case _constants.FILTER_TYPES.polygon:
|
717
|
-
return value;
|
718
|
-
|
719
|
-
default:
|
720
|
-
return null;
|
721
|
-
}
|
722
|
-
}
|
723
|
-
/* eslint-enable complexity */
|
724
|
-
|
725
|
-
/**
|
726
|
-
* Calculate numeric domain and suitable step
|
727
|
-
*/
|
728
|
-
|
729
|
-
|
730
|
-
function getNumericFieldDomain(dataContainer, valueAccessor) {
|
731
|
-
var domain = [0, 1];
|
732
|
-
var step = 0.1;
|
733
|
-
var mappedValue = dataContainer.mapIndex(valueAccessor);
|
734
|
-
|
735
|
-
if (dataContainer.numRows() > 1) {
|
736
|
-
domain = ScaleUtils.getLinearDomain(mappedValue);
|
737
|
-
var diff = domain[1] - domain[0]; // in case equal domain, [96, 96], which will break quantize scale
|
738
|
-
|
739
|
-
if (!diff) {
|
740
|
-
domain[1] = domain[0] + 1;
|
741
|
-
}
|
742
|
-
|
743
|
-
step = getNumericStepSize(diff) || step;
|
744
|
-
domain[0] = formatNumberByStep(domain[0], step, 'floor');
|
745
|
-
domain[1] = formatNumberByStep(domain[1], step, 'ceil');
|
746
|
-
}
|
747
|
-
|
748
|
-
var _getHistogram = getHistogram(domain, mappedValue),
|
749
|
-
histogram = _getHistogram.histogram,
|
750
|
-
enlargedHistogram = _getHistogram.enlargedHistogram;
|
751
|
-
|
752
|
-
return {
|
753
|
-
domain: domain,
|
754
|
-
step: step,
|
755
|
-
histogram: histogram,
|
756
|
-
enlargedHistogram: enlargedHistogram
|
757
|
-
};
|
758
|
-
}
|
759
|
-
/**
|
760
|
-
* Calculate step size for range and timerange filter
|
761
|
-
*/
|
762
|
-
|
763
|
-
|
764
|
-
function getNumericStepSize(diff) {
|
765
|
-
diff = Math.abs(diff);
|
766
|
-
|
767
|
-
if (diff > 100) {
|
768
|
-
return 1;
|
769
|
-
} else if (diff > 3) {
|
770
|
-
return 0.01;
|
771
|
-
} else if (diff > 1) {
|
772
|
-
return 0.001;
|
773
|
-
} // Try to get at least 1000 steps - and keep the step size below that of
|
774
|
-
// the (diff > 1) case.
|
775
|
-
|
776
|
-
|
777
|
-
var x = diff / 1000; // Find the exponent and truncate to 10 to the power of that exponent
|
778
|
-
|
779
|
-
var exponentialForm = x.toExponential();
|
780
|
-
var exponent = parseFloat(exponentialForm.split('e')[1]); // Getting ready for node 12
|
781
|
-
// this is why we need decimal.js
|
782
|
-
// Math.pow(10, -5) = 0.000009999999999999999
|
783
|
-
// the above result shows in browser and node 10
|
784
|
-
// node 12 behaves correctly
|
785
|
-
|
786
|
-
return new _decimal.Decimal(10).pow(exponent).toNumber();
|
787
|
-
}
|
788
|
-
/**
|
789
|
-
* Calculate timestamp domain and suitable step
|
790
|
-
*/
|
791
|
-
|
792
|
-
|
793
|
-
function getTimestampFieldDomain(dataContainer, valueAccessor) {
|
794
|
-
// to avoid converting string format time to epoch
|
795
|
-
// every time we compare we store a value mapped to int in filter domain
|
796
|
-
var mappedValue = dataContainer.mapIndex(valueAccessor);
|
797
|
-
var domain = ScaleUtils.getLinearDomain(mappedValue);
|
798
|
-
var defaultTimeFormat = getTimeWidgetTitleFormatter(domain);
|
799
|
-
var step = 0.01;
|
800
|
-
var diff = domain[1] - domain[0]; // in case equal timestamp add 1 second padding to prevent break
|
801
|
-
|
802
|
-
if (!diff) {
|
803
|
-
domain[1] = domain[0] + 1000;
|
804
|
-
}
|
805
|
-
|
806
|
-
var entry = TimestampStepMap.find(function (f) {
|
807
|
-
return f.max >= diff;
|
808
|
-
});
|
809
|
-
|
810
|
-
if (entry) {
|
811
|
-
step = entry.step;
|
812
|
-
}
|
813
|
-
|
814
|
-
var _getHistogram2 = getHistogram(domain, mappedValue),
|
815
|
-
histogram = _getHistogram2.histogram,
|
816
|
-
enlargedHistogram = _getHistogram2.enlargedHistogram;
|
817
|
-
|
818
|
-
return {
|
819
|
-
domain: domain,
|
820
|
-
step: step,
|
821
|
-
mappedValue: mappedValue,
|
822
|
-
histogram: histogram,
|
823
|
-
enlargedHistogram: enlargedHistogram,
|
824
|
-
defaultTimeFormat: defaultTimeFormat
|
825
|
-
};
|
826
|
-
}
|
827
|
-
|
828
|
-
function histogramConstruct(domain, mappedValue, bins) {
|
829
|
-
return (0, _d3Array.histogram)().thresholds((0, _d3Array.ticks)(domain[0], domain[1], bins)).domain(domain)(mappedValue).map(function (bin) {
|
830
|
-
return {
|
831
|
-
count: bin.length,
|
832
|
-
bin: bin,
|
833
|
-
x0: bin.x0,
|
834
|
-
x1: bin.x1
|
835
|
-
};
|
836
|
-
});
|
837
|
-
}
|
838
|
-
/**
|
839
|
-
* Calculate histogram from domain and array of values
|
840
|
-
*/
|
841
|
-
|
842
|
-
|
843
|
-
function getHistogram(domain, mappedValue) {
|
844
|
-
var histogram = histogramConstruct(domain, mappedValue, histogramBins);
|
845
|
-
var enlargedHistogram = histogramConstruct(domain, mappedValue, enlargedHistogramBins);
|
846
|
-
return {
|
847
|
-
histogram: histogram,
|
848
|
-
enlargedHistogram: enlargedHistogram
|
849
|
-
};
|
850
|
-
}
|
851
|
-
/**
|
852
|
-
* round number based on step
|
853
|
-
*
|
854
|
-
* @param {Number} val
|
855
|
-
* @param {Number} step
|
856
|
-
* @param {string} bound
|
857
|
-
* @returns {Number} rounded number
|
858
|
-
*/
|
859
|
-
|
860
|
-
|
861
|
-
function formatNumberByStep(val, step, bound) {
|
862
|
-
if (bound === 'floor') {
|
863
|
-
return Math.floor(val * (1 / step)) / (1 / step);
|
864
|
-
}
|
865
|
-
|
866
|
-
return Math.ceil(val * (1 / step)) / (1 / step);
|
867
|
-
}
|
868
|
-
|
869
|
-
function isInRange(val, domain) {
|
870
|
-
if (!Array.isArray(domain)) {
|
871
|
-
return false;
|
872
|
-
}
|
873
|
-
|
874
|
-
return val >= domain[0] && val <= domain[1];
|
875
|
-
}
|
876
|
-
/**
|
877
|
-
* Determines whether a point is within the provided polygon
|
878
|
-
*
|
879
|
-
* @param point as input search [lat, lng]
|
880
|
-
* @param polygon Points must be within these (Multi)Polygon(s)
|
881
|
-
* @return {boolean}
|
882
|
-
*/
|
883
|
-
|
884
|
-
|
885
|
-
function isInPolygon(point, polygon) {
|
886
|
-
return (0, _booleanWithin["default"])((0, _helpers.point)(point), polygon);
|
887
|
-
}
|
888
|
-
|
889
|
-
function getTimeWidgetTitleFormatter(domain) {
|
890
|
-
if (!isValidTimeDomain(domain)) {
|
891
|
-
return null;
|
892
|
-
}
|
893
|
-
|
894
|
-
var diff = domain[1] - domain[0]; // Local aware formats
|
895
|
-
// https://momentjs.com/docs/#/parsing/string-format
|
896
|
-
|
897
|
-
return diff > durationYear ? 'L' : diff > durationDay ? 'L LT' : 'L LTS';
|
898
|
-
}
|
899
|
-
/**
|
900
|
-
* Sanity check on filters to prepare for save
|
901
|
-
* @type {typeof import('./filter-utils').isFilterValidToSave}
|
902
|
-
*/
|
903
|
-
|
904
|
-
|
905
|
-
function isFilterValidToSave(filter) {
|
906
|
-
return (filter === null || filter === void 0 ? void 0 : filter.type) && Array.isArray(filter === null || filter === void 0 ? void 0 : filter.name) && ((filter === null || filter === void 0 ? void 0 : filter.name.length) || (filter === null || filter === void 0 ? void 0 : filter.layerId.length));
|
907
|
-
}
|
908
|
-
/**
|
909
|
-
* Sanity check on filters to prepare for save
|
910
|
-
* @type {typeof import('./filter-utils').isValidFilterValue}
|
911
|
-
*/
|
912
|
-
|
913
|
-
/* eslint-disable complexity */
|
914
|
-
|
915
|
-
|
916
|
-
function isValidFilterValue(type, value) {
|
917
|
-
if (!type) {
|
918
|
-
return false;
|
919
|
-
}
|
920
|
-
|
921
|
-
switch (type) {
|
922
|
-
case _constants.FILTER_TYPES.select:
|
923
|
-
return value === true || value === false;
|
924
|
-
|
925
|
-
case _constants.FILTER_TYPES.range:
|
926
|
-
case _constants.FILTER_TYPES.timeRange:
|
927
|
-
return Array.isArray(value) && value.every(function (v) {
|
928
|
-
return v !== null && !isNaN(v);
|
929
|
-
});
|
930
|
-
|
931
|
-
case _constants.FILTER_TYPES.multiSelect:
|
932
|
-
return Array.isArray(value) && Boolean(value.length);
|
933
|
-
|
934
|
-
case _constants.FILTER_TYPES.input:
|
935
|
-
return Boolean(value.length);
|
936
|
-
|
937
|
-
case _constants.FILTER_TYPES.polygon:
|
938
|
-
var coordinates = (0, _lodash["default"])(value, ['geometry', 'coordinates']);
|
939
|
-
return Boolean(value && value.id && coordinates);
|
940
|
-
|
941
|
-
default:
|
942
|
-
return true;
|
943
|
-
}
|
944
|
-
}
|
945
|
-
|
946
|
-
function getColumnFilterProps(filter, dataset) {
|
947
|
-
if (filter.plotType === _constants.PLOT_TYPES.histogram || !filter.yAxis) {
|
948
|
-
// histogram should be calculated when create filter
|
949
|
-
return {};
|
950
|
-
}
|
951
|
-
|
952
|
-
var _filter$mappedValue = filter.mappedValue,
|
953
|
-
mappedValue = _filter$mappedValue === void 0 ? [] : _filter$mappedValue;
|
954
|
-
var yAxis = filter.yAxis;
|
955
|
-
var fieldIdx = dataset.getColumnFieldIdx(yAxis.name);
|
956
|
-
|
957
|
-
if (fieldIdx < 0) {
|
958
|
-
_console["default"].warn("yAxis ".concat(yAxis.name, " does not exist in dataset"));
|
959
|
-
|
960
|
-
return {
|
961
|
-
lineChart: {},
|
962
|
-
yAxis: yAxis
|
963
|
-
};
|
964
|
-
} // return lineChart
|
965
|
-
|
966
|
-
|
967
|
-
var series = dataset.dataContainer.map(function (row, rowIndex) {
|
968
|
-
return {
|
969
|
-
x: mappedValue[rowIndex],
|
970
|
-
y: row.valueAt(fieldIdx)
|
971
|
-
};
|
972
|
-
}, true).filter(function (_ref7) {
|
973
|
-
var x = _ref7.x,
|
974
|
-
y = _ref7.y;
|
975
|
-
return Number.isFinite(x) && Number.isFinite(y);
|
976
|
-
}).sort(function (a, b) {
|
977
|
-
return (0, _d3Array.ascending)(a.x, b.x);
|
978
|
-
});
|
979
|
-
var yDomain = (0, _d3Array.extent)(series, function (d) {
|
980
|
-
return d.y;
|
981
|
-
});
|
982
|
-
var xDomain = [series[0].x, series[series.length - 1].x];
|
983
|
-
return {
|
984
|
-
lineChart: {
|
985
|
-
series: series,
|
986
|
-
yDomain: yDomain,
|
987
|
-
xDomain: xDomain
|
988
|
-
},
|
989
|
-
yAxis: yAxis
|
990
|
-
};
|
991
|
-
}
|
992
|
-
|
993
|
-
function getDefaultFilterPlotType(filter) {
|
994
|
-
var filterPlotTypes = filter.type && SupportedPlotType[filter.type];
|
995
|
-
|
996
|
-
if (!filterPlotTypes) {
|
997
|
-
return null;
|
998
|
-
}
|
999
|
-
|
1000
|
-
if (!filter.yAxis) {
|
1001
|
-
return filterPlotTypes["default"];
|
1002
|
-
}
|
1003
|
-
|
1004
|
-
return filterPlotTypes[filter.yAxis.type] || null;
|
1005
|
-
}
|
1006
|
-
/**
|
1007
|
-
*
|
1008
|
-
* @param datasetIds list of dataset ids to be filtered
|
1009
|
-
* @param datasets all datasets
|
1010
|
-
* @param filters all filters to be applied to datasets
|
1011
|
-
* @return datasets - new updated datasets
|
1012
|
-
*/
|
1013
|
-
|
1014
|
-
|
1015
|
-
function applyFiltersToDatasets(datasetIds, datasets, filters, layers) {
|
1016
|
-
var dataIds = (0, _utils.toArray)(datasetIds);
|
1017
|
-
return dataIds.reduce(function (acc, dataId) {
|
1018
|
-
var layersToFilter = (layers || []).filter(function (l) {
|
1019
|
-
return l.config.dataId === dataId;
|
1020
|
-
});
|
1021
|
-
var appliedFilters = filters.filter(function (d) {
|
1022
|
-
return shouldApplyFilter(d, dataId);
|
1023
|
-
});
|
1024
|
-
var table = datasets[dataId];
|
1025
|
-
return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2["default"])({}, dataId, table.filterTable(appliedFilters, layersToFilter, {})));
|
1026
|
-
}, datasets);
|
1027
|
-
}
|
1028
|
-
/**
|
1029
|
-
* Applies a new field name value to fielter and update both filter and dataset
|
1030
|
-
* @param filter - to be applied the new field name on
|
1031
|
-
* @param dataset - dataset the field belongs to
|
1032
|
-
* @param fieldName - field.name
|
1033
|
-
* @param filterDatasetIndex - field.name
|
1034
|
-
* @param option
|
1035
|
-
* @return - {filter, datasets}
|
1036
|
-
*/
|
1037
|
-
|
1038
|
-
|
1039
|
-
function applyFilterFieldName(filter, dataset, fieldName) {
|
1040
|
-
var filterDatasetIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
1041
|
-
var option = arguments.length > 4 ? arguments[4] : undefined;
|
1042
|
-
// using filterDatasetIndex we can filter only the specified dataset
|
1043
|
-
var mergeDomain = option && option.hasOwnProperty('mergeDomain') ? option.mergeDomain : false;
|
1044
|
-
var fieldIndex = dataset.getColumnFieldIdx(fieldName); // if no field with same name is found, move to the next datasets
|
1045
|
-
|
1046
|
-
if (fieldIndex === -1) {
|
1047
|
-
// throw new Error(`fieldIndex not found. Dataset must contain a property with name: ${fieldName}`);
|
1048
|
-
return {
|
1049
|
-
filter: null,
|
1050
|
-
dataset: dataset
|
1051
|
-
};
|
1052
|
-
} // TODO: validate field type
|
1053
|
-
|
1054
|
-
|
1055
|
-
var filterProps = dataset.getColumnFilterProps(fieldName);
|
1056
|
-
|
1057
|
-
var newFilter = _objectSpread(_objectSpread({}, mergeDomain ? mergeFilterDomainStep(filter, filterProps) : _objectSpread(_objectSpread({}, filter), filterProps)), {}, {
|
1058
|
-
name: Object.assign((0, _toConsumableArray2["default"])((0, _utils.toArray)(filter.name)), (0, _defineProperty2["default"])({}, filterDatasetIndex, fieldName)),
|
1059
|
-
fieldIdx: Object.assign((0, _toConsumableArray2["default"])((0, _utils.toArray)(filter.fieldIdx)), (0, _defineProperty2["default"])({}, filterDatasetIndex, fieldIndex)),
|
1060
|
-
// TODO, since we allow to add multiple fields to a filter we can no longer freeze the filter
|
1061
|
-
freeze: true
|
1062
|
-
});
|
1063
|
-
|
1064
|
-
return {
|
1065
|
-
filter: newFilter,
|
1066
|
-
dataset: dataset
|
1067
|
-
};
|
1068
|
-
}
|
1069
|
-
/**
|
1070
|
-
* Merge one filter with other filter prop domain
|
1071
|
-
*/
|
1072
|
-
|
1073
|
-
/* eslint-disable complexity */
|
1074
|
-
|
1075
|
-
|
1076
|
-
function mergeFilterDomainStep(filter, filterProps) {
|
1077
|
-
if (!filter) {
|
1078
|
-
return null;
|
1079
|
-
}
|
1080
|
-
|
1081
|
-
if (!filterProps) {
|
1082
|
-
return filter;
|
1083
|
-
}
|
1084
|
-
|
1085
|
-
if (filter.fieldType && filter.fieldType !== filterProps.fieldType || !filterProps.domain) {
|
1086
|
-
return filter;
|
1087
|
-
}
|
1088
|
-
|
1089
|
-
var combinedDomain = !filter.domain ? filterProps.domain : [].concat((0, _toConsumableArray2["default"])(filter.domain || []), (0, _toConsumableArray2["default"])(filterProps.domain || [])).sort(function (a, b) {
|
1090
|
-
return a - b;
|
1091
|
-
});
|
1092
|
-
|
1093
|
-
var newFilter = _objectSpread(_objectSpread(_objectSpread({}, filter), filterProps), {}, {
|
1094
|
-
domain: [combinedDomain[0], combinedDomain[combinedDomain.length - 1]]
|
1095
|
-
});
|
1096
|
-
|
1097
|
-
switch (filterProps.fieldType) {
|
1098
|
-
case _constants.ALL_FIELD_TYPES.string:
|
1099
|
-
case _constants.ALL_FIELD_TYPES.date:
|
1100
|
-
return _objectSpread(_objectSpread({}, newFilter), {}, {
|
1101
|
-
domain: (0, _dataUtils.unique)(combinedDomain).sort()
|
1102
|
-
});
|
1103
|
-
|
1104
|
-
case _constants.ALL_FIELD_TYPES.timestamp:
|
1105
|
-
var step = filter.step < filterProps.step ? filter.step : filterProps.step;
|
1106
|
-
return _objectSpread(_objectSpread({}, newFilter), {}, {
|
1107
|
-
step: step
|
1108
|
-
});
|
1109
|
-
|
1110
|
-
case _constants.ALL_FIELD_TYPES.real:
|
1111
|
-
case _constants.ALL_FIELD_TYPES.integer:
|
1112
|
-
default:
|
1113
|
-
return newFilter;
|
1114
|
-
}
|
1115
|
-
}
|
1116
|
-
/* eslint-enable complexity */
|
1117
|
-
|
1118
|
-
/**
|
1119
|
-
* Generates polygon filter
|
1120
|
-
*/
|
1121
|
-
|
1122
|
-
|
1123
|
-
var featureToFilterValue = function featureToFilterValue(feature, filterId, properties) {
|
1124
|
-
return _objectSpread(_objectSpread({}, feature), {}, {
|
1125
|
-
id: feature.id,
|
1126
|
-
properties: _objectSpread(_objectSpread(_objectSpread({}, feature.properties), properties), {}, {
|
1127
|
-
filterId: filterId
|
1128
|
-
})
|
1129
|
-
});
|
1130
|
-
};
|
1131
|
-
|
1132
|
-
exports.featureToFilterValue = featureToFilterValue;
|
1133
|
-
|
1134
|
-
var getFilterIdInFeature = function getFilterIdInFeature(f) {
|
1135
|
-
return (0, _lodash["default"])(f, ['properties', 'filterId']);
|
1136
|
-
};
|
1137
|
-
/**
|
1138
|
-
* Generates polygon filter
|
1139
|
-
*/
|
1140
|
-
|
1141
|
-
|
1142
|
-
exports.getFilterIdInFeature = getFilterIdInFeature;
|
1143
|
-
|
1144
|
-
function generatePolygonFilter(layers, feature) {
|
1145
|
-
var dataId = layers.map(function (l) {
|
1146
|
-
return l.config.dataId;
|
1147
|
-
}).filter(_dataUtils.notNullorUndefined);
|
1148
|
-
var layerId = layers.map(function (l) {
|
1149
|
-
return l.id;
|
1150
|
-
});
|
1151
|
-
var name = layers.map(function (l) {
|
1152
|
-
return l.config.label;
|
1153
|
-
});
|
1154
|
-
var filter = getDefaultFilter({
|
1155
|
-
dataId: dataId
|
1156
|
-
});
|
1157
|
-
return _objectSpread(_objectSpread({}, filter), {}, {
|
1158
|
-
fixedDomain: true,
|
1159
|
-
type: _constants.FILTER_TYPES.polygon,
|
1160
|
-
name: name,
|
1161
|
-
layerId: layerId,
|
1162
|
-
value: featureToFilterValue(feature, filter.id, {
|
1163
|
-
isVisible: true
|
1164
|
-
})
|
1165
|
-
});
|
1166
|
-
}
|
1167
|
-
/**
|
1168
|
-
* Run filter entirely on CPU
|
1169
|
-
*/
|
1170
|
-
|
1171
|
-
|
1172
|
-
function filterDatasetCPU(state, dataId) {
|
1173
|
-
var datasetFilters = state.filters.filter(function (f) {
|
1174
|
-
return f.dataId.includes(dataId);
|
1175
|
-
});
|
1176
|
-
var dataset = state.datasets[dataId];
|
1177
|
-
|
1178
|
-
if (!dataset) {
|
1179
|
-
return state;
|
1180
|
-
}
|
1181
|
-
|
1182
|
-
var cpuFilteredDataset = dataset.filterTableCPU(datasetFilters, state.layers);
|
1183
|
-
return (0, _utils.set)(['datasets', dataId], cpuFilteredDataset, state);
|
1184
|
-
}
|
1185
|
-
/**
|
1186
|
-
* Validate parsed filters with datasets and add filterProps to field
|
1187
|
-
*/
|
1188
|
-
|
1189
|
-
|
1190
|
-
function validateFiltersUpdateDatasets(state) {
|
1191
|
-
var filtersToValidate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
1192
|
-
// TODO Better Typings here
|
1193
|
-
var validated = [];
|
1194
|
-
var failed = [];
|
1195
|
-
var datasets = state.datasets;
|
1196
|
-
var updatedDatasets = datasets; // merge filters
|
1197
|
-
|
1198
|
-
filtersToValidate.forEach(function (filter) {
|
1199
|
-
// we can only look for datasets define in the filter dataId
|
1200
|
-
var datasetIds = (0, _utils.toArray)(filter.dataId); // we can merge a filter only if all datasets in filter.dataId are loaded
|
1201
|
-
|
1202
|
-
if (datasetIds.every(function (d) {
|
1203
|
-
return datasets[d] && !state.isMergingDatasets[d];
|
1204
|
-
})) {
|
1205
|
-
// all datasetIds in filter must be present the state datasets
|
1206
|
-
var _datasetIds$reduce = datasetIds.reduce(function (acc, datasetId) {
|
1207
|
-
var dataset = updatedDatasets[datasetId];
|
1208
|
-
var layers = state.layers.filter(function (l) {
|
1209
|
-
return l.config.dataId === dataset.id;
|
1210
|
-
});
|
1211
|
-
|
1212
|
-
var _validateFilterWithDa = validateFilterWithData(acc.augmentedDatasets[datasetId] || dataset, filter, layers),
|
1213
|
-
updatedFilter = _validateFilterWithDa.filter,
|
1214
|
-
updatedDataset = _validateFilterWithDa.dataset;
|
1215
|
-
|
1216
|
-
if (updatedFilter) {
|
1217
|
-
return _objectSpread(_objectSpread({}, acc), {}, {
|
1218
|
-
// merge filter props
|
1219
|
-
filter: acc.filter ? _objectSpread(_objectSpread({}, acc.filter), mergeFilterDomainStep(acc.filter, updatedFilter)) : updatedFilter,
|
1220
|
-
applyToDatasets: [].concat((0, _toConsumableArray2["default"])(acc.applyToDatasets), [datasetId]),
|
1221
|
-
augmentedDatasets: _objectSpread(_objectSpread({}, acc.augmentedDatasets), {}, (0, _defineProperty2["default"])({}, datasetId, updatedDataset))
|
1222
|
-
});
|
1223
|
-
}
|
1224
|
-
|
1225
|
-
return acc;
|
1226
|
-
}, {
|
1227
|
-
filter: null,
|
1228
|
-
applyToDatasets: [],
|
1229
|
-
augmentedDatasets: {}
|
1230
|
-
}),
|
1231
|
-
validatedFilter = _datasetIds$reduce.filter,
|
1232
|
-
applyToDatasets = _datasetIds$reduce.applyToDatasets,
|
1233
|
-
augmentedDatasets = _datasetIds$reduce.augmentedDatasets;
|
1234
|
-
|
1235
|
-
if (validatedFilter && (0, _lodash2["default"])(datasetIds, applyToDatasets)) {
|
1236
|
-
validated.push(validatedFilter);
|
1237
|
-
updatedDatasets = _objectSpread(_objectSpread({}, updatedDatasets), augmentedDatasets);
|
1238
|
-
} else {
|
1239
|
-
failed.push(filter);
|
1240
|
-
}
|
1241
|
-
} else {
|
1242
|
-
failed.push(filter);
|
1243
|
-
}
|
1244
|
-
});
|
1245
|
-
return {
|
1246
|
-
validated: validated,
|
1247
|
-
failed: failed,
|
1248
|
-
updatedDatasets: updatedDatasets
|
1249
|
-
};
|
1250
|
-
}
|
1251
|
-
|
1252
|
-
function getFilterPlot(filter, dataset) {
|
1253
|
-
if (filter.plotType === _constants.PLOT_TYPES.histogram || !filter.yAxis) {
|
1254
|
-
// histogram should be calculated when create filter
|
1255
|
-
return {};
|
1256
|
-
}
|
1257
|
-
|
1258
|
-
var _filter$mappedValue2 = filter.mappedValue,
|
1259
|
-
mappedValue = _filter$mappedValue2 === void 0 ? [] : _filter$mappedValue2;
|
1260
|
-
var yAxis = filter.yAxis;
|
1261
|
-
var fieldIdx = dataset.getColumnFieldIdx(yAxis.name);
|
1262
|
-
|
1263
|
-
if (fieldIdx < 0) {
|
1264
|
-
_console["default"].warn("yAxis ".concat(yAxis.name, " does not exist in dataset"));
|
1265
|
-
|
1266
|
-
return {
|
1267
|
-
lineChart: {},
|
1268
|
-
yAxis: yAxis
|
1269
|
-
};
|
1270
|
-
} // return lineChart
|
1271
|
-
|
1272
|
-
|
1273
|
-
var series = dataset.dataContainer.map(function (row, rowIndex) {
|
1274
|
-
return {
|
1275
|
-
x: mappedValue[rowIndex],
|
1276
|
-
y: row.valueAt(fieldIdx)
|
1277
|
-
};
|
1278
|
-
}, true).filter(function (_ref8) {
|
1279
|
-
var x = _ref8.x,
|
1280
|
-
y = _ref8.y;
|
1281
|
-
return Number.isFinite(x) && Number.isFinite(y);
|
1282
|
-
}).sort(function (a, b) {
|
1283
|
-
return (0, _d3Array.ascending)(a.x, b.x);
|
1284
|
-
});
|
1285
|
-
var yDomain = (0, _d3Array.extent)(series, function (d) {
|
1286
|
-
return d.y;
|
1287
|
-
});
|
1288
|
-
var xDomain = [series[0].x, series[series.length - 1].x];
|
1289
|
-
return {
|
1290
|
-
lineChart: {
|
1291
|
-
series: series,
|
1292
|
-
yDomain: yDomain,
|
1293
|
-
xDomain: xDomain
|
1294
|
-
},
|
1295
|
-
yAxis: yAxis
|
1296
|
-
};
|
1297
|
-
}
|
1298
|
-
/**
|
1299
|
-
* Retrieve interval bins for time filter
|
1300
|
-
*/
|
1301
|
-
|
1302
|
-
|
1303
|
-
function getIntervalBins(filter) {
|
1304
|
-
var _filter$plotType;
|
1305
|
-
|
1306
|
-
var bins = filter.bins;
|
1307
|
-
var interval = (_filter$plotType = filter.plotType) === null || _filter$plotType === void 0 ? void 0 : _filter$plotType.interval;
|
1308
|
-
|
1309
|
-
if (!interval || !bins || Object.keys(bins).length === 0) {
|
1310
|
-
return null;
|
1311
|
-
}
|
1312
|
-
|
1313
|
-
var values = Object.values(bins);
|
1314
|
-
return values[0] ? values[0][interval] : null;
|
1315
|
-
}
|
1316
|
-
|
1317
|
-
function isValidTimeDomain(domain) {
|
1318
|
-
return Array.isArray(domain) && domain.every(Number.isFinite);
|
1319
|
-
}
|
1320
|
-
|
1321
|
-
function getTimeWidgetHintFormatter(domain) {
|
1322
|
-
if (!isValidTimeDomain(domain)) {
|
1323
|
-
return undefined;
|
1324
|
-
}
|
1325
|
-
|
1326
|
-
var diff = domain[1] - domain[0];
|
1327
|
-
return diff > durationWeek ? 'L' : diff > durationDay ? 'L LT' : diff > durationHour ? 'LT' : 'LTS';
|
1328
|
-
}
|
1329
|
-
|
1330
|
-
function isSideFilter(filter) {
|
1331
|
-
return filter.view === _constants.FILTER_VIEW_TYPES.side;
|
1332
|
-
}
|
1333
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9maWx0ZXItdXRpbHMudHMiXSwibmFtZXMiOlsiZHVyYXRpb25TZWNvbmQiLCJkdXJhdGlvbk1pbnV0ZSIsImR1cmF0aW9uSG91ciIsImR1cmF0aW9uRGF5IiwiZHVyYXRpb25XZWVrIiwiZHVyYXRpb25ZZWFyIiwiVGltZXN0YW1wU3RlcE1hcCIsIm1heCIsInN0ZXAiLCJOdW1iZXIiLCJQT1NJVElWRV9JTkZJTklUWSIsImhpc3RvZ3JhbUJpbnMiLCJlbmxhcmdlZEhpc3RvZ3JhbUJpbnMiLCJGSUxURVJfVVBEQVRFUl9QUk9QUyIsImRhdGFJZCIsIm5hbWUiLCJsYXllcklkIiwiTElNSVRFRF9GSUxURVJfRUZGRUNUX1BST1BTIiwiU3VwcG9ydGVkUGxvdFR5cGUiLCJGSUxURVJfVFlQRVMiLCJ0aW1lUmFuZ2UiLCJBTExfRklFTERfVFlQRVMiLCJpbnRlZ2VyIiwicmVhbCIsInJhbmdlIiwiRklMVEVSX0NPTVBPTkVOVFMiLCJzZWxlY3QiLCJtdWx0aVNlbGVjdCIsInBvbHlnb24iLCJERUZBVUxUX0ZJTFRFUl9TVFJVQ1RVUkUiLCJmcmVlemUiLCJpZCIsImVuYWJsZWQiLCJmaXhlZERvbWFpbiIsInZpZXciLCJGSUxURVJfVklFV19UWVBFUyIsInNpZGUiLCJpc0FuaW1hdGluZyIsImFuaW1hdGlvbldpbmRvdyIsIkFOSU1BVElPTl9XSU5ET1ciLCJmcmVlIiwic3BlZWQiLCJ0eXBlIiwiZmllbGRJZHgiLCJkb21haW4iLCJ2YWx1ZSIsInBsb3RUeXBlIiwiUExPVF9UWVBFUyIsImhpc3RvZ3JhbSIsInlBeGlzIiwiaW50ZXJ2YWwiLCJncHUiLCJGSUxURVJfSURfTEVOR1RIIiwiTEFZRVJfRklMVEVSUyIsImdldERlZmF1bHRGaWx0ZXIiLCJzaG91bGRBcHBseUZpbHRlciIsImZpbHRlciIsImRhdGFzZXRJZCIsImRhdGFJZHMiLCJpbmNsdWRlcyIsInZhbGlkYXRlUG9seWdvbkZpbHRlciIsImRhdGFzZXQiLCJsYXllcnMiLCJmYWlsZWQiLCJpc1ZhbGlkRmlsdGVyVmFsdWUiLCJpc1ZhbGlkRGF0YXNldCIsImxheWVyIiwiZmluZCIsImwiLCJmaWx0ZXJWYWxpZGF0b3JzIiwidmFsaWRhdGVGaWx0ZXIiLCJmaWx0ZXJEYXRhSWQiLCJmaWx0ZXJEYXRhc2V0SW5kZXgiLCJpbmRleE9mIiwiaW5pdGlhbGl6ZUZpbHRlciIsImZpZWxkTmFtZSIsImFwcGx5RmlsdGVyRmllbGROYW1lIiwibWVyZ2VEb21haW4iLCJ1cGRhdGVkRmlsdGVyIiwidXBkYXRlZERhdGFzZXQiLCJhZGp1c3RWYWx1ZVRvRmlsdGVyRG9tYWluIiwidmFsaWRhdGVGaWx0ZXJZQXhpcyIsInZhbGlkYXRlRmlsdGVyV2l0aERhdGEiLCJoYXNPd25Qcm9wZXJ0eSIsImZpZWxkcyIsIm1hdGNoZWRBeGlzIiwiZ2V0RmlsdGVyUGxvdCIsImdldEZpbHRlclByb3BzIiwiZmllbGQiLCJmaWVsZERvbWFpbiIsImZpbHRlclByb3BzIiwiZmllbGRUeXBlIiwidHlwZU9wdGlvbnMiLCJzdHJpbmciLCJkYXRlIiwidGltZXN0YW1wIiwiZW5sYXJnZWQiLCJnZXRQb2x5Z29uRmlsdGVyRnVuY3RvciIsImRhdGFDb250YWluZXIiLCJnZXRQb3NpdGlvbiIsImdldFBvc2l0aW9uQWNjZXNzb3IiLCJMQVlFUl9UWVBFUyIsInBvaW50IiwiaWNvbiIsImRhdGEiLCJwb3MiLCJldmVyeSIsImlzRmluaXRlIiwiaXNJblBvbHlnb24iLCJhcmMiLCJsaW5lIiwiaGV4YWdvbklkIiwiZGF0YVRvRmVhdHVyZSIsImNlbnRyb2lkcyIsImNlbnRyb2lkIiwiaW5kZXgiLCJnZW9qc29uIiwiZ2V0RmlsdGVyRnVuY3Rpb24iLCJ2YWx1ZUFjY2Vzc29yIiwiZGVmYXVsdEZ1bmMiLCJkIiwiaXNJblJhbmdlIiwibWFwcGVkVmFsdWUiLCJhY2Nlc3NvciIsIkFycmF5IiwiaXNBcnJheSIsImZvcm1hdCIsImxlbmd0aCIsImxheWVyRmlsdGVyRnVuY3Rpb25zIiwibWFwIiwiY29uZmlnIiwiZmlsdGVyRnVuYyIsInVwZGF0ZUZpbHRlckRhdGFJZCIsImZpbHRlckRhdGFCeUZpbHRlclR5cGVzIiwiZHluYW1pY0RvbWFpbkZpbHRlcnMiLCJjcHVGaWx0ZXJzIiwiZmlsdGVyRnVuY3MiLCJmaWx0ZXJlZEluZGV4Rm9yRG9tYWluIiwiZmlsdGVyZWRJbmRleCIsImZpbHRlckNvbnRleHQiLCJmaWx0ZXJGdW5jQ2FsbGVyIiwibnVtUm93cyIsImkiLCJtYXRjaEZvckRvbWFpbiIsInB1c2giLCJtYXRjaEZvclJlbmRlciIsImdldEZpbHRlclJlY29yZCIsImZpbHRlcnMiLCJvcHQiLCJmaWx0ZXJSZWNvcmQiLCJkeW5hbWljRG9tYWluIiwiY3B1IiwiZm9yRWFjaCIsImYiLCJpZ25vcmVEb21haW4iLCJjcHVPbmx5IiwiZGlmZkZpbHRlcnMiLCJvbGRGaWx0ZXJSZWNvcmQiLCJmaWx0ZXJDaGFuZ2VkIiwiT2JqZWN0IiwiZW50cmllcyIsInJlY29yZCIsIml0ZW1zIiwib2xkRmlsdGVyIiwicHJvcCIsImZpbHRlcmVkVmFsdWUiLCJnZXROdW1lcmljRmllbGREb21haW4iLCJtYXBJbmRleCIsIlNjYWxlVXRpbHMiLCJnZXRMaW5lYXJEb21haW4iLCJkaWZmIiwiZ2V0TnVtZXJpY1N0ZXBTaXplIiwiZm9ybWF0TnVtYmVyQnlTdGVwIiwiZ2V0SGlzdG9ncmFtIiwiZW5sYXJnZWRIaXN0b2dyYW0iLCJNYXRoIiwiYWJzIiwieCIsImV4cG9uZW50aWFsRm9ybSIsInRvRXhwb25lbnRpYWwiLCJleHBvbmVudCIsInBhcnNlRmxvYXQiLCJzcGxpdCIsIkRlY2ltYWwiLCJwb3ciLCJ0b051bWJlciIsImdldFRpbWVzdGFtcEZpZWxkRG9tYWluIiwiZGVmYXVsdFRpbWVGb3JtYXQiLCJnZXRUaW1lV2lkZ2V0VGl0bGVGb3JtYXR0ZXIiLCJlbnRyeSIsImhpc3RvZ3JhbUNvbnN0cnVjdCIsImJpbnMiLCJ0aHJlc2hvbGRzIiwiYmluIiwiY291bnQiLCJ4MCIsIngxIiwidmFsIiwiYm91bmQiLCJmbG9vciIsImNlaWwiLCJpc1ZhbGlkVGltZURvbWFpbiIsImlzRmlsdGVyVmFsaWRUb1NhdmUiLCJ2IiwiaXNOYU4iLCJCb29sZWFuIiwiaW5wdXQiLCJjb29yZGluYXRlcyIsImdldENvbHVtbkZpbHRlclByb3BzIiwiZ2V0Q29sdW1uRmllbGRJZHgiLCJDb25zb2xlIiwid2FybiIsImxpbmVDaGFydCIsInNlcmllcyIsInJvdyIsInJvd0luZGV4IiwieSIsInZhbHVlQXQiLCJzb3J0IiwiYSIsImIiLCJ5RG9tYWluIiwieERvbWFpbiIsImdldERlZmF1bHRGaWx0ZXJQbG90VHlwZSIsImZpbHRlclBsb3RUeXBlcyIsImFwcGx5RmlsdGVyc1RvRGF0YXNldHMiLCJkYXRhc2V0SWRzIiwiZGF0YXNldHMiLCJyZWR1Y2UiLCJhY2MiLCJsYXllcnNUb0ZpbHRlciIsImFwcGxpZWRGaWx0ZXJzIiwidGFibGUiLCJmaWx0ZXJUYWJsZSIsIm9wdGlvbiIsImZpZWxkSW5kZXgiLCJuZXdGaWx0ZXIiLCJtZXJnZUZpbHRlckRvbWFpblN0ZXAiLCJhc3NpZ24iLCJjb21iaW5lZERvbWFpbiIsImZlYXR1cmVUb0ZpbHRlclZhbHVlIiwiZmVhdHVyZSIsImZpbHRlcklkIiwicHJvcGVydGllcyIsImdldEZpbHRlcklkSW5GZWF0dXJlIiwiZ2VuZXJhdGVQb2x5Z29uRmlsdGVyIiwibm90TnVsbG9yVW5kZWZpbmVkIiwibGFiZWwiLCJpc1Zpc2libGUiLCJmaWx0ZXJEYXRhc2V0Q1BVIiwic3RhdGUiLCJkYXRhc2V0RmlsdGVycyIsImNwdUZpbHRlcmVkRGF0YXNldCIsImZpbHRlclRhYmxlQ1BVIiwidmFsaWRhdGVGaWx0ZXJzVXBkYXRlRGF0YXNldHMiLCJmaWx0ZXJzVG9WYWxpZGF0ZSIsInZhbGlkYXRlZCIsInVwZGF0ZWREYXRhc2V0cyIsImlzTWVyZ2luZ0RhdGFzZXRzIiwiYXVnbWVudGVkRGF0YXNldHMiLCJhcHBseVRvRGF0YXNldHMiLCJ2YWxpZGF0ZWRGaWx0ZXIiLCJnZXRJbnRlcnZhbEJpbnMiLCJrZXlzIiwidmFsdWVzIiwiZ2V0VGltZVdpZGdldEhpbnRGb3JtYXR0ZXIiLCJ1bmRlZmluZWQiLCJpc1NpZGVGaWx0ZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBU0E7O0FBQ0E7O0FBdUJBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVPLElBQU1BLGNBQWMsR0FBRyxJQUF2Qjs7QUFDQSxJQUFNQyxjQUFjLEdBQUdELGNBQWMsR0FBRyxFQUF4Qzs7QUFDQSxJQUFNRSxZQUFZLEdBQUdELGNBQWMsR0FBRyxFQUF0Qzs7QUFDQSxJQUFNRSxXQUFXLEdBQUdELFlBQVksR0FBRyxFQUFuQzs7QUFDQSxJQUFNRSxZQUFZLEdBQUdELFdBQVcsR0FBRyxDQUFuQzs7QUFDQSxJQUFNRSxZQUFZLEdBQUdGLFdBQVcsR0FBRyxHQUFuQzs7QUFnQkEsSUFBTUcsZ0JBQWdCLEdBQUcsQ0FDOUI7QUFBQ0MsRUFBQUEsR0FBRyxFQUFFLENBQU47QUFBU0MsRUFBQUEsSUFBSSxFQUFFO0FBQWYsQ0FEOEIsRUFFOUI7QUFBQ0QsRUFBQUEsR0FBRyxFQUFFLEVBQU47QUFBVUMsRUFBQUEsSUFBSSxFQUFFO0FBQWhCLENBRjhCLEVBRzlCO0FBQUNELEVBQUFBLEdBQUcsRUFBRSxHQUFOO0FBQVdDLEVBQUFBLElBQUksRUFBRTtBQUFqQixDQUg4QixFQUk5QjtBQUFDRCxFQUFBQSxHQUFHLEVBQUUsR0FBTjtBQUFXQyxFQUFBQSxJQUFJLEVBQUU7QUFBakIsQ0FKOEIsRUFLOUI7QUFBQ0QsRUFBQUEsR0FBRyxFQUFFLElBQU47QUFBWUMsRUFBQUEsSUFBSSxFQUFFO0FBQWxCLENBTDhCLEVBTTlCO0FBQUNELEVBQUFBLEdBQUcsRUFBRSxJQUFOO0FBQVlDLEVBQUFBLElBQUksRUFBRTtBQUFsQixDQU44QixFQU85QjtBQUFDRCxFQUFBQSxHQUFHLEVBQUVFLE1BQU0sQ0FBQ0MsaUJBQWI7QUFBZ0NGLEVBQUFBLElBQUksRUFBRTtBQUF0QyxDQVA4QixDQUF6Qjs7QUFVQSxJQUFNRyxhQUFhLEdBQUcsRUFBdEI7O0FBQ0EsSUFBTUMscUJBQXFCLEdBQUcsR0FBOUI7O0FBRUEsSUFBTUMsb0JBQW9CLEdBQUcsMkJBQVU7QUFDNUNDLEVBQUFBLE1BQU0sRUFBRSxJQURvQztBQUU1Q0MsRUFBQUEsSUFBSSxFQUFFLElBRnNDO0FBRzVDQyxFQUFBQSxPQUFPLEVBQUU7QUFIbUMsQ0FBVixDQUE3Qjs7QUFNQSxJQUFNQywyQkFBMkIsR0FBRyxnRUFDeENKLG9CQUFvQixDQUFDRSxJQURtQixFQUNaLElBRFksRUFBcEM7QUFHUDtBQUNBO0FBQ0E7OztBQUVBLElBQU1HLGlCQUFpQixrRkFDcEJDLHdCQUFhQyxTQURPO0FBRW5CLGFBQVM7QUFGVSwyREFHbEJDLDJCQUFnQkMsT0FIRSxFQUdRLFdBSFIsMkRBSWxCRCwyQkFBZ0JFLElBSkUsRUFJSyxXQUpMLGlGQU1wQkosd0JBQWFLLEtBTk87QUFPbkIsYUFBUztBQVBVLHlEQVFsQkgsMkJBQWdCQyxPQVJFLEVBUVEsV0FSUix5REFTbEJELDJCQUFnQkUsSUFURSxFQVNLLFdBVEwsNkNBQXZCO0FBYU8sSUFBTUUsaUJBQWlCLGtGQUMzQk4sd0JBQWFPLE1BRGMsRUFDTCxvQkFESyx3REFFM0JQLHdCQUFhUSxXQUZjLEVBRUEsbUJBRkEsd0RBRzNCUix3QkFBYUMsU0FIYyxFQUdGLGlCQUhFLHdEQUkzQkQsd0JBQWFLLEtBSmMsRUFJTixhQUpNLHdEQUszQkwsd0JBQWFTLE9BTGMsRUFLSixlQUxJLHNCQUF2Qjs7QUFRQSxJQUFNQyx3QkFBd0IsR0FBRztBQUN0Q2YsRUFBQUEsTUFBTSxFQUFFLEVBRDhCO0FBQzFCO0FBQ1pnQixFQUFBQSxNQUFNLEVBQUUsS0FGOEI7QUFHdENDLEVBQUFBLEVBQUUsRUFBRSxJQUhrQztBQUl0Q0MsRUFBQUEsT0FBTyxFQUFFLElBSjZCO0FBTXRDO0FBQ0FDLEVBQUFBLFdBQVcsRUFBRSxLQVB5QjtBQVF0Q0MsRUFBQUEsSUFBSSxFQUFFQyw2QkFBa0JDLElBUmM7QUFTdENDLEVBQUFBLFdBQVcsRUFBRSxLQVR5QjtBQVV0Q0MsRUFBQUEsZUFBZSxFQUFFQyw0QkFBaUJDLElBVkk7QUFXdENDLEVBQUFBLEtBQUssRUFBRSxDQVgrQjtBQWF0QztBQUNBMUIsRUFBQUEsSUFBSSxFQUFFLEVBZGdDO0FBYzVCO0FBQ1YyQixFQUFBQSxJQUFJLEVBQUUsSUFmZ0M7QUFnQnRDQyxFQUFBQSxRQUFRLEVBQUUsRUFoQjRCO0FBZ0J4QjtBQUNkQyxFQUFBQSxNQUFNLEVBQUUsSUFqQjhCO0FBa0J0Q0MsRUFBQUEsS0FBSyxFQUFFLElBbEIrQjtBQW9CdEM7QUFDQUMsRUFBQUEsUUFBUSxFQUFFQyxzQkFBV0MsU0FyQmlCO0FBc0J0Q0MsRUFBQUEsS0FBSyxFQUFFLElBdEIrQjtBQXVCdENDLEVBQUFBLFFBQVEsRUFBRSxJQXZCNEI7QUF5QnRDO0FBQ0FDLEVBQUFBLEdBQUcsRUFBRTtBQTFCaUMsQ0FBakM7O0FBNkJBLElBQU1DLGdCQUFnQixHQUFHLENBQXpCOztBQUVBLElBQU1DLGFBQWEsR0FBRyxDQUFDbEMsd0JBQWFTLE9BQWQsQ0FBdEI7QUFFUDtBQUNBO0FBQ0E7Ozs7QUFDTyxTQUFTMEIsZ0JBQVQsR0FNd0I7QUFBQSxpRkFBM0IsRUFBMkI7QUFBQSxNQUw3QnhDLE1BSzZCLFFBTDdCQSxNQUs2QjtBQUFBLE1BSjdCaUIsRUFJNkIsUUFKN0JBLEVBSTZCOztBQUM3Qix5Q0FDS0Ysd0JBREw7QUFFRTtBQUNBZixJQUFBQSxNQUFNLEVBQUVBLE1BQU0sR0FBRyxvQkFBUUEsTUFBUixDQUFILEdBQXFCLEVBSHJDO0FBSUVpQixJQUFBQSxFQUFFLEVBQUVBLEVBQUUsSUFBSSwyQkFBZXFCLGdCQUFmO0FBSlo7QUFNRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBU0csaUJBQVQsQ0FBMkJDLE1BQTNCLEVBQTJDQyxTQUEzQyxFQUF1RTtBQUM1RSxNQUFNQyxPQUFPLEdBQUcsb0JBQVFGLE1BQU0sQ0FBQzFDLE1BQWYsQ0FBaEI7QUFDQSxTQUFPNEMsT0FBTyxDQUFDQyxRQUFSLENBQWlCRixTQUFqQixLQUErQkQsTUFBTSxDQUFDWCxLQUFQLEtBQWlCLElBQXZEO0FBQ0Q7O0FBV0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTZSxxQkFBVCxDQUNMQyxPQURLLEVBRUxMLE1BRkssRUFHTE0sTUFISyxFQUl1QztBQUM1QyxNQUFNQyxNQUFNLEdBQUc7QUFBQ0YsSUFBQUEsT0FBTyxFQUFQQSxPQUFEO0FBQVVMLElBQUFBLE1BQU0sRUFBRTtBQUFsQixHQUFmO0FBRDRDLE1BRXJDWCxLQUZxQyxHQUVMVyxNQUZLLENBRXJDWCxLQUZxQztBQUFBLE1BRTlCN0IsT0FGOEIsR0FFTHdDLE1BRkssQ0FFOUJ4QyxPQUY4QjtBQUFBLE1BRXJCMEIsSUFGcUIsR0FFTGMsTUFGSyxDQUVyQmQsSUFGcUI7QUFBQSxNQUVmNUIsTUFGZSxHQUVMMEMsTUFGSyxDQUVmMUMsTUFGZTs7QUFJNUMsTUFBSSxDQUFDRSxPQUFELElBQVksQ0FBQ2dELGtCQUFrQixDQUFDdEIsSUFBRCxFQUFPRyxLQUFQLENBQW5DLEVBQWtEO0FBQ2hELFdBQU9rQixNQUFQO0FBQ0Q7O0FBRUQsTUFBTUUsY0FBYyxHQUFHbkQsTUFBTSxDQUFDNkMsUUFBUCxDQUFnQkUsT0FBTyxDQUFDOUIsRUFBeEIsQ0FBdkI7O0FBRUEsTUFBSSxDQUFDa0MsY0FBTCxFQUFxQjtBQUNuQixXQUFPRixNQUFQO0FBQ0Q7O0FBRUQsTUFBTUcsS0FBSyxHQUFHSixNQUFNLENBQUNLLElBQVAsQ0FBWSxVQUFBQyxDQUFDO0FBQUEsV0FBSXBELE9BQU8sQ0FBQzJDLFFBQVIsQ0FBaUJTLENBQUMsQ0FBQ3JDLEVBQW5CLENBQUo7QUFBQSxHQUFiLENBQWQ7O0FBRUEsTUFBSSxDQUFDbUMsS0FBTCxFQUFZO0FBQ1YsV0FBT0gsTUFBUDtBQUNEOztBQUVELFNBQU87QUFDTFAsSUFBQUEsTUFBTSxrQ0FDREEsTUFEQztBQUVKMUIsTUFBQUEsTUFBTSxFQUFFLElBRko7QUFHSmEsTUFBQUEsUUFBUSxFQUFFO0FBSE4sTUFERDtBQU1Ma0IsSUFBQUEsT0FBTyxFQUFQQTtBQU5LLEdBQVA7QUFRRDtBQUVEO0FBQ0E7QUFDQTs7O0FBQ0EsSUFBTVEsZ0JBQWdCLHdDQUNuQmxELHdCQUFhUyxPQURNLEVBQ0lnQyxxQkFESixDQUF0QjtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDTyxTQUFTVSxjQUFULENBQ0xULE9BREssRUFFTEwsTUFGSyxFQUdnQztBQUFBOztBQUNyQztBQUNBLE1BQU1PLE1BQU0sR0FBRztBQUFDRixJQUFBQSxPQUFPLEVBQVBBLE9BQUQ7QUFBVUwsSUFBQUEsTUFBTSxFQUFFO0FBQWxCLEdBQWY7QUFDQSxNQUFNZSxZQUFZLEdBQUcsb0JBQVFmLE1BQU0sQ0FBQzFDLE1BQWYsQ0FBckI7QUFFQSxNQUFNMEQsa0JBQWtCLEdBQUdELFlBQVksQ0FBQ0UsT0FBYixDQUFxQlosT0FBTyxDQUFDOUIsRUFBN0IsQ0FBM0I7O0FBQ0EsTUFBSXlDLGtCQUFrQixHQUFHLENBQXJCLElBQTBCLENBQUMsb0JBQVFoQixNQUFNLENBQUN6QyxJQUFmLEVBQXFCeUQsa0JBQXJCLENBQS9CLEVBQXlFO0FBQ3ZFO0FBQ0EsV0FBT1QsTUFBUDtBQUNEOztBQUVELE1BQU1XLGdCQUF3QixpREFDekJwQixnQkFBZ0IsQ0FBQztBQUFDeEMsSUFBQUEsTUFBTSxFQUFFMEMsTUFBTSxDQUFDMUM7QUFBaEIsR0FBRCxDQURTLEdBRXpCMEMsTUFGeUI7QUFHNUIxQyxJQUFBQSxNQUFNLEVBQUV5RCxZQUhvQjtBQUk1QnhELElBQUFBLElBQUksRUFBRSxvQkFBUXlDLE1BQU0sQ0FBQ3pDLElBQWY7QUFKc0IsSUFBOUI7O0FBT0EsTUFBTTRELFNBQVMsR0FBR0QsZ0JBQWdCLENBQUMzRCxJQUFqQixDQUFzQnlELGtCQUF0QixDQUFsQjs7QUFsQnFDLDhCQW1Cb0JJLG9CQUFvQixDQUMzRUYsZ0JBRDJFLEVBRTNFYixPQUYyRSxFQUczRWMsU0FIMkUsRUFJM0VILGtCQUoyRSxFQUszRTtBQUFDSyxJQUFBQSxXQUFXLEVBQUU7QUFBZCxHQUwyRSxDQW5CeEM7QUFBQSxNQW1CdEJDLGFBbkJzQix5QkFtQjlCdEIsTUFuQjhCO0FBQUEsTUFtQkV1QixjQW5CRix5QkFtQlBsQixPQW5CTzs7QUEyQnJDLE1BQUksQ0FBQ2lCLGFBQUwsRUFBb0I7QUFDbEIsV0FBT2YsTUFBUDtBQUNEOztBQUVEZSxFQUFBQSxhQUFhLENBQUNqQyxLQUFkLEdBQXNCbUMseUJBQXlCLENBQUN4QixNQUFNLENBQUNYLEtBQVIsRUFBZWlDLGFBQWYsQ0FBL0M7QUFDQUEsRUFBQUEsYUFBYSxDQUFDNUMsSUFBZCxtQkFBcUJzQixNQUFNLENBQUN0QixJQUE1Qix1REFBb0M0QyxhQUFhLENBQUM1QyxJQUFsRDs7QUFFQSxNQUFJNEMsYUFBYSxDQUFDakMsS0FBZCxLQUF3QixJQUE1QixFQUFrQztBQUNoQztBQUNBLFdBQU9rQixNQUFQO0FBQ0Q7O0FBRUQsU0FBTztBQUNMUCxJQUFBQSxNQUFNLEVBQUV5QixtQkFBbUIsQ0FBQ0gsYUFBRCxFQUFnQkMsY0FBaEIsQ0FEdEI7QUFFTGxCLElBQUFBLE9BQU8sRUFBRWtCO0FBRkosR0FBUDtBQUlEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDTyxTQUFTRyxzQkFBVCxDQUNMckIsT0FESyxFQUVMTCxNQUZLLEVBR0xNLE1BSEssRUFJeUI7QUFDOUIsU0FBT04sTUFBTSxDQUFDZCxJQUFQLElBQWUyQixnQkFBZ0IsQ0FBQ2MsY0FBakIsQ0FBZ0MzQixNQUFNLENBQUNkLElBQXZDLENBQWYsR0FDSDJCLGdCQUFnQixDQUFDYixNQUFNLENBQUNkLElBQVIsQ0FBaEIsQ0FBOEJtQixPQUE5QixFQUF1Q0wsTUFBdkMsRUFBK0NNLE1BQS9DLENBREcsR0FFSFEsY0FBYyxDQUFDVCxPQUFELEVBQVVMLE1BQVYsQ0FGbEI7QUFHRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBU3lCLG1CQUFULENBQTZCekIsTUFBN0IsRUFBcUNLLE9BQXJDLEVBQThDO0FBQzVDO0FBRDRDLE1BR3JDdUIsTUFIcUMsR0FHM0J2QixPQUgyQixDQUdyQ3VCLE1BSHFDO0FBQUEsZ0JBSTVCNUIsTUFKNEI7QUFBQSxNQUlyQ1AsS0FKcUMsV0FJckNBLEtBSnFDLEVBSzVDOztBQUNBLE1BQUlBLEtBQUosRUFBVztBQUNULFFBQU1vQyxXQUFXLEdBQUdELE1BQU0sQ0FBQ2pCLElBQVAsQ0FBWTtBQUFBLFVBQUVwRCxJQUFGLFNBQUVBLElBQUY7QUFBQSxVQUFRMkIsSUFBUixTQUFRQSxJQUFSO0FBQUEsYUFBa0IzQixJQUFJLEtBQUtrQyxLQUFLLENBQUNsQyxJQUFmLElBQXVCMkIsSUFBSSxLQUFLTyxLQUFLLENBQUNQLElBQXhEO0FBQUEsS0FBWixDQUFwQjtBQUVBYyxJQUFBQSxNQUFNLEdBQUc2QixXQUFXLG1DQUVYN0IsTUFGVztBQUdkUCxNQUFBQSxLQUFLLEVBQUVvQztBQUhPLE9BSVhDLGFBQWEsaUNBQUs5QixNQUFMO0FBQWFQLE1BQUFBLEtBQUssRUFBRW9DO0FBQXBCLFFBQWtDeEIsT0FBbEMsQ0FKRixJQU1oQkwsTUFOSjtBQU9EOztBQUVELFNBQU9BLE1BQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDTyxTQUFTK0IsY0FBVCxDQUNMQyxLQURLLEVBRUxDLFdBRkssRUFHa0M7QUFDdkMsTUFBTUMsV0FBVyxtQ0FDWkQsV0FEWTtBQUVmRSxJQUFBQSxTQUFTLEVBQUVILEtBQUssQ0FBQzlDLElBRkY7QUFHZlIsSUFBQUEsSUFBSSxFQUFFQyw2QkFBa0JDO0FBSFQsSUFBakI7O0FBTUEsVUFBUW9ELEtBQUssQ0FBQzlDLElBQWQ7QUFDRSxTQUFLckIsMkJBQWdCRSxJQUFyQjtBQUNBLFNBQUtGLDJCQUFnQkMsT0FBckI7QUFDRSw2Q0FDS29FLFdBREw7QUFFRTdDLFFBQUFBLEtBQUssRUFBRTRDLFdBQVcsQ0FBQzdDLE1BRnJCO0FBR0VGLFFBQUFBLElBQUksRUFBRXZCLHdCQUFhSyxLQUhyQjtBQUlFO0FBQ0FvRSxRQUFBQSxXQUFXLEVBQUUsQ0FBQ3pFLHdCQUFhSyxLQUFkLENBTGY7QUFNRTJCLFFBQUFBLEdBQUcsRUFBRTtBQU5QOztBQVNGLFNBQUs5QixxQ0FBTDtBQUNFO0FBQ0EsNkNBQ0txRSxXQURMO0FBRUVoRCxRQUFBQSxJQUFJLEVBQUV2Qix3QkFBYU8sTUFGckI7QUFHRW1CLFFBQUFBLEtBQUssRUFBRSxJQUhUO0FBSUVNLFFBQUFBLEdBQUcsRUFBRTtBQUpQOztBQU9GLFNBQUs5QiwyQkFBZ0J3RSxNQUFyQjtBQUNBLFNBQUt4RSwyQkFBZ0J5RSxJQUFyQjtBQUNFO0FBQ0EsNkNBQ0tKLFdBREw7QUFFRWhELFFBQUFBLElBQUksRUFBRXZCLHdCQUFhUSxXQUZyQjtBQUdFa0IsUUFBQUEsS0FBSyxFQUFFLEVBSFQ7QUFJRU0sUUFBQUEsR0FBRyxFQUFFO0FBSlA7O0FBT0YsU0FBSzlCLDJCQUFnQjBFLFNBQXJCO0FBQ0U7QUFDQSw2Q0FDS0wsV0FETDtBQUVFaEQsUUFBQUEsSUFBSSxFQUFFdkIsd0JBQWFDLFNBRnJCO0FBR0VjLFFBQUFBLElBQUksRUFBRUMsNkJBQWtCNkQsUUFIMUI7QUFJRS9ELFFBQUFBLFdBQVcsRUFBRSxJQUpmO0FBS0VZLFFBQUFBLEtBQUssRUFBRTZDLFdBQVcsQ0FBQzlDLE1BTHJCO0FBTUVPLFFBQUFBLEdBQUcsRUFBRTtBQU5QOztBQVNGO0FBQ0U7QUFDQSxhQUFPLEVBQVA7QUE1Q0o7QUE4Q0Q7O0FBRU0sSUFBTThDLHVCQUF1QixHQUFHLFNBQTFCQSx1QkFBMEIsQ0FBQy9CLEtBQUQsRUFBUVYsTUFBUixFQUFnQjBDLGFBQWhCLEVBQWtDO0FBQ3ZFLE1BQU1DLFdBQVcsR0FBR2pDLEtBQUssQ0FBQ2tDLG1CQUFOLENBQTBCRixhQUExQixDQUFwQjs7QUFFQSxVQUFRaEMsS0FBSyxDQUFDeEIsSUFBZDtBQUNFLFNBQUsyRCx1QkFBWUMsS0FBakI7QUFDQSxTQUFLRCx1QkFBWUUsSUFBakI7QUFDRSxhQUFPLFVBQUFDLElBQUksRUFBSTtBQUNiLFlBQU1DLEdBQUcsR0FBR04sV0FBVyxDQUFDSyxJQUFELENBQXZCO0FBQ0EsZUFBT0MsR0FBRyxDQUFDQyxLQUFKLENBQVVqRyxNQUFNLENBQUNrRyxRQUFqQixLQUE4QkMsV0FBVyxDQUFDSCxHQUFELEVBQU1qRCxNQUFNLENBQUNYLEtBQWIsQ0FBaEQ7QUFDRCxPQUhEOztBQUlGLFNBQUt3RCx1QkFBWVEsR0FBakI7QUFDQSxTQUFLUix1QkFBWVMsSUFBakI7QUFDRSxhQUFPLFVBQUFOLElBQUksRUFBSTtBQUNiLFlBQU1DLEdBQUcsR0FBR04sV0FBVyxDQUFDSyxJQUFELENBQXZCO0FBQ0EsZUFDRUMsR0FBRyxDQUFDQyxLQUFKLENBQVVqRyxNQUFNLENBQUNrRyxRQUFqQixLQUNBLENBQ0UsQ0FBQ0YsR0FBRyxDQUFDLENBQUQsQ0FBSixFQUFTQSxHQUFHLENBQUMsQ0FBRCxDQUFaLENBREYsRUFFRSxDQUFDQSxHQUFHLENBQUMsQ0FBRCxDQUFKLEVBQVNBLEdBQUcsQ0FBQyxDQUFELENBQVosQ0FGRixFQUdFQyxLQUhGLENBR1EsVUFBQUosS0FBSztBQUFBLGlCQUFJTSxXQUFXLENBQUNOLEtBQUQsRUFBUTlDLE1BQU0sQ0FBQ1gsS0FBZixDQUFmO0FBQUEsU0FIYixDQUZGO0FBT0QsT0FURDs7QUFVRixTQUFLd0QsdUJBQVlVLFNBQWpCO0FBQ0UsVUFBSTdDLEtBQUssQ0FBQzhDLGFBQU4sSUFBdUI5QyxLQUFLLENBQUM4QyxhQUFOLENBQW9CQyxTQUEvQyxFQUEwRDtBQUN4RCxlQUFPLFVBQUFULElBQUksRUFBSTtBQUNiO0FBQ0EsY0FBTVUsUUFBUSxHQUFHaEQsS0FBSyxDQUFDOEMsYUFBTixDQUFvQkMsU0FBcEIsQ0FBOEJULElBQUksQ0FBQ1csS0FBbkMsQ0FBakI7QUFDQSxpQkFBT0QsUUFBUSxJQUFJTixXQUFXLENBQUNNLFFBQUQsRUFBVzFELE1BQU0sQ0FBQ1gsS0FBbEIsQ0FBOUI7QUFDRCxTQUpEO0FBS0Q7O0FBQ0QsYUFBTyxVQUFBMkQsSUFBSSxFQUFJO0FBQ2IsWUFBTXpFLEVBQUUsR0FBR29FLFdBQVcsQ0FBQ0ssSUFBRCxDQUF0Qjs7QUFDQSxZQUFJLENBQUMscUJBQVV6RSxFQUFWLENBQUwsRUFBb0I7QUFDbEIsaUJBQU8sS0FBUDtBQUNEOztBQUNELFlBQU0wRSxHQUFHLEdBQUcsMEJBQVk7QUFBQzFFLFVBQUFBLEVBQUUsRUFBRkE7QUFBRCxTQUFaLENBQVo7QUFDQSxlQUFPMEUsR0FBRyxDQUFDQyxLQUFKLENBQVVqRyxNQUFNLENBQUNrRyxRQUFqQixLQUE4QkMsV0FBVyxDQUFDSCxHQUFELEVBQU1qRCxNQUFNLENBQUNYLEtBQWIsQ0FBaEQ7QUFDRCxPQVBEOztBQVFGLFNBQUt3RCx1QkFBWWUsT0FBakI7QUFDRSxhQUFPLFVBQUFaLElBQUksRUFBSTtBQUNiLGVBQU90QyxLQUFLLENBQUMwQyxXQUFOLENBQWtCSixJQUFsQixFQUF3QkEsSUFBSSxDQUFDVyxLQUE3QixFQUFvQzNELE1BQU0sQ0FBQ1gsS0FBM0MsQ0FBUDtBQUNELE9BRkQ7O0FBR0Y7QUFDRSxhQUFPO0FBQUEsZUFBTSxJQUFOO0FBQUEsT0FBUDtBQXhDSjtBQTBDRCxDQTdDTTtBQStDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBQ0E7QUFDTyxTQUFTd0UsaUJBQVQsQ0FDTDdCLEtBREssRUFFTDFFLE1BRkssRUFHTDBDLE1BSEssRUFJTE0sTUFKSyxFQUtMb0MsYUFMSyxFQU1XO0FBQ2hCO0FBQ0EsTUFBTW9CLGFBQWEsR0FBRzlCLEtBQUssR0FBR0EsS0FBSyxDQUFDOEIsYUFBVCxHQUF5QixVQUFBZCxJQUFJO0FBQUEsV0FBSSxJQUFKO0FBQUEsR0FBeEQ7O0FBQ0EsTUFBTWUsV0FBVyxHQUFHLFNBQWRBLFdBQWMsQ0FBQUMsQ0FBQztBQUFBLFdBQUksSUFBSjtBQUFBLEdBQXJCOztBQUVBLE1BQUloRSxNQUFNLENBQUN4QixPQUFQLEtBQW1CLEtBQXZCLEVBQThCO0FBQzVCLFdBQU91RixXQUFQO0FBQ0Q7O0FBRUQsVUFBUS9ELE1BQU0sQ0FBQ2QsSUFBZjtBQUNFLFNBQUt2Qix3QkFBYUssS0FBbEI7QUFDRSxhQUFPLFVBQUFnRixJQUFJO0FBQUEsZUFBSWlCLFNBQVMsQ0FBQ0gsYUFBYSxDQUFDZCxJQUFELENBQWQsRUFBc0JoRCxNQUFNLENBQUNYLEtBQTdCLENBQWI7QUFBQSxPQUFYOztBQUNGLFNBQUsxQix3QkFBYVEsV0FBbEI7QUFDRSxhQUFPLFVBQUE2RSxJQUFJO0FBQUEsZUFBSWhELE1BQU0sQ0FBQ1gsS0FBUCxDQUFhYyxRQUFiLENBQXNCMkQsYUFBYSxDQUFDZCxJQUFELENBQW5DLENBQUo7QUFBQSxPQUFYOztBQUNGLFNBQUtyRix3QkFBYU8sTUFBbEI7QUFDRSxhQUFPLFVBQUE4RSxJQUFJO0FBQUEsZUFBSWMsYUFBYSxDQUFDZCxJQUFELENBQWIsS0FBd0JoRCxNQUFNLENBQUNYLEtBQW5DO0FBQUEsT0FBWDs7QUFDRixTQUFLMUIsd0JBQWFDLFNBQWxCO0FBQ0UsVUFBSSxDQUFDb0UsS0FBTCxFQUFZO0FBQ1YsZUFBTytCLFdBQVA7QUFDRDs7QUFDRCxVQUFNRyxXQUFXLEdBQUcsd0JBQUlsQyxLQUFKLEVBQVcsQ0FBQyxhQUFELEVBQWdCLGFBQWhCLENBQVgsQ0FBcEI7QUFDQSxVQUFNbUMsUUFBUSxHQUFHQyxLQUFLLENBQUNDLE9BQU4sQ0FBY0gsV0FBZCxJQUNiLFVBQUFsQixJQUFJO0FBQUEsZUFBSWtCLFdBQVcsQ0FBQ2xCLElBQUksQ0FBQ1csS0FBTixDQUFmO0FBQUEsT0FEUyxHQUViLFVBQUFYLElBQUk7QUFBQSxlQUFJLGdDQUFnQmMsYUFBYSxDQUFDZCxJQUFELENBQTdCLEVBQXFDaEIsS0FBSyxDQUFDc0MsTUFBM0MsQ0FBSjtBQUFBLE9BRlI7QUFHQSxhQUFPLFVBQUF0QixJQUFJO0FBQUEsZUFBSWlCLFNBQVMsQ0FBQ0UsUUFBUSxDQUFDbkIsSUFBRCxDQUFULEVBQWlCaEQsTUFBTSxDQUFDWCxLQUF4QixDQUFiO0FBQUEsT0FBWDs7QUFDRixTQUFLMUIsd0JBQWFTLE9BQWxCO0FBQ0UsVUFBSSxDQUFDa0MsTUFBRCxJQUFXLENBQUNBLE1BQU0sQ0FBQ2lFLE1BQW5CLElBQTZCLENBQUN2RSxNQUFNLENBQUN4QyxPQUF6QyxFQUFrRDtBQUNoRCxlQUFPdUcsV0FBUDtBQUNEOztBQUNELFVBQU1TLG9CQUFvQixHQUFHeEUsTUFBTSxDQUFDeEMsT0FBUCxDQUMxQmlILEdBRDBCLENBQ3RCLFVBQUFsRyxFQUFFO0FBQUEsZUFBSStCLE1BQU0sQ0FBQ0ssSUFBUCxDQUFZLFVBQUFDLENBQUM7QUFBQSxpQkFBSUEsQ0FBQyxDQUFDckMsRUFBRixLQUFTQSxFQUFiO0FBQUEsU0FBYixDQUFKO0FBQUEsT0FEb0IsRUFFMUJ5QixNQUYwQixDQUVuQixVQUFBWSxDQUFDO0FBQUEsZUFBSUEsQ0FBQyxJQUFJQSxDQUFDLENBQUM4RCxNQUFGLENBQVNwSCxNQUFULEtBQW9CQSxNQUE3QjtBQUFBLE9BRmtCLEVBRzFCbUgsR0FIMEIsQ0FHdEIsVUFBQS9ELEtBQUs7QUFBQSxlQUFJK0IsdUJBQXVCLENBQUMvQixLQUFELEVBQVFWLE1BQVIsRUFBZ0IwQyxhQUFoQixDQUEzQjtBQUFBLE9BSGlCLENBQTdCO0FBS0EsYUFBTyxVQUFBTSxJQUFJO0FBQUEsZUFBSXdCLG9CQUFvQixDQUFDdEIsS0FBckIsQ0FBMkIsVUFBQXlCLFVBQVU7QUFBQSxpQkFBSUEsVUFBVSxDQUFDM0IsSUFBRCxDQUFkO0FBQUEsU0FBckMsQ0FBSjtBQUFBLE9BQVg7O0FBQ0Y7QUFDRSxhQUFPZSxXQUFQO0FBM0JKO0FBNkJEOztBQUVNLFNBQVNhLGtCQUFULENBQTRCdEgsTUFBNUIsRUFBOEU7QUFDbkYsU0FBT3dDLGdCQUFnQixDQUFDO0FBQUN4QyxJQUFBQSxNQUFNLEVBQU5BO0FBQUQsR0FBRCxDQUF2QjtBQUNEOztBQUVNLFNBQVN1SCx1QkFBVCxRQVlMbkMsYUFaSyxFQWFTO0FBQUEsTUFYWm9DLG9CQVdZLFNBWFpBLG9CQVdZO0FBQUEsTUFWWkMsVUFVWSxTQVZaQSxVQVVZO0FBQUEsTUFUWkMsV0FTWSxTQVRaQSxXQVNZO0FBQ2QsTUFBTUMsc0JBQWdDLEdBQUcsRUFBekM7QUFDQSxNQUFNQyxhQUF1QixHQUFHLEVBQWhDO0FBRUEsTUFBTUMsYUFBYSxHQUFHO0FBQUN4QixJQUFBQSxLQUFLLEVBQUUsQ0FBQyxDQUFUO0FBQVlqQixJQUFBQSxhQUFhLEVBQWJBO0FBQVosR0FBdEI7O0FBQ0EsTUFBTTBDLGdCQUFnQixHQUFHLFNBQW5CQSxnQkFBbUIsQ0FBQ3BGLE1BQUQ7QUFBQSxXQUFvQmdGLFdBQVcsQ0FBQ2hGLE1BQU0sQ0FBQ3pCLEVBQVIsQ0FBWCxDQUF1QjRHLGFBQXZCLENBQXBCO0FBQUEsR0FBekI7O0FBRUEsTUFBTUUsT0FBTyxHQUFHM0MsYUFBYSxDQUFDMkMsT0FBZCxFQUFoQjs7QUFDQSxPQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdELE9BQXBCLEVBQTZCLEVBQUVDLENBQS9CLEVBQWtDO0FBQ2hDSCxJQUFBQSxhQUFhLENBQUN4QixLQUFkLEdBQXNCMkIsQ0FBdEI7QUFFQSxRQUFNQyxjQUFjLEdBQUdULG9CQUFvQixJQUFJQSxvQkFBb0IsQ0FBQzVCLEtBQXJCLENBQTJCa0MsZ0JBQTNCLENBQS9DOztBQUNBLFFBQUlHLGNBQUosRUFBb0I7QUFDbEJOLE1BQUFBLHNCQUFzQixDQUFDTyxJQUF2QixDQUE0QkwsYUFBYSxDQUFDeEIsS0FBMUM7QUFDRDs7QUFFRCxRQUFNOEIsY0FBYyxHQUFHVixVQUFVLElBQUlBLFVBQVUsQ0FBQzdCLEtBQVgsQ0FBaUJrQyxnQkFBakIsQ0FBckM7O0FBQ0EsUUFBSUssY0FBSixFQUFvQjtBQUNsQlAsTUFBQUEsYUFBYSxDQUFDTSxJQUFkLENBQW1CTCxhQUFhLENBQUN4QixLQUFqQztBQUNEO0FBQ0Y7O0FBRUQseUNBQ01tQixvQkFBb0IsR0FBRztBQUFDRyxJQUFBQSxzQkFBc0IsRUFBdEJBO0FBQUQsR0FBSCxHQUE4QixFQUR4RCxHQUVNRixVQUFVLEdBQUc7QUFBQ0csSUFBQUEsYUFBYSxFQUFiQTtBQUFELEdBQUgsR0FBcUIsRUFGckM7QUFJRDtBQUVEO0FBQ0E7QUFDQTs7O0FBQ08sU0FBU1EsZUFBVCxDQUNMcEksTUFESyxFQUVMcUksT0FGSyxFQUlTO0FBQUEsTUFEZEMsR0FDYyx1RUFEVSxFQUNWO0FBQ2QsTUFBTUMsWUFBMEIsR0FBRztBQUNqQ0MsSUFBQUEsYUFBYSxFQUFFLEVBRGtCO0FBRWpDckgsSUFBQUEsV0FBVyxFQUFFLEVBRm9CO0FBR2pDc0gsSUFBQUEsR0FBRyxFQUFFLEVBSDRCO0FBSWpDcEcsSUFBQUEsR0FBRyxFQUFFO0FBSjRCLEdBQW5DO0FBT0FnRyxFQUFBQSxPQUFPLENBQUNLLE9BQVIsQ0FBZ0IsVUFBQUMsQ0FBQyxFQUFJO0FBQ25CLFFBQUl6RixrQkFBa0IsQ0FBQ3lGLENBQUMsQ0FBQy9HLElBQUgsRUFBUytHLENBQUMsQ0FBQzVHLEtBQVgsQ0FBbEIsSUFBdUMsb0JBQVE0RyxDQUFDLENBQUMzSSxNQUFWLEVBQWtCNkMsUUFBbEIsQ0FBMkI3QyxNQUEzQixDQUEzQyxFQUErRTtBQUM3RSxPQUFDMkksQ0FBQyxDQUFDeEgsV0FBRixJQUFpQm1ILEdBQUcsQ0FBQ00sWUFBckIsR0FDR0wsWUFBWSxDQUFDcEgsV0FEaEIsR0FFR29ILFlBQVksQ0FBQ0MsYUFGakIsRUFHRU4sSUFIRixDQUdPUyxDQUhQO0FBS0EsT0FBQ0EsQ0FBQyxDQUFDdEcsR0FBRixJQUFTLENBQUNpRyxHQUFHLENBQUNPLE9BQWQsR0FBd0JOLFlBQVksQ0FBQ2xHLEdBQXJDLEdBQTJDa0csWUFBWSxDQUFDRSxHQUF6RCxFQUE4RFAsSUFBOUQsQ0FBbUVTLENBQW5FO0FBQ0Q7QUFDRixHQVREO0FBV0EsU0FBT0osWUFBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBOzs7QUFDTyxTQUFTTyxXQUFULENBQ0xQLFlBREssRUFHVTtBQUFBLE1BRGZRLGVBQ2UsdUVBRHNCLEVBQ3RCO0FBQ2YsTUFBSUMsYUFBcUMsR0FBRyxFQUE1QztBQUVDQyxFQUFBQSxNQUFNLENBQUNDLE9BQVAsQ0FBZVgsWUFBZixDQUFELENBQXdERyxPQUF4RCxDQUFnRSxpQkFBcUI7QUFBQTtBQUFBLFFBQW5CUyxNQUFtQjtBQUFBLFFBQVhDLEtBQVc7O0FBQ25GQSxJQUFBQSxLQUFLLENBQUNWLE9BQU4sQ0FBYyxVQUFBaEcsTUFBTSxFQUFJO0FBQ3RCLFVBQU0yRyxTQUFpQixHQUFHLENBQUNOLGVBQWUsQ0FBQ0ksTUFBRCxDQUFmLElBQTJCLEVBQTVCLEVBQWdDOUYsSUFBaEMsQ0FDeEIsVUFBQ3NGLENBQUQ7QUFBQSxlQUFlQSxDQUFDLENBQUMxSCxFQUFGLEtBQVN5QixNQUFNLENBQUN6QixFQUEvQjtBQUFBLE9BRHdCLENBQTFCOztBQUlBLFVBQUksQ0FBQ29JLFNBQUwsRUFBZ0I7QUFDZDtBQUNBTCxRQUFBQSxhQUFhLEdBQUcsZ0JBQUksQ0FBQ0csTUFBRCxFQUFTekcsTUFBTSxDQUFDekIsRUFBaEIsQ0FBSixFQUF5QixPQUF6QixFQUFrQytILGFBQWxDLENBQWhCO0FBQ0QsT0FIRCxNQUdPO0FBQ0w7QUFDQSxTQUFDLE1BQUQsRUFBUyxPQUFULEVBQWtCLFFBQWxCLEVBQTRCTixPQUE1QixDQUFvQyxVQUFBWSxJQUFJLEVBQUk7QUFDMUMsY0FBSTVHLE1BQU0sQ0FBQzRHLElBQUQsQ0FBTixLQUFpQkQsU0FBUyxDQUFDQyxJQUFELENBQTlCLEVBQXNDO0FBQ3BDTixZQUFBQSxhQUFhLEdBQUcsZ0JBQUksQ0FBQ0csTUFBRCxFQUFTekcsTUFBTSxDQUFDekIsRUFBaEIsQ0FBSixZQUE0QnFJLElBQTVCLGVBQTRDTixhQUE1QyxDQUFoQjtBQUNEO0FBQ0YsU0FKRDtBQUtEO0FBQ0YsS0FoQkQ7QUFrQkEsS0FBQ0QsZUFBZSxDQUFDSSxNQUFELENBQWYsSUFBMkIsRUFBNUIsRUFBZ0NULE9BQWhDLENBQXdDLFVBQUNXLFNBQUQsRUFBdUI7QUFDN0Q7QUFDQSxVQUFJLENBQUNELEtBQUssQ0FBQy9GLElBQU4sQ0FBVyxVQUFBc0YsQ0FBQztBQUFBLGVBQUlBLENBQUMsQ0FBQzFILEVBQUYsS0FBU29JLFNBQVMsQ0FBQ3BJLEVBQXZCO0FBQUEsT0FBWixDQUFMLEVBQTZDO0FBQzNDK0gsUUFBQUEsYUFBYSxHQUFHLGdCQUFJLENBQUNHLE1BQUQsRUFBU0UsU0FBUyxDQUFDcEksRUFBbkIsQ0FBSixFQUE0QixTQUE1QixFQUF1QytILGFBQXZDLENBQWhCO0FBQ0Q7QUFDRixLQUxEO0FBTUQsR0F6QkQ7QUEyQkEseUNBQVc7QUFBQ1IsSUFBQUEsYUFBYSxFQUFFLElBQWhCO0FBQXNCckgsSUFBQUEsV0FBVyxFQUFFLElBQW5DO0FBQXlDc0gsSUFBQUEsR0FBRyxFQUFFLElBQTlDO0FBQW9EcEcsSUFBQUEsR0FBRyxFQUFFO0FBQXpELEdBQVgsR0FBOEUyRyxhQUE5RTtBQUNEO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBUzlFLHlCQUFULENBQW1DbkMsS0FBbkMsU0FBMkU7QUFBQSxNQUFmRCxNQUFlLFNBQWZBLE1BQWU7QUFBQSxNQUFQRixJQUFPLFNBQVBBLElBQU87O0FBQ2hGLE1BQUksQ0FBQ0EsSUFBTCxFQUFXO0FBQ1QsV0FBTyxLQUFQO0FBQ0QsR0FIK0UsQ0FJaEY7QUFDQTs7O0FBQ0EsTUFBSUEsSUFBSSxLQUFLdkIsd0JBQWFTLE9BQXRCLElBQWlDLENBQUNnQixNQUF0QyxFQUE4QztBQUM1QyxXQUFPLEtBQVA7QUFDRDs7QUFFRCxVQUFRRixJQUFSO0FBQ0UsU0FBS3ZCLHdCQUFhSyxLQUFsQjtBQUNBLFNBQUtMLHdCQUFhQyxTQUFsQjtBQUNFLFVBQUksQ0FBQ3dHLEtBQUssQ0FBQ0MsT0FBTixDQUFjaEYsS0FBZCxDQUFELElBQXlCQSxLQUFLLENBQUNrRixNQUFOLEtBQWlCLENBQTlDLEVBQWlEO0FBQy9DLGVBQU9uRixNQUFNLENBQUNxRixHQUFQLENBQVcsVUFBQVQsQ0FBQztBQUFBLGlCQUFJQSxDQUFKO0FBQUEsU0FBWixDQUFQO0FBQ0Q7O0FBRUQsYUFBTzNFLEtBQUssQ0FBQ29GLEdBQU4sQ0FBVSxVQUFDVCxDQUFELEVBQUlzQixDQUFKO0FBQUEsZUFBVyxtQ0FBbUJ0QixDQUFuQixLQUF5QkMsU0FBUyxDQUFDRCxDQUFELEVBQUk1RSxNQUFKLENBQWxDLEdBQWdENEUsQ0FBaEQsR0FBb0Q1RSxNQUFNLENBQUNrRyxDQUFELENBQXJFO0FBQUEsT0FBVixDQUFQOztBQUVGLFNBQUszSCx3QkFBYVEsV0FBbEI7QUFDRSxVQUFJLENBQUNpRyxLQUFLLENBQUNDLE9BQU4sQ0FBY2hGLEtBQWQsQ0FBTCxFQUEyQjtBQUN6QixlQUFPLEVBQVA7QUFDRDs7QUFDRCxVQUFNd0gsYUFBYSxHQUFHeEgsS0FBSyxDQUFDVyxNQUFOLENBQWEsVUFBQWdFLENBQUM7QUFBQSxlQUFJNUUsTUFBTSxDQUFDZSxRQUFQLENBQWdCNkQsQ0FBaEIsQ0FBSjtBQUFBLE9BQWQsQ0FBdEI7QUFDQSxhQUFPNkMsYUFBYSxDQUFDdEMsTUFBZCxHQUF1QnNDLGFBQXZCLEdBQXVDLEVBQTlDOztBQUVGLFNBQUtsSix3QkFBYU8sTUFBbEI7QUFDRSxhQUFPa0IsTUFBTSxDQUFDZSxRQUFQLENBQWdCZCxLQUFoQixJQUF5QkEsS0FBekIsR0FBaUMsSUFBeEM7O0FBQ0YsU0FBSzFCLHdCQUFhUyxPQUFsQjtBQUNFLGFBQU9pQixLQUFQOztBQUVGO0FBQ0UsYUFBTyxJQUFQO0FBdEJKO0FBd0JEO0FBQ0Q7O0FBRUE7QUFDQTtBQUNBOzs7QUFDTyxTQUFTeUgscUJBQVQsQ0FDTHBFLGFBREssRUFFTG9CLGFBRkssRUFHYTtBQUNsQixNQUFJMUUsTUFBd0IsR0FBRyxDQUFDLENBQUQsRUFBSSxDQUFKLENBQS9CO0FBQ0EsTUFBSXBDLElBQUksR0FBRyxHQUFYO0FBRUEsTUFBTWtILFdBQVcsR0FBR3hCLGFBQWEsQ0FBQ3FFLFFBQWQsQ0FBdUJqRCxhQUF2QixDQUFwQjs7QUFFQSxNQUFJcEIsYUFBYSxDQUFDMkMsT0FBZCxLQUEwQixDQUE5QixFQUFpQztBQUMvQmpHLElBQUFBLE1BQU0sR0FBRzRILFVBQVUsQ0FBQ0MsZUFBWCxDQUEyQi9DLFdBQTNCLENBQVQ7QUFDQSxRQUFNZ0QsSUFBSSxHQUFHOUgsTUFBTSxDQUFDLENBQUQsQ0FBTixHQUFZQSxNQUFNLENBQUMsQ0FBRCxDQUEvQixDQUYrQixDQUkvQjs7QUFDQSxRQUFJLENBQUM4SCxJQUFMLEVBQVc7QUFDVDlILE1BQUFBLE1BQU0sQ0FBQyxDQUFELENBQU4sR0FBWUEsTUFBTSxDQUFDLENBQUQsQ0FBTixHQUFZLENBQXhCO0FBQ0Q7O0FBRURwQyxJQUFBQSxJQUFJLEdBQUdtSyxrQkFBa0IsQ0FBQ0QsSUFBRCxDQUFsQixJQUE0QmxLLElBQW5DO0FBQ0FvQyxJQUFBQSxNQUFNLENBQUMsQ0FBRCxDQUFOLEdBQVlnSSxrQkFBa0IsQ0FBQ2hJLE1BQU0sQ0FBQyxDQUFELENBQVAsRUFBWXBDLElBQVosRUFBa0IsT0FBbEIsQ0FBOUI7QUFDQW9DLElBQUFBLE1BQU0sQ0FBQyxDQUFELENBQU4sR0FBWWdJLGtCQUFrQixDQUFDaEksTUFBTSxDQUFDLENBQUQsQ0FBUCxFQUFZcEMsSUFBWixFQUFrQixNQUFsQixDQUE5QjtBQUNEOztBQWxCaUIsc0JBb0JxQnFLLFlBQVksQ0FBQ2pJLE1BQUQsRUFBUzhFLFdBQVQsQ0FwQmpDO0FBQUEsTUFvQlgxRSxTQXBCVyxpQkFvQlhBLFNBcEJXO0FBQUEsTUFvQkE4SCxpQkFwQkEsaUJBb0JBQSxpQkFwQkE7O0FBc0JsQixTQUFPO0FBQUNsSSxJQUFBQSxNQUFNLEVBQU5BLE1BQUQ7QUFBU3BDLElBQUFBLElBQUksRUFBSkEsSUFBVDtBQUFld0MsSUFBQUEsU0FBUyxFQUFUQSxTQUFmO0FBQTBCOEgsSUFBQUEsaUJBQWlCLEVBQWpCQTtBQUExQixHQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7OztBQUNPLFNBQVNILGtCQUFULENBQTRCRCxJQUE1QixFQUFrRDtBQUN2REEsRUFBQUEsSUFBSSxHQUFHSyxJQUFJLENBQUNDLEdBQUwsQ0FBU04sSUFBVCxDQUFQOztBQUVBLE1BQUlBLElBQUksR0FBRyxHQUFYLEVBQWdCO0FBQ2QsV0FBTyxDQUFQO0FBQ0QsR0FGRCxNQUVPLElBQUlBLElBQUksR0FBRyxDQUFYLEVBQWM7QUFDbkIsV0FBTyxJQUFQO0FBQ0QsR0FGTSxNQUVBLElBQUlBLElBQUksR0FBRyxDQUFYLEVBQWM7QUFDbkIsV0FBTyxLQUFQO0FBQ0QsR0FUc0QsQ0FVdkQ7QUFDQTs7O0FBQ0EsTUFBTU8sQ0FBQyxHQUFHUCxJQUFJLEdBQUcsSUFBakIsQ0FadUQsQ0FhdkQ7O0FBRUEsTUFBTVEsZUFBZSxHQUFHRCxDQUFDLENBQUNFLGFBQUYsRUFBeEI7QUFDQSxNQUFNQyxRQUFRLEdBQUdDLFVBQVUsQ0FBQ0gsZUFBZSxDQUFDSSxLQUFoQixDQUFzQixHQUF0QixFQUEyQixDQUEzQixDQUFELENBQTNCLENBaEJ1RCxDQWtCdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxTQUFPLElBQUlDLGdCQUFKLENBQVksRUFBWixFQUFnQkMsR0FBaEIsQ0FBb0JKLFFBQXBCLEVBQThCSyxRQUE5QixFQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7OztBQUNPLFNBQVNDLHVCQUFULENBQ0x4RixhQURLLEVBRUxvQixhQUZLLEVBR2lCO0FBQ3RCO0FBQ0E7QUFFQSxNQUFNSSxXQUFXLEdBQUd4QixhQUFhLENBQUNxRSxRQUFkLENBQXVCakQsYUFBdkIsQ0FBcEI7QUFDQSxNQUFNMUUsTUFBTSxHQUFHNEgsVUFBVSxDQUFDQyxlQUFYLENBQTJCL0MsV0FBM0IsQ0FBZjtBQUNBLE1BQU1pRSxpQkFBaUIsR0FBR0MsMkJBQTJCLENBQUNoSixNQUFELENBQXJEO0FBRUEsTUFBSXBDLElBQUksR0FBRyxJQUFYO0FBRUEsTUFBTWtLLElBQUksR0FBRzlILE1BQU0sQ0FBQyxDQUFELENBQU4sR0FBWUEsTUFBTSxDQUFDLENBQUQsQ0FBL0IsQ0FWc0IsQ0FXdEI7O0FBQ0EsTUFBSSxDQUFDOEgsSUFBTCxFQUFXO0FBQ1Q5SCxJQUFBQSxNQUFNLENBQUMsQ0FBRCxDQUFOLEdBQVlBLE1BQU0sQ0FBQyxDQUFELENBQU4sR0FBWSxJQUF4QjtBQUNEOztBQUNELE1BQU1pSixLQUFLLEdBQUd2TCxnQkFBZ0IsQ0FBQzZELElBQWpCLENBQXNCLFVBQUFzRixDQUFDO0FBQUEsV0FBSUEsQ0FBQyxDQUFDbEosR0FBRixJQUFTbUssSUFBYjtBQUFBLEdBQXZCLENBQWQ7O0FBQ0EsTUFBSW1CLEtBQUosRUFBVztBQUNUckwsSUFBQUEsSUFBSSxHQUFHcUwsS0FBSyxDQUFDckwsSUFBYjtBQUNEOztBQWxCcUIsdUJBb0JpQnFLLFlBQVksQ0FBQ2pJLE1BQUQsRUFBUzhFLFdBQVQsQ0FwQjdCO0FBQUEsTUFvQmYxRSxTQXBCZSxrQkFvQmZBLFNBcEJlO0FBQUEsTUFvQko4SCxpQkFwQkksa0JBb0JKQSxpQkFwQkk7O0FBc0J0QixTQUFPO0FBQ0xsSSxJQUFBQSxNQUFNLEVBQU5BLE1BREs7QUFFTHBDLElBQUFBLElBQUksRUFBSkEsSUFGSztBQUdMa0gsSUFBQUEsV0FBVyxFQUFYQSxXQUhLO0FBSUwxRSxJQUFBQSxTQUFTLEVBQVRBLFNBSks7QUFLTDhILElBQUFBLGlCQUFpQixFQUFqQkEsaUJBTEs7QUFNTGEsSUFBQUEsaUJBQWlCLEVBQWpCQTtBQU5LLEdBQVA7QUFRRDs7QUFFTSxTQUFTRyxrQkFBVCxDQUNMbEosTUFESyxFQUVMOEUsV0FGSyxFQUdMcUUsSUFISyxFQUlXO0FBQ2hCLFNBQU8sMEJBQ0pDLFVBREksQ0FDTyxvQkFBTXBKLE1BQU0sQ0FBQyxDQUFELENBQVosRUFBaUJBLE1BQU0sQ0FBQyxDQUFELENBQXZCLEVBQTRCbUosSUFBNUIsQ0FEUCxFQUVKbkosTUFGSSxDQUVHQSxNQUZILEVBRVc4RSxXQUZYLEVBR0pPLEdBSEksQ0FHQSxVQUFBZ0UsR0FBRztBQUFBLFdBQUs7QUFDWEMsTUFBQUEsS0FBSyxFQUFFRCxHQUFHLENBQUNsRSxNQURBO0FBRVhrRSxNQUFBQSxHQUFHLEVBQUhBLEdBRlc7QUFHWEUsTUFBQUEsRUFBRSxFQUFFRixHQUFHLENBQUNFLEVBSEc7QUFJWEMsTUFBQUEsRUFBRSxFQUFFSCxHQUFHLENBQUNHO0FBSkcsS0FBTDtBQUFBLEdBSEgsQ0FBUDtBQVNEO0FBQ0Q7QUFDQTtBQUNBOzs7QUFDTyxTQUFTdkIsWUFBVCxDQUNMakksTUFESyxFQUVMOEUsV0FGSyxFQUcyRDtBQUNoRSxNQUFNMUUsU0FBUyxHQUFHOEksa0JBQWtCLENBQUNsSixNQUFELEVBQVM4RSxXQUFULEVBQXNCL0csYUFBdEIsQ0FBcEM7QUFDQSxNQUFNbUssaUJBQWlCLEdBQUdnQixrQkFBa0IsQ0FBQ2xKLE1BQUQsRUFBUzhFLFdBQVQsRUFBc0I5RyxxQkFBdEIsQ0FBNUM7QUFFQSxTQUFPO0FBQUNvQyxJQUFBQSxTQUFTLEVBQVRBLFNBQUQ7QUFBWThILElBQUFBLGlCQUFpQixFQUFqQkE7QUFBWixHQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDTyxTQUFTRixrQkFBVCxDQUE0QnlCLEdBQTVCLEVBQXlDN0wsSUFBekMsRUFBdUQ4TCxLQUF2RCxFQUF3RjtBQUM3RixNQUFJQSxLQUFLLEtBQUssT0FBZCxFQUF1QjtBQUNyQixXQUFPdkIsSUFBSSxDQUFDd0IsS0FBTCxDQUFXRixHQUFHLElBQUksSUFBSTdMLElBQVIsQ0FBZCxLQUFnQyxJQUFJQSxJQUFwQyxDQUFQO0FBQ0Q7O0FBRUQsU0FBT3VLLElBQUksQ0FBQ3lCLElBQUwsQ0FBVUgsR0FBRyxJQUFJLElBQUk3TCxJQUFSLENBQWIsS0FBK0IsSUFBSUEsSUFBbkMsQ0FBUDtBQUNEOztBQUVNLFNBQVNpSCxTQUFULENBQW1CNEUsR0FBbkIsRUFBNkJ6SixNQUE3QixFQUF3RDtBQUM3RCxNQUFJLENBQUNnRixLQUFLLENBQUNDLE9BQU4sQ0FBY2pGLE1BQWQsQ0FBTCxFQUE0QjtBQUMxQixXQUFPLEtBQVA7QUFDRDs7QUFFRCxTQUFPeUosR0FBRyxJQUFJekosTUFBTSxDQUFDLENBQUQsQ0FBYixJQUFvQnlKLEdBQUcsSUFBSXpKLE1BQU0sQ0FBQyxDQUFELENBQXhDO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sU0FBU2dFLFdBQVQsQ0FBcUJOLEtBQXJCLEVBQXNDMUUsT0FBdEMsRUFBNkQ7QUFDbEUsU0FBTywrQkFBYyxvQkFBVTBFLEtBQVYsQ0FBZCxFQUFnQzFFLE9BQWhDLENBQVA7QUFDRDs7QUFDTSxTQUFTZ0ssMkJBQVQsQ0FBcUNoSixNQUFyQyxFQUE4RTtBQUNuRixNQUFJLENBQUM2SixpQkFBaUIsQ0FBQzdKLE1BQUQsQ0FBdEIsRUFBZ0M7QUFDOUIsV0FBTyxJQUFQO0FBQ0Q7O0FBRUQsTUFBTThILElBQUksR0FBRzlILE1BQU0sQ0FBQyxDQUFELENBQU4sR0FBWUEsTUFBTSxDQUFDLENBQUQsQ0FBL0IsQ0FMbUYsQ0FPbkY7QUFDQTs7QUFDQSxTQUFPOEgsSUFBSSxHQUFHckssWUFBUCxHQUFzQixHQUF0QixHQUE0QnFLLElBQUksR0FBR3ZLLFdBQVAsR0FBcUIsTUFBckIsR0FBOEIsT0FBakU7QUFDRDtBQUVEO0FBQ0E7QUFDQTtBQUNBOzs7QUFDTyxTQUFTdU0sbUJBQVQsQ0FBNkJsSixNQUE3QixFQUFtRDtBQUN4RCxTQUNFLENBQUFBLE1BQU0sU0FBTixJQUFBQSxNQUFNLFdBQU4sWUFBQUEsTUFBTSxDQUFFZCxJQUFSLEtBQWdCa0YsS0FBSyxDQUFDQyxPQUFOLENBQWNyRSxNQUFkLGFBQWNBLE1BQWQsdUJBQWNBLE1BQU0sQ0FBRXpDLElBQXRCLENBQWhCLEtBQWdELENBQUF5QyxNQUFNLFNBQU4sSUFBQUEsTUFBTSxXQUFOLFlBQUFBLE1BQU0sQ0FBRXpDLElBQVIsQ0FBYWdILE1BQWIsTUFBdUJ2RSxNQUF2QixhQUF1QkEsTUFBdkIsdUJBQXVCQSxNQUFNLENBQUV4QyxPQUFSLENBQWdCK0csTUFBdkMsQ0FBaEQsQ0FERjtBQUdEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBQ0E7OztBQUNPLFNBQVMvRCxrQkFBVCxDQUE0QnRCLElBQTVCLEVBQWlERyxLQUFqRCxFQUFzRTtBQUMzRSxNQUFJLENBQUNILElBQUwsRUFBVztBQUNULFdBQU8sS0FBUDtBQUNEOztBQUNELFVBQVFBLElBQVI7QUFDRSxTQUFLdkIsd0JBQWFPLE1BQWxCO0FBQ0UsYUFBT21CLEtBQUssS0FBSyxJQUFWLElBQWtCQSxLQUFLLEtBQUssS0FBbkM7O0FBRUYsU0FBSzFCLHdCQUFhSyxLQUFsQjtBQUNBLFNBQUtMLHdCQUFhQyxTQUFsQjtBQUNFLGFBQU93RyxLQUFLLENBQUNDLE9BQU4sQ0FBY2hGLEtBQWQsS0FBd0JBLEtBQUssQ0FBQzZELEtBQU4sQ0FBWSxVQUFBaUcsQ0FBQztBQUFBLGVBQUlBLENBQUMsS0FBSyxJQUFOLElBQWMsQ0FBQ0MsS0FBSyxDQUFDRCxDQUFELENBQXhCO0FBQUEsT0FBYixDQUEvQjs7QUFFRixTQUFLeEwsd0JBQWFRLFdBQWxCO0FBQ0UsYUFBT2lHLEtBQUssQ0FBQ0MsT0FBTixDQUFjaEYsS0FBZCxLQUF3QmdLLE9BQU8sQ0FBQ2hLLEtBQUssQ0FBQ2tGLE1BQVAsQ0FBdEM7O0FBRUYsU0FBSzVHLHdCQUFhMkwsS0FBbEI7QUFDRSxhQUFPRCxPQUFPLENBQUNoSyxLQUFLLENBQUNrRixNQUFQLENBQWQ7O0FBRUYsU0FBSzVHLHdCQUFhUyxPQUFsQjtBQUNFLFVBQU1tTCxXQUFXLEdBQUcsd0JBQUlsSyxLQUFKLEVBQVcsQ0FBQyxVQUFELEVBQWEsYUFBYixDQUFYLENBQXBCO0FBQ0EsYUFBT2dLLE9BQU8sQ0FBQ2hLLEtBQUssSUFBSUEsS0FBSyxDQUFDZCxFQUFmLElBQXFCZ0wsV0FBdEIsQ0FBZDs7QUFFRjtBQUNFLGFBQU8sSUFBUDtBQW5CSjtBQXFCRDs7QUFFTSxTQUFTQyxvQkFBVCxDQUNMeEosTUFESyxFQUVMSyxPQUZLLEVBR3FDO0FBQzFDLE1BQUlMLE1BQU0sQ0FBQ1YsUUFBUCxLQUFvQkMsc0JBQVdDLFNBQS9CLElBQTRDLENBQUNRLE1BQU0sQ0FBQ1AsS0FBeEQsRUFBK0Q7QUFDN0Q7QUFDQSxXQUFPLEVBQVA7QUFDRDs7QUFKeUMsNEJBTWZPLE1BTmUsQ0FNbkNrRSxXQU5tQztBQUFBLE1BTW5DQSxXQU5tQyxvQ0FNckIsRUFOcUI7QUFBQSxNQU9uQ3pFLEtBUG1DLEdBTzFCTyxNQVAwQixDQU9uQ1AsS0FQbUM7QUFRMUMsTUFBTU4sUUFBUSxHQUFHa0IsT0FBTyxDQUFDb0osaUJBQVIsQ0FBMEJoSyxLQUFLLENBQUNsQyxJQUFoQyxDQUFqQjs7QUFDQSxNQUFJNEIsUUFBUSxHQUFHLENBQWYsRUFBa0I7QUFDaEJ1Syx3QkFBUUMsSUFBUixpQkFBc0JsSyxLQUFLLENBQUNsQyxJQUE1Qjs7QUFDQSxXQUFPO0FBQUNxTSxNQUFBQSxTQUFTLEVBQUUsRUFBWjtBQUFnQm5LLE1BQUFBLEtBQUssRUFBTEE7QUFBaEIsS0FBUDtBQUNELEdBWnlDLENBYzFDOzs7QUFDQSxNQUFNb0ssTUFBTSxHQUFHeEosT0FBTyxDQUFDcUMsYUFBUixDQUNaK0IsR0FEWSxDQUVYLFVBQUNxRixHQUFELEVBQU1DLFFBQU47QUFBQSxXQUFvQjtBQUNsQnRDLE1BQUFBLENBQUMsRUFBRXZELFdBQVcsQ0FBQzZGLFFBQUQsQ0FESTtBQUVsQkMsTUFBQUEsQ0FBQyxFQUFFRixHQUFHLENBQUNHLE9BQUosQ0FBWTlLLFFBQVo7QUFGZSxLQUFwQjtBQUFBLEdBRlcsRUFNWCxJQU5XLEVBUVphLE1BUlksQ0FRTDtBQUFBLFFBQUV5SCxDQUFGLFNBQUVBLENBQUY7QUFBQSxRQUFLdUMsQ0FBTCxTQUFLQSxDQUFMO0FBQUEsV0FBWS9NLE1BQU0sQ0FBQ2tHLFFBQVAsQ0FBZ0JzRSxDQUFoQixLQUFzQnhLLE1BQU0sQ0FBQ2tHLFFBQVAsQ0FBZ0I2RyxDQUFoQixDQUFsQztBQUFBLEdBUkssRUFTWkUsSUFUWSxDQVNQLFVBQUNDLENBQUQsRUFBSUMsQ0FBSjtBQUFBLFdBQVUsd0JBQVVELENBQUMsQ0FBQzFDLENBQVosRUFBZTJDLENBQUMsQ0FBQzNDLENBQWpCLENBQVY7QUFBQSxHQVRPLENBQWY7QUFXQSxNQUFNNEMsT0FBTyxHQUFHLHFCQUFPUixNQUFQLEVBQWUsVUFBQTdGLENBQUM7QUFBQSxXQUFJQSxDQUFDLENBQUNnRyxDQUFOO0FBQUEsR0FBaEIsQ0FBaEI7QUFDQSxNQUFNTSxPQUFPLEdBQUcsQ0FBQ1QsTUFBTSxDQUFDLENBQUQsQ0FBTixDQUFVcEMsQ0FBWCxFQUFjb0MsTUFBTSxDQUFDQSxNQUFNLENBQUN0RixNQUFQLEdBQWdCLENBQWpCLENBQU4sQ0FBMEJrRCxDQUF4QyxDQUFoQjtBQUVBLFNBQU87QUFBQ21DLElBQUFBLFNBQVMsRUFBRTtBQUFDQyxNQUFBQSxNQUFNLEVBQU5BLE1BQUQ7QUFBU1EsTUFBQUEsT0FBTyxFQUFQQSxPQUFUO0FBQWtCQyxNQUFBQSxPQUFPLEVBQVBBO0FBQWxCLEtBQVo7QUFBd0M3SyxJQUFBQSxLQUFLLEVBQUxBO0FBQXhDLEdBQVA7QUFDRDs7QUFFTSxTQUFTOEssd0JBQVQsQ0FBa0N2SyxNQUFsQyxFQUFpRTtBQUN0RSxNQUFNd0ssZUFBZ0YsR0FDcEZ4SyxNQUFNLENBQUNkLElBQVAsSUFBZXhCLGlCQUFpQixDQUFDc0MsTUFBTSxDQUFDZCxJQUFSLENBRGxDOztBQUVBLE1BQUksQ0FBQ3NMLGVBQUwsRUFBc0I7QUFDcEIsV0FBTyxJQUFQO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDeEssTUFBTSxDQUFDUCxLQUFaLEVBQW1CO0FBQ2pCLFdBQU8rSyxlQUFlLFdBQXRCO0FBQ0Q7O0FBRUQsU0FBT0EsZUFBZSxDQUFDeEssTUFBTSxDQUFDUCxLQUFQLENBQWFQLElBQWQsQ0FBZixJQUFzQyxJQUE3QztBQUNEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVN1TCxzQkFBVCxDQUlMQyxVQUpLLEVBS0xDLFFBTEssRUFNTGhGLE9BTkssRUFPTHJGLE1BUEssRUFRYztBQUNuQixNQUFNSixPQUFPLEdBQUcsb0JBQVF3SyxVQUFSLENBQWhCO0FBQ0EsU0FBT3hLLE9BQU8sQ0FBQzBLLE1BQVIsQ0FBZSxVQUFDQyxHQUFELEVBQU12TixNQUFOLEVBQWlCO0FBQ3JDLFFBQU13TixjQUFjLEdBQUcsQ0FBQ3hLLE1BQU0sSUFBSSxFQUFYLEVBQWVOLE1BQWYsQ0FBc0IsVUFBQVksQ0FBQztBQUFBLGFBQUlBLENBQUMsQ0FBQzhELE1BQUYsQ0FBU3BILE1BQVQsS0FBb0JBLE1BQXhCO0FBQUEsS0FBdkIsQ0FBdkI7QUFDQSxRQUFNeU4sY0FBYyxHQUFHcEYsT0FBTyxDQUFDM0YsTUFBUixDQUFlLFVBQUFnRSxDQUFDO0FBQUEsYUFBSWpFLGlCQUFpQixDQUFDaUUsQ0FBRCxFQUFJMUcsTUFBSixDQUFyQjtBQUFBLEtBQWhCLENBQXZCO0FBQ0EsUUFBTTBOLEtBQUssR0FBR0wsUUFBUSxDQUFDck4sTUFBRCxDQUF0QjtBQUVBLDJDQUNLdU4sR0FETCw0Q0FFR3ZOLE1BRkgsRUFFWTBOLEtBQUssQ0FBQ0MsV0FBTixDQUFrQkYsY0FBbEIsRUFBa0NELGNBQWxDLEVBQWtELEVBQWxELENBRlo7QUFJRCxHQVRNLEVBU0pILFFBVEksQ0FBUDtBQVVEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDTyxTQUFTdkosb0JBQVQsQ0FDTHBCLE1BREssRUFFTEssT0FGSyxFQUdMYyxTQUhLLEVBU0w7QUFBQSxNQUxBSCxrQkFLQSx1RUFMcUIsQ0FLckI7QUFBQSxNQUpBa0ssTUFJQTtBQUNBO0FBQ0EsTUFBTTdKLFdBQVcsR0FBRzZKLE1BQU0sSUFBSUEsTUFBTSxDQUFDdkosY0FBUCxDQUFzQixhQUF0QixDQUFWLEdBQWlEdUosTUFBTSxDQUFDN0osV0FBeEQsR0FBc0UsS0FBMUY7QUFFQSxNQUFNOEosVUFBVSxHQUFHOUssT0FBTyxDQUFDb0osaUJBQVIsQ0FBMEJ0SSxTQUExQixDQUFuQixDQUpBLENBS0E7O0FBQ0EsTUFBSWdLLFVBQVUsS0FBSyxDQUFDLENBQXBCLEVBQXVCO0FBQ3JCO0FBQ0EsV0FBTztBQUFDbkwsTUFBQUEsTUFBTSxFQUFFLElBQVQ7QUFBZUssTUFBQUEsT0FBTyxFQUFQQTtBQUFmLEtBQVA7QUFDRCxHQVRELENBV0E7OztBQUNBLE1BQU02QixXQUFXLEdBQUc3QixPQUFPLENBQUNtSixvQkFBUixDQUE2QnJJLFNBQTdCLENBQXBCOztBQUVBLE1BQU1pSyxTQUFTLG1DQUNUL0osV0FBVyxHQUFHZ0sscUJBQXFCLENBQUNyTCxNQUFELEVBQVNrQyxXQUFULENBQXhCLG1DQUFvRGxDLE1BQXBELEdBQStEa0MsV0FBL0QsQ0FERjtBQUViM0UsSUFBQUEsSUFBSSxFQUFFZ0osTUFBTSxDQUFDK0UsTUFBUCxxQ0FBa0Isb0JBQVF0TCxNQUFNLENBQUN6QyxJQUFmLENBQWxCLHdDQUEyQ3lELGtCQUEzQyxFQUFnRUcsU0FBaEUsRUFGTztBQUdiaEMsSUFBQUEsUUFBUSxFQUFFb0gsTUFBTSxDQUFDK0UsTUFBUCxxQ0FBa0Isb0JBQVF0TCxNQUFNLENBQUNiLFFBQWYsQ0FBbEIsd0NBQ1A2QixrQkFETyxFQUNjbUssVUFEZCxFQUhHO0FBTWI7QUFDQTdNLElBQUFBLE1BQU0sRUFBRTtBQVBLLElBQWY7O0FBVUEsU0FBTztBQUNMMEIsSUFBQUEsTUFBTSxFQUFFb0wsU0FESDtBQUVML0ssSUFBQUEsT0FBTyxFQUFQQTtBQUZLLEdBQVA7QUFJRDtBQUVEO0FBQ0E7QUFDQTs7QUFDQTs7O0FBQ08sU0FBU2dMLHFCQUFULENBQ0xyTCxNQURLLEVBRUxrQyxXQUZLLEVBRzhCO0FBQ25DLE1BQUksQ0FBQ2xDLE1BQUwsRUFBYTtBQUNYLFdBQU8sSUFBUDtBQUNEOztBQUVELE1BQUksQ0FBQ2tDLFdBQUwsRUFBa0I7QUFDaEIsV0FBT2xDLE1BQVA7QUFDRDs7QUFFRCxNQUFLQSxNQUFNLENBQUNtQyxTQUFQLElBQW9CbkMsTUFBTSxDQUFDbUMsU0FBUCxLQUFxQkQsV0FBVyxDQUFDQyxTQUF0RCxJQUFvRSxDQUFDRCxXQUFXLENBQUM5QyxNQUFyRixFQUE2RjtBQUMzRixXQUFPWSxNQUFQO0FBQ0Q7O0FBRUQsTUFBTXVMLGNBQWMsR0FBRyxDQUFDdkwsTUFBTSxDQUFDWixNQUFSLEdBQ25COEMsV0FBVyxDQUFDOUMsTUFETyxHQUVuQiw4Q0FBS1ksTUFBTSxDQUFDWixNQUFQLElBQWlCLEVBQXRCLHVDQUErQjhDLFdBQVcsQ0FBQzlDLE1BQVosSUFBc0IsRUFBckQsR0FBMEQ4SyxJQUExRCxDQUErRCxVQUFDQyxDQUFELEVBQUlDLENBQUo7QUFBQSxXQUFVRCxDQUFDLEdBQUdDLENBQWQ7QUFBQSxHQUEvRCxDQUZKOztBQUlBLE1BQU1nQixTQUFTLGlEQUNWcEwsTUFEVSxHQUVWa0MsV0FGVTtBQUdiOUMsSUFBQUEsTUFBTSxFQUFFLENBQUNtTSxjQUFjLENBQUMsQ0FBRCxDQUFmLEVBQW9CQSxjQUFjLENBQUNBLGNBQWMsQ0FBQ2hILE1BQWYsR0FBd0IsQ0FBekIsQ0FBbEM7QUFISyxJQUFmOztBQU1BLFVBQVFyQyxXQUFXLENBQUNDLFNBQXBCO0FBQ0UsU0FBS3RFLDJCQUFnQndFLE1BQXJCO0FBQ0EsU0FBS3hFLDJCQUFnQnlFLElBQXJCO0FBQ0UsNkNBQ0s4SSxTQURMO0FBRUVoTSxRQUFBQSxNQUFNLEVBQUUsdUJBQU9tTSxjQUFQLEVBQXVCckIsSUFBdkI7QUFGVjs7QUFLRixTQUFLck0sMkJBQWdCMEUsU0FBckI7QUFDRSxVQUFNdkYsSUFBSSxHQUNQZ0QsTUFBRCxDQUE0QmhELElBQTVCLEdBQW9Da0YsV0FBRCxDQUFzQ2xGLElBQXpFLEdBQ0tnRCxNQUFELENBQTRCaEQsSUFEaEMsR0FFS2tGLFdBQUQsQ0FBc0NsRixJQUg1QztBQUtBLDZDQUNLb08sU0FETDtBQUVFcE8sUUFBQUEsSUFBSSxFQUFKQTtBQUZGOztBQUlGLFNBQUthLDJCQUFnQkUsSUFBckI7QUFDQSxTQUFLRiwyQkFBZ0JDLE9BQXJCO0FBQ0E7QUFDRSxhQUFPc04sU0FBUDtBQXJCSjtBQXVCRDtBQUNEOztBQUVBO0FBQ0E7QUFDQTs7O0FBQ08sSUFBTUksb0JBQW9CLEdBQUcsU0FBdkJBLG9CQUF1QixDQUNsQ0MsT0FEa0MsRUFFbENDLFFBRmtDLEVBR2xDQyxVQUhrQztBQUFBLHlDQUsvQkYsT0FMK0I7QUFNbENsTixJQUFBQSxFQUFFLEVBQUVrTixPQUFPLENBQUNsTixFQU5zQjtBQU9sQ29OLElBQUFBLFVBQVUsZ0RBQ0xGLE9BQU8sQ0FBQ0UsVUFESCxHQUVMQSxVQUZLO0FBR1JELE1BQUFBLFFBQVEsRUFBUkE7QUFIUTtBQVB3QjtBQUFBLENBQTdCOzs7O0FBY0EsSUFBTUUsb0JBQW9CLEdBQUcsU0FBdkJBLG9CQUF1QixDQUFDM0YsQ0FBRDtBQUFBLFNBQTZCLHdCQUFJQSxDQUFKLEVBQU8sQ0FBQyxZQUFELEVBQWUsVUFBZixDQUFQLENBQTdCO0FBQUEsQ0FBN0I7QUFFUDtBQUNBO0FBQ0E7Ozs7O0FBQ08sU0FBUzRGLHFCQUFULENBRUx2TCxNQUZLLEVBRVFtTCxPQUZSLEVBRXlDO0FBQzlDLE1BQU1uTyxNQUFNLEdBQUdnRCxNQUFNLENBQUNtRSxHQUFQLENBQVcsVUFBQTdELENBQUM7QUFBQSxXQUFJQSxDQUFDLENBQUM4RCxNQUFGLENBQVNwSCxNQUFiO0FBQUEsR0FBWixFQUFpQzBDLE1BQWpDLENBQXdDOEwsNkJBQXhDLENBQWY7QUFDQSxNQUFNdE8sT0FBTyxHQUFHOEMsTUFBTSxDQUFDbUUsR0FBUCxDQUFXLFVBQUE3RCxDQUFDO0FBQUEsV0FBSUEsQ0FBQyxDQUFDckMsRUFBTjtBQUFBLEdBQVosQ0FBaEI7QUFDQSxNQUFNaEIsSUFBSSxHQUFHK0MsTUFBTSxDQUFDbUUsR0FBUCxDQUFXLFVBQUE3RCxDQUFDO0FBQUEsV0FBSUEsQ0FBQyxDQUFDOEQsTUFBRixDQUFTcUgsS0FBYjtBQUFBLEdBQVosQ0FBYjtBQUNBLE1BQU0vTCxNQUFNLEdBQUdGLGdCQUFnQixDQUFDO0FBQUN4QyxJQUFBQSxNQUFNLEVBQU5BO0FBQUQsR0FBRCxDQUEvQjtBQUNBLHlDQUNLMEMsTUFETDtBQUVFdkIsSUFBQUEsV0FBVyxFQUFFLElBRmY7QUFHRVMsSUFBQUEsSUFBSSxFQUFFdkIsd0JBQWFTLE9BSHJCO0FBSUViLElBQUFBLElBQUksRUFBSkEsSUFKRjtBQUtFQyxJQUFBQSxPQUFPLEVBQVBBLE9BTEY7QUFNRTZCLElBQUFBLEtBQUssRUFBRW1NLG9CQUFvQixDQUFDQyxPQUFELEVBQVV6TCxNQUFNLENBQUN6QixFQUFqQixFQUFxQjtBQUFDeU4sTUFBQUEsU0FBUyxFQUFFO0FBQVosS0FBckI7QUFON0I7QUFRRDtBQUVEO0FBQ0E7QUFDQTs7O0FBT08sU0FBU0MsZ0JBQVQsQ0FDTEMsS0FESyxFQUVMNU8sTUFGSyxFQUdGO0FBQ0gsTUFBTTZPLGNBQWMsR0FBR0QsS0FBSyxDQUFDdkcsT0FBTixDQUFjM0YsTUFBZCxDQUFxQixVQUFBaUcsQ0FBQztBQUFBLFdBQUlBLENBQUMsQ0FBQzNJLE1BQUYsQ0FBUzZDLFFBQVQsQ0FBa0I3QyxNQUFsQixDQUFKO0FBQUEsR0FBdEIsQ0FBdkI7QUFDQSxNQUFNK0MsT0FBTyxHQUFHNkwsS0FBSyxDQUFDdkIsUUFBTixDQUFlck4sTUFBZixDQUFoQjs7QUFFQSxNQUFJLENBQUMrQyxPQUFMLEVBQWM7QUFDWixXQUFPNkwsS0FBUDtBQUNEOztBQUVELE1BQU1FLGtCQUFrQixHQUFHL0wsT0FBTyxDQUFDZ00sY0FBUixDQUF1QkYsY0FBdkIsRUFBdUNELEtBQUssQ0FBQzVMLE1BQTdDLENBQTNCO0FBRUEsU0FBTyxnQkFBSSxDQUFDLFVBQUQsRUFBYWhELE1BQWIsQ0FBSixFQUEwQjhPLGtCQUExQixFQUE4Q0YsS0FBOUMsQ0FBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBOzs7QUFFTyxTQUFTSSw2QkFBVCxDQUtMSixLQUxLLEVBV0w7QUFBQSxNQUxBSyxpQkFLQSx1RUFMb0MsRUFLcEM7QUFDQTtBQUNBLE1BQU1DLFNBQWdCLEdBQUcsRUFBekI7QUFDQSxNQUFNak0sTUFBYSxHQUFHLEVBQXRCO0FBSEEsTUFJT29LLFFBSlAsR0FJbUJ1QixLQUpuQixDQUlPdkIsUUFKUDtBQUtBLE1BQUk4QixlQUFlLEdBQUc5QixRQUF0QixDQUxBLENBT0E7O0FBQ0E0QixFQUFBQSxpQkFBaUIsQ0FBQ3ZHLE9BQWxCLENBQTBCLFVBQUFoRyxNQUFNLEVBQUk7QUFDbEM7QUFDQSxRQUFNMEssVUFBVSxHQUFHLG9CQUFRMUssTUFBTSxDQUFDMUMsTUFBZixDQUFuQixDQUZrQyxDQUlsQzs7QUFDQSxRQUFJb04sVUFBVSxDQUFDeEgsS0FBWCxDQUFpQixVQUFBYyxDQUFDO0FBQUEsYUFBSTJHLFFBQVEsQ0FBQzNHLENBQUQsQ0FBUixJQUFlLENBQUNrSSxLQUFLLENBQUNRLGlCQUFOLENBQXdCMUksQ0FBeEIsQ0FBcEI7QUFBQSxLQUFsQixDQUFKLEVBQXVFO0FBQ3JFO0FBRHFFLCtCQUVDMEcsVUFBVSxDQUFDRSxNQUFYLENBS3BFLFVBQUNDLEdBQUQsRUFBTTVLLFNBQU4sRUFBb0I7QUFDbEIsWUFBTUksT0FBTyxHQUFHb00sZUFBZSxDQUFDeE0sU0FBRCxDQUEvQjtBQUNBLFlBQU1LLE1BQU0sR0FBRzRMLEtBQUssQ0FBQzVMLE1BQU4sQ0FBYU4sTUFBYixDQUFvQixVQUFBWSxDQUFDO0FBQUEsaUJBQUlBLENBQUMsQ0FBQzhELE1BQUYsQ0FBU3BILE1BQVQsS0FBb0IrQyxPQUFPLENBQUM5QixFQUFoQztBQUFBLFNBQXJCLENBQWY7O0FBRmtCLG9DQUd1Q21ELHNCQUFzQixDQUM3RW1KLEdBQUcsQ0FBQzhCLGlCQUFKLENBQXNCMU0sU0FBdEIsS0FBb0NJLE9BRHlDLEVBRTdFTCxNQUY2RSxFQUc3RU0sTUFINkUsQ0FIN0Q7QUFBQSxZQUdIZ0IsYUFIRyx5QkFHWHRCLE1BSFc7QUFBQSxZQUdxQnVCLGNBSHJCLHlCQUdZbEIsT0FIWjs7QUFTbEIsWUFBSWlCLGFBQUosRUFBbUI7QUFDakIsaURBQ0t1SixHQURMO0FBRUU7QUFDQTdLLFlBQUFBLE1BQU0sRUFBRTZLLEdBQUcsQ0FBQzdLLE1BQUosbUNBRUM2SyxHQUFHLENBQUM3SyxNQUZMLEdBSUNxTCxxQkFBcUIsQ0FBQ1IsR0FBRyxDQUFDN0ssTUFBTCxFQUFhc0IsYUFBYixDQUp0QixJQU1KQSxhQVROO0FBV0VzTCxZQUFBQSxlQUFlLGdEQUFNL0IsR0FBRyxDQUFDK0IsZUFBVixJQUEyQjNNLFNBQTNCLEVBWGpCO0FBYUUwTSxZQUFBQSxpQkFBaUIsa0NBQ1o5QixHQUFHLENBQUM4QixpQkFEUSw0Q0FFZDFNLFNBRmMsRUFFRnNCLGNBRkU7QUFibkI7QUFrQkQ7O0FBRUQsZUFBT3NKLEdBQVA7QUFDRCxPQXBDbUUsRUFxQ3BFO0FBQ0U3SyxRQUFBQSxNQUFNLEVBQUUsSUFEVjtBQUVFNE0sUUFBQUEsZUFBZSxFQUFFLEVBRm5CO0FBR0VELFFBQUFBLGlCQUFpQixFQUFFO0FBSHJCLE9BckNvRSxDQUZEO0FBQUEsVUFFdERFLGVBRnNELHNCQUU5RDdNLE1BRjhEO0FBQUEsVUFFckM0TSxlQUZxQyxzQkFFckNBLGVBRnFDO0FBQUEsVUFFcEJELGlCQUZvQixzQkFFcEJBLGlCQUZvQjs7QUE4Q3JFLFVBQUlFLGVBQWUsSUFBSSx5QkFBUW5DLFVBQVIsRUFBb0JrQyxlQUFwQixDQUF2QixFQUE2RDtBQUMzREosUUFBQUEsU0FBUyxDQUFDaEgsSUFBVixDQUFlcUgsZUFBZjtBQUNBSixRQUFBQSxlQUFlLG1DQUNWQSxlQURVLEdBRVZFLGlCQUZVLENBQWY7QUFJRCxPQU5ELE1BTU87QUFDTHBNLFFBQUFBLE1BQU0sQ0FBQ2lGLElBQVAsQ0FBWXhGLE1BQVo7QUFDRDtBQUNGLEtBdkRELE1BdURPO0FBQ0xPLE1BQUFBLE1BQU0sQ0FBQ2lGLElBQVAsQ0FBWXhGLE1BQVo7QUFDRDtBQUNGLEdBL0REO0FBaUVBLFNBQU87QUFBQ3dNLElBQUFBLFNBQVMsRUFBVEEsU0FBRDtBQUFZak0sSUFBQUEsTUFBTSxFQUFOQSxNQUFaO0FBQW9Ca00sSUFBQUEsZUFBZSxFQUFmQTtBQUFwQixHQUFQO0FBQ0Q7O0FBRU0sU0FBUzNLLGFBQVQsQ0FDTDlCLE1BREssRUFFTEssT0FGSyxFQUdxQztBQUMxQyxNQUFJTCxNQUFNLENBQUNWLFFBQVAsS0FBb0JDLHNCQUFXQyxTQUEvQixJQUE0QyxDQUFDUSxNQUFNLENBQUNQLEtBQXhELEVBQStEO0FBQzdEO0FBQ0EsV0FBTyxFQUFQO0FBQ0Q7O0FBSnlDLDZCQU1mTyxNQU5lLENBTW5Da0UsV0FObUM7QUFBQSxNQU1uQ0EsV0FObUMscUNBTXJCLEVBTnFCO0FBQUEsTUFPbkN6RSxLQVBtQyxHQU8xQk8sTUFQMEIsQ0FPbkNQLEtBUG1DO0FBUTFDLE1BQU1OLFFBQVEsR0FBR2tCLE9BQU8sQ0FBQ29KLGlCQUFSLENBQTBCaEssS0FBSyxDQUFDbEMsSUFBaEMsQ0FBakI7O0FBQ0EsTUFBSTRCLFFBQVEsR0FBRyxDQUFmLEVBQWtCO0FBQ2hCdUssd0JBQVFDLElBQVIsaUJBQXNCbEssS0FBSyxDQUFDbEMsSUFBNUI7O0FBQ0EsV0FBTztBQUFDcU0sTUFBQUEsU0FBUyxFQUFFLEVBQVo7QUFBZ0JuSyxNQUFBQSxLQUFLLEVBQUxBO0FBQWhCLEtBQVA7QUFDRCxHQVp5QyxDQWMxQzs7O0FBQ0EsTUFBTW9LLE1BQU0sR0FBR3hKLE9BQU8sQ0FBQ3FDLGFBQVIsQ0FDWitCLEdBRFksQ0FFWCxVQUFDcUYsR0FBRCxFQUFNQyxRQUFOO0FBQUEsV0FBb0I7QUFDbEJ0QyxNQUFBQSxDQUFDLEVBQUV2RCxXQUFXLENBQUM2RixRQUFELENBREk7QUFFbEJDLE1BQUFBLENBQUMsRUFBRUYsR0FBRyxDQUFDRyxPQUFKLENBQVk5SyxRQUFaO0FBRmUsS0FBcEI7QUFBQSxHQUZXLEVBTVgsSUFOVyxFQVFaYSxNQVJZLENBUUw7QUFBQSxRQUFFeUgsQ0FBRixTQUFFQSxDQUFGO0FBQUEsUUFBS3VDLENBQUwsU0FBS0EsQ0FBTDtBQUFBLFdBQVkvTSxNQUFNLENBQUNrRyxRQUFQLENBQWdCc0UsQ0FBaEIsS0FBc0J4SyxNQUFNLENBQUNrRyxRQUFQLENBQWdCNkcsQ0FBaEIsQ0FBbEM7QUFBQSxHQVJLLEVBU1pFLElBVFksQ0FTUCxVQUFDQyxDQUFELEVBQUlDLENBQUo7QUFBQSxXQUFVLHdCQUFVRCxDQUFDLENBQUMxQyxDQUFaLEVBQWUyQyxDQUFDLENBQUMzQyxDQUFqQixDQUFWO0FBQUEsR0FUTyxDQUFmO0FBV0EsTUFBTTRDLE9BQU8sR0FBRyxxQkFBT1IsTUFBUCxFQUFlLFVBQUE3RixDQUFDO0FBQUEsV0FBSUEsQ0FBQyxDQUFDZ0csQ0FBTjtBQUFBLEdBQWhCLENBQWhCO0FBQ0EsTUFBTU0sT0FBTyxHQUFHLENBQUNULE1BQU0sQ0FBQyxDQUFELENBQU4sQ0FBVXBDLENBQVgsRUFBY29DLE1BQU0sQ0FBQ0EsTUFBTSxDQUFDdEYsTUFBUCxHQUFnQixDQUFqQixDQUFOLENBQTBCa0QsQ0FBeEMsQ0FBaEI7QUFFQSxTQUFPO0FBQUNtQyxJQUFBQSxTQUFTLEVBQUU7QUFBQ0MsTUFBQUEsTUFBTSxFQUFOQSxNQUFEO0FBQVNRLE1BQUFBLE9BQU8sRUFBUEEsT0FBVDtBQUFrQkMsTUFBQUEsT0FBTyxFQUFQQTtBQUFsQixLQUFaO0FBQXdDN0ssSUFBQUEsS0FBSyxFQUFMQTtBQUF4QyxHQUFQO0FBQ0Q7QUFFRDtBQUNBO0FBQ0E7OztBQUNPLFNBQVNxTixlQUFULENBQXlCOU0sTUFBekIsRUFBa0Q7QUFBQTs7QUFBQSxNQUNoRHVJLElBRGdELEdBQ3hDdkksTUFEd0MsQ0FDaER1SSxJQURnRDtBQUV2RCxNQUFNN0ksUUFBUSx1QkFBR00sTUFBTSxDQUFDVixRQUFWLHFEQUFHLGlCQUFpQkksUUFBbEM7O0FBQ0EsTUFBSSxDQUFDQSxRQUFELElBQWEsQ0FBQzZJLElBQWQsSUFBc0JoQyxNQUFNLENBQUN3RyxJQUFQLENBQVl4RSxJQUFaLEVBQWtCaEUsTUFBbEIsS0FBNkIsQ0FBdkQsRUFBMEQ7QUFDeEQsV0FBTyxJQUFQO0FBQ0Q7O0FBQ0QsTUFBTXlJLE1BQU0sR0FBR3pHLE1BQU0sQ0FBQ3lHLE1BQVAsQ0FBY3pFLElBQWQsQ0FBZjtBQUNBLFNBQU95RSxNQUFNLENBQUMsQ0FBRCxDQUFOLEdBQVlBLE1BQU0sQ0FBQyxDQUFELENBQU4sQ0FBVXROLFFBQVYsQ0FBWixHQUFrQyxJQUF6QztBQUNEOztBQUVNLFNBQVN1SixpQkFBVCxDQUEyQjdKLE1BQTNCLEVBQW1DO0FBQ3hDLFNBQU9nRixLQUFLLENBQUNDLE9BQU4sQ0FBY2pGLE1BQWQsS0FBeUJBLE1BQU0sQ0FBQzhELEtBQVAsQ0FBYWpHLE1BQU0sQ0FBQ2tHLFFBQXBCLENBQWhDO0FBQ0Q7O0FBRU0sU0FBUzhKLDBCQUFULENBQW9DN04sTUFBcEMsRUFBa0Y7QUFDdkYsTUFBSSxDQUFDNkosaUJBQWlCLENBQUM3SixNQUFELENBQXRCLEVBQWdDO0FBQzlCLFdBQU84TixTQUFQO0FBQ0Q7O0FBRUQsTUFBTWhHLElBQUksR0FBRzlILE1BQU0sQ0FBQyxDQUFELENBQU4sR0FBWUEsTUFBTSxDQUFDLENBQUQsQ0FBL0I7QUFDQSxTQUFPOEgsSUFBSSxHQUFHdEssWUFBUCxHQUNILEdBREcsR0FFSHNLLElBQUksR0FBR3ZLLFdBQVAsR0FDQSxNQURBLEdBRUF1SyxJQUFJLEdBQUd4SyxZQUFQLEdBQ0EsSUFEQSxHQUVBLEtBTko7QUFPRDs7QUFFTSxTQUFTeVEsWUFBVCxDQUFzQm5OLE1BQXRCLEVBQStDO0FBQ3BELFNBQU9BLE1BQU0sQ0FBQ3RCLElBQVAsS0FBZ0JDLDZCQUFrQkMsSUFBekM7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCB7YXNjZW5kaW5nLCBleHRlbnQsIGhpc3RvZ3JhbSBhcyBkM0hpc3RvZ3JhbSwgdGlja3N9IGZyb20gJ2QzLWFycmF5JztcbmltcG9ydCBrZXlNaXJyb3IgZnJvbSAna2V5bWlycm9yJztcbmltcG9ydCBDb25zb2xlIGZyb20gJ2dsb2JhbC9jb25zb2xlJztcbmltcG9ydCBnZXQgZnJvbSAnbG9kYXNoLmdldCc7XG5pbXBvcnQgaXNFcXVhbCBmcm9tICdsb2Rhc2guaXNlcXVhbCc7XG5cbmltcG9ydCBib29sZWFuV2l0aGluIGZyb20gJ0B0dXJmL2Jvb2xlYW4td2l0aGluJztcbmltcG9ydCB7cG9pbnQgYXMgdHVyZlBvaW50fSBmcm9tICdAdHVyZi9oZWxwZXJzJztcbmltcG9ydCB7RGVjaW1hbH0gZnJvbSAnZGVjaW1hbC5qcyc7XG5pbXBvcnQge1xuICBBTExfRklFTERfVFlQRVMsXG4gIEZJTFRFUl9UWVBFUyxcbiAgQU5JTUFUSU9OX1dJTkRPVyxcbiAgUExPVF9UWVBFUyxcbiAgTEFZRVJfVFlQRVMsXG4gIEZJTFRFUl9WSUVXX1RZUEVTXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7VmlzU3RhdGV9IGZyb20gJ0BrZXBsZXIuZ2wvc2NoZW1hcyc7XG5pbXBvcnQgKiBhcyBTY2FsZVV0aWxzIGZyb20gJy4vZGF0YS1zY2FsZS11dGlscyc7XG5pbXBvcnQge2gzSXNWYWxpZH0gZnJvbSAnaDMtanMnO1xuXG5pbXBvcnQge1xuICBNaWxsaXNlY29uZCxcbiAgRW50cmllcyxcbiAgRmllbGQsXG4gIFBhcnNlZEZpbHRlcixcbiAgRmlsdGVyLFxuICBGaWx0ZXJCYXNlLFxuICBQb2x5Z29uRmlsdGVyLFxuICBGaWVsZERvbWFpbixcbiAgVGltZVJhbmdlRmllbGREb21haW4sXG4gIEhpc3RvZ3JhbUJpbixcbiAgRmVhdHVyZSxcbiAgRmVhdHVyZVZhbHVlLFxuICBMaW5lQ2hhcnQsXG4gIFRpbWVSYW5nZUZpbHRlcixcbiAgUmFuZ2VGaWVsZERvbWFpbixcbiAgRmlsdGVyRGF0YXNldE9wdCxcbiAgRmlsdGVyUmVjb3JkXG59IGZyb20gJ0BrZXBsZXIuZ2wvdHlwZXMnO1xuXG5pbXBvcnQge0RhdGFDb250YWluZXJJbnRlcmZhY2V9IGZyb20gJy4vZGF0YS1jb250YWluZXItaW50ZXJmYWNlJztcbmltcG9ydCB7Z2VuZXJhdGVIYXNoSWQsIHNldCwgdG9BcnJheX0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge25vdE51bGxvclVuZGVmaW5lZCwgdGltZVRvVW5peE1pbGxpLCB1bmlxdWV9IGZyb20gJy4vZGF0YS11dGlscyc7XG5pbXBvcnQge2dldENlbnRyb2lkfSBmcm9tICcuL2gzLXV0aWxzJztcblxuZXhwb3J0IGNvbnN0IGR1cmF0aW9uU2Vjb25kID0gMTAwMDtcbmV4cG9ydCBjb25zdCBkdXJhdGlvbk1pbnV0ZSA9IGR1cmF0aW9uU2Vjb25kICogNjA7XG5leHBvcnQgY29uc3QgZHVyYXRpb25Ib3VyID0gZHVyYXRpb25NaW51dGUgKiA2MDtcbmV4cG9ydCBjb25zdCBkdXJhdGlvbkRheSA9IGR1cmF0aW9uSG91ciAqIDI0O1xuZXhwb3J0IGNvbnN0IGR1cmF0aW9uV2VlayA9IGR1cmF0aW9uRGF5ICogNztcbmV4cG9ydCBjb25zdCBkdXJhdGlvblllYXIgPSBkdXJhdGlvbkRheSAqIDM2NTtcblxuZXhwb3J0IHR5cGUgRmlsdGVyUmVzdWx0ID0ge1xuICBmaWx0ZXJlZEluZGV4Rm9yRG9tYWluPzogbnVtYmVyW107XG4gIGZpbHRlcmVkSW5kZXg/OiBudW1iZXJbXTtcbn07XG5cbmV4cG9ydCB0eXBlIEZpbHRlckNoYW5nZWQgPSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBba2V5IGluIGtleW9mIEZpbHRlclJlY29yZF06IHtcbiAgICBba2V5OiBzdHJpbmddOiAnYWRkZWQnIHwgJ2RlbGV0ZWQnIHwgJ25hbWVfY2hhbmdlZCcgfCAndmFsdWVfY2hhbmdlZCcgfCAnZGF0YUlkX2NoYW5nZWQnO1xuICB9IHwgbnVsbDtcbn07XG5cbmV4cG9ydCB0eXBlIGRhdGFWYWx1ZUFjY2Vzc29yID0gKGRhdGE6IHtpbmRleDogbnVtYmVyfSkgPT4gbnVtYmVyIHwgbnVsbDtcblxuZXhwb3J0IGNvbnN0IFRpbWVzdGFtcFN0ZXBNYXAgPSBbXG4gIHttYXg6IDEsIHN0ZXA6IDAuMDV9LFxuICB7bWF4OiAxMCwgc3RlcDogMC4xfSxcbiAge21heDogMTAwLCBzdGVwOiAxfSxcbiAge21heDogNTAwLCBzdGVwOiA1fSxcbiAge21heDogMTAwMCwgc3RlcDogMTB9LFxuICB7bWF4OiA1MDAwLCBzdGVwOiA1MH0sXG4gIHttYXg6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSwgc3RlcDogMTAwMH1cbl07XG5cbmV4cG9ydCBjb25zdCBoaXN0b2dyYW1CaW5zID0gMzA7XG5leHBvcnQgY29uc3QgZW5sYXJnZWRIaXN0b2dyYW1CaW5zID0gMTAwO1xuXG5leHBvcnQgY29uc3QgRklMVEVSX1VQREFURVJfUFJPUFMgPSBrZXlNaXJyb3Ioe1xuICBkYXRhSWQ6IG51bGwsXG4gIG5hbWU6IG51bGwsXG4gIGxheWVySWQ6IG51bGxcbn0pO1xuXG5leHBvcnQgY29uc3QgTElNSVRFRF9GSUxURVJfRUZGRUNUX1BST1BTID0ga2V5TWlycm9yKHtcbiAgW0ZJTFRFUl9VUERBVEVSX1BST1BTLm5hbWVdOiBudWxsXG59KTtcbi8qKlxuICogTWF4IG51bWJlciBvZiBmaWx0ZXIgdmFsdWUgYnVmZmVycyB0aGF0IGRlY2suZ2wgcHJvdmlkZXNcbiAqL1xuXG5jb25zdCBTdXBwb3J0ZWRQbG90VHlwZSA9IHtcbiAgW0ZJTFRFUl9UWVBFUy50aW1lUmFuZ2VdOiB7XG4gICAgZGVmYXVsdDogJ2hpc3RvZ3JhbScsXG4gICAgW0FMTF9GSUVMRF9UWVBFUy5pbnRlZ2VyXTogJ2xpbmVDaGFydCcsXG4gICAgW0FMTF9GSUVMRF9UWVBFUy5yZWFsXTogJ2xpbmVDaGFydCdcbiAgfSxcbiAgW0ZJTFRFUl9UWVBFUy5yYW5nZV06IHtcbiAgICBkZWZhdWx0OiAnaGlzdG9ncmFtJyxcbiAgICBbQUxMX0ZJRUxEX1RZUEVTLmludGVnZXJdOiAnbGluZUNoYXJ0JyxcbiAgICBbQUxMX0ZJRUxEX1RZUEVTLnJlYWxdOiAnbGluZUNoYXJ0J1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgRklMVEVSX0NPTVBPTkVOVFMgPSB7XG4gIFtGSUxURVJfVFlQRVMuc2VsZWN0XTogJ1NpbmdsZVNlbGVjdEZpbHRlcicsXG4gIFtGSUxURVJfVFlQRVMubXVsdGlTZWxlY3RdOiAnTXVsdGlTZWxlY3RGaWx0ZXInLFxuICBbRklMVEVSX1RZUEVTLnRpbWVSYW5nZV06ICdUaW1lUmFuZ2VGaWx0ZXInLFxuICBbRklMVEVSX1RZUEVTLnJhbmdlXTogJ1JhbmdlRmlsdGVyJyxcbiAgW0ZJTFRFUl9UWVBFUy5wb2x5Z29uXTogJ1BvbHlnb25GaWx0ZXInXG59O1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9GSUxURVJfU1RSVUNUVVJFID0ge1xuICBkYXRhSWQ6IFtdLCAvLyBbc3RyaW5nXVxuICBmcmVlemU6IGZhbHNlLFxuICBpZDogbnVsbCxcbiAgZW5hYmxlZDogdHJ1ZSxcblxuICAvLyB0aW1lIHJhbmdlIGZpbHRlciBzcGVjaWZpY1xuICBmaXhlZERvbWFpbjogZmFsc2UsXG4gIHZpZXc6IEZJTFRFUl9WSUVXX1RZUEVTLnNpZGUsXG4gIGlzQW5pbWF0aW5nOiBmYWxzZSxcbiAgYW5pbWF0aW9uV2luZG93OiBBTklNQVRJT05fV0lORE9XLmZyZWUsXG4gIHNwZWVkOiAxLFxuXG4gIC8vIGZpZWxkIHNwZWNpZmljXG4gIG5hbWU6IFtdLCAvLyBzdHJpbmdcbiAgdHlwZTogbnVsbCxcbiAgZmllbGRJZHg6IFtdLCAvLyBbaW50ZWdlcl1cbiAgZG9tYWluOiBudWxsLFxuICB2YWx1ZTogbnVsbCxcblxuICAvLyBwbG90XG4gIHBsb3RUeXBlOiBQTE9UX1RZUEVTLmhpc3RvZ3JhbSxcbiAgeUF4aXM6IG51bGwsXG4gIGludGVydmFsOiBudWxsLFxuXG4gIC8vIG1vZGVcbiAgZ3B1OiBmYWxzZVxufTtcblxuZXhwb3J0IGNvbnN0IEZJTFRFUl9JRF9MRU5HVEggPSA0O1xuXG5leHBvcnQgY29uc3QgTEFZRVJfRklMVEVSUyA9IFtGSUxURVJfVFlQRVMucG9seWdvbl07XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgZmlsdGVyIHdpdGggYSBkYXRhc2V0IGlkIGFzIGRhdGFJZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdEZpbHRlcih7XG4gIGRhdGFJZCxcbiAgaWRcbn06IHtcbiAgZGF0YUlkPzogc3RyaW5nIHwgbnVsbCB8IHN0cmluZ1tdO1xuICBpZD86IHN0cmluZztcbn0gPSB7fSk6IEZpbHRlckJhc2U8TGluZUNoYXJ0PiB7XG4gIHJldHVybiB7XG4gICAgLi4uREVGQVVMVF9GSUxURVJfU1RSVUNUVVJFLFxuICAgIC8vIHN0b3JlIGl0IGFzIGRhdGFJZCBhbmQgaXQgY291bGQgYmUgb25lIG9yIG1hbnlcbiAgICBkYXRhSWQ6IGRhdGFJZCA/IHRvQXJyYXkoZGF0YUlkKSA6IFtdLFxuICAgIGlkOiBpZCB8fCBnZW5lcmF0ZUhhc2hJZChGSUxURVJfSURfTEVOR1RIKVxuICB9O1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgZmlsdGVyIGlzIHZhbGlkIGJhc2VkIG9uIHRoZSBnaXZlbiBkYXRhSWRcbiAqIEBwYXJhbSAgZmlsdGVyIHRvIHZhbGlkYXRlXG4gKiBAcGFyYW0gIGRhdGFzZXRJZCBpZCB0byB2YWxpZGF0ZSBmaWx0ZXIgYWdhaW5zdFxuICogQHJldHVybiB0cnVlIGlmIGEgZmlsdGVyIGlzIHZhbGlkLCBmYWxzZSBvdGhlcndpc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZEFwcGx5RmlsdGVyKGZpbHRlcjogRmlsdGVyLCBkYXRhc2V0SWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBkYXRhSWRzID0gdG9BcnJheShmaWx0ZXIuZGF0YUlkKTtcbiAgcmV0dXJuIGRhdGFJZHMuaW5jbHVkZXMoZGF0YXNldElkKSAmJiBmaWx0ZXIudmFsdWUgIT09IG51bGw7XG59XG5cbmludGVyZmFjZSBLZXBsZXJUYWJsZU1vZGVsPEssIEw+IHtcbiAgaWQ6IHN0cmluZztcbiAgZ2V0Q29sdW1uRmllbGRJZHgoY29sdW1uTmFtZTogc3RyaW5nKTogbnVtYmVyO1xuICBmaWx0ZXJUYWJsZShmaWx0ZXJzOiBGaWx0ZXJbXSwgbGF5ZXJzOiBMW10sIG9wdD86IEZpbHRlckRhdGFzZXRPcHQpOiBLO1xuICBnZXRDb2x1bW5GaWx0ZXJQcm9wcyhjb2x1bW5OYW1lOiBzdHJpbmcpOiBGaWVsZFsnZmlsdGVyUHJvcHMnXSB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2U7XG4gIGZpbHRlclRhYmxlQ1BVKGZpbHRlcnM6IEZpbHRlcltdLCBsYXllcnM6IExbXSk6IEs7XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGFuZCBtb2RpZmllcyBwb2x5Z29uIGZpbHRlciBzdHJ1Y3R1cmVcbiAqIEBwYXJhbSBkYXRhc2V0XG4gKiBAcGFyYW0gZmlsdGVyXG4gKiBAcGFyYW0gbGF5ZXJzXG4gKiBAcmV0dXJuIC0ge2ZpbHRlciwgZGF0YXNldH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUG9seWdvbkZpbHRlcjxLIGV4dGVuZHMgS2VwbGVyVGFibGVNb2RlbDxLLCBMPiwgTCBleHRlbmRzIHtpZDogc3RyaW5nfT4oXG4gIGRhdGFzZXQ6IEssXG4gIGZpbHRlcjogUG9seWdvbkZpbHRlcixcbiAgbGF5ZXJzOiBMW11cbik6IHtmaWx0ZXI6IFBvbHlnb25GaWx0ZXIgfCBudWxsOyBkYXRhc2V0OiBLfSB7XG4gIGNvbnN0IGZhaWxlZCA9IHtkYXRhc2V0LCBmaWx0ZXI6IG51bGx9O1xuICBjb25zdCB7dmFsdWUsIGxheWVySWQsIHR5cGUsIGRhdGFJZH0gPSBmaWx0ZXI7XG5cbiAgaWYgKCFsYXllcklkIHx8ICFpc1ZhbGlkRmlsdGVyVmFsdWUodHlwZSwgdmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhaWxlZDtcbiAgfVxuXG4gIGNvbnN0IGlzVmFsaWREYXRhc2V0ID0gZGF0YUlkLmluY2x1ZGVzKGRhdGFzZXQuaWQpO1xuXG4gIGlmICghaXNWYWxpZERhdGFzZXQpIHtcbiAgICByZXR1cm4gZmFpbGVkO1xuICB9XG5cbiAgY29uc3QgbGF5ZXIgPSBsYXllcnMuZmluZChsID0+IGxheWVySWQuaW5jbHVkZXMobC5pZCkpO1xuXG4gIGlmICghbGF5ZXIpIHtcbiAgICByZXR1cm4gZmFpbGVkO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmaWx0ZXI6IHtcbiAgICAgIC4uLmZpbHRlcixcbiAgICAgIGZyZWV6ZTogdHJ1ZSxcbiAgICAgIGZpZWxkSWR4OiBbXVxuICAgIH0sXG4gICAgZGF0YXNldFxuICB9O1xufVxuXG4vKipcbiAqIEN1c3RvbSBmaWx0ZXIgdmFsaWRhdG9yc1xuICovXG5jb25zdCBmaWx0ZXJWYWxpZGF0b3JzID0ge1xuICBbRklMVEVSX1RZUEVTLnBvbHlnb25dOiB2YWxpZGF0ZVBvbHlnb25GaWx0ZXJcbn07XG5cbi8qKlxuICogRGVmYXVsdCB2YWxpZGF0ZSBmaWx0ZXIgZnVuY3Rpb25cbiAqIEBwYXJhbSBkYXRhc2V0XG4gKiBAcGFyYW0gZmlsdGVyXG4gKiBAcmV0dXJuIC0ge2ZpbHRlciwgZGF0YXNldH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlRmlsdGVyPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPihcbiAgZGF0YXNldDogSyxcbiAgZmlsdGVyOiBQYXJzZWRGaWx0ZXJcbik6IHtmaWx0ZXI6IEZpbHRlciB8IG51bGw7IGRhdGFzZXQ6IEt9IHtcbiAgLy8gbWF0Y2ggZmlsdGVyLmRhdGFJZFxuICBjb25zdCBmYWlsZWQgPSB7ZGF0YXNldCwgZmlsdGVyOiBudWxsfTtcbiAgY29uc3QgZmlsdGVyRGF0YUlkID0gdG9BcnJheShmaWx0ZXIuZGF0YUlkKTtcblxuICBjb25zdCBmaWx0ZXJEYXRhc2V0SW5kZXggPSBmaWx0ZXJEYXRhSWQuaW5kZXhPZihkYXRhc2V0LmlkKTtcbiAgaWYgKGZpbHRlckRhdGFzZXRJbmRleCA8IDAgfHwgIXRvQXJyYXkoZmlsdGVyLm5hbWUpW2ZpbHRlckRhdGFzZXRJbmRleF0pIHtcbiAgICAvLyB0aGUgY3VycmVudCBmaWx0ZXIgaXMgbm90IG1hcHBlZCBhZ2FpbnN0IHRoZSBjdXJyZW50IGRhdGFzZXRcbiAgICByZXR1cm4gZmFpbGVkO1xuICB9XG5cbiAgY29uc3QgaW5pdGlhbGl6ZUZpbHRlcjogRmlsdGVyID0ge1xuICAgIC4uLmdldERlZmF1bHRGaWx0ZXIoe2RhdGFJZDogZmlsdGVyLmRhdGFJZH0pLFxuICAgIC4uLmZpbHRlcixcbiAgICBkYXRhSWQ6IGZpbHRlckRhdGFJZCxcbiAgICBuYW1lOiB0b0FycmF5KGZpbHRlci5uYW1lKVxuICB9O1xuXG4gIGNvbnN0IGZpZWxkTmFtZSA9IGluaXRpYWxpemVGaWx0ZXIubmFtZVtmaWx0ZXJEYXRhc2V0SW5kZXhdO1xuICBjb25zdCB7ZmlsdGVyOiB1cGRhdGVkRmlsdGVyLCBkYXRhc2V0OiB1cGRhdGVkRGF0YXNldH0gPSBhcHBseUZpbHRlckZpZWxkTmFtZShcbiAgICBpbml0aWFsaXplRmlsdGVyLFxuICAgIGRhdGFzZXQsXG4gICAgZmllbGROYW1lLFxuICAgIGZpbHRlckRhdGFzZXRJbmRleCxcbiAgICB7bWVyZ2VEb21haW46IHRydWV9XG4gICk7XG5cbiAgaWYgKCF1cGRhdGVkRmlsdGVyKSB7XG4gICAgcmV0dXJuIGZhaWxlZDtcbiAgfVxuXG4gIHVwZGF0ZWRGaWx0ZXIudmFsdWUgPSBhZGp1c3RWYWx1ZVRvRmlsdGVyRG9tYWluKGZpbHRlci52YWx1ZSwgdXBkYXRlZEZpbHRlcik7XG4gIHVwZGF0ZWRGaWx0ZXIudmlldyA9IGZpbHRlci52aWV3ID8/IHVwZGF0ZWRGaWx0ZXIudmlldztcblxuICBpZiAodXBkYXRlZEZpbHRlci52YWx1ZSA9PT0gbnVsbCkge1xuICAgIC8vIGNhbm5vdCBhZGp1c3Qgc2F2ZWQgdmFsdWUgdG8gZmlsdGVyXG4gICAgcmV0dXJuIGZhaWxlZDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZmlsdGVyOiB2YWxpZGF0ZUZpbHRlcllBeGlzKHVwZGF0ZWRGaWx0ZXIsIHVwZGF0ZWREYXRhc2V0KSxcbiAgICBkYXRhc2V0OiB1cGRhdGVkRGF0YXNldFxuICB9O1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIHNhdmVkIGZpbHRlciBjb25maWcgd2l0aCBuZXcgZGF0YSxcbiAqIGNhbGN1bGF0ZSBkb21haW4gYW5kIGZpZWxkSWR4IGJhc2VkIG5ldyBmaWVsZHMgYW5kIGRhdGFcbiAqXG4gKiBAcGFyYW0gZGF0YXNldFxuICogQHBhcmFtIGZpbHRlciAtIGZpbHRlciB0byBiZSB2YWxpZGF0ZVxuICogQHBhcmFtIGxheWVycyAtIGxheWVyc1xuICogQHJldHVybiB2YWxpZGF0ZWQgZmlsdGVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUZpbHRlcldpdGhEYXRhPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPihcbiAgZGF0YXNldDogSyxcbiAgZmlsdGVyOiBQYXJzZWRGaWx0ZXIsXG4gIGxheWVyczogTFtdXG4pOiB7ZmlsdGVyOiBGaWx0ZXI7IGRhdGFzZXQ6IEt9IHtcbiAgcmV0dXJuIGZpbHRlci50eXBlICYmIGZpbHRlclZhbGlkYXRvcnMuaGFzT3duUHJvcGVydHkoZmlsdGVyLnR5cGUpXG4gICAgPyBmaWx0ZXJWYWxpZGF0b3JzW2ZpbHRlci50eXBlXShkYXRhc2V0LCBmaWx0ZXIsIGxheWVycylcbiAgICA6IHZhbGlkYXRlRmlsdGVyKGRhdGFzZXQsIGZpbHRlcik7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgWUF4aXNcbiAqIEBwYXJhbSBmaWx0ZXJcbiAqIEBwYXJhbSBkYXRhc2V0XG4gKiBAcmV0dXJuIHsqfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZpbHRlcllBeGlzKGZpbHRlciwgZGF0YXNldCkge1xuICAvLyBUT0RPOiB2YWxpZGF0ZSB5QXhpcyBhZ2FpbnN0IG90aGVyIGRhdGFzZXRzXG5cbiAgY29uc3Qge2ZpZWxkc30gPSBkYXRhc2V0O1xuICBjb25zdCB7eUF4aXN9ID0gZmlsdGVyO1xuICAvLyBUT0RPOiB2YWxpZGF0ZSB5QXhpcyBhZ2FpbnN0IG90aGVyIGRhdGFzZXRzXG4gIGlmICh5QXhpcykge1xuICAgIGNvbnN0IG1hdGNoZWRBeGlzID0gZmllbGRzLmZpbmQoKHtuYW1lLCB0eXBlfSkgPT4gbmFtZSA9PT0geUF4aXMubmFtZSAmJiB0eXBlID09PSB5QXhpcy50eXBlKTtcblxuICAgIGZpbHRlciA9IG1hdGNoZWRBeGlzXG4gICAgICA/IHtcbiAgICAgICAgICAuLi5maWx0ZXIsXG4gICAgICAgICAgeUF4aXM6IG1hdGNoZWRBeGlzLFxuICAgICAgICAgIC4uLmdldEZpbHRlclBsb3Qoey4uLmZpbHRlciwgeUF4aXM6IG1hdGNoZWRBeGlzfSwgZGF0YXNldClcbiAgICAgICAgfVxuICAgICAgOiBmaWx0ZXI7XG4gIH1cblxuICByZXR1cm4gZmlsdGVyO1xufVxuXG4vKipcbiAqIEdldCBkZWZhdWx0IGZpbHRlciBwcm9wIGJhc2VkIG9uIGZpZWxkIHR5cGVcbiAqXG4gKiBAcGFyYW0gZmllbGRcbiAqIEBwYXJhbSBmaWVsZERvbWFpblxuICogQHJldHVybnMgZGVmYXVsdCBmaWx0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbHRlclByb3BzKFxuICBmaWVsZDogRmllbGQsXG4gIGZpZWxkRG9tYWluOiBGaWVsZERvbWFpblxuKTogUGFydGlhbDxGaWx0ZXI+ICYge2ZpZWxkVHlwZTogc3RyaW5nfSB7XG4gIGNvbnN0IGZpbHRlclByb3BzID0ge1xuICAgIC4uLmZpZWxkRG9tYWluLFxuICAgIGZpZWxkVHlwZTogZmllbGQudHlwZSxcbiAgICB2aWV3OiBGSUxURVJfVklFV19UWVBFUy5zaWRlXG4gIH07XG5cbiAgc3dpdGNoIChmaWVsZC50eXBlKSB7XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMucmVhbDpcbiAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5pbnRlZ2VyOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uZmlsdGVyUHJvcHMsXG4gICAgICAgIHZhbHVlOiBmaWVsZERvbWFpbi5kb21haW4sXG4gICAgICAgIHR5cGU6IEZJTFRFUl9UWVBFUy5yYW5nZSxcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICB0eXBlT3B0aW9uczogW0ZJTFRFUl9UWVBFUy5yYW5nZV0sXG4gICAgICAgIGdwdTogdHJ1ZVxuICAgICAgfTtcblxuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLmJvb2xlYW46XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5maWx0ZXJQcm9wcyxcbiAgICAgICAgdHlwZTogRklMVEVSX1RZUEVTLnNlbGVjdCxcbiAgICAgICAgdmFsdWU6IHRydWUsXG4gICAgICAgIGdwdTogZmFsc2VcbiAgICAgIH07XG5cbiAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5zdHJpbmc6XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuZGF0ZTpcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmZpbHRlclByb3BzLFxuICAgICAgICB0eXBlOiBGSUxURVJfVFlQRVMubXVsdGlTZWxlY3QsXG4gICAgICAgIHZhbHVlOiBbXSxcbiAgICAgICAgZ3B1OiBmYWxzZVxuICAgICAgfTtcblxuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLnRpbWVzdGFtcDpcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmZpbHRlclByb3BzLFxuICAgICAgICB0eXBlOiBGSUxURVJfVFlQRVMudGltZVJhbmdlLFxuICAgICAgICB2aWV3OiBGSUxURVJfVklFV19UWVBFUy5lbmxhcmdlZCxcbiAgICAgICAgZml4ZWREb21haW46IHRydWUsXG4gICAgICAgIHZhbHVlOiBmaWx0ZXJQcm9wcy5kb21haW4sXG4gICAgICAgIGdwdTogdHJ1ZVxuICAgICAgfTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGdldFBvbHlnb25GaWx0ZXJGdW5jdG9yID0gKGxheWVyLCBmaWx0ZXIsIGRhdGFDb250YWluZXIpID0+IHtcbiAgY29uc3QgZ2V0UG9zaXRpb24gPSBsYXllci5nZXRQb3NpdGlvbkFjY2Vzc29yKGRhdGFDb250YWluZXIpO1xuXG4gIHN3aXRjaCAobGF5ZXIudHlwZSkge1xuICAgIGNhc2UgTEFZRVJfVFlQRVMucG9pbnQ6XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5pY29uOlxuICAgICAgcmV0dXJuIGRhdGEgPT4ge1xuICAgICAgICBjb25zdCBwb3MgPSBnZXRQb3NpdGlvbihkYXRhKTtcbiAgICAgICAgcmV0dXJuIHBvcy5ldmVyeShOdW1iZXIuaXNGaW5pdGUpICYmIGlzSW5Qb2x5Z29uKHBvcywgZmlsdGVyLnZhbHVlKTtcbiAgICAgIH07XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5hcmM6XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5saW5lOlxuICAgICAgcmV0dXJuIGRhdGEgPT4ge1xuICAgICAgICBjb25zdCBwb3MgPSBnZXRQb3NpdGlvbihkYXRhKTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBwb3MuZXZlcnkoTnVtYmVyLmlzRmluaXRlKSAmJlxuICAgICAgICAgIFtcbiAgICAgICAgICAgIFtwb3NbMF0sIHBvc1sxXV0sXG4gICAgICAgICAgICBbcG9zWzNdLCBwb3NbNF1dXG4gICAgICAgICAgXS5ldmVyeShwb2ludCA9PiBpc0luUG9seWdvbihwb2ludCwgZmlsdGVyLnZhbHVlKSlcbiAgICAgICAgKTtcbiAgICAgIH07XG4gICAgY2FzZSBMQVlFUl9UWVBFUy5oZXhhZ29uSWQ6XG4gICAgICBpZiAobGF5ZXIuZGF0YVRvRmVhdHVyZSAmJiBsYXllci5kYXRhVG9GZWF0dXJlLmNlbnRyb2lkcykge1xuICAgICAgICByZXR1cm4gZGF0YSA9PiB7XG4gICAgICAgICAgLy8gbnVsbCBvciBnZXRDZW50cm9pZCh7aWR9KVxuICAgICAgICAgIGNvbnN0IGNlbnRyb2lkID0gbGF5ZXIuZGF0YVRvRmVhdHVyZS5jZW50cm9pZHNbZGF0YS5pbmRleF07XG4gICAgICAgICAgcmV0dXJuIGNlbnRyb2lkICYmIGlzSW5Qb2x5Z29uKGNlbnRyb2lkLCBmaWx0ZXIudmFsdWUpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGEgPT4ge1xuICAgICAgICBjb25zdCBpZCA9IGdldFBvc2l0aW9uKGRhdGEpO1xuICAgICAgICBpZiAoIWgzSXNWYWxpZChpZCkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcG9zID0gZ2V0Q2VudHJvaWQoe2lkfSk7XG4gICAgICAgIHJldHVybiBwb3MuZXZlcnkoTnVtYmVyLmlzRmluaXRlKSAmJiBpc0luUG9seWdvbihwb3MsIGZpbHRlci52YWx1ZSk7XG4gICAgICB9O1xuICAgIGNhc2UgTEFZRVJfVFlQRVMuZ2VvanNvbjpcbiAgICAgIHJldHVybiBkYXRhID0+IHtcbiAgICAgICAgcmV0dXJuIGxheWVyLmlzSW5Qb2x5Z29uKGRhdGEsIGRhdGEuaW5kZXgsIGZpbHRlci52YWx1ZSk7XG4gICAgICB9O1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gKCkgPT4gdHJ1ZTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0gcGFyYW0gQW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIHJvdyByZWNvcmQuXG4gKiBAcGFyYW0gcGFyYW0uaW5kZXggSW5kZXggb2YgdGhlIHJvdyBpbiBkYXRhIGNvbnRhaW5lci5cbiAqIEByZXR1cm5zIFJldHVybnMgdHJ1ZSB0byBrZWVwIHRoZSBlbGVtZW50LCBvciBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbnR5cGUgZmlsdGVyRnVuY3Rpb24gPSAoZGF0YToge2luZGV4OiBudW1iZXJ9KSA9PiBib29sZWFuO1xuLyoqXG4gKiBAcGFyYW0gZmllbGQgZGF0YXNldCBGaWVsZFxuICogQHBhcmFtIGRhdGFJZCBEYXRhc2V0IGlkXG4gKiBAcGFyYW0gZmlsdGVyIEZpbHRlciBvYmplY3RcbiAqIEBwYXJhbSBsYXllcnMgbGlzdCBvZiBsYXllcnMgdG8gZmlsdGVyIHVwb25cbiAqIEBwYXJhbSBkYXRhQ29udGFpbmVyIERhdGEgY29udGFpbmVyXG4gKiBAcmV0dXJuIGZpbHRlckZ1bmN0aW9uXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRGaWx0ZXJGdW5jdGlvbjxMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbH07IGlkOiBzdHJpbmd9PihcbiAgZmllbGQ6IEZpZWxkIHwgbnVsbCxcbiAgZGF0YUlkOiBzdHJpbmcsXG4gIGZpbHRlcjogRmlsdGVyLFxuICBsYXllcnM6IExbXSxcbiAgZGF0YUNvbnRhaW5lcjogRGF0YUNvbnRhaW5lckludGVyZmFjZVxuKTogZmlsdGVyRnVuY3Rpb24ge1xuICAvLyBmaWVsZCBjb3VsZCBiZSBudWxsIGluIHBvbHlnb24gZmlsdGVyXG4gIGNvbnN0IHZhbHVlQWNjZXNzb3IgPSBmaWVsZCA/IGZpZWxkLnZhbHVlQWNjZXNzb3IgOiBkYXRhID0+IG51bGw7XG4gIGNvbnN0IGRlZmF1bHRGdW5jID0gZCA9PiB0cnVlO1xuXG4gIGlmIChmaWx0ZXIuZW5hYmxlZCA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gZGVmYXVsdEZ1bmM7XG4gIH1cblxuICBzd2l0Y2ggKGZpbHRlci50eXBlKSB7XG4gICAgY2FzZSBGSUxURVJfVFlQRVMucmFuZ2U6XG4gICAgICByZXR1cm4gZGF0YSA9PiBpc0luUmFuZ2UodmFsdWVBY2Nlc3NvcihkYXRhKSwgZmlsdGVyLnZhbHVlKTtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5tdWx0aVNlbGVjdDpcbiAgICAgIHJldHVybiBkYXRhID0+IGZpbHRlci52YWx1ZS5pbmNsdWRlcyh2YWx1ZUFjY2Vzc29yKGRhdGEpKTtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5zZWxlY3Q6XG4gICAgICByZXR1cm4gZGF0YSA9PiB2YWx1ZUFjY2Vzc29yKGRhdGEpID09PSBmaWx0ZXIudmFsdWU7XG4gICAgY2FzZSBGSUxURVJfVFlQRVMudGltZVJhbmdlOlxuICAgICAgaWYgKCFmaWVsZCkge1xuICAgICAgICByZXR1cm4gZGVmYXVsdEZ1bmM7XG4gICAgICB9XG4gICAgICBjb25zdCBtYXBwZWRWYWx1ZSA9IGdldChmaWVsZCwgWydmaWx0ZXJQcm9wcycsICdtYXBwZWRWYWx1ZSddKTtcbiAgICAgIGNvbnN0IGFjY2Vzc29yID0gQXJyYXkuaXNBcnJheShtYXBwZWRWYWx1ZSlcbiAgICAgICAgPyBkYXRhID0+IG1hcHBlZFZhbHVlW2RhdGEuaW5kZXhdXG4gICAgICAgIDogZGF0YSA9PiB0aW1lVG9Vbml4TWlsbGkodmFsdWVBY2Nlc3NvcihkYXRhKSwgZmllbGQuZm9ybWF0KTtcbiAgICAgIHJldHVybiBkYXRhID0+IGlzSW5SYW5nZShhY2Nlc3NvcihkYXRhKSwgZmlsdGVyLnZhbHVlKTtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5wb2x5Z29uOlxuICAgICAgaWYgKCFsYXllcnMgfHwgIWxheWVycy5sZW5ndGggfHwgIWZpbHRlci5sYXllcklkKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0RnVuYztcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxheWVyRmlsdGVyRnVuY3Rpb25zID0gZmlsdGVyLmxheWVySWRcbiAgICAgICAgLm1hcChpZCA9PiBsYXllcnMuZmluZChsID0+IGwuaWQgPT09IGlkKSlcbiAgICAgICAgLmZpbHRlcihsID0+IGwgJiYgbC5jb25maWcuZGF0YUlkID09PSBkYXRhSWQpXG4gICAgICAgIC5tYXAobGF5ZXIgPT4gZ2V0UG9seWdvbkZpbHRlckZ1bmN0b3IobGF5ZXIsIGZpbHRlciwgZGF0YUNvbnRhaW5lcikpO1xuXG4gICAgICByZXR1cm4gZGF0YSA9PiBsYXllckZpbHRlckZ1bmN0aW9ucy5ldmVyeShmaWx0ZXJGdW5jID0+IGZpbHRlckZ1bmMoZGF0YSkpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZGVmYXVsdEZ1bmM7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUZpbHRlckRhdGFJZChkYXRhSWQ6IHN0cmluZyB8IHN0cmluZ1tdKTogRmlsdGVyQmFzZTxMaW5lQ2hhcnQ+IHtcbiAgcmV0dXJuIGdldERlZmF1bHRGaWx0ZXIoe2RhdGFJZH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyRGF0YUJ5RmlsdGVyVHlwZXMoXG4gIHtcbiAgICBkeW5hbWljRG9tYWluRmlsdGVycyxcbiAgICBjcHVGaWx0ZXJzLFxuICAgIGZpbHRlckZ1bmNzXG4gIH06IHtcbiAgICBkeW5hbWljRG9tYWluRmlsdGVyczogRmlsdGVyW10gfCBudWxsO1xuICAgIGNwdUZpbHRlcnM6IEZpbHRlcltdIHwgbnVsbDtcbiAgICBmaWx0ZXJGdW5jczoge1xuICAgICAgW2tleTogc3RyaW5nXTogZmlsdGVyRnVuY3Rpb247XG4gICAgfTtcbiAgfSxcbiAgZGF0YUNvbnRhaW5lcjogRGF0YUNvbnRhaW5lckludGVyZmFjZVxuKTogRmlsdGVyUmVzdWx0IHtcbiAgY29uc3QgZmlsdGVyZWRJbmRleEZvckRvbWFpbjogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgZmlsdGVyZWRJbmRleDogbnVtYmVyW10gPSBbXTtcblxuICBjb25zdCBmaWx0ZXJDb250ZXh0ID0ge2luZGV4OiAtMSwgZGF0YUNvbnRhaW5lcn07XG4gIGNvbnN0IGZpbHRlckZ1bmNDYWxsZXIgPSAoZmlsdGVyOiBGaWx0ZXIpID0+IGZpbHRlckZ1bmNzW2ZpbHRlci5pZF0oZmlsdGVyQ29udGV4dCk7XG5cbiAgY29uc3QgbnVtUm93cyA9IGRhdGFDb250YWluZXIubnVtUm93cygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bVJvd3M7ICsraSkge1xuICAgIGZpbHRlckNvbnRleHQuaW5kZXggPSBpO1xuXG4gICAgY29uc3QgbWF0Y2hGb3JEb21haW4gPSBkeW5hbWljRG9tYWluRmlsdGVycyAmJiBkeW5hbWljRG9tYWluRmlsdGVycy5ldmVyeShmaWx0ZXJGdW5jQ2FsbGVyKTtcbiAgICBpZiAobWF0Y2hGb3JEb21haW4pIHtcbiAgICAgIGZpbHRlcmVkSW5kZXhGb3JEb21haW4ucHVzaChmaWx0ZXJDb250ZXh0LmluZGV4KTtcbiAgICB9XG5cbiAgICBjb25zdCBtYXRjaEZvclJlbmRlciA9IGNwdUZpbHRlcnMgJiYgY3B1RmlsdGVycy5ldmVyeShmaWx0ZXJGdW5jQ2FsbGVyKTtcbiAgICBpZiAobWF0Y2hGb3JSZW5kZXIpIHtcbiAgICAgIGZpbHRlcmVkSW5kZXgucHVzaChmaWx0ZXJDb250ZXh0LmluZGV4KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLihkeW5hbWljRG9tYWluRmlsdGVycyA/IHtmaWx0ZXJlZEluZGV4Rm9yRG9tYWlufSA6IHt9KSxcbiAgICAuLi4oY3B1RmlsdGVycyA/IHtmaWx0ZXJlZEluZGV4fSA6IHt9KVxuICB9O1xufVxuXG4vKipcbiAqIEdldCBhIHJlY29yZCBvZiBmaWx0ZXJzIGJhc2VkIG9uIGRvbWFpbiB0eXBlIGFuZCBncHUgLyBjcHVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbHRlclJlY29yZChcbiAgZGF0YUlkOiBzdHJpbmcsXG4gIGZpbHRlcnM6IEZpbHRlcltdLFxuICBvcHQ6IEZpbHRlckRhdGFzZXRPcHQgPSB7fVxuKTogRmlsdGVyUmVjb3JkIHtcbiAgY29uc3QgZmlsdGVyUmVjb3JkOiBGaWx0ZXJSZWNvcmQgPSB7XG4gICAgZHluYW1pY0RvbWFpbjogW10sXG4gICAgZml4ZWREb21haW46IFtdLFxuICAgIGNwdTogW10sXG4gICAgZ3B1OiBbXVxuICB9O1xuXG4gIGZpbHRlcnMuZm9yRWFjaChmID0+IHtcbiAgICBpZiAoaXNWYWxpZEZpbHRlclZhbHVlKGYudHlwZSwgZi52YWx1ZSkgJiYgdG9BcnJheShmLmRhdGFJZCkuaW5jbHVkZXMoZGF0YUlkKSkge1xuICAgICAgKGYuZml4ZWREb21haW4gfHwgb3B0Lmlnbm9yZURvbWFpblxuICAgICAgICA/IGZpbHRlclJlY29yZC5maXhlZERvbWFpblxuICAgICAgICA6IGZpbHRlclJlY29yZC5keW5hbWljRG9tYWluXG4gICAgICApLnB1c2goZik7XG5cbiAgICAgIChmLmdwdSAmJiAhb3B0LmNwdU9ubHkgPyBmaWx0ZXJSZWNvcmQuZ3B1IDogZmlsdGVyUmVjb3JkLmNwdSkucHVzaChmKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBmaWx0ZXJSZWNvcmQ7XG59XG5cbi8qKlxuICogQ29tcGFyZSBmaWx0ZXIgcmVjb3JkcyB0byBnZXQgd2hhdCBoYXMgY2hhbmdlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlmZkZpbHRlcnMoXG4gIGZpbHRlclJlY29yZDogRmlsdGVyUmVjb3JkLFxuICBvbGRGaWx0ZXJSZWNvcmQ6IEZpbHRlclJlY29yZCB8IHt9ID0ge31cbik6IEZpbHRlckNoYW5nZWQge1xuICBsZXQgZmlsdGVyQ2hhbmdlZDogUGFydGlhbDxGaWx0ZXJDaGFuZ2VkPiA9IHt9O1xuXG4gIChPYmplY3QuZW50cmllcyhmaWx0ZXJSZWNvcmQpIGFzIEVudHJpZXM8RmlsdGVyUmVjb3JkPikuZm9yRWFjaCgoW3JlY29yZCwgaXRlbXNdKSA9PiB7XG4gICAgaXRlbXMuZm9yRWFjaChmaWx0ZXIgPT4ge1xuICAgICAgY29uc3Qgb2xkRmlsdGVyOiBGaWx0ZXIgPSAob2xkRmlsdGVyUmVjb3JkW3JlY29yZF0gfHwgW10pLmZpbmQoXG4gICAgICAgIChmOiBGaWx0ZXIpID0+IGYuaWQgPT09IGZpbHRlci5pZFxuICAgICAgKTtcblxuICAgICAgaWYgKCFvbGRGaWx0ZXIpIHtcbiAgICAgICAgLy8gYWRkZWRcbiAgICAgICAgZmlsdGVyQ2hhbmdlZCA9IHNldChbcmVjb3JkLCBmaWx0ZXIuaWRdLCAnYWRkZWQnLCBmaWx0ZXJDaGFuZ2VkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGNoZWNrICB3aGF0IGhhcyBjaGFuZ2VkXG4gICAgICAgIFsnbmFtZScsICd2YWx1ZScsICdkYXRhSWQnXS5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICAgIGlmIChmaWx0ZXJbcHJvcF0gIT09IG9sZEZpbHRlcltwcm9wXSkge1xuICAgICAgICAgICAgZmlsdGVyQ2hhbmdlZCA9IHNldChbcmVjb3JkLCBmaWx0ZXIuaWRdLCBgJHtwcm9wfV9jaGFuZ2VkYCwgZmlsdGVyQ2hhbmdlZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIChvbGRGaWx0ZXJSZWNvcmRbcmVjb3JkXSB8fCBbXSkuZm9yRWFjaCgob2xkRmlsdGVyOiBGaWx0ZXIpID0+IHtcbiAgICAgIC8vIGRlbGV0ZWRcbiAgICAgIGlmICghaXRlbXMuZmluZChmID0+IGYuaWQgPT09IG9sZEZpbHRlci5pZCkpIHtcbiAgICAgICAgZmlsdGVyQ2hhbmdlZCA9IHNldChbcmVjb3JkLCBvbGRGaWx0ZXIuaWRdLCAnZGVsZXRlZCcsIGZpbHRlckNoYW5nZWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gey4uLntkeW5hbWljRG9tYWluOiBudWxsLCBmaXhlZERvbWFpbjogbnVsbCwgY3B1OiBudWxsLCBncHU6IG51bGx9LCAuLi5maWx0ZXJDaGFuZ2VkfTtcbn1cbi8qKlxuICogQ2FsbCBieSBwYXJzaW5nIGZpbHRlcnMgZnJvbSBVUkxcbiAqIENoZWNrIGlmIHZhbHVlIG9mIGZpbHRlciB3aXRoaW4gZmlsdGVyIGRvbWFpbiwgaWYgbm90IGFkanVzdCBpdCB0byBtYXRjaFxuICogZmlsdGVyIGRvbWFpblxuICpcbiAqIEByZXR1cm5zIHZhbHVlIC0gYWRqdXN0ZWQgdmFsdWUgdG8gbWF0Y2ggZmlsdGVyIG9yIG51bGwgdG8gcmVtb3ZlIGZpbHRlclxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuZXhwb3J0IGZ1bmN0aW9uIGFkanVzdFZhbHVlVG9GaWx0ZXJEb21haW4odmFsdWU6IEZpbHRlclsndmFsdWUnXSwge2RvbWFpbiwgdHlwZX0pIHtcbiAgaWYgKCF0eXBlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGlmIHRoZSBjdXJyZW50IGZpbHRlciBpcyBhIHBvbHlnb24gaXQgd2lsbCBub3QgaGF2ZSBhbnkgZG9tYWluXG4gIC8vIGFsbCBvdGhlciBmaWx0ZXIgdHlwZXMgcmVxdWlyZSBkb21haW5cbiAgaWYgKHR5cGUgIT09IEZJTFRFUl9UWVBFUy5wb2x5Z29uICYmICFkb21haW4pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5yYW5nZTpcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy50aW1lUmFuZ2U6XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpIHx8IHZhbHVlLmxlbmd0aCAhPT0gMikge1xuICAgICAgICByZXR1cm4gZG9tYWluLm1hcChkID0+IGQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsdWUubWFwKChkLCBpKSA9PiAobm90TnVsbG9yVW5kZWZpbmVkKGQpICYmIGlzSW5SYW5nZShkLCBkb21haW4pID8gZCA6IGRvbWFpbltpXSkpO1xuXG4gICAgY2FzZSBGSUxURVJfVFlQRVMubXVsdGlTZWxlY3Q6XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbHRlcmVkVmFsdWUgPSB2YWx1ZS5maWx0ZXIoZCA9PiBkb21haW4uaW5jbHVkZXMoZCkpO1xuICAgICAgcmV0dXJuIGZpbHRlcmVkVmFsdWUubGVuZ3RoID8gZmlsdGVyZWRWYWx1ZSA6IFtdO1xuXG4gICAgY2FzZSBGSUxURVJfVFlQRVMuc2VsZWN0OlxuICAgICAgcmV0dXJuIGRvbWFpbi5pbmNsdWRlcyh2YWx1ZSkgPyB2YWx1ZSA6IHRydWU7XG4gICAgY2FzZSBGSUxURVJfVFlQRVMucG9seWdvbjpcbiAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cbi8qKlxuICogQ2FsY3VsYXRlIG51bWVyaWMgZG9tYWluIGFuZCBzdWl0YWJsZSBzdGVwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXROdW1lcmljRmllbGREb21haW4oXG4gIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gIHZhbHVlQWNjZXNzb3I6IGRhdGFWYWx1ZUFjY2Vzc29yXG4pOiBSYW5nZUZpZWxkRG9tYWluIHtcbiAgbGV0IGRvbWFpbjogW251bWJlciwgbnVtYmVyXSA9IFswLCAxXTtcbiAgbGV0IHN0ZXAgPSAwLjE7XG5cbiAgY29uc3QgbWFwcGVkVmFsdWUgPSBkYXRhQ29udGFpbmVyLm1hcEluZGV4KHZhbHVlQWNjZXNzb3IpO1xuXG4gIGlmIChkYXRhQ29udGFpbmVyLm51bVJvd3MoKSA+IDEpIHtcbiAgICBkb21haW4gPSBTY2FsZVV0aWxzLmdldExpbmVhckRvbWFpbihtYXBwZWRWYWx1ZSk7XG4gICAgY29uc3QgZGlmZiA9IGRvbWFpblsxXSAtIGRvbWFpblswXTtcblxuICAgIC8vIGluIGNhc2UgZXF1YWwgZG9tYWluLCBbOTYsIDk2XSwgd2hpY2ggd2lsbCBicmVhayBxdWFudGl6ZSBzY2FsZVxuICAgIGlmICghZGlmZikge1xuICAgICAgZG9tYWluWzFdID0gZG9tYWluWzBdICsgMTtcbiAgICB9XG5cbiAgICBzdGVwID0gZ2V0TnVtZXJpY1N0ZXBTaXplKGRpZmYpIHx8IHN0ZXA7XG4gICAgZG9tYWluWzBdID0gZm9ybWF0TnVtYmVyQnlTdGVwKGRvbWFpblswXSwgc3RlcCwgJ2Zsb29yJyk7XG4gICAgZG9tYWluWzFdID0gZm9ybWF0TnVtYmVyQnlTdGVwKGRvbWFpblsxXSwgc3RlcCwgJ2NlaWwnKTtcbiAgfVxuXG4gIGNvbnN0IHtoaXN0b2dyYW0sIGVubGFyZ2VkSGlzdG9ncmFtfSA9IGdldEhpc3RvZ3JhbShkb21haW4sIG1hcHBlZFZhbHVlKTtcblxuICByZXR1cm4ge2RvbWFpbiwgc3RlcCwgaGlzdG9ncmFtLCBlbmxhcmdlZEhpc3RvZ3JhbX07XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHN0ZXAgc2l6ZSBmb3IgcmFuZ2UgYW5kIHRpbWVyYW5nZSBmaWx0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE51bWVyaWNTdGVwU2l6ZShkaWZmOiBudW1iZXIpOiBudW1iZXIge1xuICBkaWZmID0gTWF0aC5hYnMoZGlmZik7XG5cbiAgaWYgKGRpZmYgPiAxMDApIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIGlmIChkaWZmID4gMykge1xuICAgIHJldHVybiAwLjAxO1xuICB9IGVsc2UgaWYgKGRpZmYgPiAxKSB7XG4gICAgcmV0dXJuIDAuMDAxO1xuICB9XG4gIC8vIFRyeSB0byBnZXQgYXQgbGVhc3QgMTAwMCBzdGVwcyAtIGFuZCBrZWVwIHRoZSBzdGVwIHNpemUgYmVsb3cgdGhhdCBvZlxuICAvLyB0aGUgKGRpZmYgPiAxKSBjYXNlLlxuICBjb25zdCB4ID0gZGlmZiAvIDEwMDA7XG4gIC8vIEZpbmQgdGhlIGV4cG9uZW50IGFuZCB0cnVuY2F0ZSB0byAxMCB0byB0aGUgcG93ZXIgb2YgdGhhdCBleHBvbmVudFxuXG4gIGNvbnN0IGV4cG9uZW50aWFsRm9ybSA9IHgudG9FeHBvbmVudGlhbCgpO1xuICBjb25zdCBleHBvbmVudCA9IHBhcnNlRmxvYXQoZXhwb25lbnRpYWxGb3JtLnNwbGl0KCdlJylbMV0pO1xuXG4gIC8vIEdldHRpbmcgcmVhZHkgZm9yIG5vZGUgMTJcbiAgLy8gdGhpcyBpcyB3aHkgd2UgbmVlZCBkZWNpbWFsLmpzXG4gIC8vIE1hdGgucG93KDEwLCAtNSkgPSAwLjAwMDAwOTk5OTk5OTk5OTk5OTk5OVxuICAvLyB0aGUgYWJvdmUgcmVzdWx0IHNob3dzIGluIGJyb3dzZXIgYW5kIG5vZGUgMTBcbiAgLy8gbm9kZSAxMiBiZWhhdmVzIGNvcnJlY3RseVxuICByZXR1cm4gbmV3IERlY2ltYWwoMTApLnBvdyhleHBvbmVudCkudG9OdW1iZXIoKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGltZXN0YW1wIGRvbWFpbiBhbmQgc3VpdGFibGUgc3RlcFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGltZXN0YW1wRmllbGREb21haW4oXG4gIGRhdGFDb250YWluZXI6IERhdGFDb250YWluZXJJbnRlcmZhY2UsXG4gIHZhbHVlQWNjZXNzb3I6IGRhdGFWYWx1ZUFjY2Vzc29yXG4pOiBUaW1lUmFuZ2VGaWVsZERvbWFpbiB7XG4gIC8vIHRvIGF2b2lkIGNvbnZlcnRpbmcgc3RyaW5nIGZvcm1hdCB0aW1lIHRvIGVwb2NoXG4gIC8vIGV2ZXJ5IHRpbWUgd2UgY29tcGFyZSB3ZSBzdG9yZSBhIHZhbHVlIG1hcHBlZCB0byBpbnQgaW4gZmlsdGVyIGRvbWFpblxuXG4gIGNvbnN0IG1hcHBlZFZhbHVlID0gZGF0YUNvbnRhaW5lci5tYXBJbmRleCh2YWx1ZUFjY2Vzc29yKTtcbiAgY29uc3QgZG9tYWluID0gU2NhbGVVdGlscy5nZXRMaW5lYXJEb21haW4obWFwcGVkVmFsdWUpO1xuICBjb25zdCBkZWZhdWx0VGltZUZvcm1hdCA9IGdldFRpbWVXaWRnZXRUaXRsZUZvcm1hdHRlcihkb21haW4pO1xuXG4gIGxldCBzdGVwID0gMC4wMTtcblxuICBjb25zdCBkaWZmID0gZG9tYWluWzFdIC0gZG9tYWluWzBdO1xuICAvLyBpbiBjYXNlIGVxdWFsIHRpbWVzdGFtcCBhZGQgMSBzZWNvbmQgcGFkZGluZyB0byBwcmV2ZW50IGJyZWFrXG4gIGlmICghZGlmZikge1xuICAgIGRvbWFpblsxXSA9IGRvbWFpblswXSArIDEwMDA7XG4gIH1cbiAgY29uc3QgZW50cnkgPSBUaW1lc3RhbXBTdGVwTWFwLmZpbmQoZiA9PiBmLm1heCA+PSBkaWZmKTtcbiAgaWYgKGVudHJ5KSB7XG4gICAgc3RlcCA9IGVudHJ5LnN0ZXA7XG4gIH1cblxuICBjb25zdCB7aGlzdG9ncmFtLCBlbmxhcmdlZEhpc3RvZ3JhbX0gPSBnZXRIaXN0b2dyYW0oZG9tYWluLCBtYXBwZWRWYWx1ZSk7XG5cbiAgcmV0dXJuIHtcbiAgICBkb21haW4sXG4gICAgc3RlcCxcbiAgICBtYXBwZWRWYWx1ZSxcbiAgICBoaXN0b2dyYW0sXG4gICAgZW5sYXJnZWRIaXN0b2dyYW0sXG4gICAgZGVmYXVsdFRpbWVGb3JtYXRcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhpc3RvZ3JhbUNvbnN0cnVjdChcbiAgZG9tYWluOiBbbnVtYmVyLCBudW1iZXJdLFxuICBtYXBwZWRWYWx1ZTogKE1pbGxpc2Vjb25kIHwgbnVtYmVyKVtdLFxuICBiaW5zOiBudW1iZXJcbik6IEhpc3RvZ3JhbUJpbltdIHtcbiAgcmV0dXJuIGQzSGlzdG9ncmFtKClcbiAgICAudGhyZXNob2xkcyh0aWNrcyhkb21haW5bMF0sIGRvbWFpblsxXSwgYmlucykpXG4gICAgLmRvbWFpbihkb21haW4pKG1hcHBlZFZhbHVlKVxuICAgIC5tYXAoYmluID0+ICh7XG4gICAgICBjb3VudDogYmluLmxlbmd0aCxcbiAgICAgIGJpbixcbiAgICAgIHgwOiBiaW4ueDAsXG4gICAgICB4MTogYmluLngxXG4gICAgfSkpO1xufVxuLyoqXG4gKiBDYWxjdWxhdGUgaGlzdG9ncmFtIGZyb20gZG9tYWluIGFuZCBhcnJheSBvZiB2YWx1ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEhpc3RvZ3JhbShcbiAgZG9tYWluOiBbbnVtYmVyLCBudW1iZXJdLFxuICBtYXBwZWRWYWx1ZTogKE1pbGxpc2Vjb25kIHwgbnVtYmVyKVtdXG4pOiB7aGlzdG9ncmFtOiBIaXN0b2dyYW1CaW5bXTsgZW5sYXJnZWRIaXN0b2dyYW06IEhpc3RvZ3JhbUJpbltdfSB7XG4gIGNvbnN0IGhpc3RvZ3JhbSA9IGhpc3RvZ3JhbUNvbnN0cnVjdChkb21haW4sIG1hcHBlZFZhbHVlLCBoaXN0b2dyYW1CaW5zKTtcbiAgY29uc3QgZW5sYXJnZWRIaXN0b2dyYW0gPSBoaXN0b2dyYW1Db25zdHJ1Y3QoZG9tYWluLCBtYXBwZWRWYWx1ZSwgZW5sYXJnZWRIaXN0b2dyYW1CaW5zKTtcblxuICByZXR1cm4ge2hpc3RvZ3JhbSwgZW5sYXJnZWRIaXN0b2dyYW19O1xufVxuXG4vKipcbiAqIHJvdW5kIG51bWJlciBiYXNlZCBvbiBzdGVwXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtOdW1iZXJ9IHN0ZXBcbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZFxuICogQHJldHVybnMge051bWJlcn0gcm91bmRlZCBudW1iZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdE51bWJlckJ5U3RlcCh2YWw6IG51bWJlciwgc3RlcDogbnVtYmVyLCBib3VuZDogJ2Zsb29yJyB8ICdjZWlsJyk6IG51bWJlciB7XG4gIGlmIChib3VuZCA9PT0gJ2Zsb29yJykge1xuICAgIHJldHVybiBNYXRoLmZsb29yKHZhbCAqICgxIC8gc3RlcCkpIC8gKDEgLyBzdGVwKTtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmNlaWwodmFsICogKDEgLyBzdGVwKSkgLyAoMSAvIHN0ZXApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNJblJhbmdlKHZhbDogYW55LCBkb21haW46IG51bWJlcltdKTogYm9vbGVhbiB7XG4gIGlmICghQXJyYXkuaXNBcnJheShkb21haW4pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHZhbCA+PSBkb21haW5bMF0gJiYgdmFsIDw9IGRvbWFpblsxXTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBwb2ludCBpcyB3aXRoaW4gdGhlIHByb3ZpZGVkIHBvbHlnb25cbiAqXG4gKiBAcGFyYW0gcG9pbnQgYXMgaW5wdXQgc2VhcmNoIFtsYXQsIGxuZ11cbiAqIEBwYXJhbSBwb2x5Z29uIFBvaW50cyBtdXN0IGJlIHdpdGhpbiB0aGVzZSAoTXVsdGkpUG9seWdvbihzKVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSW5Qb2x5Z29uKHBvaW50OiBudW1iZXJbXSwgcG9seWdvbjogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiBib29sZWFuV2l0aGluKHR1cmZQb2ludChwb2ludCksIHBvbHlnb24pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbWVXaWRnZXRUaXRsZUZvcm1hdHRlcihkb21haW46IFtudW1iZXIsIG51bWJlcl0pOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKCFpc1ZhbGlkVGltZURvbWFpbihkb21haW4pKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBkaWZmID0gZG9tYWluWzFdIC0gZG9tYWluWzBdO1xuXG4gIC8vIExvY2FsIGF3YXJlIGZvcm1hdHNcbiAgLy8gaHR0cHM6Ly9tb21lbnRqcy5jb20vZG9jcy8jL3BhcnNpbmcvc3RyaW5nLWZvcm1hdFxuICByZXR1cm4gZGlmZiA+IGR1cmF0aW9uWWVhciA/ICdMJyA6IGRpZmYgPiBkdXJhdGlvbkRheSA/ICdMIExUJyA6ICdMIExUUyc7XG59XG5cbi8qKlxuICogU2FuaXR5IGNoZWNrIG9uIGZpbHRlcnMgdG8gcHJlcGFyZSBmb3Igc2F2ZVxuICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4vZmlsdGVyLXV0aWxzJykuaXNGaWx0ZXJWYWxpZFRvU2F2ZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRmlsdGVyVmFsaWRUb1NhdmUoZmlsdGVyOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBmaWx0ZXI/LnR5cGUgJiYgQXJyYXkuaXNBcnJheShmaWx0ZXI/Lm5hbWUpICYmIChmaWx0ZXI/Lm5hbWUubGVuZ3RoIHx8IGZpbHRlcj8ubGF5ZXJJZC5sZW5ndGgpXG4gICk7XG59XG5cbi8qKlxuICogU2FuaXR5IGNoZWNrIG9uIGZpbHRlcnMgdG8gcHJlcGFyZSBmb3Igc2F2ZVxuICogQHR5cGUge3R5cGVvZiBpbXBvcnQoJy4vZmlsdGVyLXV0aWxzJykuaXNWYWxpZEZpbHRlclZhbHVlfVxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEZpbHRlclZhbHVlKHR5cGU6IHN0cmluZyB8IG51bGwsIHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKCF0eXBlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgRklMVEVSX1RZUEVTLnNlbGVjdDpcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gZmFsc2U7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5yYW5nZTpcbiAgICBjYXNlIEZJTFRFUl9UWVBFUy50aW1lUmFuZ2U6XG4gICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUuZXZlcnkodiA9PiB2ICE9PSBudWxsICYmICFpc05hTih2KSk7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5tdWx0aVNlbGVjdDpcbiAgICAgIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiBCb29sZWFuKHZhbHVlLmxlbmd0aCk7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5pbnB1dDpcbiAgICAgIHJldHVybiBCb29sZWFuKHZhbHVlLmxlbmd0aCk7XG5cbiAgICBjYXNlIEZJTFRFUl9UWVBFUy5wb2x5Z29uOlxuICAgICAgY29uc3QgY29vcmRpbmF0ZXMgPSBnZXQodmFsdWUsIFsnZ2VvbWV0cnknLCAnY29vcmRpbmF0ZXMnXSk7XG4gICAgICByZXR1cm4gQm9vbGVhbih2YWx1ZSAmJiB2YWx1ZS5pZCAmJiBjb29yZGluYXRlcyk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvbHVtbkZpbHRlclByb3BzPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPihcbiAgZmlsdGVyOiBGaWx0ZXIsXG4gIGRhdGFzZXQ6IEtcbik6IHtsaW5lQ2hhcnQ6IExpbmVDaGFydDsgeUF4czogRmllbGR9IHwge30ge1xuICBpZiAoZmlsdGVyLnBsb3RUeXBlID09PSBQTE9UX1RZUEVTLmhpc3RvZ3JhbSB8fCAhZmlsdGVyLnlBeGlzKSB7XG4gICAgLy8gaGlzdG9ncmFtIHNob3VsZCBiZSBjYWxjdWxhdGVkIHdoZW4gY3JlYXRlIGZpbHRlclxuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IHttYXBwZWRWYWx1ZSA9IFtdfSA9IGZpbHRlcjtcbiAgY29uc3Qge3lBeGlzfSA9IGZpbHRlcjtcbiAgY29uc3QgZmllbGRJZHggPSBkYXRhc2V0LmdldENvbHVtbkZpZWxkSWR4KHlBeGlzLm5hbWUpO1xuICBpZiAoZmllbGRJZHggPCAwKSB7XG4gICAgQ29uc29sZS53YXJuKGB5QXhpcyAke3lBeGlzLm5hbWV9IGRvZXMgbm90IGV4aXN0IGluIGRhdGFzZXRgKTtcbiAgICByZXR1cm4ge2xpbmVDaGFydDoge30sIHlBeGlzfTtcbiAgfVxuXG4gIC8vIHJldHVybiBsaW5lQ2hhcnRcbiAgY29uc3Qgc2VyaWVzID0gZGF0YXNldC5kYXRhQ29udGFpbmVyXG4gICAgLm1hcChcbiAgICAgIChyb3csIHJvd0luZGV4KSA9PiAoe1xuICAgICAgICB4OiBtYXBwZWRWYWx1ZVtyb3dJbmRleF0sXG4gICAgICAgIHk6IHJvdy52YWx1ZUF0KGZpZWxkSWR4KVxuICAgICAgfSksXG4gICAgICB0cnVlXG4gICAgKVxuICAgIC5maWx0ZXIoKHt4LCB5fSkgPT4gTnVtYmVyLmlzRmluaXRlKHgpICYmIE51bWJlci5pc0Zpbml0ZSh5KSlcbiAgICAuc29ydCgoYSwgYikgPT4gYXNjZW5kaW5nKGEueCwgYi54KSk7XG5cbiAgY29uc3QgeURvbWFpbiA9IGV4dGVudChzZXJpZXMsIGQgPT4gZC55KTtcbiAgY29uc3QgeERvbWFpbiA9IFtzZXJpZXNbMF0ueCwgc2VyaWVzW3Nlcmllcy5sZW5ndGggLSAxXS54XTtcblxuICByZXR1cm4ge2xpbmVDaGFydDoge3NlcmllcywgeURvbWFpbiwgeERvbWFpbn0sIHlBeGlzfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRGaWx0ZXJQbG90VHlwZShmaWx0ZXI6IEZpbHRlcik6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBmaWx0ZXJQbG90VHlwZXM6IHR5cGVvZiBTdXBwb3J0ZWRQbG90VHlwZVtrZXlvZiB0eXBlb2YgU3VwcG9ydGVkUGxvdFR5cGVdIHwgbnVsbCA9XG4gICAgZmlsdGVyLnR5cGUgJiYgU3VwcG9ydGVkUGxvdFR5cGVbZmlsdGVyLnR5cGVdO1xuICBpZiAoIWZpbHRlclBsb3RUeXBlcykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKCFmaWx0ZXIueUF4aXMpIHtcbiAgICByZXR1cm4gZmlsdGVyUGxvdFR5cGVzLmRlZmF1bHQ7XG4gIH1cblxuICByZXR1cm4gZmlsdGVyUGxvdFR5cGVzW2ZpbHRlci55QXhpcy50eXBlXSB8fCBudWxsO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0gZGF0YXNldElkcyBsaXN0IG9mIGRhdGFzZXQgaWRzIHRvIGJlIGZpbHRlcmVkXG4gKiBAcGFyYW0gZGF0YXNldHMgYWxsIGRhdGFzZXRzXG4gKiBAcGFyYW0gZmlsdGVycyBhbGwgZmlsdGVycyB0byBiZSBhcHBsaWVkIHRvIGRhdGFzZXRzXG4gKiBAcmV0dXJuIGRhdGFzZXRzIC0gbmV3IHVwZGF0ZWQgZGF0YXNldHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5RmlsdGVyc1RvRGF0YXNldHM8XG4gIEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LFxuICBMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbH19XG4+KFxuICBkYXRhc2V0SWRzOiBzdHJpbmdbXSxcbiAgZGF0YXNldHM6IHtbaWQ6IHN0cmluZ106IEt9LFxuICBmaWx0ZXJzOiBGaWx0ZXJbXSxcbiAgbGF5ZXJzPzogTFtdXG4pOiB7W2lkOiBzdHJpbmddOiBLfSB7XG4gIGNvbnN0IGRhdGFJZHMgPSB0b0FycmF5KGRhdGFzZXRJZHMpO1xuICByZXR1cm4gZGF0YUlkcy5yZWR1Y2UoKGFjYywgZGF0YUlkKSA9PiB7XG4gICAgY29uc3QgbGF5ZXJzVG9GaWx0ZXIgPSAobGF5ZXJzIHx8IFtdKS5maWx0ZXIobCA9PiBsLmNvbmZpZy5kYXRhSWQgPT09IGRhdGFJZCk7XG4gICAgY29uc3QgYXBwbGllZEZpbHRlcnMgPSBmaWx0ZXJzLmZpbHRlcihkID0+IHNob3VsZEFwcGx5RmlsdGVyKGQsIGRhdGFJZCkpO1xuICAgIGNvbnN0IHRhYmxlID0gZGF0YXNldHNbZGF0YUlkXTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5hY2MsXG4gICAgICBbZGF0YUlkXTogdGFibGUuZmlsdGVyVGFibGUoYXBwbGllZEZpbHRlcnMsIGxheWVyc1RvRmlsdGVyLCB7fSlcbiAgICB9O1xuICB9LCBkYXRhc2V0cyk7XG59XG5cbi8qKlxuICogQXBwbGllcyBhIG5ldyBmaWVsZCBuYW1lIHZhbHVlIHRvIGZpZWx0ZXIgYW5kIHVwZGF0ZSBib3RoIGZpbHRlciBhbmQgZGF0YXNldFxuICogQHBhcmFtIGZpbHRlciAtIHRvIGJlIGFwcGxpZWQgdGhlIG5ldyBmaWVsZCBuYW1lIG9uXG4gKiBAcGFyYW0gZGF0YXNldCAtIGRhdGFzZXQgdGhlIGZpZWxkIGJlbG9uZ3MgdG9cbiAqIEBwYXJhbSBmaWVsZE5hbWUgLSBmaWVsZC5uYW1lXG4gKiBAcGFyYW0gZmlsdGVyRGF0YXNldEluZGV4IC0gZmllbGQubmFtZVxuICogQHBhcmFtIG9wdGlvblxuICogQHJldHVybiAtIHtmaWx0ZXIsIGRhdGFzZXRzfVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlGaWx0ZXJGaWVsZE5hbWU8SyBleHRlbmRzIEtlcGxlclRhYmxlTW9kZWw8SywgTD4sIEw+KFxuICBmaWx0ZXI6IEZpbHRlcixcbiAgZGF0YXNldDogSyxcbiAgZmllbGROYW1lOiBzdHJpbmcsXG4gIGZpbHRlckRhdGFzZXRJbmRleCA9IDAsXG4gIG9wdGlvbj86IHttZXJnZURvbWFpbjogYm9vbGVhbn1cbik6IHtcbiAgZmlsdGVyOiBGaWx0ZXIgfCBudWxsO1xuICBkYXRhc2V0OiBLO1xufSB7XG4gIC8vIHVzaW5nIGZpbHRlckRhdGFzZXRJbmRleCB3ZSBjYW4gZmlsdGVyIG9ubHkgdGhlIHNwZWNpZmllZCBkYXRhc2V0XG4gIGNvbnN0IG1lcmdlRG9tYWluID0gb3B0aW9uICYmIG9wdGlvbi5oYXNPd25Qcm9wZXJ0eSgnbWVyZ2VEb21haW4nKSA/IG9wdGlvbi5tZXJnZURvbWFpbiA6IGZhbHNlO1xuXG4gIGNvbnN0IGZpZWxkSW5kZXggPSBkYXRhc2V0LmdldENvbHVtbkZpZWxkSWR4KGZpZWxkTmFtZSk7XG4gIC8vIGlmIG5vIGZpZWxkIHdpdGggc2FtZSBuYW1lIGlzIGZvdW5kLCBtb3ZlIHRvIHRoZSBuZXh0IGRhdGFzZXRzXG4gIGlmIChmaWVsZEluZGV4ID09PSAtMSkge1xuICAgIC8vIHRocm93IG5ldyBFcnJvcihgZmllbGRJbmRleCBub3QgZm91bmQuIERhdGFzZXQgbXVzdCBjb250YWluIGEgcHJvcGVydHkgd2l0aCBuYW1lOiAke2ZpZWxkTmFtZX1gKTtcbiAgICByZXR1cm4ge2ZpbHRlcjogbnVsbCwgZGF0YXNldH07XG4gIH1cblxuICAvLyBUT0RPOiB2YWxpZGF0ZSBmaWVsZCB0eXBlXG4gIGNvbnN0IGZpbHRlclByb3BzID0gZGF0YXNldC5nZXRDb2x1bW5GaWx0ZXJQcm9wcyhmaWVsZE5hbWUpO1xuXG4gIGNvbnN0IG5ld0ZpbHRlciA9IHtcbiAgICAuLi4obWVyZ2VEb21haW4gPyBtZXJnZUZpbHRlckRvbWFpblN0ZXAoZmlsdGVyLCBmaWx0ZXJQcm9wcykgOiB7Li4uZmlsdGVyLCAuLi5maWx0ZXJQcm9wc30pLFxuICAgIG5hbWU6IE9iamVjdC5hc3NpZ24oWy4uLnRvQXJyYXkoZmlsdGVyLm5hbWUpXSwge1tmaWx0ZXJEYXRhc2V0SW5kZXhdOiBmaWVsZE5hbWV9KSxcbiAgICBmaWVsZElkeDogT2JqZWN0LmFzc2lnbihbLi4udG9BcnJheShmaWx0ZXIuZmllbGRJZHgpXSwge1xuICAgICAgW2ZpbHRlckRhdGFzZXRJbmRleF06IGZpZWxkSW5kZXhcbiAgICB9KSxcbiAgICAvLyBUT0RPLCBzaW5jZSB3ZSBhbGxvdyB0byBhZGQgbXVsdGlwbGUgZmllbGRzIHRvIGEgZmlsdGVyIHdlIGNhbiBubyBsb25nZXIgZnJlZXplIHRoZSBmaWx0ZXJcbiAgICBmcmVlemU6IHRydWVcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGZpbHRlcjogbmV3RmlsdGVyLFxuICAgIGRhdGFzZXRcbiAgfTtcbn1cblxuLyoqXG4gKiBNZXJnZSBvbmUgZmlsdGVyIHdpdGggb3RoZXIgZmlsdGVyIHByb3AgZG9tYWluXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUZpbHRlckRvbWFpblN0ZXAoXG4gIGZpbHRlcjogRmlsdGVyLFxuICBmaWx0ZXJQcm9wcz86IFBhcnRpYWw8RmlsdGVyPlxuKTogKEZpbHRlciAmIHtzdGVwPzogbnVtYmVyfSkgfCBudWxsIHtcbiAgaWYgKCFmaWx0ZXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmICghZmlsdGVyUHJvcHMpIHtcbiAgICByZXR1cm4gZmlsdGVyO1xuICB9XG5cbiAgaWYgKChmaWx0ZXIuZmllbGRUeXBlICYmIGZpbHRlci5maWVsZFR5cGUgIT09IGZpbHRlclByb3BzLmZpZWxkVHlwZSkgfHwgIWZpbHRlclByb3BzLmRvbWFpbikge1xuICAgIHJldHVybiBmaWx0ZXI7XG4gIH1cblxuICBjb25zdCBjb21iaW5lZERvbWFpbiA9ICFmaWx0ZXIuZG9tYWluXG4gICAgPyBmaWx0ZXJQcm9wcy5kb21haW5cbiAgICA6IFsuLi4oZmlsdGVyLmRvbWFpbiB8fCBbXSksIC4uLihmaWx0ZXJQcm9wcy5kb21haW4gfHwgW10pXS5zb3J0KChhLCBiKSA9PiBhIC0gYik7XG5cbiAgY29uc3QgbmV3RmlsdGVyID0ge1xuICAgIC4uLmZpbHRlcixcbiAgICAuLi5maWx0ZXJQcm9wcyxcbiAgICBkb21haW46IFtjb21iaW5lZERvbWFpblswXSwgY29tYmluZWREb21haW5bY29tYmluZWREb21haW4ubGVuZ3RoIC0gMV1dXG4gIH07XG5cbiAgc3dpdGNoIChmaWx0ZXJQcm9wcy5maWVsZFR5cGUpIHtcbiAgICBjYXNlIEFMTF9GSUVMRF9UWVBFUy5zdHJpbmc6XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuZGF0ZTpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm5ld0ZpbHRlcixcbiAgICAgICAgZG9tYWluOiB1bmlxdWUoY29tYmluZWREb21haW4pLnNvcnQoKVxuICAgICAgfTtcblxuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLnRpbWVzdGFtcDpcbiAgICAgIGNvbnN0IHN0ZXAgPVxuICAgICAgICAoZmlsdGVyIGFzIFRpbWVSYW5nZUZpbHRlcikuc3RlcCA8IChmaWx0ZXJQcm9wcyBhcyBUaW1lUmFuZ2VGaWVsZERvbWFpbikuc3RlcFxuICAgICAgICAgID8gKGZpbHRlciBhcyBUaW1lUmFuZ2VGaWx0ZXIpLnN0ZXBcbiAgICAgICAgICA6IChmaWx0ZXJQcm9wcyBhcyBUaW1lUmFuZ2VGaWVsZERvbWFpbikuc3RlcDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubmV3RmlsdGVyLFxuICAgICAgICBzdGVwXG4gICAgICB9O1xuICAgIGNhc2UgQUxMX0ZJRUxEX1RZUEVTLnJlYWw6XG4gICAgY2FzZSBBTExfRklFTERfVFlQRVMuaW50ZWdlcjpcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG5ld0ZpbHRlcjtcbiAgfVxufVxuLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cbi8qKlxuICogR2VuZXJhdGVzIHBvbHlnb24gZmlsdGVyXG4gKi9cbmV4cG9ydCBjb25zdCBmZWF0dXJlVG9GaWx0ZXJWYWx1ZSA9IChcbiAgZmVhdHVyZTogRmVhdHVyZSxcbiAgZmlsdGVySWQ6IHN0cmluZyxcbiAgcHJvcGVydGllcz86IHt9XG4pOiBGZWF0dXJlVmFsdWUgPT4gKHtcbiAgLi4uZmVhdHVyZSxcbiAgaWQ6IGZlYXR1cmUuaWQsXG4gIHByb3BlcnRpZXM6IHtcbiAgICAuLi5mZWF0dXJlLnByb3BlcnRpZXMsXG4gICAgLi4ucHJvcGVydGllcyxcbiAgICBmaWx0ZXJJZFxuICB9XG59KTtcblxuZXhwb3J0IGNvbnN0IGdldEZpbHRlcklkSW5GZWF0dXJlID0gKGY6IEZlYXR1cmVWYWx1ZSk6IHN0cmluZyA9PiBnZXQoZiwgWydwcm9wZXJ0aWVzJywgJ2ZpbHRlcklkJ10pO1xuXG4vKipcbiAqIEdlbmVyYXRlcyBwb2x5Z29uIGZpbHRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVQb2x5Z29uRmlsdGVyPFxuICBMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbDsgbGFiZWw6IHN0cmluZ307IGlkOiBzdHJpbmd9XG4+KGxheWVyczogTFtdLCBmZWF0dXJlOiBGZWF0dXJlKTogUG9seWdvbkZpbHRlciB7XG4gIGNvbnN0IGRhdGFJZCA9IGxheWVycy5tYXAobCA9PiBsLmNvbmZpZy5kYXRhSWQpLmZpbHRlcihub3ROdWxsb3JVbmRlZmluZWQpO1xuICBjb25zdCBsYXllcklkID0gbGF5ZXJzLm1hcChsID0+IGwuaWQpO1xuICBjb25zdCBuYW1lID0gbGF5ZXJzLm1hcChsID0+IGwuY29uZmlnLmxhYmVsKTtcbiAgY29uc3QgZmlsdGVyID0gZ2V0RGVmYXVsdEZpbHRlcih7ZGF0YUlkfSk7XG4gIHJldHVybiB7XG4gICAgLi4uZmlsdGVyLFxuICAgIGZpeGVkRG9tYWluOiB0cnVlLFxuICAgIHR5cGU6IEZJTFRFUl9UWVBFUy5wb2x5Z29uLFxuICAgIG5hbWUsXG4gICAgbGF5ZXJJZCxcbiAgICB2YWx1ZTogZmVhdHVyZVRvRmlsdGVyVmFsdWUoZmVhdHVyZSwgZmlsdGVyLmlkLCB7aXNWaXNpYmxlOiB0cnVlfSlcbiAgfTtcbn1cblxuLyoqXG4gKiBSdW4gZmlsdGVyIGVudGlyZWx5IG9uIENQVVxuICovXG5pbnRlcmZhY2UgU3RhdGVUeXBlPEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LCBMPiB7XG4gIGxheWVyczogTFtdO1xuICBmaWx0ZXJzOiBGaWx0ZXJbXTtcbiAgZGF0YXNldHM6IHtbaWQ6IHN0cmluZ106IEt9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyRGF0YXNldENQVTxUIGV4dGVuZHMgU3RhdGVUeXBlPEssIEw+LCBLIGV4dGVuZHMgS2VwbGVyVGFibGVNb2RlbDxLLCBMPiwgTD4oXG4gIHN0YXRlOiBULFxuICBkYXRhSWQ6IHN0cmluZ1xuKTogVCB7XG4gIGNvbnN0IGRhdGFzZXRGaWx0ZXJzID0gc3RhdGUuZmlsdGVycy5maWx0ZXIoZiA9PiBmLmRhdGFJZC5pbmNsdWRlcyhkYXRhSWQpKTtcbiAgY29uc3QgZGF0YXNldCA9IHN0YXRlLmRhdGFzZXRzW2RhdGFJZF07XG5cbiAgaWYgKCFkYXRhc2V0KSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgY29uc3QgY3B1RmlsdGVyZWREYXRhc2V0ID0gZGF0YXNldC5maWx0ZXJUYWJsZUNQVShkYXRhc2V0RmlsdGVycywgc3RhdGUubGF5ZXJzKTtcblxuICByZXR1cm4gc2V0KFsnZGF0YXNldHMnLCBkYXRhSWRdLCBjcHVGaWx0ZXJlZERhdGFzZXQsIHN0YXRlKTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBwYXJzZWQgZmlsdGVycyB3aXRoIGRhdGFzZXRzIGFuZCBhZGQgZmlsdGVyUHJvcHMgdG8gZmllbGRcbiAqL1xudHlwZSBNaW5WaXNTdGF0ZUZvckZpbHRlciA9IFBpY2s8VmlzU3RhdGUsICdsYXllcnMnIHwgJ2RhdGFzZXRzJyB8ICdpc01lcmdpbmdEYXRhc2V0cyc+O1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlRmlsdGVyc1VwZGF0ZURhdGFzZXRzPFxuICBTIGV4dGVuZHMgTWluVmlzU3RhdGVGb3JGaWx0ZXIsXG4gIEsgZXh0ZW5kcyBLZXBsZXJUYWJsZU1vZGVsPEssIEw+LFxuICBMIGV4dGVuZHMge2NvbmZpZzoge2RhdGFJZDogc3RyaW5nIHwgbnVsbDsgbGFiZWw6IHN0cmluZ307IGlkOiBzdHJpbmd9XG4+KFxuICBzdGF0ZTogUyxcbiAgZmlsdGVyc1RvVmFsaWRhdGU6IFBhcnNlZEZpbHRlcltdID0gW11cbik6IHtcbiAgdmFsaWRhdGVkOiBGaWx0ZXJbXTtcbiAgZmFpbGVkOiBGaWx0ZXJbXTtcbiAgdXBkYXRlZERhdGFzZXRzOiBTWydkYXRhc2V0cyddO1xufSB7XG4gIC8vIFRPRE8gQmV0dGVyIFR5cGluZ3MgaGVyZVxuICBjb25zdCB2YWxpZGF0ZWQ6IGFueVtdID0gW107XG4gIGNvbnN0IGZhaWxlZDogYW55W10gPSBbXTtcbiAgY29uc3Qge2RhdGFzZXRzfSA9IHN0YXRlO1xuICBsZXQgdXBkYXRlZERhdGFzZXRzID0gZGF0YXNldHM7XG5cbiAgLy8gbWVyZ2UgZmlsdGVyc1xuICBmaWx0ZXJzVG9WYWxpZGF0ZS5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgLy8gd2UgY2FuIG9ubHkgbG9vayBmb3IgZGF0YXNldHMgZGVmaW5lIGluIHRoZSBmaWx0ZXIgZGF0YUlkXG4gICAgY29uc3QgZGF0YXNldElkcyA9IHRvQXJyYXkoZmlsdGVyLmRhdGFJZCk7XG5cbiAgICAvLyB3ZSBjYW4gbWVyZ2UgYSBmaWx0ZXIgb25seSBpZiBhbGwgZGF0YXNldHMgaW4gZmlsdGVyLmRhdGFJZCBhcmUgbG9hZGVkXG4gICAgaWYgKGRhdGFzZXRJZHMuZXZlcnkoZCA9PiBkYXRhc2V0c1tkXSAmJiAhc3RhdGUuaXNNZXJnaW5nRGF0YXNldHNbZF0pKSB7XG4gICAgICAvLyBhbGwgZGF0YXNldElkcyBpbiBmaWx0ZXIgbXVzdCBiZSBwcmVzZW50IHRoZSBzdGF0ZSBkYXRhc2V0c1xuICAgICAgY29uc3Qge2ZpbHRlcjogdmFsaWRhdGVkRmlsdGVyLCBhcHBseVRvRGF0YXNldHMsIGF1Z21lbnRlZERhdGFzZXRzfSA9IGRhdGFzZXRJZHMucmVkdWNlPHtcbiAgICAgICAgZmlsdGVyOiBGaWx0ZXIgfCBudWxsO1xuICAgICAgICBhcHBseVRvRGF0YXNldHM6IHN0cmluZ1tdO1xuICAgICAgICBhdWdtZW50ZWREYXRhc2V0czoge1tkYXRhc2V0SWQ6IHN0cmluZ106IGFueX07XG4gICAgICB9PihcbiAgICAgICAgKGFjYywgZGF0YXNldElkKSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YXNldCA9IHVwZGF0ZWREYXRhc2V0c1tkYXRhc2V0SWRdO1xuICAgICAgICAgIGNvbnN0IGxheWVycyA9IHN0YXRlLmxheWVycy5maWx0ZXIobCA9PiBsLmNvbmZpZy5kYXRhSWQgPT09IGRhdGFzZXQuaWQpO1xuICAgICAgICAgIGNvbnN0IHtmaWx0ZXI6IHVwZGF0ZWRGaWx0ZXIsIGRhdGFzZXQ6IHVwZGF0ZWREYXRhc2V0fSA9IHZhbGlkYXRlRmlsdGVyV2l0aERhdGEoXG4gICAgICAgICAgICBhY2MuYXVnbWVudGVkRGF0YXNldHNbZGF0YXNldElkXSB8fCBkYXRhc2V0LFxuICAgICAgICAgICAgZmlsdGVyLFxuICAgICAgICAgICAgbGF5ZXJzXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmICh1cGRhdGVkRmlsdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICAgIC8vIG1lcmdlIGZpbHRlciBwcm9wc1xuICAgICAgICAgICAgICBmaWx0ZXI6IGFjYy5maWx0ZXJcbiAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uYWNjLmZpbHRlcixcbiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyBjaGVjazogY2hhbmdlZCBmcm9tIGFjYyB0byBhY2MuZmlsdGVyIHRvIGZpeCB0eXBlc1xuICAgICAgICAgICAgICAgICAgICAuLi5tZXJnZUZpbHRlckRvbWFpblN0ZXAoYWNjLmZpbHRlciwgdXBkYXRlZEZpbHRlcilcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA6IHVwZGF0ZWRGaWx0ZXIsXG5cbiAgICAgICAgICAgICAgYXBwbHlUb0RhdGFzZXRzOiBbLi4uYWNjLmFwcGx5VG9EYXRhc2V0cywgZGF0YXNldElkXSxcblxuICAgICAgICAgICAgICBhdWdtZW50ZWREYXRhc2V0czoge1xuICAgICAgICAgICAgICAgIC4uLmFjYy5hdWdtZW50ZWREYXRhc2V0cyxcbiAgICAgICAgICAgICAgICBbZGF0YXNldElkXTogdXBkYXRlZERhdGFzZXRcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgZmlsdGVyOiBudWxsLFxuICAgICAgICAgIGFwcGx5VG9EYXRhc2V0czogW10sXG4gICAgICAgICAgYXVnbWVudGVkRGF0YXNldHM6IHt9XG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIGlmICh2YWxpZGF0ZWRGaWx0ZXIgJiYgaXNFcXVhbChkYXRhc2V0SWRzLCBhcHBseVRvRGF0YXNldHMpKSB7XG4gICAgICAgIHZhbGlkYXRlZC5wdXNoKHZhbGlkYXRlZEZpbHRlcik7XG4gICAgICAgIHVwZGF0ZWREYXRhc2V0cyA9IHtcbiAgICAgICAgICAuLi51cGRhdGVkRGF0YXNldHMsXG4gICAgICAgICAgLi4uYXVnbWVudGVkRGF0YXNldHNcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZhaWxlZC5wdXNoKGZpbHRlcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZhaWxlZC5wdXNoKGZpbHRlcik7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4ge3ZhbGlkYXRlZCwgZmFpbGVkLCB1cGRhdGVkRGF0YXNldHN9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsdGVyUGxvdDxLIGV4dGVuZHMgS2VwbGVyVGFibGVNb2RlbDxLLCBMPiwgTD4oXG4gIGZpbHRlcjogRmlsdGVyLFxuICBkYXRhc2V0OiBLXG4pOiB7bGluZUNoYXJ0OiBMaW5lQ2hhcnQ7IHlBeHM6IEZpZWxkfSB8IHt9IHtcbiAgaWYgKGZpbHRlci5wbG90VHlwZSA9PT0gUExPVF9UWVBFUy5oaXN0b2dyYW0gfHwgIWZpbHRlci55QXhpcykge1xuICAgIC8vIGhpc3RvZ3JhbSBzaG91bGQgYmUgY2FsY3VsYXRlZCB3aGVuIGNyZWF0ZSBmaWx0ZXJcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBjb25zdCB7bWFwcGVkVmFsdWUgPSBbXX0gPSBmaWx0ZXI7XG4gIGNvbnN0IHt5QXhpc30gPSBmaWx0ZXI7XG4gIGNvbnN0IGZpZWxkSWR4ID0gZGF0YXNldC5nZXRDb2x1bW5GaWVsZElkeCh5QXhpcy5uYW1lKTtcbiAgaWYgKGZpZWxkSWR4IDwgMCkge1xuICAgIENvbnNvbGUud2FybihgeUF4aXMgJHt5QXhpcy5uYW1lfSBkb2VzIG5vdCBleGlzdCBpbiBkYXRhc2V0YCk7XG4gICAgcmV0dXJuIHtsaW5lQ2hhcnQ6IHt9LCB5QXhpc307XG4gIH1cblxuICAvLyByZXR1cm4gbGluZUNoYXJ0XG4gIGNvbnN0IHNlcmllcyA9IGRhdGFzZXQuZGF0YUNvbnRhaW5lclxuICAgIC5tYXAoXG4gICAgICAocm93LCByb3dJbmRleCkgPT4gKHtcbiAgICAgICAgeDogbWFwcGVkVmFsdWVbcm93SW5kZXhdLFxuICAgICAgICB5OiByb3cudmFsdWVBdChmaWVsZElkeClcbiAgICAgIH0pLFxuICAgICAgdHJ1ZVxuICAgIClcbiAgICAuZmlsdGVyKCh7eCwgeX0pID0+IE51bWJlci5pc0Zpbml0ZSh4KSAmJiBOdW1iZXIuaXNGaW5pdGUoeSkpXG4gICAgLnNvcnQoKGEsIGIpID0+IGFzY2VuZGluZyhhLngsIGIueCkpO1xuXG4gIGNvbnN0IHlEb21haW4gPSBleHRlbnQoc2VyaWVzLCBkID0+IGQueSk7XG4gIGNvbnN0IHhEb21haW4gPSBbc2VyaWVzWzBdLngsIHNlcmllc1tzZXJpZXMubGVuZ3RoIC0gMV0ueF07XG5cbiAgcmV0dXJuIHtsaW5lQ2hhcnQ6IHtzZXJpZXMsIHlEb21haW4sIHhEb21haW59LCB5QXhpc307XG59XG5cbi8qKlxuICogUmV0cmlldmUgaW50ZXJ2YWwgYmlucyBmb3IgdGltZSBmaWx0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEludGVydmFsQmlucyhmaWx0ZXI6IFRpbWVSYW5nZUZpbHRlcikge1xuICBjb25zdCB7Ymluc30gPSBmaWx0ZXI7XG4gIGNvbnN0IGludGVydmFsID0gZmlsdGVyLnBsb3RUeXBlPy5pbnRlcnZhbDtcbiAgaWYgKCFpbnRlcnZhbCB8fCAhYmlucyB8fCBPYmplY3Qua2V5cyhiaW5zKS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCB2YWx1ZXMgPSBPYmplY3QudmFsdWVzKGJpbnMpO1xuICByZXR1cm4gdmFsdWVzWzBdID8gdmFsdWVzWzBdW2ludGVydmFsXSA6IG51bGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkVGltZURvbWFpbihkb21haW4pIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZG9tYWluKSAmJiBkb21haW4uZXZlcnkoTnVtYmVyLmlzRmluaXRlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbWVXaWRnZXRIaW50Rm9ybWF0dGVyKGRvbWFpbjogW251bWJlciwgbnVtYmVyXSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaXNWYWxpZFRpbWVEb21haW4oZG9tYWluKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkaWZmID0gZG9tYWluWzFdIC0gZG9tYWluWzBdO1xuICByZXR1cm4gZGlmZiA+IGR1cmF0aW9uV2Vla1xuICAgID8gJ0wnXG4gICAgOiBkaWZmID4gZHVyYXRpb25EYXlcbiAgICA/ICdMIExUJ1xuICAgIDogZGlmZiA+IGR1cmF0aW9uSG91clxuICAgID8gJ0xUJ1xuICAgIDogJ0xUUyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1NpZGVGaWx0ZXIoZmlsdGVyOiBGaWx0ZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGZpbHRlci52aWV3ID09PSBGSUxURVJfVklFV19UWVBFUy5zaWRlO1xufVxuIl19
|