@kepler.gl/reducers 3.3.0-alpha.5 → 3.3.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/cjs/combined-updaters.js +491 -0
  2. package/dist/cjs/composer-helpers.js +101 -0
  3. package/dist/cjs/composers.js +22 -0
  4. package/dist/cjs/core.js +105 -0
  5. package/dist/cjs/data-utils.js +53 -0
  6. package/dist/cjs/export-utils.js +91 -0
  7. package/dist/{index.js → cjs/index.js} +1 -1
  8. package/dist/cjs/interaction-utils.js +105 -0
  9. package/dist/cjs/layer-utils.js +635 -0
  10. package/dist/cjs/map-state-updaters.js +658 -0
  11. package/dist/cjs/map-state.js +35 -0
  12. package/dist/cjs/map-style-updaters.js +660 -0
  13. package/dist/cjs/map-style.js +33 -0
  14. package/dist/cjs/merger-handler.js +105 -0
  15. package/dist/cjs/middleware.js +27 -0
  16. package/dist/cjs/provider-state-updaters.js +465 -0
  17. package/dist/cjs/provider-state.js +34 -0
  18. package/dist/cjs/root.js +207 -0
  19. package/dist/cjs/ui-state-updaters.js +934 -0
  20. package/dist/cjs/ui-state.js +36 -0
  21. package/dist/cjs/vis-state-merger.js +1193 -0
  22. package/dist/cjs/vis-state-selectors.js +30 -0
  23. package/dist/{vis-state-updaters.js → cjs/vis-state-updaters.js} +338 -47
  24. package/dist/cjs/vis-state.js +35 -0
  25. package/dist/combined-updaters.d.ts +1 -1
  26. package/dist/esm/combined-updaters.js +484 -0
  27. package/dist/esm/composer-helpers.js +85 -0
  28. package/dist/esm/composers.js +14 -0
  29. package/dist/esm/core.js +101 -0
  30. package/dist/esm/data-utils.js +47 -0
  31. package/dist/esm/export-utils.js +86 -0
  32. package/dist/esm/index.js +62 -0
  33. package/dist/esm/interaction-utils.js +96 -0
  34. package/dist/esm/layer-utils.js +602 -0
  35. package/dist/esm/map-state-updaters.js +650 -0
  36. package/dist/esm/map-state.js +29 -0
  37. package/dist/esm/map-style-updaters.js +652 -0
  38. package/dist/esm/map-style.js +27 -0
  39. package/dist/esm/merger-handler.js +96 -0
  40. package/dist/esm/middleware.js +19 -0
  41. package/dist/esm/provider-state-updaters.js +458 -0
  42. package/dist/esm/provider-state.js +28 -0
  43. package/dist/esm/root.js +201 -0
  44. package/dist/esm/ui-state-updaters.js +929 -0
  45. package/dist/esm/ui-state.js +30 -0
  46. package/dist/esm/vis-state-merger.js +1161 -0
  47. package/dist/esm/vis-state-selectors.js +24 -0
  48. package/dist/esm/vis-state-updaters.js +4320 -0
  49. package/dist/esm/vis-state.js +29 -0
  50. package/dist/ui-state-updaters.d.ts +15 -1
  51. package/dist/vis-state-updaters.d.ts +27 -0
  52. package/package.json +31 -22
  53. package/dist/combined-updaters.js +0 -491
  54. package/dist/composer-helpers.js +0 -101
  55. package/dist/composers.js +0 -22
  56. package/dist/core.js +0 -105
  57. package/dist/data-utils.js +0 -53
  58. package/dist/export-utils.js +0 -91
  59. package/dist/interaction-utils.js +0 -105
  60. package/dist/layer-utils.js +0 -635
  61. package/dist/map-state-updaters.js +0 -649
  62. package/dist/map-state.js +0 -35
  63. package/dist/map-style-updaters.js +0 -660
  64. package/dist/map-style.js +0 -33
  65. package/dist/merger-handler.js +0 -105
  66. package/dist/middleware.js +0 -27
  67. package/dist/provider-state-updaters.js +0 -465
  68. package/dist/provider-state.js +0 -34
  69. package/dist/root.js +0 -207
  70. package/dist/ui-state-updaters.js +0 -905
  71. package/dist/ui-state.js +0 -36
  72. package/dist/vis-state-merger.js +0 -1193
  73. package/dist/vis-state-selectors.js +0 -30
  74. package/dist/vis-state.js +0 -35
