@kepler.gl/mcp 0.0.0-stage → 3.3.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/commands/add-column-command.js +192 -0
- package/dist/cjs/commands/basemap-command.js +80 -0
- package/dist/cjs/commands/boundary-command.js +81 -0
- package/dist/cjs/commands/command-wrappers.js +122 -0
- package/dist/cjs/commands/dataset-context-command.js +87 -0
- package/dist/cjs/commands/index.js +230 -0
- package/dist/cjs/commands/layer-creation-command.js +534 -0
- package/dist/cjs/commands/layer-style-command.js +136 -0
- package/dist/cjs/commands/load-data-command.js +270 -0
- package/dist/cjs/commands/save-data-command.js +118 -0
- package/dist/cjs/commands/split-view-command.js +261 -0
- package/dist/cjs/commands/table-command.js +199 -0
- package/dist/cjs/commands/time-filter-command.js +289 -0
- package/dist/cjs/commands/toggle-time-filter-command.js +155 -0
- package/dist/cjs/commands/types.js +6 -0
- package/dist/cjs/commands/utils.js +536 -0
- package/dist/cjs/commands/view-mode-command.js +94 -0
- package/dist/cjs/index.js +39 -0
- package/dist/cjs/map-contract.js +6 -0
- package/dist/cjs/server/bridge-server.js +435 -0
- package/dist/cjs/server/index.js +31 -0
- package/dist/cjs/server/stdio.js +201 -0
- package/dist/cjs/types.js +30 -0
- package/dist/commands/add-column-command.d.ts +4 -0
- package/dist/commands/basemap-command.d.ts +4 -0
- package/dist/commands/boundary-command.d.ts +4 -0
- package/dist/commands/command-wrappers.d.ts +52 -0
- package/dist/commands/dataset-context-command.d.ts +4 -0
- package/dist/commands/index.d.ts +31 -0
- package/dist/commands/layer-creation-command.d.ts +8 -0
- package/dist/commands/layer-style-command.d.ts +4 -0
- package/dist/commands/load-data-command.d.ts +4 -0
- package/dist/commands/save-data-command.d.ts +4 -0
- package/dist/commands/split-view-command.d.ts +4 -0
- package/dist/commands/table-command.d.ts +4 -0
- package/dist/commands/time-filter-command.d.ts +13 -0
- package/dist/commands/toggle-time-filter-command.d.ts +4 -0
- package/dist/commands/types.d.ts +132 -0
- package/dist/commands/utils.d.ts +138 -0
- package/dist/commands/view-mode-command.d.ts +4 -0
- package/dist/esm/commands/add-column-command.js +185 -0
- package/dist/esm/commands/basemap-command.js +72 -0
- package/dist/esm/commands/boundary-command.js +73 -0
- package/dist/esm/commands/command-wrappers.js +114 -0
- package/dist/esm/commands/dataset-context-command.js +79 -0
- package/dist/esm/commands/index.js +51 -0
- package/dist/esm/commands/layer-creation-command.js +527 -0
- package/dist/esm/commands/layer-style-command.js +130 -0
- package/dist/esm/commands/load-data-command.js +264 -0
- package/dist/esm/commands/save-data-command.js +112 -0
- package/dist/esm/commands/split-view-command.js +255 -0
- package/dist/esm/commands/table-command.js +194 -0
- package/dist/esm/commands/time-filter-command.js +280 -0
- package/dist/esm/commands/toggle-time-filter-command.js +147 -0
- package/dist/esm/commands/types.js +3 -0
- package/dist/esm/commands/utils.js +521 -0
- package/dist/esm/commands/view-mode-command.js +86 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/map-contract.js +3 -0
- package/dist/esm/server/bridge-server.js +428 -0
- package/dist/esm/server/index.js +13 -0
- package/dist/esm/server/stdio.js +198 -0
- package/dist/esm/types.js +24 -0
- package/dist/index.d.ts +15 -0
- package/dist/map-contract.d.ts +31 -0
- package/dist/server/bridge-server.d.ts +53 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/stdio.d.ts +2 -0
- package/dist/types.d.ts +24 -0
- package/package.json +84 -4
- package/skill/kepler/SKILL.md +438 -0
- package/skill/kepler/skill.yaml +4 -0
- package/README.md +0 -3
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.addLayerCommandId = void 0;
|
|
8
|
+
exports.getAddLayerCommand = getAddLayerCommand;
|
|
9
|
+
exports.guessDefaultLayer = guessDefaultLayer;
|
|
10
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
11
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
12
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
13
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
+
var _zod = require("zod");
|
|
15
|
+
var _constants = require("@kepler.gl/constants");
|
|
16
|
+
var _layers = require("@kepler.gl/layers");
|
|
17
|
+
var _reducers = require("@kepler.gl/reducers");
|
|
18
|
+
var _actions = require("@kepler.gl/actions");
|
|
19
|
+
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; }
|
|
20
|
+
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
|
|
21
|
+
// Copyright contributors to the kepler.gl project
|
|
22
|
+
/**
|
|
23
|
+
* Unique layer id. Date.now()-based ids can collide when multiple layers are
|
|
24
|
+
* created within the same millisecond (rapid successive tool calls), producing
|
|
25
|
+
* duplicate layer ids and unpredictable reducer behavior. Append a random
|
|
26
|
+
* suffix — the same Math.random().toString(36) trick kepler's generateHashId
|
|
27
|
+
* uses — so ids stay unique.
|
|
28
|
+
*/
|
|
29
|
+
function uniqueLayerId() {
|
|
30
|
+
var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'layer';
|
|
31
|
+
return "".concat(prefix, "_").concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 8));
|
|
32
|
+
}
|
|
33
|
+
function guessDefaultLayer(dataset, layerType, options) {
|
|
34
|
+
if (layerType === 'heatmap') {
|
|
35
|
+
if (dataset.fieldPairs && dataset.fieldPairs.length > 0) {
|
|
36
|
+
var props = dataset.fieldPairs.map(function (fieldPair) {
|
|
37
|
+
return {
|
|
38
|
+
isVisible: true,
|
|
39
|
+
label: 'Heatmap',
|
|
40
|
+
columns: fieldPair.pair
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
var _layer = new _layers.LayerClasses.heatmap(props[0]);
|
|
44
|
+
return _layer;
|
|
45
|
+
}
|
|
46
|
+
} else if (layerType === 'hexagon') {
|
|
47
|
+
if (dataset.fieldPairs && dataset.fieldPairs.length > 0) {
|
|
48
|
+
var _props = dataset.fieldPairs.map(function (fieldPair) {
|
|
49
|
+
return {
|
|
50
|
+
isVisible: true,
|
|
51
|
+
label: 'Hexbin',
|
|
52
|
+
columns: fieldPair.pair
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
var _layer2 = new _layers.LayerClasses.hexagon(_props[0]);
|
|
56
|
+
return _layer2;
|
|
57
|
+
}
|
|
58
|
+
} else if (layerType === 'cluster') {
|
|
59
|
+
if (dataset.fieldPairs && dataset.fieldPairs.length > 0) {
|
|
60
|
+
var _props2 = dataset.fieldPairs.map(function (fieldPair) {
|
|
61
|
+
return {
|
|
62
|
+
isVisible: true,
|
|
63
|
+
label: 'Cluster',
|
|
64
|
+
columns: fieldPair.pair
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
var _layer3 = new _layers.LayerClasses.cluster(_props2[0]);
|
|
68
|
+
return _layer3;
|
|
69
|
+
}
|
|
70
|
+
} else if (layerType === 'trip') {
|
|
71
|
+
var layers = (0, _reducers.findDefaultLayer)(dataset, [_layers.LayerClasses.trip]);
|
|
72
|
+
var _layer4 = layers.find(function (l) {
|
|
73
|
+
return l.type === layerType;
|
|
74
|
+
});
|
|
75
|
+
if (_layer4) return _layer4;
|
|
76
|
+
throw new Error("Failed to create a trip layer. Trip layer requires id, lat, lng, and timestamp columns.");
|
|
77
|
+
} else if (layerType === 'flow') {
|
|
78
|
+
// Flow layers are never auto-detected (findDefaultLayerProps returns
|
|
79
|
+
// {props: []}), so build one explicitly from the first two point lat/lng
|
|
80
|
+
// field pairs — the same source/target pair logic the default arc layer
|
|
81
|
+
// uses: pair[0] = origin (lat0/lng0), pair[1] = destination (lat1/lng1).
|
|
82
|
+
// The count column (flow magnitude) is optional; without it every flow
|
|
83
|
+
// renders at weight 1.
|
|
84
|
+
var pairs = dataset.fieldPairs || [];
|
|
85
|
+
if (pairs.length < 2) {
|
|
86
|
+
throw new Error("Failed to create a flow layer. Flow layer requires two point lat/lng pairs " + "(origin + destination), e.g. origin_lat/origin_lng and dest_lat/dest_lng.");
|
|
87
|
+
}
|
|
88
|
+
var columns = {
|
|
89
|
+
lat0: pairs[0].pair.lat,
|
|
90
|
+
lng0: pairs[0].pair.lng,
|
|
91
|
+
lat1: pairs[1].pair.lat,
|
|
92
|
+
lng1: pairs[1].pair.lng
|
|
93
|
+
};
|
|
94
|
+
if (options !== null && options !== void 0 && options.countColumn && dataset.getColumnFieldIdx(options.countColumn) >= 0) {
|
|
95
|
+
columns.count = {
|
|
96
|
+
value: options.countColumn,
|
|
97
|
+
fieldIdx: dataset.getColumnFieldIdx(options.countColumn)
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// LayerClasses' computed keys (keyMirror) aren't statically named, so
|
|
101
|
+
// access flow like the trip branch accesses trip: through an `as any` cast.
|
|
102
|
+
var _layer5 = new _layers.LayerClasses.flow({
|
|
103
|
+
isVisible: true,
|
|
104
|
+
label: "".concat(pairs[0].defaultName, " -> ").concat(pairs[1].defaultName, " flow"),
|
|
105
|
+
columns: columns
|
|
106
|
+
});
|
|
107
|
+
return _layer5;
|
|
108
|
+
}
|
|
109
|
+
var defaultLayers = (0, _reducers.findDefaultLayer)(dataset, _layers.LayerClasses);
|
|
110
|
+
var layer = defaultLayers.find(function (l) {
|
|
111
|
+
return l.type === layerType;
|
|
112
|
+
});
|
|
113
|
+
// Return null (not a fallback to the first default layer) when the requested
|
|
114
|
+
// type can't be created — silently substituting a different layer type (e.g.
|
|
115
|
+
// requesting "h3" and getting a point layer) violates the command contract
|
|
116
|
+
// and makes failures hard to diagnose. The caller errors clearly on null.
|
|
117
|
+
return layer || null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Column names the flow field layer resolves when the caller doesn't name them. */
|
|
121
|
+
var FLOW_FIELD_ALTITUDE_COLUMNS = ['altitude', 'alt', 'elevation', 'elev', 'elv', 'height', 'z'];
|
|
122
|
+
var FLOW_FIELD_MODES = ['UV', 'SPEED_DIR', 'ELEVATION'];
|
|
123
|
+
/**
|
|
124
|
+
* Flow Field is a vector/streamline layer: each row is a sample point carrying
|
|
125
|
+
* a position plus a direction — u/v components, speed/direction, or an altitude
|
|
126
|
+
* whose downhill gradient supplies the direction. Unlike the origin→destination
|
|
127
|
+
* `flow` layer it needs no second point pair, and unlike `trip` it animates
|
|
128
|
+
* itself, so no time filter belongs on it.
|
|
129
|
+
*/
|
|
130
|
+
function buildFlowFieldLayer(dataset, position) {
|
|
131
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
132
|
+
var hasColumn = function hasColumn(name) {
|
|
133
|
+
return !!name && dataset.getColumnFieldIdx(name) >= 0;
|
|
134
|
+
};
|
|
135
|
+
var columnRef = function columnRef(name) {
|
|
136
|
+
var fieldIdx = dataset.getColumnFieldIdx(name);
|
|
137
|
+
if (fieldIdx < 0) {
|
|
138
|
+
var _dataset$fields$map$j, _dataset$fields;
|
|
139
|
+
var available = (_dataset$fields$map$j = (_dataset$fields = dataset.fields) === null || _dataset$fields === void 0 ? void 0 : _dataset$fields.map(function (f) {
|
|
140
|
+
return f.name;
|
|
141
|
+
}).join(', ')) !== null && _dataset$fields$map$j !== void 0 ? _dataset$fields$map$j : '';
|
|
142
|
+
throw new Error("Column \"".concat(name, "\" not found in dataset \"").concat(dataset.label, "\". Available columns: ").concat(available));
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
value: name,
|
|
146
|
+
fieldIdx: fieldIdx
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// Position: explicit lat/lng, else the dataset's first detected point pair,
|
|
151
|
+
// else a GeoJSON geometry column (one position per feature).
|
|
152
|
+
var positionColumns = null;
|
|
153
|
+
if (position.latitudeColumn && position.longitudeColumn) {
|
|
154
|
+
positionColumns = {
|
|
155
|
+
lat: columnRef(position.latitudeColumn),
|
|
156
|
+
lng: columnRef(position.longitudeColumn)
|
|
157
|
+
};
|
|
158
|
+
} else {
|
|
159
|
+
var _dataset$fieldPairs;
|
|
160
|
+
var pair = (_dataset$fieldPairs = dataset.fieldPairs) === null || _dataset$fieldPairs === void 0 || (_dataset$fieldPairs = _dataset$fieldPairs[0]) === null || _dataset$fieldPairs === void 0 ? void 0 : _dataset$fieldPairs.pair;
|
|
161
|
+
if (pair !== null && pair !== void 0 && pair.lat && pair !== null && pair !== void 0 && pair.lng) {
|
|
162
|
+
positionColumns = {
|
|
163
|
+
lat: pair.lat,
|
|
164
|
+
lng: pair.lng
|
|
165
|
+
};
|
|
166
|
+
} else {
|
|
167
|
+
var _dataset$fields2;
|
|
168
|
+
var geoField = (_dataset$fields2 = dataset.fields) === null || _dataset$fields2 === void 0 ? void 0 : _dataset$fields2.find(function (f) {
|
|
169
|
+
return f.type === 'geojson' || _constants.GEOJSON_FIELDS.geojson.includes(f.name);
|
|
170
|
+
});
|
|
171
|
+
if (geoField) {
|
|
172
|
+
positionColumns = {
|
|
173
|
+
geojson: {
|
|
174
|
+
value: geoField.name,
|
|
175
|
+
fieldIdx: geoField.fieldIdx
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (!positionColumns) {
|
|
182
|
+
throw new Error('A flow field layer needs a position: lat/lng columns (auto-detected, or pass ' + 'latitudeColumn/longitudeColumn) or a GeoJSON geometry column.');
|
|
183
|
+
}
|
|
184
|
+
var altitudeName = options.altitudeColumn || FLOW_FIELD_ALTITUDE_COLUMNS.find(function (name) {
|
|
185
|
+
return hasColumn(name);
|
|
186
|
+
}) || null;
|
|
187
|
+
var mode = options.mode || (options.uColumn || options.vColumn || hasColumn('u') && hasColumn('v') ? 'UV' : options.speedColumn || options.directionColumn || hasColumn('speed') && hasColumn('direction') ? 'SPEED_DIR' : altitudeName ? 'ELEVATION' : null);
|
|
188
|
+
if (!mode) {
|
|
189
|
+
throw new Error('A flow field layer needs a vector: u/v columns, speed/direction columns, or an ' + 'altitude column (pass flowField.uColumn/vColumn/speedColumn/directionColumn/' + 'altitudeColumn when the names differ).');
|
|
190
|
+
}
|
|
191
|
+
var flowColumns;
|
|
192
|
+
if (mode === 'UV') {
|
|
193
|
+
flowColumns = {
|
|
194
|
+
u: columnRef(options.uColumn || 'u'),
|
|
195
|
+
v: columnRef(options.vColumn || 'v')
|
|
196
|
+
};
|
|
197
|
+
} else if (mode === 'SPEED_DIR') {
|
|
198
|
+
flowColumns = {
|
|
199
|
+
speed: columnRef(options.speedColumn || 'speed'),
|
|
200
|
+
direction: columnRef(options.directionColumn || 'direction')
|
|
201
|
+
};
|
|
202
|
+
} else {
|
|
203
|
+
if (!altitudeName) {
|
|
204
|
+
throw new Error('A flow field layer in ELEVATION mode needs an altitude column (pass flowField.altitudeColumn).');
|
|
205
|
+
}
|
|
206
|
+
flowColumns = {
|
|
207
|
+
altitude: columnRef(altitudeName)
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// UV and SPEED_DIR may also carry an altitude, which lifts the streamlines.
|
|
212
|
+
var altitudeColumn = mode === 'ELEVATION' || !altitudeName ? {} : {
|
|
213
|
+
altitude: columnRef(altitudeName)
|
|
214
|
+
};
|
|
215
|
+
var layer = new _layers.LayerClasses.flowField({
|
|
216
|
+
isVisible: true,
|
|
217
|
+
label: 'Flow Field',
|
|
218
|
+
color: [255, 255, 255],
|
|
219
|
+
columnMode: mode,
|
|
220
|
+
columns: _objectSpread(_objectSpread(_objectSpread({}, positionColumns), flowColumns), altitudeColumn)
|
|
221
|
+
});
|
|
222
|
+
if (options.colorBySpeed) {
|
|
223
|
+
layer.config.visConfig = _objectSpread(_objectSpread({}, layer.config.visConfig), {}, {
|
|
224
|
+
colorBySpeed: true
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return layer;
|
|
228
|
+
}
|
|
229
|
+
function buildLayerConfig(layer, datasetId, layerName, sourceName, layerType) {
|
|
230
|
+
var _layer$config, _layer$config2;
|
|
231
|
+
var layerId = layer.id || uniqueLayerId();
|
|
232
|
+
var columns = ((_layer$config = layer.config) === null || _layer$config === void 0 ? void 0 : _layer$config.columns) || {};
|
|
233
|
+
return {
|
|
234
|
+
id: layerId,
|
|
235
|
+
type: layer.type,
|
|
236
|
+
config: _objectSpread(_objectSpread({}, layer.config), {}, {
|
|
237
|
+
dataId: datasetId,
|
|
238
|
+
isVisible: true,
|
|
239
|
+
label: layerName || "".concat(sourceName, "-").concat(layerType),
|
|
240
|
+
columns: Object.keys(columns).reduce(function (acc, key) {
|
|
241
|
+
var column = columns[key];
|
|
242
|
+
if (column) {
|
|
243
|
+
acc[key] = column.value;
|
|
244
|
+
}
|
|
245
|
+
return acc;
|
|
246
|
+
}, {}),
|
|
247
|
+
visConfig: _objectSpread({}, (_layer$config2 = layer.config) === null || _layer$config2 === void 0 ? void 0 : _layer$config2.visConfig)
|
|
248
|
+
})
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function applyColorConfig(newLayer, dataset, args) {
|
|
252
|
+
if (args.simpleColor) {
|
|
253
|
+
var color = args.simpleColor.replace(/[^\d,]/g, '').split(',').map(Number);
|
|
254
|
+
if (color.length === 3) {
|
|
255
|
+
newLayer.config.color = color;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
var colorBy = args.colorBy,
|
|
259
|
+
colorType = args.colorType,
|
|
260
|
+
providedColorMap = args.colorMap;
|
|
261
|
+
if (colorBy) {
|
|
262
|
+
var colorField = dataset.fields.find(function (f) {
|
|
263
|
+
return f.name === colorBy;
|
|
264
|
+
});
|
|
265
|
+
if (!colorField) {
|
|
266
|
+
throw new Error("Field ".concat(colorBy, " not found."));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// For categorical (customOrdinal) color maps, every value becomes the scale
|
|
270
|
+
// domain, so it must be a real value present in the data. The agent must not
|
|
271
|
+
// invent category labels — get them via geoda.analysis (analysis: 'classify',
|
|
272
|
+
// method: 'unique values'). Rejecting here turns a silent wrong render into a
|
|
273
|
+
// recoverable error. Only run this when colorType is explicitly 'unique':
|
|
274
|
+
// an omitted colorType defaults to a continuous (breaks) scale, whose
|
|
275
|
+
// colorMap values are break boundaries, not data values.
|
|
276
|
+
if (colorType === 'unique' && providedColorMap) {
|
|
277
|
+
// Validate without materializing the whole column: scan rows, deleting
|
|
278
|
+
// matches from a small `wanted` set (early-exit when all are found),
|
|
279
|
+
// while collecting a small sample of actual values for the error message.
|
|
280
|
+
// Scan ALL rows — a bounded sample (prefix OR fixed-stride) can
|
|
281
|
+
// systematically miss a category that exists later in the data and
|
|
282
|
+
// falsely report it as "not found". The early-exit keeps the common case
|
|
283
|
+
// (all categories found early) fast; only a genuinely missing category
|
|
284
|
+
// costs a full scan, which is the price of an accurate error.
|
|
285
|
+
var wanted = new Set(providedColorMap.map(function (c) {
|
|
286
|
+
return c.value;
|
|
287
|
+
}));
|
|
288
|
+
var sample = [];
|
|
289
|
+
var seen = new Set();
|
|
290
|
+
for (var i = 0; i < dataset.length && wanted.size > 0; i++) {
|
|
291
|
+
var v = dataset.getValue(colorBy, i);
|
|
292
|
+
if (wanted.has(v)) {
|
|
293
|
+
wanted["delete"](v);
|
|
294
|
+
} else if (!seen.has(v) && sample.length < 20) {
|
|
295
|
+
seen.add(v);
|
|
296
|
+
sample.push(v);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (wanted.size > 0) {
|
|
300
|
+
var missing = (0, _toConsumableArray2["default"])(wanted);
|
|
301
|
+
throw new Error("colorMap value(s) ".concat(missing.map(function (v) {
|
|
302
|
+
return JSON.stringify(v);
|
|
303
|
+
}).join(', '), " not found in field \"").concat(colorBy, "\". ") + "Actual unique values: ".concat(sample.map(function (v) {
|
|
304
|
+
return JSON.stringify(v);
|
|
305
|
+
}).join(', ')).concat(sample.length >= 20 ? ', …' : '', ". ") + "Call geoda.analysis (analysis: 'classify', method: 'unique values') to get the real values.");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// colorType is optional; when omitted, default to a continuous (breaks)
|
|
310
|
+
// scale so numeric fields colored via colorBy aren't mis-colored as
|
|
311
|
+
// categorical. Only an explicit 'unique' selects the categorical scale.
|
|
312
|
+
var colorScale = colorType === 'unique' ? 'customOrdinal' : 'custom';
|
|
313
|
+
|
|
314
|
+
// Only force a custom palette when the caller provided an explicit
|
|
315
|
+
// colorMap. A synthetic single-entry colorMap ({value: null, color:
|
|
316
|
+
// '#333333'}) would route through kepler's custom colorMap scale path and
|
|
317
|
+
// render everything as the no-value/unknown color; without an explicit
|
|
318
|
+
// colorMap, bind the color field and let kepler.gl's default color range
|
|
319
|
+
// apply.
|
|
320
|
+
var colorRange = providedColorMap ? {
|
|
321
|
+
name: 'color.customPalette',
|
|
322
|
+
type: 'custom',
|
|
323
|
+
category: 'Custom',
|
|
324
|
+
colors: providedColorMap.map(function (c) {
|
|
325
|
+
return c.color;
|
|
326
|
+
}),
|
|
327
|
+
colorMap: providedColorMap.map(function (c) {
|
|
328
|
+
return [c.value, c.color];
|
|
329
|
+
})
|
|
330
|
+
} : null;
|
|
331
|
+
if (newLayer.type === 'heatmap') {
|
|
332
|
+
if (colorRange && providedColorMap && providedColorMap.length > 1) {
|
|
333
|
+
newLayer.config.visConfig['colorRange'] = _objectSpread({}, colorRange);
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
newLayer.config['colorScale'] = colorScale;
|
|
337
|
+
newLayer.config['colorField'] = colorField;
|
|
338
|
+
newLayer.config['strokeColorScale'] = colorScale;
|
|
339
|
+
newLayer.config['strokeColorField'] = colorField;
|
|
340
|
+
newLayer.config.visConfig['filled'] = true;
|
|
341
|
+
if (colorRange) {
|
|
342
|
+
newLayer.config.visConfig['colorRange'] = colorRange;
|
|
343
|
+
newLayer.config.visConfig['strokeColorRange'] = colorRange;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
var addLayerCommandId = exports.addLayerCommandId = 'map.add-layer';
|
|
349
|
+
function getAddLayerCommand(ctx) {
|
|
350
|
+
return {
|
|
351
|
+
id: addLayerCommandId,
|
|
352
|
+
name: 'Add map layer',
|
|
353
|
+
group: 'Map',
|
|
354
|
+
description: "Add a kepler.gl map layer from a dataset.\nIMPORTANT: generated layer names must be unique.\n\nLAYER TYPES:\n- point: Point markers (requires lat/lng columns)\n- flow: Origin->destination flow map (requires two point lat/lng pairs, auto-detected)\n- flowField: Animated streamlines over a vector field (u/v, speed/direction, or altitude)\n- h3: H3 hexagon cells (requires hexId column)\n- geojson: Polygon/geometry features (uses geometry column, usually auto-detected)\n- hexagon: Hexagonal binning of points\n- heatmap: Heat map visualization\n- cluster: Clustered point visualization\n- arc/line: Arc or line connections between points\n- grid: Grid binning\n- trip: Animated trip (flights, deliveries, vessels)\n- s2: S2 geometry cells\n\nFLOW MAPS (layerType 'flow'):\nFor origin->destination flows use layerType 'flow' \u2014 a dedicated flow layer that draws\nlocations and weighted flows between them. It needs TWO point lat/lng pairs in the\ndataset (source pair + destination pair), which are auto-detected. Prefer 'flow' over\n'arc' for O-D flows; 'arc' draws straight great-circle lines without location clustering\nor flow aggregation. To weight the flows by a value column (flow magnitude), pass\ncountColumn with the column name \u2014 omit it to render all flows at weight 1.\n\nFLOW FIELD (layerType 'flowField'):\nAnimated streamlines over a vector field \u2014 wind, currents, or downhill flow. It is NOT\nthe origin->destination 'flow' layer: 'flow' joins two point pairs, 'flowField' draws\nmany short lines through a field of vectors, one row per sample point.\nThe direction comes from one of three column sets, auto-detected in this order:\n- u/v components (default mode 'UV'), optionally with an altitude column\n- speed + direction (mode 'SPEED_DIR')\n- altitude only (mode 'ELEVATION'): the downhill gradient gives the direction\nPosition is lat/lng (auto-detected, or latitudeColumn/longitudeColumn) or a GeoJSON\ngeometry column. When the dataset names the columns differently, pass flowField.mode\nplus flowField.uColumn/vColumn/speedColumn/directionColumn/altitudeColumn.\nSet flowField.colorBySpeed true to color lines by local speed; otherwise simpleColor\napplies. colorBy/colorMap do not apply to this layer. Do NOT add a time filter \u2014 the\nflow field animates itself.\n\nBASIC MAP:\n- Use datasetName, latitudeColumn/longitudeColumn (for point maps), and layerType\n- Omit color-related parameters for simple visualization, use simpleColor instead.\n\nCOLOR MAPPING:\n- If user requests color visualization, use available columns in the dataset\n- Use geoda.analysis (analysis: 'classify') to classify data into bins or unique values when needed\n- For continuous data (colorType 'breaks'):\n [{value: 0, color: '#fee5d9'}, {value: 50, color: '#fcae91'}, {value: 100, color: '#fb6a4a'}, {value: null, color: '#de2d26'}]\n The last entry with value: null represents the color for the highest values\n- For categorical data (colorType 'unique'):\n [{value: 'category1', color: '#1f77b4'}, {value: 'category2', color: '#ff7f0e'}]\n HARD RULE: the colorMap values MUST be the actual unique values present in the data.\n Call geoda.analysis (analysis: 'classify', method: 'unique values') first and use the\n returned uniqueValues verbatim. NEVER invent category labels from the field name \u2014\n the command rejects values that do not exist in the data.\n- If the user doesn't specify colors, omit colorBy/colorMap \u2014 kepler.gl applies its default color range automatically\n\nFor geojson datasets:\n- Use geometryColumn: '_geojson' and layerType: 'geojson' even for point collections\n",
|
|
355
|
+
metadata: {
|
|
356
|
+
readOnly: false,
|
|
357
|
+
riskLevel: 'medium',
|
|
358
|
+
idempotent: false
|
|
359
|
+
},
|
|
360
|
+
inputSchema: _zod.z.object({
|
|
361
|
+
datasetName: _zod.z.string().describe('The name (label) or id of the dataset. Prefer the label when known.'),
|
|
362
|
+
latitudeColumn: _zod.z.string().optional(),
|
|
363
|
+
longitudeColumn: _zod.z.string().optional(),
|
|
364
|
+
layerName: _zod.z.string().optional().describe('Generate a unique name for the layer based on the context.'),
|
|
365
|
+
layerType: _zod.z["enum"](['point', 'flow', 'flowField', 'arc', 'line', 'grid', 'hexagon', 'geojson', 'cluster', 'heatmap', 'h3', 'trip', 's2']),
|
|
366
|
+
flowField: _zod.z.object({
|
|
367
|
+
mode: _zod.z["enum"](FLOW_FIELD_MODES).optional(),
|
|
368
|
+
uColumn: _zod.z.string().optional(),
|
|
369
|
+
vColumn: _zod.z.string().optional(),
|
|
370
|
+
speedColumn: _zod.z.string().optional(),
|
|
371
|
+
directionColumn: _zod.z.string().optional(),
|
|
372
|
+
altitudeColumn: _zod.z.string().optional(),
|
|
373
|
+
colorBySpeed: _zod.z["boolean"]().optional()
|
|
374
|
+
}).optional().describe('For layerType "flowField" only: how the vector field is encoded. The mode is ' + 'inferred from the columns (u/v, speed/direction, otherwise altitude); the ' + '*Column fields name the columns when they differ from those defaults.'),
|
|
375
|
+
simpleColor: _zod.z.string().optional().describe('The color of the layer e.g. [255, 0, 0]. Only used for simple map visualization (no colorBy, colorType, colorMap).'),
|
|
376
|
+
colorBy: _zod.z.string().optional(),
|
|
377
|
+
colorType: _zod.z["enum"](['breaks', 'unique']).optional(),
|
|
378
|
+
countColumn: _zod.z.string().optional().describe('For layerType "flow" (and only flow): a numeric column whose value weights each flow (flow magnitude). Omit to render all flows at weight 1.'),
|
|
379
|
+
colorMap: _zod.z.array(_zod.z.object({
|
|
380
|
+
value: _zod.z.union([_zod.z.string(), _zod.z.number(), _zod.z["null"]()]),
|
|
381
|
+
color: _zod.z.string()
|
|
382
|
+
})).optional()
|
|
383
|
+
}),
|
|
384
|
+
execute: function () {
|
|
385
|
+
var _execute = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(_execCtx, input) {
|
|
386
|
+
var args, datasetName, layerName, latitudeColumn, longitudeColumn, layerType, simpleColor, colorBy, colorType, colorMap, countColumn, flowField, _dataset$fields4, VALID_LAYER_TYPES, visState, datasets, datasetId, dataset, layer, latIdx, lngIdx, _dataset$fields$map$j2, _dataset$fields3, missing, available, newLayer, addedLayer, bounds, temporalFields, hasTemporalFields;
|
|
387
|
+
return _regenerator["default"].wrap(function _callee$(_context) {
|
|
388
|
+
while (1) switch (_context.prev = _context.next) {
|
|
389
|
+
case 0:
|
|
390
|
+
args = input !== null && input !== void 0 ? input : {};
|
|
391
|
+
datasetName = args.datasetName, layerName = args.layerName, latitudeColumn = args.latitudeColumn, longitudeColumn = args.longitudeColumn, layerType = args.layerType, simpleColor = args.simpleColor, colorBy = args.colorBy, colorType = args.colorType, colorMap = args.colorMap, countColumn = args.countColumn, flowField = args.flowField;
|
|
392
|
+
_context.prev = 2;
|
|
393
|
+
// Runtime guard: the bridge/webMCP call execute without zod parsing, so
|
|
394
|
+
// a missing/invalid layerType must not fall through to
|
|
395
|
+
// guessDefaultLayer's first-default-layer fallback (layerType is
|
|
396
|
+
// required by the command contract).
|
|
397
|
+
VALID_LAYER_TYPES = ['point', 'flow', 'flowField', 'arc', 'line', 'grid', 'hexagon', 'geojson', 'cluster', 'heatmap', 'h3', 'trip', 's2'];
|
|
398
|
+
if (!(!layerType || !VALID_LAYER_TYPES.includes(layerType))) {
|
|
399
|
+
_context.next = 6;
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
throw new Error("Invalid layerType \"".concat(String(layerType), "\". Must be one of: ").concat(VALID_LAYER_TYPES.join(', '), "."));
|
|
403
|
+
case 6:
|
|
404
|
+
visState = ctx.getVisState();
|
|
405
|
+
datasets = visState.datasets;
|
|
406
|
+
datasetId = Object.keys(datasets).find(function (dataId) {
|
|
407
|
+
return datasets[dataId].label === datasetName || dataId === datasetName;
|
|
408
|
+
});
|
|
409
|
+
if (datasetId) {
|
|
410
|
+
_context.next = 11;
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
throw new Error("Dataset ".concat(datasetName, " not found."));
|
|
414
|
+
case 11:
|
|
415
|
+
dataset = datasets[datasetId]; // The flow field layer resolves its own columns (position + vector, in
|
|
416
|
+
// one of three modes), so it does not go through guessDefaultLayer —
|
|
417
|
+
// that path only auto-detects the u/v case and would ignore explicit
|
|
418
|
+
// column names.
|
|
419
|
+
layer = layerType === 'flowField' ? buildFlowFieldLayer(dataset, {
|
|
420
|
+
latitudeColumn: latitudeColumn,
|
|
421
|
+
longitudeColumn: longitudeColumn
|
|
422
|
+
}, flowField) : guessDefaultLayer(dataset, layerType, {
|
|
423
|
+
countColumn: countColumn
|
|
424
|
+
});
|
|
425
|
+
if (layer) {
|
|
426
|
+
_context.next = 22;
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
if (!(layerType === 'point' && latitudeColumn && longitudeColumn)) {
|
|
430
|
+
_context.next = 22;
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
// Validate both columns exist before building the config —
|
|
434
|
+
// getColumnFieldIdx returns -1 for a missing column, and an
|
|
435
|
+
// invalid fieldIdx would dispatch a broken layer config (empty
|
|
436
|
+
// render / confusing runtime errors).
|
|
437
|
+
latIdx = dataset.getColumnFieldIdx(latitudeColumn);
|
|
438
|
+
lngIdx = dataset.getColumnFieldIdx(longitudeColumn);
|
|
439
|
+
if (!(latIdx < 0 || lngIdx < 0)) {
|
|
440
|
+
_context.next = 21;
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
missing = latIdx < 0 ? latitudeColumn : longitudeColumn;
|
|
444
|
+
available = (_dataset$fields$map$j2 = (_dataset$fields3 = dataset.fields) === null || _dataset$fields3 === void 0 ? void 0 : _dataset$fields3.map(function (f) {
|
|
445
|
+
return f.name;
|
|
446
|
+
}).join(', ')) !== null && _dataset$fields$map$j2 !== void 0 ? _dataset$fields$map$j2 : '';
|
|
447
|
+
throw new Error("Column \"".concat(missing, "\" not found in dataset \"").concat(datasetName, "\". Available columns: ").concat(available));
|
|
448
|
+
case 21:
|
|
449
|
+
layer = {
|
|
450
|
+
id: uniqueLayerId(),
|
|
451
|
+
type: 'point',
|
|
452
|
+
config: {
|
|
453
|
+
dataId: datasetId,
|
|
454
|
+
label: layerName || "".concat(datasetName, "-").concat(layerType),
|
|
455
|
+
columns: {
|
|
456
|
+
lat: {
|
|
457
|
+
value: latitudeColumn,
|
|
458
|
+
fieldIdx: latIdx
|
|
459
|
+
},
|
|
460
|
+
lng: {
|
|
461
|
+
value: longitudeColumn,
|
|
462
|
+
fieldIdx: lngIdx
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
visConfig: {}
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
case 22:
|
|
469
|
+
if (layer) {
|
|
470
|
+
_context.next = 24;
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
throw new Error("Could not create ".concat(layerType, " layer. Check that the dataset has the required columns."));
|
|
474
|
+
case 24:
|
|
475
|
+
newLayer = buildLayerConfig(layer, datasetId, layerName, datasetName, layerType);
|
|
476
|
+
applyColorConfig(newLayer, dataset, {
|
|
477
|
+
simpleColor: simpleColor,
|
|
478
|
+
colorBy: colorBy,
|
|
479
|
+
colorType: colorType,
|
|
480
|
+
colorMap: colorMap
|
|
481
|
+
});
|
|
482
|
+
ctx.dispatch((0, _actions.addLayer)(newLayer, datasetId));
|
|
483
|
+
|
|
484
|
+
// Center the map on the new layer's data bounds. `addDataToMap` with
|
|
485
|
+
// `autoCreateLayers: false` (used by `map.load-data`) never fits bounds
|
|
486
|
+
// because no layer exists at load time, and `addLayerUpdater` does not
|
|
487
|
+
// center either — so fit here explicitly.
|
|
488
|
+
addedLayer = ctx.getVisState().layers.find(function (l) {
|
|
489
|
+
return l.id === newLayer.id;
|
|
490
|
+
});
|
|
491
|
+
bounds = addedLayer ? (0, _reducers.findMapBounds)([addedLayer]) : null;
|
|
492
|
+
if (bounds) {
|
|
493
|
+
ctx.dispatch((0, _actions.fitBounds)(bounds));
|
|
494
|
+
}
|
|
495
|
+
temporalFields = (_dataset$fields4 = dataset.fields) === null || _dataset$fields4 === void 0 ? void 0 : _dataset$fields4.filter(function (f) {
|
|
496
|
+
return f.type === 'timestamp' || f.type === 'date';
|
|
497
|
+
}).map(function (f) {
|
|
498
|
+
return f.name;
|
|
499
|
+
});
|
|
500
|
+
hasTemporalFields = temporalFields && temporalFields.length > 0;
|
|
501
|
+
return _context.abrupt("return", {
|
|
502
|
+
success: true,
|
|
503
|
+
commandId: addLayerCommandId,
|
|
504
|
+
data: {
|
|
505
|
+
details: "Map layer ".concat(newLayer.id, " has been added to the map."),
|
|
506
|
+
dateTimeColumns: hasTemporalFields ? temporalFields : undefined,
|
|
507
|
+
dateTimeHint: hasTemporalFields ? "DateTime columns detected: ".concat(temporalFields.join(', '), ". You can call addTimeFilter with one of these columns to enable time-range animation on the map.") : undefined
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
case 35:
|
|
511
|
+
_context.prev = 35;
|
|
512
|
+
_context.t0 = _context["catch"](2);
|
|
513
|
+
return _context.abrupt("return", {
|
|
514
|
+
success: false,
|
|
515
|
+
commandId: addLayerCommandId,
|
|
516
|
+
error: _context.t0 instanceof Error ? _context.t0.message : 'Unknown error',
|
|
517
|
+
data: {
|
|
518
|
+
instruction: 'Try to fix the error. If the error persists, ask the user to try with different parameters.'
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
case 38:
|
|
522
|
+
case "end":
|
|
523
|
+
return _context.stop();
|
|
524
|
+
}
|
|
525
|
+
}, _callee, null, [[2, 35]]);
|
|
526
|
+
}));
|
|
527
|
+
function execute(_x, _x2) {
|
|
528
|
+
return _execute.apply(this, arguments);
|
|
529
|
+
}
|
|
530
|
+
return execute;
|
|
531
|
+
}()
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfem9kIiwicmVxdWlyZSIsIl9jb25zdGFudHMiLCJfbGF5ZXJzIiwiX3JlZHVjZXJzIiwiX2FjdGlvbnMiLCJvd25LZXlzIiwiZSIsInIiLCJ0IiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsInVuaXF1ZUxheWVySWQiLCJwcmVmaXgiLCJ1bmRlZmluZWQiLCJjb25jYXQiLCJEYXRlIiwibm93IiwiTWF0aCIsInJhbmRvbSIsInRvU3RyaW5nIiwic2xpY2UiLCJndWVzc0RlZmF1bHRMYXllciIsImRhdGFzZXQiLCJsYXllclR5cGUiLCJvcHRpb25zIiwiZmllbGRQYWlycyIsInByb3BzIiwibWFwIiwiZmllbGRQYWlyIiwiaXNWaXNpYmxlIiwibGFiZWwiLCJjb2x1bW5zIiwicGFpciIsImxheWVyIiwiTGF5ZXJDbGFzc2VzIiwiaGVhdG1hcCIsImhleGFnb24iLCJjbHVzdGVyIiwibGF5ZXJzIiwiZmluZERlZmF1bHRMYXllciIsInRyaXAiLCJmaW5kIiwibCIsInR5cGUiLCJFcnJvciIsInBhaXJzIiwibGF0MCIsImxhdCIsImxuZzAiLCJsbmciLCJsYXQxIiwibG5nMSIsImNvdW50Q29sdW1uIiwiZ2V0Q29sdW1uRmllbGRJZHgiLCJjb3VudCIsInZhbHVlIiwiZmllbGRJZHgiLCJmbG93IiwiZGVmYXVsdE5hbWUiLCJkZWZhdWx0TGF5ZXJzIiwiRkxPV19GSUVMRF9BTFRJVFVERV9DT0xVTU5TIiwiRkxPV19GSUVMRF9NT0RFUyIsImJ1aWxkRmxvd0ZpZWxkTGF5ZXIiLCJwb3NpdGlvbiIsImhhc0NvbHVtbiIsIm5hbWUiLCJjb2x1bW5SZWYiLCJfZGF0YXNldCRmaWVsZHMkbWFwJGoiLCJfZGF0YXNldCRmaWVsZHMiLCJhdmFpbGFibGUiLCJmaWVsZHMiLCJmIiwiam9pbiIsInBvc2l0aW9uQ29sdW1ucyIsImxhdGl0dWRlQ29sdW1uIiwibG9uZ2l0dWRlQ29sdW1uIiwiX2RhdGFzZXQkZmllbGRQYWlycyIsIl9kYXRhc2V0JGZpZWxkczIiLCJnZW9GaWVsZCIsIkdFT0pTT05fRklFTERTIiwiZ2VvanNvbiIsImluY2x1ZGVzIiwiYWx0aXR1ZGVOYW1lIiwiYWx0aXR1ZGVDb2x1bW4iLCJtb2RlIiwidUNvbHVtbiIsInZDb2x1bW4iLCJzcGVlZENvbHVtbiIsImRpcmVjdGlvbkNvbHVtbiIsImZsb3dDb2x1bW5zIiwidSIsInYiLCJzcGVlZCIsImRpcmVjdGlvbiIsImFsdGl0dWRlIiwiZmxvd0ZpZWxkIiwiY29sb3IiLCJjb2x1bW5Nb2RlIiwiY29sb3JCeVNwZWVkIiwiY29uZmlnIiwidmlzQ29uZmlnIiwiYnVpbGRMYXllckNvbmZpZyIsImRhdGFzZXRJZCIsImxheWVyTmFtZSIsInNvdXJjZU5hbWUiLCJfbGF5ZXIkY29uZmlnIiwiX2xheWVyJGNvbmZpZzIiLCJsYXllcklkIiwiaWQiLCJkYXRhSWQiLCJyZWR1Y2UiLCJhY2MiLCJrZXkiLCJjb2x1bW4iLCJhcHBseUNvbG9yQ29uZmlnIiwibmV3TGF5ZXIiLCJhcmdzIiwic2ltcGxlQ29sb3IiLCJyZXBsYWNlIiwic3BsaXQiLCJOdW1iZXIiLCJjb2xvckJ5IiwiY29sb3JUeXBlIiwicHJvdmlkZWRDb2xvck1hcCIsImNvbG9yTWFwIiwiY29sb3JGaWVsZCIsIndhbnRlZCIsIlNldCIsImMiLCJzYW1wbGUiLCJzZWVuIiwiaSIsInNpemUiLCJnZXRWYWx1ZSIsImhhcyIsImFkZCIsIm1pc3NpbmciLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwiSlNPTiIsInN0cmluZ2lmeSIsImNvbG9yU2NhbGUiLCJjb2xvclJhbmdlIiwiY2F0ZWdvcnkiLCJjb2xvcnMiLCJhZGRMYXllckNvbW1hbmRJZCIsImV4cG9ydHMiLCJnZXRBZGRMYXllckNvbW1hbmQiLCJjdHgiLCJncm91cCIsImRlc2NyaXB0aW9uIiwibWV0YWRhdGEiLCJyZWFkT25seSIsInJpc2tMZXZlbCIsImlkZW1wb3RlbnQiLCJpbnB1dFNjaGVtYSIsInoiLCJvYmplY3QiLCJkYXRhc2V0TmFtZSIsInN0cmluZyIsImRlc2NyaWJlIiwib3B0aW9uYWwiLCJhcnJheSIsInVuaW9uIiwibnVtYmVyIiwiZXhlY3V0ZSIsIl9leGVjdXRlIiwiX2FzeW5jVG9HZW5lcmF0b3IyIiwiX3JlZ2VuZXJhdG9yIiwibWFyayIsIl9jYWxsZWUiLCJfZXhlY0N0eCIsImlucHV0IiwiX2RhdGFzZXQkZmllbGRzNCIsIlZBTElEX0xBWUVSX1RZUEVTIiwidmlzU3RhdGUiLCJkYXRhc2V0cyIsImxhdElkeCIsImxuZ0lkeCIsIl9kYXRhc2V0JGZpZWxkcyRtYXAkajIiLCJfZGF0YXNldCRmaWVsZHMzIiwiYWRkZWRMYXllciIsImJvdW5kcyIsInRlbXBvcmFsRmllbGRzIiwiaGFzVGVtcG9yYWxGaWVsZHMiLCJ3cmFwIiwiX2NhbGxlZSQiLCJfY29udGV4dCIsInByZXYiLCJuZXh0IiwiU3RyaW5nIiwiZ2V0VmlzU3RhdGUiLCJkaXNwYXRjaCIsImFkZExheWVyQWN0aW9uIiwiZmluZE1hcEJvdW5kcyIsImZpdEJvdW5kcyIsImFicnVwdCIsInN1Y2Nlc3MiLCJjb21tYW5kSWQiLCJkYXRhIiwiZGV0YWlscyIsImRhdGVUaW1lQ29sdW1ucyIsImRhdGVUaW1lSGludCIsInQwIiwiZXJyb3IiLCJtZXNzYWdlIiwiaW5zdHJ1Y3Rpb24iLCJzdG9wIiwiX3giLCJfeDIiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tbWFuZHMvbGF5ZXItY3JlYXRpb24tY29tbWFuZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQgdHlwZSB7Um9vbUNvbW1hbmR9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHt6fSBmcm9tICd6b2QnO1xuaW1wb3J0IHtHRU9KU09OX0ZJRUxEU30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtMYXllckNsYXNzZXN9IGZyb20gJ0BrZXBsZXIuZ2wvbGF5ZXJzJztcbmltcG9ydCB0eXBlIEtlcGxlclRhYmxlIGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuaW1wb3J0IHR5cGUge0RhdGFzZXRzfSBmcm9tICdAa2VwbGVyLmdsL3RhYmxlJztcbmltcG9ydCB7ZmluZERlZmF1bHRMYXllciwgZmluZE1hcEJvdW5kc30gZnJvbSAnQGtlcGxlci5nbC9yZWR1Y2Vycyc7XG5pbXBvcnQge2FkZExheWVyIGFzIGFkZExheWVyQWN0aW9uLCBmaXRCb3VuZHN9IGZyb20gJ0BrZXBsZXIuZ2wvYWN0aW9ucyc7XG5pbXBvcnQgdHlwZSB7S2VwbGVyQ29udGV4dH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogVW5pcXVlIGxheWVyIGlkLiBEYXRlLm5vdygpLWJhc2VkIGlkcyBjYW4gY29sbGlkZSB3aGVuIG11bHRpcGxlIGxheWVycyBhcmVcbiAqIGNyZWF0ZWQgd2l0aGluIHRoZSBzYW1lIG1pbGxpc2Vjb25kIChyYXBpZCBzdWNjZXNzaXZlIHRvb2wgY2FsbHMpLCBwcm9kdWNpbmdcbiAqIGR1cGxpY2F0ZSBsYXllciBpZHMgYW5kIHVucHJlZGljdGFibGUgcmVkdWNlciBiZWhhdmlvci4gQXBwZW5kIGEgcmFuZG9tXG4gKiBzdWZmaXgg4oCUIHRoZSBzYW1lIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpIHRyaWNrIGtlcGxlcidzIGdlbmVyYXRlSGFzaElkXG4gKiB1c2VzIOKAlCBzbyBpZHMgc3RheSB1bmlxdWUuXG4gKi9cbmZ1bmN0aW9uIHVuaXF1ZUxheWVySWQocHJlZml4ID0gJ2xheWVyJyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtwcmVmaXh9XyR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KX1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ3Vlc3NEZWZhdWx0TGF5ZXIoXG4gIGRhdGFzZXQ6IEtlcGxlclRhYmxlLFxuICBsYXllclR5cGU6IHN0cmluZyxcbiAgb3B0aW9ucz86IHtjb3VudENvbHVtbj86IHN0cmluZ31cbikge1xuICBpZiAobGF5ZXJUeXBlID09PSAnaGVhdG1hcCcpIHtcbiAgICBpZiAoZGF0YXNldC5maWVsZFBhaXJzICYmIGRhdGFzZXQuZmllbGRQYWlycy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBwcm9wcyA9IGRhdGFzZXQuZmllbGRQYWlycy5tYXAoZmllbGRQYWlyID0+ICh7XG4gICAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgbGFiZWw6ICdIZWF0bWFwJyxcbiAgICAgICAgY29sdW1uczogZmllbGRQYWlyLnBhaXJcbiAgICAgIH0pKTtcbiAgICAgIGNvbnN0IGxheWVyID0gbmV3IExheWVyQ2xhc3Nlcy5oZWF0bWFwKHByb3BzWzBdKTtcbiAgICAgIHJldHVybiBsYXllcjtcbiAgICB9XG4gIH0gZWxzZSBpZiAobGF5ZXJUeXBlID09PSAnaGV4YWdvbicpIHtcbiAgICBpZiAoZGF0YXNldC5maWVsZFBhaXJzICYmIGRhdGFzZXQuZmllbGRQYWlycy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBwcm9wcyA9IGRhdGFzZXQuZmllbGRQYWlycy5tYXAoZmllbGRQYWlyID0+ICh7XG4gICAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgbGFiZWw6ICdIZXhiaW4nLFxuICAgICAgICBjb2x1bW5zOiBmaWVsZFBhaXIucGFpclxuICAgICAgfSkpO1xuICAgICAgY29uc3QgbGF5ZXIgPSBuZXcgTGF5ZXJDbGFzc2VzLmhleGFnb24ocHJvcHNbMF0pO1xuICAgICAgcmV0dXJuIGxheWVyO1xuICAgIH1cbiAgfSBlbHNlIGlmIChsYXllclR5cGUgPT09ICdjbHVzdGVyJykge1xuICAgIGlmIChkYXRhc2V0LmZpZWxkUGFpcnMgJiYgZGF0YXNldC5maWVsZFBhaXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHByb3BzID0gZGF0YXNldC5maWVsZFBhaXJzLm1hcChmaWVsZFBhaXIgPT4gKHtcbiAgICAgICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgICAgICBsYWJlbDogJ0NsdXN0ZXInLFxuICAgICAgICBjb2x1bW5zOiBmaWVsZFBhaXIucGFpclxuICAgICAgfSkpO1xuICAgICAgY29uc3QgbGF5ZXIgPSBuZXcgTGF5ZXJDbGFzc2VzLmNsdXN0ZXIocHJvcHNbMF0pO1xuICAgICAgcmV0dXJuIGxheWVyO1xuICAgIH1cbiAgfSBlbHNlIGlmIChsYXllclR5cGUgPT09ICd0cmlwJykge1xuICAgIGNvbnN0IGxheWVycyA9IGZpbmREZWZhdWx0TGF5ZXIoZGF0YXNldCwgW0xheWVyQ2xhc3Nlcy50cmlwXSBhcyBhbnkpO1xuICAgIGNvbnN0IGxheWVyID0gbGF5ZXJzLmZpbmQobCA9PiBsLnR5cGUgPT09IGxheWVyVHlwZSk7XG4gICAgaWYgKGxheWVyKSByZXR1cm4gbGF5ZXI7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBjcmVhdGUgYSB0cmlwIGxheWVyLiBUcmlwIGxheWVyIHJlcXVpcmVzIGlkLCBsYXQsIGxuZywgYW5kIHRpbWVzdGFtcCBjb2x1bW5zLmBcbiAgICApO1xuICB9IGVsc2UgaWYgKGxheWVyVHlwZSA9PT0gJ2Zsb3cnKSB7XG4gICAgLy8gRmxvdyBsYXllcnMgYXJlIG5ldmVyIGF1dG8tZGV0ZWN0ZWQgKGZpbmREZWZhdWx0TGF5ZXJQcm9wcyByZXR1cm5zXG4gICAgLy8ge3Byb3BzOiBbXX0pLCBzbyBidWlsZCBvbmUgZXhwbGljaXRseSBmcm9tIHRoZSBmaXJzdCB0d28gcG9pbnQgbGF0L2xuZ1xuICAgIC8vIGZpZWxkIHBhaXJzIOKAlCB0aGUgc2FtZSBzb3VyY2UvdGFyZ2V0IHBhaXIgbG9naWMgdGhlIGRlZmF1bHQgYXJjIGxheWVyXG4gICAgLy8gdXNlczogcGFpclswXSA9IG9yaWdpbiAobGF0MC9sbmcwKSwgcGFpclsxXSA9IGRlc3RpbmF0aW9uIChsYXQxL2xuZzEpLlxuICAgIC8vIFRoZSBjb3VudCBjb2x1bW4gKGZsb3cgbWFnbml0dWRlKSBpcyBvcHRpb25hbDsgd2l0aG91dCBpdCBldmVyeSBmbG93XG4gICAgLy8gcmVuZGVycyBhdCB3ZWlnaHQgMS5cbiAgICBjb25zdCBwYWlycyA9IGRhdGFzZXQuZmllbGRQYWlycyB8fCBbXTtcbiAgICBpZiAocGFpcnMubGVuZ3RoIDwgMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGNyZWF0ZSBhIGZsb3cgbGF5ZXIuIEZsb3cgbGF5ZXIgcmVxdWlyZXMgdHdvIHBvaW50IGxhdC9sbmcgcGFpcnMgYCArXG4gICAgICAgICAgYChvcmlnaW4gKyBkZXN0aW5hdGlvbiksIGUuZy4gb3JpZ2luX2xhdC9vcmlnaW5fbG5nIGFuZCBkZXN0X2xhdC9kZXN0X2xuZy5gXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBjb2x1bW5zOiBhbnkgPSB7XG4gICAgICBsYXQwOiBwYWlyc1swXS5wYWlyLmxhdCxcbiAgICAgIGxuZzA6IHBhaXJzWzBdLnBhaXIubG5nLFxuICAgICAgbGF0MTogcGFpcnNbMV0ucGFpci5sYXQsXG4gICAgICBsbmcxOiBwYWlyc1sxXS5wYWlyLmxuZ1xuICAgIH07XG4gICAgaWYgKG9wdGlvbnM/LmNvdW50Q29sdW1uICYmIGRhdGFzZXQuZ2V0Q29sdW1uRmllbGRJZHgob3B0aW9ucy5jb3VudENvbHVtbikgPj0gMCkge1xuICAgICAgY29sdW1ucy5jb3VudCA9IHtcbiAgICAgICAgdmFsdWU6IG9wdGlvbnMuY291bnRDb2x1bW4sXG4gICAgICAgIGZpZWxkSWR4OiBkYXRhc2V0LmdldENvbHVtbkZpZWxkSWR4KG9wdGlvbnMuY291bnRDb2x1bW4pXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBMYXllckNsYXNzZXMnIGNvbXB1dGVkIGtleXMgKGtleU1pcnJvcikgYXJlbid0IHN0YXRpY2FsbHkgbmFtZWQsIHNvXG4gICAgLy8gYWNjZXNzIGZsb3cgbGlrZSB0aGUgdHJpcCBicmFuY2ggYWNjZXNzZXMgdHJpcDogdGhyb3VnaCBhbiBgYXMgYW55YCBjYXN0LlxuICAgIGNvbnN0IGxheWVyID0gbmV3IChMYXllckNsYXNzZXMgYXMgYW55KS5mbG93KHtcbiAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgIGxhYmVsOiBgJHtwYWlyc1swXS5kZWZhdWx0TmFtZX0gLT4gJHtwYWlyc1sxXS5kZWZhdWx0TmFtZX0gZmxvd2AsXG4gICAgICBjb2x1bW5zXG4gICAgfSk7XG4gICAgcmV0dXJuIGxheWVyO1xuICB9XG4gIGNvbnN0IGRlZmF1bHRMYXllcnMgPSBmaW5kRGVmYXVsdExheWVyKGRhdGFzZXQsIExheWVyQ2xhc3NlcyBhcyBhbnkpO1xuICBjb25zdCBsYXllciA9IGRlZmF1bHRMYXllcnMuZmluZChsID0+IGwudHlwZSA9PT0gbGF5ZXJUeXBlKTtcbiAgLy8gUmV0dXJuIG51bGwgKG5vdCBhIGZhbGxiYWNrIHRvIHRoZSBmaXJzdCBkZWZhdWx0IGxheWVyKSB3aGVuIHRoZSByZXF1ZXN0ZWRcbiAgLy8gdHlwZSBjYW4ndCBiZSBjcmVhdGVkIOKAlCBzaWxlbnRseSBzdWJzdGl0dXRpbmcgYSBkaWZmZXJlbnQgbGF5ZXIgdHlwZSAoZS5nLlxuICAvLyByZXF1ZXN0aW5nIFwiaDNcIiBhbmQgZ2V0dGluZyBhIHBvaW50IGxheWVyKSB2aW9sYXRlcyB0aGUgY29tbWFuZCBjb250cmFjdFxuICAvLyBhbmQgbWFrZXMgZmFpbHVyZXMgaGFyZCB0byBkaWFnbm9zZS4gVGhlIGNhbGxlciBlcnJvcnMgY2xlYXJseSBvbiBudWxsLlxuICByZXR1cm4gbGF5ZXIgfHwgbnVsbDtcbn1cblxuLyoqIENvbHVtbiBuYW1lcyB0aGUgZmxvdyBmaWVsZCBsYXllciByZXNvbHZlcyB3aGVuIHRoZSBjYWxsZXIgZG9lc24ndCBuYW1lIHRoZW0uICovXG5jb25zdCBGTE9XX0ZJRUxEX0FMVElUVURFX0NPTFVNTlMgPSBbJ2FsdGl0dWRlJywgJ2FsdCcsICdlbGV2YXRpb24nLCAnZWxldicsICdlbHYnLCAnaGVpZ2h0JywgJ3onXTtcbmNvbnN0IEZMT1dfRklFTERfTU9ERVMgPSBbJ1VWJywgJ1NQRUVEX0RJUicsICdFTEVWQVRJT04nXSBhcyBjb25zdDtcbnR5cGUgRmxvd0ZpZWxkTW9kZSA9ICh0eXBlb2YgRkxPV19GSUVMRF9NT0RFUylbbnVtYmVyXTtcblxudHlwZSBGbG93RmllbGRPcHRpb25zID0ge1xuICBtb2RlPzogRmxvd0ZpZWxkTW9kZTtcbiAgdUNvbHVtbj86IHN0cmluZztcbiAgdkNvbHVtbj86IHN0cmluZztcbiAgc3BlZWRDb2x1bW4/OiBzdHJpbmc7XG4gIGRpcmVjdGlvbkNvbHVtbj86IHN0cmluZztcbiAgYWx0aXR1ZGVDb2x1bW4/OiBzdHJpbmc7XG4gIGNvbG9yQnlTcGVlZD86IGJvb2xlYW47XG59O1xuXG4vKipcbiAqIEZsb3cgRmllbGQgaXMgYSB2ZWN0b3Ivc3RyZWFtbGluZSBsYXllcjogZWFjaCByb3cgaXMgYSBzYW1wbGUgcG9pbnQgY2FycnlpbmdcbiAqIGEgcG9zaXRpb24gcGx1cyBhIGRpcmVjdGlvbiDigJQgdS92IGNvbXBvbmVudHMsIHNwZWVkL2RpcmVjdGlvbiwgb3IgYW4gYWx0aXR1ZGVcbiAqIHdob3NlIGRvd25oaWxsIGdyYWRpZW50IHN1cHBsaWVzIHRoZSBkaXJlY3Rpb24uIFVubGlrZSB0aGUgb3JpZ2lu4oaSZGVzdGluYXRpb25cbiAqIGBmbG93YCBsYXllciBpdCBuZWVkcyBubyBzZWNvbmQgcG9pbnQgcGFpciwgYW5kIHVubGlrZSBgdHJpcGAgaXQgYW5pbWF0ZXNcbiAqIGl0c2VsZiwgc28gbm8gdGltZSBmaWx0ZXIgYmVsb25ncyBvbiBpdC5cbiAqL1xuZnVuY3Rpb24gYnVpbGRGbG93RmllbGRMYXllcihcbiAgZGF0YXNldDogS2VwbGVyVGFibGUsXG4gIHBvc2l0aW9uOiB7bGF0aXR1ZGVDb2x1bW4/OiBzdHJpbmc7IGxvbmdpdHVkZUNvbHVtbj86IHN0cmluZ30sXG4gIG9wdGlvbnM6IEZsb3dGaWVsZE9wdGlvbnMgPSB7fVxuKSB7XG4gIGNvbnN0IGhhc0NvbHVtbiA9IChuYW1lPzogc3RyaW5nKSA9PiAhIW5hbWUgJiYgZGF0YXNldC5nZXRDb2x1bW5GaWVsZElkeChuYW1lKSA+PSAwO1xuICBjb25zdCBjb2x1bW5SZWYgPSAobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgZmllbGRJZHggPSBkYXRhc2V0LmdldENvbHVtbkZpZWxkSWR4KG5hbWUpO1xuICAgIGlmIChmaWVsZElkeCA8IDApIHtcbiAgICAgIGNvbnN0IGF2YWlsYWJsZSA9IGRhdGFzZXQuZmllbGRzPy5tYXAoKGY6IGFueSkgPT4gZi5uYW1lKS5qb2luKCcsICcpID8/ICcnO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ29sdW1uIFwiJHtuYW1lfVwiIG5vdCBmb3VuZCBpbiBkYXRhc2V0IFwiJHtkYXRhc2V0LmxhYmVsfVwiLiBBdmFpbGFibGUgY29sdW1uczogJHthdmFpbGFibGV9YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHt2YWx1ZTogbmFtZSwgZmllbGRJZHh9O1xuICB9O1xuXG4gIC8vIFBvc2l0aW9uOiBleHBsaWNpdCBsYXQvbG5nLCBlbHNlIHRoZSBkYXRhc2V0J3MgZmlyc3QgZGV0ZWN0ZWQgcG9pbnQgcGFpcixcbiAgLy8gZWxzZSBhIEdlb0pTT04gZ2VvbWV0cnkgY29sdW1uIChvbmUgcG9zaXRpb24gcGVyIGZlYXR1cmUpLlxuICBsZXQgcG9zaXRpb25Db2x1bW5zOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbCA9IG51bGw7XG4gIGlmIChwb3NpdGlvbi5sYXRpdHVkZUNvbHVtbiAmJiBwb3NpdGlvbi5sb25naXR1ZGVDb2x1bW4pIHtcbiAgICBwb3NpdGlvbkNvbHVtbnMgPSB7XG4gICAgICBsYXQ6IGNvbHVtblJlZihwb3NpdGlvbi5sYXRpdHVkZUNvbHVtbiksXG4gICAgICBsbmc6IGNvbHVtblJlZihwb3NpdGlvbi5sb25naXR1ZGVDb2x1bW4pXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBwYWlyID0gZGF0YXNldC5maWVsZFBhaXJzPy5bMF0/LnBhaXI7XG4gICAgaWYgKHBhaXI/LmxhdCAmJiBwYWlyPy5sbmcpIHtcbiAgICAgIHBvc2l0aW9uQ29sdW1ucyA9IHtsYXQ6IHBhaXIubGF0LCBsbmc6IHBhaXIubG5nfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZ2VvRmllbGQgPSBkYXRhc2V0LmZpZWxkcz8uZmluZChcbiAgICAgICAgKGY6IGFueSkgPT4gZi50eXBlID09PSAnZ2VvanNvbicgfHwgR0VPSlNPTl9GSUVMRFMuZ2VvanNvbi5pbmNsdWRlcyhmLm5hbWUpXG4gICAgICApO1xuICAgICAgaWYgKGdlb0ZpZWxkKSB7XG4gICAgICAgIHBvc2l0aW9uQ29sdW1ucyA9IHtnZW9qc29uOiB7dmFsdWU6IGdlb0ZpZWxkLm5hbWUsIGZpZWxkSWR4OiBnZW9GaWVsZC5maWVsZElkeH19O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoIXBvc2l0aW9uQ29sdW1ucykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdBIGZsb3cgZmllbGQgbGF5ZXIgbmVlZHMgYSBwb3NpdGlvbjogbGF0L2xuZyBjb2x1bW5zIChhdXRvLWRldGVjdGVkLCBvciBwYXNzICcgK1xuICAgICAgICAnbGF0aXR1ZGVDb2x1bW4vbG9uZ2l0dWRlQ29sdW1uKSBvciBhIEdlb0pTT04gZ2VvbWV0cnkgY29sdW1uLidcbiAgICApO1xuICB9XG5cbiAgY29uc3QgYWx0aXR1ZGVOYW1lID1cbiAgICBvcHRpb25zLmFsdGl0dWRlQ29sdW1uIHx8IEZMT1dfRklFTERfQUxUSVRVREVfQ09MVU1OUy5maW5kKG5hbWUgPT4gaGFzQ29sdW1uKG5hbWUpKSB8fCBudWxsO1xuXG4gIGNvbnN0IG1vZGU6IEZsb3dGaWVsZE1vZGUgfCBudWxsID1cbiAgICBvcHRpb25zLm1vZGUgfHxcbiAgICAob3B0aW9ucy51Q29sdW1uIHx8IG9wdGlvbnMudkNvbHVtbiB8fCAoaGFzQ29sdW1uKCd1JykgJiYgaGFzQ29sdW1uKCd2JykpXG4gICAgICA/ICdVVidcbiAgICAgIDogb3B0aW9ucy5zcGVlZENvbHVtbiB8fFxuICAgICAgICBvcHRpb25zLmRpcmVjdGlvbkNvbHVtbiB8fFxuICAgICAgICAoaGFzQ29sdW1uKCdzcGVlZCcpICYmIGhhc0NvbHVtbignZGlyZWN0aW9uJykpXG4gICAgICA/ICdTUEVFRF9ESVInXG4gICAgICA6IGFsdGl0dWRlTmFtZVxuICAgICAgPyAnRUxFVkFUSU9OJ1xuICAgICAgOiBudWxsKTtcbiAgaWYgKCFtb2RlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0EgZmxvdyBmaWVsZCBsYXllciBuZWVkcyBhIHZlY3RvcjogdS92IGNvbHVtbnMsIHNwZWVkL2RpcmVjdGlvbiBjb2x1bW5zLCBvciBhbiAnICtcbiAgICAgICAgJ2FsdGl0dWRlIGNvbHVtbiAocGFzcyBmbG93RmllbGQudUNvbHVtbi92Q29sdW1uL3NwZWVkQ29sdW1uL2RpcmVjdGlvbkNvbHVtbi8nICtcbiAgICAgICAgJ2FsdGl0dWRlQ29sdW1uIHdoZW4gdGhlIG5hbWVzIGRpZmZlcikuJ1xuICAgICk7XG4gIH1cblxuICBsZXQgZmxvd0NvbHVtbnM6IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIGlmIChtb2RlID09PSAnVVYnKSB7XG4gICAgZmxvd0NvbHVtbnMgPSB7XG4gICAgICB1OiBjb2x1bW5SZWYob3B0aW9ucy51Q29sdW1uIHx8ICd1JyksXG4gICAgICB2OiBjb2x1bW5SZWYob3B0aW9ucy52Q29sdW1uIHx8ICd2JylcbiAgICB9O1xuICB9IGVsc2UgaWYgKG1vZGUgPT09ICdTUEVFRF9ESVInKSB7XG4gICAgZmxvd0NvbHVtbnMgPSB7XG4gICAgICBzcGVlZDogY29sdW1uUmVmKG9wdGlvbnMuc3BlZWRDb2x1bW4gfHwgJ3NwZWVkJyksXG4gICAgICBkaXJlY3Rpb246IGNvbHVtblJlZihvcHRpb25zLmRpcmVjdGlvbkNvbHVtbiB8fCAnZGlyZWN0aW9uJylcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGlmICghYWx0aXR1ZGVOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdBIGZsb3cgZmllbGQgbGF5ZXIgaW4gRUxFVkFUSU9OIG1vZGUgbmVlZHMgYW4gYWx0aXR1ZGUgY29sdW1uIChwYXNzIGZsb3dGaWVsZC5hbHRpdHVkZUNvbHVtbikuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgZmxvd0NvbHVtbnMgPSB7YWx0aXR1ZGU6IGNvbHVtblJlZihhbHRpdHVkZU5hbWUpfTtcbiAgfVxuXG4gIC8vIFVWIGFuZCBTUEVFRF9ESVIgbWF5IGFsc28gY2FycnkgYW4gYWx0aXR1ZGUsIHdoaWNoIGxpZnRzIHRoZSBzdHJlYW1saW5lcy5cbiAgY29uc3QgYWx0aXR1ZGVDb2x1bW4gPVxuICAgIG1vZGUgPT09ICdFTEVWQVRJT04nIHx8ICFhbHRpdHVkZU5hbWUgPyB7fSA6IHthbHRpdHVkZTogY29sdW1uUmVmKGFsdGl0dWRlTmFtZSl9O1xuXG4gIGNvbnN0IGxheWVyID0gbmV3IChMYXllckNsYXNzZXMgYXMgYW55KS5mbG93RmllbGQoe1xuICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICBsYWJlbDogJ0Zsb3cgRmllbGQnLFxuICAgIGNvbG9yOiBbMjU1LCAyNTUsIDI1NV0sXG4gICAgY29sdW1uTW9kZTogbW9kZSxcbiAgICBjb2x1bW5zOiB7Li4ucG9zaXRpb25Db2x1bW5zLCAuLi5mbG93Q29sdW1ucywgLi4uYWx0aXR1ZGVDb2x1bW59XG4gIH0pO1xuICBpZiAob3B0aW9ucy5jb2xvckJ5U3BlZWQpIHtcbiAgICBsYXllci5jb25maWcudmlzQ29uZmlnID0gey4uLmxheWVyLmNvbmZpZy52aXNDb25maWcsIGNvbG9yQnlTcGVlZDogdHJ1ZX07XG4gIH1cbiAgcmV0dXJuIGxheWVyO1xufVxuXG5mdW5jdGlvbiBidWlsZExheWVyQ29uZmlnKFxuICBsYXllcjogYW55LFxuICBkYXRhc2V0SWQ6IHN0cmluZyxcbiAgbGF5ZXJOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHNvdXJjZU5hbWU6IHN0cmluZyxcbiAgbGF5ZXJUeXBlOiBzdHJpbmdcbikge1xuICBjb25zdCBsYXllcklkID0gbGF5ZXIuaWQgfHwgdW5pcXVlTGF5ZXJJZCgpO1xuICBjb25zdCBjb2x1bW5zID0gbGF5ZXIuY29uZmlnPy5jb2x1bW5zIHx8IHt9O1xuXG4gIHJldHVybiB7XG4gICAgaWQ6IGxheWVySWQsXG4gICAgdHlwZTogbGF5ZXIudHlwZSxcbiAgICBjb25maWc6IHtcbiAgICAgIC4uLmxheWVyLmNvbmZpZyxcbiAgICAgIGRhdGFJZDogZGF0YXNldElkLFxuICAgICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgICAgbGFiZWw6IGxheWVyTmFtZSB8fCBgJHtzb3VyY2VOYW1lfS0ke2xheWVyVHlwZX1gLFxuICAgICAgY29sdW1uczogT2JqZWN0LmtleXMoY29sdW1ucykucmVkdWNlPFJlY29yZDxzdHJpbmcsIGFueT4+KChhY2MsIGtleSkgPT4ge1xuICAgICAgICBjb25zdCBjb2x1bW4gPSBjb2x1bW5zW2tleV07XG4gICAgICAgIGlmIChjb2x1bW4pIHtcbiAgICAgICAgICBhY2Nba2V5XSA9IGNvbHVtbi52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwge30pLFxuICAgICAgdmlzQ29uZmlnOiB7XG4gICAgICAgIC4uLmxheWVyLmNvbmZpZz8udmlzQ29uZmlnXG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBhcHBseUNvbG9yQ29uZmlnKFxuICBuZXdMYXllcjogYW55LFxuICBkYXRhc2V0OiBLZXBsZXJUYWJsZSxcbiAgYXJnczoge1xuICAgIHNpbXBsZUNvbG9yPzogc3RyaW5nO1xuICAgIGNvbG9yQnk/OiBzdHJpbmc7XG4gICAgY29sb3JUeXBlPzogJ2JyZWFrcycgfCAndW5pcXVlJztcbiAgICBjb2xvck1hcD86IEFycmF5PHt2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbDsgY29sb3I6IHN0cmluZ30+O1xuICB9XG4pIHtcbiAgaWYgKGFyZ3Muc2ltcGxlQ29sb3IpIHtcbiAgICBjb25zdCBjb2xvciA9IGFyZ3Muc2ltcGxlQ29sb3JcbiAgICAgIC5yZXBsYWNlKC9bXlxcZCxdL2csICcnKVxuICAgICAgLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoTnVtYmVyKTtcbiAgICBpZiAoY29sb3IubGVuZ3RoID09PSAzKSB7XG4gICAgICBuZXdMYXllci5jb25maWcuY29sb3IgPSBjb2xvcjtcbiAgICB9XG4gIH1cblxuICBjb25zdCB7Y29sb3JCeSwgY29sb3JUeXBlLCBjb2xvck1hcDogcHJvdmlkZWRDb2xvck1hcH0gPSBhcmdzO1xuXG4gIGlmIChjb2xvckJ5KSB7XG4gICAgY29uc3QgY29sb3JGaWVsZCA9IGRhdGFzZXQuZmllbGRzLmZpbmQoZiA9PiBmLm5hbWUgPT09IGNvbG9yQnkpO1xuICAgIGlmICghY29sb3JGaWVsZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGaWVsZCAke2NvbG9yQnl9IG5vdCBmb3VuZC5gKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgY2F0ZWdvcmljYWwgKGN1c3RvbU9yZGluYWwpIGNvbG9yIG1hcHMsIGV2ZXJ5IHZhbHVlIGJlY29tZXMgdGhlIHNjYWxlXG4gICAgLy8gZG9tYWluLCBzbyBpdCBtdXN0IGJlIGEgcmVhbCB2YWx1ZSBwcmVzZW50IGluIHRoZSBkYXRhLiBUaGUgYWdlbnQgbXVzdCBub3RcbiAgICAvLyBpbnZlbnQgY2F0ZWdvcnkgbGFiZWxzIOKAlCBnZXQgdGhlbSB2aWEgZ2VvZGEuYW5hbHlzaXMgKGFuYWx5c2lzOiAnY2xhc3NpZnknLFxuICAgIC8vIG1ldGhvZDogJ3VuaXF1ZSB2YWx1ZXMnKS4gUmVqZWN0aW5nIGhlcmUgdHVybnMgYSBzaWxlbnQgd3JvbmcgcmVuZGVyIGludG8gYVxuICAgIC8vIHJlY292ZXJhYmxlIGVycm9yLiBPbmx5IHJ1biB0aGlzIHdoZW4gY29sb3JUeXBlIGlzIGV4cGxpY2l0bHkgJ3VuaXF1ZSc6XG4gICAgLy8gYW4gb21pdHRlZCBjb2xvclR5cGUgZGVmYXVsdHMgdG8gYSBjb250aW51b3VzIChicmVha3MpIHNjYWxlLCB3aG9zZVxuICAgIC8vIGNvbG9yTWFwIHZhbHVlcyBhcmUgYnJlYWsgYm91bmRhcmllcywgbm90IGRhdGEgdmFsdWVzLlxuICAgIGlmIChjb2xvclR5cGUgPT09ICd1bmlxdWUnICYmIHByb3ZpZGVkQ29sb3JNYXApIHtcbiAgICAgIC8vIFZhbGlkYXRlIHdpdGhvdXQgbWF0ZXJpYWxpemluZyB0aGUgd2hvbGUgY29sdW1uOiBzY2FuIHJvd3MsIGRlbGV0aW5nXG4gICAgICAvLyBtYXRjaGVzIGZyb20gYSBzbWFsbCBgd2FudGVkYCBzZXQgKGVhcmx5LWV4aXQgd2hlbiBhbGwgYXJlIGZvdW5kKSxcbiAgICAgIC8vIHdoaWxlIGNvbGxlY3RpbmcgYSBzbWFsbCBzYW1wbGUgb2YgYWN0dWFsIHZhbHVlcyBmb3IgdGhlIGVycm9yIG1lc3NhZ2UuXG4gICAgICAvLyBTY2FuIEFMTCByb3dzIOKAlCBhIGJvdW5kZWQgc2FtcGxlIChwcmVmaXggT1IgZml4ZWQtc3RyaWRlKSBjYW5cbiAgICAgIC8vIHN5c3RlbWF0aWNhbGx5IG1pc3MgYSBjYXRlZ29yeSB0aGF0IGV4aXN0cyBsYXRlciBpbiB0aGUgZGF0YSBhbmRcbiAgICAgIC8vIGZhbHNlbHkgcmVwb3J0IGl0IGFzIFwibm90IGZvdW5kXCIuIFRoZSBlYXJseS1leGl0IGtlZXBzIHRoZSBjb21tb24gY2FzZVxuICAgICAgLy8gKGFsbCBjYXRlZ29yaWVzIGZvdW5kIGVhcmx5KSBmYXN0OyBvbmx5IGEgZ2VudWluZWx5IG1pc3NpbmcgY2F0ZWdvcnlcbiAgICAgIC8vIGNvc3RzIGEgZnVsbCBzY2FuLCB3aGljaCBpcyB0aGUgcHJpY2Ugb2YgYW4gYWNjdXJhdGUgZXJyb3IuXG4gICAgICBjb25zdCB3YW50ZWQgPSBuZXcgU2V0KHByb3ZpZGVkQ29sb3JNYXAubWFwKGMgPT4gYy52YWx1ZSkpO1xuICAgICAgY29uc3Qgc2FtcGxlOiB1bmtub3duW10gPSBbXTtcbiAgICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHVua25vd24+KCk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFzZXQubGVuZ3RoICYmIHdhbnRlZC5zaXplID4gMDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHYgPSBkYXRhc2V0LmdldFZhbHVlKGNvbG9yQnksIGkpO1xuICAgICAgICBpZiAod2FudGVkLmhhcyh2KSkge1xuICAgICAgICAgIHdhbnRlZC5kZWxldGUodik7XG4gICAgICAgIH0gZWxzZSBpZiAoIXNlZW4uaGFzKHYpICYmIHNhbXBsZS5sZW5ndGggPCAyMCkge1xuICAgICAgICAgIHNlZW4uYWRkKHYpO1xuICAgICAgICAgIHNhbXBsZS5wdXNoKHYpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAod2FudGVkLnNpemUgPiAwKSB7XG4gICAgICAgIGNvbnN0IG1pc3NpbmcgPSBbLi4ud2FudGVkXTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBjb2xvck1hcCB2YWx1ZShzKSAke21pc3NpbmdcbiAgICAgICAgICAgIC5tYXAodiA9PiBKU09OLnN0cmluZ2lmeSh2KSlcbiAgICAgICAgICAgIC5qb2luKCcsICcpfSBub3QgZm91bmQgaW4gZmllbGQgXCIke2NvbG9yQnl9XCIuIGAgK1xuICAgICAgICAgICAgYEFjdHVhbCB1bmlxdWUgdmFsdWVzOiAke3NhbXBsZS5tYXAodiA9PiBKU09OLnN0cmluZ2lmeSh2KSkuam9pbignLCAnKX0ke1xuICAgICAgICAgICAgICBzYW1wbGUubGVuZ3RoID49IDIwID8gJywg4oCmJyA6ICcnXG4gICAgICAgICAgICB9LiBgICtcbiAgICAgICAgICAgIGBDYWxsIGdlb2RhLmFuYWx5c2lzIChhbmFseXNpczogJ2NsYXNzaWZ5JywgbWV0aG9kOiAndW5pcXVlIHZhbHVlcycpIHRvIGdldCB0aGUgcmVhbCB2YWx1ZXMuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNvbG9yVHlwZSBpcyBvcHRpb25hbDsgd2hlbiBvbWl0dGVkLCBkZWZhdWx0IHRvIGEgY29udGludW91cyAoYnJlYWtzKVxuICAgIC8vIHNjYWxlIHNvIG51bWVyaWMgZmllbGRzIGNvbG9yZWQgdmlhIGNvbG9yQnkgYXJlbid0IG1pcy1jb2xvcmVkIGFzXG4gICAgLy8gY2F0ZWdvcmljYWwuIE9ubHkgYW4gZXhwbGljaXQgJ3VuaXF1ZScgc2VsZWN0cyB0aGUgY2F0ZWdvcmljYWwgc2NhbGUuXG4gICAgY29uc3QgY29sb3JTY2FsZSA9IGNvbG9yVHlwZSA9PT0gJ3VuaXF1ZScgPyAnY3VzdG9tT3JkaW5hbCcgOiAnY3VzdG9tJztcblxuICAgIC8vIE9ubHkgZm9yY2UgYSBjdXN0b20gcGFsZXR0ZSB3aGVuIHRoZSBjYWxsZXIgcHJvdmlkZWQgYW4gZXhwbGljaXRcbiAgICAvLyBjb2xvck1hcC4gQSBzeW50aGV0aWMgc2luZ2xlLWVudHJ5IGNvbG9yTWFwICh7dmFsdWU6IG51bGwsIGNvbG9yOlxuICAgIC8vICcjMzMzMzMzJ30pIHdvdWxkIHJvdXRlIHRocm91Z2gga2VwbGVyJ3MgY3VzdG9tIGNvbG9yTWFwIHNjYWxlIHBhdGggYW5kXG4gICAgLy8gcmVuZGVyIGV2ZXJ5dGhpbmcgYXMgdGhlIG5vLXZhbHVlL3Vua25vd24gY29sb3I7IHdpdGhvdXQgYW4gZXhwbGljaXRcbiAgICAvLyBjb2xvck1hcCwgYmluZCB0aGUgY29sb3IgZmllbGQgYW5kIGxldCBrZXBsZXIuZ2wncyBkZWZhdWx0IGNvbG9yIHJhbmdlXG4gICAgLy8gYXBwbHkuXG4gICAgY29uc3QgY29sb3JSYW5nZSA9IHByb3ZpZGVkQ29sb3JNYXBcbiAgICAgID8gKHtcbiAgICAgICAgICBuYW1lOiAnY29sb3IuY3VzdG9tUGFsZXR0ZScsXG4gICAgICAgICAgdHlwZTogJ2N1c3RvbScsXG4gICAgICAgICAgY2F0ZWdvcnk6ICdDdXN0b20nLFxuICAgICAgICAgIGNvbG9yczogcHJvdmlkZWRDb2xvck1hcC5tYXAoYyA9PiBjLmNvbG9yKSxcbiAgICAgICAgICBjb2xvck1hcDogcHJvdmlkZWRDb2xvck1hcC5tYXAoYyA9PiBbYy52YWx1ZSwgYy5jb2xvcl0pXG4gICAgICAgIH0gYXMgY29uc3QpXG4gICAgICA6IG51bGw7XG5cbiAgICBpZiAobmV3TGF5ZXIudHlwZSA9PT0gJ2hlYXRtYXAnKSB7XG4gICAgICBpZiAoY29sb3JSYW5nZSAmJiBwcm92aWRlZENvbG9yTWFwICYmIHByb3ZpZGVkQ29sb3JNYXAubGVuZ3RoID4gMSkge1xuICAgICAgICBuZXdMYXllci5jb25maWcudmlzQ29uZmlnWydjb2xvclJhbmdlJ10gPSB7Li4uY29sb3JSYW5nZX07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snY29sb3JTY2FsZSddID0gY29sb3JTY2FsZTtcbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snY29sb3JGaWVsZCddID0gY29sb3JGaWVsZDtcbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snc3Ryb2tlQ29sb3JTY2FsZSddID0gY29sb3JTY2FsZTtcbiAgICAgIG5ld0xheWVyLmNvbmZpZ1snc3Ryb2tlQ29sb3JGaWVsZCddID0gY29sb3JGaWVsZDtcbiAgICAgIG5ld0xheWVyLmNvbmZpZy52aXNDb25maWdbJ2ZpbGxlZCddID0gdHJ1ZTtcbiAgICAgIGlmIChjb2xvclJhbmdlKSB7XG4gICAgICAgIG5ld0xheWVyLmNvbmZpZy52aXNDb25maWdbJ2NvbG9yUmFuZ2UnXSA9IGNvbG9yUmFuZ2U7XG4gICAgICAgIG5ld0xheWVyLmNvbmZpZy52aXNDb25maWdbJ3N0cm9rZUNvbG9yUmFuZ2UnXSA9IGNvbG9yUmFuZ2U7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBhZGRMYXllckNvbW1hbmRJZCA9ICdtYXAuYWRkLWxheWVyJyBhcyBjb25zdDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFkZExheWVyQ29tbWFuZChjdHg6IEtlcGxlckNvbnRleHQpOiBSb29tQ29tbWFuZCB7XG4gIHJldHVybiB7XG4gICAgaWQ6IGFkZExheWVyQ29tbWFuZElkLFxuICAgIG5hbWU6ICdBZGQgbWFwIGxheWVyJyxcbiAgICBncm91cDogJ01hcCcsXG4gICAgZGVzY3JpcHRpb246IGBBZGQgYSBrZXBsZXIuZ2wgbWFwIGxheWVyIGZyb20gYSBkYXRhc2V0LlxuSU1QT1JUQU5UOiBnZW5lcmF0ZWQgbGF5ZXIgbmFtZXMgbXVzdCBiZSB1bmlxdWUuXG5cbkxBWUVSIFRZUEVTOlxuLSBwb2ludDogUG9pbnQgbWFya2VycyAocmVxdWlyZXMgbGF0L2xuZyBjb2x1bW5zKVxuLSBmbG93OiBPcmlnaW4tPmRlc3RpbmF0aW9uIGZsb3cgbWFwIChyZXF1aXJlcyB0d28gcG9pbnQgbGF0L2xuZyBwYWlycywgYXV0by1kZXRlY3RlZClcbi0gZmxvd0ZpZWxkOiBBbmltYXRlZCBzdHJlYW1saW5lcyBvdmVyIGEgdmVjdG9yIGZpZWxkICh1L3YsIHNwZWVkL2RpcmVjdGlvbiwgb3IgYWx0aXR1ZGUpXG4tIGgzOiBIMyBoZXhhZ29uIGNlbGxzIChyZXF1aXJlcyBoZXhJZCBjb2x1bW4pXG4tIGdlb2pzb246IFBvbHlnb24vZ2VvbWV0cnkgZmVhdHVyZXMgKHVzZXMgZ2VvbWV0cnkgY29sdW1uLCB1c3VhbGx5IGF1dG8tZGV0ZWN0ZWQpXG4tIGhleGFnb246IEhleGFnb25hbCBiaW5uaW5nIG9mIHBvaW50c1xuLSBoZWF0bWFwOiBIZWF0IG1hcCB2aXN1YWxpemF0aW9uXG4tIGNsdXN0ZXI6IENsdXN0ZXJlZCBwb2ludCB2aXN1YWxpemF0aW9uXG4tIGFyYy9saW5lOiBBcmMgb3IgbGluZSBjb25uZWN0aW9ucyBiZXR3ZWVuIHBvaW50c1xuLSBncmlkOiBHcmlkIGJpbm5pbmdcbi0gdHJpcDogQW5pbWF0ZWQgdHJpcCAoZmxpZ2h0cywgZGVsaXZlcmllcywgdmVzc2Vscylcbi0gczI6IFMyIGdlb21ldHJ5IGNlbGxzXG5cbkZMT1cgTUFQUyAobGF5ZXJUeXBlICdmbG93Jyk6XG5Gb3Igb3JpZ2luLT5kZXN0aW5hdGlvbiBmbG93cyB1c2UgbGF5ZXJUeXBlICdmbG93JyDigJQgYSBkZWRpY2F0ZWQgZmxvdyBsYXllciB0aGF0IGRyYXdzXG5sb2NhdGlvbnMgYW5kIHdlaWdodGVkIGZsb3dzIGJldHdlZW4gdGhlbS4gSXQgbmVlZHMgVFdPIHBvaW50IGxhdC9sbmcgcGFpcnMgaW4gdGhlXG5kYXRhc2V0IChzb3VyY2UgcGFpciArIGRlc3RpbmF0aW9uIHBhaXIpLCB3aGljaCBhcmUgYXV0by1kZXRlY3RlZC4gUHJlZmVyICdmbG93JyBvdmVyXG4nYXJjJyBmb3IgTy1EIGZsb3dzOyAnYXJjJyBkcmF3cyBzdHJhaWdodCBncmVhdC1jaXJjbGUgbGluZXMgd2l0aG91dCBsb2NhdGlvbiBjbHVzdGVyaW5nXG5vciBmbG93IGFnZ3JlZ2F0aW9uLiBUbyB3ZWlnaHQgdGhlIGZsb3dzIGJ5IGEgdmFsdWUgY29sdW1uIChmbG93IG1hZ25pdHVkZSksIHBhc3NcbmNvdW50Q29sdW1uIHdpdGggdGhlIGNvbHVtbiBuYW1lIOKAlCBvbWl0IGl0IHRvIHJlbmRlciBhbGwgZmxvd3MgYXQgd2VpZ2h0IDEuXG5cbkZMT1cgRklFTEQgKGxheWVyVHlwZSAnZmxvd0ZpZWxkJyk6XG5BbmltYXRlZCBzdHJlYW1saW5lcyBvdmVyIGEgdmVjdG9yIGZpZWxkIOKAlCB3aW5kLCBjdXJyZW50cywgb3IgZG93bmhpbGwgZmxvdy4gSXQgaXMgTk9UXG50aGUgb3JpZ2luLT5kZXN0aW5hdGlvbiAnZmxvdycgbGF5ZXI6ICdmbG93JyBqb2lucyB0d28gcG9pbnQgcGFpcnMsICdmbG93RmllbGQnIGRyYXdzXG5tYW55IHNob3J0IGxpbmVzIHRocm91Z2ggYSBmaWVsZCBvZiB2ZWN0b3JzLCBvbmUgcm93IHBlciBzYW1wbGUgcG9pbnQuXG5UaGUgZGlyZWN0aW9uIGNvbWVzIGZyb20gb25lIG9mIHRocmVlIGNvbHVtbiBzZXRzLCBhdXRvLWRldGVjdGVkIGluIHRoaXMgb3JkZXI6XG4tIHUvdiBjb21wb25lbnRzIChkZWZhdWx0IG1vZGUgJ1VWJyksIG9wdGlvbmFsbHkgd2l0aCBhbiBhbHRpdHVkZSBjb2x1bW5cbi0gc3BlZWQgKyBkaXJlY3Rpb24gKG1vZGUgJ1NQRUVEX0RJUicpXG4tIGFsdGl0dWRlIG9ubHkgKG1vZGUgJ0VMRVZBVElPTicpOiB0aGUgZG93bmhpbGwgZ3JhZGllbnQgZ2l2ZXMgdGhlIGRpcmVjdGlvblxuUG9zaXRpb24gaXMgbGF0L2xuZyAoYXV0by1kZXRlY3RlZCwgb3IgbGF0aXR1ZGVDb2x1bW4vbG9uZ2l0dWRlQ29sdW1uKSBvciBhIEdlb0pTT05cbmdlb21ldHJ5IGNvbHVtbi4gV2hlbiB0aGUgZGF0YXNldCBuYW1lcyB0aGUgY29sdW1ucyBkaWZmZXJlbnRseSwgcGFzcyBmbG93RmllbGQubW9kZVxucGx1cyBmbG93RmllbGQudUNvbHVtbi92Q29sdW1uL3NwZWVkQ29sdW1uL2RpcmVjdGlvbkNvbHVtbi9hbHRpdHVkZUNvbHVtbi5cblNldCBmbG93RmllbGQuY29sb3JCeVNwZWVkIHRydWUgdG8gY29sb3IgbGluZXMgYnkgbG9jYWwgc3BlZWQ7IG90aGVyd2lzZSBzaW1wbGVDb2xvclxuYXBwbGllcy4gY29sb3JCeS9jb2xvck1hcCBkbyBub3QgYXBwbHkgdG8gdGhpcyBsYXllci4gRG8gTk9UIGFkZCBhIHRpbWUgZmlsdGVyIOKAlCB0aGVcbmZsb3cgZmllbGQgYW5pbWF0ZXMgaXRzZWxmLlxuXG5CQVNJQyBNQVA6XG4tIFVzZSBkYXRhc2V0TmFtZSwgbGF0aXR1ZGVDb2x1bW4vbG9uZ2l0dWRlQ29sdW1uIChmb3IgcG9pbnQgbWFwcyksIGFuZCBsYXllclR5cGVcbi0gT21pdCBjb2xvci1yZWxhdGVkIHBhcmFtZXRlcnMgZm9yIHNpbXBsZSB2aXN1YWxpemF0aW9uLCB1c2Ugc2ltcGxlQ29sb3IgaW5zdGVhZC5cblxuQ09MT1IgTUFQUElORzpcbi0gSWYgdXNlciByZXF1ZXN0cyBjb2xvciB2aXN1YWxpemF0aW9uLCB1c2UgYXZhaWxhYmxlIGNvbHVtbnMgaW4gdGhlIGRhdGFzZXRcbi0gVXNlIGdlb2RhLmFuYWx5c2lzIChhbmFseXNpczogJ2NsYXNzaWZ5JykgdG8gY2xhc3NpZnkgZGF0YSBpbnRvIGJpbnMgb3IgdW5pcXVlIHZhbHVlcyB3aGVuIG5lZWRlZFxuLSBGb3IgY29udGludW91cyBkYXRhIChjb2xvclR5cGUgJ2JyZWFrcycpOlxuICBbe3ZhbHVlOiAwLCBjb2xvcjogJyNmZWU1ZDknfSwge3ZhbHVlOiA1MCwgY29sb3I6ICcjZmNhZTkxJ30sIHt2YWx1ZTogMTAwLCBjb2xvcjogJyNmYjZhNGEnfSwge3ZhbHVlOiBudWxsLCBjb2xvcjogJyNkZTJkMjYnfV1cbiAgVGhlIGxhc3QgZW50cnkgd2l0aCB2YWx1ZTogbnVsbCByZXByZXNlbnRzIHRoZSBjb2xvciBmb3IgdGhlIGhpZ2hlc3QgdmFsdWVzXG4tIEZvciBjYXRlZ29yaWNhbCBkYXRhIChjb2xvclR5cGUgJ3VuaXF1ZScpOlxuICBbe3ZhbHVlOiAnY2F0ZWdvcnkxJywgY29sb3I6ICcjMWY3N2I0J30sIHt2YWx1ZTogJ2NhdGVnb3J5MicsIGNvbG9yOiAnI2ZmN2YwZSd9XVxuICBIQVJEIFJVTEU6IHRoZSBjb2xvck1hcCB2YWx1ZXMgTVVTVCBiZSB0aGUgYWN0dWFsIHVuaXF1ZSB2YWx1ZXMgcHJlc2VudCBpbiB0aGUgZGF0YS5cbiAgQ2FsbCBnZW9kYS5hbmFseXNpcyAoYW5hbHlzaXM6ICdjbGFzc2lmeScsIG1ldGhvZDogJ3VuaXF1ZSB2YWx1ZXMnKSBmaXJzdCBhbmQgdXNlIHRoZVxuICByZXR1cm5lZCB1bmlxdWVWYWx1ZXMgdmVyYmF0aW0uIE5FVkVSIGludmVudCBjYXRlZ29yeSBsYWJlbHMgZnJvbSB0aGUgZmllbGQgbmFtZSDigJRcbiAgdGhlIGNvbW1hbmQgcmVqZWN0cyB2YWx1ZXMgdGhhdCBkbyBub3QgZXhpc3QgaW4gdGhlIGRhdGEuXG4tIElmIHRoZSB1c2VyIGRvZXNuJ3Qgc3BlY2lmeSBjb2xvcnMsIG9taXQgY29sb3JCeS9jb2xvck1hcCDigJQga2VwbGVyLmdsIGFwcGxpZXMgaXRzIGRlZmF1bHQgY29sb3IgcmFuZ2UgYXV0b21hdGljYWxseVxuXG5Gb3IgZ2VvanNvbiBkYXRhc2V0czpcbi0gVXNlIGdlb21ldHJ5Q29sdW1uOiAnX2dlb2pzb24nIGFuZCBsYXllclR5cGU6ICdnZW9qc29uJyBldmVuIGZvciBwb2ludCBjb2xsZWN0aW9uc1xuYCxcbiAgICBtZXRhZGF0YToge3JlYWRPbmx5OiBmYWxzZSwgcmlza0xldmVsOiAnbWVkaXVtJywgaWRlbXBvdGVudDogZmFsc2V9LFxuICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICBkYXRhc2V0TmFtZTogelxuICAgICAgICAuc3RyaW5nKClcbiAgICAgICAgLmRlc2NyaWJlKCdUaGUgbmFtZSAobGFiZWwpIG9yIGlkIG9mIHRoZSBkYXRhc2V0LiBQcmVmZXIgdGhlIGxhYmVsIHdoZW4ga25vd24uJyksXG4gICAgICBsYXRpdHVkZUNvbHVtbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgbG9uZ2l0dWRlQ29sdW1uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICBsYXllck5hbWU6IHpcbiAgICAgICAgLnN0cmluZygpXG4gICAgICAgIC5vcHRpb25hbCgpXG4gICAgICAgIC5kZXNjcmliZSgnR2VuZXJhdGUgYSB1bmlxdWUgbmFtZSBmb3IgdGhlIGxheWVyIGJhc2VkIG9uIHRoZSBjb250ZXh0LicpLFxuICAgICAgbGF5ZXJUeXBlOiB6LmVudW0oW1xuICAgICAgICAncG9pbnQnLFxuICAgICAgICAnZmxvdycsXG4gICAgICAgICdmbG93RmllbGQnLFxuICAgICAgICAnYXJjJyxcbiAgICAgICAgJ2xpbmUnLFxuICAgICAgICAnZ3JpZCcsXG4gICAgICAgICdoZXhhZ29uJyxcbiAgICAgICAgJ2dlb2pzb24nLFxuICAgICAgICAnY2x1c3RlcicsXG4gICAgICAgICdoZWF0bWFwJyxcbiAgICAgICAgJ2gzJyxcbiAgICAgICAgJ3RyaXAnLFxuICAgICAgICAnczInXG4gICAgICBdKSxcbiAgICAgIGZsb3dGaWVsZDogelxuICAgICAgICAub2JqZWN0KHtcbiAgICAgICAgICBtb2RlOiB6LmVudW0oRkxPV19GSUVMRF9NT0RFUykub3B0aW9uYWwoKSxcbiAgICAgICAgICB1Q29sdW1uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgdkNvbHVtbjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgICAgIHNwZWVkQ29sdW1uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgZGlyZWN0aW9uQ29sdW1uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICAgICAgYWx0aXR1ZGVDb2x1bW46IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgICAgICBjb2xvckJ5U3BlZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKClcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbmFsKClcbiAgICAgICAgLmRlc2NyaWJlKFxuICAgICAgICAgICdGb3IgbGF5ZXJUeXBlIFwiZmxvd0ZpZWxkXCIgb25seTogaG93IHRoZSB2ZWN0b3IgZmllbGQgaXMgZW5jb2RlZC4gVGhlIG1vZGUgaXMgJyArXG4gICAgICAgICAgICAnaW5mZXJyZWQgZnJvbSB0aGUgY29sdW1ucyAodS92LCBzcGVlZC9kaXJlY3Rpb24sIG90aGVyd2lzZSBhbHRpdHVkZSk7IHRoZSAnICtcbiAgICAgICAgICAgICcqQ29sdW1uIGZpZWxkcyBuYW1lIHRoZSBjb2x1bW5zIHdoZW4gdGhleSBkaWZmZXIgZnJvbSB0aG9zZSBkZWZhdWx0cy4nXG4gICAgICAgICksXG4gICAgICBzaW1wbGVDb2xvcjogelxuICAgICAgICAuc3RyaW5nKClcbiAgICAgICAgLm9wdGlvbmFsKClcbiAgICAgICAgLmRlc2NyaWJlKFxuICAgICAgICAgICdUaGUgY29sb3Igb2YgdGhlIGxheWVyIGUuZy4gWzI1NSwgMCwgMF0uIE9ubHkgdXNlZCBmb3Igc2ltcGxlIG1hcCB2aXN1YWxpemF0aW9uIChubyBjb2xvckJ5LCBjb2xvclR5cGUsIGNvbG9yTWFwKS4nXG4gICAgICAgICksXG4gICAgICBjb2xvckJ5OiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICBjb2xvclR5cGU6IHouZW51bShbJ2JyZWFrcycsICd1bmlxdWUnXSkub3B0aW9uYWwoKSxcbiAgICAgIGNvdW50Q29sdW1uOiB6XG4gICAgICAgIC5zdHJpbmcoKVxuICAgICAgICAub3B0aW9uYWwoKVxuICAgICAgICAuZGVzY3JpYmUoXG4gICAgICAgICAgJ0ZvciBsYXllclR5cGUgXCJmbG93XCIgKGFuZCBvbmx5IGZsb3cpOiBhIG51bWVyaWMgY29sdW1uIHdob3NlIHZhbHVlIHdlaWdodHMgZWFjaCBmbG93IChmbG93IG1hZ25pdHVkZSkuIE9taXQgdG8gcmVuZGVyIGFsbCBmbG93cyBhdCB3ZWlnaHQgMS4nXG4gICAgICAgICksXG4gICAgICBjb2xvck1hcDogelxuICAgICAgICAuYXJyYXkoXG4gICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgdmFsdWU6IHoudW5pb24oW3ouc3RyaW5nKCksIHoubnVtYmVyKCksIHoubnVsbCgpXSksXG4gICAgICAgICAgICBjb2xvcjogei5zdHJpbmcoKVxuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICAgLm9wdGlvbmFsKClcbiAgICB9KSBhcyBhbnksXG4gICAgZXhlY3V0ZTogYXN5bmMgKF9leGVjQ3R4LCBpbnB1dCkgPT4ge1xuICAgICAgY29uc3QgYXJncyA9IChpbnB1dCA/PyB7fSkgYXMge1xuICAgICAgICBkYXRhc2V0TmFtZTogc3RyaW5nO1xuICAgICAgICBsYXllck5hbWU/OiBzdHJpbmc7XG4gICAgICAgIGxhdGl0dWRlQ29sdW1uPzogc3RyaW5nO1xuICAgICAgICBsb25naXR1ZGVDb2x1bW4/OiBzdHJpbmc7XG4gICAgICAgIGxheWVyVHlwZTogc3RyaW5nO1xuICAgICAgICBzaW1wbGVDb2xvcj86IHN0cmluZztcbiAgICAgICAgY29sb3JCeT86IHN0cmluZztcbiAgICAgICAgY29sb3JUeXBlPzogJ2JyZWFrcycgfCAndW5pcXVlJztcbiAgICAgICAgY29sb3JNYXA/OiBBcnJheTx7dmFsdWU6IHN0cmluZyB8IG51bWJlciB8IG51bGw7IGNvbG9yOiBzdHJpbmd9PjtcbiAgICAgICAgY291bnRDb2x1bW4/OiBzdHJpbmc7XG4gICAgICAgIGZsb3dGaWVsZD86IEZsb3dGaWVsZE9wdGlvbnM7XG4gICAgICB9O1xuICAgICAgY29uc3Qge1xuICAgICAgICBkYXRhc2V0TmFtZSxcbiAgICAgICAgbGF5ZXJOYW1lLFxuICAgICAgICBsYXRpdHVkZUNvbHVtbixcbiAgICAgICAgbG9uZ2l0dWRlQ29sdW1uLFxuICAgICAgICBsYXllclR5cGUsXG4gICAgICAgIHNpbXBsZUNvbG9yLFxuICAgICAgICBjb2xvckJ5LFxuICAgICAgICBjb2xvclR5cGUsXG4gICAgICAgIGNvbG9yTWFwLFxuICAgICAgICBjb3VudENvbHVtbixcbiAgICAgICAgZmxvd0ZpZWxkXG4gICAgICB9ID0gYXJncztcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIFJ1bnRpbWUgZ3VhcmQ6IHRoZSBicmlkZ2Uvd2ViTUNQIGNhbGwgZXhlY3V0ZSB3aXRob3V0IHpvZCBwYXJzaW5nLCBzb1xuICAgICAgICAvLyBhIG1pc3NpbmcvaW52YWxpZCBsYXllclR5cGUgbXVzdCBub3QgZmFsbCB0aHJvdWdoIHRvXG4gICAgICAgIC8vIGd1ZXNzRGVmYXVsdExheWVyJ3MgZmlyc3QtZGVmYXVsdC1sYXllciBmYWxsYmFjayAobGF5ZXJUeXBlIGlzXG4gICAgICAgIC8vIHJlcXVpcmVkIGJ5IHRoZSBjb21tYW5kIGNvbnRyYWN0KS5cbiAgICAgICAgY29uc3QgVkFMSURfTEFZRVJfVFlQRVMgPSBbXG4gICAgICAgICAgJ3BvaW50JyxcbiAgICAgICAgICAnZmxvdycsXG4gICAgICAgICAgJ2Zsb3dGaWVsZCcsXG4gICAgICAgICAgJ2FyYycsXG4gICAgICAgICAgJ2xpbmUnLFxuICAgICAgICAgICdncmlkJyxcbiAgICAgICAgICAnaGV4YWdvbicsXG4gICAgICAgICAgJ2dlb2pzb24nLFxuICAgICAgICAgICdjbHVzdGVyJyxcbiAgICAgICAgICAnaGVhdG1hcCcsXG4gICAgICAgICAgJ2gzJyxcbiAgICAgICAgICAndHJpcCcsXG4gICAgICAgICAgJ3MyJ1xuICAgICAgICBdO1xuICAgICAgICBpZiAoIWxheWVyVHlwZSB8fCAhVkFMSURfTEFZRVJfVFlQRVMuaW5jbHVkZXMobGF5ZXJUeXBlKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBJbnZhbGlkIGxheWVyVHlwZSBcIiR7U3RyaW5nKGxheWVyVHlwZSl9XCIuIE11c3QgYmUgb25lIG9mOiAke1ZBTElEX0xBWUVSX1RZUEVTLmpvaW4oXG4gICAgICAgICAgICAgICcsICdcbiAgICAgICAgICAgICl9LmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmlzU3RhdGUgPSBjdHguZ2V0VmlzU3RhdGUoKTtcbiAgICAgICAgY29uc3QgZGF0YXNldHM6IERhdGFzZXRzID0gdmlzU3RhdGUuZGF0YXNldHM7XG5cbiAgICAgICAgY29uc3QgZGF0YXNldElkID0gT2JqZWN0LmtleXMoZGF0YXNldHMpLmZpbmQoXG4gICAgICAgICAgZGF0YUlkID0+IGRhdGFzZXRzW2RhdGFJZF0ubGFiZWwgPT09IGRhdGFzZXROYW1lIHx8IGRhdGFJZCA9PT0gZGF0YXNldE5hbWVcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFkYXRhc2V0SWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERhdGFzZXQgJHtkYXRhc2V0TmFtZX0gbm90IGZvdW5kLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW2RhdGFzZXRJZF07XG4gICAgICAgIC8vIFRoZSBmbG93IGZpZWxkIGxheWVyIHJlc29sdmVzIGl0cyBvd24gY29sdW1ucyAocG9zaXRpb24gKyB2ZWN0b3IsIGluXG4gICAgICAgIC8vIG9uZSBvZiB0aHJlZSBtb2RlcyksIHNvIGl0IGRvZXMgbm90IGdvIHRocm91Z2ggZ3Vlc3NEZWZhdWx0TGF5ZXIg4oCUXG4gICAgICAgIC8vIHRoYXQgcGF0aCBvbmx5IGF1dG8tZGV0ZWN0cyB0aGUgdS92IGNhc2UgYW5kIHdvdWxkIGlnbm9yZSBleHBsaWNpdFxuICAgICAgICAvLyBjb2x1bW4gbmFtZXMuXG4gICAgICAgIGxldCBsYXllciA9XG4gICAgICAgICAgbGF5ZXJUeXBlID09PSAnZmxvd0ZpZWxkJ1xuICAgICAgICAgICAgPyBidWlsZEZsb3dGaWVsZExheWVyKGRhdGFzZXQsIHtsYXRpdHVkZUNvbHVtbiwgbG9uZ2l0dWRlQ29sdW1ufSwgZmxvd0ZpZWxkKVxuICAgICAgICAgICAgOiBndWVzc0RlZmF1bHRMYXllcihkYXRhc2V0LCBsYXllclR5cGUsIHtjb3VudENvbHVtbn0pO1xuXG4gICAgICAgIGlmICghbGF5ZXIpIHtcbiAgICAgICAgICBpZiAobGF5ZXJUeXBlID09PSAncG9pbnQnICYmIGxhdGl0dWRlQ29sdW1uICYmIGxvbmdpdHVkZUNvbHVtbikge1xuICAgICAgICAgICAgLy8gVmFsaWRhdGUgYm90aCBjb2x1bW5zIGV4aXN0IGJlZm9yZSBidWlsZGluZyB0aGUgY29uZmlnIOKAlFxuICAgICAgICAgICAgLy8gZ2V0Q29sdW1uRmllbGRJZHggcmV0dXJucyAtMSBmb3IgYSBtaXNzaW5nIGNvbHVtbiwgYW5kIGFuXG4gICAgICAgICAgICAvLyBpbnZhbGlkIGZpZWxkSWR4IHdvdWxkIGRpc3BhdGNoIGEgYnJva2VuIGxheWVyIGNvbmZpZyAoZW1wdHlcbiAgICAgICAgICAgIC8vIHJlbmRlciAvIGNvbmZ1c2luZyBydW50aW1lIGVycm9ycykuXG4gICAgICAgICAgICBjb25zdCBsYXRJZHggPSBkYXRhc2V0LmdldENvbHVtbkZpZWxkSWR4KGxhdGl0dWRlQ29sdW1uKTtcbiAgICAgICAgICAgIGNvbnN0IGxuZ0lkeCA9IGRhdGFzZXQuZ2V0Q29sdW1uRmllbGRJZHgobG9uZ2l0dWRlQ29sdW1uKTtcbiAgICAgICAgICAgIGlmIChsYXRJZHggPCAwIHx8IGxuZ0lkeCA8IDApIHtcbiAgICAgICAgICAgICAgY29uc3QgbWlzc2luZyA9IGxhdElkeCA8IDAgPyBsYXRpdHVkZUNvbHVtbiA6IGxvbmdpdHVkZUNvbHVtbjtcbiAgICAgICAgICAgICAgY29uc3QgYXZhaWxhYmxlID0gZGF0YXNldC5maWVsZHM/Lm1hcCgoZjogYW55KSA9PiBmLm5hbWUpLmpvaW4oJywgJykgPz8gJyc7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgQ29sdW1uIFwiJHttaXNzaW5nfVwiIG5vdCBmb3VuZCBpbiBkYXRhc2V0IFwiJHtkYXRhc2V0TmFtZX1cIi4gQXZhaWxhYmxlIGNvbHVtbnM6ICR7YXZhaWxhYmxlfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxheWVyID0ge1xuICAgICAgICAgICAgICBpZDogdW5pcXVlTGF5ZXJJZCgpLFxuICAgICAgICAgICAgICB0eXBlOiAncG9pbnQnLFxuICAgICAgICAgICAgICBjb25maWc6IHtcbiAgICAgICAgICAgICAgICBkYXRhSWQ6IGRhdGFzZXRJZCxcbiAgICAgICAgICAgICAgICBsYWJlbDogbGF5ZXJOYW1lIHx8IGAke2RhdGFzZXROYW1lfS0ke2xheWVyVHlwZX1gLFxuICAgICAgICAgICAgICAgIGNvbHVtbnM6IHtcbiAgICAgICAgICAgICAgICAgIGxhdDoge3ZhbHVlOiBsYXRpdHVkZUNvbHVtbiwgZmllbGRJZHg6IGxhdElkeH0sXG4gICAgICAgICAgICAgICAgICBsbmc6IHt2YWx1ZTogbG9uZ2l0dWRlQ29sdW1uLCBmaWVsZElkeDogbG5nSWR4fVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdmlzQ29uZmlnOiB7fVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGFzIGFueTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFsYXllcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBDb3VsZCBub3QgY3JlYXRlICR7bGF5ZXJUeXBlfSBsYXllci4gQ2hlY2sgdGhhdCB0aGUgZGF0YXNldCBoYXMgdGhlIHJlcXVpcmVkIGNvbHVtbnMuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXdMYXllciA9IGJ1aWxkTGF5ZXJDb25maWcobGF5ZXIsIGRhdGFzZXRJZCwgbGF5ZXJOYW1lLCBkYXRhc2V0TmFtZSwgbGF5ZXJUeXBlKTtcbiAgICAgICAgYXBwbHlDb2xvckNvbmZpZyhuZXdMYXllciwgZGF0YXNldCwge3NpbXBsZUNvbG9yLCBjb2xvckJ5LCBjb2xvclR5cGUsIGNvbG9yTWFwfSk7XG5cbiAgICAgICAgY3R4LmRpc3BhdGNoKGFkZExheWVyQWN0aW9uKG5ld0xheWVyLCBkYXRhc2V0SWQpKTtcblxuICAgICAgICAvLyBDZW50ZXIgdGhlIG1hcCBvbiB0aGUgbmV3IGxheWVyJ3MgZGF0YSBib3VuZHMuIGBhZGREYXRhVG9NYXBgIHdpdGhcbiAgICAgICAgLy8gYGF1dG9DcmVhdGVMYXllcnM6IGZhbHNlYCAodXNlZCBieSBgbWFwLmxvYWQtZGF0YWApIG5ldmVyIGZpdHMgYm91bmRzXG4gICAgICAgIC8vIGJlY2F1c2Ugbm8gbGF5ZXIgZXhpc3RzIGF0IGxvYWQgdGltZSwgYW5kIGBhZGRMYXllclVwZGF0ZXJgIGRvZXMgbm90XG4gICAgICAgIC8vIGNlbnRlciBlaXRoZXIg4oCUIHNvIGZpdCBoZXJlIGV4cGxpY2l0bHkuXG4gICAgICAgIGNvbnN0IGFkZGVkTGF5ZXIgPSBjdHguZ2V0VmlzU3RhdGUoKS5sYXllcnMuZmluZChsID0+IGwuaWQgPT09IG5ld0xheWVyLmlkKTtcbiAgICAgICAgY29uc3QgYm91bmRzID0gYWRkZWRMYXllciA/IGZpbmRNYXBCb3VuZHMoW2FkZGVkTGF5ZXJdKSA6IG51bGw7XG4gICAgICAgIGlmIChib3VuZHMpIHtcbiAgICAgICAgICBjdHguZGlzcGF0Y2goZml0Qm91bmRzKGJvdW5kcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGVtcG9yYWxGaWVsZHMgPSBkYXRhc2V0LmZpZWxkc1xuICAgICAgICAgID8uZmlsdGVyKChmOiBhbnkpID0+IGYudHlwZSA9PT0gJ3RpbWVzdGFtcCcgfHwgZi50eXBlID09PSAnZGF0ZScpXG4gICAgICAgICAgLm1hcCgoZjogYW55KSA9PiBmLm5hbWUpO1xuICAgICAgICBjb25zdCBoYXNUZW1wb3JhbEZpZWxkcyA9IHRlbXBvcmFsRmllbGRzICYmIHRlbXBvcmFsRmllbGRzLmxlbmd0aCA+IDA7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIGNvbW1hbmRJZDogYWRkTGF5ZXJDb21tYW5kSWQsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgZGV0YWlsczogYE1hcCBsYXllciAke25ld0xheWVyLmlkfSBoYXMgYmVlbiBhZGRlZCB0byB0aGUgbWFwLmAsXG4gICAgICAgICAgICBkYXRlVGltZUNvbHVtbnM6IGhhc1RlbXBvcmFsRmllbGRzID8gdGVtcG9yYWxGaWVsZHMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBkYXRlVGltZUhpbnQ6IGhhc1RlbXBvcmFsRmllbGRzXG4gICAgICAgICAgICAgID8gYERhdGVUaW1lIGNvbHVtbnMgZGV0ZWN0ZWQ6ICR7dGVtcG9yYWxGaWVsZHMuam9pbihcbiAgICAgICAgICAgICAgICAgICcsICdcbiAgICAgICAgICAgICAgICApfS4gWW91IGNhbiBjYWxsIGFkZFRpbWVGaWx0ZXIgd2l0aCBvbmUgb2YgdGhlc2UgY29sdW1ucyB0byBlbmFibGUgdGltZS1yYW5nZSBhbmltYXRpb24gb24gdGhlIG1hcC5gXG4gICAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICBjb21tYW5kSWQ6IGFkZExheWVyQ29tbWFuZElkLFxuICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdVbmtub3duIGVycm9yJyxcbiAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICBpbnN0cnVjdGlvbjpcbiAgICAgICAgICAgICAgJ1RyeSB0byBmaXggdGhlIGVycm9yLiBJZiB0aGUgZXJyb3IgcGVyc2lzdHMsIGFzayB0aGUgdXNlciB0byB0cnkgd2l0aCBkaWZmZXJlbnQgcGFyYW1ldGVycy4nXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUlBLElBQUFBLElBQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLFVBQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLE9BQUEsR0FBQUYsT0FBQTtBQUdBLElBQUFHLFNBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLFFBQUEsR0FBQUosT0FBQTtBQUF5RSxTQUFBSyxRQUFBQyxDQUFBLEVBQUFDLENBQUEsUUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLElBQUEsQ0FBQUosQ0FBQSxPQUFBRyxNQUFBLENBQUFFLHFCQUFBLFFBQUFDLENBQUEsR0FBQUgsTUFBQSxDQUFBRSxxQkFBQSxDQUFBTCxDQUFBLEdBQUFDLENBQUEsS0FBQUssQ0FBQSxHQUFBQSxDQUFBLENBQUFDLE1BQUEsV0FBQU4sQ0FBQSxXQUFBRSxNQUFBLENBQUFLLHdCQUFBLENBQUFSLENBQUEsRUFBQUMsQ0FBQSxFQUFBUSxVQUFBLE9B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
|