kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
267 lines (260 loc) • 33.1 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _utils = require("@kepler.gl/utils");
var _iterableTileSet = _interopRequireDefault(require("./iterable-tile-set"));
var _tileUtils = require("./tile-utils");
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
/**
* Per-tile stats, for caching
*/
/**
* Stateful class offering dataset-style functions for the set of tiles.
*/
var TileDataset = exports["default"] = /*#__PURE__*/function () {
function TileDataset(accessors, tiles) {
(0, _classCallCheck2["default"])(this, TileDataset);
(0, _defineProperty2["default"])(this, "accessors", void 0);
(0, _defineProperty2["default"])(this, "tiles", void 0);
(0, _defineProperty2["default"])(this, "tileSet", void 0);
(0, _defineProperty2["default"])(this, "tileIds", new Set());
/** Cache for per-tile field stats: tileId -> fieldId -> stats */
(0, _defineProperty2["default"])(this, "tileStats", new Map());
this.accessors = accessors;
this.tiles = [];
this.tileSet = new _iterableTileSet["default"]([], accessors.getRowCount);
if (tiles) {
this.updateTiles(tiles);
}
}
/**
* Invalidate the cached data
*/
return (0, _createClass2["default"])(TileDataset, [{
key: "invalidateCache",
value: function invalidateCache() {
// TODO: implement later
}
/**
* Update the set of tiles in the viewport
*/
}, {
key: "updateTiles",
value: function updateTiles(tiles) {
var _this$accessors = this.accessors,
getTileId = _this$accessors.getTileId,
getIterable = _this$accessors.getIterable,
getRowCount = _this$accessors.getRowCount;
var tileIds = new Set(tiles.map(getTileId));
if (!areEqualSets(tileIds, this.tileIds)) {
this.invalidateCache();
}
this.tiles = tiles;
this.tileIds = tileIds;
this.tileSet = new _iterableTileSet["default"](tiles.map(getIterable), getRowCount);
}
/**
* Get the min/max domain of a field
*/
}, {
key: "getExtent",
value: function getExtent(field) {
var _this$accessors2 = this.accessors,
getRowValue = _this$accessors2.getRowValue,
getIterable = _this$accessors2.getIterable;
var accessor = getRowValue(field);
var min = Infinity;
var max = -Infinity;
var _iterator = _createForOfIteratorHelper(this.tiles),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var tile = _step.value;
// Check the cache
var extent = this.getTileStat(tile, field, 'extent');
if (!extent) {
// Cache miss, calculate and cache
extent = getTileExtent(getIterable(tile), field, accessor);
this.setTileStat(tile, field, 'extent', extent);
}
if (extent) {
if (extent[0] < min) min = extent[0];
if (extent[1] > max) max = extent[1];
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return Number.isFinite(min) && Number.isFinite(max) ? [min, max] : [0, 0];
}
/**
* Get a sample of field values to use in estimating quantiles
*/
}, {
key: "getQuantileSample",
value: function getQuantileSample(field) {
var minRowCount = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
// TODO: There should be reasonable per-tile caching possible here
var set = this.tileSet;
var accessor = this.accessors.getRowValue(field);
var sample = [];
var sampleStep = Math.max(Math.floor(set.rowCount / minRowCount), 1);
var i = 0;
var _iterator2 = _createForOfIteratorHelper(set),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var _row = _step2.value;
if (++i === sampleStep) {
var val = accessor(field, _row);
if (val !== null) sample.push(val);
i = 0;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
(0, _utils.quickInsertionSort)(sample);
(0, _tileUtils.pruneQuantiles)(sample);
return sample;
}
/**
* Get a set of unique values for a field
*/
}, {
key: "getUniqueValues",
value: function getUniqueValues(field) {
var _this$accessors3 = this.accessors,
getRowValue = _this$accessors3.getRowValue,
getIterable = _this$accessors3.getIterable;
var accessor = getRowValue(field);
var uniques = new Set();
var _iterator3 = _createForOfIteratorHelper(this.tiles),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var _tileUniques;
var tile = _step3.value;
// Check the cache
var tileUniques = this.getTileStat(tile, field, 'uniqueValues');
if (!tileUniques) {
// Cache miss, calculate and cache
tileUniques = getTileUniqueValues(getIterable(tile), field, accessor);
this.setTileStat(tile, field, 'uniqueValues', tileUniques);
}
var _iterator4 = _createForOfIteratorHelper((_tileUniques = tileUniques) !== null && _tileUniques !== void 0 ? _tileUniques : []),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var val = _step4.value;
uniques.add(val);
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
return (0, _toConsumableArray2["default"])(uniques);
}
}, {
key: "getTileStat",
value: function getTileStat(tile, field, stat) {
var _this$tileStats$get;
return (_this$tileStats$get = this.tileStats.get(this.accessors.getTileId(tile))) === null || _this$tileStats$get === void 0 || (_this$tileStats$get = _this$tileStats$get.get(field.name)) === null || _this$tileStats$get === void 0 ? void 0 : _this$tileStats$get[stat];
}
}, {
key: "setTileStat",
value: function setTileStat(tile, field, stat, value) {
var _this$tileStats$get2, _tileStats$get;
var tileId = this.accessors.getTileId(tile);
var tileStats = (_this$tileStats$get2 = this.tileStats.get(tileId)) !== null && _this$tileStats$get2 !== void 0 ? _this$tileStats$get2 : new Map();
var tileFieldStats = (_tileStats$get = tileStats.get(field.name)) !== null && _tileStats$get !== void 0 ? _tileStats$get : {};
tileFieldStats[stat] = value;
tileStats.set(field.name, tileFieldStats);
this.tileStats.set(tileId, tileStats);
}
}]);
}();
/**
* Get the min/max domain of a field in a given tile
*/
function getTileExtent(iterable, field, accessor) {
var min = Infinity;
var max = -Infinity;
var _iterator5 = _createForOfIteratorHelper(iterable),
_step5;
try {
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
var _row2 = _step5.value;
var val = accessor(field, _row2);
if (val === null) continue;
if (val < min) min = val;
if (val > max) max = val;
}
} catch (err) {
_iterator5.e(err);
} finally {
_iterator5.f();
}
return Number.isFinite(min) && Number.isFinite(max) ? [min, max] : undefined;
}
/**
* Get unique values for a field in a given tile
*/
function getTileUniqueValues(iterable, field, accessor) {
var maxUniques = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 20;
var uniques = new Set();
var _iterator6 = _createForOfIteratorHelper(iterable),
_step6;
try {
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
var _row3 = _step6.value;
if (uniques.size >= maxUniques) return uniques;
uniques.add(accessor(field, _row3));
}
} catch (err) {
_iterator6.e(err);
} finally {
_iterator6.f();
}
return uniques;
}
function areEqualSets(a, b) {
if (a.size !== b.size) return false;
var _iterator7 = _createForOfIteratorHelper(a),
_step7;
try {
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
var val = _step7.value;
if (!b.has(val)) {
return false;
}
}
} catch (err) {
_iterator7.e(err);
} finally {
_iterator7.f();
}
return true;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdXRpbHMiLCJyZXF1aXJlIiwiX2l0ZXJhYmxlVGlsZVNldCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfdGlsZVV0aWxzIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJUaWxlRGF0YXNldCIsImV4cG9ydHMiLCJhY2Nlc3NvcnMiLCJ0aWxlcyIsIl9jbGFzc0NhbGxDaGVjazIiLCJfZGVmaW5lUHJvcGVydHkyIiwiU2V0IiwiTWFwIiwidGlsZVNldCIsIkl0ZXJhYmxlVGlsZVNldCIsImdldFJvd0NvdW50IiwidXBkYXRlVGlsZXMiLCJfY3JlYXRlQ2xhc3MyIiwia2V5IiwiaW52YWxpZGF0ZUNhY2hlIiwiX3RoaXMkYWNjZXNzb3JzIiwiZ2V0VGlsZUlkIiwiZ2V0SXRlcmFibGUiLCJ0aWxlSWRzIiwibWFwIiwiYXJlRXF1YWxTZXRzIiwiZ2V0RXh0ZW50IiwiZmllbGQiLCJfdGhpcyRhY2Nlc3NvcnMyIiwiZ2V0Um93VmFsdWUiLCJhY2Nlc3NvciIsIm1pbiIsIkluZmluaXR5IiwibWF4IiwiX2l0ZXJhdG9yIiwiX3N0ZXAiLCJ0aWxlIiwiZXh0ZW50IiwiZ2V0VGlsZVN0YXQiLCJnZXRUaWxlRXh0ZW50Iiwic2V0VGlsZVN0YXQiLCJlcnIiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImdldFF1YW50aWxlU2FtcGxlIiwibWluUm93Q291bnQiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJzZXQiLCJzYW1wbGUiLCJzYW1wbGVTdGVwIiwiTWF0aCIsImZsb29yIiwicm93Q291bnQiLCJpIiwiX2l0ZXJhdG9yMiIsIl9zdGVwMiIsInJvdyIsInZhbCIsInB1c2giLCJxdWlja0luc2VydGlvblNvcnQiLCJwcnVuZVF1YW50aWxlcyIsImdldFVuaXF1ZVZhbHVlcyIsIl90aGlzJGFjY2Vzc29yczMiLCJ1bmlxdWVzIiwiX2l0ZXJhdG9yMyIsIl9zdGVwMyIsIl90aWxlVW5pcXVlcyIsInRpbGVVbmlxdWVzIiwiZ2V0VGlsZVVuaXF1ZVZhbHVlcyIsIl9pdGVyYXRvcjQiLCJfc3RlcDQiLCJhZGQiLCJfdG9Db25zdW1hYmxlQXJyYXkyIiwic3RhdCIsIl90aGlzJHRpbGVTdGF0cyRnZXQiLCJ0aWxlU3RhdHMiLCJnZXQiLCJfdGhpcyR0aWxlU3RhdHMkZ2V0MiIsIl90aWxlU3RhdHMkZ2V0IiwidGlsZUlkIiwidGlsZUZpZWxkU3RhdHMiLCJpdGVyYWJsZSIsIl9pdGVyYXRvcjUiLCJfc3RlcDUiLCJtYXhVbmlxdWVzIiwiX2l0ZXJhdG9yNiIsIl9zdGVwNiIsInNpemUiLCJiIiwiX2l0ZXJhdG9yNyIsIl9zdGVwNyIsImhhcyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy92ZWN0b3ItdGlsZS9jb21tb24tdGlsZS90aWxlLWRhdGFzZXQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHtGaWVsZCBhcyBLZXBsZXJGaWVsZH0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQge3F1aWNrSW5zZXJ0aW9uU29ydH0gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5cbmltcG9ydCBJdGVyYWJsZVRpbGVTZXQsIHtSb3dDb3VudEFjY2Vzc29yfSBmcm9tICcuL2l0ZXJhYmxlLXRpbGUtc2V0JztcbmltcG9ydCB7cHJ1bmVRdWFudGlsZXN9IGZyb20gJy4vdGlsZS11dGlscyc7XG5cbmV4cG9ydCB0eXBlIERhdHVtID0gbnVtYmVyIHwgc3RyaW5nIHwgbnVsbDtcblxudHlwZSBSb3dWYWx1ZUFjY2Vzc29yPFQ+ID0gKFxuICBmaWVsZDogS2VwbGVyRmllbGQsXG4gIHJvdzogVCBleHRlbmRzIEl0ZXJhYmxlPGluZmVyIFY+ID8gViA6IG5ldmVyXG4pID0+IERhdHVtO1xudHlwZSBSb3dWYWx1ZUFjY2Vzc29yRmFjdG9yeTxUPiA9IChcbiAgZmllbGQ/OiBLZXBsZXJGaWVsZCxcbiAgaW5kZXhLZXk/OiBudW1iZXIgfCBudWxsXG4pID0+IFJvd1ZhbHVlQWNjZXNzb3I8VD47XG5cbnR5cGUgVGlsZUFjY2Vzc29yczxULCBJIGV4dGVuZHMgSXRlcmFibGU8YW55PiA9IFQgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+ID8gVCA6IG5ldmVyPiA9IHtcbiAgZ2V0VGlsZUlkOiAodGlsZTogVCkgPT4gc3RyaW5nO1xuICBnZXRJdGVyYWJsZTogKHRpbGU6IFQpID0+IEk7XG4gIGdldFJvd0NvdW50OiBSb3dDb3VudEFjY2Vzc29yPEk+O1xuICBnZXRSb3dWYWx1ZTogUm93VmFsdWVBY2Nlc3NvckZhY3Rvcnk8ST47XG59O1xuXG4vKipcbiAqIFBlci10aWxlIHN0YXRzLCBmb3IgY2FjaGluZ1xuICovXG50eXBlIFRpbGVGaWVsZFN0YXRzID0ge1xuICBleHRlbnQ/OiBbbnVtYmVyLCBudW1iZXJdO1xuICBzYW1wbGU/OiBEYXR1bVtdO1xuICB1bmlxdWVWYWx1ZXM/OiBTZXQ8RGF0dW0+O1xufTtcblxuLyoqXG4gKiBTdGF0ZWZ1bCBjbGFzcyBvZmZlcmluZyBkYXRhc2V0LXN0eWxlIGZ1bmN0aW9ucyBmb3IgdGhlIHNldCBvZiB0aWxlcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGlsZURhdGFzZXQ8VCwgSSBleHRlbmRzIEl0ZXJhYmxlPGFueT4gPSBUIGV4dGVuZHMgSXRlcmFibGU8YW55PiA/IFQgOiBuZXZlcj4ge1xuICBwcml2YXRlIGFjY2Vzc29yczogVGlsZUFjY2Vzc29yczxULCBJPjtcbiAgcHJpdmF0ZSB0aWxlczogcmVhZG9ubHkgVFtdO1xuICBwcml2YXRlIHRpbGVTZXQ6IEl0ZXJhYmxlVGlsZVNldDxJPjtcbiAgcHJpdmF0ZSB0aWxlSWRzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcblxuICAvKiogQ2FjaGUgZm9yIHBlci10aWxlIGZpZWxkIHN0YXRzOiB0aWxlSWQgLT4gZmllbGRJZCAtPiBzdGF0cyAqL1xuICBwcml2YXRlIHRpbGVTdGF0czogTWFwPHN0cmluZywgTWFwPHN0cmluZywgVGlsZUZpZWxkU3RhdHM+PiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihhY2Nlc3NvcnM6IFRpbGVBY2Nlc3NvcnM8VCwgST4sIHRpbGVzPzogcmVhZG9ubHkgVFtdKSB7XG4gICAgdGhpcy5hY2Nlc3NvcnMgPSBhY2Nlc3NvcnM7XG4gICAgdGhpcy50aWxlcyA9IFtdO1xuICAgIHRoaXMudGlsZVNldCA9IG5ldyBJdGVyYWJsZVRpbGVTZXQoW10sIGFjY2Vzc29ycy5nZXRSb3dDb3VudCk7XG4gICAgaWYgKHRpbGVzKSB7XG4gICAgICB0aGlzLnVwZGF0ZVRpbGVzKHRpbGVzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW52YWxpZGF0ZSB0aGUgY2FjaGVkIGRhdGFcbiAgICovXG4gIGludmFsaWRhdGVDYWNoZSgpOiB2b2lkIHtcbiAgICAvLyBUT0RPOiBpbXBsZW1lbnQgbGF0ZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIHNldCBvZiB0aWxlcyBpbiB0aGUgdmlld3BvcnRcbiAgICovXG4gIHVwZGF0ZVRpbGVzKHRpbGVzOiByZWFkb25seSBUW10pOiB2b2lkIHtcbiAgICBjb25zdCB7Z2V0VGlsZUlkLCBnZXRJdGVyYWJsZSwgZ2V0Um93Q291bnR9ID0gdGhpcy5hY2Nlc3NvcnM7XG4gICAgY29uc3QgdGlsZUlkcyA9IG5ldyBTZXQ8c3RyaW5nPih0aWxlcy5tYXAoZ2V0VGlsZUlkKSk7XG4gICAgaWYgKCFhcmVFcXVhbFNldHModGlsZUlkcywgdGhpcy50aWxlSWRzKSkge1xuICAgICAgdGhpcy5pbnZhbGlkYXRlQ2FjaGUoKTtcbiAgICB9XG4gICAgdGhpcy50aWxlcyA9IHRpbGVzO1xuICAgIHRoaXMudGlsZUlkcyA9IHRpbGVJZHM7XG4gICAgdGhpcy50aWxlU2V0ID0gbmV3IEl0ZXJhYmxlVGlsZVNldCh0aWxlcy5tYXAoZ2V0SXRlcmFibGUpLCBnZXRSb3dDb3VudCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBtaW4vbWF4IGRvbWFpbiBvZiBhIGZpZWxkXG4gICAqL1xuICBnZXRFeHRlbnQoZmllbGQ6IEtlcGxlckZpZWxkKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3Qge2dldFJvd1ZhbHVlLCBnZXRJdGVyYWJsZX0gPSB0aGlzLmFjY2Vzc29ycztcbiAgICBjb25zdCBhY2Nlc3NvciA9IGdldFJvd1ZhbHVlKGZpZWxkKTtcbiAgICBsZXQgbWluID0gSW5maW5pdHk7XG4gICAgbGV0IG1heCA9IC1JbmZpbml0eTtcblxuICAgIGZvciAoY29uc3QgdGlsZSBvZiB0aGlzLnRpbGVzKSB7XG4gICAgICAvLyBDaGVjayB0aGUgY2FjaGVcbiAgICAgIGxldCBleHRlbnQgPSB0aGlzLmdldFRpbGVTdGF0KHRpbGUsIGZpZWxkLCAnZXh0ZW50Jyk7XG4gICAgICBpZiAoIWV4dGVudCkge1xuICAgICAgICAvLyBDYWNoZSBtaXNzLCBjYWxjdWxhdGUgYW5kIGNhY2hlXG4gICAgICAgIGV4dGVudCA9IGdldFRpbGVFeHRlbnQoZ2V0SXRlcmFibGUodGlsZSksIGZpZWxkLCBhY2Nlc3Nvcik7XG4gICAgICAgIHRoaXMuc2V0VGlsZVN0YXQodGlsZSwgZmllbGQsICdleHRlbnQnLCBleHRlbnQpO1xuICAgICAgfVxuICAgICAgaWYgKGV4dGVudCkge1xuICAgICAgICBpZiAoZXh0ZW50WzBdIDwgbWluKSBtaW4gPSBleHRlbnRbMF07XG4gICAgICAgIGlmIChleHRlbnRbMV0gPiBtYXgpIG1heCA9IGV4dGVudFsxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShtaW4pICYmIE51bWJlci5pc0Zpbml0ZShtYXgpID8gW21pbiwgbWF4XSA6IFswLCAwXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBzYW1wbGUgb2YgZmllbGQgdmFsdWVzIHRvIHVzZSBpbiBlc3RpbWF0aW5nIHF1YW50aWxlc1xuICAgKi9cbiAgZ2V0UXVhbnRpbGVTYW1wbGUoZmllbGQ6IEtlcGxlckZpZWxkLCBtaW5Sb3dDb3VudCA9IDEwMDApOiBudW1iZXJbXSB7XG4gICAgLy8gVE9ETzogVGhlcmUgc2hvdWxkIGJlIHJlYXNvbmFibGUgcGVyLXRpbGUgY2FjaGluZyBwb3NzaWJsZSBoZXJlXG4gICAgY29uc3Qgc2V0ID0gdGhpcy50aWxlU2V0O1xuICAgIGNvbnN0IGFjY2Vzc29yID0gdGhpcy5hY2Nlc3NvcnMuZ2V0Um93VmFsdWUoZmllbGQpO1xuICAgIGNvbnN0IHNhbXBsZTogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBzYW1wbGVTdGVwID0gTWF0aC5tYXgoTWF0aC5mbG9vcihzZXQucm93Q291bnQgLyBtaW5Sb3dDb3VudCksIDEpO1xuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiBzZXQpIHtcbiAgICAgIGlmICgrK2kgPT09IHNhbXBsZVN0ZXApIHtcbiAgICAgICAgY29uc3QgdmFsID0gYWNjZXNzb3IoZmllbGQsIHJvdykgYXMgbnVtYmVyIHwgbnVsbDtcbiAgICAgICAgaWYgKHZhbCAhPT0gbnVsbCkgc2FtcGxlLnB1c2godmFsKTtcbiAgICAgICAgaSA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHF1aWNrSW5zZXJ0aW9uU29ydChzYW1wbGUpO1xuICAgIHBydW5lUXVhbnRpbGVzKHNhbXBsZSk7XG4gICAgcmV0dXJuIHNhbXBsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBzZXQgb2YgdW5pcXVlIHZhbHVlcyBmb3IgYSBmaWVsZFxuICAgKi9cbiAgZ2V0VW5pcXVlVmFsdWVzKGZpZWxkOiBLZXBsZXJGaWVsZCk6IERhdHVtW10ge1xuICAgIGNvbnN0IHtnZXRSb3dWYWx1ZSwgZ2V0SXRlcmFibGV9ID0gdGhpcy5hY2Nlc3NvcnM7XG4gICAgY29uc3QgYWNjZXNzb3IgPSBnZXRSb3dWYWx1ZShmaWVsZCk7XG4gICAgY29uc3QgdW5pcXVlcyA9IG5ldyBTZXQ8RGF0dW0+KCk7XG5cbiAgICBmb3IgKGNvbnN0IHRpbGUgb2YgdGhpcy50aWxlcykge1xuICAgICAgLy8gQ2hlY2sgdGhlIGNhY2hlXG4gICAgICBsZXQgdGlsZVVuaXF1ZXMgPSB0aGlzLmdldFRpbGVTdGF0KHRpbGUsIGZpZWxkLCAndW5pcXVlVmFsdWVzJyk7XG4gICAgICBpZiAoIXRpbGVVbmlxdWVzKSB7XG4gICAgICAgIC8vIENhY2hlIG1pc3MsIGNhbGN1bGF0ZSBhbmQgY2FjaGVcbiAgICAgICAgdGlsZVVuaXF1ZXMgPSBnZXRUaWxlVW5pcXVlVmFsdWVzKGdldEl0ZXJhYmxlKHRpbGUpLCBmaWVsZCwgYWNjZXNzb3IpO1xuICAgICAgICB0aGlzLnNldFRpbGVTdGF0KHRpbGUsIGZpZWxkLCAndW5pcXVlVmFsdWVzJywgdGlsZVVuaXF1ZXMpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB2YWwgb2YgdGlsZVVuaXF1ZXMgPz8gW10pIHtcbiAgICAgICAgdW5pcXVlcy5hZGQodmFsKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFsuLi51bmlxdWVzXTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VGlsZVN0YXQ8SyBleHRlbmRzIGtleW9mIFRpbGVGaWVsZFN0YXRzPihcbiAgICB0aWxlOiBULFxuICAgIGZpZWxkOiBLZXBsZXJGaWVsZCxcbiAgICBzdGF0OiBLXG4gICk6IFRpbGVGaWVsZFN0YXRzW0tdIHtcbiAgICByZXR1cm4gdGhpcy50aWxlU3RhdHMuZ2V0KHRoaXMuYWNjZXNzb3JzLmdldFRpbGVJZCh0aWxlKSk/LmdldChmaWVsZC5uYW1lKT8uW3N0YXRdO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRUaWxlU3RhdDxLIGV4dGVuZHMga2V5b2YgVGlsZUZpZWxkU3RhdHM+KFxuICAgIHRpbGU6IFQsXG4gICAgZmllbGQ6IEtlcGxlckZpZWxkLFxuICAgIHN0YXQ6IEssXG4gICAgdmFsdWU6IFRpbGVGaWVsZFN0YXRzW0tdXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHRpbGVJZCA9IHRoaXMuYWNjZXNzb3JzLmdldFRpbGVJZCh0aWxlKTtcbiAgICBjb25zdCB0aWxlU3RhdHMgPSB0aGlzLnRpbGVTdGF0cy5nZXQodGlsZUlkKSA/PyBuZXcgTWFwKCk7XG4gICAgY29uc3QgdGlsZUZpZWxkU3RhdHMgPSB0aWxlU3RhdHMuZ2V0KGZpZWxkLm5hbWUpID8/IHt9O1xuICAgIHRpbGVGaWVsZFN0YXRzW3N0YXRdID0gdmFsdWU7XG4gICAgdGlsZVN0YXRzLnNldChmaWVsZC5uYW1lLCB0aWxlRmllbGRTdGF0cyk7XG4gICAgdGhpcy50aWxlU3RhdHMuc2V0KHRpbGVJZCwgdGlsZVN0YXRzKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgbWluL21heCBkb21haW4gb2YgYSBmaWVsZCBpbiBhIGdpdmVuIHRpbGVcbiAqL1xuZnVuY3Rpb24gZ2V0VGlsZUV4dGVudDxJIGV4dGVuZHMgSXRlcmFibGU8YW55Pj4oXG4gIGl0ZXJhYmxlOiBJLFxuICBmaWVsZDogS2VwbGVyRmllbGQsXG4gIGFjY2Vzc29yOiBSb3dWYWx1ZUFjY2Vzc29yPEk+XG4pOiBbbnVtYmVyLCBudW1iZXJdIHwgdW5kZWZpbmVkIHtcbiAgbGV0IG1pbiA9IEluZmluaXR5O1xuICBsZXQgbWF4ID0gLUluZmluaXR5O1xuICBmb3IgKGNvbnN0IHJvdyBvZiBpdGVyYWJsZSkge1xuICAgIGNvbnN0IHZhbCA9IGFjY2Vzc29yKGZpZWxkLCByb3cpIGFzIG51bWJlciB8IG51bGw7XG4gICAgaWYgKHZhbCA9PT0gbnVsbCkgY29udGludWU7XG4gICAgaWYgKHZhbCA8IG1pbikgbWluID0gdmFsO1xuICAgIGlmICh2YWwgPiBtYXgpIG1heCA9IHZhbDtcbiAgfVxuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG1pbikgJiYgTnVtYmVyLmlzRmluaXRlKG1heCkgPyBbbWluLCBtYXhdIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEdldCB1bmlxdWUgdmFsdWVzIGZvciBhIGZpZWxkIGluIGEgZ2l2ZW4gdGlsZVxuICovXG5mdW5jdGlvbiBnZXRUaWxlVW5pcXVlVmFsdWVzPEkgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+PihcbiAgaXRlcmFibGU6IEksXG4gIGZpZWxkOiBLZXBsZXJGaWVsZCxcbiAgYWNjZXNzb3I6IFJvd1ZhbHVlQWNjZXNzb3I8ST4sXG4gIG1heFVuaXF1ZXMgPSAyMFxuKTogU2V0PERhdHVtPiB7XG4gIGNvbnN0IHVuaXF1ZXMgPSBuZXcgU2V0PERhdHVtPigpO1xuICBmb3IgKGNvbnN0IHJvdyBvZiBpdGVyYWJsZSkge1xuICAgIGlmICh1bmlxdWVzLnNpemUgPj0gbWF4VW5pcXVlcykgcmV0dXJuIHVuaXF1ZXM7XG4gICAgdW5pcXVlcy5hZGQoYWNjZXNzb3IoZmllbGQsIHJvdykpO1xuICB9XG4gIHJldHVybiB1bmlxdWVzO1xufVxuXG5mdW5jdGlvbiBhcmVFcXVhbFNldHMoYTogU2V0PHN0cmluZz4sIGI6IFNldDxzdHJpbmc+KTogYm9vbGVhbiB7XG4gIGlmIChhLnNpemUgIT09IGIuc2l6ZSkgcmV0dXJuIGZhbHNlO1xuICBmb3IgKGNvbnN0IHZhbCBvZiBhKSB7XG4gICAgaWYgKCFiLmhhcyh2YWwpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUlBLElBQUFBLE1BQUEsR0FBQUMsT0FBQTtBQUVBLElBQUFDLGdCQUFBLEdBQUFDLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBRyxVQUFBLEdBQUFILE9BQUE7QUFBNEMsU0FBQUksMkJBQUFDLENBQUEsRUFBQUMsQ0FBQSxR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
;