@@ -0,0 +1,1193 @@
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.VIS_STATE_MERGERS = void 0;
9
+ exports.createLayerFromConfig = createLayerFromConfig;
10
+ exports.insertLayerAtRightOrder = insertLayerAtRightOrder;
11
+ exports.isSavedLayerConfigV1 = isSavedLayerConfigV1;
12
+ exports.mergeAnimationConfig = mergeAnimationConfig;
13
+ exports.mergeAnnotations = mergeAnnotations;
14
+ exports.mergeDatasetsByOrder = mergeDatasetsByOrder;
15
+ exports.mergeEditor = mergeEditor;
16
+ exports.mergeEffects = mergeEffects;
17
+ exports.mergeFilters = mergeFilters;
18
+ exports.mergeInteractionTooltipConfig = mergeInteractionTooltipConfig;
19
+ exports.mergeInteractions = mergeInteractions;
20
+ exports.mergeLayerBlending = mergeLayerBlending;
21
+ exports.mergeLayerOrder = mergeLayerOrder;
22
+ exports.mergeLayers = mergeLayers;
23
+ exports.mergeOverlayBlending = mergeOverlayBlending;
24
+ exports.mergeSplitMaps = mergeSplitMaps;
25
+ exports.parseLayerConfig = parseLayerConfig;
26
+ exports.replaceFilterDatasetIds = replaceFilterDatasetIds;
27
+ exports.serializeEffect = serializeEffect;
28
+ exports.serializeFilter = serializeFilter;
29
+ exports.serializeLayer = serializeLayer;
30
+ exports.serializeVisState = serializeVisState;
31
+ exports.validateColumn = validateColumn;
32
+ exports.validateLayerWithData = validateLayerWithData;
33
+ exports.validateLayersByDatasets = validateLayersByDatasets;
34
+ exports.validateSavedLayerColumns = validateSavedLayerColumns;
35
+ exports.validateSavedTextLabel = validateSavedTextLabel;
36
+ exports.validateSavedVisualChannels = validateSavedVisualChannels;
37
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
38
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
39
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
40
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
41
+ var _uniq = _interopRequireDefault(require("lodash/uniq"));
42
+ var _pick = _interopRequireDefault(require("lodash/pick"));
43
+ var _flattenDeep = _interopRequireDefault(require("lodash/flattenDeep"));
44
+ var _deepmerge = _interopRequireDefault(require("deepmerge"));
45
+ var _utils = require("@kepler.gl/utils");
46
+ var _effects = require("@kepler.gl/effects");
47
+ var _commonUtils = require("@kepler.gl/common-utils");
48
+ var _constants = require("@kepler.gl/constants");
49
+ var _schemas = require("@kepler.gl/schemas");
50
+ var _table = require("@kepler.gl/table");
51
+ var _layerUtils = require("./layer-utils");
52
+ var _excluded = ["enabled"];
53
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
54
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
55
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
56
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
57
+ 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); }
58
+ 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; }
59
+ 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
60
+ // Copyright contributors to the kepler.gl project
61
+ /**
62
+ * Merge loaded filters with current state, if no fields or data are loaded
63
+ * save it for later
64
+ *
65
+ */
66
+ function mergeFilters(state, filtersToMerge, fromConfig) {
67
+ var preserveFilterOrder = fromConfig ? filtersToMerge === null || filtersToMerge === void 0 ? void 0 : filtersToMerge.map(function (l) {
68
+ return l.id;
69
+ }) : state.preserveFilterOrder;
70
+ if (!Array.isArray(filtersToMerge) || !filtersToMerge.length) {
71
+ return state;
72
+ }
73
+ var _validateFiltersUpdat = (0, _utils.validateFiltersUpdateDatasets)(state, filtersToMerge),
74
+ validated = _validateFiltersUpdat.validated,
75
+ failed = _validateFiltersUpdat.failed,
76
+ updatedDatasets = _validateFiltersUpdat.updatedDatasets;
77
+ var updatedFilters = insertItemBasedOnPreservedOrder(state.filters, validated, preserveFilterOrder);
78
+
79
+ // merge filter with existing
80
+ updatedFilters = (0, _table.resetFilterGpuMode)(updatedFilters);
81
+ updatedFilters = (0, _table.assignGpuChannels)(updatedFilters);
82
+ // filter data
83
+ var datasetsToFilter = (0, _uniq["default"])((0, _flattenDeep["default"])(validated.map(function (f) {
84
+ return f.dataId;
85
+ })));
86
+ var filtered = (0, _utils.applyFiltersToDatasets)(datasetsToFilter, updatedDatasets, updatedFilters, state.layers);
87
+ return _objectSpread(_objectSpread({}, state), {}, {
88
+ filters: updatedFilters,
89
+ datasets: filtered,
90
+ preserveFilterOrder: preserveFilterOrder,
91
+ filterToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.filterToBeMerged), (0, _toConsumableArray2["default"])(failed))
92
+ });
93
+ }
94
+
95
+ // replace dataId in saved Filter
96
+ function replaceFilterDatasetIds(savedFilter, dataId, dataIdToUse) {
97
+ var replaced = [];
98
+ savedFilter.forEach(function (filter) {
99
+ if (filter.dataId.includes(dataId)) {
100
+ var _filter$plotType;
101
+ var newDataId = filter.dataId.map(function (d) {
102
+ return d === dataId ? dataIdToUse : d;
103
+ });
104
+ var plotType;
105
+ // TODO: more generic approach to save plotType.colorsByDataId
106
+ if ((_filter$plotType = filter.plotType) !== null && _filter$plotType !== void 0 && (_filter$plotType = _filter$plotType.colorsByDataId) !== null && _filter$plotType !== void 0 && _filter$plotType[dataId]) {
107
+ var _filter$plotType2;
108
+ // replace colorByDataId in filter.plotType
109
+ var _ref = ((_filter$plotType2 = filter.plotType) === null || _filter$plotType2 === void 0 ? void 0 : _filter$plotType2.colorsByDataId) || {},
110
+ color = _ref[dataId],
111
+ rest = (0, _objectWithoutProperties2["default"])(_ref, [dataId].map(_toPropertyKey));
112
+ plotType = _objectSpread(_objectSpread({}, filter.plotType), {}, {
113
+ colorsByDataId: _objectSpread(_objectSpread({}, rest), {}, (0, _defineProperty2["default"])({}, dataIdToUse, color))
114
+ });
115
+ }
116
+ replaced.push(_objectSpread(_objectSpread({}, filter), {}, {
117
+ dataId: newDataId
118
+ }, plotType ? {
119
+ plotType: plotType
120
+ } : {}));
121
+ }
122
+ });
123
+ return replaced.length ? replaced : null;
124
+ }
125
+ function isSavedLayerConfigV1(layerConfig) {
126
+ // exported layer configuration contains visualChannels property
127
+ return layerConfig === null || layerConfig === void 0 ? void 0 : layerConfig.visualChannels;
128
+ }
129
+ function parseLayerConfig(schema, layerConfig) {
130
+ var _schema$parseSavedCon;
131
+ // assume the layer config is current version
132
+ var savedConfig = {
133
+ version: _schemas.CURRENT_VERSION,
134
+ config: {
135
+ visState: {
136
+ layers: [layerConfig],
137
+ layerOrder: [layerConfig.id]
138
+ }
139
+ }
140
+ };
141
+ return (_schema$parseSavedCon = schema.parseSavedConfig(savedConfig)) === null || _schema$parseSavedCon === void 0 || (_schema$parseSavedCon = _schema$parseSavedCon.visState) === null || _schema$parseSavedCon === void 0 || (_schema$parseSavedCon = _schema$parseSavedCon.layers) === null || _schema$parseSavedCon === void 0 ? void 0 : _schema$parseSavedCon[0];
142
+ }
143
+ function insertItemBasedOnPreservedOrder(currentItems, items) {
144
+ var preservedOrder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
145
+ var defaultStart = arguments.length > 3 ? arguments[3] : undefined;
146
+ var newItems = (0, _toConsumableArray2["default"])(currentItems);
147
+ var _iterator = _createForOfIteratorHelper(items),
148
+ _step;
149
+ try {
150
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
151
+ var item = _step.value;
152
+ var expectedIdx = preservedOrder.indexOf(item.id);
153
+ // insertAt the end by default
154
+ var insertAt = defaultStart ? 0 : newItems.length;
155
+ if (expectedIdx > 0) {
156
+ // look for layer to insert after
157
+ var i = expectedIdx + 1;
158
+ var preceedIdx = -1;
159
+ var _loop = function _loop() {
160
+ // keep looking for preceed layer that is already loaded
161
+ var preceedItemId = preservedOrder[i - 1];
162
+ preceedIdx = newItems.findIndex(function (d) {
163
+ return d.id === preceedItemId;
164
+ });
165
+ };
166
+ while (i-- > 0 && preceedIdx < 0) {
167
+ _loop();
168
+ }
169
+ if (preceedIdx > -1) {
170
+ // if found
171
+ insertAt = preceedIdx + 1;
172
+ }
173
+ }
174
+ newItems = (0, _utils.arrayInsert)(newItems, insertAt, item);
175
+ }
176
+ } catch (err) {
177
+ _iterator.e(err);
178
+ } finally {
179
+ _iterator.f();
180
+ }
181
+ return newItems;
182
+ }
183
+ function createLayerFromConfig(state, layerConfig) {
184
+ // check if the layer config is parsed
185
+ var parsedLayerConfig = isSavedLayerConfigV1(layerConfig) ? parseLayerConfig(state.schema, layerConfig) : layerConfig;
186
+ if (!parsedLayerConfig) {
187
+ return null;
188
+ }
189
+ // first validate config against dataset
190
+ var _validateLayersByData = validateLayersByDatasets(state.datasets, state.layerClasses, [parsedLayerConfig], {
191
+ allowEmptyColumn: true
192
+ }),
193
+ validated = _validateLayersByData.validated,
194
+ failed = _validateLayersByData.failed;
195
+ if (failed !== null && failed !== void 0 && failed.length || !validated.length) {
196
+ // failed
197
+ return null;
198
+ }
199
+ var newLayer = validated[0];
200
+ newLayer.updateLayerDomain(state.datasets);
201
+ return newLayer;
202
+ }
203
+
204
+ /**
205
+ * Get loaded filter from state
206
+ */
207
+ function serializeFilter(newFilter, schema) {
208
+ var _serializedVisState$f;
209
+ var serializedVisState = serializeVisState({
210
+ filters: [newFilter]
211
+ }, schema);
212
+ return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$f = serializedVisState.filters) === null || _serializedVisState$f === void 0 ? void 0 : _serializedVisState$f[0];
213
+ }
214
+
215
+ /**
216
+ * Get loaded layer from state
217
+ */
218
+ function serializeLayer(newLayer, schema) {
219
+ var _serializedVisState$l;
220
+ var serializedVisState = serializeVisState({
221
+ layers: [newLayer],
222
+ layerOrder: [newLayer.id]
223
+ }, schema);
224
+ return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$l = serializedVisState.layers) === null || _serializedVisState$l === void 0 ? void 0 : _serializedVisState$l[0];
225
+ }
226
+
227
+ /**
228
+ * Get loaded effect from state
229
+ */
230
+ function serializeEffect(newEffect, schema) {
231
+ var _serializedVisState$e;
232
+ var serializedVisState = serializeVisState({
233
+ effects: [newEffect],
234
+ effectOrder: [newEffect.id]
235
+ }, schema);
236
+ return serializedVisState === null || serializedVisState === void 0 || (_serializedVisState$e = serializedVisState.effects) === null || _serializedVisState$e === void 0 ? void 0 : _serializedVisState$e[0];
237
+ }
238
+
239
+ /**
240
+ * Get vis state config
241
+ */
242
+ function serializeVisState(visState, schema) {
243
+ var _schema$parseSavedCon2;
244
+ var savedState = schema.getConfigToSave({
245
+ visState: visState
246
+ });
247
+ return savedState ? (_schema$parseSavedCon2 = schema.parseSavedConfig(savedState)) === null || _schema$parseSavedCon2 === void 0 ? void 0 : _schema$parseSavedCon2.visState : undefined;
248
+ }
249
+ /**
250
+ * Merge layers from de-serialized state, if no fields or data are loaded
251
+ * save it for later
252
+ *
253
+ */
254
+ function mergeLayers(state) {
255
+ var layersToMerge = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
256
+ var fromConfig = arguments.length > 2 ? arguments[2] : undefined;
257
+ var preserveLayerOrder = fromConfig ? (0, _layerUtils.getLayerOrderFromLayers)(layersToMerge) : state.preserveLayerOrder;
258
+ if (!Array.isArray(layersToMerge) || !layersToMerge.length) {
259
+ return state;
260
+ }
261
+ // don't merge layer if dataset is being merged
262
+ var unmerged = [];
263
+ var toMerge = [];
264
+ layersToMerge.forEach(function (l) {
265
+ var _l$config;
266
+ if (l !== null && l !== void 0 && (_l$config = l.config) !== null && _l$config !== void 0 && _l$config.dataId && state.isMergingDatasets[l.config.dataId]) {
267
+ unmerged.push(l);
268
+ } else {
269
+ toMerge.push(l);
270
+ }
271
+ });
272
+ var _validateLayersByData2 = validateLayersByDatasets(state.datasets, state.layerClasses, toMerge),
273
+ mergedLayer = _validateLayersByData2.validated,
274
+ failed = _validateLayersByData2.failed;
275
+ unmerged.push.apply(unmerged, (0, _toConsumableArray2["default"])(failed));
276
+ // put new layers in front of current layers
277
+ var _insertLayerAtRightOr = insertLayerAtRightOrder(state.layers, mergedLayer, state.layerOrder, preserveLayerOrder),
278
+ newLayerOrder = _insertLayerAtRightOr.newLayerOrder,
279
+ newLayers = _insertLayerAtRightOr.newLayers;
280
+ var mergedState = _objectSpread(_objectSpread({}, state), {}, {
281
+ layers: newLayers,
282
+ layerOrder: newLayerOrder,
283
+ preserveLayerOrder: preserveLayerOrder,
284
+ layerToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.layerToBeMerged), unmerged)
285
+ });
286
+
287
+ // Apply pending layerOrder with groups if layers are now available
288
+ if (mergedState.layerOrderToBeMerged && mergedState.layers.length > 0) {
289
+ var savedOrder = mergedState.layerOrderToBeMerged;
290
+ mergedState = mergeLayerOrder(mergedState, savedOrder);
291
+ // Keep savedLayerOrder available for future deferred layers
292
+ if (mergedState.layerToBeMerged.length > 0) {
293
+ mergedState = _objectSpread(_objectSpread({}, mergedState), {}, {
294
+ layerOrderToBeMerged: savedOrder
295
+ });
296
+ }
297
+ }
298
+ return mergedState;
299
+ }
300
+ function insertLayerAtRightOrder(currentLayers, layersToInsert, currentOrder) {
301
+ var preservedOrder = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
302
+ if (!(layersToInsert !== null && layersToInsert !== void 0 && layersToInsert.length)) {
303
+ return {
304
+ newLayers: currentLayers,
305
+ newLayerOrder: currentOrder
306
+ };
307
+ }
308
+ var currentLayerQueue = currentOrder.filter(function (entry) {
309
+ return typeof entry === 'string';
310
+ }).map(function (id) {
311
+ return (0, _utils.findById)(id)(currentLayers);
312
+ }).filter(function (layer) {
313
+ return Boolean(layer);
314
+ });
315
+ var newLayers = currentLayers.concat(layersToInsert);
316
+ var newLayerOrderQueue = insertItemBasedOnPreservedOrder(currentLayerQueue, layersToInsert, preservedOrder, true);
317
+ var newFlatLayerOrder = (0, _layerUtils.getLayerOrderFromLayers)(newLayerOrderQueue);
318
+
319
+ // If no groups exist in current order, just use the new flat order
320
+ var hasGroups = currentOrder.some(function (entry) {
321
+ return (0, _utils.isPlainObject)(entry);
322
+ });
323
+ if (!hasGroups) {
324
+ return {
325
+ newLayerOrder: newFlatLayerOrder,
326
+ newLayers: newLayers
327
+ };
328
+ }
329
+
330
+ // Rebuild layerOrder preserving groups in their relative positions.
331
+ // Replace each string entry with its updated position from newFlatLayerOrder,
332
+ // and keep groups as-is.
333
+ var existingFlatIds = new Set(currentOrder.filter(function (entry) {
334
+ return typeof entry === 'string';
335
+ }));
336
+ var newInsertedIds = newFlatLayerOrder.filter(function (id) {
337
+ return !existingFlatIds.has(id);
338
+ });
339
+
340
+ // Rebuild: walk through currentOrder, replace string entries with their
341
+ // new position equivalents from newFlatLayerOrder, then append any newly inserted layers
342
+ var result = [];
343
+ var flatQueue = (0, _toConsumableArray2["default"])(newFlatLayerOrder.filter(function (id) {
344
+ return existingFlatIds.has(id);
345
+ }));
346
+ var flatIdx = 0;
347
+ var _iterator2 = _createForOfIteratorHelper(currentOrder),
348
+ _step2;
349
+ try {
350
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
351
+ var entry = _step2.value;
352
+ if ((0, _utils.isPlainObject)(entry)) {
353
+ result.push(entry);
354
+ } else {
355
+ // Replace with corresponding entry from reordered flat list
356
+ if (flatIdx < flatQueue.length) {
357
+ result.push(flatQueue[flatIdx]);
358
+ flatIdx++;
359
+ }
360
+ }
361
+ }
362
+
363
+ // Append any newly inserted layers at the front (they are new)
364
+ } catch (err) {
365
+ _iterator2.e(err);
366
+ } finally {
367
+ _iterator2.f();
368
+ }
369
+ return {
370
+ newLayerOrder: [].concat((0, _toConsumableArray2["default"])(newInsertedIds), result),
371
+ newLayers: newLayers
372
+ };
373
+ }
374
+
375
+ /**
376
+ * Merge saved layerOrder with current state to restore layer groups.
377
+ * Called after layers have been merged. If the saved config contains a layerOrder
378
+ * with groups, this replaces the flat layerOrder with the saved hierarchical one,
379
+ * filtering out any layer IDs that don't exist in the current state.
380
+ */
381
+ function mergeLayerOrder(state, savedLayerOrder, fromConfig) {
382
+ if (!savedLayerOrder || !Array.isArray(savedLayerOrder) || savedLayerOrder.length === 0) {
383
+ return state;
384
+ }
385
+
386
+ // Check if the saved layerOrder contains any groups
387
+ var hasGroups = savedLayerOrder.some(function (entry) {
388
+ return (0, _utils.isPlainObject)(entry);
389
+ });
390
+ if (!hasGroups) {
391
+ // No groups - the layer merger already handled ordering via preserveLayerOrder
392
+ return state;
393
+ }
394
+
395
+ // If layers haven't been merged yet, store for later
396
+ if (state.layers.length === 0) {
397
+ return _objectSpread(_objectSpread({}, state), {}, {
398
+ layerOrderToBeMerged: savedLayerOrder
399
+ });
400
+ }
401
+
402
+ // Build a set of valid layer IDs from current state
403
+ var validLayerIds = new Set(state.layers.map(function (l) {
404
+ return l.id;
405
+ }));
406
+
407
+ // Recursively filter the saved layerOrder to only include valid layers
408
+ function filterLayerOrder(order) {
409
+ var result = [];
410
+ var _iterator3 = _createForOfIteratorHelper(order),
411
+ _step3;
412
+ try {
413
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
414
+ var entry = _step3.value;
415
+ if ((0, _utils.isPlainObject)(entry)) {
416
+ var group = entry;
417
+ var filteredGroupOrder = filterLayerOrder(group.layerOrder);
418
+ // Keep the group even if empty (user may want the empty group)
419
+ result.push(_objectSpread(_objectSpread({}, group), {}, {
420
+ layerOrder: filteredGroupOrder
421
+ }));
422
+ } else if (typeof entry === 'string' && validLayerIds.has(entry)) {
423
+ result.push(entry);
424
+ }
425
+ }
426
+ } catch (err) {
427
+ _iterator3.e(err);
428
+ } finally {
429
+ _iterator3.f();
430
+ }
431
+ return result;
432
+ }
433
+ var restoredLayerOrder = filterLayerOrder(savedLayerOrder);
434
+
435
+ // Find any layers in the current state that aren't in the restored order
436
+ // (could happen if layers were added between save and load)
437
+ var layerIdsInRestored = new Set();
438
+ function collectIds(order) {
439
+ var _iterator4 = _createForOfIteratorHelper(order),
440
+ _step4;
441
+ try {
442
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
443
+ var entry = _step4.value;
444
+ if ((0, _utils.isPlainObject)(entry)) {
445
+ collectIds(entry.layerOrder);
446
+ } else if (typeof entry === 'string') {
447
+ layerIdsInRestored.add(entry);
448
+ }
449
+ }
450
+ } catch (err) {
451
+ _iterator4.e(err);
452
+ } finally {
453
+ _iterator4.f();
454
+ }
455
+ }
456
+ collectIds(restoredLayerOrder);
457
+
458
+ // Add any missing layers at the top
459
+ var missingLayers = state.layers.filter(function (l) {
460
+ return !layerIdsInRestored.has(l.id);
461
+ }).map(function (l) {
462
+ return l.id;
463
+ });
464
+ return _objectSpread(_objectSpread({}, state), {}, {
465
+ layerOrder: [].concat((0, _toConsumableArray2["default"])(missingLayers), (0, _toConsumableArray2["default"])(restoredLayerOrder)),
466
+ layerOrderToBeMerged: null
467
+ });
468
+ }
469
+
470
+ /**
471
+ * Merge interactions with saved config
472
+ *
473
+ */
474
+ function mergeInteractions(state, interactionToBeMerged) {
475
+ var merged = {};
476
+ var unmerged = {};
477
+ if (interactionToBeMerged) {
478
+ Object.keys(interactionToBeMerged).forEach(function (key) {
479
+ if (!state.interactionConfig[key]) {
480
+ return;
481
+ }
482
+ var currentConfig = key === 'tooltip' || key === 'brush' || key === 'geocoder' ? state.interactionConfig[key].config : null;
483
+ var _ref2 = interactionToBeMerged[key] || {},
484
+ enabled = _ref2.enabled,
485
+ configSaved = (0, _objectWithoutProperties2["default"])(_ref2, _excluded);
486
+ var configToMerge = configSaved;
487
+ if (key === 'tooltip') {
488
+ var _mergeInteractionTool = mergeInteractionTooltipConfig(state, configSaved),
489
+ mergedTooltip = _mergeInteractionTool.mergedTooltip,
490
+ unmergedTooltip = _mergeInteractionTool.unmergedTooltip;
491
+
492
+ // merge new dataset tooltips with original dataset tooltips
493
+ configToMerge = {
494
+ fieldsToShow: _objectSpread(_objectSpread({}, currentConfig.fieldsToShow), mergedTooltip)
495
+ };
496
+ if (Object.keys(unmergedTooltip).length) {
497
+ // @ts-expect-error
498
+ unmerged.tooltip = {
499
+ fieldsToShow: unmergedTooltip,
500
+ enabled: Boolean(enabled)
501
+ };
502
+ }
503
+ }
504
+ merged[key] = _objectSpread(_objectSpread({}, state.interactionConfig[key]), {}, {
505
+ enabled: Boolean(enabled)
506
+ }, currentConfig ? {
507
+ config: (0, _pick["default"])(_objectSpread(_objectSpread({}, currentConfig), configToMerge), Object.keys(currentConfig))
508
+ } : {});
509
+ });
510
+ }
511
+ var nextState = _objectSpread(_objectSpread({}, state), {}, {
512
+ interactionConfig: _objectSpread(_objectSpread({}, state.interactionConfig), merged),
513
+ interactionToBeMerged: savedUnmergedInteraction(state, unmerged)
514
+ });
515
+ return nextState;
516
+ }
517
+ function combineInteractionConfigs(configs) {
518
+ var combined = _objectSpread({}, configs[0]);
519
+ // handle each property key of an `InteractionConfig`, e.g. tooltip, geocoder, brush, coordinate
520
+ // by combining values for each among all passed in configs
521
+ var _loop2 = function _loop2(key) {
522
+ var toBeCombinedProps = configs.map(function (c) {
523
+ return c[key];
524
+ });
525
+
526
+ // all of these have an enabled boolean
527
+ combined[key] = {
528
+ // are any of the configs' enabled values true?
529
+ enabled: toBeCombinedProps.some(function (p) {
530
+ return p === null || p === void 0 ? void 0 : p.enabled;
531
+ })
532
+ };
533
+ if (key === 'tooltip') {
534
+ // are any of the configs' compareMode values true?
535
+ combined[key].compareMode = toBeCombinedProps.some(function (p) {
536
+ return p === null || p === void 0 ? void 0 : p.compareMode;
537
+ });
538
+
539
+ // return the compare type mode, it will be either absolute or relative
540
+ combined[key].compareType = getValueWithHighestOccurrence(toBeCombinedProps.map(function (p) {
541
+ return p.compareType;
542
+ }));
543
+
544
+ // combine fieldsToShow among all dataset ids
545
+ combined[key].fieldsToShow = toBeCombinedProps.map(function (p) {
546
+ return p.fieldsToShow;
547
+ }).reduce(function (acc, nextFieldsToShow) {
548
+ var _loop3 = function _loop3(nextDataIdKey) {
549
+ var nextTooltipFields = nextFieldsToShow[nextDataIdKey];
550
+ if (!acc[nextDataIdKey]) {
551
+ // if the dataset id is not present in the accumulator
552
+ // then add it with its tooltip fields
553
+ acc[nextDataIdKey] = nextTooltipFields;
554
+ } else {
555
+ // otherwise the dataset id is already present in the accumulator
556
+ // so only add the next tooltip fields for this dataset's array if they are not already present,
557
+ // using the tooltipField.name property for uniqueness
558
+ nextTooltipFields.forEach(function (nextTF) {
559
+ if (!acc[nextDataIdKey].find(function (_ref3) {
560
+ var name = _ref3.name;
561
+ return nextTF.name === name;
562
+ })) {
563
+ acc[nextDataIdKey].push(nextTF);
564
+ }
565
+ });
566
+ }
567
+ };
568
+ for (var nextDataIdKey in nextFieldsToShow) {
569
+ _loop3(nextDataIdKey);
570
+ }
571
+ return acc;
572
+ }, {});
573
+ }
574
+ if (key === 'brush') {
575
+ var _aggregate;
576
+ // keep the biggest brush size
577
+ combined[key].size = (_aggregate = (0, _utils.aggregate)(toBeCombinedProps, _constants.AGGREGATION_TYPES.maximum, function (p) {
578
+ return p.size;
579
+ })) !== null && _aggregate !== void 0 ? _aggregate : null;
580
+ }
581
+ if (key === 'geocoder') {
582
+ combined[key].limitSearch = toBeCombinedProps.some(function (p) {
583
+ return p === null || p === void 0 ? void 0 : p.limitSearch;
584
+ });
585
+ }
586
+ };
587
+ for (var key in combined) {
588
+ _loop2(key);
589
+ }
590
+ return combined;
591
+ }
592
+ function savedUnmergedInteraction(state, unmerged) {
593
+ var _unmerged$tooltip, _unmerged$tooltip2, _state$interactionToB, _unmerged$tooltip3;
594
+ if (!(unmerged !== null && unmerged !== void 0 && (_unmerged$tooltip = unmerged.tooltip) !== null && _unmerged$tooltip !== void 0 && _unmerged$tooltip.fieldsToShow)) {
595
+ return state.interactionToBeMerged;
596
+ }
597
+ return {
598
+ tooltip: _objectSpread(_objectSpread(_objectSpread({}, state.interactionToBeMerged.tooltip), typeof (unmerged === null || unmerged === void 0 || (_unmerged$tooltip2 = unmerged.tooltip) === null || _unmerged$tooltip2 === void 0 ? void 0 : _unmerged$tooltip2.enabled) === 'boolean' ? {
599
+ enabled: unmerged.tooltip.enabled
600
+ } : {}), {}, {
601
+ fieldsToShow: _objectSpread(_objectSpread({}, (_state$interactionToB = state.interactionToBeMerged) === null || _state$interactionToB === void 0 || (_state$interactionToB = _state$interactionToB.tooltip) === null || _state$interactionToB === void 0 ? void 0 : _state$interactionToB.fieldsToShow), unmerged === null || unmerged === void 0 || (_unmerged$tooltip3 = unmerged.tooltip) === null || _unmerged$tooltip3 === void 0 ? void 0 : _unmerged$tooltip3.fieldsToShow)
602
+ })
603
+ };
604
+ }
605
+ function replaceInteractionDatasetIds(interactionConfig, dataId, dataIdToReplace) {
606
+ var _interactionConfig$to;
607
+ if (interactionConfig !== null && interactionConfig !== void 0 && (_interactionConfig$to = interactionConfig.tooltip) !== null && _interactionConfig$to !== void 0 && _interactionConfig$to.fieldsToShow[dataId]) {
608
+ var _interactionConfig$to2;
609
+ return _objectSpread(_objectSpread({}, interactionConfig), {}, {
610
+ tooltip: _objectSpread(_objectSpread({}, interactionConfig.tooltip), {}, {
611
+ fieldsToShow: (0, _defineProperty2["default"])({}, dataIdToReplace, interactionConfig === null || interactionConfig === void 0 || (_interactionConfig$to2 = interactionConfig.tooltip) === null || _interactionConfig$to2 === void 0 ? void 0 : _interactionConfig$to2.fieldsToShow[dataId])
612
+ })
613
+ });
614
+ }
615
+ return null;
616
+ }
617
+
618
+ /**
619
+ * Merge splitMaps config with current visStete.
620
+ * 1. if current map is split, but splitMap DOESNOT contain maps
621
+ * : don't merge anything
622
+ * 2. if current map is NOT split, but splitMaps contain maps
623
+ * : add to splitMaps, and add current layers to splitMaps
624
+ */
625
+ function mergeSplitMaps(state) {
626
+ var splitMaps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
627
+ var merged = (0, _toConsumableArray2["default"])(state.splitMaps);
628
+ var unmerged = [];
629
+ splitMaps.forEach(function (sm, i) {
630
+ var entries = Object.entries(sm.layers);
631
+ if (entries.length > 0) {
632
+ entries.forEach(function (_ref4) {
633
+ var _ref5 = (0, _slicedToArray2["default"])(_ref4, 2),
634
+ id = _ref5[0],
635
+ value = _ref5[1];
636
+ // check if layer exists
637
+ var pushTo = state.layers.find(function (l) {
638
+ return l.id === id;
639
+ }) ? merged : unmerged;
640
+
641
+ // create map panel if current map is not split
642
+ pushTo[i] = pushTo[i] || _objectSpread(_objectSpread({}, sm), {}, {
643
+ layers: pushTo === merged ? (0, _utils.getInitialMapLayersForSplitMap)(state.layers) : []
644
+ });
645
+ pushTo[i].layers = _objectSpread(_objectSpread({}, pushTo[i].layers), {}, (0, _defineProperty2["default"])({}, id, value));
646
+ });
647
+ } else {
648
+ // We are merging if there are no layers in both split map
649
+ merged.push(sm);
650
+ }
651
+ });
652
+ return _objectSpread(_objectSpread({}, state), {}, {
653
+ splitMaps: merged,
654
+ splitMapsToBeMerged: [].concat((0, _toConsumableArray2["default"])(state.splitMapsToBeMerged), unmerged)
655
+ });
656
+ }
657
+
658
+ /**
659
+ * Merge effects with saved config
660
+ */
661
+ function mergeEffects(state, effects, fromConfig) {
662
+ var newEffects = [].concat((0, _toConsumableArray2["default"])(state.effects), (0, _toConsumableArray2["default"])((effects || []).map(function (effect) {
663
+ return fromConfig ? (0, _effects.createEffect)(_deepmerge["default"].all([effect, {
664
+ // collapse all panels when loading effects
665
+ isConfigActive: false
666
+ }])) : effect;
667
+ }).filter(function (effect) {
668
+ return Boolean(effect && effect.isValidToSave());
669
+ })));
670
+ return _objectSpread(_objectSpread({}, state), {}, {
671
+ effects: newEffects,
672
+ effectOrder: newEffects.map(function (effect) {
673
+ return effect.id;
674
+ })
675
+ });
676
+ }
677
+
678
+ /**
679
+ * Merge annotations with saved config
680
+ */
681
+ function mergeAnnotations(state, annotations) {
682
+ if (!annotations || !annotations.length) {
683
+ return state;
684
+ }
685
+ var existingIds = new Set(state.annotations.map(function (a) {
686
+ return a.id;
687
+ }));
688
+ var validAnnotations = annotations.filter(function (a) {
689
+ return a && a.id && !existingIds.has(a.id) && (0, _constants.isAnnotationKind)(a.kind) && Array.isArray(a.anchorPoint) && a.anchorPoint.length === 2;
690
+ }).map(function (a) {
691
+ return _objectSpread({
692
+ isVisible: true,
693
+ autoSize: true,
694
+ autoSizeY: true,
695
+ label: '',
696
+ lineColor: _constants.INITIAL_ANNOTATION_LINE_COLOR,
697
+ lineWidth: _constants.INITIAL_ANNOTATION_LINE_WIDTH,
698
+ textWidth: 0,
699
+ textHeight: 0
700
+ }, a);
701
+ });
702
+ if (!validAnnotations.length) {
703
+ return state;
704
+ }
705
+ return _objectSpread(_objectSpread({}, state), {}, {
706
+ annotations: [].concat((0, _toConsumableArray2["default"])(state.annotations), (0, _toConsumableArray2["default"])(validAnnotations))
707
+ });
708
+ }
709
+
710
+ /**
711
+ * Merge interactionConfig.tooltip with saved config,
712
+ * validate fieldsToShow
713
+ *
714
+ * @param state
715
+ * @param tooltipConfig
716
+ * @return - {mergedTooltip: {}, unmergedTooltip: {}}
717
+ */
718
+ function mergeInteractionTooltipConfig(state) {
719
+ var tooltipConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
720
+ var unmergedTooltip = {};
721
+ var mergedTooltip = {};
722
+ if (!tooltipConfig || !tooltipConfig.fieldsToShow || !Object.keys(tooltipConfig.fieldsToShow).length) {
723
+ return {
724
+ mergedTooltip: mergedTooltip,
725
+ unmergedTooltip: unmergedTooltip
726
+ };
727
+ }
728
+ var _loop4 = function _loop4() {
729
+ if (!state.datasets[dataId] || state.isMergingDatasets[dataId]) {
730
+ // is not yet loaded
731
+ unmergedTooltip[dataId] = tooltipConfig.fieldsToShow[dataId];
732
+ } else {
733
+ // if dataset is loaded
734
+ var allFields = state.datasets[dataId].fields.map(function (d) {
735
+ return d.name;
736
+ });
737
+ var foundFieldsToShow = tooltipConfig.fieldsToShow[dataId].filter(function (field) {
738
+ return allFields.includes(field.name);
739
+ });
740
+ mergedTooltip[dataId] = foundFieldsToShow;
741
+ }
742
+ };
743
+ for (var dataId in tooltipConfig.fieldsToShow) {
744
+ _loop4();
745
+ }
746
+ return {
747
+ mergedTooltip: mergedTooltip,
748
+ unmergedTooltip: unmergedTooltip
749
+ };
750
+ }
751
+ /**
752
+ * Merge layerBlending with saved
753
+ *
754
+ */
755
+ function mergeLayerBlending(state, layerBlending) {
756
+ if (layerBlending && _constants.LAYER_BLENDINGS[layerBlending]) {
757
+ return _objectSpread(_objectSpread({}, state), {}, {
758
+ layerBlending: layerBlending
759
+ });
760
+ }
761
+ return state;
762
+ }
763
+
764
+ /**
765
+ * Combines multiple layer blending configs into a single string
766
+ * by returning the one with the highest occurrence
767
+ */
768
+ function combineLayerBlendingConfigs(configs) {
769
+ // return the mode of the layer blending type
770
+ return getValueWithHighestOccurrence(configs);
771
+ }
772
+
773
+ /**
774
+ * Merge overlayBlending with saved
775
+ */
776
+ function mergeOverlayBlending(state, overlayBlending) {
777
+ if (overlayBlending && _constants.OVERLAY_BLENDINGS[overlayBlending]) {
778
+ return _objectSpread(_objectSpread({}, state), {}, {
779
+ overlayBlending: overlayBlending
780
+ });
781
+ }
782
+ return state;
783
+ }
784
+
785
+ /**
786
+ * Combines multiple overlay blending configs into a single string
787
+ * by returning the one with the highest occurrence
788
+ **/
789
+ function combineOverlayBlendingConfigs(configs) {
790
+ // return the mode of the overlay blending type
791
+ return getValueWithHighestOccurrence(configs);
792
+ }
793
+
794
+ /**
795
+ * Merge animation config
796
+ */
797
+ function mergeAnimationConfig(state, animation) {
798
+ if (animation && animation.currentTime) {
799
+ return _objectSpread(_objectSpread({}, state), {}, {
800
+ animationConfig: _objectSpread(_objectSpread(_objectSpread({}, state.animationConfig), animation), {}, {
801
+ domain: null
802
+ })
803
+ });
804
+ }
805
+ return state;
806
+ }
807
+ function combineAnimationConfigs(configs) {
808
+ var _aggregate2, _aggregate3;
809
+ // get the smallest values of currentTime and speed among all configs
810
+ return {
811
+ currentTime: (_aggregate2 = (0, _utils.aggregate)(configs, _constants.AGGREGATION_TYPES.minimum, function (c) {
812
+ return c.currentTime;
813
+ })) !== null && _aggregate2 !== void 0 ? _aggregate2 : null,
814
+ speed: (_aggregate3 = (0, _utils.aggregate)(configs, _constants.AGGREGATION_TYPES.minimum, function (c) {
815
+ return c.speed;
816
+ })) !== null && _aggregate3 !== void 0 ? _aggregate3 : null
817
+ };
818
+ }
819
+
820
+ /**
821
+ * Validate saved layer columns with new data,
822
+ * update fieldIdx based on new fields
823
+ *
824
+ * @param fields
825
+ * @param savedCols
826
+ * @param emptyCols
827
+ * @param options
828
+ * @return - validated columns or null
829
+ */
830
+
831
+ function validateSavedLayerColumns(fields) {
832
+ var savedCols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
833
+ var emptyCols = arguments.length > 2 ? arguments[2] : undefined;
834
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
835
+ // Prepare columns for the validator
836
+ var columns = {};
837
+ var _loop5 = function _loop5() {
838
+ var key = _Object$keys[_i];
839
+ columns[key] = _objectSpread({}, emptyCols[key]);
840
+ var saved = savedCols[key];
841
+ if (saved) {
842
+ var fieldIdx = fields.findIndex(function (_ref6) {
843
+ var name = _ref6.name;
844
+ return name === saved;
845
+ });
846
+ if (fieldIdx > -1) {
847
+ // update found columns
848
+ columns[key].fieldIdx = fieldIdx;
849
+ columns[key].value = saved;
850
+ }
851
+ }
852
+ };
853
+ for (var _i = 0, _Object$keys = Object.keys(emptyCols); _i < _Object$keys.length; _i++) {
854
+ _loop5();
855
+ }
856
+
857
+ // find actual column fieldIdx, in case it has changed
858
+ var allColFound = Object.keys(columns).every(function (key) {
859
+ return validateColumn(columns[key], columns, fields);
860
+ });
861
+ var rv = allColFound ? columns : null;
862
+ if (options.throwOnError) {
863
+ var requiredColumns = Object.keys(emptyCols).filter(function (k) {
864
+ return !emptyCols[k].optional;
865
+ });
866
+ var missingColumns = requiredColumns.filter(function (k) {
867
+ return !(columns !== null && columns !== void 0 && columns[k].value);
868
+ });
869
+ if (missingColumns.length) {
870
+ throw new Error("Layer has missing or invalid columns: ".concat(missingColumns.join(', ')));
871
+ }
872
+ var configColumns = Object.keys(savedCols);
873
+ var invalidColumns = configColumns.filter(function (k) {
874
+ var _columns$k;
875
+ return !(columns !== null && columns !== void 0 && (_columns$k = columns[k]) !== null && _columns$k !== void 0 && _columns$k.value);
876
+ });
877
+ if (invalidColumns.length) {
878
+ throw new Error("Layer has invalid columns: ".concat(invalidColumns.join(', ')));
879
+ }
880
+ }
881
+ return rv;
882
+ }
883
+
884
+ /**
885
+ * Validate layer column
886
+ */
887
+ function validateColumn(column, columns, allFields) {
888
+ if (column.optional || column.value) {
889
+ return true;
890
+ }
891
+ if (column.validator) {
892
+ return column.validator(column, columns, allFields);
893
+ }
894
+ return false;
895
+ }
896
+
897
+ /**
898
+ * Validate saved text label config with new data
899
+ * refer to vis-state-schema.js TextLabelSchemaV1
900
+ *
901
+ * @param {Array<Object>} fields
902
+ * @param {Object} savedTextLabel
903
+ * @param {Object} options
904
+ * @return {Object} - validated textlabel
905
+ */
906
+ function validateSavedTextLabel(fields, _ref7, savedTextLabel) {
907
+ var _ref8 = (0, _slicedToArray2["default"])(_ref7, 1),
908
+ layerTextLabel = _ref8[0];
909
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
910
+ var savedTextLabels = Array.isArray(savedTextLabel) ? savedTextLabel : [savedTextLabel];
911
+
912
+ // validate field
913
+ return savedTextLabels.map(function (textLabel) {
914
+ var field = textLabel.field ? fields.find(function (fd) {
915
+ return Object.keys(textLabel.field).every(function (key) {
916
+ return textLabel.field[key] === fd[key];
917
+ });
918
+ }) : null;
919
+ if (field === undefined && options.throwOnError) {
920
+ throw new Error("Layer has invalid text label field: ".concat(JSON.stringify(textLabel.field)));
921
+ }
922
+ return Object.keys(layerTextLabel).reduce(function (accu, key) {
923
+ return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, key === 'field' ? field : textLabel[key] || layerTextLabel[key]));
924
+ }, {});
925
+ });
926
+ }
927
+
928
+ /**
929
+ * Validate saved visual channels config with new data,
930
+ * refer to vis-state-schema.js VisualChannelSchemaV1
931
+ */
932
+ function validateSavedVisualChannels(fields, newLayer, savedLayer) {
933
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
934
+ Object.values(newLayer.visualChannels).forEach(function (_ref9) {
935
+ var field = _ref9.field,
936
+ scale = _ref9.scale,
937
+ key = _ref9.key;
938
+ var foundField;
939
+ if (savedLayer.config) {
940
+ if (savedLayer.config[field]) {
941
+ foundField = fields.find(function (fd) {
942
+ return savedLayer.config && fd.name === savedLayer.config[field].name;
943
+ });
944
+ }
945
+ var foundChannel = _objectSpread(_objectSpread({}, foundField ? (0, _defineProperty2["default"])({}, field, foundField) : {}), savedLayer.config[scale] ? (0, _defineProperty2["default"])({}, scale, savedLayer.config[scale]) : {});
946
+ if (Object.keys(foundChannel).length) {
947
+ newLayer.updateLayerConfig(foundChannel);
948
+ }
949
+ newLayer.validateVisualChannel(key);
950
+ if (options.throwOnError) {
951
+ var _savedLayer$config, _newLayer$config$fiel;
952
+ var fieldName = (_savedLayer$config = savedLayer.config) === null || _savedLayer$config === void 0 || (_savedLayer$config = _savedLayer$config[field]) === null || _savedLayer$config === void 0 ? void 0 : _savedLayer$config.name;
953
+ if (fieldName && fieldName !== ((_newLayer$config$fiel = newLayer.config[field]) === null || _newLayer$config$fiel === void 0 ? void 0 : _newLayer$config$fiel.name)) {
954
+ throw new Error("Layer has invalid visual channel field: ".concat(field));
955
+ }
956
+ }
957
+ }
958
+ });
959
+ return newLayer;
960
+ }
961
+ function validateLayersByDatasets(datasets, layerClasses) {
962
+ var layers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
963
+ var options = arguments.length > 3 ? arguments[3] : undefined;
964
+ var validated = [];
965
+ var failed = [];
966
+ layers.forEach(function (layer) {
967
+ var _layer$config;
968
+ var validateLayer = null;
969
+ if (layer !== null && layer !== void 0 && (_layer$config = layer.config) !== null && _layer$config !== void 0 && _layer$config.dataId) {
970
+ if (datasets[layer.config.dataId]) {
971
+ // datasets are already loaded
972
+ validateLayer = validateLayerWithData(datasets[layer.config.dataId], layer, layerClasses, options);
973
+ }
974
+ }
975
+ if (validateLayer) {
976
+ validated.push(validateLayer);
977
+ } else {
978
+ // datasets not yet loaded
979
+ failed.push(layer);
980
+ }
981
+ });
982
+ return {
983
+ validated: validated,
984
+ failed: failed
985
+ };
986
+ }
987
+
988
+ /**
989
+ * Get required columns for validation based on column mode
990
+ */
991
+ function _getColumnConfigForValidation(newLayer) {
992
+ // find column fieldIdx
993
+ var columnConfig = newLayer.getLayerColumns();
994
+ // if columnMode is defined, find column mode config
995
+ var colModeConfig = newLayer.config.columnMode ? (newLayer.supportedColumnModes || []).find(function (colMode) {
996
+ return colMode.key === newLayer.config.columnMode;
997
+ }) : null;
998
+ if (colModeConfig) {
999
+ // only validate columns in column mode
1000
+ columnConfig = [].concat((0, _toConsumableArray2["default"])(colModeConfig.requiredColumns || []), (0, _toConsumableArray2["default"])(colModeConfig.optionalColumns || [])).reduce(function (accu, key) {
1001
+ return _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, key, columnConfig[key]));
1002
+ }, {});
1003
+ }
1004
+ return columnConfig;
1005
+ }
1006
+
1007
+ /**
1008
+ * Validate saved layer config with new data,
1009
+ * update fieldIdx based on new fields
1010
+ */
1011
+ // eslint-disable-next-line complexity
1012
+ function validateLayerWithData(dataset, savedLayer, layerClasses) {
1013
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1014
+ var fields = dataset.fields,
1015
+ dataId = dataset.id;
1016
+ var type = savedLayer.type;
1017
+ var throwOnError = options.throwOnError;
1018
+ // layer doesnt have a valid type
1019
+ if (!type || !Object.prototype.hasOwnProperty.call(layerClasses, type) || !savedLayer.config) {
1020
+ if (throwOnError) {
1021
+ throw new Error("Layer has invalid type \"".concat(type, "\" or config is missing"));
1022
+ }
1023
+ return null;
1024
+ }
1025
+ var newLayer = new layerClasses[type]({
1026
+ id: savedLayer.id,
1027
+ dataId: dataId,
1028
+ label: savedLayer.config.label,
1029
+ color: savedLayer.config.color,
1030
+ isVisible: savedLayer.config.isVisible,
1031
+ hidden: savedLayer.config.hidden,
1032
+ columnMode: savedLayer.config.columnMode,
1033
+ highlightColor: savedLayer.config.highlightColor
1034
+ });
1035
+ var columnConfig = _getColumnConfigForValidation(newLayer);
1036
+ if (Object.keys(columnConfig)) {
1037
+ var columns = validateSavedLayerColumns(fields, savedLayer.config.columns, columnConfig, options);
1038
+ if (columns) {
1039
+ newLayer.updateLayerConfig({
1040
+ columns: _objectSpread(_objectSpread({}, newLayer.config.columns), columns)
1041
+ });
1042
+ } else if (!options.allowEmptyColumn) {
1043
+ return null;
1044
+ }
1045
+ }
1046
+ var textLabel = savedLayer.config.textLabel && newLayer.config.textLabel ? validateSavedTextLabel(fields, newLayer.config.textLabel, savedLayer.config.textLabel, options) : newLayer.config.textLabel;
1047
+
1048
+ // copy visConfig over to emptyLayer to make sure it has all the props
1049
+ var copiedVisConfig = newLayer.copyLayerConfig(newLayer.config.visConfig, savedLayer.config.visConfig || {}, {
1050
+ shallowCopy: ['colorRange', 'strokeColorRange']
1051
+ });
1052
+
1053
+ // call layer methods to validate visConfig when switching dataset
1054
+ var visConfig = newLayer.validateVisConfig ? newLayer.validateVisConfig(dataset, copiedVisConfig) : copiedVisConfig;
1055
+ newLayer.updateLayerConfig({
1056
+ visConfig: visConfig,
1057
+ textLabel: textLabel
1058
+ });
1059
+
1060
+ // visual channel field is saved to be {name, type}
1061
+ // find visual channel field by matching both name and type
1062
+ // refer to vis-state-schema.js VisualChannelSchemaV1
1063
+ newLayer = validateSavedVisualChannels(fields, newLayer, savedLayer, options);
1064
+ if (throwOnError) {
1065
+ if (!newLayer.isValidToSave()) {
1066
+ throw new Error("Layer is not valid to save: ".concat(newLayer.id));
1067
+ }
1068
+ }
1069
+ return newLayer;
1070
+ }
1071
+ function mergeEditor(state, savedEditor) {
1072
+ var _savedEditor$visible;
1073
+ if (!savedEditor) {
1074
+ return state;
1075
+ }
1076
+ return _objectSpread(_objectSpread({}, state), {}, {
1077
+ editor: _objectSpread(_objectSpread({}, state.editor), {}, {
1078
+ features: [].concat((0, _toConsumableArray2["default"])(state.editor.features), (0, _toConsumableArray2["default"])(savedEditor.features || [])),
1079
+ // if savedEditor.visible is undefined keep state.editor.visible
1080
+ visible: (_savedEditor$visible = savedEditor.visible) !== null && _savedEditor$visible !== void 0 ? _savedEditor$visible : state.editor.visible
1081
+ })
1082
+ });
1083
+ }
1084
+ function combineEditorConfigs(configs) {
1085
+ return configs.reduce(function (acc, nextConfig) {
1086
+ return _objectSpread(_objectSpread({}, acc), {}, {
1087
+ features: [].concat((0, _toConsumableArray2["default"])(acc.features), (0, _toConsumableArray2["default"])(nextConfig.features || []))
1088
+ });
1089
+ }, {
1090
+ // start with:
1091
+ // - empty array for features accumulation
1092
+ // - and are any of the configs' visible values true?
1093
+ features: [],
1094
+ visible: configs.some(function (c) {
1095
+ return c === null || c === void 0 ? void 0 : c.visible;
1096
+ })
1097
+ });
1098
+ }
1099
+
1100
+ /**
1101
+ * Validate saved layer config with new data,
1102
+ * update fieldIdx based on new fields
1103
+ */
1104
+ function mergeDatasetsByOrder(state, newDataEntries) {
1105
+ var merged = _objectSpread(_objectSpread({}, state.datasets), newDataEntries);
1106
+ if (Array.isArray(state.preserveDatasetOrder)) {
1107
+ // preserveDatasetOrder might not include the new datasets
1108
+ var newDatasetIds = Object.keys(merged).filter(function (id) {
1109
+ var _state$preserveDatase;
1110
+ return !((_state$preserveDatase = state.preserveDatasetOrder) !== null && _state$preserveDatase !== void 0 && _state$preserveDatase.includes(id));
1111
+ });
1112
+ return [].concat((0, _toConsumableArray2["default"])(state.preserveDatasetOrder), (0, _toConsumableArray2["default"])(newDatasetIds)).reduce(function (accu, dataId) {
1113
+ return _objectSpread(_objectSpread({}, accu), merged[dataId] ? (0, _defineProperty2["default"])({}, dataId, merged[dataId]) : {});
1114
+ }, {});
1115
+ }
1116
+ return merged;
1117
+ }
1118
+
1119
+ /**
1120
+ * Simliar purpose to aggregation utils `getMode` function,
1121
+ * but returns the mode in the same value type without coercing to a string.
1122
+ * It ignores `undefined` or `null` values, but returns `null` if no mode could be calculated.
1123
+ */
1124
+ function getValueWithHighestOccurrence(arr) {
1125
+ var _ref11;
1126
+ var tallys = new Map();
1127
+ arr.forEach(function (value) {
1128
+ if ((0, _commonUtils.notNullorUndefined)(value)) {
1129
+ if (!tallys.has(value)) {
1130
+ tallys.set(value, 1);
1131
+ } else {
1132
+ tallys.set(value, tallys.get(value) + 1);
1133
+ }
1134
+ }
1135
+ });
1136
+ // return the value with the highest total occurrence count
1137
+ if (tallys.size === 0) {
1138
+ return null;
1139
+ }
1140
+ return (_ref11 = (0, _toConsumableArray2["default"])(tallys.entries())) === null || _ref11 === void 0 ? void 0 : _ref11.reduce(function (acc, next) {
1141
+ return next[1] > acc[1] ? next : acc;
1142
+ })[0];
1143
+ }
1144
+ var VIS_STATE_MERGERS = exports.VIS_STATE_MERGERS = [{
1145
+ merge: mergeLayers,
1146
+ prop: 'layers',
1147
+ toMergeProp: 'layerToBeMerged',
1148
+ preserveOrder: 'preserveLayerOrder'
1149
+ }, {
1150
+ merge: mergeLayerOrder,
1151
+ prop: 'layerOrder'
1152
+ }, {
1153
+ merge: mergeFilters,
1154
+ prop: 'filters',
1155
+ toMergeProp: 'filterToBeMerged',
1156
+ preserveOrder: 'preserveFilterOrder',
1157
+ replaceParentDatasetIds: replaceFilterDatasetIds
1158
+ }, {
1159
+ merge: mergeEffects,
1160
+ prop: 'effects'
1161
+ }, {
1162
+ merge: mergeAnnotations,
1163
+ prop: 'annotations',
1164
+ toMergeProp: 'annotationsToBeMerged'
1165
+ }, {
1166
+ merge: mergeInteractions,
1167
+ prop: 'interactionConfig',
1168
+ toMergeProp: 'interactionToBeMerged',
1169
+ replaceParentDatasetIds: replaceInteractionDatasetIds,
1170
+ saveUnmerged: savedUnmergedInteraction,
1171
+ combineConfigs: combineInteractionConfigs
1172
+ }, {
1173
+ merge: mergeLayerBlending,
1174
+ prop: 'layerBlending',
1175
+ combineConfigs: combineLayerBlendingConfigs
1176
+ }, {
1177
+ merge: mergeOverlayBlending,
1178
+ prop: 'overlayBlending',
1179
+ combineConfigs: combineOverlayBlendingConfigs
1180
+ }, {
1181
+ merge: mergeSplitMaps,
1182
+ prop: 'splitMaps',
1183
+ toMergeProp: 'splitMapsToBeMerged'
1184
+ }, {
1185
+ merge: mergeAnimationConfig,
1186
+ prop: 'animationConfig',
1187
+ combineConfigs: combineAnimationConfigs
1188
+ }, {
1189
+ merge: mergeEditor,
1190
+ prop: 'editor',
1191
+ combineConfigs: combineEditorConfigs
1192
+ }];
1193
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdW5pcSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX3BpY2siLCJfZmxhdHRlbkRlZXAiLCJfZGVlcG1lcmdlIiwiX3V0aWxzIiwiX2VmZmVjdHMiLCJfY29tbW9uVXRpbHMiLCJfY29uc3RhbnRzIiwiX3NjaGVtYXMiLCJfdGFibGUiLCJfbGF5ZXJVdGlscyIsIl9leGNsdWRlZCIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiciIsImUiLCJ0IiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJBcnJheSIsImlzQXJyYXkiLCJfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkiLCJsZW5ndGgiLCJfbiIsIkYiLCJzIiwibiIsImRvbmUiLCJ2YWx1ZSIsImYiLCJUeXBlRXJyb3IiLCJvIiwiYSIsInUiLCJjYWxsIiwibmV4dCIsIl9hcnJheUxpa2VUb0FycmF5IiwidG9TdHJpbmciLCJzbGljZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsImZyb20iLCJ0ZXN0IiwiX3RvUHJvcGVydHlLZXkiLCJpIiwiX3RvUHJpbWl0aXZlIiwiX3R5cGVvZiIsInRvUHJpbWl0aXZlIiwiU3RyaW5nIiwiTnVtYmVyIiwib3duS2V5cyIsIk9iamVjdCIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIm1lcmdlRmlsdGVycyIsInN0YXRlIiwiZmlsdGVyc1RvTWVyZ2UiLCJmcm9tQ29uZmlnIiwicHJlc2VydmVGaWx0ZXJPcmRlciIsIm1hcCIsImwiLCJpZCIsIl92YWxpZGF0ZUZpbHRlcnNVcGRhdCIsInZhbGlkYXRlRmlsdGVyc1VwZGF0ZURhdGFzZXRzIiwidmFsaWRhdGVkIiwiZmFpbGVkIiwidXBkYXRlZERhdGFzZXRzIiwidXBkYXRlZEZpbHRlcnMiLCJpbnNlcnRJdGVtQmFzZWRPblByZXNlcnZlZE9yZGVyIiwiZmlsdGVycyIsInJlc2V0RmlsdGVyR3B1TW9kZSIsImFzc2lnbkdwdUNoYW5uZWxzIiwiZGF0YXNldHNUb0ZpbHRlciIsInVuaXEiLCJmbGF0dGVuRGVlcCIsImRhdGFJZCIsImZpbHRlcmVkIiwiYXBwbHlGaWx0ZXJzVG9EYXRhc2V0cyIsImxheWVycyIsImRhdGFzZXRzIiwiZmlsdGVyVG9CZU1lcmdlZCIsImNvbmNhdCIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJyZXBsYWNlRmlsdGVyRGF0YXNldElkcyIsInNhdmVkRmlsdGVyIiwiZGF0YUlkVG9Vc2UiLCJyZXBsYWNlZCIsImluY2x1ZGVzIiwiX2ZpbHRlciRwbG90VHlwZSIsIm5ld0RhdGFJZCIsImQiLCJwbG90VHlwZSIsImNvbG9yc0J5RGF0YUlkIiwiX2ZpbHRlciRwbG90VHlwZTIiLCJfcmVmIiwiY29sb3IiLCJyZXN0IiwiX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzMiIsImlzU2F2ZWRMYXllckNvbmZpZ1YxIiwibGF5ZXJDb25maWciLCJ2aXN1YWxDaGFubmVscyIsInBhcnNlTGF5ZXJDb25maWciLCJzY2hlbWEiLCJfc2NoZW1hJHBhcnNlU2F2ZWRDb24iLCJzYXZlZENvbmZpZyIsInZlcnNpb24iLCJDVVJSRU5UX1ZFUlNJT04iLCJjb25maWciLCJ2aXNTdGF0ZSIsImxheWVyT3JkZXIiLCJwYXJzZVNhdmVkQ29uZmlnIiwiY3VycmVudEl0ZW1zIiwiaXRlbXMiLCJwcmVzZXJ2ZWRPcmRlciIsInVuZGVmaW5lZCIsImRlZmF1bHRTdGFydCIsIm5ld0l0ZW1zIiwiX2l0ZXJhdG9yIiwiX3N0ZXAiLCJpdGVtIiwiZXhwZWN0ZWRJZHgiLCJpbmRleE9mIiwiaW5zZXJ0QXQiLCJwcmVjZWVkSWR4IiwiX2xvb3AiLCJwcmVjZWVkSXRlbUlkIiwiZmluZEluZGV4IiwiYXJyYXlJbnNlcnQiLCJlcnIiLCJjcmVhdGVMYXllckZyb21Db25maWciLCJwYXJzZWRMYXllckNvbmZpZyIsIl92YWxpZGF0ZUxheWVyc0J5RGF0YSIsInZhbGlkYXRlTGF5ZXJzQnlEYXRhc2V0cyIsImxheWVyQ2xhc3NlcyIsImFsbG93RW1wdHlDb2x1bW4iLCJuZXdMYXllciIsInVwZGF0ZUxheWVyRG9tYWluIiwic2VyaWFsaXplRmlsdGVyIiwibmV3RmlsdGVyIiwiX3NlcmlhbGl6ZWRWaXNTdGF0ZSRmIiwic2VyaWFsaXplZFZpc1N0YXRlIiwic2VyaWFsaXplVmlzU3RhdGUiLCJzZXJpYWxpemVMYXllciIsIl9zZXJpYWxpemVkVmlzU3RhdGUkbCIsInNlcmlhbGl6ZUVmZmVjdCIsIm5ld0VmZmVjdCIsIl9zZXJpYWxpemVkVmlzU3RhdGUkZSIsImVmZmVjdHMiLCJlZmZlY3RPcmRlciIsIl9zY2hlbWEkcGFyc2VTYXZlZENvbjIiLCJzYXZlZFN0YXRlIiwiZ2V0Q29uZmlnVG9TYXZlIiwibWVyZ2VMYXllcnMiLCJsYXllcnNUb01lcmdlIiwicHJlc2VydmVMYXllck9yZGVyIiwiZ2V0TGF5ZXJPcmRlckZyb21MYXllcnMiLCJ1bm1lcmdlZCIsInRvTWVyZ2UiLCJfbCRjb25maWciLCJpc01lcmdpbmdEYXRhc2V0cyIsIl92YWxpZGF0ZUxheWVyc0J5RGF0YTIiLCJtZXJnZWRMYXllciIsIl9pbnNlcnRMYXllckF0UmlnaHRPciIsImluc2VydExheWVyQXRSaWdodE9yZGVyIiwibmV3TGF5ZXJPcmRlciIsIm5ld0xheWVycyIsIm1lcmdlZFN0YXRlIiwibGF5ZXJUb0JlTWVyZ2VkIiwibGF5ZXJPcmRlclRvQmVNZXJnZWQiLCJzYXZlZE9yZGVyIiwibWVyZ2VMYXllck9yZGVyIiwiY3VycmVudExheWVycyIsImxheWVyc1RvSW5zZXJ0IiwiY3VycmVudE9yZGVyIiwiY3VycmVudExheWVyUXVldWUiLCJlbnRyeSIsImZpbmRCeUlkIiwibGF5ZXIiLCJCb29sZWFuIiwibmV3TGF5ZXJPcmRlclF1ZXVlIiwibmV3RmxhdExheWVyT3JkZXIiLCJoYXNHcm91cHMiLCJzb21lIiwiaXNQbGFpbk9iamVjdCIsImV4aXN0aW5nRmxhdElkcyIsIlNldCIsIm5ld0luc2VydGVkSWRzIiwiaGFzIiwicmVzdWx0IiwiZmxhdFF1ZXVlIiwiZmxhdElkeCIsIl9pdGVyYXRvcjIiLCJfc3RlcDIiLCJzYXZlZExheWVyT3JkZXIiLCJ2YWxpZExheWVySWRzIiwiZmlsdGVyTGF5ZXJPcmRlciIsIm9yZGVyIiwiX2l0ZXJhdG9yMyIsIl9zdGVwMyIsImdyb3VwIiwiZmlsdGVyZWRHcm91cE9yZGVyIiwicmVzdG9yZWRMYXllck9yZGVyIiwibGF5ZXJJZHNJblJlc3RvcmVkIiwiY29sbGVjdElkcyIsIl9pdGVyYXRvcjQiLCJfc3RlcDQiLCJhZGQiLCJtaXNzaW5nTGF5ZXJzIiwibWVyZ2VJbnRlcmFjdGlvbnMiLCJpbnRlcmFjdGlvblRvQmVNZXJnZWQiLCJtZXJnZWQiLCJrZXkiLCJpbnRlcmFjdGlvbkNvbmZpZyIsImN1cnJlbnRDb25maWciLCJfcmVmMiIsImVuYWJsZWQiLCJjb25maWdTYXZlZCIsImNvbmZpZ1RvTWVyZ2UiLCJfbWVyZ2VJbnRlcmFjdGlvblRvb2wiLCJtZXJnZUludGVyYWN0aW9uVG9vbHRpcENvbmZpZyIsIm1lcmdlZFRvb2x0aXAiLCJ1bm1lcmdlZFRvb2x0aXAiLCJmaWVsZHNUb1Nob3ciLCJ0b29sdGlwIiwicGljayIsIm5leHRTdGF0ZSIsInNhdmVkVW5tZXJnZWRJbnRlcmFjdGlvbiIsImNvbWJpbmVJbnRlcmFjdGlvbkNvbmZpZ3MiLCJjb25maWdzIiwiY29tYmluZWQiLCJfbG9vcDIiLCJ0b0JlQ29tYmluZWRQcm9wcyIsImMiLCJwIiwiY29tcGFyZU1vZGUiLCJjb21wYXJlVHlwZSIsImdldFZhbHVlV2l0aEhpZ2hlc3RPY2N1cnJlbmNlIiwicmVkdWNlIiwiYWNjIiwibmV4dEZpZWxkc1RvU2hvdyIsIl9sb29wMyIsIm5leHREYXRhSWRLZXkiLCJuZXh0VG9vbHRpcEZpZWxkcyIsIm5leHRURiIsImZpbmQiLCJfcmVmMyIsIl9hZ2dyZWdhdGUiLCJzaXplIiwiYWdncmVnYXRlIiwiQUdHUkVHQVRJT05fVFlQRVMiLCJtYXhpbXVtIiwibGltaXRTZWFyY2giLCJfdW5tZXJnZWQkdG9vbHRpcCIsIl91bm1lcmdlZCR0b29sdGlwMiIsIl9zdGF0ZSRpbnRlcmFjdGlvblRvQiIsIl91bm1lcmdlZCR0b29sdGlwMyIsInJlcGxhY2VJbnRlcmFjdGlvbkRhdGFzZXRJZHMiLCJkYXRhSWRUb1JlcGxhY2UiLCJfaW50ZXJhY3Rpb25Db25maWckdG8iLCJfaW50ZXJhY3Rpb25Db25maWckdG8yIiwibWVyZ2VTcGxpdE1hcHMiLCJzcGxpdE1hcHMiLCJzbSIsImVudHJpZXMiLCJfcmVmNCIsIl9yZWY1IiwiX3NsaWNlZFRvQXJyYXkyIiwicHVzaFRvIiwiZ2V0SW5pdGlhbE1hcExheWVyc0ZvclNwbGl0TWFwIiwic3BsaXRNYXBzVG9CZU1lcmdlZCIsIm1lcmdlRWZmZWN0cyIsIm5ld0VmZmVjdHMiLCJlZmZlY3QiLCJjcmVhdGVFZmZlY3QiLCJkZWVwbWVyZ2UiLCJhbGwiLCJpc0NvbmZpZ0FjdGl2ZSIsImlzVmFsaWRUb1NhdmUiLCJtZXJnZUFubm90YXRpb25zIiwiYW5ub3RhdGlvbnMiLCJleGlzdGluZ0lkcyIsInZhbGlkQW5ub3RhdGlvbnMiLCJpc0Fubm90YXRpb25LaW5kIiwia2luZCIsImFuY2hvclBvaW50IiwiaXNWaXNpYmxlIiwiYXV0b1NpemUiLCJhdXRvU2l6ZVkiLCJsYWJlbCIsImxpbmVDb2xvciIsIklOSVRJQUxfQU5OT1RBVElPTl9MSU5FX0NPTE9SIiwibGluZVdpZHRoIiwiSU5JVElBTF9BTk5PVEFUSU9OX0xJTkVfV0lEVEgiLCJ0ZXh0V2lkdGgiLCJ0ZXh0SGVpZ2h0IiwidG9vbHRpcENvbmZpZyIsIl9sb29wNCIsImFsbEZpZWxkcyIsImZpZWxkcyIsImZvdW5kRmllbGRzVG9TaG93IiwiZmllbGQiLCJtZXJnZUxheWVyQmxlbmRpbmciLCJsYXllckJsZW5kaW5nIiwiTEFZRVJfQkxFTkRJTkdTIiwiY29tYmluZUxheWVyQmxlbmRpbmdDb25maWdzIiwibWVyZ2VPdmVybGF5QmxlbmRpbmciLCJvdmVybGF5QmxlbmRpbmciLCJPVkVSTEFZX0JMRU5ESU5HUyIsImNvbWJpbmVPdmVybGF5QmxlbmRpbmdDb25maWdzIiwibWVyZ2VBbmltYXRpb25Db25maWciLCJhbmltYXRpb24iLCJjdXJyZW50VGltZSIsImFuaW1hdGlvbkNvbmZpZyIsImRvbWFpbiIsImNvbWJpbmVBbmltYXRpb25Db25maWdzIiwiX2FnZ3JlZ2F0ZTIiLCJfYWdncmVnYXRlMyIsIm1pbmltdW0iLCJzcGVlZCIsInZhbGlkYXRlU2F2ZWRMYXllckNvbHVtbnMiLCJzYXZlZENvbHMiLCJlbXB0eUNvbHMiLCJvcHRpb25zIiwiY29sdW1ucyIsIl9sb29wNSIsIl9PYmplY3Qka2V5cyIsIl9pIiwic2F2ZWQiLCJmaWVsZElkeCIsIl9yZWY2IiwiYWxsQ29sRm91bmQiLCJldmVyeSIsInZhbGlkYXRlQ29sdW1uIiwicnYiLCJ0aHJvd09uRXJyb3IiLCJyZXF1aXJlZENvbHVtbnMiLCJrIiwib3B0aW9uYWwiLCJtaXNzaW5nQ29sdW1ucyIsIkVycm9yIiwiam9pbiIsImNvbmZpZ0NvbHVtbnMiLCJpbnZhbGlkQ29sdW1ucyIsIl9jb2x1bW5zJGsiLCJjb2x1bW4iLCJ2YWxpZGF0b3IiLCJ2YWxpZGF0ZVNhdmVkVGV4dExhYmVsIiwiX3JlZjciLCJzYXZlZFRleHRMYWJlbCIsIl9yZWY4IiwibGF5ZXJUZXh0TGFiZWwiLCJzYXZlZFRleHRMYWJlbHMiLCJ0ZXh0TGFiZWwiLCJmZCIsIkpTT04iLCJzdHJpbmdpZnkiLCJhY2N1IiwidmFsaWRhdGVTYXZlZFZpc3VhbENoYW5uZWxzIiwic2F2ZWRMYXllciIsInZhbHVlcyIsIl9yZWY5Iiwic2NhbGUiLCJmb3VuZEZpZWxkIiwiZm91bmRDaGFubmVsIiwidXBkYXRlTGF5ZXJDb25maWciLCJ2YWxpZGF0ZVZpc3VhbENoYW5uZWwiLCJfc2F2ZWRMYXllciRjb25maWciLCJfbmV3TGF5ZXIkY29uZmlnJGZpZWwiLCJmaWVsZE5hbWUiLCJfbGF5ZXIkY29uZmlnIiwidmFsaWRhdGVMYXllciIsInZhbGlkYXRlTGF5ZXJXaXRoRGF0YSIsIl9nZXRDb2x1bW5Db25maWdGb3JWYWxpZGF0aW9uIiwiY29sdW1uQ29uZmlnIiwiZ2V0TGF5ZXJDb2x1bW5zIiwiY29sTW9kZUNvbmZpZyIsImNvbHVtbk1vZGUiLCJzdXBwb3J0ZWRDb2x1bW5Nb2RlcyIsImNvbE1vZGUiLCJvcHRpb25hbENvbHVtbnMiLCJkYXRhc2V0IiwidHlwZSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiaGlkZGVuIiwiaGlnaGxpZ2h0Q29sb3IiLCJjb3BpZWRWaXNDb25maWciLCJjb3B5TGF5ZXJDb25maWciLCJ2aXNDb25maWciLCJzaGFsbG93Q29weSIsInZhbGlkYXRlVmlzQ29uZmlnIiwibWVyZ2VFZGl0b3IiLCJzYXZlZEVkaXRvciIsIl9zYXZlZEVkaXRvciR2aXNpYmxlIiwiZWRpdG9yIiwiZmVhdHVyZXMiLCJ2aXNpYmxlIiwiY29tYmluZUVkaXRvckNvbmZpZ3MiLCJuZXh0Q29uZmlnIiwibWVyZ2VEYXRhc2V0c0J5T3JkZXIiLCJuZXdEYXRhRW50cmllcyIsInByZXNlcnZlRGF0YXNldE9yZGVyIiwibmV3RGF0YXNldElkcyIsIl9zdGF0ZSRwcmVzZXJ2ZURhdGFzZSIsImFyciIsIl9yZWYxMSIsInRhbGx5cyIsIk1hcCIsIm5vdE51bGxvclVuZGVmaW5lZCIsInNldCIsImdldCIsIlZJU19TVEFURV9NRVJHRVJTIiwiZXhwb3J0cyIsIm1lcmdlIiwicHJvcCIsInRvTWVyZ2VQcm9wIiwicHJlc2VydmVPcmRlciIsInJlcGxhY2VQYXJlbnREYXRhc2V0SWRzIiwic2F2ZVVubWVyZ2VkIiwiY29tYmluZUNvbmZpZ3MiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdmlzLXN0YXRlLW1lcmdlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgdW5pcSBmcm9tICdsb2Rhc2gvdW5pcSc7XG5pbXBvcnQgcGljayBmcm9tICdsb2Rhc2gvcGljayc7XG5pbXBvcnQgZmxhdHRlbkRlZXAgZnJvbSAnbG9kYXNoL2ZsYXR0ZW5EZWVwJztcbmltcG9ydCBkZWVwbWVyZ2UgZnJvbSAnZGVlcG1lcmdlJztcbmltcG9ydCB7XG4gIGFycmF5SW5zZXJ0LFxuICBnZXRJbml0aWFsTWFwTGF5ZXJzRm9yU3BsaXRNYXAsXG4gIGFwcGx5RmlsdGVyc1RvRGF0YXNldHMsXG4gIHZhbGlkYXRlRmlsdGVyc1VwZGF0ZURhdGFzZXRzLFxuICBmaW5kQnlJZCxcbiAgYWdncmVnYXRlLFxuICBpc1BsYWluT2JqZWN0XG59IGZyb20gJ0BrZXBsZXIuZ2wvdXRpbHMnO1xuXG5pbXBvcnQge0xheWVyfSBmcm9tICdAa2VwbGVyLmdsL2xheWVycyc7XG5pbXBvcnQge2NyZWF0ZUVmZmVjdH0gZnJvbSAnQGtlcGxlci5nbC9lZmZlY3RzJztcbmltcG9ydCB7bm90TnVsbG9yVW5kZWZpbmVkfSBmcm9tICdAa2VwbGVyLmdsL2NvbW1vbi11dGlscyc7XG5pbXBvcnQge1xuICBBR0dSRUdBVElPTl9UWVBFUyxcbiAgTEFZRVJfQkxFTkRJTkdTLFxuICBPVkVSTEFZX0JMRU5ESU5HUyxcbiAgaXNBbm5vdGF0aW9uS2luZCxcbiAgSU5JVElBTF9BTk5PVEFUSU9OX0xJTkVfQ09MT1IsXG4gIElOSVRJQUxfQU5OT1RBVElPTl9MSU5FX1dJRFRIXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7Q1VSUkVOVF9WRVJTSU9OLCBWaXNTdGF0ZSwgVmlzU3RhdGVNZXJnZXJzLCBLZXBsZXJHTFNjaGVtYUNsYXNzfSBmcm9tICdAa2VwbGVyLmdsL3NjaGVtYXMnO1xuXG5pbXBvcnQge1xuICBQYXJzZWRMYXllcixcbiAgUGFyc2VkVmlzU3RhdGUsXG4gIFNhdmVkSW50ZXJhY3Rpb25Db25maWcsXG4gIFRvb2x0aXBJbmZvLFxuICBTYXZlZEVkaXRvcixcbiAgUGFyc2VkQ29uZmlnLFxuICBGaWx0ZXIsXG4gIEVmZmVjdCBhcyBFZmZlY3RUeXBlLFxuICBQYXJzZWRFZmZlY3QsXG4gIExheWVyQ29sdW1ucyxcbiAgTGF5ZXJDb2x1bW4sXG4gIFBhcnNlZEZpbHRlcixcbiAgTmVzdGVkUGFydGlhbCxcbiAgU2F2ZWRBbmltYXRpb25Db25maWcsXG4gIExheWVyT3JkZXIsXG4gIExheWVyT3JkZXJHcm91cFxufSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB7S2VwbGVyVGFibGUsIERhdGFzZXRzLCBhc3NpZ25HcHVDaGFubmVscywgcmVzZXRGaWx0ZXJHcHVNb2RlfSBmcm9tICdAa2VwbGVyLmdsL3RhYmxlJztcblxuaW1wb3J0IHtnZXRMYXllck9yZGVyRnJvbUxheWVyc30gZnJvbSAnLi9sYXllci11dGlscyc7XG5cbi8qKlxuICogTWVyZ2UgbG9hZGVkIGZpbHRlcnMgd2l0aCBjdXJyZW50IHN0YXRlLCBpZiBubyBmaWVsZHMgb3IgZGF0YSBhcmUgbG9hZGVkXG4gKiBzYXZlIGl0IGZvciBsYXRlclxuICpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlRmlsdGVyczxTIGV4dGVuZHMgVmlzU3RhdGU+KFxuICBzdGF0ZTogUyxcbiAgZmlsdGVyc1RvTWVyZ2U6IE5vbk51bGxhYmxlPFBhcnNlZENvbmZpZ1sndmlzU3RhdGUnXT5bJ2ZpbHRlcnMnXSxcbiAgZnJvbUNvbmZpZz86IGJvb2xlYW5cbik6IFMge1xuICBjb25zdCBwcmVzZXJ2ZUZpbHRlck9yZGVyID0gZnJvbUNvbmZpZ1xuICAgID8gZmlsdGVyc1RvTWVyZ2U/Lm1hcChsID0+IGwuaWQpXG4gICAgOiBzdGF0ZS5wcmVzZXJ2ZUZpbHRlck9yZGVyO1xuXG4gIGlmICghQXJyYXkuaXNBcnJheShmaWx0ZXJzVG9NZXJnZSkgfHwgIWZpbHRlcnNUb01lcmdlLmxlbmd0aCkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIGNvbnN0IHt2YWxpZGF0ZWQsIGZhaWxlZCwgdXBkYXRlZERhdGFzZXRzfSA9IHZhbGlkYXRlRmlsdGVyc1VwZGF0ZURhdGFzZXRzKHN0YXRlLCBmaWx0ZXJzVG9NZXJnZSk7XG4gIGxldCB1cGRhdGVkRmlsdGVycyA9IGluc2VydEl0ZW1CYXNlZE9uUHJlc2VydmVkT3JkZXIoXG4gICAgc3RhdGUuZmlsdGVycyxcbiAgICB2YWxpZGF0ZWQsXG4gICAgcHJlc2VydmVGaWx0ZXJPcmRlclxuICApO1xuXG4gIC8vIG1lcmdlIGZpbHRlciB3aXRoIGV4aXN0aW5nXG4gIHVwZGF0ZWRGaWx0ZXJzID0gcmVzZXRGaWx0ZXJHcHVNb2RlKHVwZGF0ZWRGaWx0ZXJzKTtcbiAgdXBkYXRlZEZpbHRlcnMgPSBhc3NpZ25HcHVDaGFubmVscyh1cGRhdGVkRmlsdGVycyk7XG4gIC8vIGZpbHRlciBkYXRhXG4gIGNvbnN0IGRhdGFzZXRzVG9GaWx0ZXIgPSB1bmlxKGZsYXR0ZW5EZWVwKHZhbGlkYXRlZC5tYXAoZiA9PiBmLmRhdGFJZCkpKTtcblxuICBjb25zdCBmaWx0ZXJlZCA9IGFwcGx5RmlsdGVyc1RvRGF0YXNldHMoXG4gICAgZGF0YXNldHNUb0ZpbHRlcixcbiAgICB1cGRhdGVkRGF0YXNldHMsXG4gICAgdXBkYXRlZEZpbHRlcnMsXG4gICAgc3RhdGUubGF5ZXJzXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBmaWx0ZXJzOiB1cGRhdGVkRmlsdGVycyxcbiAgICBkYXRhc2V0czogZmlsdGVyZWQsXG4gICAgcHJlc2VydmVGaWx0ZXJPcmRlcixcbiAgICBmaWx0ZXJUb0JlTWVyZ2VkOiBbLi4uc3RhdGUuZmlsdGVyVG9CZU1lcmdlZCwgLi4uZmFpbGVkXVxuICB9O1xufVxuXG4vLyByZXBsYWNlIGRhdGFJZCBpbiBzYXZlZCBGaWx0ZXJcbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlRmlsdGVyRGF0YXNldElkcyhcbiAgc2F2ZWRGaWx0ZXI6IEZpbHRlcltdLFxuICBkYXRhSWQ6IHN0cmluZyxcbiAgZGF0YUlkVG9Vc2U6IHN0cmluZ1xuKSB7XG4gIGNvbnN0IHJlcGxhY2VkOiBGaWx0ZXJbXSA9IFtdO1xuICBzYXZlZEZpbHRlci5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgaWYgKGZpbHRlci5kYXRhSWQuaW5jbHVkZXMoZGF0YUlkKSkge1xuICAgICAgY29uc3QgbmV3RGF0YUlkID0gZmlsdGVyLmRhdGFJZC5tYXAoZCA9PiAoZCA9PT0gZGF0YUlkID8gZGF0YUlkVG9Vc2UgOiBkKSk7XG4gICAgICBsZXQgcGxvdFR5cGU7XG4gICAgICAvLyBUT0RPOiBtb3JlIGdlbmVyaWMgYXBwcm9hY2ggdG8gc2F2ZSBwbG90VHlwZS5jb2xvcnNCeURhdGFJZFxuICAgICAgaWYgKGZpbHRlci5wbG90VHlwZT8uY29sb3JzQnlEYXRhSWQ/LltkYXRhSWRdKSB7XG4gICAgICAgIC8vIHJlcGxhY2UgY29sb3JCeURhdGFJZCBpbiBmaWx0ZXIucGxvdFR5cGVcbiAgICAgICAgY29uc3Qge1tkYXRhSWRdOiBjb2xvciwgLi4ucmVzdH0gPSBmaWx0ZXIucGxvdFR5cGU/LmNvbG9yc0J5RGF0YUlkIHx8IHt9O1xuICAgICAgICBwbG90VHlwZSA9IHtcbiAgICAgICAgICAuLi5maWx0ZXIucGxvdFR5cGUsXG4gICAgICAgICAgY29sb3JzQnlEYXRhSWQ6IHtcbiAgICAgICAgICAgIC4uLnJlc3QsXG4gICAgICAgICAgICBbZGF0YUlkVG9Vc2VdOiBjb2xvclxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJlcGxhY2VkLnB1c2goe1xuICAgICAgICAuLi5maWx0ZXIsXG4gICAgICAgIGRhdGFJZDogbmV3RGF0YUlkLFxuICAgICAgICAuLi4ocGxvdFR5cGUgPyB7cGxvdFR5cGV9IDoge30pXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVwbGFjZWQubGVuZ3RoID8gcmVwbGFjZWQgOiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTYXZlZExheWVyQ29uZmlnVjEobGF5ZXJDb25maWc6IGFueSk6IGJvb2xlYW4ge1xuICAvLyBleHBvcnRlZCBsYXllciBjb25maWd1cmF0aW9uIGNvbnRhaW5zIHZpc3VhbENoYW5uZWxzIHByb3BlcnR5XG4gIHJldHVybiBsYXllckNvbmZpZz8udmlzdWFsQ2hhbm5lbHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxheWVyQ29uZmlnKFxuICBzY2hlbWE6IEtlcGxlckdMU2NoZW1hQ2xhc3MsXG4gIGxheWVyQ29uZmlnOiBhbnlcbik6IFBhcnNlZExheWVyIHwgdW5kZWZpbmVkIHtcbiAgLy8gYXNzdW1lIHRoZSBsYXllciBjb25maWcgaXMgY3VycmVudCB2ZXJzaW9uXG4gIGNvbnN0IHNhdmVkQ29uZmlnID0ge1xuICAgIHZlcnNpb246IENVUlJFTlRfVkVSU0lPTixcbiAgICBjb25maWc6IHtcbiAgICAgIHZpc1N0YXRlOiB7bGF5ZXJzOiBbbGF5ZXJDb25maWddLCBsYXllck9yZGVyOiBbbGF5ZXJDb25maWcuaWRdfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc2NoZW1hLnBhcnNlU2F2ZWRDb25maWcoc2F2ZWRDb25maWcpPy52aXNTdGF0ZT8ubGF5ZXJzPy5bMF07XG59XG5cbmZ1bmN0aW9uIGluc2VydEl0ZW1CYXNlZE9uUHJlc2VydmVkT3JkZXIoXG4gIGN1cnJlbnRJdGVtczogRmlsdGVyW10sXG4gIGl0ZW1zOiBGaWx0ZXJbXSxcbiAgcHJlc2VydmVkT3JkZXI6IGFueVtdID0gW10sXG4gIGRlZmF1bHRTdGFydD86IGJvb2xlYW5cbikge1xuICBsZXQgbmV3SXRlbXMgPSBbLi4uY3VycmVudEl0ZW1zXTtcblxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICBjb25zdCBleHBlY3RlZElkeCA9IHByZXNlcnZlZE9yZGVyLmluZGV4T2YoaXRlbS5pZCk7XG4gICAgLy8gaW5zZXJ0QXQgdGhlIGVuZCBieSBkZWZhdWx0XG4gICAgbGV0IGluc2VydEF0ID0gZGVmYXVsdFN0YXJ0ID8gMCA6IG5ld0l0ZW1zLmxlbmd0aDtcbiAgICBpZiAoZXhwZWN0ZWRJZHggPiAwKSB7XG4gICAgICAvLyBsb29rIGZvciBsYXllciB0byBpbnNlcnQgYWZ0ZXJcbiAgICAgIGxldCBpID0gZXhwZWN0ZWRJZHggKyAxO1xuICAgICAgbGV0IHByZWNlZWRJZHggPSAtMTtcbiAgICAgIHdoaWxlIChpLS0gPiAwICYmIHByZWNlZWRJZHggPCAwKSB7XG4gICAgICAgIC8vIGtlZXAgbG9va2luZyBmb3IgcHJlY2VlZCBsYXllciB0aGF0IGlzIGFscmVhZHkgbG9hZGVkXG4gICAgICAgIGNvbnN0IHByZWNlZWRJdGVtSWQgPSBwcmVzZXJ2ZWRPcmRlcltpIC0gMV07XG4gICAgICAgIHByZWNlZWRJZHggPSBuZXdJdGVtcy5maW5kSW5kZXgoZCA9PiBkLmlkID09PSBwcmVjZWVkSXRlbUlkKTtcbiAgICAgIH1cbiAgICAgIGlmIChwcmVjZWVkSWR4ID4gLTEpIHtcbiAgICAgICAgLy8gaWYgZm91bmRcbiAgICAgICAgaW5zZXJ0QXQgPSBwcmVjZWVkSWR4ICsgMTtcbiAgICAgIH1cbiAgICB9XG4gICAgbmV3SXRlbXMgPSBhcnJheUluc2VydChuZXdJdGVtcywgaW5zZXJ0QXQsIGl0ZW0pO1xuICB9XG4gIHJldHVybiBuZXdJdGVtcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUxheWVyRnJvbUNvbmZpZyhzdGF0ZTogVmlzU3RhdGUsIGxheWVyQ29uZmlnOiBhbnkpOiBMYXllciB8IG51bGwge1xuICAvLyBjaGVjayBpZiB0aGUgbGF5ZXIgY29uZmlnIGlzIHBhcnNlZFxuICBjb25zdCBwYXJzZWRMYXllckNvbmZpZyA9IGlzU2F2ZWRMYXllckNvbmZpZ1YxKGxheWVyQ29uZmlnKVxuICAgID8gcGFyc2VMYXllckNvbmZpZyhzdGF0ZS5zY2hlbWEsIGxheWVyQ29uZmlnKVxuICAgIDogbGF5ZXJDb25maWc7XG5cbiAgaWYgKCFwYXJzZWRMYXllckNvbmZpZykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIC8vIGZpcnN0IHZhbGlkYXRlIGNvbmZpZyBhZ2FpbnN0IGRhdGFzZXRcbiAgY29uc3Qge3ZhbGlkYXRlZCwgZmFpbGVkfSA9IHZhbGlkYXRlTGF5ZXJzQnlEYXRhc2V0cyhcbiAgICBzdGF0ZS5kYXRhc2V0cyxcbiAgICBzdGF0ZS5sYXllckNsYXNzZXMsXG4gICAgW3BhcnNlZExheWVyQ29uZmlnXSxcbiAgICB7YWxsb3dFbXB0eUNvbHVtbjogdHJ1ZX1cbiAgKTtcblxuICBpZiAoZmFpbGVkPy5sZW5ndGggfHwgIXZhbGlkYXRlZC5sZW5ndGgpIHtcbiAgICAvLyBmYWlsZWRcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IG5ld0xheWVyID0gdmFsaWRhdGVkWzBdO1xuICBuZXdMYXllci51cGRhdGVMYXllckRvbWFpbihzdGF0ZS5kYXRhc2V0cyk7XG4gIHJldHVybiBuZXdMYXllcjtcbn1cblxuLyoqXG4gKiBHZXQgbG9hZGVkIGZpbHRlciBmcm9tIHN0YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVGaWx0ZXIoXG4gIG5ld0ZpbHRlcjogRmlsdGVyLFxuICBzY2hlbWE6IEtlcGxlckdMU2NoZW1hQ2xhc3Ncbik6IFBhcnNlZEZpbHRlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNlcmlhbGl6ZWRWaXNTdGF0ZSA9IHNlcmlhbGl6ZVZpc1N0YXRlKHtmaWx0ZXJzOiBbbmV3RmlsdGVyXX0sIHNjaGVtYSk7XG4gIHJldHVybiBzZXJpYWxpemVkVmlzU3RhdGU/LmZpbHRlcnM/LlswXTtcbn1cblxuLyoqXG4gKiBHZXQgbG9hZGVkIGxheWVyIGZyb20gc3RhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZUxheWVyKFxuICBuZXdMYXllcjogTGF5ZXIsXG4gIHNjaGVtYTogS2VwbGVyR0xTY2hlbWFDbGFzc1xuKTogUGFyc2VkTGF5ZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBzZXJpYWxpemVkVmlzU3RhdGUgPSBzZXJpYWxpemVWaXNTdGF0ZShcbiAgICB7bGF5ZXJzOiBbbmV3TGF5ZXJdLCBsYXllck9yZGVyOiBbbmV3TGF5ZXIuaWRdfSxcbiAgICBzY2hlbWFcbiAgKTtcbiAgcmV0dXJuIHNlcmlhbGl6ZWRWaXNTdGF0ZT8ubGF5ZXJzPy5bMF07XG59XG5cbi8qKlxuICogR2V0IGxvYWRlZCBlZmZlY3QgZnJvbSBzdGF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplRWZmZWN0KFxuICBuZXdFZmZlY3Q6IEVmZmVjdFR5cGUsXG4gIHNjaGVtYTogS2VwbGVyR0xTY2hlbWFDbGFzc1xuKTogUGFyc2VkRWZmZWN0IHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc2VyaWFsaXplZFZpc1N0YXRlID0gc2VyaWFsaXplVmlzU3RhdGUoXG4gICAge2VmZmVjdHM6IFtuZXdFZmZlY3RdLCBlZmZlY3RPcmRlcjogW25ld0VmZmVjdC5pZF19LFxuICAgIHNjaGVtYVxuICApO1xuICByZXR1cm4gc2VyaWFsaXplZFZpc1N0YXRlPy5lZmZlY3RzPy5bMF07XG59XG5cbi8qKlxuICogR2V0IHZpcyBzdGF0ZSBjb25maWdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZVZpc1N0YXRlKFxuICB2aXNTdGF0ZTogUGFydGlhbDxWaXNTdGF0ZT4sXG4gIHNjaGVtYTogS2VwbGVyR0xTY2hlbWFDbGFzc1xuKTogUGFyc2VkVmlzU3RhdGUgfCB1bmRlZmluZWQge1xuICBjb25zdCBzYXZlZFN0YXRlID0gc2NoZW1hLmdldENvbmZpZ1RvU2F2ZSh7XG4gICAgdmlzU3RhdGVcbiAgfSk7XG4gIHJldHVybiBzYXZlZFN0YXRlID8gc2NoZW1hLnBhcnNlU2F2ZWRDb25maWcoc2F2ZWRTdGF0ZSk/LnZpc1N0YXRlIDogdW5kZWZpbmVkO1xufVxuLyoqXG4gKiBNZXJnZSBsYXllcnMgZnJvbSBkZS1zZXJpYWxpemVkIHN0YXRlLCBpZiBubyBmaWVsZHMgb3IgZGF0YSBhcmUgbG9hZGVkXG4gKiBzYXZlIGl0IGZvciBsYXRlclxuICpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlTGF5ZXJzPFMgZXh0ZW5kcyBWaXNTdGF0ZT4oXG4gIHN0YXRlOiBTLFxuICBsYXllcnNUb01lcmdlOiBOb25OdWxsYWJsZTxQYXJzZWRDb25maWdbJ3Zpc1N0YXRlJ10+WydsYXllcnMnXSA9IFtdLFxuICBmcm9tQ29uZmlnPzogYm9vbGVhblxuKTogUyB7XG4gIGNvbnN0IHByZXNlcnZlTGF5ZXJPcmRlciA9IGZyb21Db25maWdcbiAgICA/IGdldExheWVyT3JkZXJGcm9tTGF5ZXJzKGxheWVyc1RvTWVyZ2UpXG4gICAgOiBzdGF0ZS5wcmVzZXJ2ZUxheWVyT3JkZXI7XG4gIGlmICghQXJyYXkuaXNBcnJheShsYXllcnNUb01lcmdlKSB8fCAhbGF5ZXJzVG9NZXJnZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cbiAgLy8gZG9uJ3QgbWVyZ2UgbGF5ZXIgaWYgZGF0YXNldCBpcyBiZWluZyBtZXJnZWRcbiAgY29uc3QgdW5tZXJnZWQ6IFBhcnNlZExheWVyW10gPSBbXTtcbiAgY29uc3QgdG9NZXJnZTogUGFyc2VkTGF5ZXJbXSA9IFtdO1xuICBsYXllcnNUb01lcmdlLmZvckVhY2goKGw6IFBhcnNlZExheWVyKSA9PiB7XG4gICAgaWYgKGw/LmNvbmZpZz8uZGF0YUlkICYmIHN0YXRlLmlzTWVyZ2luZ0RhdGFzZXRzW2wuY29uZmlnLmRhdGFJZF0pIHtcbiAgICAgIHVubWVyZ2VkLnB1c2gobCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRvTWVyZ2UucHVzaChsKTtcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IHt2YWxpZGF0ZWQ6IG1lcmdlZExheWVyLCBmYWlsZWR9ID0gdmFsaWRhdGVMYXllcnNCeURhdGFzZXRzKFxuICAgIHN0YXRlLmRhdGFzZXRzLFxuICAgIHN0YXRlLmxheWVyQ2xhc3NlcyxcbiAgICB0b01lcmdlXG4gICk7XG4gIHVubWVyZ2VkLnB1c2goLi4uZmFpbGVkKTtcbiAgLy8gcHV0IG5ldyBsYXllcnMgaW4gZnJvbnQgb2YgY3VycmVudCBsYXllcnNcbiAgY29uc3Qge25ld0xheWVyT3JkZXIsIG5ld0xheWVyc30gPSBpbnNlcnRMYXllckF0UmlnaHRPcmRlcihcbiAgICBzdGF0ZS5sYXllcnMsXG4gICAgbWVyZ2VkTGF5ZXIsXG4gICAgc3RhdGUubGF5ZXJPcmRlcixcbiAgICBwcmVzZXJ2ZUxheWVyT3JkZXJcbiAgKTtcblxuICBsZXQgbWVyZ2VkU3RhdGU6IFMgPSB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJzOiBuZXdMYXllcnMsXG4gICAgbGF5ZXJPcmRlcjogbmV3TGF5ZXJPcmRlcixcbiAgICBwcmVzZXJ2ZUxheWVyT3JkZXIsXG4gICAgbGF5ZXJUb0JlTWVyZ2VkOiBbLi4uc3RhdGUubGF5ZXJUb0JlTWVyZ2VkLCAuLi51bm1lcmdlZF1cbiAgfTtcblxuICAvLyBBcHBseSBwZW5kaW5nIGxheWVyT3JkZXIgd2l0aCBncm91cHMgaWYgbGF5ZXJzIGFyZSBub3cgYXZhaWxhYmxlXG4gIGlmIChtZXJnZWRTdGF0ZS5sYXllck9yZGVyVG9CZU1lcmdlZCAmJiBtZXJnZWRTdGF0ZS5sYXllcnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHNhdmVkT3JkZXIgPSBtZXJnZWRTdGF0ZS5sYXllck9yZGVyVG9CZU1lcmdlZDtcbiAgICBtZXJnZWRTdGF0ZSA9IG1lcmdlTGF5ZXJPcmRlcihtZXJnZWRTdGF0ZSwgc2F2ZWRPcmRlcik7XG4gICAgLy8gS2VlcCBzYXZlZExheWVyT3JkZXIgYXZhaWxhYmxlIGZvciBmdXR1cmUgZGVmZXJyZWQgbGF5ZXJzXG4gICAgaWYgKG1lcmdlZFN0YXRlLmxheWVyVG9CZU1lcmdlZC5sZW5ndGggPiAwKSB7XG4gICAgICBtZXJnZWRTdGF0ZSA9IHsuLi5tZXJnZWRTdGF0ZSwgbGF5ZXJPcmRlclRvQmVNZXJnZWQ6IHNhdmVkT3JkZXJ9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtZXJnZWRTdGF0ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydExheWVyQXRSaWdodE9yZGVyKFxuICBjdXJyZW50TGF5ZXJzLFxuICBsYXllcnNUb0luc2VydCxcbiAgY3VycmVudE9yZGVyLFxuICBwcmVzZXJ2ZWRPcmRlcjogc3RyaW5nW10gPSBbXVxuKSB7XG4gIGlmICghbGF5ZXJzVG9JbnNlcnQ/Lmxlbmd0aCkge1xuICAgIHJldHVybiB7bmV3TGF5ZXJzOiBjdXJyZW50TGF5ZXJzLCBuZXdMYXllck9yZGVyOiBjdXJyZW50T3JkZXJ9O1xuICB9XG5cbiAgY29uc3QgY3VycmVudExheWVyUXVldWUgPSBjdXJyZW50T3JkZXJcbiAgICAuZmlsdGVyKGVudHJ5ID0+IHR5cGVvZiBlbnRyeSA9PT0gJ3N0cmluZycpXG4gICAgLm1hcChpZCA9PiBmaW5kQnlJZChpZCkoY3VycmVudExheWVycykpXG4gICAgLmZpbHRlcihsYXllciA9PiBCb29sZWFuKGxheWVyKSk7XG4gIGNvbnN0IG5ld0xheWVycyA9IGN1cnJlbnRMYXllcnMuY29uY2F0KGxheWVyc1RvSW5zZXJ0KTtcbiAgY29uc3QgbmV3TGF5ZXJPcmRlclF1ZXVlID0gaW5zZXJ0SXRlbUJhc2VkT25QcmVzZXJ2ZWRPcmRlcihcbiAgICBjdXJyZW50TGF5ZXJRdWV1ZSxcbiAgICBsYXllcnNUb0luc2VydCxcbiAgICBwcmVzZXJ2ZWRPcmRlcixcbiAgICB0cnVlXG4gICk7XG5cbiAgY29uc3QgbmV3RmxhdExheWVyT3JkZXIgPSBnZXRMYXllck9yZGVyRnJvbUxheWVycyhuZXdMYXllck9yZGVyUXVldWUpO1xuXG4gIC8vIElmIG5vIGdyb3VwcyBleGlzdCBpbiBjdXJyZW50IG9yZGVyLCBqdXN0IHVzZSB0aGUgbmV3IGZsYXQgb3JkZXJcbiAgY29uc3QgaGFzR3JvdXBzID0gY3VycmVudE9yZGVyLnNvbWUoZW50cnkgPT4gaXNQbGFpbk9iamVjdChlbnRyeSkpO1xuICBpZiAoIWhhc0dyb3Vwcykge1xuICAgIHJldHVybiB7XG4gICAgICBuZXdMYXllck9yZGVyOiBuZXdGbGF0TGF5ZXJPcmRlcixcbiAgICAgIG5ld0xheWVyc1xuICAgIH07XG4gIH1cblxuICAvLyBSZWJ1aWxkIGxheWVyT3JkZXIgcHJlc2VydmluZyBncm91cHMgaW4gdGhlaXIgcmVsYXRpdmUgcG9zaXRpb25zLlxuICAvLyBSZXBsYWNlIGVhY2ggc3RyaW5nIGVudHJ5IHdpdGggaXRzIHVwZGF0ZWQgcG9zaXRpb24gZnJvbSBuZXdGbGF0TGF5ZXJPcmRlcixcbiAgLy8gYW5kIGtlZXAgZ3JvdXBzIGFzLWlzLlxuICBjb25zdCBleGlzdGluZ0ZsYXRJZHMgPSBuZXcgU2V0KFxuICAgIGN1cnJlbnRPcmRlci5maWx0ZXIoZW50cnkgPT4gdHlwZW9mIGVudHJ5ID09PSAnc3RyaW5nJykgYXMgc3RyaW5nW11cbiAgKTtcbiAgY29uc3QgbmV3SW5zZXJ0ZWRJZHMgPSBuZXdGbGF0TGF5ZXJPcmRlci5maWx0ZXIoaWQgPT4gIWV4aXN0aW5nRmxhdElkcy5oYXMoaWQpKTtcblxuICAvLyBSZWJ1aWxkOiB3YWxrIHRocm91Z2ggY3VycmVudE9yZGVyLCByZXBsYWNlIHN0cmluZyBlbnRyaWVzIHdpdGggdGhlaXJcbiAgLy8gbmV3IHBvc2l0aW9uIGVxdWl2YWxlbnRzIGZyb20gbmV3RmxhdExheWVyT3JkZXIsIHRoZW4gYXBwZW5kIGFueSBuZXdseSBpbnNlcnRlZCBsYXllcnNcbiAgY29uc3QgcmVzdWx0OiBMYXllck9yZGVyID0gW107XG4gIGNvbnN0IGZsYXRRdWV1ZSA9IFsuLi5uZXdGbGF0TGF5ZXJPcmRlci5maWx0ZXIoaWQgPT4gZXhpc3RpbmdGbGF0SWRzLmhhcyhpZCkpXTtcbiAgbGV0IGZsYXRJZHggPSAwO1xuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgY3VycmVudE9yZGVyKSB7XG4gICAgaWYgKGlzUGxhaW5PYmplY3QoZW50cnkpKSB7XG4gICAgICByZXN1bHQucHVzaChlbnRyeSBhcyBMYXllck9yZGVyR3JvdXApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZXBsYWNlIHdpdGggY29ycmVzcG9uZGluZyBlbnRyeSBmcm9tIHJlb3JkZXJlZCBmbGF0IGxpc3RcbiAgICAgIGlmIChmbGF0SWR4IDwgZmxhdFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICByZXN1bHQucHVzaChmbGF0UXVldWVbZmxhdElkeF0pO1xuICAgICAgICBmbGF0SWR4Kys7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQXBwZW5kIGFueSBuZXdseSBpbnNlcnRlZCBsYXllcnMgYXQgdGhlIGZyb250ICh0aGV5IGFyZSBuZXcpXG4gIHJldHVybiB7XG4gICAgbmV3TGF5ZXJPcmRlcjogWy4uLm5ld0luc2VydGVkSWRzLCAuLi5yZXN1bHRdLFxuICAgIG5ld0xheWVyc1xuICB9O1xufVxuXG4vKipcbiAqIE1lcmdlIHNhdmVkIGxheWVyT3JkZXIgd2l0aCBjdXJyZW50IHN0YXRlIHRvIHJlc3RvcmUgbGF5ZXIgZ3JvdXBzLlxuICogQ2FsbGVkIGFmdGVyIGxheWVycyBoYXZlIGJlZW4gbWVyZ2VkLiBJZiB0aGUgc2F2ZWQgY29uZmlnIGNvbnRhaW5zIGEgbGF5ZXJPcmRlclxuICogd2l0aCBncm91cHMsIHRoaXMgcmVwbGFjZXMgdGhlIGZsYXQgbGF5ZXJPcmRlciB3aXRoIHRoZSBzYXZlZCBoaWVyYXJjaGljYWwgb25lLFxuICogZmlsdGVyaW5nIG91dCBhbnkgbGF5ZXIgSURzIHRoYXQgZG9uJ3QgZXhpc3QgaW4gdGhlIGN1cnJlbnQgc3RhdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUxheWVyT3JkZXI8UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIHNhdmVkTGF5ZXJPcmRlcj86IGFueVtdLFxuICBmcm9tQ29uZmlnPzogYm9vbGVhblxuKTogUyB7XG4gIGlmICghc2F2ZWRMYXllck9yZGVyIHx8ICFBcnJheS5pc0FycmF5KHNhdmVkTGF5ZXJPcmRlcikgfHwgc2F2ZWRMYXllck9yZGVyLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIHRoZSBzYXZlZCBsYXllck9yZGVyIGNvbnRhaW5zIGFueSBncm91cHNcbiAgY29uc3QgaGFzR3JvdXBzID0gc2F2ZWRMYXllck9yZGVyLnNvbWUoZW50cnkgPT4gaXNQbGFpbk9iamVjdChlbnRyeSkpO1xuICBpZiAoIWhhc0dyb3Vwcykge1xuICAgIC8vIE5vIGdyb3VwcyAtIHRoZSBsYXllciBtZXJnZXIgYWxyZWFkeSBoYW5kbGVkIG9yZGVyaW5nIHZpYSBwcmVzZXJ2ZUxheWVyT3JkZXJcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICAvLyBJZiBsYXllcnMgaGF2ZW4ndCBiZWVuIG1lcmdlZCB5ZXQsIHN0b3JlIGZvciBsYXRlclxuICBpZiAoc3RhdGUubGF5ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIGxheWVyT3JkZXJUb0JlTWVyZ2VkOiBzYXZlZExheWVyT3JkZXJcbiAgICB9O1xuICB9XG5cbiAgLy8gQnVpbGQgYSBzZXQgb2YgdmFsaWQgbGF5ZXIgSURzIGZyb20gY3VycmVudCBzdGF0ZVxuICBjb25zdCB2YWxpZExheWVySWRzID0gbmV3IFNldChzdGF0ZS5sYXllcnMubWFwKGwgPT4gbC5pZCkpO1xuXG4gIC8vIFJlY3Vyc2l2ZWx5IGZpbHRlciB0aGUgc2F2ZWQgbGF5ZXJPcmRlciB0byBvbmx5IGluY2x1ZGUgdmFsaWQgbGF5ZXJzXG4gIGZ1bmN0aW9uIGZpbHRlckxheWVyT3JkZXIob3JkZXI6IGFueVtdKTogTGF5ZXJPcmRlciB7XG4gICAgY29uc3QgcmVzdWx0OiBMYXllck9yZGVyID0gW107XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBvcmRlcikge1xuICAgICAgaWYgKGlzUGxhaW5PYmplY3QoZW50cnkpKSB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gZW50cnkgYXMgTGF5ZXJPcmRlckdyb3VwO1xuICAgICAgICBjb25zdCBmaWx0ZXJlZEdyb3VwT3JkZXIgPSBmaWx0ZXJMYXllck9yZGVyKGdyb3VwLmxheWVyT3JkZXIpO1xuICAgICAgICAvLyBLZWVwIHRoZSBncm91cCBldmVuIGlmIGVtcHR5ICh1c2VyIG1heSB3YW50IHRoZSBlbXB0eSBncm91cClcbiAgICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICAgIC4uLmdyb3VwLFxuICAgICAgICAgIGxheWVyT3JkZXI6IGZpbHRlcmVkR3JvdXBPcmRlclxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGVudHJ5ID09PSAnc3RyaW5nJyAmJiB2YWxpZExheWVySWRzLmhhcyhlbnRyeSkpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goZW50cnkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgY29uc3QgcmVzdG9yZWRMYXllck9yZGVyID0gZmlsdGVyTGF5ZXJPcmRlcihzYXZlZExheWVyT3JkZXIpO1xuXG4gIC8vIEZpbmQgYW55IGxheWVycyBpbiB0aGUgY3VycmVudCBzdGF0ZSB0aGF0IGFyZW4ndCBpbiB0aGUgcmVzdG9yZWQgb3JkZXJcbiAgLy8gKGNvdWxkIGhhcHBlbiBpZiBsYXllcnMgd2VyZSBhZGRlZCBiZXR3ZWVuIHNhdmUgYW5kIGxvYWQpXG4gIGNvbnN0IGxheWVySWRzSW5SZXN0b3JlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBmdW5jdGlvbiBjb2xsZWN0SWRzKG9yZGVyOiBhbnlbXSkge1xuICAgIGZvciAoY29uc3QgZW50cnkgb2Ygb3JkZXIpIHtcbiAgICAgIGlmIChpc1BsYWluT2JqZWN0KGVudHJ5KSkge1xuICAgICAgICBjb2xsZWN0SWRzKChlbnRyeSBhcyBMYXllck9yZGVyR3JvdXApLmxheWVyT3JkZXIpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZW50cnkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGxheWVySWRzSW5SZXN0b3JlZC5hZGQoZW50cnkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb2xsZWN0SWRzKHJlc3RvcmVkTGF5ZXJPcmRlcik7XG5cbiAgLy8gQWRkIGFueSBtaXNzaW5nIGxheWVycyBhdCB0aGUgdG9wXG4gIGNvbnN0IG1pc3NpbmdMYXllcnMgPSBzdGF0ZS5sYXllcnNcbiAgICAuZmlsdGVyKGwgPT4gIWxheWVySWRzSW5SZXN0b3JlZC5oYXMobC5pZCkpXG4gICAgLm1hcChsID0+IGwuaWQpO1xuXG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgbGF5ZXJPcmRlcjogWy4uLm1pc3NpbmdMYXllcnMsIC4uLnJlc3RvcmVkTGF5ZXJPcmRlcl0sXG4gICAgbGF5ZXJPcmRlclRvQmVNZXJnZWQ6IG51bGxcbiAgfTtcbn1cblxuLyoqXG4gKiBNZXJnZSBpbnRlcmFjdGlvbnMgd2l0aCBzYXZlZCBjb25maWdcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUludGVyYWN0aW9uczxTIGV4dGVuZHMgVmlzU3RhdGU+KFxuICBzdGF0ZTogUyxcbiAgaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkOiBQYXJ0aWFsPFNhdmVkSW50ZXJhY3Rpb25Db25maWc+IHwgdW5kZWZpbmVkXG4pOiBTIHtcbiAgY29uc3QgbWVyZ2VkOiBOZXN0ZWRQYXJ0aWFsPFNhdmVkSW50ZXJhY3Rpb25Db25maWc+ID0ge307XG4gIGNvbnN0IHVubWVyZ2VkOiBQYXJ0aWFsPFNhdmVkSW50ZXJhY3Rpb25Db25maWc+ID0ge307XG5cbiAgaWYgKGludGVyYWN0aW9uVG9CZU1lcmdlZCkge1xuICAgIChPYmplY3Qua2V5cyhpbnRlcmFjdGlvblRvQmVNZXJnZWQpIGFzIEFycmF5PGtleW9mIFNhdmVkSW50ZXJhY3Rpb25Db25maWc+KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAoIXN0YXRlLmludGVyYWN0aW9uQ29uZmlnW2tleV0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjdXJyZW50Q29uZmlnID1cbiAgICAgICAga2V5ID09PSAndG9vbHRpcCcgfHwga2V5ID09PSAnYnJ1c2gnIHx8IGtleSA9PT0gJ2dlb2NvZGVyJ1xuICAgICAgICAgID8gc3RhdGUuaW50ZXJhY3Rpb25Db25maWdba2V5XS5jb25maWdcbiAgICAgICAgICA6IG51bGw7XG5cbiAgICAgIGNvbnN0IHtlbmFibGVkLCAuLi5jb25maWdTYXZlZH0gPSBpbnRlcmFjdGlvblRvQmVNZXJnZWRba2V5XSB8fCB7fTtcblxuICAgICAgbGV0IGNvbmZpZ1RvTWVyZ2UgPSBjb25maWdTYXZlZDtcblxuICAgICAgaWYgKGtleSA9PT0gJ3Rvb2x0aXAnKSB7XG4gICAgICAgIGNvbnN0IHttZXJnZWRUb29sdGlwLCB1bm1lcmdlZFRvb2x0aXB9ID0gbWVyZ2VJbnRlcmFjdGlvblRvb2x0aXBDb25maWcoXG4gICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgY29uZmlnU2F2ZWQgYXMgU2F2ZWRJbnRlcmFjdGlvbkNvbmZpZ1sndG9vbHRpcCddXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gbWVyZ2UgbmV3IGRhdGFzZXQgdG9vbHRpcHMgd2l0aCBvcmlnaW5hbCBkYXRhc2V0IHRvb2x0aXBzXG4gICAgICAgIGNvbmZpZ1RvTWVyZ2UgPSB7XG4gICAgICAgICAgZmllbGRzVG9TaG93OiB7XG4gICAgICAgICAgICAuLi4oY3VycmVudENvbmZpZyBhcyBUb29sdGlwSW5mb1snY29uZmlnJ10pLmZpZWxkc1RvU2hvdyxcbiAgICAgICAgICAgIC4uLm1lcmdlZFRvb2x0aXBcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKHVubWVyZ2VkVG9vbHRpcCkubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgIHVubWVyZ2VkLnRvb2x0aXAgPSB7ZmllbGRzVG9TaG93OiB1bm1lcmdlZFRvb2x0aXAsIGVuYWJsZWQ6IEJvb2xlYW4oZW5hYmxlZCl9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG1lcmdlZFtrZXldID0ge1xuICAgICAgICAuLi5zdGF0ZS5pbnRlcmFjdGlvbkNvbmZpZ1trZXldLFxuICAgICAgICBlbmFibGVkOiBCb29sZWFuKGVuYWJsZWQpLFxuICAgICAgICAuLi4oY3VycmVudENvbmZpZ1xuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICBjb25maWc6IHBpY2soXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgLi4uY3VycmVudENvbmZpZyxcbiAgICAgICAgICAgICAgICAgIC4uLmNvbmZpZ1RvTWVyZ2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGN1cnJlbnRDb25maWcpXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHt9KVxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IG5leHRTdGF0ZSA9IHtcbiAgICAuLi5zdGF0ZSxcbiAgICBpbnRlcmFjdGlvbkNvbmZpZzoge1xuICAgICAgLi4uc3RhdGUuaW50ZXJhY3Rpb25Db25maWcsXG4gICAgICAuLi5tZXJnZWRcbiAgICB9LFxuICAgIGludGVyYWN0aW9uVG9CZU1lcmdlZDogc2F2ZWRVbm1lcmdlZEludGVyYWN0aW9uKHN0YXRlLCB1bm1lcmdlZClcbiAgfTtcbiAgcmV0dXJuIG5leHRTdGF0ZTtcbn1cblxuZnVuY3Rpb24gY29tYmluZUludGVyYWN0aW9uQ29uZmlncyhjb25maWdzOiBTYXZlZEludGVyYWN0aW9uQ29uZmlnW10pOiBTYXZlZEludGVyYWN0aW9uQ29uZmlnIHtcbiAgY29uc3QgY29tYmluZWQgPSB7Li4uY29uZmlnc1swXX07XG4gIC8vIGhhbmRsZSBlYWNoIHByb3BlcnR5IGtleSBvZiBhbiBgSW50ZXJhY3Rpb25Db25maWdgLCBlLmcuIHRvb2x0aXAsIGdlb2NvZGVyLCBicnVzaCwgY29vcmRpbmF0ZVxuICAvLyBieSBjb21iaW5pbmcgdmFsdWVzIGZvciBlYWNoIGFtb25nIGFsbCBwYXNzZWQgaW4gY29uZmlnc1xuXG4gIGZvciAoY29uc3Qga2V5IGluIGNvbWJpbmVkKSB7XG4gICAgY29uc3QgdG9CZUNvbWJpbmVkUHJvcHMgPSBjb25maWdzLm1hcChjID0+IGNba2V5XSk7XG5cbiAgICAvLyBhbGwgb2YgdGhlc2UgaGF2ZSBhbiBlbmFibGVkIGJvb2xlYW5cbiAgICBjb21iaW5lZFtrZXldID0ge1xuICAgICAgLy8gYXJlIGFueSBvZiB0aGUgY29uZmlncycgZW5hYmxlZCB2YWx1ZXMgdHJ1ZT9cbiAgICAgIGVuYWJsZWQ6IHRvQmVDb21iaW5lZFByb3BzLnNvbWUocCA9PiBwPy5lbmFibGVkKVxuICAgIH07XG5cbiAgICBpZiAoa2V5ID09PSAndG9vbHRpcCcpIHtcbiAgICAgIC8vIGFyZSBhbnkgb2YgdGhlIGNvbmZpZ3MnIGNvbXBhcmVNb2RlIHZhbHVlcyB0cnVlP1xuICAgICAgY29tYmluZWRba2V5XS5jb21wYXJlTW9kZSA9IHRvQmVDb21iaW5lZFByb3BzLnNvbWUocCA9PiBwPy5jb21wYXJlTW9kZSk7XG5cbiAgICAgIC8vIHJldHVybiB0aGUgY29tcGFyZSB0eXBlIG1vZGUsIGl0IHdpbGwgYmUgZWl0aGVyIGFic29sdXRlIG9yIHJlbGF0aXZlXG4gICAgICBjb21iaW5lZFtrZXldLmNvbXBhcmVUeXBlID0gZ2V0VmFsdWVXaXRoSGlnaGVzdE9jY3VycmVuY2UoXG4gICAgICAgIHRvQmVDb21iaW5lZFByb3BzLm1hcChwID0+IHAuY29tcGFyZVR5cGUpXG4gICAgICApO1xuXG4gICAgICAvLyBjb21iaW5lIGZpZWxkc1RvU2hvdyBhbW9uZyBhbGwgZGF0YXNldCBpZHNcbiAgICAgIGNvbWJpbmVkW2tleV0uZmllbGRzVG9TaG93ID0gdG9CZUNvbWJpbmVkUHJvcHNcbiAgICAgICAgLm1hcChwID0+IHAuZmllbGRzVG9TaG93KVxuICAgICAgICAucmVkdWNlKChhY2MsIG5leHRGaWVsZHNUb1Nob3cpID0+IHtcbiAgICAgICAgICBmb3IgKGNvbnN0IG5leHREYXRhSWRLZXkgaW4gbmV4dEZpZWxkc1RvU2hvdykge1xuICAgICAgICAgICAgY29uc3QgbmV4dFRvb2x0aXBGaWVsZHMgPSBuZXh0RmllbGRzVG9TaG93W25leHREYXRhSWRLZXldO1xuICAgICAgICAgICAgaWYgKCFhY2NbbmV4dERhdGFJZEtleV0pIHtcbiAgICAgICAgICAgICAgLy8gaWYgdGhlIGRhdGFzZXQgaWQgaXMgbm90IHByZXNlbnQgaW4gdGhlIGFjY3VtdWxhdG9yXG4gICAgICAgICAgICAgIC8vIHRoZW4gYWRkIGl0IHdpdGggaXRzIHRvb2x0aXAgZmllbGRzXG4gICAgICAgICAgICAgIGFjY1tuZXh0RGF0YUlkS2V5XSA9IG5leHRUb29sdGlwRmllbGRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBkYXRhc2V0IGlkIGlzIGFscmVhZHkgcHJlc2VudCBpbiB0aGUgYWNjdW11bGF0b3JcbiAgICAgICAgICAgICAgLy8gc28gb25seSBhZGQgdGhlIG5leHQgdG9vbHRpcCBmaWVsZHMgZm9yIHRoaXMgZGF0YXNldCdzIGFycmF5IGlmIHRoZXkgYXJlIG5vdCBhbHJlYWR5IHByZXNlbnQsXG4gICAgICAgICAgICAgIC8vIHVzaW5nIHRoZSB0b29sdGlwRmllbGQubmFtZSBwcm9wZXJ0eSBmb3IgdW5pcXVlbmVzc1xuICAgICAgICAgICAgICBuZXh0VG9vbHRpcEZpZWxkcy5mb3JFYWNoKG5leHRURiA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFhY2NbbmV4dERhdGFJZEtleV0uZmluZCgoe25hbWV9KSA9PiBuZXh0VEYubmFtZSA9PT0gbmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgIGFjY1tuZXh0RGF0YUlkS2V5XS5wdXNoKG5leHRURik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwge30pO1xuICAgIH1cblxuICAgIGlmIChrZXkgPT09ICdicnVzaCcpIHtcbiAgICAgIC8vIGtlZXAgdGhlIGJpZ2dlc3QgYnJ1c2ggc2l6ZVxuICAgICAgY29tYmluZWRba2V5XS5zaXplID1cbiAgICAgICAgYWdncmVnYXRlKHRvQmVDb21iaW5lZFByb3BzLCBBR0dSRUdBVElPTl9UWVBFUy5tYXhpbXVtLCBwID0+IHAuc2l6ZSkgPz8gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoa2V5ID09PSAnZ2VvY29kZXInKSB7XG4gICAgICBjb21iaW5lZFtrZXldLmxpbWl0U2VhcmNoID0gdG9CZUNvbWJpbmVkUHJvcHMuc29tZShwID0+IHA/LmxpbWl0U2VhcmNoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29tYmluZWQ7XG59XG5cbmZ1bmN0aW9uIHNhdmVkVW5tZXJnZWRJbnRlcmFjdGlvbjxTIGV4dGVuZHMgVmlzU3RhdGU+KFxuICBzdGF0ZTogUyxcbiAgdW5tZXJnZWQ6IFBhcnRpYWw8U2F2ZWRJbnRlcmFjdGlvbkNvbmZpZz5cbikge1xuICBpZiAoIXVubWVyZ2VkPy50b29sdGlwPy5maWVsZHNUb1Nob3cpIHtcbiAgICByZXR1cm4gc3RhdGUuaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkO1xuICB9XG4gIHJldHVybiB7XG4gICAgdG9vbHRpcDoge1xuICAgICAgLi4uc3RhdGUuaW50ZXJhY3Rpb25Ub0JlTWVyZ2VkLnRvb2x0aXAsXG4gICAgICAuLi4odHlwZW9mIHVubWVyZ2VkPy50b29sdGlwPy5lbmFibGVkID09PSAnYm9vbGVhbidcbiAgICAgICAgPyB7ZW5hYmxlZDogdW5tZXJnZWQudG9vbHRpcC5lbmFibGVkfVxuICAgICAgICA6IHt9KSxcbiAgICAgIGZpZWxkc1RvU2hvdzoge1xuICAgICAgICAuLi5zdGF0ZS5pbnRlcmFjdGlvblRvQmVNZXJnZWQ/LnRvb2x0aXA/LmZpZWxkc1RvU2hvdyxcbiAgICAgICAgLi4udW5tZXJnZWQ/LnRvb2x0aXA/LmZpZWxkc1RvU2hvd1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVwbGFjZUludGVyYWN0aW9uRGF0YXNldElkcyhpbnRlcmFjdGlvbkNvbmZpZywgZGF0YUlkOiBzdHJpbmcsIGRhdGFJZFRvUmVwbGFjZTogc3RyaW5nKSB7XG4gIGlmIChpbnRlcmFjdGlvbkNvbmZpZz8udG9vbHRpcD8uZmllbGRzVG9TaG93W2RhdGFJZF0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uaW50ZXJhY3Rpb25Db25maWcsXG4gICAgICB0b29sdGlwOiB7XG4gICAgICAgIC4uLmludGVyYWN0aW9uQ29uZmlnLnRvb2x0aXAsXG4gICAgICAgIGZpZWxkc1RvU2hvdzoge1xuICAgICAgICAgIFtkYXRhSWRUb1JlcGxhY2VdOiBpbnRlcmFjdGlvbkNvbmZpZz8udG9vbHRpcD8uZmllbGRzVG9TaG93W2RhdGFJZF1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogTWVyZ2Ugc3BsaXRNYXBzIGNvbmZpZyB3aXRoIGN1cnJlbnQgdmlzU3RldGUuXG4gKiAxLiBpZiBjdXJyZW50IG1hcCBpcyBzcGxpdCwgYnV0IHNwbGl0TWFwIERPRVNOT1QgY29udGFpbiBtYXBzXG4gKiAgICA6IGRvbid0IG1lcmdlIGFueXRoaW5nXG4gKiAyLiBpZiBjdXJyZW50IG1hcCBpcyBOT1Qgc3BsaXQsIGJ1dCBzcGxpdE1hcHMgY29udGFpbiBtYXBzXG4gKiAgICA6IGFkZCB0byBzcGxpdE1hcHMsIGFuZCBhZGQgY3VycmVudCBsYXllcnMgdG8gc3BsaXRNYXBzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZVNwbGl0TWFwczxTIGV4dGVuZHMgVmlzU3RhdGU+KFxuICBzdGF0ZTogUyxcbiAgc3BsaXRNYXBzOiBOb25OdWxsYWJsZTxQYXJzZWRDb25maWdbJ3Zpc1N0YXRlJ10+WydzcGxpdE1hcHMnXSA9IFtdXG4pOiBTIHtcbiAgY29uc3QgbWVyZ2VkID0gWy4uLnN0YXRlLnNwbGl0TWFwc107XG4gIGNvbnN0IHVubWVyZ2VkID0gW107XG4gIHNwbGl0TWFwcy5mb3JFYWNoKChzbSwgaSkgPT4ge1xuICAgIGNvbnN0IGVudHJpZXMgPSBPYmplY3QuZW50cmllcyhzbS5sYXllcnMpO1xuICAgIGlmIChlbnRyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGVudHJpZXMuZm9yRWFjaCgoW2lkLCB2YWx1ZV0pID0+IHtcbiAgICAgICAgLy8gY2hlY2sgaWYgbGF5ZXIgZXhpc3RzXG4gICAgICAgIGNvbnN0IHB1c2hUbyA9IHN0YXRlLmxheWVycy5maW5kKGwgPT4gbC5pZCA9PT0gaWQpID8gbWVyZ2VkIDogdW5tZXJnZWQ7XG5cbiAgICAgICAgLy8gY3JlYXRlIG1hcCBwYW5lbCBpZiBjdXJyZW50IG1hcCBpcyBub3Qgc3BsaXRcbiAgICAgICAgcHVzaFRvW2ldID0gcHVzaFRvW2ldIHx8IHtcbiAgICAgICAgICAvLyBrZWVwIGlkXG4gICAgICAgICAgLi4uc20sXG4gICAgICAgICAgbGF5ZXJzOiBwdXNoVG8gPT09IG1lcmdlZCA/IGdldEluaXRpYWxNYXBMYXllcnNGb3JTcGxpdE1hcChzdGF0ZS5sYXllcnMpIDogW11cbiAgICAgICAgfTtcbiAgICAgICAgcHVzaFRvW2ldLmxheWVycyA9IHtcbiAgICAgICAgICAuLi5wdXNoVG9baV0ubGF5ZXJzLFxuICAgICAgICAgIFtpZF06IHZhbHVlXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gV2UgYXJlIG1lcmdpbmcgaWYgdGhlcmUgYXJlIG5vIGxheWVycyBpbiBib3RoIHNwbGl0IG1hcFxuICAgICAgbWVyZ2VkLnB1c2goc20pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBzcGxpdE1hcHM6IG1lcmdlZCxcbiAgICBzcGxpdE1hcHNUb0JlTWVyZ2VkOiBbLi4uc3RhdGUuc3BsaXRNYXBzVG9CZU1lcmdlZCwgLi4udW5tZXJnZWRdXG4gIH07XG59XG5cbi8qKlxuICogTWVyZ2UgZWZmZWN0cyB3aXRoIHNhdmVkIGNvbmZpZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VFZmZlY3RzPFMgZXh0ZW5kcyBWaXNTdGF0ZT4oXG4gIHN0YXRlOiBTLFxuICBlZmZlY3RzOiBOb25OdWxsYWJsZTxQYXJzZWRDb25maWdbJ3Zpc1N0YXRlJ10+WydlZmZlY3RzJ10sXG4gIGZyb21Db25maWc/OiBib29sZWFuXG4pOiBTIHtcbiAgY29uc3QgbmV3RWZmZWN0cyA9IFtcbiAgICAuLi5zdGF0ZS5lZmZlY3RzLFxuICAgIC4uLihlZmZlY3RzIHx8IFtdKVxuICAgICAgLm1hcChlZmZlY3QgPT4ge1xuICAgICAgICByZXR1cm4gZnJvbUNvbmZpZ1xuICAgICAgICAgID8gY3JlYXRlRWZmZWN0KFxuICAgICAgICAgICAgICBkZWVwbWVyZ2UuYWxsKFtcbiAgICAgICAgICAgICAgICBlZmZlY3QsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgLy8gY29sbGFwc2UgYWxsIHBhbmVscyB3aGVuIGxvYWRpbmcgZWZmZWN0c1xuICAgICAgICAgICAgICAgICAgaXNDb25maWdBY3RpdmU6IGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBdKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogKGVmZmVjdCBhcyBFZmZlY3RUeXBlKTtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKGVmZmVjdCA9PiB7XG4gICAgICAgIHJldHVybiBCb29sZWFuKGVmZmVjdCAmJiBlZmZlY3QuaXNWYWxpZFRvU2F2ZSgpKTtcbiAgICAgIH0pXG4gIF07XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgZWZmZWN0czogbmV3RWZmZWN0cyxcbiAgICBlZmZlY3RPcmRlcjogbmV3RWZmZWN0cy5tYXAoZWZmZWN0ID0+IGVmZmVjdC5pZClcbiAgfTtcbn1cblxuLyoqXG4gKiBNZXJnZSBhbm5vdGF0aW9ucyB3aXRoIHNhdmVkIGNvbmZpZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VBbm5vdGF0aW9uczxTIGV4dGVuZHMgVmlzU3RhdGU+KHN0YXRlOiBTLCBhbm5vdGF0aW9uczogYW55W10pOiBTIHtcbiAgaWYgKCFhbm5vdGF0aW9ucyB8fCAhYW5ub3RhdGlvbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIGNvbnN0IGV4aXN0aW5nSWRzID0gbmV3IFNldChzdGF0ZS5hbm5vdGF0aW9ucy5tYXAoYSA9PiBhLmlkKSk7XG4gIGNvbnN0IHZhbGlkQW5ub3RhdGlvbnMgPSBhbm5vdGF0aW9uc1xuICAgIC5maWx0ZXIoXG4gICAgICBhID0+XG4gICAgICAgIGEgJiZcbiAgICAgICAgYS5pZCAmJlxuICAgICAgICAhZXhpc3RpbmdJZHMuaGFzKGEuaWQpICYmXG4gICAgICAgIGlzQW5ub3RhdGlvbktpbmQoYS5raW5kKSAmJlxuICAgICAgICBBcnJheS5pc0FycmF5KGEuYW5jaG9yUG9pbnQpICYmXG4gICAgICAgIGEuYW5jaG9yUG9pbnQubGVuZ3RoID09PSAyXG4gICAgKVxuICAgIC5tYXAoYSA9PiAoe1xuICAgICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgICAgYXV0b1NpemU6IHRydWUsXG4gICAgICBhdXRvU2l6ZVk6IHRydWUsXG4gICAgICBsYWJlbDogJycsXG4gICAgICBsaW5lQ29sb3I6IElOSVRJQUxfQU5OT1RBVElPTl9MSU5FX0NPTE9SLFxuICAgICAgbGluZVdpZHRoOiBJTklUSUFMX0FOTk9UQVRJT05fTElORV9XSURUSCxcbiAgICAgIHRleHRXaWR0aDogMCxcbiAgICAgIHRleHRIZWlnaHQ6IDAsXG4gICAgICAuLi5hXG4gICAgfSkpO1xuICBpZiAoIXZhbGlkQW5ub3RhdGlvbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdGUsXG4gICAgYW5ub3RhdGlvbnM6IFsuLi5zdGF0ZS5hbm5vdGF0aW9ucywgLi4udmFsaWRBbm5vdGF0aW9uc11cbiAgfTtcbn1cblxuLyoqXG4gKiBNZXJnZSBpbnRlcmFjdGlvbkNvbmZpZy50b29sdGlwIHdpdGggc2F2ZWQgY29uZmlnLFxuICogdmFsaWRhdGUgZmllbGRzVG9TaG93XG4gKlxuICogQHBhcmFtIHN0YXRlXG4gKiBAcGFyYW0gdG9vbHRpcENvbmZpZ1xuICogQHJldHVybiAtIHttZXJnZWRUb29sdGlwOiB7fSwgdW5tZXJnZWRUb29sdGlwOiB7fX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlSW50ZXJhY3Rpb25Ub29sdGlwQ29uZmlnKFxuICBzdGF0ZTogVmlzU3RhdGUsXG4gIHRvb2x0aXBDb25maWc6IFBpY2s8VG9vbHRpcEluZm9bJ2NvbmZpZyddLCAnZmllbGRzVG9TaG93Jz4gfCBudWxsID0gbnVsbFxuKSB7XG4gIGNvbnN0IHVubWVyZ2VkVG9vbHRpcDogVG9vbHRpcEluZm9bJ2NvbmZpZyddWydmaWVsZHNUb1Nob3cnXSA9IHt9O1xuICBjb25zdCBtZXJnZWRUb29sdGlwOiBUb29sdGlwSW5mb1snY29uZmlnJ11bJ2ZpZWxkc1RvU2hvdyddID0ge307XG5cbiAgaWYgKFxuICAgICF0b29sdGlwQ29uZmlnIHx8XG4gICAgIXRvb2x0aXBDb25maWcuZmllbGRzVG9TaG93IHx8XG4gICAgIU9iamVjdC5rZXlzKHRvb2x0aXBDb25maWcuZmllbGRzVG9TaG93KS5sZW5ndGhcbiAgKSB7XG4gICAgcmV0dXJuIHttZXJnZWRUb29sdGlwLCB1bm1lcmdlZFRvb2x0aXB9O1xuICB9XG5cbiAgZm9yIChjb25zdCBkYXRhSWQgaW4gdG9vbHRpcENvbmZpZy5maWVsZHNUb1Nob3cpIHtcbiAgICBpZiAoIXN0YXRlLmRhdGFzZXRzW2RhdGFJZF0gfHwgc3RhdGUuaXNNZXJnaW5nRGF0YXNldHNbZGF0YUlkXSkge1xuICAgICAgLy8gaXMgbm90IHlldCBsb2FkZWRcbiAgICAgIHVubWVyZ2VkVG9vbHRpcFtkYXRhSWRdID0gdG9vbHRpcENvbmZpZy5maWVsZHNUb1Nob3dbZGF0YUlkXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgZGF0YXNldCBpcyBsb2FkZWRcbiAgICAgIGNvbnN0IGFsbEZpZWxkcyA9IHN0YXRlLmRhdGFzZXRzW2RhdGFJZF0uZmllbGRzLm1hcChkID0+IGQubmFtZSk7XG4gICAgICBjb25zdCBmb3VuZEZpZWxkc1RvU2hvdyA9IHRvb2x0aXBDb25maWcuZmllbGRzVG9TaG93W2RhdGFJZF0uZmlsdGVyKGZpZWxkID0+XG4gICAgICAgIGFsbEZpZWxkcy5pbmNsdWRlcyhmaWVsZC5uYW1lKVxuICAgICAgKTtcblxuICAgICAgbWVyZ2VkVG9vbHRpcFtkYXRhSWRdID0gZm91bmRGaWVsZHNUb1Nob3c7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHttZXJnZWRUb29sdGlwLCB1bm1lcmdlZFRvb2x0aXB9O1xufVxuLyoqXG4gKiBNZXJnZSBsYXllckJsZW5kaW5nIHdpdGggc2F2ZWRcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUxheWVyQmxlbmRpbmc8UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIGxheWVyQmxlbmRpbmc6IE5vbk51bGxhYmxlPFBhcnNlZENvbmZpZ1sndmlzU3RhdGUnXT5bJ2xheWVyQmxlbmRpbmcnXVxuKTogUyB7XG4gIGlmIChsYXllckJsZW5kaW5nICYmIExBWUVSX0JMRU5ESU5HU1tsYXllckJsZW5kaW5nXSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIGxheWVyQmxlbmRpbmdcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlO1xufVxuXG4vKipcbiAqIENvbWJpbmVzIG11bHRpcGxlIGxheWVyIGJsZW5kaW5nIGNvbmZpZ3MgaW50byBhIHNpbmdsZSBzdHJpbmdcbiAqIGJ5IHJldHVybmluZyB0aGUgb25lIHdpdGggdGhlIGhpZ2hlc3Qgb2NjdXJyZW5jZVxuICovXG5mdW5jdGlvbiBjb21iaW5lTGF5ZXJCbGVuZGluZ0NvbmZpZ3MoY29uZmlnczogc3RyaW5nW10pOiBzdHJpbmcgfCBudWxsIHtcbiAgLy8gcmV0dXJuIHRoZSBtb2RlIG9mIHRoZSBsYXllciBibGVuZGluZyB0eXBlXG4gIHJldHVybiBnZXRWYWx1ZVdpdGhIaWdoZXN0T2NjdXJyZW5jZShjb25maWdzKTtcbn1cblxuLyoqXG4gKiBNZXJnZSBvdmVybGF5QmxlbmRpbmcgd2l0aCBzYXZlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VPdmVybGF5QmxlbmRpbmc8UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIG92ZXJsYXlCbGVuZGluZzogTm9uTnVsbGFibGU8UGFyc2VkQ29uZmlnWyd2aXNTdGF0ZSddPlsnb3ZlcmxheUJsZW5kaW5nJ11cbik6IFMge1xuICBpZiAob3ZlcmxheUJsZW5kaW5nICYmIE9WRVJMQVlfQkxFTkRJTkdTW292ZXJsYXlCbGVuZGluZ10pIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBvdmVybGF5QmxlbmRpbmdcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlO1xufVxuXG4vKipcbiAqIENvbWJpbmVzIG11bHRpcGxlIG92ZXJsYXkgYmxlbmRpbmcgY29uZmlncyBpbnRvIGEgc2luZ2xlIHN0cmluZ1xuICogYnkgcmV0dXJuaW5nIHRoZSBvbmUgd2l0aCB0aGUgaGlnaGVzdCBvY2N1cnJlbmNlXG4gKiovXG5mdW5jdGlvbiBjb21iaW5lT3ZlcmxheUJsZW5kaW5nQ29uZmlncyhjb25maWdzOiBzdHJpbmdbXSk6IHN0cmluZyB8IG51bGwge1xuICAvLyByZXR1cm4gdGhlIG1vZGUgb2YgdGhlIG92ZXJsYXkgYmxlbmRpbmcgdHlwZVxuICByZXR1cm4gZ2V0VmFsdWVXaXRoSGlnaGVzdE9jY3VycmVuY2UoY29uZmlncyk7XG59XG5cbi8qKlxuICogTWVyZ2UgYW5pbWF0aW9uIGNvbmZpZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VBbmltYXRpb25Db25maWc8UyBleHRlbmRzIFZpc1N0YXRlPihcbiAgc3RhdGU6IFMsXG4gIGFuaW1hdGlvbjogTm9uTnVsbGFibGU8UGFyc2VkQ29uZmlnWyd2aXNTdGF0ZSddPlsnYW5pbWF0aW9uQ29uZmlnJ11cbik6IFMge1xuICBpZiAoYW5pbWF0aW9uICYmIGFuaW1hdGlvbi5jdXJyZW50VGltZSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5zdGF0ZSxcbiAgICAgIGFuaW1hdGlvbkNvbmZpZzoge1xuICAgICAgICAuLi5zdGF0ZS5hbmltYXRpb25Db25maWcsXG4gICAgICAgIC4uLmFuaW1hdGlvbixcbiAgICAgICAgZG9tYWluOiBudWxsXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBzdGF0ZTtcbn1cblxuZnVuY3Rpb24gY29tYmluZUFuaW1hdGlvbkNvbmZpZ3MoY29uZmlnczogU2F2ZWRBbmltYXRpb25Db25maWdbXSk6IFNhdmVkQW5pbWF0aW9uQ29uZmlnIHtcbiAgLy8gZ2V0IHRoZSBzbWFsbGVzdCB2YWx1ZXMgb2YgY3VycmVudFRpbWUgYW5kIHNwZWVkIGFtb25nIGFsbCBjb25maWdzXG4gIHJldHVybiB7XG4gICAgY3VycmVudFRpbWU6IGFnZ3JlZ2F0ZShjb25maWdzLCBBR0dSRUdBVElPTl9UWVBFUy5taW5pbXVtLCBjID0+IGMuY3VycmVudFRpbWUpID8/IG51bGwsXG4gICAgc3BlZWQ6IGFnZ3JlZ2F0ZShjb25maWdzLCBBR0dSRUdBVElPTl9UWVBFUy5taW5pbXVtLCBjID0+IGMuc3BlZWQpID8/IG51bGxcbiAgfTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBzYXZlZCBsYXllciBjb2x1bW5zIHdpdGggbmV3IGRhdGEsXG4gKiB1cGRhdGUgZmllbGRJZHggYmFzZWQgb24gbmV3IGZpZWxkc1xuICpcbiAqIEBwYXJhbSBmaWVsZHNcbiAqIEBwYXJhbSBzYXZlZENvbHNcbiAqIEBwYXJhbSBlbXB0eUNvbHNcbiAqIEBwYXJhbSBvcHRpb25zXG4gKiBAcmV0dXJuIC0gdmFsaWRhdGVkIGNvbHVtbnMgb3IgbnVsbFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVNhdmVkTGF5ZXJDb2x1bW5zKFxuICBmaWVsZHM6IEtlcGxlclRhYmxlWydmaWVsZHMnXSxcbiAgc2F2ZWRDb2xzOiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICB9ID0ge30sXG4gIGVtcHR5Q29sczogTGF5ZXJDb2x1bW5zLFxuICBvcHRpb25zOiB7dGhyb3dPbkVycm9yPzogYm9vbGVhbn0gPSB7fVxuKSB7XG4gIC8vIFByZXBhcmUgY29sdW1ucyBmb3IgdGhlIHZhbGlkYXRvclxuICBjb25zdCBjb2x1bW5zOiB0eXBlb2YgZW1wdHlDb2xzID0ge307XG4gIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGVtcHR5Q29scykpIHtcbiAgICBjb2x1bW5zW2tleV0gPSB7Li4uZW1wdHlDb2xzW2tleV19O1xuXG4gICAgY29uc3Qgc2F2ZWQgPSBzYXZlZENvbHNba2V5XTtcbiAgICBpZiAoc2F2ZWQpIHtcbiAgICAgIGNvbnN0IGZpZWxkSWR4ID0gZmllbGRzLmZpbmRJbmRleCgoe25hbWV9KSA9PiBuYW1lID09PSBzYXZlZCk7XG5cbiAgICAgIGlmIChmaWVsZElkeCA+IC0xKSB7XG4gICAgICAgIC8vIHVwZGF0ZSBmb3VuZCBjb2x1bW5zXG4gICAgICAgIGNvbHVtbnNba2V5XS5maWVsZElkeCA9IGZpZWxkSWR4O1xuICAgICAgICBjb2x1bW5zW2tleV0udmFsdWUgPSBzYXZlZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBmaW5kIGFjdHVhbCBjb2x1bW4gZmllbGRJZHgsIGluIGNhc2UgaXQgaGFzIGNoYW5nZWRcbiAgY29uc3QgYWxsQ29sRm91bmQgPSBPYmplY3Qua2V5cyhjb2x1bW5zKS5ldmVyeShrZXkgPT5cbiAgICB2YWxpZGF0ZUNvbHVtbihjb2x1bW5zW2tleV0sIGNvbHVtbnMsIGZpZWxkcylcbiAgKTtcblxuICBjb25zdCBydiA9IGFsbENvbEZvdW5kID8gY29sdW1ucyA6IG51bGw7XG4gIGlmIChvcHRpb25zLnRocm93T25FcnJvcikge1xuICAgIGNvbnN0IHJlcXVpcmVkQ29sdW1ucyA9IE9iamVjdC5rZXlzKGVtcHR5Q29scykuZmlsdGVyKGsgPT4gIWVtcHR5Q29sc1trXS5vcHRpb25hbCk7XG4gICAgY29uc3QgbWlzc2luZ0NvbHVtbnMgPSByZXF1aXJlZENvbHVtbnMuZmlsdGVyKGsgPT4gIWNvbHVtbnM/LltrXS52YWx1ZSk7XG4gICAgaWYgKG1pc3NpbmdDb2x1bW5zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMYXllciBoYXMgbWlzc2luZyBvciBpbnZhbGlkIGNvbHVtbnM6ICR7bWlzc2luZ0NvbHVtbnMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgY29uc3QgY29uZmlnQ29sdW1ucyA9IE9iamVjdC5rZXlzKHNhdmVkQ29scyk7XG4gICAgY29uc3QgaW52YWxpZENvbHVtbnMgPSBjb25maWdDb2x1bW5zLmZpbHRlcihrID0+ICFjb2x1bW5zPy5ba10/LnZhbHVlKTtcbiAgICBpZiAoaW52YWxpZENvbHVtbnMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYExheWVyIGhhcyBpbnZhbGlkIGNvbHVtbnM6ICR7aW52YWxpZENvbHVtbnMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcnY7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgbGF5ZXIgY29sdW1uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUNvbHVtbihcbiAgY29sdW1uOiBMYXllckNvbHVtbiAmIHt2YWxpZGF0b3I/OiB0eXBlb2YgdmFsaWRhdGVDb2x1bW59LFxuICBjb2x1bW5zOiBMYXllckNvbHVtbnMsXG4gIGFsbEZpZWxkczogS2VwbGVyVGFibGVbJ2ZpZWxkcyddXG4pOiBib29sZWFuIHtcbiAgaWYgKGNvbHVtbi5vcHRpb25hbCB8fCBjb2x1bW4udmFsdWUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoY29sdW1uLnZhbGlkYXRvcikge1xuICAgIHJldHVybiBjb2x1bW4udmFsaWRhdG9yKGNvbHVtbiwgY29sdW1ucywgYWxsRmllbGRzKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgc2F2ZWQgdGV4dCBsYWJlbCBjb25maWcgd2l0aCBuZXcgZGF0YVxuICogcmVmZXIgdG8gdmlzLXN0YXRlLXNjaGVtYS5qcyBUZXh0TGFiZWxTY2hlbWFWMVxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gZmllbGRzXG4gKiBAcGFyYW0ge09iamVjdH0gc2F2ZWRUZXh0TGFiZWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtPYmplY3R9IC0gdmFsaWRhdGVkIHRleHRsYWJlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVTYXZlZFRleHRMYWJlbChcbiAgZmllbGRzLFxuICBbbGF5ZXJUZXh0TGFiZWxdLFxuICBzYXZlZFRleHRMYWJlbCxcbiAgb3B0aW9uczoge3Rocm93T25FcnJvcj86IGJvb2xlYW59ID0ge31cbikge1xuICBjb25zdCBzYXZlZFRleHRMYWJlbHMgPSBBcnJheS5pc0FycmF5KHNhdmVkVGV4dExhYmVsKSA/IHNhdmVkVGV4dExhYmVsIDogW3NhdmVkVGV4dExhYmVsXTtcblxuICAvLyB2YWxpZGF0ZSBmaWVsZFxuICByZXR1cm4gc2F2ZWRUZXh0TGFiZWxzLm1hcCh0ZXh0TGFiZWwgPT4ge1xuICAgIGNvbnN0IGZpZWxkID0gdGV4dExhYmVsLmZpZWxkXG4gICAgICA/IGZpZWxkcy5maW5kKGZkID0+XG4gICAgICAgICAgT2JqZWN0LmtleXModGV4dExhYmVsLmZpZWxkKS5ldmVyeShrZXkgPT4gdGV4dExhYmVsLmZpZWxkW2tleV0gPT09IGZkW2tleV0pXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcblxuICAgIGlmIChmaWVsZCA9PT0gdW5kZWZpbmVkICYmIG9wdGlvbnMudGhyb3dPbkVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYExheWVyIGhhcyBpbnZhbGlkIHRleHQgbGFiZWwgZmllbGQ6ICR7SlNPTi5zdHJpbmdpZnkodGV4dExhYmVsLmZpZWxkKX1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMobGF5ZXJUZXh0TGFiZWwpLnJlZHVjZShcbiAgICAgIChhY2N1LCBrZXkpID0+ICh7XG4gICAgICAgIC4uLmFjY3UsXG4gICAgICAgIFtrZXldOiBrZXkgPT09ICdmaWVsZCcgPyBmaWVsZCA6IHRleHRMYWJlbFtrZXldIHx8IGxheWVyVGV4dExhYmVsW2tleV1cbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuICB9KTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBzYXZlZCB2aXN1YWwgY2hhbm5lbHMgY29uZmlnIHdpdGggbmV3IGRhdGEsXG4gKiByZWZlciB0byB2aXMtc3RhdGUtc2NoZW1hLmpzIFZpc3VhbENoYW5uZWxTY2hlbWFWMVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVTYXZlZFZpc3VhbENoYW5uZWxzKFxuICBmaWVsZHM6IEtlcGxlclRhYmxlWydmaWVsZHMnXSxcbiAgbmV3TGF5ZXI6IExheWVyLFxuICBzYXZlZExheWVyOiBQYXJzZWRMYXllcixcbiAgb3B0aW9uczoge3Rocm93T25FcnJvcj86IGJvb2xlYW59ID0ge31cbik6IG51bGwgfCBMYXllciB7XG4gIE9iamVjdC52YWx1ZXMobmV3TGF5ZXIudmlzdWFsQ2hhbm5lbHMpLmZvckVhY2goKHtmaWVsZCwgc2NhbGUsIGtleX0pID0+IHtcbiAgICBsZXQgZm91bmRGaWVsZDtcbiAgICBpZiAoc2F2ZWRMYXllci5jb25maWcpIHtcbiAgICAgIGlmIChzYXZlZExheWVyLmNvbmZpZ1tmaWVsZF0pIHtcbiAgICAgICAgZm91bmRGaWVsZCA9IGZpZWxkcy5maW5kKFxuICAgICAgICAgIGZkID0+IHNhdmVkTGF5ZXIuY29uZmlnICYmIGZkLm5hbWUgPT09IHNhdmVkTGF5ZXIuY29uZmlnW2ZpZWxkXS5uYW1lXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZvdW5kQ2hhbm5lbCA9IHtcbiAgICAgICAgLi4uKGZvdW5kRmllbGQgPyB7W2ZpZWxkXTogZm91bmRGaWVsZH0gOiB7fSksXG4gICAgICAgIC4uLihzYXZlZExheWVyLmNvbmZpZ1tzY2FsZV0gPyB7W3NjYWxlXTogc2F2ZWRMYXllci5jb25maWdbc2NhbGVdfSA6IHt9KVxuICAgICAgfTtcbiAgICAgIGlmIChPYmplY3Qua2V5cyhmb3VuZENoYW5uZWwpLmxlbmd0aCkge1xuICAgICAgICBuZXdMYXllci51cGRhdGVMYXllckNvbmZpZyhmb3VuZENoYW5uZWwpO1xuICAgICAgfVxuXG4gICAgICBuZXdMYXllci52YWxpZGF0ZVZpc3VhbENoYW5uZWwoa2V5KTtcbiAgICAgIGlmIChvcHRpb25zLnRocm93T25FcnJvcikge1xuICAgICAgICBjb25zdCBmaWVsZE5hbWUgPSBzYXZlZExheWVyLmNvbmZpZz8uW2ZpZWxkXT8ubmFtZTtcbiAgICAgICAgaWYgKGZpZWxkTmFtZSAmJiBmaWVsZE5hbWUgIT09IG5ld0xheWVyLmNvbmZpZ1tmaWVsZF0/Lm5hbWUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYExheWVyIGhhcyBpbnZhbGlkIHZpc3VhbCBjaGFubmVsIGZpZWxkOiAke2ZpZWxkfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG5ld0xheWVyO1xufVxuXG50eXBlIFZhbGlkYXRlTGF5ZXJPcHRpb24gPSB7XG4gIGFsbG93RW1wdHlDb2x1bW4/OiBib29sZWFuO1xuICB0aHJvd09uRXJyb3I/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlTGF5ZXJzQnlEYXRhc2V0cyhcbiAgZGF0YXNldHM6IERhdGFzZXRzLFxuICBsYXllckNsYXNzZXM6IFZpc1N0YXRlWydsYXllckNsYXNzZXMnXSxcbiAgbGF5ZXJzOiBOb25OdWxsYWJsZTxQYXJzZWRDb25maWdbJ3Zpc1N0YXRlJ10+WydsYXllcnMnXSA9IFtdLFxuICBvcHRpb25zPzogVmFsaWRhdGVMYXllck9wdGlvblxuKSB7XG4gIGNvbnN0IHZhbGlkYXRlZDogTGF5ZXJbXSA9IFtdO1xuICBjb25zdCBmYWlsZWQ6IE5vbk51bGxhYmxlPFBhcnNlZENvbmZpZ1sndmlzU3RhdGUnXT5bJ2xheWVycyddID0gW107XG5cbiAgbGF5ZXJzLmZvckVhY2gobGF5ZXIgPT4ge1xuICAgIGxldCB2YWxpZGF0ZUxheWVyOiBMYXllciB8IG51bGwgPSBudWxsO1xuXG4gICAgaWYgKGxheWVyPy5jb25maWc/LmRhdGFJZCkge1xuICAgICAgaWYgKGRhdGFzZXRzW2xheWVyLmNvbmZpZy5kYXRhSWRdKSB7XG4gICAgICAgIC8vIGRhdGFzZXRzIGFyZSBhbHJlYWR5IGxvYWRlZFxuICAgICAgICB2YWxpZGF0ZUxheWVyID0gdmFsaWRhdGVMYXllcldpdGhEYXRhKFxuICAgICAgICAgIGRhdGFzZXRzW2xheWVyLmNvbmZpZy5kYXRhSWRdLFxuICAgICAgICAgIGxheWVyLFxuICAgICAgICAgIGxheWVyQ2xhc3NlcyxcbiAgICAgICAgICBvcHRpb25zXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHZhbGlkYXRlTGF5ZXIpIHtcbiAgICAgIHZhbGlkYXRlZC5wdXNoKHZhbGlkYXRlTGF5ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBkYXRhc2V0cyBub3QgeWV0IGxvYWRlZFxuICAgICAgZmFpbGVkLnB1c2gobGF5ZXIpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHt2YWxpZGF0ZWQsIGZhaWxlZH07XG59XG5cbi8qKlxuICogR2V0IHJlcXVpcmVkIGNvbHVtbnMgZm9yIHZhbGlkYXRpb24gYmFzZWQgb24gY29sdW1uIG1vZGVcbiAqL1xuZnVuY3Rpb24gX2dldENvbHVtbkNvbmZpZ0ZvclZhbGlkYXRpb24obmV3TGF5ZXIpIHtcbiAgLy8gZmluZCBjb2x1bW4gZmllbGRJZHhcbiAgbGV0IGNvbHVtbkNvbmZpZyA9IG5ld0xheWVyLmdldExheWVyQ29sdW1ucygpO1xuICAvLyBpZiBjb2x1bW5Nb2RlIGlzIGRlZmluZWQsIGZpbmQgY29sdW1uIG1vZGUgY29uZmlnXG4gIGNvbnN0IGNvbE1vZGVDb25maWcgPSBuZXdMYXllci5jb25maWcuY29sdW1uTW9kZVxuICAgID8gKG5ld0xheWVyLnN1cHBvcnRlZENvbHVtbk1vZGVzIHx8IFtdKS5maW5kKFxuICAgICAgICBjb2xNb2RlID0+IGNvbE1vZGUua2V5ID09PSBuZXdMYXllci5jb25maWcuY29sdW1uTW9kZVxuICAgICAgKVxuICAgIDogbnVsbDtcblxuICBpZiAoY29sTW9kZUNvbmZpZykge1xuICAgIC8vIG9ubHkgdmFsaWRhdGUgY29sdW1ucyBpbiBjb2x1bW4gbW9kZVxuICAgIGNvbHVtbkNvbmZpZyA9IFtcbiAgICAgIC4uLihjb2xNb2RlQ29uZmlnLnJlcXVpcmVkQ29sdW1ucyB8fCBbXSksXG4gICAgICAuLi4oY29sTW9kZUNvbmZpZy5vcHRpb25hbENvbHVtbnMgfHwgW10pXG4gICAgXS5yZWR1Y2UoXG4gICAgICAoYWNjdSwga2V5KSA9PiAoe1xuICAgICAgICAuLi5hY2N1LFxuICAgICAgICBba2V5XTogY29sdW1uQ29uZmlnW2tleV1cbiAgICAgIH0pLFxuICAgICAge31cbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGNvbHVtbkNvbmZpZztcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBzYXZlZCBsYXllciBjb25maWcgd2l0aCBuZXcgZGF0YSxcbiAqIHVwZGF0ZSBmaWVsZElkeCBiYXNlZCBvbiBuZXcgZmllbGRzXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVMYXllcldpdGhEYXRhKFxuICBkYXRhc2V0OiBLZXBsZXJUYWJsZSxcbiAgc2F2ZWRMYXllcjogUGFyc2VkTGF5ZXIsXG4gIGxheWVyQ2xhc3NlczogVmlzU3RhdGVbJ2xheWVyQ2xhc3NlcyddLFxuICBvcHRpb25zOiBWYWxpZGF0ZUxheWVyT3B0aW9uID0ge31cbik6IExheWVyIHwgbnVsbCB7XG4gIGNvbnN0IHtmaWVsZHMsIGlkOiBkYXRhSWR9ID0gZGF0YXNldDtcbiAgY29uc3Qge3R5cGV9ID0gc2F2ZWRMYXllcjtcbiAgY29uc3Qge3Rocm93T25FcnJvcn0gPSBvcHRpb25zO1xuICAvLyBsYXllciBkb2VzbnQgaGF2ZSBhIHZhbGlkIHR5cGVcbiAgaWYgKCF0eXBlIHx8ICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobGF5ZXJDbGFzc2VzLCB0eXBlKSB8fCAhc2F2ZWRMYXllci5jb25maWcpIHtcbiAgICBpZiAodGhyb3dPbkVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYExheWVyIGhhcyBpbnZhbGlkIHR5cGUgXCIke3R5cGV9XCIgb3IgY29uZmlnIGlzIG1pc3NpbmdgKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBsZXQgbmV3TGF5ZXIgPSBuZXcgbGF5ZXJDbGFzc2VzW3R5cGVdKHtcbiAgICBpZDogc2F2ZWRMYXllci5pZCxcbiAgICBkYXRhSWQsXG4gICAgbGFiZWw6IHNhdmVkTGF5ZXIuY29uZmlnLmxhYmVsLFxuICAgIGNvbG9yOiBzYXZlZExheWVyLmNvbmZpZy5jb2xvcixcbiAgICBpc1Zpc2libGU6IHNhdmVkTGF5ZXIuY29uZmlnLmlzVmlzaWJsZSxcbiAgICBoaWRkZW46IHNhdmVkTGF5ZXIuY29uZmlnLmhpZGRlbixcbiAgICBjb2x1bW5Nb2RlOiBzYXZlZExheWVyLmNvbmZpZy5jb2x1bW5Nb2RlLFxuICAgIGhpZ2hsaWdodENvbG9yOiBzYXZlZExheWVyLmNvbmZpZy5oaWdobGlnaHRDb2xvclxuICB9KTtcblxuICBjb25zdCBjb2x1bW5Db25maWcgPSBfZ2V0Q29sdW1uQ29uZmlnRm9yVmFsaWRhdGlvbihuZXdMYXllcik7XG5cbiAgaWYgKE9iamVjdC5rZXlzKGNvbHVtbkNvbmZpZykpIHtcbiAgICBjb25zdCBjb2x1bW5zID0gdmFsaWRhdGVTYXZlZExheWVyQ29sdW1ucyhcbiAgICAgIGZpZWxkcyxcbiAgICAgIHNhdmVkTGF5ZXIuY29uZmlnLmNvbHVtbnMsXG4gICAgICBjb2x1bW5Db25maWcsXG4gICAgICBvcHRpb25zXG4gICAgKTtcbiAgICBpZiAoY29sdW1ucykge1xuICAgICAgbmV3TGF5ZXIudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgICAgICBjb2x1bW5zOiB7XG4gICAgICAgICAgLi4ubmV3TGF5ZXIuY29uZmlnLmNvbHVtbnMsXG4gICAgICAgICAgLi4uY29sdW1uc1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKCFvcHRpb25zLmFsbG93RW1wdHlDb2x1bW4pIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHRleHRMYWJlbCA9XG4gICAgc2F2ZWRMYXllci5jb25maWcudGV4dExhYmVsICYmIG5ld0xheWVyLmNvbmZpZy50ZXh0TGFiZWxcbiAgICAgID8gdmFsaWRhdGVTYXZlZFRleHRMYWJlbChcbiAgICAgICAgICBmaWVsZHMsXG4gICAgICAgICAgbmV3TGF5ZXIuY29uZmlnLnRleHRMYWJlbCxcbiAgICAgICAgICBzYXZlZExheWVyLmNvbmZpZy50ZXh0TGFiZWwsXG4gICAgICAgICAgb3B0aW9uc1xuICAgICAgICApXG4gICAgICA6IG5ld0xheWVyLmNvbmZpZy50ZXh0TGFiZWw7XG5cbiAgLy8gY29weSB2aXNDb25maWcgb3ZlciB0byBlbXB0eUxheWVyIHRvIG1ha2Ugc3VyZSBpdCBoYXMgYWxsIHRoZSBwcm9wc1xuICBjb25zdCBjb3BpZWRWaXNDb25maWcgPSBuZXdMYXllci5jb3B5TGF5ZXJDb25maWcoXG4gICAgbmV3TGF5ZXIuY29uZmlnLnZpc0NvbmZpZyxcbiAgICBzYXZlZExheWVyLmNvbmZpZy52aXNDb25maWcgfHwge30sXG4gICAge1xuICAgICAgc2hhbGxvd0NvcHk6IFsnY29sb3JSYW5nZScsICdzdHJva2VDb2xvclJhbmdlJ11cbiAgICB9XG4gICk7XG5cbiAgLy8gY2FsbCBsYXllciBtZXRob2RzIHRvIHZhbGlkYXRlIHZpc0NvbmZpZyB3aGVuIHN3aXRjaGluZyBkYXRhc2V0XG4gIGNvbnN0IHZpc0NvbmZpZyA9IG5ld0xheWVyLnZhbGlkYXRlVmlzQ29uZmlnXG4gICAgPyBuZXdMYXllci52YWxpZGF0ZVZpc0NvbmZpZyhkYXRhc2V0LCBjb3BpZWRWaXNDb25maWcpXG4gICAgOiBjb3BpZWRWaXNDb25maWc7XG5cbiAgbmV3TGF5ZXIudXBkYXRlTGF5ZXJDb25maWcoe1xuICAgIHZpc0NvbmZpZyxcbiAgICB0ZXh0TGFiZWxcbiAgfSk7XG5cbiAgLy8gdmlzdWFsIGNoYW5uZWwgZmllbGQgaXMgc2F2ZWQgdG8gYmUge25hbWUsIHR5cGV9XG4gIC8vIGZpbmQgdmlzdWFsIGNoYW5uZWwgZmllbGQgYnkgbWF0Y2hpbmcgYm90aCBuYW1lIGFuZCB0eXBlXG4gIC8vIHJlZmVyIHRvIHZpcy1zdGF0ZS1zY2hlbWEuanMgVmlzdWFsQ2hhbm5lbFNjaGVtYVYxXG4gIG5ld0xheWVyID0gdmFsaWRhdGVTYXZlZFZpc3VhbENoYW5uZWxzKGZpZWxkcywgbmV3TGF5ZXIsIHNhdmVkTGF5ZXIsIG9wdGlvbnMpO1xuXG4gIGlmICh0aHJvd09uRXJyb3IpIHtcbiAgICBpZiAoIW5ld0xheWVyLmlzVmFsaWRUb1NhdmUoKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBMYXllciBpcyBub3QgdmFsaWQgdG8gc2F2ZTogJHtuZXdMYXllci5pZH1gKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3TGF5ZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUVkaXRvcjxTIGV4dGVuZHMgVmlzU3RhdGU+KHN0YXRlOiBTLCBzYXZlZEVkaXRvcjogU2F2ZWRFZGl0b3IpIHtcbiAgaWYgKCFzYXZlZEVkaXRvcikge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGVkaXRvcjoge1xuICAgICAgLi4uc3RhdGUuZWRpdG9yLFxuICAgICAgZmVhdHVyZXM6IFsuLi5zdGF0ZS5lZGl0b3IuZmVhdHVyZXMsIC4uLihzYXZlZEVkaXRvci5mZWF0dXJlcyB8fCBbXSldLFxuICAgICAgLy8gaWYgc2F2ZWRFZGl0b3IudmlzaWJsZSBpcyB1bmRlZmluZWQga2VlcCBzdGF0ZS5lZGl0b3IudmlzaWJsZVxuICAgICAgdmlzaWJsZTogc2F2ZWRFZGl0b3IudmlzaWJsZSA/PyBzdGF0ZS5lZGl0b3IudmlzaWJsZVxuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gY29tYmluZUVkaXRvckNvbmZpZ3MoY29uZmlnczogU2F2ZWRFZGl0b3JbXSk6IFNhdmVkRWRpdG9yIHtcbiAgcmV0dXJuIGNvbmZpZ3MucmVkdWNlKFxuICAgIChhY2MsIG5leHRDb25maWcpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmFjYyxcbiAgICAgICAgZmVhdHVyZXM6IFsuLi5hY2MuZmVhdHVyZXMsIC4uLihuZXh0Q29uZmlnLmZlYXR1cmVzIHx8IFtdKV1cbiAgICAgIH07XG4gICAgfSxcbiAgICB7XG4gICAgICAvLyBzdGFydCB3aXRoOlxuICAgICAgLy8gLSBlbXB0eSBhcnJheSBmb3IgZmVhdHVyZXMgYWNjdW11bGF0aW9uXG4gICAgICAvLyAtIGFuZCBhcmUgYW55IG9mIHRoZSBjb25maWdzJyB2aXNpYmxlIHZhbHVlcyB0cnVlP1xuICAgICAgZmVhdHVyZXM6IFtdLFxuICAgICAgdmlzaWJsZTogY29uZmlncy5zb21lKGMgPT4gYz8udmlzaWJsZSlcbiAgICB9XG4gICk7XG59XG5cbi8qKlxuICogVmFsaWRhdGUgc2F2ZWQgbGF5ZXIgY29uZmlnIHdpdGggbmV3IGRhdGEsXG4gKiB1cGRhdGUgZmllbGRJZHggYmFzZWQgb24gbmV3IGZpZWxkc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEYXRhc2V0c0J5T3JkZXIoc3RhdGU6IFZpc1N0YXRlLCBuZXdEYXRhRW50cmllczogRGF0YXNldHMpOiBEYXRhc2V0cyB7XG4gIGNvbnN0IG1lcmdlZCA9IHtcbiAgICAuLi5zdGF0ZS5kYXRhc2V0cyxcbiAgICAuLi5uZXdEYXRhRW50cmllc1xuICB9O1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHN0YXRlLnByZXNlcnZlRGF0YXNldE9yZGVyKSkge1xuICAgIC8vIHByZXNlcnZlRGF0YXNldE9yZGVyICBtaWdodCBub3QgaW5jbHVkZSB0aGUgIG5ldyBkYXRhc2V0c1xuICAgIGNvbnN0IG5ld0RhdGFzZXRJZHMgPSBPYmplY3Qua2V5cyhtZXJnZWQpLmZpbHRlcihcbiAgICAgIGlkID0+ICFzdGF0ZS5wcmVzZXJ2ZURhdGFzZXRPcmRlcj8uaW5jbHVkZXMoaWQpXG4gICAgKTtcbiAgICByZXR1cm4gWy4uLnN0YXRlLnByZXNlcnZlRGF0YXNldE9yZGVyLCAuLi5uZXdEYXRhc2V0SWRzXS5yZWR1Y2UoXG4gICAgICAoYWNjdSwgZGF0YUlkKSA9PiAoe1xuICAgICAgICAuLi5hY2N1LFxuICAgICAgICAuLi4obWVyZ2VkW2RhdGFJZF0gPyB7W2RhdGFJZF06IG1lcmdlZFtkYXRhSWRdfSA6IHt9KVxuICAgICAgfSksXG4gICAgICB7fVxuICAgICk7XG4gIH1cblxuICByZXR1cm4gbWVyZ2VkO1xufVxuXG4vKipcbiAqIFNpbWxpYXIgcHVycG9zZSB0byBhZ2dyZWdhdGlvbiB1dGlscyBgZ2V0TW9kZWAgZnVuY3Rpb24sXG4gKiBidXQgcmV0dXJucyB0aGUgbW9kZSBpbiB0aGUgc2FtZSB2YWx1ZSB0eXBlIHdpdGhvdXQgY29lcmNpbmcgdG8gYSBzdHJpbmcuXG4gKiBJdCBpZ25vcmVzIGB1bmRlZmluZWRgIG9yIGBudWxsYCB2YWx1ZXMsIGJ1dCByZXR1cm5zIGBudWxsYCBpZiBubyBtb2RlIGNvdWxkIGJlIGNhbGN1bGF0ZWQuXG4gKi9cbmZ1bmN0aW9uIGdldFZhbHVlV2l0aEhpZ2hlc3RPY2N1cnJlbmNlPFQ+KGFycjogVFtdKTogVCB8IG51bGwge1xuICBjb25zdCB0YWxseXMgPSBuZXcgTWFwKCk7XG4gIGFyci5mb3JFYWNoKHZhbHVlID0+IHtcbiAgICBpZiAobm90TnVsbG9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgICAgaWYgKCF0YWxseXMuaGFzKHZhbHVlKSkge1xuICAgICAgICB0YWxseXMuc2V0KHZhbHVlLCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRhbGx5cy5zZXQodmFsdWUsIHRhbGx5cy5nZXQodmFsdWUpICsgMSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgLy8gcmV0dXJuIHRoZSB2YWx1ZSB3aXRoIHRoZSBoaWdoZXN0IHRvdGFsIG9jY3VycmVuY2UgY291bnRcbiAgaWYgKHRhbGx5cy5zaXplID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIFsuLi50YWxseXMuZW50cmllcygpXT8ucmVkdWNlKChhY2MsIG5leHQpID0+IChuZXh0WzFdID4gYWNjWzFdID8gbmV4dCA6IGFjYykpWzBdO1xufVxuXG5leHBvcnQgY29uc3QgVklTX1NUQVRFX01FUkdFUlM6IFZpc1N0YXRlTWVyZ2Vyczxhbnk+ID0gW1xuICB7XG4gICAgbWVyZ2U6IG1lcmdlTGF5ZXJzLFxuICAgIHByb3A6ICdsYXllcnMnLFxuICAgIHRvTWVyZ2VQcm9wOiAnbGF5ZXJUb0JlTWVyZ2VkJyxcbiAgICBwcmVzZXJ2ZU9yZGVyOiAncHJlc2VydmVMYXllck9yZGVyJ1xuICB9LFxuICB7XG4gICAgbWVyZ2U6IG1lcmdlTGF5ZXJPcmRlcixcbiAgICBwcm9wOiAnbGF5ZXJPcmRlcidcbiAgfSxcbiAge1xuICAgIG1lcmdlOiBtZXJnZUZpbHRlcnMsXG4gICAgcHJvcDogJ2ZpbHRlcnMnLFxuICAgIHRvTWVyZ2VQcm9wOiAnZmlsdGVyVG9CZU1lcmdlZCcsXG4gICAgcHJlc2VydmVPcmRlcjogJ3ByZXNlcnZlRmlsdGVyT3JkZXInLFxuICAgIHJlcGxhY2VQYXJlbnREYXRhc2V0SWRzOiByZXBsYWNlRmlsdGVyRGF0YXNldElkc1xuICB9LFxuICB7XG4gICAgbWVyZ2U6IG1lcmdlRWZmZWN0cyxcbiAgICBwcm9wOiAnZWZmZWN0cydcbiAgfSxcbiAge1xuICAgIG1lcmdlOiBtZXJnZUFubm90YXRpb25zLFxuICAgIHByb3A6ICdhbm5vdGF0aW9ucycsXG4gICAgdG9NZXJnZVByb3A6ICdhbm5vdGF0aW9uc1RvQmVNZXJnZWQnXG4gIH0sXG4gIHtcbiAgICBtZXJnZTogbWVyZ2VJbnRlcmFjdGlvbnMsXG4gICAgcHJvcDogJ2ludGVyYWN0aW9uQ29uZmlnJyxcbiAgICB0b01lcmdlUHJvcDogJ2ludGVyYWN0aW9uVG9CZU1lcmdlZCcsXG4gICAgcmVwbGFjZVBhcmVudERhdGFzZXRJZHM6IHJlcGxhY2VJbnRlcmFjdGlvbkRhdGFzZXRJZHMsXG4gICAgc2F2ZVVubWVyZ2VkOiBzYXZlZFVubWVyZ2VkSW50ZXJhY3Rpb24sXG4gICAgY29tYmluZUNvbmZpZ3M6IGNvbWJpbmVJbnRlcmFjdGlvbkNvbmZpZ3NcbiAgfSxcbiAge21lcmdlOiBtZXJnZUxheWVyQmxlbmRpbmcsIHByb3A6ICdsYXllckJsZW5kaW5nJywgY29tYmluZUNvbmZpZ3M6IGNvbWJpbmVMYXllckJsZW5kaW5nQ29uZmlnc30sXG4gIHtcbiAgICBtZXJnZTogbWVyZ2VPdmVybGF5QmxlbmRpbmcsXG4gICAgcHJvcDogJ292ZXJsYXlCbGVuZGluZycsXG4gICAgY29tYmluZUNvbmZpZ3M6IGNvbWJpbmVPdmVybGF5QmxlbmRpbmdDb25maWdzXG4gIH0sXG4gIHttZXJnZTogbWVyZ2VTcGxpdE1hcHMsIHByb3A6ICdzcGxpdE1hcHMnLCB0b01lcmdlUHJvcDogJ3NwbGl0TWFwc1RvQmVNZXJnZWQnfSxcbiAge21lcmdlOiBtZXJnZUFuaW1hdGlvbkNvbmZpZywgcHJvcDogJ2FuaW1hdGlvbkNvbmZpZycsIGNvbWJpbmVDb25maWdzOiBjb21iaW5lQW5pbWF0aW9uQ29uZmlnc30sXG4gIHttZXJnZTogbWVyZ2VFZGl0b3IsIHByb3A6ICdlZGl0b3InLCBjb21iaW5lQ29uZmlnczogY29tYmluZUVkaXRvckNvbmZpZ3N9XG5dO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0EsSUFBQUEsS0FBQSxHQUFB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