kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
206 lines (204 loc) • 31.2 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.AddLayerToolComponent = AddLayerToolComponent;
exports.addLayer = void 0;
exports.guessDefaultLayer = guessDefaultLayer;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _reactRedux = require("react-redux");
var _layers = require("@kepler.gl/layers");
var _reducers = require("@kepler.gl/reducers");
var _actions = require("@kepler.gl/actions");
var _utils = require("../utils");
var _utils2 = require("@openassistant/utils");
var _zod = require("zod");
var _react = require("react");
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; }
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
// Copyright contributors to the kepler.gl project
var addLayer = exports.addLayer = (0, _utils2.tool)({
description: 'add a kepler.gl map layer',
parameters: _zod.z.object({
datasetName: _zod.z.string().describe('The name of the dataset. Note: please do NOT use the datasetId.'),
fieldName: _zod.z.string(),
layerType: _zod.z["enum"](['point', 'arc', 'line', 'grid', 'hexagon', 'geojson', 'cluster', 'heatmap', 'h3', 'trip', 's2']),
colorScale: _zod.z["enum"](['quantile', 'quantize', 'ordinal', 'custom']).optional(),
customColorScale: _zod.z.array(_zod.z.number()).optional().describe('An array of numeric breakpoints used to define custom color intervals. Only applicable when colorScale is set to "custom"')
}),
execute: executeAddLayer,
component: AddLayerToolComponent
});
function isAddLayerArgs(args) {
return (0, _typeof2["default"])(args) === 'object' && args !== null && 'datasetName' in args && 'fieldName' in args && 'layerType' in args;
}
function isAddLayerFunctionContext(context) {
return context && typeof context.getDatasets === 'function';
}
function executeAddLayer(_x, _x2) {
return _executeAddLayer.apply(this, arguments);
}
function _executeAddLayer() {
_executeAddLayer = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(args, options) {
var datasetName, fieldName, layerType, _args$colorScale, colorScale, customColorScale, datasets, datasetId, dataset, field, layer, colorField, customColorRange, newColors, newLayer;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.prev = 0;
if (isAddLayerArgs(args)) {
_context.next = 3;
break;
}
throw new Error('Invalid addLayer arguments');
case 3:
if (isAddLayerFunctionContext(options.context)) {
_context.next = 5;
break;
}
throw new Error('Invalid addLayer context');
case 5:
datasetName = args.datasetName, fieldName = args.fieldName, layerType = args.layerType, _args$colorScale = args.colorScale, colorScale = _args$colorScale === void 0 ? 'quantile' : _args$colorScale, customColorScale = args.customColorScale;
datasets = options.context.getDatasets(); // check if dataset exists in kepler.gl
datasetId = Object.keys(datasets).find(function (dataId) {
return datasets[dataId].label === datasetName;
});
if (datasetId) {
_context.next = 10;
break;
}
throw new Error("Dataset ".concat(datasetName, " not found."));
case 10:
// check if field exists in the dataset
dataset = datasets[datasetId];
field = dataset.fields.find(function (f) {
return f.name === fieldName;
});
if (field) {
_context.next = 14;
break;
}
throw new Error("Field ".concat(fieldName, " not found."));
case 14:
if (['quantile', 'quantize', 'ordinal', 'custom'].includes(colorScale)) {
_context.next = 16;
break;
}
throw new Error("Invalid color scale: ".concat(colorScale, "."));
case 16:
if (!(colorScale === 'custom' && !customColorScale)) {
_context.next = 18;
break;
}
throw new Error('Custom color scale or breaks is required when colorScale is "custom".');
case 18:
// check if layerType is valid
layer = guessDefaultLayer(dataset, layerType);
if (layer) {
_context.next = 21;
break;
}
throw new Error("Invalid layer type: ".concat(layerType, "."));
case 21:
colorField = {
name: field.name,
type: field.type
}; // create custom colorRange if needed
customColorRange = layer.config.visConfig.colorRange;
if (colorScale === 'custom') {
newColors = (0, _utils.interpolateColor)(customColorRange.colors, customColorScale.length + 1);
customColorRange = _objectSpread(_objectSpread({}, customColorRange), {}, {
colors: newColors,
colorMap: newColors.map(function (color, index) {
return [customColorScale[index] || null, color];
})
});
}
// construct new layer config for addLayer() action
newLayer = {
id: layer.id,
type: layer.type,
config: _objectSpread(_objectSpread({}, layer.config), {}, {
dataId: datasetId,
label: "".concat(field.name, "-").concat(colorScale),
columns: Object.keys(layer.config.columns).reduce(function (acc, key) {
acc[key] = layer.config.columns[key].value;
return acc;
}, {}),
colorScale: colorScale,
colorField: colorField,
strokeColorScale: colorScale,
strokeColorField: colorField,
visConfig: _objectSpread(_objectSpread({}, layer.config.visConfig), {}, {
colorRange: customColorRange,
strokeColorRange: customColorRange
}, customColorScale ? {
colorDomain: customColorScale,
strokeColorDomain: customColorScale
} : {})
})
};
return _context.abrupt("return", {
llmResult: {
success: true,
layer: JSON.stringify(newLayer),
details: "map layer with ".concat(field.name, " and ").concat(colorScale, " color scale will be added to the map.")
},
additionalData: {
layer: newLayer,
datasetId: datasetId
}
});
case 28:
_context.prev = 28;
_context.t0 = _context["catch"](0);
return _context.abrupt("return", {
llmResult: {
success: false,
error: _context.t0 instanceof Error ? _context.t0.message : 'Unknown error',
instruction: 'Try to fix the error. If the error persists, pause the execution and ask the user to try with different prompt and context.'
}
});
case 31:
case "end":
return _context.stop();
}
}, _callee, null, [[0, 28]]);
}));
return _executeAddLayer.apply(this, arguments);
}
function guessDefaultLayer(dataset, layerType) {
// special case for hexagon layer, which could be implemented as findDefaultLayerProps() in hexagon-layer.tsx
if (layerType === 'hexagon') {
if (dataset.fieldPairs && dataset.fieldPairs.length > 0) {
var props = dataset.fieldPairs.map(function (fieldPair) {
return {
isVisible: true,
label: 'Hexbin',
columns: fieldPair.pair
};
});
var _layer = new _layers.LayerClasses.hexagon(props[0]);
return _layer;
}
}
var defaultLayers = (0, _reducers.findDefaultLayer)(dataset, _layers.LayerClasses);
var layer = defaultLayers.find(function (l) {
return l.type === layerType;
});
return layer || defaultLayers.length > 0 ? defaultLayers[0] : null;
}
function AddLayerToolComponent(_ref) {
var layer = _ref.layer,
datasetId = _ref.datasetId;
var dispatch = (0, _reactRedux.useDispatch)();
(0, _react.useEffect)(function () {
dispatch((0, _actions.addLayer)(layer, datasetId));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return null;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3RSZWR1eCIsInJlcXVpcmUiLCJfbGF5ZXJzIiwiX3JlZHVjZXJzIiwiX2FjdGlvbnMiLCJfdXRpbHMiLCJfdXRpbHMyIiwiX3pvZCIsIl9yZWFjdCIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiYWRkTGF5ZXIiLCJleHBvcnRzIiwidG9vbCIsImRlc2NyaXB0aW9uIiwicGFyYW1ldGVycyIsInoiLCJvYmplY3QiLCJkYXRhc2V0TmFtZSIsInN0cmluZyIsImRlc2NyaWJlIiwiZmllbGROYW1lIiwibGF5ZXJUeXBlIiwiY29sb3JTY2FsZSIsIm9wdGlvbmFsIiwiY3VzdG9tQ29sb3JTY2FsZSIsImFycmF5IiwibnVtYmVyIiwiZXhlY3V0ZSIsImV4ZWN1dGVBZGRMYXllciIsImNvbXBvbmVudCIsIkFkZExheWVyVG9vbENvbXBvbmVudCIsImlzQWRkTGF5ZXJBcmdzIiwiYXJncyIsIl90eXBlb2YyIiwiaXNBZGRMYXllckZ1bmN0aW9uQ29udGV4dCIsImNvbnRleHQiLCJnZXREYXRhc2V0cyIsIl94IiwiX3gyIiwiX2V4ZWN1dGVBZGRMYXllciIsIl9hc3luY1RvR2VuZXJhdG9yMiIsIl9yZWdlbmVyYXRvciIsIm1hcmsiLCJfY2FsbGVlIiwib3B0aW9ucyIsIl9hcmdzJGNvbG9yU2NhbGUiLCJkYXRhc2V0cyIsImRhdGFzZXRJZCIsImRhdGFzZXQiLCJmaWVsZCIsImxheWVyIiwiY29sb3JGaWVsZCIsImN1c3RvbUNvbG9yUmFuZ2UiLCJuZXdDb2xvcnMiLCJuZXdMYXllciIsIndyYXAiLCJfY2FsbGVlJCIsIl9jb250ZXh0IiwicHJldiIsIm5leHQiLCJFcnJvciIsImZpbmQiLCJkYXRhSWQiLCJsYWJlbCIsImNvbmNhdCIsImZpZWxkcyIsImYiLCJuYW1lIiwiaW5jbHVkZXMiLCJndWVzc0RlZmF1bHRMYXllciIsInR5cGUiLCJjb25maWciLCJ2aXNDb25maWciLCJjb2xvclJhbmdlIiwiaW50ZXJwb2xhdGVDb2xvciIsImNvbG9ycyIsImNvbG9yTWFwIiwibWFwIiwiY29sb3IiLCJpbmRleCIsImlkIiwiY29sdW1ucyIsInJlZHVjZSIsImFjYyIsImtleSIsInZhbHVlIiwic3Ryb2tlQ29sb3JTY2FsZSIsInN0cm9rZUNvbG9yRmllbGQiLCJzdHJva2VDb2xvclJhbmdlIiwiY29sb3JEb21haW4iLCJzdHJva2VDb2xvckRvbWFpbiIsImFicnVwdCIsImxsbVJlc3VsdCIsInN1Y2Nlc3MiLCJKU09OIiwic3RyaW5naWZ5IiwiZGV0YWlscyIsImFkZGl0aW9uYWxEYXRhIiwidDAiLCJlcnJvciIsIm1lc3NhZ2UiLCJpbnN0cnVjdGlvbiIsInN0b3AiLCJmaWVsZFBhaXJzIiwicHJvcHMiLCJmaWVsZFBhaXIiLCJpc1Zpc2libGUiLCJwYWlyIiwiTGF5ZXJDbGFzc2VzIiwiaGV4YWdvbiIsImRlZmF1bHRMYXllcnMiLCJmaW5kRGVmYXVsdExheWVyIiwibCIsIl9yZWYiLCJkaXNwYXRjaCIsInVzZURpc3BhdGNoIiwidXNlRWZmZWN0IiwiYWRkTGF5ZXJBY3Rpb24iXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdG9vbHMva2VwbGVyLXRvb2xzL2xheWVyLWNyZWF0aW9uLXRvb2wudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCB7dXNlRGlzcGF0Y2h9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7TGF5ZXJDbGFzc2VzfSBmcm9tICdAa2VwbGVyLmdsL2xheWVycyc7XG5pbXBvcnQgS2VwbGVyVGFibGUsIHtEYXRhc2V0c30gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge2ZpbmREZWZhdWx0TGF5ZXJ9IGZyb20gJ0BrZXBsZXIuZ2wvcmVkdWNlcnMnO1xuaW1wb3J0IHthZGRMYXllciBhcyBhZGRMYXllckFjdGlvbn0gZnJvbSAnQGtlcGxlci5nbC9hY3Rpb25zJztcbmltcG9ydCB7aW50ZXJwb2xhdGVDb2xvcn0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHt0b29sfSBmcm9tICdAb3BlbmFzc2lzdGFudC91dGlscyc7XG5pbXBvcnQge3p9IGZyb20gJ3pvZCc7XG5pbXBvcnQge3VzZUVmZmVjdH0gZnJvbSAncmVhY3QnO1xuXG5leHBvcnQgY29uc3QgYWRkTGF5ZXIgPSB0b29sPFxuICAvLyBwYXJhbWV0ZXJzXG4gIHouWm9kT2JqZWN0PHtcbiAgICBkYXRhc2V0TmFtZTogei5ab2RTdHJpbmc7XG4gICAgZmllbGROYW1lOiB6LlpvZFN0cmluZztcbiAgICBsYXllclR5cGU6IHouWm9kRW51bTxcbiAgICAgIFtcbiAgICAgICAgJ3BvaW50JyxcbiAgICAgICAgJ2FyYycsXG4gICAgICAgICdsaW5lJyxcbiAgICAgICAgJ2dyaWQnLFxuICAgICAgICAnaGV4YWdvbicsXG4gICAgICAgICdnZW9qc29uJyxcbiAgICAgICAgJ2NsdXN0ZXInLFxuICAgICAgICAnaGVhdG1hcCcsXG4gICAgICAgICdoMycsXG4gICAgICAgICd0cmlwJyxcbiAgICAgICAgJ3MyJ1xuICAgICAgXVxuICAgID47XG4gICAgY29sb3JTY2FsZTogei5ab2RPcHRpb25hbDx6LlpvZEVudW08WydxdWFudGlsZScsICdxdWFudGl6ZScsICdvcmRpbmFsJywgJ2N1c3RvbSddPj47XG4gICAgY3VzdG9tQ29sb3JTY2FsZTogei5ab2RPcHRpb25hbDx6LlpvZEFycmF5PHouWm9kTnVtYmVyPj47XG4gIH0+LFxuICAvLyByZXR1cm4gdHlwZVxuICBFeGVjdXRlQWRkTGF5ZXJSZXN1bHRbJ2xsbVJlc3VsdCddLFxuICAvLyBhZGRpdGlvbmFsIGRhdGFcbiAgRXhlY3V0ZUFkZExheWVyUmVzdWx0WydhZGRpdGlvbmFsRGF0YSddLFxuICAvLyBjb250ZXh0XG4gIEFkZExheWVyRnVuY3Rpb25Db250ZXh0XG4+KHtcbiAgZGVzY3JpcHRpb246ICdhZGQgYSBrZXBsZXIuZ2wgbWFwIGxheWVyJyxcbiAgcGFyYW1ldGVyczogei5vYmplY3Qoe1xuICAgIGRhdGFzZXROYW1lOiB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5kZXNjcmliZSgnVGhlIG5hbWUgb2YgdGhlIGRhdGFzZXQuIE5vdGU6IHBsZWFzZSBkbyBOT1QgdXNlIHRoZSBkYXRhc2V0SWQuJyksXG4gICAgZmllbGROYW1lOiB6LnN0cmluZygpLFxuICAgIGxheWVyVHlwZTogei5lbnVtKFtcbiAgICAgICdwb2ludCcsXG4gICAgICAnYXJjJyxcbiAgICAgICdsaW5lJyxcbiAgICAgICdncmlkJyxcbiAgICAgICdoZXhhZ29uJyxcbiAgICAgICdnZW9qc29uJyxcbiAgICAgICdjbHVzdGVyJyxcbiAgICAgICdoZWF0bWFwJyxcbiAgICAgICdoMycsXG4gICAgICAndHJpcCcsXG4gICAgICAnczInXG4gICAgXSksXG4gICAgY29sb3JTY2FsZTogei5lbnVtKFsncXVhbnRpbGUnLCAncXVhbnRpemUnLCAnb3JkaW5hbCcsICdjdXN0b20nXSkub3B0aW9uYWwoKSxcbiAgICBjdXN0b21Db2xvclNjYWxlOiB6XG4gICAgICAuYXJyYXkoei5udW1iZXIoKSlcbiAgICAgIC5vcHRpb25hbCgpXG4gICAgICAuZGVzY3JpYmUoXG4gICAgICAgICdBbiBhcnJheSBvZiBudW1lcmljIGJyZWFrcG9pbnRzIHVzZWQgdG8gZGVmaW5lIGN1c3RvbSBjb2xvciBpbnRlcnZhbHMuIE9ubHkgYXBwbGljYWJsZSB3aGVuIGNvbG9yU2NhbGUgaXMgc2V0IHRvIFwiY3VzdG9tXCInXG4gICAgICApXG4gIH0pLFxuICBleGVjdXRlOiBleGVjdXRlQWRkTGF5ZXIsXG4gIGNvbXBvbmVudDogQWRkTGF5ZXJUb29sQ29tcG9uZW50XG59KTtcblxuZXhwb3J0IHR5cGUgQWRkTGF5ZXJUb29sID0gdHlwZW9mIGFkZExheWVyO1xuXG50eXBlIEFkZExheWVyQXJncyA9IHtcbiAgZGF0YXNldE5hbWU6IHN0cmluZztcbiAgbGF5ZXJUeXBlOiBzdHJpbmc7XG4gIGZpZWxkTmFtZTogc3RyaW5nO1xuICBjb2xvclNjYWxlOiBzdHJpbmc7XG4gIGN1c3RvbUNvbG9yU2NhbGU6IEFycmF5PG51bWJlcj47XG59O1xuXG5mdW5jdGlvbiBpc0FkZExheWVyQXJncyhhcmdzOiBhbnkpOiBhcmdzIGlzIEFkZExheWVyQXJncyB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIGFyZ3MgPT09ICdvYmplY3QnICYmXG4gICAgYXJncyAhPT0gbnVsbCAmJlxuICAgICdkYXRhc2V0TmFtZScgaW4gYXJncyAmJlxuICAgICdmaWVsZE5hbWUnIGluIGFyZ3MgJiZcbiAgICAnbGF5ZXJUeXBlJyBpbiBhcmdzXG4gICk7XG59XG5cbnR5cGUgQWRkTGF5ZXJGdW5jdGlvbkNvbnRleHQgPSB7XG4gIGdldERhdGFzZXRzOiAoKSA9PiBEYXRhc2V0cztcbn07XG5cbmZ1bmN0aW9uIGlzQWRkTGF5ZXJGdW5jdGlvbkNvbnRleHQoY29udGV4dDogYW55KTogY29udGV4dCBpcyBBZGRMYXllckZ1bmN0aW9uQ29udGV4dCB7XG4gIHJldHVybiBjb250ZXh0ICYmIHR5cGVvZiBjb250ZXh0LmdldERhdGFzZXRzID09PSAnZnVuY3Rpb24nO1xufVxuXG50eXBlIEV4ZWN1dGVBZGRMYXllclJlc3VsdCA9IHtcbiAgbGxtUmVzdWx0OiB7XG4gICAgc3VjY2VzczogYm9vbGVhbjtcbiAgICBsYXllcj86IHN0cmluZztcbiAgICBkZXRhaWxzPzogc3RyaW5nO1xuICAgIGVycm9yPzogc3RyaW5nO1xuICAgIGluc3RydWN0aW9uPzogc3RyaW5nO1xuICB9O1xuICBhZGRpdGlvbmFsRGF0YT86IHtcbiAgICBsYXllcjogb2JqZWN0O1xuICAgIGRhdGFzZXRJZDogc3RyaW5nO1xuICB9O1xufTtcblxuYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUFkZExheWVyKGFyZ3MsIG9wdGlvbnMpOiBQcm9taXNlPEV4ZWN1dGVBZGRMYXllclJlc3VsdD4ge1xuICB0cnkge1xuICAgIGlmICghaXNBZGRMYXllckFyZ3MoYXJncykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhZGRMYXllciBhcmd1bWVudHMnKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzQWRkTGF5ZXJGdW5jdGlvbkNvbnRleHQob3B0aW9ucy5jb250ZXh0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGFkZExheWVyIGNvbnRleHQnKTtcbiAgICB9XG5cbiAgICBjb25zdCB7ZGF0YXNldE5hbWUsIGZpZWxkTmFtZSwgbGF5ZXJUeXBlLCBjb2xvclNjYWxlID0gJ3F1YW50aWxlJywgY3VzdG9tQ29sb3JTY2FsZX0gPSBhcmdzO1xuXG4gICAgY29uc3QgZGF0YXNldHMgPSBvcHRpb25zLmNvbnRleHQuZ2V0RGF0YXNldHMoKTtcblxuICAgIC8vIGNoZWNrIGlmIGRhdGFzZXQgZXhpc3RzIGluIGtlcGxlci5nbFxuICAgIGNvbnN0IGRhdGFzZXRJZCA9IE9iamVjdC5rZXlzKGRhdGFzZXRzKS5maW5kKGRhdGFJZCA9PiBkYXRhc2V0c1tkYXRhSWRdLmxhYmVsID09PSBkYXRhc2V0TmFtZSk7XG4gICAgaWYgKCFkYXRhc2V0SWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRGF0YXNldCAke2RhdGFzZXROYW1lfSBub3QgZm91bmQuYCk7XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgZmllbGQgZXhpc3RzIGluIHRoZSBkYXRhc2V0XG4gICAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW2RhdGFzZXRJZF07XG4gICAgY29uc3QgZmllbGQgPSBkYXRhc2V0LmZpZWxkcy5maW5kKGYgPT4gZi5uYW1lID09PSBmaWVsZE5hbWUpO1xuICAgIGlmICghZmllbGQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmllbGQgJHtmaWVsZE5hbWV9IG5vdCBmb3VuZC5gKTtcbiAgICB9XG5cbiAgICAvLyBjaGVjayBjb2xvclNjYWxlIGlzIHZhbGlkXG4gICAgaWYgKCFbJ3F1YW50aWxlJywgJ3F1YW50aXplJywgJ29yZGluYWwnLCAnY3VzdG9tJ10uaW5jbHVkZXMoY29sb3JTY2FsZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBjb2xvciBzY2FsZTogJHtjb2xvclNjYWxlfS5gKTtcbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiBjdXN0b21Db2xvclNjYWxlIGlzIGF2YWlsYWJsZVxuICAgIGlmIChjb2xvclNjYWxlID09PSAnY3VzdG9tJyAmJiAhY3VzdG9tQ29sb3JTY2FsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDdXN0b20gY29sb3Igc2NhbGUgb3IgYnJlYWtzIGlzIHJlcXVpcmVkIHdoZW4gY29sb3JTY2FsZSBpcyBcImN1c3RvbVwiLicpO1xuICAgIH1cblxuICAgIC8vIGNoZWNrIGlmIGxheWVyVHlwZSBpcyB2YWxpZFxuICAgIGNvbnN0IGxheWVyID0gZ3Vlc3NEZWZhdWx0TGF5ZXIoZGF0YXNldCwgbGF5ZXJUeXBlKTtcblxuICAgIGlmICghbGF5ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBsYXllciB0eXBlOiAke2xheWVyVHlwZX0uYCk7XG4gICAgfVxuXG4gICAgY29uc3QgY29sb3JGaWVsZCA9IHtcbiAgICAgIG5hbWU6IGZpZWxkLm5hbWUsXG4gICAgICB0eXBlOiBmaWVsZC50eXBlXG4gICAgfTtcblxuICAgIC8vIGNyZWF0ZSBjdXN0b20gY29sb3JSYW5nZSBpZiBuZWVkZWRcbiAgICBsZXQgY3VzdG9tQ29sb3JSYW5nZSA9IGxheWVyLmNvbmZpZy52aXNDb25maWcuY29sb3JSYW5nZTtcbiAgICBpZiAoY29sb3JTY2FsZSA9PT0gJ2N1c3RvbScpIHtcbiAgICAgIGNvbnN0IG5ld0NvbG9ycyA9IGludGVycG9sYXRlQ29sb3IoY3VzdG9tQ29sb3JSYW5nZS5jb2xvcnMsIGN1c3RvbUNvbG9yU2NhbGUubGVuZ3RoICsgMSk7XG4gICAgICBjdXN0b21Db2xvclJhbmdlID0ge1xuICAgICAgICAuLi5jdXN0b21Db2xvclJhbmdlLFxuICAgICAgICBjb2xvcnM6IG5ld0NvbG9ycyxcbiAgICAgICAgY29sb3JNYXA6IG5ld0NvbG9ycy5tYXAoKGNvbG9yLCBpbmRleCkgPT4gW2N1c3RvbUNvbG9yU2NhbGVbaW5kZXhdIHx8IG51bGwsIGNvbG9yXSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gY29uc3RydWN0IG5ldyBsYXllciBjb25maWcgZm9yIGFkZExheWVyKCkgYWN0aW9uXG4gICAgY29uc3QgbmV3TGF5ZXIgPSB7XG4gICAgICBpZDogbGF5ZXIuaWQsXG4gICAgICB0eXBlOiBsYXllci50eXBlLFxuICAgICAgY29uZmlnOiB7XG4gICAgICAgIC4uLmxheWVyLmNvbmZpZyxcbiAgICAgICAgZGF0YUlkOiBkYXRhc2V0SWQsXG4gICAgICAgIGxhYmVsOiBgJHtmaWVsZC5uYW1lfS0ke2NvbG9yU2NhbGV9YCxcbiAgICAgICAgY29sdW1uczogT2JqZWN0LmtleXMobGF5ZXIuY29uZmlnLmNvbHVtbnMpLnJlZHVjZSgoYWNjLCBrZXkpID0+IHtcbiAgICAgICAgICBhY2Nba2V5XSA9IGxheWVyLmNvbmZpZy5jb2x1bW5zW2tleV0udmFsdWU7XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwge30pLFxuICAgICAgICBjb2xvclNjYWxlLFxuICAgICAgICBjb2xvckZpZWxkLFxuICAgICAgICBzdHJva2VDb2xvclNjYWxlOiBjb2xvclNjYWxlLFxuICAgICAgICBzdHJva2VDb2xvckZpZWxkOiBjb2xvckZpZWxkLFxuICAgICAgICB2aXNDb25maWc6IHtcbiAgICAgICAgICAuLi5sYXllci5jb25maWcudmlzQ29uZmlnLFxuICAgICAgICAgIGNvbG9yUmFuZ2U6IGN1c3RvbUNvbG9yUmFuZ2UsXG4gICAgICAgICAgc3Ryb2tlQ29sb3JSYW5nZTogY3VzdG9tQ29sb3JSYW5nZSxcbiAgICAgICAgICAuLi4oY3VzdG9tQ29sb3JTY2FsZVxuICAgICAgICAgICAgPyB7Y29sb3JEb21haW46IGN1c3RvbUNvbG9yU2NhbGUsIHN0cm9rZUNvbG9yRG9tYWluOiBjdXN0b21Db2xvclNjYWxlfVxuICAgICAgICAgICAgOiB7fSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGxtUmVzdWx0OiB7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGxheWVyOiBKU09OLnN0cmluZ2lmeShuZXdMYXllciksXG4gICAgICAgIGRldGFpbHM6IGBtYXAgbGF5ZXIgd2l0aCAke2ZpZWxkLm5hbWV9IGFuZCAke2NvbG9yU2NhbGV9IGNvbG9yIHNjYWxlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIG1hcC5gXG4gICAgICB9LFxuICAgICAgYWRkaXRpb25hbERhdGE6IHtcbiAgICAgICAgbGF5ZXI6IG5ld0xheWVyLFxuICAgICAgICBkYXRhc2V0SWRcbiAgICAgIH1cbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB7XG4gICAgICBsbG1SZXN1bHQ6IHtcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdVbmtub3duIGVycm9yJyxcbiAgICAgICAgaW5zdHJ1Y3Rpb246XG4gICAgICAgICAgJ1RyeSB0byBmaXggdGhlIGVycm9yLiBJZiB0aGUgZXJyb3IgcGVyc2lzdHMsIHBhdXNlIHRoZSBleGVjdXRpb24gYW5kIGFzayB0aGUgdXNlciB0byB0cnkgd2l0aCBkaWZmZXJlbnQgcHJvbXB0IGFuZCBjb250ZXh0LidcbiAgICAgIH1cbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBndWVzc0RlZmF1bHRMYXllcihkYXRhc2V0OiBLZXBsZXJUYWJsZSwgbGF5ZXJUeXBlOiBzdHJpbmcpIHtcbiAgLy8gc3BlY2lhbCBjYXNlIGZvciBoZXhhZ29uIGxheWVyLCB3aGljaCBjb3VsZCBiZSBpbXBsZW1lbnRlZCBhcyBmaW5kRGVmYXVsdExheWVyUHJvcHMoKSBpbiBoZXhhZ29uLWxheWVyLnRzeFxuICBpZiAobGF5ZXJUeXBlID09PSAnaGV4YWdvbicpIHtcbiAgICBpZiAoZGF0YXNldC5maWVsZFBhaXJzICYmIGRhdGFzZXQuZmllbGRQYWlycy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBwcm9wcyA9IGRhdGFzZXQuZmllbGRQYWlycy5tYXAoZmllbGRQYWlyID0+ICh7XG4gICAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgbGFiZWw6ICdIZXhiaW4nLFxuICAgICAgICBjb2x1bW5zOiBmaWVsZFBhaXIucGFpclxuICAgICAgfSkpO1xuICAgICAgY29uc3QgbGF5ZXIgPSBuZXcgTGF5ZXJDbGFzc2VzLmhleGFnb24ocHJvcHNbMF0pO1xuICAgICAgcmV0dXJuIGxheWVyO1xuICAgIH1cbiAgfVxuICBjb25zdCBkZWZhdWx0TGF5ZXJzID0gZmluZERlZmF1bHRMYXllcihkYXRhc2V0LCBMYXllckNsYXNzZXMpO1xuICBjb25zdCBsYXllciA9IGRlZmF1bHRMYXllcnMuZmluZChsID0+IGwudHlwZSA9PT0gbGF5ZXJUeXBlKTtcbiAgcmV0dXJuIGxheWVyIHx8IGRlZmF1bHRMYXllcnMubGVuZ3RoID4gMCA/IGRlZmF1bHRMYXllcnNbMF0gOiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gQWRkTGF5ZXJUb29sQ29tcG9uZW50KHtsYXllciwgZGF0YXNldElkfSkge1xuICBjb25zdCBkaXNwYXRjaCA9IHVzZURpc3BhdGNoKCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBkaXNwYXRjaChhZGRMYXllckFjdGlvbihsYXllciwgZGF0YXNldElkKSk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCBbXSk7XG5cbiAgcmV0dXJuIG51bGw7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxXQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxTQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxRQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxNQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxPQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxJQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxNQUFBLEdBQUFQLE9BQUE7QUFBZ0MsU0FBQVEsUUFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEsR0FBQUMsTUFBQSxDQUFBQyxJQUFBLENBQUFKLENBQUEsT0FBQUcsTUFBQSxDQUFBRSxxQkFBQSxRQUFBQyxDQUFBLEdBQUFILE1BQUEsQ0FBQUUscUJBQUEsQ0FBQUwsQ0FBQSxHQUFBQyxDQUFBLEtBQUFLLENBQUEsR0FBQUEsQ0FBQSxDQUFBQyxNQUFBLFdBQUFOLENBQUEsV0FBQUUsTUFBQSxDQUFBSyx3QkFBQSxDQUFBUixDQUFBLEVBQUFDLENBQUEsRUFBQVEsVUFBQSxPQUFBUCxDQUFBLENBQUFRLElBQUEsQ0FBQUMsS0FBQSxDQUFBVCxDQUFBLEVBQUFJLENBQUEsWUFBQUosQ0FBQTtBQUFBLFNBQUFVLGNBQUFaLENBQUEsYUFBQUMsQ0FBQSxNQUFBQSxDQUFBLEdBQUFZLFNBQUEsQ0FBQUMsTUFBQSxFQUFBYixDQUFBLFVBQUFDLENBQUEsV0FBQVcsU0FBQSxDQUFBWixDQUFBLElBQUFZLFNBQUEsQ0FBQVosQ0FBQSxRQUFBQSxDQUFBLE9BQUFGLE9BQUEsQ0FBQUksTUFBQSxDQUFBRCxDQUFBLE9BQUFhLE9BQUEs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
;