UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

399 lines (385 loc) 52.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getDatasetContext = getDatasetContext; exports.getGeometriesFromDataset = getGeometriesFromDataset; exports.getValuesFromDataset = getValuesFromDataset; exports.getValuesFromVectorTileLayer = getValuesFromVectorTileLayer; exports.highlightRows = highlightRows; exports.highlightRowsByColumnValues = highlightRowsByColumnValues; exports.interpolateColor = interpolateColor; exports.saveAsDataset = saveAsDataset; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _colorInterpolate = _interopRequireDefault(require("color-interpolate")); var _constants = require("@kepler.gl/constants"); function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project /** * Interpolate the colors from the original colors with the given number of colors * @param originalColors The original colors * @param numberOfColors The number of colors * @returns The interpolated colors */ function interpolateColor(originalColors, numberOfColors) { if (originalColors.length === numberOfColors) { return originalColors; } var interp = (0, _colorInterpolate["default"])(originalColors); var colors = Array.from({ length: numberOfColors }, function (_, j) { return interp(j / (numberOfColors - 1)); }); // convert colors from 'rgb(255, 255, 255)' to '#ffffff' var hexColors = colors.map(function (color) { var rgb = color.match(/\d+/g); return "#".concat(rgb === null || rgb === void 0 ? void 0 : rgb.map(function (c) { return parseInt(c).toString(16).padStart(2, '0'); }).join('')); }); return hexColors; } /** * Get the values from a dataset for a variable * @param datasets * @param datasetName * @param variableName * @returns {number[]} */ function getValuesFromDataset(datasets, layers, datasetName, variableName) { // find which dataset has the variableName var datasetId = Object.keys(datasets).find(function (dataId) { return datasets[dataId].label === datasetName; }); if (!datasetId) { throw new Error("Dataset ".concat(datasetName, " not found")); } var dataset = datasets[datasetId]; if (dataset) { // check if field exists var field = dataset.fields.find(function (field) { return field.name === variableName; }); if (!field) { throw new Error("Field ".concat(variableName, " not found in dataset ").concat(datasetName)); } // for vector-tile, getting values from layerData if (dataset.type === 'vector-tile') { // get field from dataset var _field = dataset.fields.find(function (field) { return field.name === variableName; }); if (_field) { return getValuesFromVectorTileLayer(datasetId, layers, _field); } } return Array.from({ length: dataset.length }, function (_, i) { return dataset.getValue(variableName, i); }); } return []; } function isVectorTileLayer(layer) { return layer.type === _constants.LAYER_TYPES.vectorTile; } function getValuesFromVectorTileLayer(datasetId, layers, field) { // get the index of the layer var layerIndex = layers.findIndex(function (layer) { return layer.config.dataId === datasetId; }); if (layerIndex === -1) return []; var layer = layers[layerIndex]; if (!isVectorTileLayer(layer)) return []; var accessor = layer.accessRowValue(field); var values = []; // @ts-expect-error TODO fix this later in the vector-tile layer var _iterator = _createForOfIteratorHelper(layer.tileDataset.tileSet), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var row = _step.value; var value = accessor(field, row); if (value === null) break; values.push(value); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return values; } /** * Highlight the rows in a dataset * @param datasets The kepler.gl datasets * @param layers The kepler.gl layers * @param datasetName The name of the dataset * @param selectedRowIndices The indices of the rows to highlight * @param layerSetIsValid The function to set the layer validity */ function highlightRows(datasets, layers, datasetName, selectedRowIndices, layerSetIsValid) { // update the filteredIndex in the dataset var datasetId = Object.keys(datasets).find(function (dataId) { return datasets[dataId].label === datasetName; }); if (!datasetId) return; var dataset = datasets[datasetId]; if (dataset) { dataset.filteredIndex = selectedRowIndices.length === 0 ? dataset.allIndexes : selectedRowIndices; // get all layers that use this dataset var selectLayers = layers.filter(function (layer) { return layer.config.dataId === dataset.id; }); selectLayers.forEach(function (layer) { layer.formatLayerData(datasets); // trigger a re-render using layerSetIsValid() to update the top layer layerSetIsValid(layer, true); }); } } /** * Get the dataset context, which is used to provide the dataset information to the AI assistant * @param datasets The kepler.gl datasets * @param layers The kepler.gl layers * @returns The dataset context */ function getDatasetContext(datasets, layers) { if (!datasets || !layers) return ''; var context = 'Please ONLY use the following datasets and layers to answer the user question:'; var dataMeta = Object.values(datasets).map(function (dataset) { return { datasetName: dataset.label, datasetId: dataset.id, fields: dataset.fields.map(function (field) { return (0, _defineProperty2["default"])({}, field.name, field.type); }), layers: layers.filter(function (layer) { return layer.config.dataId === dataset.id; }).map(function (layer) { return { id: layer.id, label: layer.config.label, type: layer.type, geometryMode: layer.config.columnMode, // get the valid geometry columns as string geometryColumns: Object.fromEntries(Object.entries(layer.config.columns).filter(function (_ref2) { var _ref3 = (0, _slicedToArray2["default"])(_ref2, 2), value = _ref3[1]; return value !== null; }).map(function (_ref4) { var _ref5 = (0, _slicedToArray2["default"])(_ref4, 2), key = _ref5[0], value = _ref5[1]; return [key, (0, _typeof2["default"])(value) === 'object' && value !== null ? Object.fromEntries(Object.entries(value).filter(function (_ref6) { var _ref7 = (0, _slicedToArray2["default"])(_ref6, 2), v = _ref7[1]; return v !== null; })) : value]; })) }; }) }; }); return "".concat(context, "\n").concat(JSON.stringify(dataMeta)); } /** * Get the geometries from a dataset * @param datasets The kepler.gl datasets * @param layers The kepler.gl layers * @param layerData The layer data * @param datasetName The name of the dataset * @returns The geometries */ function getGeometriesFromDataset(datasets, layers, layerData, datasetName) { var datasetId = Object.keys(datasets).find(function (dataId) { return datasets[dataId].label === datasetName; }); if (!datasetId) { return []; } var dataset = datasets[datasetId]; // if layer is vector-tile, get the geometries from the layer if (dataset.type === 'vector-tile') { // find the vector-tile layer var selected = layers.filter(function (layer) { return layer.config.dataId === dataset.id; }); var layer = selected.find(function (layer) { return layer.type === _constants.LAYER_TYPES.vectorTile; }); if (!layer) return []; var geometries = []; // @ts-expect-error TODO fix this later in the vector-tile layer var _iterator2 = _createForOfIteratorHelper(layer.tileDataset.tileSet), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var row = _step2.value; geometries.push(row); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } return geometries; } // for non-vector-tile dataset, get the geometries from the possible layer var selectedLayers = layers.filter(function (layer) { return layer.config.dataId === dataset.id; }); if (selectedLayers.length === 0) return []; // find geojson layer, then point layer, then other layers var geojsonLayer = selectedLayers.find(function (layer) { return layer.type === _constants.LAYER_TYPES.geojson; }); var pointLayer = selectedLayers.find(function (layer) { return layer.type === _constants.LAYER_TYPES.point; }); var otherLayers = selectedLayers.filter(function (layer) { return layer.type !== _constants.LAYER_TYPES.geojson && layer.type !== _constants.LAYER_TYPES.point; }); var validLayer = geojsonLayer || pointLayer || otherLayers[0]; if (validLayer) { var layerIndex = layers.findIndex(function (layer) { return layer.id === validLayer.id; }); var _geometries = layerData[layerIndex]; return _geometries.data; } return []; } /** * Save the data as a new dataset by joining it with the left dataset * @param datasets The kepler.gl datasets * @param datasetName The name of the left dataset * @param data The data to save * @param addDataToMap The function to add the data to the map */ function saveAsDataset(datasets, layers, datasetName, newDatasetName, data) { // find datasetId from datasets var datasetId = Object.keys(datasets).find(function (dataId) { return datasets[dataId].label === datasetName; }); if (!datasetId) return; // check if newDatasetName already exists if (Object.keys(datasets).includes(newDatasetName)) return; // Save the data as a new dataset by joining it with the left dataset var leftDataset = datasets[datasetId]; var numRows = leftDataset.length; var geometries; if (leftDataset.type === 'vector-tile') { // we need to get geometries from the vector-tile layer geometries = getFeaturesFromVectorTile(leftDataset, layers) || []; numRows = geometries.length; } var fields = [].concat((0, _toConsumableArray2["default"])(Object.keys(data).map(function (fieldName, index) { return { name: fieldName, id: "".concat(fieldName, "_").concat(index), displayName: fieldName, type: determineFieldType(data[fieldName][0]) }; })), (0, _toConsumableArray2["default"])(leftDataset.fields.map(function (field, index) { return { name: field.name, id: field.id || "".concat(field.name, "_").concat(index), displayName: field.displayName, type: field.type }; })), (0, _toConsumableArray2["default"])(leftDataset.type === 'vector-tile' ? [{ name: '_geojson', id: '_geojson', displayName: '_geojson', type: 'geojson' }] : [])); // Pre-calculate data values array var dataValues = Object.values(data); var rows = Array(numRows).fill(null).map(function (_, rowIdx) { return [].concat((0, _toConsumableArray2["default"])(dataValues.map(function (col) { return col[rowIdx]; })), (0, _toConsumableArray2["default"])(leftDataset.fields.map(function (field) { var _geometries$rowIdx$pr; return leftDataset.type === 'vector-tile' ? (_geometries$rowIdx$pr = geometries[rowIdx].properties) === null || _geometries$rowIdx$pr === void 0 ? void 0 : _geometries$rowIdx$pr[field.name] : leftDataset.getValue(field.name, rowIdx); })), (0, _toConsumableArray2["default"])(leftDataset.type === 'vector-tile' ? [geometries[rowIdx]] : [])); }); // create new dataset var newDataset = { info: { id: newDatasetName, label: newDatasetName }, data: { fields: fields, rows: rows } }; return newDataset; } /** * Helper function to determine field type * @param value The value to determine the field type * @returns The field type */ function determineFieldType(value) { return typeof value === 'number' ? Number.isInteger(value) ? _constants.ALL_FIELD_TYPES.integer : _constants.ALL_FIELD_TYPES.real : _constants.ALL_FIELD_TYPES.string; } function highlightRowsByColumnValues(datasets, layers, datasetName, columnName, selectedValues, layerSetIsValid) { var datasetId = Object.keys(datasets).find(function (dataId) { return datasets[dataId].label === datasetName; }); if (!datasetId) return; var dataset = datasets[datasetId]; if (dataset) { // get the values of the column var values = Array.from({ length: dataset.length }, function (_, i) { return dataset.getValue(columnName, i); }); // create a dict using the values var valueDict = values.reduce(function (acc, value, index) { acc[value] = index; return acc; }, {}); // need to fix the type error of value here var selectedIndices = selectedValues.map(function (value) { return valueDict[value]; }); // highlight the rows highlightRows(datasets, layers, datasetName, selectedIndices, layerSetIsValid); } } function getFeaturesFromVectorTile(leftDataset, layers) { var layerIndex = layers.findIndex(function (layer) { return layer.config.dataId === leftDataset.id; }); if (layerIndex === -1) return; var layer = layers[layerIndex]; if (!isVectorTileLayer(layer)) return; var features = []; // @ts-expect-error TODO fix this later in the vector-tile layer var _iterator3 = _createForOfIteratorHelper(layer.tileDataset.tileSet), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var row = _step3.value; features.push(row); } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } return features; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29sb3JJbnRlcnBvbGF0ZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2NvbnN0YW50cyIsIl9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyIiwiciIsImUiLCJ0IiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJBcnJheSIsImlzQXJyYXkiLCJfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkiLCJsZW5ndGgiLCJfbiIsIkYiLCJzIiwibiIsImRvbmUiLCJ2YWx1ZSIsImYiLCJUeXBlRXJyb3IiLCJvIiwiYSIsInUiLCJjYWxsIiwibmV4dCIsIl9hcnJheUxpa2VUb0FycmF5IiwidG9TdHJpbmciLCJzbGljZSIsImNvbnN0cnVjdG9yIiwibmFtZSIsImZyb20iLCJ0ZXN0IiwiaW50ZXJwb2xhdGVDb2xvciIsIm9yaWdpbmFsQ29sb3JzIiwibnVtYmVyT2ZDb2xvcnMiLCJpbnRlcnAiLCJpbnRlcnBvbGF0ZSIsImNvbG9ycyIsIl8iLCJqIiwiaGV4Q29sb3JzIiwibWFwIiwiY29sb3IiLCJyZ2IiLCJtYXRjaCIsImNvbmNhdCIsImMiLCJwYXJzZUludCIsInBhZFN0YXJ0Iiwiam9pbiIsImdldFZhbHVlc0Zyb21EYXRhc2V0IiwiZGF0YXNldHMiLCJsYXllcnMiLCJkYXRhc2V0TmFtZSIsInZhcmlhYmxlTmFtZSIsImRhdGFzZXRJZCIsIk9iamVjdCIsImtleXMiLCJmaW5kIiwiZGF0YUlkIiwibGFiZWwiLCJFcnJvciIsImRhdGFzZXQiLCJmaWVsZCIsImZpZWxkcyIsInR5cGUiLCJnZXRWYWx1ZXNGcm9tVmVjdG9yVGlsZUxheWVyIiwiaSIsImdldFZhbHVlIiwiaXNWZWN0b3JUaWxlTGF5ZXIiLCJsYXllciIsIkxBWUVSX1RZUEVTIiwidmVjdG9yVGlsZSIsImxheWVySW5kZXgiLCJmaW5kSW5kZXgiLCJjb25maWciLCJhY2Nlc3NvciIsImFjY2Vzc1Jvd1ZhbHVlIiwidmFsdWVzIiwiX2l0ZXJhdG9yIiwidGlsZURhdGFzZXQiLCJ0aWxlU2V0IiwiX3N0ZXAiLCJyb3ciLCJwdXNoIiwiZXJyIiwiaGlnaGxpZ2h0Um93cyIsInNlbGVjdGVkUm93SW5kaWNlcyIsImxheWVyU2V0SXNWYWxpZCIsImZpbHRlcmVkSW5kZXgiLCJhbGxJbmRleGVzIiwic2VsZWN0TGF5ZXJzIiwiZmlsdGVyIiwiaWQiLCJmb3JFYWNoIiwiZm9ybWF0TGF5ZXJEYXRhIiwiZ2V0RGF0YXNldENvbnRleHQiLCJjb250ZXh0IiwiZGF0YU1ldGEiLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2VvbWV0cnlNb2RlIiwiY29sdW1uTW9kZSIsImdlb21ldHJ5Q29sdW1ucyIsImZyb21FbnRyaWVzIiwiZW50cmllcyIsImNvbHVtbnMiLCJfcmVmMiIsIl9yZWYzIiwiX3NsaWNlZFRvQXJyYXkyIiwiX3JlZjQiLCJfcmVmNSIsImtleSIsIl90eXBlb2YyIiwiX3JlZjYiLCJfcmVmNyIsInYiLCJKU09OIiwic3RyaW5naWZ5IiwiZ2V0R2VvbWV0cmllc0Zyb21EYXRhc2V0IiwibGF5ZXJEYXRhIiwic2VsZWN0ZWQiLCJnZW9tZXRyaWVzIiwiX2l0ZXJhdG9yMiIsIl9zdGVwMiIsInNlbGVjdGVkTGF5ZXJzIiwiZ2VvanNvbkxheWVyIiwiZ2VvanNvbiIsInBvaW50TGF5ZXIiLCJwb2ludCIsIm90aGVyTGF5ZXJzIiwidmFsaWRMYXllciIsImRhdGEiLCJzYXZlQXNEYXRhc2V0IiwibmV3RGF0YXNldE5hbWUiLCJpbmNsdWRlcyIsImxlZnREYXRhc2V0IiwibnVtUm93cyIsImdldEZlYXR1cmVzRnJvbVZlY3RvclRpbGUiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwiZmllbGROYW1lIiwiaW5kZXgiLCJkaXNwbGF5TmFtZSIsImRldGVybWluZUZpZWxkVHlwZSIsImRhdGFWYWx1ZXMiLCJyb3dzIiwiZmlsbCIsInJvd0lkeCIsImNvbCIsIl9nZW9tZXRyaWVzJHJvd0lkeCRwciIsInByb3BlcnRpZXMiLCJuZXdEYXRhc2V0IiwiaW5mbyIsIk51bWJlciIsImlzSW50ZWdlciIsIkFMTF9GSUVMRF9UWVBFUyIsImludGVnZXIiLCJyZWFsIiwic3RyaW5nIiwiaGlnaGxpZ2h0Um93c0J5Q29sdW1uVmFsdWVzIiwiY29sdW1uTmFtZSIsInNlbGVjdGVkVmFsdWVzIiwidmFsdWVEaWN0IiwicmVkdWNlIiwiYWNjIiwic2VsZWN0ZWRJbmRpY2VzIiwiZmVhdHVyZXMiLCJfaXRlcmF0b3IzIiwiX3N0ZXAzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rvb2xzL3V0aWxzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCBpbnRlcnBvbGF0ZSBmcm9tICdjb2xvci1pbnRlcnBvbGF0ZSc7XG5pbXBvcnQge0ZlYXR1cmV9IGZyb20gJ2dlb2pzb24nO1xuaW1wb3J0IHtMYXllciwgVmVjdG9yVGlsZUxheWVyfSBmcm9tICdAa2VwbGVyLmdsL2xheWVycyc7XG5pbXBvcnQge0RhdGFzZXRzLCBLZXBsZXJUYWJsZX0gZnJvbSAnQGtlcGxlci5nbC90YWJsZSc7XG5pbXBvcnQge1NwYXRpYWxKb2luR2VvbWV0cmllc30gZnJvbSAnQG9wZW5hc3Npc3RhbnQvZ2VvZGEnO1xuaW1wb3J0IHtBTExfRklFTERfVFlQRVMsIExBWUVSX1RZUEVTfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5pbXBvcnQge0ZpZWxkLCBQcm90b0RhdGFzZXQsIFByb3RvRGF0YXNldEZpZWxkfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcblxuLyoqXG4gKiBJbnRlcnBvbGF0ZSB0aGUgY29sb3JzIGZyb20gdGhlIG9yaWdpbmFsIGNvbG9ycyB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YgY29sb3JzXG4gKiBAcGFyYW0gb3JpZ2luYWxDb2xvcnMgVGhlIG9yaWdpbmFsIGNvbG9yc1xuICogQHBhcmFtIG51bWJlck9mQ29sb3JzIFRoZSBudW1iZXIgb2YgY29sb3JzXG4gKiBAcmV0dXJucyBUaGUgaW50ZXJwb2xhdGVkIGNvbG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJwb2xhdGVDb2xvcihvcmlnaW5hbENvbG9yczogc3RyaW5nW10sIG51bWJlck9mQ29sb3JzOiBudW1iZXIpIHtcbiAgaWYgKG9yaWdpbmFsQ29sb3JzLmxlbmd0aCA9PT0gbnVtYmVyT2ZDb2xvcnMpIHtcbiAgICByZXR1cm4gb3JpZ2luYWxDb2xvcnM7XG4gIH1cbiAgY29uc3QgaW50ZXJwID0gaW50ZXJwb2xhdGUob3JpZ2luYWxDb2xvcnMpO1xuICBjb25zdCBjb2xvcnMgPSBBcnJheS5mcm9tKHtsZW5ndGg6IG51bWJlck9mQ29sb3JzfSwgKF8sIGopID0+IGludGVycChqIC8gKG51bWJlck9mQ29sb3JzIC0gMSkpKTtcbiAgLy8gY29udmVydCBjb2xvcnMgZnJvbSAncmdiKDI1NSwgMjU1LCAyNTUpJyB0byAnI2ZmZmZmZidcbiAgY29uc3QgaGV4Q29sb3JzID0gY29sb3JzLm1hcChjb2xvciA9PiB7XG4gICAgY29uc3QgcmdiID0gY29sb3IubWF0Y2goL1xcZCsvZyk7XG4gICAgcmV0dXJuIGAjJHtyZ2I/Lm1hcChjID0+IHBhcnNlSW50KGMpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCAnMCcpKS5qb2luKCcnKX1gO1xuICB9KTtcbiAgcmV0dXJuIGhleENvbG9ycztcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHZhbHVlcyBmcm9tIGEgZGF0YXNldCBmb3IgYSB2YXJpYWJsZVxuICogQHBhcmFtIGRhdGFzZXRzXG4gKiBAcGFyYW0gZGF0YXNldE5hbWVcbiAqIEBwYXJhbSB2YXJpYWJsZU5hbWVcbiAqIEByZXR1cm5zIHtudW1iZXJbXX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlc0Zyb21EYXRhc2V0KFxuICBkYXRhc2V0czogRGF0YXNldHMsXG4gIGxheWVyczogTGF5ZXJbXSxcbiAgZGF0YXNldE5hbWU6IHN0cmluZyxcbiAgdmFyaWFibGVOYW1lOiBzdHJpbmdcbik6IHVua25vd25bXSB7XG4gIC8vIGZpbmQgd2hpY2ggZGF0YXNldCBoYXMgdGhlIHZhcmlhYmxlTmFtZVxuICBjb25zdCBkYXRhc2V0SWQgPSBPYmplY3Qua2V5cyhkYXRhc2V0cykuZmluZChkYXRhSWQgPT4gZGF0YXNldHNbZGF0YUlkXS5sYWJlbCA9PT0gZGF0YXNldE5hbWUpO1xuICBpZiAoIWRhdGFzZXRJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRGF0YXNldCAke2RhdGFzZXROYW1lfSBub3QgZm91bmRgKTtcbiAgfVxuICBjb25zdCBkYXRhc2V0ID0gZGF0YXNldHNbZGF0YXNldElkXTtcbiAgaWYgKGRhdGFzZXQpIHtcbiAgICAvLyBjaGVjayBpZiBmaWVsZCBleGlzdHNcbiAgICBjb25zdCBmaWVsZCA9IGRhdGFzZXQuZmllbGRzLmZpbmQoZmllbGQgPT4gZmllbGQubmFtZSA9PT0gdmFyaWFibGVOYW1lKTtcbiAgICBpZiAoIWZpZWxkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpZWxkICR7dmFyaWFibGVOYW1lfSBub3QgZm91bmQgaW4gZGF0YXNldCAke2RhdGFzZXROYW1lfWApO1xuICAgIH1cbiAgICAvLyBmb3IgdmVjdG9yLXRpbGUsIGdldHRpbmcgdmFsdWVzIGZyb20gbGF5ZXJEYXRhXG4gICAgaWYgKGRhdGFzZXQudHlwZSA9PT0gJ3ZlY3Rvci10aWxlJykge1xuICAgICAgLy8gZ2V0IGZpZWxkIGZyb20gZGF0YXNldFxuICAgICAgY29uc3QgZmllbGQgPSBkYXRhc2V0LmZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLm5hbWUgPT09IHZhcmlhYmxlTmFtZSk7XG4gICAgICBpZiAoZmllbGQpIHtcbiAgICAgICAgcmV0dXJuIGdldFZhbHVlc0Zyb21WZWN0b3JUaWxlTGF5ZXIoZGF0YXNldElkLCBsYXllcnMsIGZpZWxkKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIEFycmF5LmZyb20oe2xlbmd0aDogZGF0YXNldC5sZW5ndGh9LCAoXywgaSkgPT4gZGF0YXNldC5nZXRWYWx1ZSh2YXJpYWJsZU5hbWUsIGkpKTtcbiAgfVxuICByZXR1cm4gW107XG59XG5cbmZ1bmN0aW9uIGlzVmVjdG9yVGlsZUxheWVyKGxheWVyOiBMYXllcik6IGxheWVyIGlzIFZlY3RvclRpbGVMYXllciB7XG4gIHJldHVybiBsYXllci50eXBlID09PSBMQVlFUl9UWVBFUy52ZWN0b3JUaWxlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsdWVzRnJvbVZlY3RvclRpbGVMYXllcihkYXRhc2V0SWQ6IHN0cmluZywgbGF5ZXJzOiBMYXllcltdLCBmaWVsZDogRmllbGQpIHtcbiAgLy8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgbGF5ZXJcbiAgY29uc3QgbGF5ZXJJbmRleCA9IGxheWVycy5maW5kSW5kZXgobGF5ZXIgPT4gbGF5ZXIuY29uZmlnLmRhdGFJZCA9PT0gZGF0YXNldElkKTtcbiAgaWYgKGxheWVySW5kZXggPT09IC0xKSByZXR1cm4gW107XG4gIGNvbnN0IGxheWVyID0gbGF5ZXJzW2xheWVySW5kZXhdO1xuICBpZiAoIWlzVmVjdG9yVGlsZUxheWVyKGxheWVyKSkgcmV0dXJuIFtdO1xuICBjb25zdCBhY2Nlc3NvciA9IGxheWVyLmFjY2Vzc1Jvd1ZhbHVlKGZpZWxkKTtcbiAgY29uc3QgdmFsdWVzOiB1bmtub3duW10gPSBbXTtcbiAgLy8gQHRzLWV4cGVjdC1lcnJvciBUT0RPIGZpeCB0aGlzIGxhdGVyIGluIHRoZSB2ZWN0b3ItdGlsZSBsYXllclxuICBmb3IgKGNvbnN0IHJvdyBvZiBsYXllci50aWxlRGF0YXNldC50aWxlU2V0KSB7XG4gICAgY29uc3QgdmFsdWUgPSBhY2Nlc3NvcihmaWVsZCwgcm93KTtcbiAgICBpZiAodmFsdWUgPT09IG51bGwpIGJyZWFrO1xuICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgfVxuICByZXR1cm4gdmFsdWVzO1xufVxuXG4vKipcbiAqIEhpZ2hsaWdodCB0aGUgcm93cyBpbiBhIGRhdGFzZXRcbiAqIEBwYXJhbSBkYXRhc2V0cyBUaGUga2VwbGVyLmdsIGRhdGFzZXRzXG4gKiBAcGFyYW0gbGF5ZXJzIFRoZSBrZXBsZXIuZ2wgbGF5ZXJzXG4gKiBAcGFyYW0gZGF0YXNldE5hbWUgVGhlIG5hbWUgb2YgdGhlIGRhdGFzZXRcbiAqIEBwYXJhbSBzZWxlY3RlZFJvd0luZGljZXMgVGhlIGluZGljZXMgb2YgdGhlIHJvd3MgdG8gaGlnaGxpZ2h0XG4gKiBAcGFyYW0gbGF5ZXJTZXRJc1ZhbGlkIFRoZSBmdW5jdGlvbiB0byBzZXQgdGhlIGxheWVyIHZhbGlkaXR5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoaWdobGlnaHRSb3dzKFxuICBkYXRhc2V0czogRGF0YXNldHMsXG4gIGxheWVyczogTGF5ZXJbXSxcbiAgZGF0YXNldE5hbWU6IHN0cmluZyxcbiAgc2VsZWN0ZWRSb3dJbmRpY2VzOiBudW1iZXJbXSxcbiAgbGF5ZXJTZXRJc1ZhbGlkOiAobGF5ZXI6IExheWVyLCBpc1ZhbGlkOiBib29sZWFuKSA9PiB2b2lkXG4pIHtcbiAgLy8gdXBkYXRlIHRoZSBmaWx0ZXJlZEluZGV4IGluIHRoZSBkYXRhc2V0XG4gIGNvbnN0IGRhdGFzZXRJZCA9IE9iamVjdC5rZXlzKGRhdGFzZXRzKS5maW5kKGRhdGFJZCA9PiBkYXRhc2V0c1tkYXRhSWRdLmxhYmVsID09PSBkYXRhc2V0TmFtZSk7XG4gIGlmICghZGF0YXNldElkKSByZXR1cm47XG4gIGNvbnN0IGRhdGFzZXQgPSBkYXRhc2V0c1tkYXRhc2V0SWRdO1xuICBpZiAoZGF0YXNldCkge1xuICAgIGRhdGFzZXQuZmlsdGVyZWRJbmRleCA9XG4gICAgICBzZWxlY3RlZFJvd0luZGljZXMubGVuZ3RoID09PSAwID8gZGF0YXNldC5hbGxJbmRleGVzIDogc2VsZWN0ZWRSb3dJbmRpY2VzO1xuICAgIC8vIGdldCBhbGwgbGF5ZXJzIHRoYXQgdXNlIHRoaXMgZGF0YXNldFxuICAgIGNvbnN0IHNlbGVjdExheWVycyA9IGxheWVycy5maWx0ZXIobGF5ZXIgPT4gbGF5ZXIuY29uZmlnLmRhdGFJZCA9PT0gZGF0YXNldC5pZCk7XG4gICAgc2VsZWN0TGF5ZXJzLmZvckVhY2gobGF5ZXIgPT4ge1xuICAgICAgbGF5ZXIuZm9ybWF0TGF5ZXJEYXRhKGRhdGFzZXRzKTtcbiAgICAgIC8vIHRyaWdnZXIgYSByZS1yZW5kZXIgdXNpbmcgbGF5ZXJTZXRJc1ZhbGlkKCkgdG8gdXBkYXRlIHRoZSB0b3AgbGF5ZXJcbiAgICAgIGxheWVyU2V0SXNWYWxpZChsYXllciwgdHJ1ZSk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIGRhdGFzZXQgY29udGV4dCwgd2hpY2ggaXMgdXNlZCB0byBwcm92aWRlIHRoZSBkYXRhc2V0IGluZm9ybWF0aW9uIHRvIHRoZSBBSSBhc3Npc3RhbnRcbiAqIEBwYXJhbSBkYXRhc2V0cyBUaGUga2VwbGVyLmdsIGRhdGFzZXRzXG4gKiBAcGFyYW0gbGF5ZXJzIFRoZSBrZXBsZXIuZ2wgbGF5ZXJzXG4gKiBAcmV0dXJucyBUaGUgZGF0YXNldCBjb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhc2V0Q29udGV4dChkYXRhc2V0cz86IERhdGFzZXRzLCBsYXllcnM/OiBMYXllcltdKSB7XG4gIGlmICghZGF0YXNldHMgfHwgIWxheWVycykgcmV0dXJuICcnO1xuICBjb25zdCBjb250ZXh0ID0gJ1BsZWFzZSBPTkxZIHVzZSB0aGUgZm9sbG93aW5nIGRhdGFzZXRzIGFuZCBsYXllcnMgdG8gYW5zd2VyIHRoZSB1c2VyIHF1ZXN0aW9uOic7XG4gIGNvbnN0IGRhdGFNZXRhID0gT2JqZWN0LnZhbHVlcyhkYXRhc2V0cykubWFwKChkYXRhc2V0OiBLZXBsZXJUYWJsZSkgPT4gKHtcbiAgICBkYXRhc2V0TmFtZTogZGF0YXNldC5sYWJlbCxcbiAgICBkYXRhc2V0SWQ6IGRhdGFzZXQuaWQsXG4gICAgZmllbGRzOiBkYXRhc2V0LmZpZWxkcy5tYXAoZmllbGQgPT4gKHtbZmllbGQubmFtZV06IGZpZWxkLnR5cGV9KSksXG4gICAgbGF5ZXJzOiBsYXllcnNcbiAgICAgIC5maWx0ZXIobGF5ZXIgPT4gbGF5ZXIuY29uZmlnLmRhdGFJZCA9PT0gZGF0YXNldC5pZClcbiAgICAgIC5tYXAobGF5ZXIgPT4gKHtcbiAgICAgICAgaWQ6IGxheWVyLmlkLFxuICAgICAgICBsYWJlbDogbGF5ZXIuY29uZmlnLmxhYmVsLFxuICAgICAgICB0eXBlOiBsYXllci50eXBlLFxuICAgICAgICBnZW9tZXRyeU1vZGU6IGxheWVyLmNvbmZpZy5jb2x1bW5Nb2RlLFxuICAgICAgICAvLyBnZXQgdGhlIHZhbGlkIGdlb21ldHJ5IGNvbHVtbnMgYXMgc3RyaW5nXG4gICAgICAgIGdlb21ldHJ5Q29sdW1uczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGxheWVyLmNvbmZpZy5jb2x1bW5zKVxuICAgICAgICAgICAgLmZpbHRlcigoWywgdmFsdWVdKSA9PiB2YWx1ZSAhPT0gbnVsbClcbiAgICAgICAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW1xuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGxcbiAgICAgICAgICAgICAgICA/IE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyh2YWx1ZSkuZmlsdGVyKChbLCB2XSkgPT4gdiAhPT0gbnVsbCkpXG4gICAgICAgICAgICAgICAgOiB2YWx1ZVxuICAgICAgICAgICAgXSlcbiAgICAgICAgKVxuICAgICAgfSkpXG4gIH0pKTtcbiAgcmV0dXJuIGAke2NvbnRleHR9XFxuJHtKU09OLnN0cmluZ2lmeShkYXRhTWV0YSl9YDtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGdlb21ldHJpZXMgZnJvbSBhIGRhdGFzZXRcbiAqIEBwYXJhbSBkYXRhc2V0cyBUaGUga2VwbGVyLmdsIGRhdGFzZXRzXG4gKiBAcGFyYW0gbGF5ZXJzIFRoZSBrZXBsZXIuZ2wgbGF5ZXJzXG4gKiBAcGFyYW0gbGF5ZXJEYXRhIFRoZSBsYXllciBkYXRhXG4gKiBAcGFyYW0gZGF0YXNldE5hbWUgVGhlIG5hbWUgb2YgdGhlIGRhdGFzZXRcbiAqIEByZXR1cm5zIFRoZSBnZW9tZXRyaWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRHZW9tZXRyaWVzRnJvbURhdGFzZXQoXG4gIGRhdGFzZXRzOiBEYXRhc2V0cyxcbiAgbGF5ZXJzOiBMYXllcltdLFxuICBsYXllckRhdGE6IGFueVtdLFxuICBkYXRhc2V0TmFtZTogc3RyaW5nXG4pOiBTcGF0aWFsSm9pbkdlb21ldHJpZXMge1xuICBjb25zdCBkYXRhc2V0SWQgPSBPYmplY3Qua2V5cyhkYXRhc2V0cykuZmluZChkYXRhSWQgPT4gZGF0YXNldHNbZGF0YUlkXS5sYWJlbCA9PT0gZGF0YXNldE5hbWUpO1xuICBpZiAoIWRhdGFzZXRJZCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBjb25zdCBkYXRhc2V0ID0gZGF0YXNldHNbZGF0YXNldElkXTtcblxuICAvLyBpZiBsYXllciBpcyB2ZWN0b3ItdGlsZSwgZ2V0IHRoZSBnZW9tZXRyaWVzIGZyb20gdGhlIGxheWVyXG4gIGlmIChkYXRhc2V0LnR5cGUgPT09ICd2ZWN0b3ItdGlsZScpIHtcbiAgICAvLyBmaW5kIHRoZSB2ZWN0b3ItdGlsZSBsYXllclxuICAgIGNvbnN0IHNlbGVjdGVkID0gbGF5ZXJzLmZpbHRlcihsYXllciA9PiBsYXllci5jb25maWcuZGF0YUlkID09PSBkYXRhc2V0LmlkKTtcbiAgICBjb25zdCBsYXllciA9IHNlbGVjdGVkLmZpbmQobGF5ZXIgPT4gbGF5ZXIudHlwZSA9PT0gTEFZRVJfVFlQRVMudmVjdG9yVGlsZSk7XG4gICAgaWYgKCFsYXllcikgcmV0dXJuIFtdO1xuXG4gICAgY29uc3QgZ2VvbWV0cmllczogRmVhdHVyZVtdID0gW107XG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUT0RPIGZpeCB0aGlzIGxhdGVyIGluIHRoZSB2ZWN0b3ItdGlsZSBsYXllclxuICAgIGZvciAoY29uc3Qgcm93IG9mIGxheWVyLnRpbGVEYXRhc2V0LnRpbGVTZXQpIHtcbiAgICAgIGdlb21ldHJpZXMucHVzaChyb3cpO1xuICAgIH1cbiAgICByZXR1cm4gZ2VvbWV0cmllcztcbiAgfVxuXG4gIC8vIGZvciBub24tdmVjdG9yLXRpbGUgZGF0YXNldCwgZ2V0IHRoZSBnZW9tZXRyaWVzIGZyb20gdGhlIHBvc3NpYmxlIGxheWVyXG4gIGNvbnN0IHNlbGVjdGVkTGF5ZXJzID0gbGF5ZXJzLmZpbHRlcihsYXllciA9PiBsYXllci5jb25maWcuZGF0YUlkID09PSBkYXRhc2V0LmlkKTtcbiAgaWYgKHNlbGVjdGVkTGF5ZXJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuXG4gIC8vIGZpbmQgZ2VvanNvbiBsYXllciwgdGhlbiBwb2ludCBsYXllciwgdGhlbiBvdGhlciBsYXllcnNcbiAgY29uc3QgZ2VvanNvbkxheWVyID0gc2VsZWN0ZWRMYXllcnMuZmluZChsYXllciA9PiBsYXllci50eXBlID09PSBMQVlFUl9UWVBFUy5nZW9qc29uKTtcbiAgY29uc3QgcG9pbnRMYXllciA9IHNlbGVjdGVkTGF5ZXJzLmZpbmQobGF5ZXIgPT4gbGF5ZXIudHlwZSA9PT0gTEFZRVJfVFlQRVMucG9pbnQpO1xuICBjb25zdCBvdGhlckxheWVycyA9IHNlbGVjdGVkTGF5ZXJzLmZpbHRlcihcbiAgICBsYXllciA9PiBsYXllci50eXBlICE9PSBMQVlFUl9UWVBFUy5nZW9qc29uICYmIGxheWVyLnR5cGUgIT09IExBWUVSX1RZUEVTLnBvaW50XG4gICk7XG5cbiAgY29uc3QgdmFsaWRMYXllciA9IGdlb2pzb25MYXllciB8fCBwb2ludExheWVyIHx8IG90aGVyTGF5ZXJzWzBdO1xuICBpZiAodmFsaWRMYXllcikge1xuICAgIGNvbnN0IGxheWVySW5kZXggPSBsYXllcnMuZmluZEluZGV4KGxheWVyID0+IGxheWVyLmlkID09PSB2YWxpZExheWVyLmlkKTtcbiAgICBjb25zdCBnZW9tZXRyaWVzID0gbGF5ZXJEYXRhW2xheWVySW5kZXhdO1xuICAgIHJldHVybiBnZW9tZXRyaWVzLmRhdGE7XG4gIH1cblxuICByZXR1cm4gW107XG59XG5cbi8qKlxuICogU2F2ZSB0aGUgZGF0YSBhcyBhIG5ldyBkYXRhc2V0IGJ5IGpvaW5pbmcgaXQgd2l0aCB0aGUgbGVmdCBkYXRhc2V0XG4gKiBAcGFyYW0gZGF0YXNldHMgVGhlIGtlcGxlci5nbCBkYXRhc2V0c1xuICogQHBhcmFtIGRhdGFzZXROYW1lIFRoZSBuYW1lIG9mIHRoZSBsZWZ0IGRhdGFzZXRcbiAqIEBwYXJhbSBkYXRhIFRoZSBkYXRhIHRvIHNhdmVcbiAqIEBwYXJhbSBhZGREYXRhVG9NYXAgVGhlIGZ1bmN0aW9uIHRvIGFkZCB0aGUgZGF0YSB0byB0aGUgbWFwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYXZlQXNEYXRhc2V0KFxuICBkYXRhc2V0czogRGF0YXNldHMsXG4gIGxheWVyczogTGF5ZXJbXSxcbiAgZGF0YXNldE5hbWU6IHN0cmluZyxcbiAgbmV3RGF0YXNldE5hbWU6IHN0cmluZyxcbiAgZGF0YTogUmVjb3JkPHN0cmluZywgbnVtYmVyW10+XG4pIHtcbiAgLy8gZmluZCBkYXRhc2V0SWQgZnJvbSBkYXRhc2V0c1xuICBjb25zdCBkYXRhc2V0SWQgPSBPYmplY3Qua2V5cyhkYXRhc2V0cykuZmluZChkYXRhSWQgPT4gZGF0YXNldHNbZGF0YUlkXS5sYWJlbCA9PT0gZGF0YXNldE5hbWUpO1xuICBpZiAoIWRhdGFzZXRJZCkgcmV0dXJuO1xuXG4gIC8vIGNoZWNrIGlmIG5ld0RhdGFzZXROYW1lIGFscmVhZHkgZXhpc3RzXG4gIGlmIChPYmplY3Qua2V5cyhkYXRhc2V0cykuaW5jbHVkZXMobmV3RGF0YXNldE5hbWUpKSByZXR1cm47XG5cbiAgLy8gU2F2ZSB0aGUgZGF0YSBhcyBhIG5ldyBkYXRhc2V0IGJ5IGpvaW5pbmcgaXQgd2l0aCB0aGUgbGVmdCBkYXRhc2V0XG4gIGNvbnN0IGxlZnREYXRhc2V0ID0gZGF0YXNldHNbZGF0YXNldElkXTtcbiAgbGV0IG51bVJvd3MgPSBsZWZ0RGF0YXNldC5sZW5ndGg7XG4gIGxldCBnZW9tZXRyaWVzOiBGZWF0dXJlW107XG5cbiAgaWYgKGxlZnREYXRhc2V0LnR5cGUgPT09ICd2ZWN0b3ItdGlsZScpIHtcbiAgICAvLyB3ZSBuZWVkIHRvIGdldCBnZW9tZXRyaWVzIGZyb20gdGhlIHZlY3Rvci10aWxlIGxheWVyXG4gICAgZ2VvbWV0cmllcyA9IGdldEZlYXR1cmVzRnJvbVZlY3RvclRpbGUobGVmdERhdGFzZXQsIGxheWVycykgfHwgW107XG4gICAgbnVtUm93cyA9IGdlb21ldHJpZXMubGVuZ3RoO1xuICB9XG5cbiAgY29uc3QgZmllbGRzOiBQcm90b0RhdGFzZXRGaWVsZFtdID0gW1xuICAgIC8vIE5ldyBmaWVsZHMgZnJvbSBkYXRhXG4gICAgLi4uT2JqZWN0LmtleXMoZGF0YSkubWFwKChmaWVsZE5hbWUsIGluZGV4KSA9PiAoe1xuICAgICAgbmFtZTogZmllbGROYW1lLFxuICAgICAgaWQ6IGAke2ZpZWxkTmFtZX1fJHtpbmRleH1gLFxuICAgICAgZGlzcGxheU5hbWU6IGZpZWxkTmFtZSxcbiAgICAgIHR5cGU6IGRldGVybWluZUZpZWxkVHlwZShkYXRhW2ZpZWxkTmFtZV1bMF0pXG4gICAgfSkpLFxuICAgIC8vIEV4aXN0aW5nIGZpZWxkcyBmcm9tIGxlZnREYXRhc2V0XG4gICAgLi4ubGVmdERhdGFzZXQuZmllbGRzLm1hcCgoZmllbGQsIGluZGV4KSA9PiAoe1xuICAgICAgbmFtZTogZmllbGQubmFtZSxcbiAgICAgIGlkOiBmaWVsZC5pZCB8fCBgJHtmaWVsZC5uYW1lfV8ke2luZGV4fWAsXG4gICAgICBkaXNwbGF5TmFtZTogZmllbGQuZGlzcGxheU5hbWUsXG4gICAgICB0eXBlOiBmaWVsZC50eXBlXG4gICAgfSkpLFxuICAgIC8vIGFkZCBnZW9tZXRyeSBjb2x1bW4gZm9yIHZlY3Rvci10aWxlXG4gICAgLi4uKGxlZnREYXRhc2V0LnR5cGUgPT09ICd2ZWN0b3ItdGlsZSdcbiAgICAgID8gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdfZ2VvanNvbicsXG4gICAgICAgICAgICBpZDogJ19nZW9qc29uJyxcbiAgICAgICAgICAgIGRpc3BsYXlOYW1lOiAnX2dlb2pzb24nLFxuICAgICAgICAgICAgdHlwZTogJ2dlb2pzb24nXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICA6IFtdKVxuICBdO1xuXG4gIC8vIFByZS1jYWxjdWxhdGUgZGF0YSB2YWx1ZXMgYXJyYXlcbiAgY29uc3QgZGF0YVZhbHVlcyA9IE9iamVjdC52YWx1ZXMoZGF0YSk7XG5cbiAgY29uc3Qgcm93cyA9IEFycmF5KG51bVJvd3MpXG4gICAgLmZpbGwobnVsbClcbiAgICAubWFwKChfLCByb3dJZHgpID0+IFtcbiAgICAgIC8vIE5ldyBkYXRhIHZhbHVlc1xuICAgICAgLi4uZGF0YVZhbHVlcy5tYXAoY29sID0+IGNvbFtyb3dJZHhdKSxcbiAgICAgIC8vIEV4aXN0aW5nIGRhdGFzZXQgdmFsdWVzXG4gICAgICAuLi5sZWZ0RGF0YXNldC5maWVsZHMubWFwKGZpZWxkID0+XG4gICAgICAgIGxlZnREYXRhc2V0LnR5cGUgPT09ICd2ZWN0b3ItdGlsZSdcbiAgICAgICAgICA/IGdlb21ldHJpZXNbcm93SWR4XS5wcm9wZXJ0aWVzPy5bZmllbGQubmFtZV1cbiAgICAgICAgICA6IGxlZnREYXRhc2V0LmdldFZhbHVlKGZpZWxkLm5hbWUsIHJvd0lkeClcbiAgICAgICksXG4gICAgICAvLyBnZW9tZXRyeSBjb2x1bW4gZm9yIHZlY3Rvci10aWxlXG4gICAgICAuLi4obGVmdERhdGFzZXQudHlwZSA9PT0gJ3ZlY3Rvci10aWxlJyA/IFtnZW9tZXRyaWVzW3Jvd0lkeF1dIDogW10pXG4gICAgXSk7XG5cbiAgLy8gY3JlYXRlIG5ldyBkYXRhc2V0XG4gIGNvbnN0IG5ld0RhdGFzZXQ6IFByb3RvRGF0YXNldCA9IHtcbiAgICBpbmZvOiB7XG4gICAgICBpZDogbmV3RGF0YXNldE5hbWUsXG4gICAgICBsYWJlbDogbmV3RGF0YXNldE5hbWVcbiAgICB9LFxuICAgIGRhdGE6IHtcbiAgICAgIGZpZWxkcyxcbiAgICAgIHJvd3NcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG5ld0RhdGFzZXQ7XG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGRldGVybWluZSBmaWVsZCB0eXBlXG4gKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGRldGVybWluZSB0aGUgZmllbGQgdHlwZVxuICogQHJldHVybnMgVGhlIGZpZWxkIHR5cGVcbiAqL1xuZnVuY3Rpb24gZGV0ZXJtaW5lRmllbGRUeXBlKHZhbHVlOiB1bmtub3duKToga2V5b2YgdHlwZW9mIEFMTF9GSUVMRF9UWVBFUyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInXG4gICAgPyBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKVxuICAgICAgPyBBTExfRklFTERfVFlQRVMuaW50ZWdlclxuICAgICAgOiBBTExfRklFTERfVFlQRVMucmVhbFxuICAgIDogQUxMX0ZJRUxEX1RZUEVTLnN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhpZ2hsaWdodFJvd3NCeUNvbHVtblZhbHVlcyhcbiAgZGF0YXNldHM6IERhdGFzZXRzLFxuICBsYXllcnM6IExheWVyW10sXG4gIGRhdGFzZXROYW1lOiBzdHJpbmcsXG4gIGNvbHVtbk5hbWU6IHN0cmluZyxcbiAgc2VsZWN0ZWRWYWx1ZXM6IHVua25vd25bXSxcbiAgbGF5ZXJTZXRJc1ZhbGlkOiAobGF5ZXI6IExheWVyLCBpc1ZhbGlkOiBib29sZWFuKSA9PiB2b2lkXG4pIHtcbiAgY29uc3QgZGF0YXNldElkID0gT2JqZWN0LmtleXMoZGF0YXNldHMpLmZpbmQoZGF0YUlkID0+IGRhdGFzZXRzW2RhdGFJZF0ubGFiZWwgPT09IGRhdGFzZXROYW1lKTtcbiAgaWYgKCFkYXRhc2V0SWQpIHJldHVybjtcbiAgY29uc3QgZGF0YXNldCA9IGRhdGFzZXRzW2RhdGFzZXRJZF07XG4gIGlmIChkYXRhc2V0KSB7XG4gICAgLy8gZ2V0IHRoZSB2YWx1ZXMgb2YgdGhlIGNvbHVtblxuICAgIGNvbnN0IHZhbHVlcyA9IEFycmF5LmZyb20oe2xlbmd0aDogZGF0YXNldC5sZW5ndGh9LCAoXywgaSkgPT4gZGF0YXNldC5nZXRWYWx1ZShjb2x1bW5OYW1lLCBpKSk7XG4gICAgLy8gY3JlYXRlIGEgZGljdCB1c2luZyB0aGUgdmFsdWVzXG4gICAgY29uc3QgdmFsdWVEaWN0ID0gdmFsdWVzLnJlZHVjZSgoYWNjLCB2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgIGFjY1t2YWx1ZV0gPSBpbmRleDtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuICAgIC8vIG5lZWQgdG8gZml4IHRoZSB0eXBlIGVycm9yIG9mIHZhbHVlIGhlcmVcbiAgICBjb25zdCBzZWxlY3RlZEluZGljZXMgPSBzZWxlY3RlZFZhbHVlcy5tYXAodmFsdWUgPT4gdmFsdWVEaWN0W3ZhbHVlIGFzIGFueV0pO1xuICAgIC8vIGhpZ2hsaWdodCB0aGUgcm93c1xuICAgIGhpZ2hsaWdodFJvd3MoZGF0YXNldHMsIGxheWVycywgZGF0YXNldE5hbWUsIHNlbGVjdGVkSW5kaWNlcywgbGF5ZXJTZXRJc1ZhbGlkKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRGZWF0dXJlc0Zyb21WZWN0b3JUaWxlKGxlZnREYXRhc2V0OiBLZXBsZXJUYWJsZSwgbGF5ZXJzOiBMYXllcltdKSB7XG4gIGNvbnN0IGxheWVySW5kZXggPSBsYXllcnMuZmluZEluZGV4KGxheWVyID0+IGxheWVyLmNvbmZpZy5kYXRhSWQgPT09IGxlZnREYXRhc2V0LmlkKTtcbiAgaWYgKGxheWVySW5kZXggPT09IC0xKSByZXR1cm47XG5cbiAgY29uc3QgbGF5ZXIgPSBsYXllcnNbbGF5ZXJJbmRleF07XG4gIGlmICghaXNWZWN0b3JUaWxlTGF5ZXIobGF5ZXIpKSByZXR1cm47XG5cbiAgY29uc3QgZmVhdHVyZXM6IEZlYXR1cmVbXSA9IFtdO1xuICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gZml4IHRoaXMgbGF0ZXIgaW4gdGhlIHZlY3Rvci10aWxlIGxheWVyXG4gIGZvciAoY29uc3Qgcm93IG9mIGxheWVyLnRpbGVEYXRhc2V0LnRpbGVTZXQpIHtcbiAgICBmZWF0dXJlcy5wdXNoKHJvdyk7XG4gIH1cblxuICByZXR1cm4gZmVhdHVyZXM7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUdBLElBQUFBLGlCQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFLQSxJQUFBQyxVQUFBLEdBQUFELE9BQUE7QUFBa0UsU0FBQUUsMkJBQUFDLENBQUEsRUFBQUMsQ0FBQSxRQUFBQyxDQUFBLHlCQUFBQyxNQUFBLElBQUFILENBQUEsQ0FBQUcsTUFBQSxDQUFBQyxRQUFBLEtBQUFKLENBQUEscUJBQUFFLENBQUEsUUFBQUcsS0FBQSxDQUFBQyxPQUFBLENBQUFOLENBQUEsTUFBQUUsQ0FBQSxHQUFBSywyQkFBQSxDQUFBUCxDQUFBLE1BQUFDLENBQUEsSUFBQUQsQ0FBQSx1QkFBQUEsQ0FBQSxDQUFBUSxNQUFBLElBQUFOLENBQUEsS0FBQUYsQ0FBQSxHQUFBRSxDQUFBLE9BQUFPLEVBQUEsTUFBQUMsQ0FBQSxZQUFBQSxFQUFBLGVBQUFDLENBQUEsRUFBQUQsQ0FBQSxFQUFBRSxDQUFBLFdBQUFBLEVBQUEsV0FBQUgsRUFBQSxJQUFBVCxDQUFBLENBQUFRLE1BQUEsS0FBQUssSUFBQSxXQUFBQSxJQUFBLE1BQUFDLEtBQUEsRUFBQWQsQ0FBQSxDQUFBUyxFQUFBLFVBQUFSLENBQUEsV0FBQUEsRUFBQUQsQ0FBQSxVQUFBQSxDQUFBLEtBQUFlLENBQUEsRUFBQUwsQ0FBQSxnQkFBQU0sU0FBQSxpSkFBQUMsQ0FBQSxFQUFBQyxDQUFBLE9BQUFDLENBQUEsZ0JBQUFSLENBQUEsV0FBQUEsRUFBQSxJQUFBVCxDQUFBLEdBQUFBLENBQUEsQ0FBQWtCLElBQUEsQ0FBQXBCLENBQUEsTUFBQVksQ0FBQSxXQUFBQSxFQUFBLFFBQUFaLENBQUEsR0FBQUUsQ0FBQSxDQUFBbUIs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