@nebula.gl/layers
Version:
A suite of 3D-enabled data editing layers, suitable for deck.gl
433 lines (366 loc) • 41.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getPickedEditHandle = getPickedEditHandle;
exports.getIntermediatePosition = getIntermediatePosition;
exports.getEditHandlesForGeometry = getEditHandlesForGeometry;
exports.ModeHandler = void 0;
var _union = _interopRequireDefault(require("@turf/union"));
var _difference = _interopRequireDefault(require("@turf/difference"));
var _intersect = _interopRequireDefault(require("@turf/intersect"));
var _editModes = require("@nebula.gl/edit-modes");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var ModeHandler = /*#__PURE__*/function () {
// TODO: add underscore
function ModeHandler(featureCollection) {
_classCallCheck(this, ModeHandler);
_defineProperty(this, "featureCollection", void 0);
_defineProperty(this, "_tentativeFeature", void 0);
_defineProperty(this, "_modeConfig", null);
_defineProperty(this, "_selectedFeatureIndexes", []);
_defineProperty(this, "_clickSequence", []);
if (featureCollection) {
this.setFeatureCollection(featureCollection);
}
}
_createClass(ModeHandler, [{
key: "getFeatureCollection",
value: function getFeatureCollection() {
return this.featureCollection.getObject();
}
}, {
key: "getImmutableFeatureCollection",
value: function getImmutableFeatureCollection() {
return this.featureCollection;
}
}, {
key: "getSelectedFeature",
value: function getSelectedFeature() {
if (this._selectedFeatureIndexes.length === 1) {
return this.featureCollection.getObject().features[this._selectedFeatureIndexes[0]];
}
return null;
}
}, {
key: "getSelectedGeometry",
value: function getSelectedGeometry() {
var feature = this.getSelectedFeature();
if (feature) {
return feature.geometry;
}
return null;
}
}, {
key: "getSelectedFeaturesAsFeatureCollection",
value: function getSelectedFeaturesAsFeatureCollection() {
var _this$featureCollecti = this.featureCollection.getObject(),
features = _this$featureCollecti.features;
var selectedFeatures = this.getSelectedFeatureIndexes().map(function (selectedIndex) {
return features[selectedIndex];
});
return {
type: 'FeatureCollection',
features: selectedFeatures
};
}
}, {
key: "setFeatureCollection",
value: function setFeatureCollection(featureCollection) {
this.featureCollection = new _editModes.ImmutableFeatureCollection(featureCollection);
}
}, {
key: "getModeConfig",
value: function getModeConfig() {
return this._modeConfig;
}
}, {
key: "setModeConfig",
value: function setModeConfig(modeConfig) {
if (this._modeConfig === modeConfig) {
return;
}
this._modeConfig = modeConfig;
this._setTentativeFeature(null);
}
}, {
key: "getSelectedFeatureIndexes",
value: function getSelectedFeatureIndexes() {
return this._selectedFeatureIndexes;
}
}, {
key: "setSelectedFeatureIndexes",
value: function setSelectedFeatureIndexes(indexes) {
if (this._selectedFeatureIndexes === indexes) {
return;
}
this._selectedFeatureIndexes = indexes;
this._setTentativeFeature(null);
}
}, {
key: "getClickSequence",
value: function getClickSequence() {
return this._clickSequence;
}
}, {
key: "resetClickSequence",
value: function resetClickSequence() {
this._clickSequence = [];
}
}, {
key: "getTentativeFeature",
value: function getTentativeFeature() {
return this._tentativeFeature;
} // TODO: remove the underscore
}, {
key: "_setTentativeFeature",
value: function _setTentativeFeature(tentativeFeature) {
this._tentativeFeature = tentativeFeature;
if (!tentativeFeature) {
// Reset the click sequence
this._clickSequence = [];
}
}
/**
* Returns a flat array of positions for the given feature along with their indexes into the feature's geometry's coordinates.
*
* @param featureIndex The index of the feature to get edit handles
*/
}, {
key: "getEditHandles",
value: function getEditHandles(picks, groundCoords) {
return [];
}
}, {
key: "getCursor",
value: function getCursor(_ref) {
var isDragging = _ref.isDragging;
return 'cell';
}
}, {
key: "isSelectionPicked",
value: function isSelectionPicked(picks) {
if (!picks.length) return false;
var pickedIndexes = picks.map(function (_ref2) {
var index = _ref2.index;
return index;
});
var selectedFeatureIndexes = this.getSelectedFeatureIndexes();
return selectedFeatureIndexes.some(function (index) {
return pickedIndexes.includes(index);
});
}
}, {
key: "getAddFeatureAction",
value: function getAddFeatureAction(geometry) {
// Unsure why flow can't deal with Geometry type, but there I fixed it
var geometryAsAny = geometry;
var updatedData = this.getImmutableFeatureCollection().addFeature({
type: 'Feature',
properties: {},
geometry: geometryAsAny
}).getObject();
return {
updatedData: updatedData,
editType: 'addFeature',
featureIndexes: [updatedData.features.length - 1],
editContext: {
featureIndexes: [updatedData.features.length - 1]
}
};
}
}, {
key: "getAddManyFeaturesAction",
value: function getAddManyFeaturesAction(featureCollection) {
var features = featureCollection.features;
var updatedData = this.getImmutableFeatureCollection();
var initialIndex = updatedData.getObject().features.length;
var updatedIndexes = [];
var _iterator = _createForOfIteratorHelper(features),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var feature = _step.value;
var properties = feature.properties,
geometry = feature.geometry;
var geometryAsAny = geometry;
updatedData = updatedData.addFeature({
type: 'Feature',
properties: properties,
geometry: geometryAsAny
});
updatedIndexes.push(initialIndex + updatedIndexes.length);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return {
updatedData: updatedData.getObject(),
editType: 'addFeature',
featureIndexes: updatedIndexes,
editContext: {
featureIndexes: updatedIndexes
}
};
}
}, {
key: "getAddFeatureOrBooleanPolygonAction",
value: function getAddFeatureOrBooleanPolygonAction(geometry) {
var selectedFeature = this.getSelectedFeature();
var modeConfig = this.getModeConfig();
if (modeConfig && modeConfig.booleanOperation) {
if (!selectedFeature || selectedFeature.geometry.type !== 'Polygon' && selectedFeature.geometry.type !== 'MultiPolygon') {
// eslint-disable-next-line no-console,no-undef
console.warn('booleanOperation only supported for single Polygon or MultiPolygon selection');
return null;
}
var feature = {
type: 'Feature',
geometry: geometry
};
var updatedGeometry;
if (modeConfig.booleanOperation === 'union') {
updatedGeometry = (0, _union["default"])(selectedFeature, feature);
} else if (modeConfig.booleanOperation === 'difference') {
// @ts-ignore
updatedGeometry = (0, _difference["default"])(selectedFeature, feature);
} else if (modeConfig.booleanOperation === 'intersection') {
// @ts-ignore
updatedGeometry = (0, _intersect["default"])(selectedFeature, feature);
} else {
// eslint-disable-next-line no-console,no-undef
console.warn("Invalid booleanOperation ".concat(modeConfig.booleanOperation));
return null;
}
if (!updatedGeometry) {
// eslint-disable-next-line no-console,no-undef
console.warn('Canceling edit. Boolean operation erased entire polygon.');
return null;
}
var featureIndex = this.getSelectedFeatureIndexes()[0];
var updatedData = this.getImmutableFeatureCollection().replaceGeometry(featureIndex, updatedGeometry.geometry).getObject();
var editAction = {
updatedData: updatedData,
editType: 'unionGeometry',
featureIndexes: [featureIndex],
editContext: {
featureIndexes: [featureIndex]
}
};
return editAction;
}
return this.getAddFeatureAction(geometry);
}
}, {
key: "handleClick",
value: function handleClick(event) {
this._clickSequence.push(event.groundCoords);
return null;
}
}, {
key: "handlePointerMove",
value: function handlePointerMove(event) {
return {
editAction: null,
cancelMapPan: false
};
}
}, {
key: "handleStartDragging",
value: function handleStartDragging(event) {
return null;
}
}, {
key: "handleStopDragging",
value: function handleStopDragging(event) {
return null;
}
}]);
return ModeHandler;
}();
exports.ModeHandler = ModeHandler;
function getPickedEditHandle(picks) {
var info = picks && picks.find(function (pick) {
return pick.isEditingHandle;
});
if (info) {
return info.object;
}
return null;
}
function getIntermediatePosition(position1, position2) {
var intermediatePosition = [(position1[0] + position2[0]) / 2.0, (position1[1] + position2[1]) / 2.0]; // @ts-ignore
return intermediatePosition;
}
function getEditHandlesForGeometry(geometry, featureIndex) {
var editHandleType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'existing';
var handles = [];
switch (geometry.type) {
case 'Point':
// positions are not nested
handles = [{
position: geometry.coordinates,
positionIndexes: [],
featureIndex: featureIndex,
type: editHandleType
}];
break;
case 'MultiPoint':
case 'LineString':
// positions are nested 1 level
handles = handles.concat(getEditHandlesForCoordinates(geometry.coordinates, [], featureIndex, editHandleType));
break;
case 'Polygon':
case 'MultiLineString':
// positions are nested 2 levels
for (var a = 0; a < geometry.coordinates.length; a++) {
handles = handles.concat(getEditHandlesForCoordinates(geometry.coordinates[a], [a], featureIndex, editHandleType));
if (geometry.type === 'Polygon') {
// Don't repeat the first/last handle for Polygons
handles = handles.slice(0, -1);
}
}
break;
case 'MultiPolygon':
// positions are nested 3 levels
for (var _a = 0; _a < geometry.coordinates.length; _a++) {
for (var b = 0; b < geometry.coordinates[_a].length; b++) {
handles = handles.concat(getEditHandlesForCoordinates(geometry.coordinates[_a][b], [_a, b], featureIndex, editHandleType)); // Don't repeat the first/last handle for Polygons
handles = handles.slice(0, -1);
}
}
break;
default:
// @ts-ignore
throw Error("Unhandled geometry type: ".concat(geometry.type));
}
return handles;
}
function getEditHandlesForCoordinates(coordinates, positionIndexPrefix, featureIndex) {
var editHandleType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'existing';
var editHandles = [];
for (var i = 0; i < coordinates.length; i++) {
var position = coordinates[i];
editHandles.push({
position: position,
positionIndexes: [].concat(_toConsumableArray(positionIndexPrefix), [i]),
featureIndex: featureIndex,
type: editHandleType
});
}
return editHandles;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlLWhhbmRsZXJzL21vZGUtaGFuZGxlci50cyJdLCJuYW1lcyI6WyJNb2RlSGFuZGxlciIsImZlYXR1cmVDb2xsZWN0aW9uIiwic2V0RmVhdHVyZUNvbGxlY3Rpb24iLCJnZXRPYmplY3QiLCJfc2VsZWN0ZWRGZWF0dXJlSW5kZXhlcyIsImxlbmd0aCIsImZlYXR1cmVzIiwiZmVhdHVyZSIsImdldFNlbGVjdGVkRmVhdHVyZSIsImdlb21ldHJ5Iiwic2VsZWN0ZWRGZWF0dXJlcyIsImdldFNlbGVjdGVkRmVhdHVyZUluZGV4ZXMiLCJtYXAiLCJzZWxlY3RlZEluZGV4IiwidHlwZSIsIkltbXV0YWJsZUZlYXR1cmVDb2xsZWN0aW9uIiwiX21vZGVDb25maWciLCJtb2RlQ29uZmlnIiwiX3NldFRlbnRhdGl2ZUZlYXR1cmUiLCJpbmRleGVzIiwiX2NsaWNrU2VxdWVuY2UiLCJfdGVudGF0aXZlRmVhdHVyZSIsInRlbnRhdGl2ZUZlYXR1cmUiLCJwaWNrcyIsImdyb3VuZENvb3JkcyIsImlzRHJhZ2dpbmciLCJwaWNrZWRJbmRleGVzIiwiaW5kZXgiLCJzZWxlY3RlZEZlYXR1cmVJbmRleGVzIiwic29tZSIsImluY2x1ZGVzIiwiZ2VvbWV0cnlBc0FueSIsInVwZGF0ZWREYXRhIiwiZ2V0SW1tdXRhYmxlRmVhdHVyZUNvbGxlY3Rpb24iLCJhZGRGZWF0dXJlIiwicHJvcGVydGllcyIsImVkaXRUeXBlIiwiZmVhdHVyZUluZGV4ZXMiLCJlZGl0Q29udGV4dCIsImluaXRpYWxJbmRleCIsInVwZGF0ZWRJbmRleGVzIiwicHVzaCIsInNlbGVjdGVkRmVhdHVyZSIsImdldE1vZGVDb25maWciLCJib29sZWFuT3BlcmF0aW9uIiwiY29uc29sZSIsIndhcm4iLCJ1cGRhdGVkR2VvbWV0cnkiLCJmZWF0dXJlSW5kZXgiLCJyZXBsYWNlR2VvbWV0cnkiLCJlZGl0QWN0aW9uIiwiZ2V0QWRkRmVhdHVyZUFjdGlvbiIsImV2ZW50IiwiY2FuY2VsTWFwUGFuIiwiZ2V0UGlja2VkRWRpdEhhbmRsZSIsImluZm8iLCJmaW5kIiwicGljayIsImlzRWRpdGluZ0hhbmRsZSIsIm9iamVjdCIsImdldEludGVybWVkaWF0ZVBvc2l0aW9uIiwicG9zaXRpb24xIiwicG9zaXRpb24yIiwiaW50ZXJtZWRpYXRlUG9zaXRpb24iLCJnZXRFZGl0SGFuZGxlc0Zvckdlb21ldHJ5IiwiZWRpdEhhbmRsZVR5cGUiLCJoYW5kbGVzIiwicG9zaXRpb24iLCJjb29yZGluYXRlcyIsInBvc2l0aW9uSW5kZXhlcyIsImNvbmNhdCIsImdldEVkaXRIYW5kbGVzRm9yQ29vcmRpbmF0ZXMiLCJhIiwic2xpY2UiLCJiIiwiRXJyb3IiLCJwb3NpdGlvbkluZGV4UHJlZml4IiwiZWRpdEhhbmRsZXMiLCJpIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBaUNhQSxXO0FBQ1g7QUFPQSx1QkFBWUMsaUJBQVosRUFBbUQ7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQSx5Q0FKaEMsSUFJZ0M7O0FBQUEscURBSGYsRUFHZTs7QUFBQSw0Q0FGdEIsRUFFc0I7O0FBQ2pELFFBQUlBLGlCQUFKLEVBQXVCO0FBQ3JCLFdBQUtDLG9CQUFMLENBQTBCRCxpQkFBMUI7QUFDRDtBQUNGOzs7OzJDQUV5QztBQUN4QyxhQUFPLEtBQUtBLGlCQUFMLENBQXVCRSxTQUF2QixFQUFQO0FBQ0Q7OztvREFFMkQ7QUFDMUQsYUFBTyxLQUFLRixpQkFBWjtBQUNEOzs7eUNBRWdEO0FBQy9DLFVBQUksS0FBS0csdUJBQUwsQ0FBNkJDLE1BQTdCLEtBQXdDLENBQTVDLEVBQStDO0FBQzdDLGVBQU8sS0FBS0osaUJBQUwsQ0FBdUJFLFNBQXZCLEdBQW1DRyxRQUFuQyxDQUE0QyxLQUFLRix1QkFBTCxDQUE2QixDQUE3QixDQUE1QyxDQUFQO0FBQ0Q7O0FBQ0QsYUFBTyxJQUFQO0FBQ0Q7OzswQ0FFa0Q7QUFDakQsVUFBTUcsT0FBTyxHQUFH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LEdBQUdBLE9BQU8sQ0FBQ08sS0FBUixDQUFjLENBQWQsRUFBaUIsQ0FBQyxDQUFsQixDQUFWO0FBQ0Q7QUFDRjs7QUFFRDs7QUFDRjtBQUNFO0FBQ0EsWUFBTUUsS0FBSyxvQ0FBNkJsRSxRQUFRLENBQUNLLElBQXRDLEVBQVg7QUFyREo7O0FBd0RBLFNBQU9vRCxPQUFQO0FBQ0Q7O0FBRUQsU0FBU0ssNEJBQVQsQ0FDRUgsV0FERixFQUVFUSxtQkFGRixFQUdFNUIsWUFIRixFQUtnQjtBQUFBLE1BRGRpQixjQUNjLHVFQURtQixVQUNuQjtBQUNkLE1BQU1ZLFdBQVcsR0FBRyxFQUFwQjs7QUFDQSxPQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdWLFdBQVcsQ0FBQy9ELE1BQWhDLEVBQXdDeUUsQ0FBQyxFQUF6QyxFQUE2QztBQUMzQyxRQUFNWCxRQUFRLEdBQUdDLFdBQVcsQ0FBQ1UsQ0FBRCxDQUE1QjtBQUNBRCxJQUFBQSxXQUFXLENBQUNwQyxJQUFaLENBQWlCO0FBQ2YwQixNQUFBQSxRQUFRLEVBQVJBLFFBRGU7QUFFZkUsTUFBQUEsZUFBZSwrQkFBTU8sbUJBQU4sSUFBMkJFLENBQTNCLEVBRkE7QUFHZjlCLE1BQUFBLFlBQVksRUFBWkEsWUFIZTtBQUlmbEMsTUFBQUEsSUFBSSxFQUFFbUQ7QUFKUyxLQUFqQjtBQU1EOztBQUNELFNBQU9ZLFdBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRPRE8gZWRpdC1tb2RlczogZGVsZXRlIGhhbmRsZXJzIG9uY2UgRWRpdE1vZGUgZnVsbHkgaW1wbGVtZW50ZWRcblxuaW1wb3J0IHR1cmZVbmlvbiBmcm9tICdAdHVyZi91bmlvbic7XG5pbXBvcnQgdHVyZkRpZmZlcmVuY2UgZnJvbSAnQHR1cmYvZGlmZmVyZW5jZSc7XG5pbXBvcnQgdHVyZkludGVyc2VjdCBmcm9tICdAdHVyZi9pbnRlcnNlY3QnO1xuXG5pbXBvcnQge1xuICBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbixcbiAgRmVhdHVyZUNvbGxlY3Rpb24sXG4gIEZlYXR1cmUsXG4gIFBvbHlnb24sXG4gIEdlb21ldHJ5LFxuICBQb3NpdGlvbixcbn0gZnJvbSAnQG5lYnVsYS5nbC9lZGl0LW1vZGVzJztcblxuaW1wb3J0IHtcbiAgQ2xpY2tFdmVudCxcbiAgUG9pbnRlck1vdmVFdmVudCxcbiAgU3RhcnREcmFnZ2luZ0V2ZW50LFxuICBTdG9wRHJhZ2dpbmdFdmVudCxcbiAgRGVja0dMUGljayxcbn0gZnJvbSAnLi4vZXZlbnQtdHlwZXMnO1xuXG5leHBvcnQgdHlwZSBFZGl0SGFuZGxlVHlwZSA9ICdleGlzdGluZycgfCAnaW50ZXJtZWRpYXRlJyB8ICdzbmFwJztcblxuZXhwb3J0IHR5cGUgRWRpdEhhbmRsZSA9IHtcbiAgcG9zaXRpb246IFBvc2l0aW9uO1xuICBwb3NpdGlvbkluZGV4ZXM6IG51bWJlcltdO1xuICBmZWF0dXJlSW5kZXg6IG51bWJlcjtcbiAgdHlwZTogRWRpdEhhbmRsZVR5cGU7XG59O1xuXG5leHBvcnQgdHlwZSBFZGl0QWN0aW9uID0ge1xuICB1cGRhdGVkRGF0YTogRmVhdHVyZUNvbGxlY3Rpb247XG4gIGVkaXRUeXBlOiBzdHJpbmc7XG4gIGZlYXR1cmVJbmRleGVzOiBudW1iZXJbXTtcbiAgZWRpdENvbnRleHQ6IGFueTtcbn07XG5cbmV4cG9ydCBjbGFzcyBNb2RlSGFuZGxlciB7XG4gIC8vIFRPRE86IGFkZCB1bmRlcnNjb3JlXG4gIGZlYXR1cmVDb2xsZWN0aW9uOiBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbjtcbiAgX3RlbnRhdGl2ZUZlYXR1cmU6IEZlYXR1cmUgfCBudWxsIHwgdW5kZWZpbmVkO1xuICBfbW9kZUNvbmZpZzogYW55ID0gbnVsbDtcbiAgX3NlbGVjdGVkRmVhdHVyZUluZGV4ZXM6IG51bWJlcltdID0gW107XG4gIF9jbGlja1NlcXVlbmNlOiBQb3NpdGlvbltdID0gW107XG5cbiAgY29uc3RydWN0b3IoZmVhdHVyZUNvbGxlY3Rpb24/OiBGZWF0dXJlQ29sbGVjdGlvbikge1xuICAgIGlmIChmZWF0dXJlQ29sbGVjdGlvbikge1xuICAgICAgdGhpcy5zZXRGZWF0dXJlQ29sbGVjdGlvbihmZWF0dXJlQ29sbGVjdGlvbik7XG4gICAgfVxuICB9XG5cbiAgZ2V0RmVhdHVyZUNvbGxlY3Rpb24oKTogRmVhdHVyZUNvbGxlY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVDb2xsZWN0aW9uLmdldE9iamVjdCgpO1xuICB9XG5cbiAgZ2V0SW1tdXRhYmxlRmVhdHVyZUNvbGxlY3Rpb24oKTogSW1tdXRhYmxlRmVhdHVyZUNvbGxlY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVDb2xsZWN0aW9uO1xuICB9XG5cbiAgZ2V0U2VsZWN0ZWRGZWF0dXJlKCk6IEZlYXR1cmUgfCBudWxsIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5fc2VsZWN0ZWRGZWF0dXJlSW5kZXhlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiB0aGlzLmZlYXR1cmVDb2xsZWN0aW9uLmdldE9iamVjdCgpLmZlYXR1cmVzW3RoaXMuX3NlbGVjdGVkRmVhdHVyZUluZGV4ZXNbMF1dO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGdldFNlbGVjdGVkR2VvbWV0cnkoKTogR2VvbWV0cnkgfCBudWxsIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBmZWF0dXJlID0gdGhpcy5nZXRTZWxlY3RlZEZlYXR1cmUoKTtcbiAgICBpZiAoZmVhdHVyZSkge1xuICAgICAgcmV0dXJuIGZlYXR1cmUuZ2VvbWV0cnk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZ2V0U2VsZWN0ZWRGZWF0dXJlc0FzRmVhdHVyZUNvbGxlY3Rpb24oKTogRmVhdHVyZUNvbGxlY3Rpb24ge1xuICAgIGNvbnN0IHsgZmVhdHVyZXMgfSA9IHRoaXMuZmVhdHVyZUNvbGxlY3Rpb24uZ2V0T2JqZWN0KCk7XG4gICAgY29uc3Qgc2VsZWN0ZWRGZWF0dXJlcyA9IHRoaXMuZ2V0U2VsZWN0ZWRGZWF0dXJlSW5kZXhlcygpLm1hcChcbiAgICAgIChzZWxlY3RlZEluZGV4KSA9PiBmZWF0dXJlc1tzZWxlY3RlZEluZGV4XVxuICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdGZWF0dXJlQ29sbGVjdGlvbicsXG4gICAgICBmZWF0dXJlczogc2VsZWN0ZWRGZWF0dXJlcyxcbiAgICB9O1xuICB9XG5cbiAgc2V0RmVhdHVyZUNvbGxlY3Rpb24oZmVhdHVyZUNvbGxlY3Rpb246IEZlYXR1cmVDb2xsZWN0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5mZWF0dXJlQ29sbGVjdGlvbiA9IG5ldyBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbihmZWF0dXJlQ29sbGVjdGlvbik7XG4gIH1cblxuICBnZXRNb2RlQ29uZmlnKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGVDb25maWc7XG4gIH1cblxuICBzZXRNb2RlQ29uZmlnKG1vZGVDb25maWc6IGFueSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9tb2RlQ29uZmlnID09PSBtb2RlQ29uZmlnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fbW9kZUNvbmZpZyA9IG1vZGVDb25maWc7XG4gICAgdGhpcy5fc2V0VGVudGF0aXZlRmVhdHVyZShudWxsKTtcbiAgfVxuXG4gIGdldFNlbGVjdGVkRmVhdHVyZUluZGV4ZXMoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZEZlYXR1cmVJbmRleGVzO1xuICB9XG5cbiAgc2V0U2VsZWN0ZWRGZWF0dXJlSW5kZXhlcyhpbmRleGVzOiBudW1iZXJbXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9zZWxlY3RlZEZlYXR1cmVJbmRleGVzID09PSBpbmRleGVzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fc2VsZWN0ZWRGZWF0dXJlSW5kZXhlcyA9IGluZGV4ZXM7XG4gICAgdGhpcy5fc2V0VGVudGF0aXZlRmVhdHVyZShudWxsKTtcbiAgfVxuXG4gIGdldENsaWNrU2VxdWVuY2UoKTogUG9zaXRpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWNrU2VxdWVuY2U7XG4gIH1cblxuICByZXNldENsaWNrU2VxdWVuY2UoKTogdm9pZCB7XG4gICAgdGhpcy5fY2xpY2tTZXF1ZW5jZSA9IFtdO1xuICB9XG5cbiAgZ2V0VGVudGF0aXZlRmVhdHVyZSgpOiBGZWF0dXJlIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3RlbnRhdGl2ZUZlYXR1cmU7XG4gIH1cblxuICAvLyBUT0RPOiByZW1vdmUgdGhlIHVuZGVyc2NvcmVcbiAgX3NldFRlbnRhdGl2ZUZlYXR1cmUodGVudGF0aXZlRmVhdHVyZTogRmVhdHVyZSB8IG51bGwgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICB0aGlzLl90ZW50YXRpdmVGZWF0dXJlID0gdGVudGF0aXZlRmVhdHVyZTtcbiAgICBpZiAoIXRlbnRhdGl2ZUZlYXR1cmUpIHtcbiAgICAgIC8vIFJlc2V0IHRoZSBjbGljayBzZXF1ZW5jZVxuICAgICAgdGhpcy5fY2xpY2tTZXF1ZW5jZSA9IFtdO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgZmxhdCBhcnJheSBvZiBwb3NpdGlvbnMgZm9yIHRoZSBnaXZlbiBmZWF0dXJlIGFsb25nIHdpdGggdGhlaXIgaW5kZXhlcyBpbnRvIHRoZSBmZWF0dXJlJ3MgZ2VvbWV0cnkncyBjb29yZGluYXRlcy5cbiAgICpcbiAgICogQHBhcmFtIGZlYXR1cmVJbmRleCBUaGUgaW5kZXggb2YgdGhlIGZlYXR1cmUgdG8gZ2V0IGVkaXQgaGFuZGxlc1xuICAgKi9cbiAgZ2V0RWRpdEhhbmRsZXMocGlja3M/OiBBcnJheTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiwgZ3JvdW5kQ29vcmRzPzogUG9zaXRpb24pOiBFZGl0SGFuZGxlW10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGdldEN1cnNvcih7IGlzRHJhZ2dpbmcgfTogeyBpc0RyYWdnaW5nOiBib29sZWFuIH0pOiBzdHJpbmcge1xuICAgIHJldHVybiAnY2VsbCc7XG4gIH1cblxuICBpc1NlbGVjdGlvblBpY2tlZChwaWNrczogRGVja0dMUGlja1tdKTogYm9vbGVhbiB7XG4gICAgaWYgKCFwaWNrcy5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBwaWNrZWRJbmRleGVzID0gcGlja3MubWFwKCh7IGluZGV4IH0pID0+IGluZGV4KTtcbiAgICBjb25zdCBzZWxlY3RlZEZlYXR1cmVJbmRleGVzID0gdGhpcy5nZXRTZWxlY3RlZEZlYXR1cmVJbmRleGVzKCk7XG4gICAgcmV0dXJuIHNlbGVjdGVkRmVhdHVyZUluZGV4ZXMuc29tZSgoaW5kZXgpID0+IHBpY2tlZEluZGV4ZXMuaW5jbHVkZXMoaW5kZXgpKTtcbiAgfVxuXG4gIGdldEFkZEZlYXR1cmVBY3Rpb24oZ2VvbWV0cnk6IEdlb21ldHJ5KTogRWRpdEFjdGlvbiB7XG4gICAgLy8gVW5zdXJlIHdoeSBmbG93IGNhbid0IGRlYWwgd2l0aCBHZW9tZXRyeSB0eXBlLCBidXQgdGhlcmUgSSBmaXhlZCBpdFxuICAgIGNvbnN0IGdlb21ldHJ5QXNBbnk6IGFueSA9IGdlb21ldHJ5O1xuXG4gICAgY29uc3QgdXBkYXRlZERhdGEgPSB0aGlzLmdldEltbXV0YWJsZUZlYXR1cmVDb2xsZWN0aW9uKClcbiAgICAgIC5hZGRGZWF0dXJlKHtcbiAgICAgICAgdHlwZTogJ0ZlYXR1cmUnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7fSxcbiAgICAgICAgZ2VvbWV0cnk6IGdlb21ldHJ5QXNBbnksXG4gICAgICB9KVxuICAgICAgLmdldE9iamVjdCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHVwZGF0ZWREYXRhLFxuICAgICAgZWRpdFR5cGU6ICdhZGRGZWF0dXJlJyxcbiAgICAgIGZlYXR1cmVJbmRleGVzOiBbdXBkYXRlZERhdGEuZmVhdHVyZXMubGVuZ3RoIC0gMV0sXG4gICAgICBlZGl0Q29udGV4dDoge1xuICAgICAgICBmZWF0dXJlSW5kZXhlczogW3VwZGF0ZWREYXRhLmZlYXR1cmVzLmxlbmd0aCAtIDFdLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgZ2V0QWRkTWFueUZlYXR1cmVzQWN0aW9uKGZlYXR1cmVDb2xsZWN0aW9uOiBGZWF0dXJlQ29sbGVjdGlvbik6IEVkaXRBY3Rpb24ge1xuICAgIGNvbnN0IGZlYXR1cmVzID0gZmVhdHVyZUNvbGxlY3Rpb24uZmVhdHVyZXM7XG4gICAgbGV0IHVwZGF0ZWREYXRhID0gdGhpcy5nZXRJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbigpO1xuICAgIGNvbnN0IGluaXRpYWxJbmRleCA9IHVwZGF0ZWREYXRhLmdldE9iamVjdCgpLmZlYXR1cmVzLmxlbmd0aDtcbiAgICBjb25zdCB1cGRhdGVkSW5kZXhlcyA9IFtdO1xuICAgIGZvciAoY29uc3QgZmVhdHVyZSBvZiBmZWF0dXJlcykge1xuICAgICAgY29uc3QgeyBwcm9wZXJ0aWVzLCBnZW9tZXRyeSB9ID0gZmVhdHVyZTtcbiAgICAgIGNvbnN0IGdlb21ldHJ5QXNBbnk6IGFueSA9IGdlb21ldHJ5O1xuICAgICAgdXBkYXRlZERhdGEgPSB1cGRhdGVkRGF0YS5hZGRGZWF0dXJlKHtcbiAgICAgICAgdHlwZTogJ0ZlYXR1cmUnLFxuICAgICAgICBwcm9wZXJ0aWVzLFxuICAgICAgICBnZW9tZXRyeTogZ2VvbWV0cnlBc0FueSxcbiAgICAgIH0pO1xuICAgICAgdXBkYXRlZEluZGV4ZXMucHVzaChpbml0aWFsSW5kZXggKyB1cGRhdGVkSW5kZXhlcy5sZW5ndGgpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB1cGRhdGVkRGF0YTogdXBkYXRlZERhdGEuZ2V0T2JqZWN0KCksXG4gICAgICBlZGl0VHlwZTogJ2FkZEZlYXR1cmUnLFxuICAgICAgZmVhdHVyZUluZGV4ZXM6IHVwZGF0ZWRJbmRleGVzLFxuICAgICAgZWRpdENvbnRleHQ6IHtcbiAgICAgICAgZmVhdHVyZUluZGV4ZXM6IHVwZGF0ZWRJbmRleGVzLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgZ2V0QWRkRmVhdHVyZU9yQm9vbGVhblBvbHlnb25BY3Rpb24oZ2VvbWV0cnk6IFBvbHlnb24pOiBFZGl0QWN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRGZWF0dXJlID0gdGhpcy5nZXRTZWxlY3RlZEZlYXR1cmUoKTtcbiAgICBjb25zdCBtb2RlQ29uZmlnID0gdGhpcy5nZXRNb2RlQ29uZmlnKCk7XG4gICAgaWYgKG1vZGVDb25maWcgJiYgbW9kZUNvbmZpZy5ib29sZWFuT3BlcmF0aW9uKSB7XG4gICAgICBpZiAoXG4gICAgICAgICFzZWxlY3RlZEZlYXR1cmUgfHxcbiAgICAgICAgKHNlbGVjdGVkRmVhdHVyZS5nZW9tZXRyeS50eXBlICE9PSAnUG9seWdvbicgJiZcbiAgICAgICAgICBzZWxlY3RlZEZlYXR1cmUuZ2VvbWV0cnkudHlwZSAhPT0gJ011bHRpUG9seWdvbicpXG4gICAgICApIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUsbm8tdW5kZWZcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICdib29sZWFuT3BlcmF0aW9uIG9ubHkgc3VwcG9ydGVkIGZvciBzaW5nbGUgUG9seWdvbiBvciBNdWx0aVBvbHlnb24gc2VsZWN0aW9uJ1xuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmVhdHVyZSA9IHtcbiAgICAgICAgdHlwZTogJ0ZlYXR1cmUnLFxuICAgICAgICBnZW9tZXRyeSxcbiAgICAgIH07XG5cbiAgICAgIGxldCB1cGRhdGVkR2VvbWV0cnk7XG4gICAgICBpZiAobW9kZUNvbmZpZy5ib29sZWFuT3BlcmF0aW9uID09PSAndW5pb24nKSB7XG4gICAgICAgIHVwZGF0ZWRHZW9tZXRyeSA9IHR1cmZVbmlvbihzZWxlY3RlZEZlYXR1cmUsIGZlYXR1cmUpO1xuICAgICAgfSBlbHNlIGlmIChtb2RlQ29uZmlnLmJvb2xlYW5PcGVyYXRpb24gPT09ICdkaWZmZXJlbmNlJykge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHVwZGF0ZWRHZW9tZXRyeSA9IHR1cmZEaWZmZXJlbmNlKHNlbGVjdGVkRmVhdHVyZSwgZmVhdHVyZSk7XG4gICAgICB9IGVsc2UgaWYgKG1vZGVDb25maWcuYm9vbGVhbk9wZXJhdGlvbiA9PT0gJ2ludGVyc2VjdGlvbicpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB1cGRhdGVkR2VvbWV0cnkgPSB0dXJmSW50ZXJzZWN0KHNlbGVjdGVkRmVhdHVyZSwgZmVhdHVyZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZSxuby11bmRlZlxuICAgICAgICBjb25zb2xlLndhcm4oYEludmFsaWQgYm9vbGVhbk9wZXJhdGlvbiAke21vZGVDb25maWcuYm9vbGVhbk9wZXJhdGlvbn1gKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmICghdXBkYXRlZEdlb21ldHJ5KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlLG5vLXVuZGVmXG4gICAgICAgIGNvbnNvbGUud2FybignQ2FuY2VsaW5nIGVkaXQuIEJvb2xlYW4gb3BlcmF0aW9uIGVyYXNlZCBlbnRpcmUgcG9seWdvbi4nKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZlYXR1cmVJbmRleCA9IHRoaXMuZ2V0U2VsZWN0ZWRGZWF0dXJlSW5kZXhlcygpWzBdO1xuXG4gICAgICBjb25zdCB1cGRhdGVkRGF0YSA9IHRoaXMuZ2V0SW1tdXRhYmxlRmVhdHVyZUNvbGxlY3Rpb24oKVxuICAgICAgICAucmVwbGFjZUdlb21ldHJ5KGZlYXR1cmVJbmRleCwgdXBkYXRlZEdlb21ldHJ5Lmdlb21ldHJ5KVxuICAgICAgICAuZ2V0T2JqZWN0KCk7XG5cbiAgICAgIGNvbnN0IGVkaXRBY3Rpb246IEVkaXRBY3Rpb24gPSB7XG4gICAgICAgIHVwZGF0ZWREYXRhLFxuICAgICAgICBlZGl0VHlwZTogJ3VuaW9uR2VvbWV0cnknLFxuICAgICAgICBmZWF0dXJlSW5kZXhlczogW2ZlYXR1cmVJbmRleF0sXG4gICAgICAgIGVkaXRDb250ZXh0OiB7XG4gICAgICAgICAgZmVhdHVyZUluZGV4ZXM6IFtmZWF0dXJlSW5kZXhdLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGVkaXRBY3Rpb247XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmdldEFkZEZlYXR1cmVBY3Rpb24oZ2VvbWV0cnkpO1xuICB9XG5cbiAgaGFuZGxlQ2xpY2soZXZlbnQ6IENsaWNrRXZlbnQpOiBFZGl0QWN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgdGhpcy5fY2xpY2tTZXF1ZW5jZS5wdXNoKGV2ZW50Lmdyb3VuZENvb3Jkcyk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGhhbmRsZVBvaW50ZXJNb3ZlKFxuICAgIGV2ZW50OiBQb2ludGVyTW92ZUV2ZW50XG4gICk6IHsgZWRpdEFjdGlvbjogRWRpdEFjdGlvbiB8IG51bGwgfCB1bmRlZmluZWQ7IGNhbmNlbE1hcFBhbjogYm9vbGVhbiB9IHtcbiAgICByZXR1cm4geyBlZGl0QWN0aW9uOiBudWxsLCBjYW5jZWxNYXBQYW46IGZhbHNlIH07XG4gIH1cblxuICBoYW5kbGVTdGFydERyYWdnaW5nKGV2ZW50OiBTdGFydERyYWdnaW5nRXZlbnQpOiBFZGl0QWN0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBoYW5kbGVTdG9wRHJhZ2dpbmcoZXZlbnQ6IFN0b3BEcmFnZ2luZ0V2ZW50KTogRWRpdEFjdGlvbiB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQaWNrZWRFZGl0SGFuZGxlKFxuICBwaWNrczogYW55W10gfCBudWxsIHwgdW5kZWZpbmVkXG4pOiBFZGl0SGFuZGxlIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGluZm8gPSBwaWNrcyAmJiBwaWNrcy5maW5kKChwaWNrKSA9PiBwaWNrLmlzRWRpdGluZ0hhbmRsZSk7XG4gIGlmIChpbmZvKSB7XG4gICAgcmV0dXJuIGluZm8ub2JqZWN0O1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW50ZXJtZWRpYXRlUG9zaXRpb24ocG9zaXRpb24xOiBQb3NpdGlvbiwgcG9zaXRpb24yOiBQb3NpdGlvbik6IFBvc2l0aW9uIHtcbiAgY29uc3QgaW50ZXJtZWRpYXRlUG9zaXRpb24gPSBbXG4gICAgKHBvc2l0aW9uMVswXSArIHBvc2l0aW9uMlswXSkgLyAyLjAsXG4gICAgKHBvc2l0aW9uMVsxXSArIHBvc2l0aW9uMlsxXSkgLyAyLjAsXG4gIF07XG4gIC8vIEB0cy1pZ25vcmVcbiAgcmV0dXJuIGludGVybWVkaWF0ZVBvc2l0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWRpdEhhbmRsZXNGb3JHZW9tZXRyeShcbiAgZ2VvbWV0cnk6IEdlb21ldHJ5LFxuICBmZWF0dXJlSW5kZXg6IG51bWJlcixcbiAgZWRpdEhhbmRsZVR5cGU6IEVkaXRIYW5kbGVUeXBlID0gJ2V4aXN0aW5nJ1xuKSB7XG4gIGxldCBoYW5kbGVzOiBFZGl0SGFuZGxlW10gPSBbXTtcblxuICBzd2l0Y2ggKGdlb21ldHJ5LnR5cGUpIHtcbiAgICBjYXNlICdQb2ludCc6XG4gICAgICAvLyBwb3NpdGlvbnMgYXJlIG5vdCBuZXN0ZWRcbiAgICAgIGhhbmRsZXMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBwb3NpdGlvbjogZ2VvbWV0cnkuY29vcmRpbmF0ZXMsXG4gICAgICAgICAgcG9zaXRpb25JbmRleGVzOiBbXSxcbiAgICAgICAgICBmZWF0dXJlSW5kZXgsXG4gICAgICAgICAgdHlwZTogZWRpdEhhbmRsZVR5cGUsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnTXVsdGlQb2ludCc6XG4gICAgY2FzZSAnTGluZVN0cmluZyc6XG4gICAgICAvLyBwb3NpdGlvbnMgYXJlIG5lc3RlZCAxIGxldmVsXG4gICAgICBoYW5kbGVzID0gaGFuZGxlcy5jb25jYXQoXG4gICAgICAgIGdldEVkaXRIYW5kbGVzRm9yQ29vcmRpbmF0ZXMoZ2VvbWV0cnkuY29vcmRpbmF0ZXMsIFtdLCBmZWF0dXJlSW5kZXgsIGVkaXRIYW5kbGVUeXBlKVxuICAgICAgKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgIGNhc2UgJ011bHRpTGluZVN0cmluZyc6XG4gICAgICAvLyBwb3NpdGlvbnMgYXJlIG5lc3RlZCAyIGxldmVsc1xuICAgICAgZm9yIChsZXQgYSA9IDA7IGEgPCBnZW9tZXRyeS5jb29yZGluYXRlcy5sZW5ndGg7IGErKykge1xuICAgICAgICBoYW5kbGVzID0gaGFuZGxlcy5jb25jYXQoXG4gICAgICAgICAgZ2V0RWRpdEhhbmRsZXNGb3JDb29yZGluYXRlcyhnZW9tZXRyeS5jb29yZGluYXRlc1thXSwgW2FdLCBmZWF0dXJlSW5kZXgsIGVkaXRIYW5kbGVUeXBlKVxuICAgICAgICApO1xuICAgICAgICBpZiAoZ2VvbWV0cnkudHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgICAgLy8gRG9uJ3QgcmVwZWF0IHRoZSBmaXJzdC9sYXN0IGhhbmRsZSBmb3IgUG9seWdvbnNcbiAgICAgICAgICBoYW5kbGVzID0gaGFuZGxlcy5zbGljZSgwLCAtMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnTXVsdGlQb2x5Z29uJzpcbiAgICAgIC8vIHBvc2l0aW9ucyBhcmUgbmVzdGVkIDMgbGV2ZWxzXG4gICAgICBmb3IgKGxldCBhID0gMDsgYSA8IGdlb21ldHJ5LmNvb3JkaW5hdGVzLmxlbmd0aDsgYSsrKSB7XG4gICAgICAgIGZvciAobGV0IGIgPSAwOyBiIDwgZ2VvbWV0cnkuY29vcmRpbmF0ZXNbYV0ubGVuZ3RoOyBiKyspIHtcbiAgICAgICAgICBoYW5kbGVzID0gaGFuZGxlcy5jb25jYXQoXG4gICAgICAgICAgICBnZXRFZGl0SGFuZGxlc0ZvckNvb3JkaW5hdGVzKFxuICAgICAgICAgICAgICBnZW9tZXRyeS5jb29yZGluYXRlc1thXVtiXSxcbiAgICAgICAgICAgICAgW2EsIGJdLFxuICAgICAgICAgICAgICBmZWF0dXJlSW5kZXgsXG4gICAgICAgICAgICAgIGVkaXRIYW5kbGVUeXBlXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvLyBEb24ndCByZXBlYXQgdGhlIGZpcnN0L2xhc3QgaGFuZGxlIGZvciBQb2x5Z29uc1xuICAgICAgICAgIGhhbmRsZXMgPSBoYW5kbGVzLnNsaWNlKDAsIC0xKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhyb3cgRXJyb3IoYFVuaGFuZGxlZCBnZW9tZXRyeSB0eXBlOiAke2dlb21ldHJ5LnR5cGV9YCk7XG4gIH1cblxuICByZXR1cm4gaGFuZGxlcztcbn1cblxuZnVuY3Rpb24gZ2V0RWRpdEhhbmRsZXNGb3JDb29yZGluYXRlcyhcbiAgY29vcmRpbmF0ZXM6IGFueVtdLFxuICBwb3NpdGlvbkluZGV4UHJlZml4OiBudW1iZXJbXSxcbiAgZmVhdHVyZUluZGV4OiBudW1iZXIsXG4gIGVkaXRIYW5kbGVUeXBlOiBFZGl0SGFuZGxlVHlwZSA9ICdleGlzdGluZydcbik6IEVkaXRIYW5kbGVbXSB7XG4gIGNvbnN0IGVkaXRIYW5kbGVzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY29vcmRpbmF0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBwb3NpdGlvbiA9IGNvb3JkaW5hdGVzW2ldO1xuICAgIGVkaXRIYW5kbGVzLnB1c2goe1xuICAgICAgcG9zaXRpb24sXG4gICAgICBwb3NpdGlvbkluZGV4ZXM6IFsuLi5wb3NpdGlvbkluZGV4UHJlZml4LCBpXSxcbiAgICAgIGZlYXR1cmVJbmRleCxcbiAgICAgIHR5cGU6IGVkaXRIYW5kbGVUeXBlLFxuICAgIH0pO1xuICB9XG4gIHJldHVybiBlZGl0SGFuZGxlcztcbn1cbiJdfQ==
;