kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
276 lines (268 loc) • 33.5 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);
}
/**
* Return current tiles
*/
}, {
key: "getTiles",
value: function getTiles() {
return this.tiles;
}
/**
* 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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdXRpbHMiLCJyZXF1aXJlIiwiX2l0ZXJhYmxlVGlsZVNldCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfdGlsZVV0aWxzIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJUaWxlRGF0YXNldCIsImV4cG9ydHMiLCJhY2Nlc3NvcnMiLCJ0aWxlcyIsIl9jbGFzc0NhbGxDaGVjazIiLCJfZGVmaW5lUHJvcGVydHkyIiwiU2V0IiwiTWFwIiwidGlsZVNldCIsIkl0ZXJhYmxlVGlsZVNldCIsImdldFJvd0NvdW50IiwidXBkYXRlVGlsZXMiLCJfY3JlYXRlQ2xhc3MyIiwia2V5IiwiaW52YWxpZGF0ZUNhY2hlIiwiX3RoaXMkYWNjZXNzb3JzIiwiZ2V0VGlsZUlkIiwiZ2V0SXRlcmFibGUiLCJ0aWxlSWRzIiwibWFwIiwiYXJlRXF1YWxTZXRzIiwiZ2V0VGlsZXMiLCJnZXRFeHRlbnQiLCJmaWVsZCIsIl90aGlzJGFjY2Vzc29yczIiLCJnZXRSb3dWYWx1ZSIsImFjY2Vzc29yIiwibWluIiwiSW5maW5pdHkiLCJtYXgiLCJfaXRlcmF0b3IiLCJfc3RlcCIsInRpbGUiLCJleHRlbnQiLCJnZXRUaWxlU3RhdCIsImdldFRpbGVFeHRlbnQiLCJzZXRUaWxlU3RhdCIsImVyciIsIk51bWJlciIsImlzRmluaXRlIiwiZ2V0UXVhbnRpbGVTYW1wbGUiLCJtaW5Sb3dDb3VudCIsImFyZ3VtZW50cyIsInVuZGVmaW5lZCIsInNldCIsInNhbXBsZSIsInNhbXBsZVN0ZXAiLCJNYXRoIiwiZmxvb3IiLCJyb3dDb3VudCIsImkiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwicm93IiwidmFsIiwicHVzaCIsInF1aWNrSW5zZXJ0aW9uU29ydCIsInBydW5lUXVhbnRpbGVzIiwiZ2V0VW5pcXVlVmFsdWVzIiwiX3RoaXMkYWNjZXNzb3JzMyIsInVuaXF1ZXMiLCJfaXRlcmF0b3IzIiwiX3N0ZXAzIiwiX3RpbGVVbmlxdWVzIiwidGlsZVVuaXF1ZXMiLCJnZXRUaWxlVW5pcXVlVmFsdWVzIiwiX2l0ZXJhdG9yNCIsIl9zdGVwNCIsImFkZCIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJzdGF0IiwiX3RoaXMkdGlsZVN0YXRzJGdldCIsInRpbGVTdGF0cyIsImdldCIsIl90aGlzJHRpbGVTdGF0cyRnZXQyIiwiX3RpbGVTdGF0cyRnZXQiLCJ0aWxlSWQiLCJ0aWxlRmllbGRTdGF0cyIsIml0ZXJhYmxlIiwiX2l0ZXJhdG9yNSIsIl9zdGVwNSIsIm1heFVuaXF1ZXMiLCJfaXRlcmF0b3I2IiwiX3N0ZXA2Iiwic2l6ZSIsImIiLCJfaXRlcmF0b3I3IiwiX3N0ZXA3IiwiaGFzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3ZlY3Rvci10aWxlL2NvbW1vbi10aWxlL3RpbGUtZGF0YXNldC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0ZpZWxkIGFzIEtlcGxlckZpZWxkfSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB7cXVpY2tJbnNlcnRpb25Tb3J0fSBmcm9tICdAa2VwbGVyLmdsL3V0aWxzJztcblxuaW1wb3J0IEl0ZXJhYmxlVGlsZVNldCwge1Jvd0NvdW50QWNjZXNzb3J9IGZyb20gJy4vaXRlcmFibGUtdGlsZS1zZXQnO1xuaW1wb3J0IHtwcnVuZVF1YW50aWxlc30gZnJvbSAnLi90aWxlLXV0aWxzJztcblxuZXhwb3J0IHR5cGUgRGF0dW0gPSBudW1iZXIgfCBzdHJpbmcgfCBudWxsO1xuXG50eXBlIFJvd1ZhbHVlQWNjZXNzb3I8VD4gPSAoXG4gIGZpZWxkOiBLZXBsZXJGaWVsZCxcbiAgcm93OiBUIGV4dGVuZHMgSXRlcmFibGU8aW5mZXIgVj4gPyBWIDogbmV2ZXJcbikgPT4gRGF0dW07XG50eXBlIFJvd1ZhbHVlQWNjZXNzb3JGYWN0b3J5PFQ+ID0gKFxuICBmaWVsZD86IEtlcGxlckZpZWxkLFxuICBpbmRleEtleT86IG51bWJlciB8IG51bGxcbikgPT4gUm93VmFsdWVBY2Nlc3NvcjxUPjtcblxudHlwZSBUaWxlQWNjZXNzb3JzPFQsIEkgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+ID0gVCBleHRlbmRzIEl0ZXJhYmxlPGFueT4gPyBUIDogbmV2ZXI+ID0ge1xuICBnZXRUaWxlSWQ6ICh0aWxlOiBUKSA9PiBzdHJpbmc7XG4gIGdldEl0ZXJhYmxlOiAodGlsZTogVCkgPT4gSTtcbiAgZ2V0Um93Q291bnQ6IFJvd0NvdW50QWNjZXNzb3I8ST47XG4gIGdldFJvd1ZhbHVlOiBSb3dWYWx1ZUFjY2Vzc29yRmFjdG9yeTxJPjtcbn07XG5cbi8qKlxuICogUGVyLXRpbGUgc3RhdHMsIGZvciBjYWNoaW5nXG4gKi9cbnR5cGUgVGlsZUZpZWxkU3RhdHMgPSB7XG4gIGV4dGVudD86IFtudW1iZXIsIG51bWJlcl07XG4gIHNhbXBsZT86IERhdHVtW107XG4gIHVuaXF1ZVZhbHVlcz86IFNldDxEYXR1bT47XG59O1xuXG4vKipcbiAqIFN0YXRlZnVsIGNsYXNzIG9mZmVyaW5nIGRhdGFzZXQtc3R5bGUgZnVuY3Rpb25zIGZvciB0aGUgc2V0IG9mIHRpbGVzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaWxlRGF0YXNldDxULCBJIGV4dGVuZHMgSXRlcmFibGU8YW55PiA9IFQgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+ID8gVCA6IG5ldmVyPiB7XG4gIHByaXZhdGUgYWNjZXNzb3JzOiBUaWxlQWNjZXNzb3JzPFQsIEk+O1xuICBwcml2YXRlIHRpbGVzOiByZWFkb25seSBUW107XG4gIHByaXZhdGUgdGlsZVNldDogSXRlcmFibGVUaWxlU2V0PEk+O1xuICBwcml2YXRlIHRpbGVJZHM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gIC8qKiBDYWNoZSBmb3IgcGVyLXRpbGUgZmllbGQgc3RhdHM6IHRpbGVJZCAtPiBmaWVsZElkIC0+IHN0YXRzICovXG4gIHByaXZhdGUgdGlsZVN0YXRzOiBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBUaWxlRmllbGRTdGF0cz4+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKGFjY2Vzc29yczogVGlsZUFjY2Vzc29yczxULCBJPiwgdGlsZXM/OiByZWFkb25seSBUW10pIHtcbiAgICB0aGlzLmFjY2Vzc29ycyA9IGFjY2Vzc29ycztcbiAgICB0aGlzLnRpbGVzID0gW107XG4gICAgdGhpcy50aWxlU2V0ID0gbmV3IEl0ZXJhYmxlVGlsZVNldChbXSwgYWNjZXNzb3JzLmdldFJvd0NvdW50KTtcbiAgICBpZiAodGlsZXMpIHtcbiAgICAgIHRoaXMudXBkYXRlVGlsZXModGlsZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZhbGlkYXRlIHRoZSBjYWNoZWQgZGF0YVxuICAgKi9cbiAgaW52YWxpZGF0ZUNhY2hlKCk6IHZvaWQge1xuICAgIC8vIFRPRE86IGltcGxlbWVudCBsYXRlclxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB0aGUgc2V0IG9mIHRpbGVzIGluIHRoZSB2aWV3cG9ydFxuICAgKi9cbiAgdXBkYXRlVGlsZXModGlsZXM6IHJlYWRvbmx5IFRbXSk6IHZvaWQge1xuICAgIGNvbnN0IHtnZXRUaWxlSWQsIGdldEl0ZXJhYmxlLCBnZXRSb3dDb3VudH0gPSB0aGlzLmFjY2Vzc29ycztcbiAgICBjb25zdCB0aWxlSWRzID0gbmV3IFNldDxzdHJpbmc+KHRpbGVzLm1hcChnZXRUaWxlSWQpKTtcbiAgICBpZiAoIWFyZUVxdWFsU2V0cyh0aWxlSWRzLCB0aGlzLnRpbGVJZHMpKSB7XG4gICAgICB0aGlzLmludmFsaWRhdGVDYWNoZSgpO1xuICAgIH1cbiAgICB0aGlzLnRpbGVzID0gdGlsZXM7XG4gICAgdGhpcy50aWxlSWRzID0gdGlsZUlkcztcbiAgICB0aGlzLnRpbGVTZXQgPSBuZXcgSXRlcmFibGVUaWxlU2V0KHRpbGVzLm1hcChnZXRJdGVyYWJsZSksIGdldFJvd0NvdW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gY3VycmVudCB0aWxlc1xuICAgKi9cbiAgZ2V0VGlsZXMoKTogcmVhZG9ubHkgVFtdIHtcbiAgICByZXR1cm4gdGhpcy50aWxlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbi9tYXggZG9tYWluIG9mIGEgZmllbGRcbiAgICovXG4gIGdldEV4dGVudChmaWVsZDogS2VwbGVyRmllbGQpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICBjb25zdCB7Z2V0Um93VmFsdWUsIGdldEl0ZXJhYmxlfSA9IHRoaXMuYWNjZXNzb3JzO1xuICAgIGNvbnN0IGFjY2Vzc29yID0gZ2V0Um93VmFsdWUoZmllbGQpO1xuICAgIGxldCBtaW4gPSBJbmZpbml0eTtcbiAgICBsZXQgbWF4ID0gLUluZmluaXR5O1xuXG4gICAgZm9yIChjb25zdCB0aWxlIG9mIHRoaXMudGlsZXMpIHtcbiAgICAgIC8vIENoZWNrIHRoZSBjYWNoZVxuICAgICAgbGV0IGV4dGVudCA9IHRoaXMuZ2V0VGlsZVN0YXQodGlsZSwgZmllbGQsICdleHRlbnQnKTtcbiAgICAgIGlmICghZXh0ZW50KSB7XG4gICAgICAgIC8vIENhY2hlIG1pc3MsIGNhbGN1bGF0ZSBhbmQgY2FjaGVcbiAgICAgICAgZXh0ZW50ID0gZ2V0VGlsZUV4dGVudChnZXRJdGVyYWJsZSh0aWxlKSwgZmllbGQsIGFjY2Vzc29yKTtcbiAgICAgICAgdGhpcy5zZXRUaWxlU3RhdCh0aWxlLCBmaWVsZCwgJ2V4dGVudCcsIGV4dGVudCk7XG4gICAgICB9XG4gICAgICBpZiAoZXh0ZW50KSB7XG4gICAgICAgIGlmIChleHRlbnRbMF0gPCBtaW4pIG1pbiA9IGV4dGVudFswXTtcbiAgICAgICAgaWYgKGV4dGVudFsxXSA+IG1heCkgbWF4ID0gZXh0ZW50WzFdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG1pbikgJiYgTnVtYmVyLmlzRmluaXRlKG1heCkgPyBbbWluLCBtYXhdIDogWzAsIDBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHNhbXBsZSBvZiBmaWVsZCB2YWx1ZXMgdG8gdXNlIGluIGVzdGltYXRpbmcgcXVhbnRpbGVzXG4gICAqL1xuICBnZXRRdWFudGlsZVNhbXBsZShmaWVsZDogS2VwbGVyRmllbGQsIG1pblJvd0NvdW50ID0gMTAwMCk6IG51bWJlcltdIHtcbiAgICAvLyBUT0RPOiBUaGVyZSBzaG91bGQgYmUgcmVhc29uYWJsZSBwZXItdGlsZSBjYWNoaW5nIHBvc3NpYmxlIGhlcmVcbiAgICBjb25zdCBzZXQgPSB0aGlzLnRpbGVTZXQ7XG4gICAgY29uc3QgYWNjZXNzb3IgPSB0aGlzLmFjY2Vzc29ycy5nZXRSb3dWYWx1ZShmaWVsZCk7XG4gICAgY29uc3Qgc2FtcGxlOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IHNhbXBsZVN0ZXAgPSBNYXRoLm1heChNYXRoLmZsb29yKHNldC5yb3dDb3VudCAvIG1pblJvd0NvdW50KSwgMSk7XG4gICAgbGV0IGkgPSAwO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHNldCkge1xuICAgICAgaWYgKCsraSA9PT0gc2FtcGxlU3RlcCkge1xuICAgICAgICBjb25zdCB2YWwgPSBhY2Nlc3NvcihmaWVsZCwgcm93KSBhcyBudW1iZXIgfCBudWxsO1xuICAgICAgICBpZiAodmFsICE9PSBudWxsKSBzYW1wbGUucHVzaCh2YWwpO1xuICAgICAgICBpID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgcXVpY2tJbnNlcnRpb25Tb3J0KHNhbXBsZSk7XG4gICAgcHJ1bmVRdWFudGlsZXMoc2FtcGxlKTtcbiAgICByZXR1cm4gc2FtcGxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHNldCBvZiB1bmlxdWUgdmFsdWVzIGZvciBhIGZpZWxkXG4gICAqL1xuICBnZXRVbmlxdWVWYWx1ZXMoZmllbGQ6IEtlcGxlckZpZWxkKTogRGF0dW1bXSB7XG4gICAgY29uc3Qge2dldFJvd1ZhbHVlLCBnZXRJdGVyYWJsZX0gPSB0aGlzLmFjY2Vzc29ycztcbiAgICBjb25zdCBhY2Nlc3NvciA9IGdldFJvd1ZhbHVlKGZpZWxkKTtcbiAgICBjb25zdCB1bmlxdWVzID0gbmV3IFNldDxEYXR1bT4oKTtcblxuICAgIGZvciAoY29uc3QgdGlsZSBvZiB0aGlzLnRpbGVzKSB7XG4gICAgICAvLyBDaGVjayB0aGUgY2FjaGVcbiAgICAgIGxldCB0aWxlVW5pcXVlcyA9IHRoaXMuZ2V0VGlsZVN0YXQodGlsZSwgZmllbGQsICd1bmlxdWVWYWx1ZXMnKTtcbiAgICAgIGlmICghdGlsZVVuaXF1ZXMpIHtcbiAgICAgICAgLy8gQ2FjaGUgbWlzcywgY2FsY3VsYXRlIGFuZCBjYWNoZVxuICAgICAgICB0aWxlVW5pcXVlcyA9IGdldFRpbGVVbmlxdWVWYWx1ZXMoZ2V0SXRlcmFibGUodGlsZSksIGZpZWxkLCBhY2Nlc3Nvcik7XG4gICAgICAgIHRoaXMuc2V0VGlsZVN0YXQodGlsZSwgZmllbGQsICd1bmlxdWVWYWx1ZXMnLCB0aWxlVW5pcXVlcyk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aWxlVW5pcXVlcyA/PyBbXSkge1xuICAgICAgICB1bmlxdWVzLmFkZCh2YWwpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gWy4uLnVuaXF1ZXNdO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUaWxlU3RhdDxLIGV4dGVuZHMga2V5b2YgVGlsZUZpZWxkU3RhdHM+KFxuICAgIHRpbGU6IFQsXG4gICAgZmllbGQ6IEtlcGxlckZpZWxkLFxuICAgIHN0YXQ6IEtcbiAgKTogVGlsZUZpZWxkU3RhdHNbS10ge1xuICAgIHJldHVybiB0aGlzLnRpbGVTdGF0cy5nZXQodGhpcy5hY2Nlc3NvcnMuZ2V0VGlsZUlkKHRpbGUpKT8uZ2V0KGZpZWxkLm5hbWUpPy5bc3RhdF07XG4gIH1cblxuICBwcml2YXRlIHNldFRpbGVTdGF0PEsgZXh0ZW5kcyBrZXlvZiBUaWxlRmllbGRTdGF0cz4oXG4gICAgdGlsZTogVCxcbiAgICBmaWVsZDogS2VwbGVyRmllbGQsXG4gICAgc3RhdDogSyxcbiAgICB2YWx1ZTogVGlsZUZpZWxkU3RhdHNbS11cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgdGlsZUlkID0gdGhpcy5hY2Nlc3NvcnMuZ2V0VGlsZUlkKHRpbGUpO1xuICAgIGNvbnN0IHRpbGVTdGF0cyA9IHRoaXMudGlsZVN0YXRzLmdldCh0aWxlSWQpID8/IG5ldyBNYXAoKTtcbiAgICBjb25zdCB0aWxlRmllbGRTdGF0cyA9IHRpbGVTdGF0cy5nZXQoZmllbGQubmFtZSkgPz8ge307XG4gICAgdGlsZUZpZWxkU3RhdHNbc3RhdF0gPSB2YWx1ZTtcbiAgICB0aWxlU3RhdHMuc2V0KGZpZWxkLm5hbWUsIHRpbGVGaWVsZFN0YXRzKTtcbiAgICB0aGlzLnRpbGVTdGF0cy5zZXQodGlsZUlkLCB0aWxlU3RhdHMpO1xuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBtaW4vbWF4IGRvbWFpbiBvZiBhIGZpZWxkIGluIGEgZ2l2ZW4gdGlsZVxuICovXG5mdW5jdGlvbiBnZXRUaWxlRXh0ZW50PEkgZXh0ZW5kcyBJdGVyYWJsZTxhbnk+PihcbiAgaXRlcmFibGU6IEksXG4gIGZpZWxkOiBLZXBsZXJGaWVsZCxcbiAgYWNjZXNzb3I6IFJvd1ZhbHVlQWNjZXNzb3I8ST5cbik6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQge1xuICBsZXQgbWluID0gSW5maW5pdHk7XG4gIGxldCBtYXggPSAtSW5maW5pdHk7XG4gIGZvciAoY29uc3Qgcm93IG9mIGl0ZXJhYmxlKSB7XG4gICAgY29uc3QgdmFsID0gYWNjZXNzb3IoZmllbGQsIHJvdykgYXMgbnVtYmVyIHwgbnVsbDtcbiAgICBpZiAodmFsID09PSBudWxsKSBjb250aW51ZTtcbiAgICBpZiAodmFsIDwgbWluKSBtaW4gPSB2YWw7XG4gICAgaWYgKHZhbCA+IG1heCkgbWF4ID0gdmFsO1xuICB9XG4gIHJldHVybiBOdW1iZXIuaXNGaW5pdGUobWluKSAmJiBOdW1iZXIuaXNGaW5pdGUobWF4KSA/IFttaW4sIG1heF0gOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2V0IHVuaXF1ZSB2YWx1ZXMgZm9yIGEgZmllbGQgaW4gYSBnaXZlbiB0aWxlXG4gKi9cbmZ1bmN0aW9uIGdldFRpbGVVbmlxdWVWYWx1ZXM8SSBleHRlbmRzIEl0ZXJhYmxlPGFueT4+KFxuICBpdGVyYWJsZTogSSxcbiAgZmllbGQ6IEtlcGxlckZpZWxkLFxuICBhY2Nlc3NvcjogUm93VmFsdWVBY2Nlc3NvcjxJPixcbiAgbWF4VW5pcXVlcyA9IDIwXG4pOiBTZXQ8RGF0dW0+IHtcbiAgY29uc3QgdW5pcXVlcyA9IG5ldyBTZXQ8RGF0dW0+KCk7XG4gIGZvciAoY29uc3Qgcm93IG9mIGl0ZXJhYmxlKSB7XG4gICAgaWYgKHVuaXF1ZXMuc2l6ZSA+PSBtYXhVbmlxdWVzKSByZXR1cm4gdW5pcXVlcztcbiAgICB1bmlxdWVzLmFkZChhY2Nlc3NvcihmaWVsZCwgcm93KSk7XG4gIH1cbiAgcmV0dXJuIHVuaXF1ZXM7XG59XG5cbmZ1bmN0aW9uIGFyZUVxdWFsU2V0cyhhOiBTZXQ8c3RyaW5nPiwgYjogU2V0PHN0cmluZz4pOiBib29sZWFuIHtcbiAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSByZXR1cm4gZmFsc2U7XG4gIGZvciAoY29uc3QgdmFsIG9mIGEpIHtcbiAgICBpZiAoIWIuaGFzKHZhbCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBSUEsSUFBQUEsTUFBQSxH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