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