UNPKG

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
"use strict"; 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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