kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
881 lines (859 loc) • 120 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getNumRasterTilesBeingLoaded = exports["default"] = exports.LOAD_ELEVATION_AFTER_ZOOM = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _typed = require("@deck.gl/core/typed");
var _typed2 = require("@deck.gl/geo-layers/typed");
var _pmtiles = require("@loaders.gl/pmtiles");
var _memoize = _interopRequireDefault(require("lodash/memoize"));
var _typed3 = require("@deck.gl/layers/typed");
var _constants = require("@kepler.gl/constants");
var _deckglLayers = require("@kepler.gl/deckgl-layers");
var _commonUtils = require("@kepler.gl/common-utils");
var _utils = require("@kepler.gl/utils");
var _config = require("./config");
var _gpuUtils = require("./gpu-utils");
var _image = require("./image");
var _rasterTileIcon = _interopRequireDefault(require("./raster-tile-icon"));
var _rasterTileUtils = require("./raster-tile-utils");
var _baseLayer = _interopRequireDefault(require("../base-layer"));
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; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _superPropGet(t, e, r, o) { var p = (0, _get2["default"])((0, _getPrototypeOf2["default"])(1 & o ? t.prototype : t), e, r); return 2 & o ? function (t) { return p.apply(r, t); } : p; } // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
// Adjust tileSize to devicePixelRatio, but not higher than 2 to reduce requests to server
var devicePixelRatio = Math.min(2, typeof window !== 'undefined' && window.devicePixelRatio || 1);
// Global counter that represents the number of tiles currently being loaded across all the raster tile layers
var tilesBeingLoaded = 0;
// This is a temp solution to track loading
var getNumRasterTilesBeingLoaded = exports.getNumRasterTilesBeingLoaded = function getNumRasterTilesBeingLoaded() {
return tilesBeingLoaded;
};
var LOAD_ELEVATION_AFTER_ZOOM = exports.LOAD_ELEVATION_AFTER_ZOOM = 8.9;
var getShouldLoadTerrain = function getShouldLoadTerrain(stac, mapState, visConfig) {
var _stac$rasterTileServe;
return Boolean(
// we need a raster tile server for elevations even when we user PMTiles
((_stac$rasterTileServe = stac.rasterTileServerUrls) === null || _stac$rasterTileServe === void 0 ? void 0 : _stac$rasterTileServe.length) > 0 &&
// check the switch from the layer configurator
visConfig.enableTerrain &&
// for now only in 3D mode, not top mode
mapState.dragRotate && (0, _utils.getApplicationConfig)().rasterServerSupportsElevation);
};
var RasterTileLayer = exports["default"] = /*#__PURE__*/function (_KeplerLayer) {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function RasterTileLayer(props) {
var _this;
(0, _classCallCheck2["default"])(this, RasterTileLayer);
_this = _callSuper(this, RasterTileLayer, [props]);
/** Min bands image data value, based on the current viewport */
(0, _defineProperty2["default"])(_this, "minViewportPixelValue", Infinity);
/** Max bands image data value, based on the current viewport */
(0, _defineProperty2["default"])(_this, "maxViewportPixelValue", -Infinity);
/** Memoized method that calculates data source params */
(0, _defineProperty2["default"])(_this, "getDataSourceParams", void 0);
_this.registerVisConfig(_config.rasterVisConfigs);
// No two STAC ids may be the same within a single collection, though it's conceivably possible
// across multiple STAC collections there could be an id collision. Note: STAC Collection
// objects don't have a `collection` key; STAC Item objects have a `collection` key (which
// matches the collection's `id`).
var resolver = function resolver(stac, preset, presetOptions) {
var _presetOptions$single, _presetOptions$single2;
return "".concat(stac.id, "-").concat(stac.collection, "-").concat(preset, "-").concat((_presetOptions$single = presetOptions.singleBand) === null || _presetOptions$single === void 0 ? void 0 : _presetOptions$single.assetId, "-").concat((_presetOptions$single2 = presetOptions.singleBand) === null || _presetOptions$single2 === void 0 ? void 0 : _presetOptions$single2.bandIndex);
};
_this.getDataSourceParams = (0, _memoize["default"])(function (stac, preset, presetOptions) {
return (0, _rasterTileUtils.getDataSourceParams)(stac, preset, presetOptions);
}, resolver);
_this.meta = {
zRange: null
};
return _this;
}
(0, _inherits2["default"])(RasterTileLayer, _KeplerLayer);
return (0, _createClass2["default"])(RasterTileLayer, [{
key: "type",
get: function get() {
return _constants.LAYER_TYPES.rasterTile;
}
}, {
key: "name",
get: function get() {
return 'Raster Tile';
}
}, {
key: "layerIcon",
get: function get() {
return _rasterTileIcon["default"];
}
}, {
key: "supportedDatasetTypes",
get: function get() {
return [_constants.DatasetType.RASTER_TILE];
}
}, {
key: "visualChannels",
get: function get() {
var categoricalColorLegends = this.config.visConfig.colorRange.colorLegends;
if (categoricalColorLegends) {
return {
color: _superPropGet(RasterTileLayer, "visualChannels", this, 1).color
};
} else {
return {};
}
}
}, {
key: "requireData",
get: function get() {
return true;
}
}, {
key: "getDefaultLayerConfig",
value: function getDefaultLayerConfig(props) {
return _objectSpread(_objectSpread({}, _superPropGet(RasterTileLayer, "getDefaultLayerConfig", this, 3)([props])), {}, {
colorField: {
analyzerType: '',
name: 'Category',
format: '',
type: 'string',
fieldIdx: -1,
valueAccessor: function valueAccessor() {
return '';
},
displayName: 'Category'
}
});
}
}, {
key: "getHoverData",
value: function getHoverData() {
return null;
}
// We can render without columns, so we redefine this method
}, {
key: "shouldRenderLayer",
value: function shouldRenderLayer() {
return Boolean(this.type && this.config.isVisible);
}
}, {
key: "formatLayerData",
value: function formatLayerData(datasets, oldLayerData) {
var _dataset$metadata;
var dataId = this.config.dataId;
if (!(0, _commonUtils.notNullorUndefined)(dataId)) {
return {};
}
var dataset = datasets[dataId];
// call updateData to updateLayerMeta
var dataUpdateTriggers = this.getDataUpdateTriggers(dataset);
var triggerChanged = this.getChangedTriggers(dataUpdateTriggers);
if (triggerChanged && triggerChanged.getMeta) {
this.updateLayerMeta(dataset);
}
var tileSource = null;
if (((_dataset$metadata = dataset.metadata) === null || _dataset$metadata === void 0 ? void 0 : _dataset$metadata.pmtilesType) === _constants.PMTilesType.RASTER) {
var metadataUrl = dataset.metadata.metadataUrl;
// use the old tile source if it exists and matches the new metadataUrl
var _ref = oldLayerData || {},
oldDataset = _ref.dataset,
oldTileSource = _ref.tileSource;
if (oldDataset === dataset && (oldTileSource === null || oldTileSource === void 0 ? void 0 : oldTileSource.data) === metadataUrl) {
tileSource = oldLayerData.tileSource;
} else {
tileSource = metadataUrl ? _pmtiles.PMTilesSource.createDataSource(metadataUrl, {}) : null;
}
}
return {
dataset: dataset,
tileSource: tileSource
};
}
}, {
key: "updateLayerMeta",
value: function updateLayerMeta(dataset) {
if (dataset.type !== _constants.DatasetType.RASTER_TILE) {
return;
}
var stac = dataset.metadata;
if (stac.pmtilesType === _constants.PMTilesType.RASTER) {
return this.updateMeta({
bounds: stac.bounds
});
}
var bounds = (0, _rasterTileUtils.getSTACBounds)(stac);
if (bounds) {
// If a STAC Item (i.e. stac.type === 'Feature'), then set map bounds.
// But we don't want to set bounds for Landsat or Sentinel because it would zoom out to zoom
// 0, and we don't have low-zoom tiles.
if (stac.type === 'Feature') {
this.updateMeta({
bounds: bounds
});
}
}
}
/**
* Run when adding a new dataset
*/
}, {
key: "setInitialLayerConfig",
value: function setInitialLayerConfig(dataset) {
var stac = dataset === null || dataset === void 0 ? void 0 : dataset.metadata;
if (!stac) {
return this;
}
if (stac.pmtilesType === _constants.PMTilesType.RASTER) {
return this;
}
// When a STAC Collection is added, useStacSearching should be true to prevent a black screen
this.updateLayerVisConfig({
useSTACSearching: stac.type === 'Collection'
});
// Set singleBandName if there is only one band
var availableBands = (0, _rasterTileUtils.getEOBands)(stac) || [];
if ((availableBands === null || availableBands === void 0 ? void 0 : availableBands.length) === 1) {
this.updateLayerVisConfig({
singleBandName: availableBands[0].name
});
}
// Change the preset if the default one is not allowed
var availablePresets = (0, _rasterTileUtils.filterAvailablePresets)(stac, _config.PRESET_OPTIONS);
if (availablePresets !== null && availablePresets !== void 0 && availablePresets.length && !(availablePresets !== null && availablePresets !== void 0 && availablePresets.includes(this.visConfigSettings.preset.defaultValue))) {
this.updateLayerVisConfig({
preset: availablePresets[0]
});
}
// Apply improved image processing props only for non single band modes
var preset = this.config.visConfig.preset;
var colorDefaults = _config.DATA_SOURCE_COLOR_DEFAULTS[stac.id];
if (colorDefaults && preset !== 'singleBand') {
this.updateLayerVisConfig(colorDefaults);
}
/*
LandSat specifies temporal bounds but the valid data is after end date
const updatedDates = timeRangeToStacTemporalInterval(
stac as StacTypes.STACCollection,
this.config.visConfig.startDate,
this.config.visConfig.endDate
);
this.updateLayerVisConfig(updatedDates);
*/
return this;
}
/**
* Update zRange of viewport. This is necessary so that tiles in extruded mode are shown properly
* at high elevations: https://github.com/foursquare/studio-monorepo/pull/1892/files
* Derived from https://github.com/visgl/deck.gl/blob/8d824a4b836fee3bfebe6fc962e0f03d8c1dbd0d/modules/geo-layers/src/terrain-layer/terrain-layer.js#L173-L196
*
* @param tiles Array of tiles in current viewport
*/
}, {
key: "onViewportLoad",
value: function onViewportLoad(tiles) {
this.updateMinMaxPixelValue(tiles);
var newZRange = (0, _rasterTileUtils.computeZRange)(tiles);
if (!newZRange) {
return;
}
var zRange = this.meta.zRange;
if (!zRange || newZRange[0] < zRange[0] || newZRange[1] > zRange[1]) {
this.meta.zRange = newZRange;
}
}
/**
* Update viewport-related minPxelValue and maxPixelValue
* @param tiles - deck.gl tiles
*/
}, {
key: "updateMinMaxPixelValue",
value: function updateMinMaxPixelValue(tiles) {
var _getMinMaxFromTile2DH = (0, _rasterTileUtils.getMinMaxFromTile2DHeaders)(tiles),
_getMinMaxFromTile2DH2 = (0, _slicedToArray2["default"])(_getMinMaxFromTile2DH, 2),
min = _getMinMaxFromTile2DH2[0],
max = _getMinMaxFromTile2DH2[1];
this.minViewportPixelValue = min;
this.maxViewportPixelValue = max;
}
/**
* Calculate min and max values of input raster band image properties
* and update `minBandsValue` and `maxBandsValue`
* @param images - raster band image properties
* @return [min, max] pixel values for the tile
*/
}, {
key: "getMinMaxPixelValues",
value: function getMinMaxPixelValues(images) {
var minPixelValue = Infinity;
var maxPixelValue = -Infinity;
if (images) {
var _iterator = _createForOfIteratorHelper(images),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var image = _step.value;
var _getImageMinMax = (0, _rasterTileUtils.getImageMinMax)(image.data),
_getImageMinMax2 = (0, _slicedToArray2["default"])(_getImageMinMax, 2),
min = _getImageMinMax2[0],
max = _getImageMinMax2[1];
if (typeof min === 'number') {
minPixelValue = Math.min(min, minPixelValue);
}
if (typeof max === 'number') {
maxPixelValue = Math.max(max, maxPixelValue);
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
return [minPixelValue, maxPixelValue];
}
// generate a deck layer
}, {
key: "renderLayer",
value: function renderLayer(opts) {
var _data$dataset;
var data = opts.data;
if ((data === null || data === void 0 || (_data$dataset = data.dataset) === null || _data$dataset === void 0 || (_data$dataset = _data$dataset.metadata) === null || _data$dataset === void 0 ? void 0 : _data$dataset.pmtilesType) === _constants.PMTilesType.RASTER) {
return this.renderPMTilesLayer(opts);
}
return this.renderStacLayer(opts);
}
}, {
key: "renderStacLayer",
value: function renderStacLayer(opts) {
var _data$dataset2,
_this2 = this;
var data = opts.data,
mapState = opts.mapState,
experimentalContext = opts.experimentalContext;
var stac = data === null || data === void 0 || (_data$dataset2 = data.dataset) === null || _data$dataset2 === void 0 ? void 0 : _data$dataset2.metadata;
// If a tabular dataset is loaded, and then the layer type is switched from Point to Raster Tile
// layer, this `stac` object will exist but will not be raster metadata
if (!stac || !stac.stac_version) {
return [];
}
var visConfig = this.config.visConfig;
var _this$getDefaultDeckL = this.getDefaultDeckLayerProps(opts),
id = _this$getDefaultDeckL.id,
opacity = _this$getDefaultDeckL.opacity,
visible = _this$getDefaultDeckL.visible;
var hasShadowEffect = experimentalContext === null || experimentalContext === void 0 ? void 0 : experimentalContext.hasShadowEffect;
var preset = visConfig.preset,
colormapId = visConfig.colormapId,
linearRescaling = visConfig.linearRescaling,
linearRescalingFactor = visConfig.linearRescalingFactor,
nonLinearRescaling = visConfig.nonLinearRescaling,
gammaContrastFactor = visConfig.gammaContrastFactor,
sigmoidalContrastFactor = visConfig.sigmoidalContrastFactor,
sigmoidalBiasFactor = visConfig.sigmoidalBiasFactor,
saturationValue = visConfig.saturationValue,
filterEnabled = visConfig.filterEnabled,
filterRange = visConfig.filterRange,
useSTACSearching = visConfig.useSTACSearching,
stacSearchProvider = visConfig.stacSearchProvider,
startDate = visConfig.startDate,
endDate = visConfig.endDate,
_stacQuery = visConfig._stacQuery,
singleBandName = visConfig.singleBandName,
categoricalColorMap = visConfig.colorRange.colorMap,
dynamicColor = visConfig.dynamicColor;
var shouldLoadTerrain = getShouldLoadTerrain(stac, mapState, visConfig);
if (new Date(endDate) < new Date(startDate)) {
return [];
}
var bandCombination = _config.PRESET_OPTIONS[preset].bandCombination;
var singleBand = (0, _rasterTileUtils.getSingleBandPresetOptions)(stac, singleBandName);
var dataSourceParams = this.getDataSourceParams(stac, preset, {
singleBand: singleBand
});
if (!dataSourceParams) {
return [];
}
var minZoom = dataSourceParams.minZoom,
maxZoom = dataSourceParams.maxZoom,
globalBounds = dataSourceParams.globalBounds,
loadAssetIds = dataSourceParams.loadAssetIds,
loadBandIndexes = dataSourceParams.loadBandIndexes,
renderBandIndexes = dataSourceParams.renderBandIndexes,
dataType = dataSourceParams.dataType,
dsMinPixelValue = dataSourceParams.minPixelValue,
dsMaxPixelValue = dataSourceParams.maxPixelValue,
minCategoricalBandValue = dataSourceParams.minCategoricalBandValue,
maxCategoricalBandValue = dataSourceParams.maxCategoricalBandValue;
var minPixelValue = !dynamicColor && Number.isFinite(dsMinPixelValue) ? dsMinPixelValue : this.minViewportPixelValue;
var maxPixelValue = !dynamicColor && Number.isFinite(dsMaxPixelValue) ? dsMaxPixelValue : this.maxViewportPixelValue;
var getTileDataCustomProps = {
stac: stac,
loadAssetIds: loadAssetIds,
loadBandIndexes: loadBandIndexes,
colormapId: colormapId,
shouldLoadTerrain: shouldLoadTerrain,
globalBounds: globalBounds,
useSTACSearching: useSTACSearching,
stacSearchProvider: stacSearchProvider,
startDate: startDate,
endDate: endDate,
_stacQuery: _stacQuery,
categoricalColorMap: categoricalColorMap,
minCategoricalBandValue: minCategoricalBandValue,
maxCategoricalBandValue: maxCategoricalBandValue
};
var tileLayer = new _typed2.TileLayer(_objectSpread(_objectSpread({
id: id,
minZoom: minZoom,
maxZoom: maxZoom,
tileSize: 512 / devicePixelRatio,
getTileData: function getTileData(args) {
return _this2.getTileData(_objectSpread(_objectSpread({}, args), getTileDataCustomProps));
},
onViewportLoad: this.onViewportLoad.bind(this),
// @ts-expect-error - TS doesn't know we'll pass appropriate props here
renderSubLayers: renderSubLayersStac,
maxRequests: (0, _rasterTileUtils.getMaxRequests)(stac.rasterTileServerUrls || []),
// Passing visible on to TileLayer is necessary for split view to work
visible: visible,
updateTriggers: {
getTileData: [shouldLoadTerrain,
// Colormap has changed
colormapId].concat((0, _toConsumableArray2["default"])(loadAssetIds), (0, _toConsumableArray2["default"])(loadBandIndexes), [useSTACSearching, stacSearchProvider, startDate, endDate, _stacQuery, categoricalColorMap, minCategoricalBandValue, maxCategoricalBandValue])
}
}, shouldLoadTerrain ? {
zRange: this.meta.zRange || null,
refinementStrategy: 'no-overlap'
} : {}), {}, {
renderBandIndexes: renderBandIndexes,
opacity: opacity,
linearRescaling: linearRescaling,
linearRescalingFactor: linearRescalingFactor,
nonLinearRescaling: nonLinearRescaling,
minPixelValue: minPixelValue,
maxPixelValue: maxPixelValue,
gammaContrastFactor: gammaContrastFactor,
sigmoidalContrastFactor: sigmoidalContrastFactor,
sigmoidalBiasFactor: sigmoidalBiasFactor,
saturationValue: saturationValue,
bandCombination: bandCombination,
filterEnabled: filterEnabled,
filterRange: filterRange,
dataType: dataType,
minCategoricalBandValue: minCategoricalBandValue,
maxCategoricalBandValue: maxCategoricalBandValue,
hasCategoricalColorMap: Boolean(categoricalColorMap),
hasShadowEffect: hasShadowEffect
}));
return [tileLayer];
}
}, {
key: "renderPMTilesLayer",
value: function renderPMTilesLayer(opts) {
var _data$dataset3,
_this3 = this;
var _this$getDefaultDeckL2 = this.getDefaultDeckLayerProps(opts),
id = _this$getDefaultDeckL2.id,
opacity = _this$getDefaultDeckL2.opacity,
visible = _this$getDefaultDeckL2.visible;
var data = opts.data,
mapState = opts.mapState;
var metadata = data === null || data === void 0 || (_data$dataset3 = data.dataset) === null || _data$dataset3 === void 0 ? void 0 : _data$dataset3.metadata;
var visConfig = this.config.visConfig;
var tileSource = data.tileSource;
var showTileBorders = false;
var minZoom = metadata.minZoom || 0;
var maxZoom = metadata.maxZoom || 30;
var shouldLoadTerrain = getShouldLoadTerrain(metadata, mapState, visConfig);
return [new _typed2.TileLayer(_objectSpread({
id: id,
getTileData: function getTileData(args) {
return _this3.getTileDataPMTiles(_objectSpread(_objectSpread({}, args), {}, {
shouldLoadTerrain: shouldLoadTerrain,
metadata: metadata
}), tileSource);
},
// Assume the pmtiles file support HTTP/2, so we aren't limited by the browser to a certain number per domain.
maxRequests: 20,
pickable: true,
autoHighlight: showTileBorders,
onViewportLoad: this.onViewportLoad.bind(this),
minZoom: minZoom,
maxZoom: maxZoom,
tileSize: 512 / devicePixelRatio,
zoomOffset: devicePixelRatio === 1 ? -1 : 0,
// @ts-expect-error - TS doesn't know we'll pass appropriate props here
renderSubLayers: renderSubLayersPMTiles,
tileSource: tileSource,
showTileBorders: showTileBorders,
visible: visible,
opacity: opacity,
updateTriggers: {
getTileData: [shouldLoadTerrain]
}
}, shouldLoadTerrain ? {
zRange: this.meta.zRange || null,
refinementStrategy: 'no-overlap'
} : {}))];
}
}, {
key: "getTileData",
value: function () {
var _getTileData = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(props) {
var shouldLoadTerrain, globalBounds, _props$bbox, west, south, east, north, zoom, assetRequests, terrain, _yield$Promise$all, _yield$Promise$all2, images, _terrain, _this$getMinMaxPixelV, _this$getMinMaxPixelV2, min, max;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
shouldLoadTerrain = props.shouldLoadTerrain, globalBounds = props.globalBounds, _props$bbox = props.bbox, west = _props$bbox.west, south = _props$bbox.south, east = _props$bbox.east, north = _props$bbox.north, zoom = props.index.z;
if (!(globalBounds && !(0, _rasterTileUtils.bboxIntersects)(globalBounds, [west, south, east, north]))) {
_context.next = 3;
break;
}
return _context.abrupt("return", null);
case 3:
_context.next = 5;
return (0, _image.getSTACImageRequests)(props);
case 5:
assetRequests = _context.sent;
if (assetRequests) {
_context.next = 14;
break;
}
_context.t0 = shouldLoadTerrain && LOAD_ELEVATION_AFTER_ZOOM < zoom;
if (!_context.t0) {
_context.next = 12;
break;
}
_context.next = 11;
return (0, _image.loadTerrain)({
boundsForGeometry: [west, north, east, south],
index: props.index,
signal: props.signal,
rasterTileServerUrls: props.stac.rasterTileServerUrls || []
});
case 11:
_context.t0 = _context.sent;
case 12:
terrain = _context.t0;
return _context.abrupt("return", _objectSpread({
images: null
}, terrain ? {
terrain: terrain
} : {}));
case 14:
tilesBeingLoaded++;
// Wrap loading images into a try/catch because tiles that are only briefly in view will be
// aborted. The `AbortController.abort()` creates a DOMException error.
// Note that since loading is async, try/catch will only work when awaited inside the try block
_context.prev = 15;
_context.next = 18;
return Promise.all([(0, _image.loadImages)(assetRequests, props.colormapId, {
colorMap: props.categoricalColorMap,
minValue: props.minCategoricalBandValue,
maxValue: props.maxCategoricalBandValue
}), shouldLoadTerrain && LOAD_ELEVATION_AFTER_ZOOM < zoom ? (0, _image.loadTerrain)({
boundsForGeometry: [west, north, east, south],
index: props.index,
signal: props.signal,
rasterTileServerUrls: props.stac.rasterTileServerUrls || []
}) : null]);
case 18:
_yield$Promise$all = _context.sent;
_yield$Promise$all2 = (0, _slicedToArray2["default"])(_yield$Promise$all, 2);
images = _yield$Promise$all2[0];
_terrain = _yield$Promise$all2[1];
_this$getMinMaxPixelV = this.getMinMaxPixelValues(images.imageBands), _this$getMinMaxPixelV2 = (0, _slicedToArray2["default"])(_this$getMinMaxPixelV, 2), min = _this$getMinMaxPixelV2[0], max = _this$getMinMaxPixelV2[1];
tilesBeingLoaded--;
// Add terrain data only if we requested it above
return _context.abrupt("return", _objectSpread(_objectSpread({
images: images
}, _terrain ? {
terrain: _terrain
} : {}), {}, {
minPixelValue: min,
maxPixelValue: max
}));
case 27:
_context.prev = 27;
_context.t1 = _context["catch"](15);
tilesBeingLoaded--;
if (!(_context.t1.name === 'AbortError')) {
_context.next = 32;
break;
}
return _context.abrupt("return", null);
case 32:
throw _context.t1;
case 33:
case "end":
return _context.stop();
}
}, _callee, this, [[15, 27]]);
}));
function getTileData(_x) {
return _getTileData.apply(this, arguments);
}
return getTileData;
}()
}, {
key: "getTileDataPMTiles",
value: function () {
var _getTileDataPMTiles = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(props, tileSource) {
var shouldLoadTerrain, globalBounds, _props$bbox2, west, south, east, north, zoom, metadata, _yield$Promise$all3, _yield$Promise$all4, image, terrain, minPixelValue, maxPixelValue, _this$getMinMaxPixelV3, _this$getMinMaxPixelV4, min, max;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
shouldLoadTerrain = props.shouldLoadTerrain, globalBounds = props.globalBounds, _props$bbox2 = props.bbox, west = _props$bbox2.west, south = _props$bbox2.south, east = _props$bbox2.east, north = _props$bbox2.north, zoom = props.index.z, metadata = props.metadata;
if (!(globalBounds && !(0, _rasterTileUtils.bboxIntersects)(globalBounds, [west, south, east, north]))) {
_context2.next = 3;
break;
}
return _context2.abrupt("return", null);
case 3:
tilesBeingLoaded++;
_context2.prev = 4;
_context2.next = 7;
return Promise.all([tileSource.getTileData(props)]);
case 7:
_yield$Promise$all3 = _context2.sent;
_yield$Promise$all4 = (0, _slicedToArray2["default"])(_yield$Promise$all3, 1);
image = _yield$Promise$all4[0];
if (!(image && shouldLoadTerrain && LOAD_ELEVATION_AFTER_ZOOM < zoom)) {
_context2.next = 16;
break;
}
_context2.next = 13;
return (0, _image.loadTerrain)({
boundsForGeometry: [west, north, east, south],
index: props.index,
signal: props.signal,
rasterTileServerUrls: metadata.rasterTileServerUrls
});
case 13:
_context2.t0 = _context2.sent;
_context2.next = 17;
break;
case 16:
_context2.t0 = null;
case 17:
terrain = _context2.t0;
minPixelValue = null;
maxPixelValue = null;
if (image) {
_this$getMinMaxPixelV3 = this.getMinMaxPixelValues([{
data: image
}]), _this$getMinMaxPixelV4 = (0, _slicedToArray2["default"])(_this$getMinMaxPixelV3, 2), min = _this$getMinMaxPixelV4[0], max = _this$getMinMaxPixelV4[1];
minPixelValue = min;
maxPixelValue = max;
}
tilesBeingLoaded--;
// Add terrain data only if we requested it above
return _context2.abrupt("return", _objectSpread({
image: image,
minPixelValue: minPixelValue,
maxPixelValue: maxPixelValue
}, terrain ? {
terrain: terrain
} : {}));
case 25:
_context2.prev = 25;
_context2.t1 = _context2["catch"](4);
tilesBeingLoaded--;
if (!(_context2.t1.name === 'AbortError')) {
_context2.next = 30;
break;
}
return _context2.abrupt("return", null);
case 30:
throw _context2.t1;
case 31:
case "end":
return _context2.stop();
}
}, _callee2, this, [[4, 25]]);
}));
function getTileDataPMTiles(_x2, _x3) {
return _getTileDataPMTiles.apply(this, arguments);
}
return getTileDataPMTiles;
}()
}], [{
key: "findDefaultLayerProps",
value: function findDefaultLayerProps(dataset) {
if (dataset.type !== _constants.DatasetType.RASTER_TILE) {
return {
props: []
};
}
var newLayerProp = {
dataId: dataset.id,
label: dataset.label,
isVisible: true
};
return {
props: [newLayerProp]
};
}
}]);
}(_baseLayer["default"]);
function renderSubLayersStac(props) {
var tile = props.tile,
data = props.data,
globalMinPixelValue = props.minPixelValue,
globalMaxPixelValue = props.maxPixelValue;
var bbox = tile.bbox;
var west = bbox.west,
south = bbox.south,
east = bbox.east,
north = bbox.north;
if (!data) {
return [];
}
var images = data.images,
terrain = data.terrain,
tileMinPixelValue = data.minPixelValue,
tileMaxPixelValue = data.maxPixelValue;
if (!images || Array.isArray(images) && images.length === 0) {
return [];
}
var minPixelValue = Number.isFinite(globalMinPixelValue) ? globalMinPixelValue : tileMinPixelValue;
var maxPixelValue = Number.isFinite(globalMaxPixelValue) ? globalMaxPixelValue : tileMaxPixelValue;
if (typeof minPixelValue !== 'number' || typeof maxPixelValue !== 'number') {
return [];
}
var _getModules = (0, _gpuUtils.getModules)({
images: images,
props: _objectSpread(_objectSpread({}, props), {}, {
minPixelValue: minPixelValue,
maxPixelValue: maxPixelValue
})
}),
modules = _getModules.modules,
moduleProps = _getModules.moduleProps;
var idSuffix = props.hasShadowEffect ? 'shadow' : '';
return terrain ? new _deckglLayers.RasterMeshLayer(props, {
id: "raster-3d-layer-".concat(props.id, "-").concat(idSuffix),
// Dummy data
data: [1],
mesh: terrain,
images: images,
modules: modules,
moduleProps: moduleProps,
getPolygonOffset: null,
coordinateSystem: _typed.COORDINATE_SYSTEM.LNGLAT,
// Color to use if surfaceImage is unavailable
getColor: [255, 255, 255]
// material: false
}) : new _deckglLayers.RasterLayer(props, {
id: "raster-2d-layer-".concat(props.id, "-").concat(idSuffix),
images: images,
modules: modules,
moduleProps: moduleProps,
bounds: [west, south, east, north],
_imageCoordinateSystem: _typed.COORDINATE_SYSTEM.CARTESIAN
});
}
function renderSubLayersPMTiles(props) {
var _props$data;
var tileSource = props.tileSource,
showTileBorders = props.showTileBorders,
minZoom = props.minZoom,
maxZoom = props.maxZoom,
_props$tile = props.tile,
zoom = _props$tile.index.z,
_props$tile$bbox = _props$tile.bbox,
west = _props$tile$bbox.west,
south = _props$tile$bbox.south,
east = _props$tile$bbox.east,
north = _props$tile$bbox.north;
var layers = [];
if ((_props$data = props.data) !== null && _props$data !== void 0 && _props$data.image) {
switch (tileSource.mimeType) {
case 'image/png':
case 'image/jpeg':
case 'image/webp':
case 'image/avif':
layers.push(getRasterLayerPMTiles(props));
break;
default:
break;
}
}
// Debug tile borders
var borderColor = zoom <= minZoom || zoom >= maxZoom ? [255, 0, 0, 255] : [0, 0, 255, 255];
if (showTileBorders) {
layers.push(new _typed3.PathLayer({
id: "".concat(props.id, "-border"),
data: [[[west, north], [west, south], [east, south], [east, north], [west, north]]],
getPath: function getPath(d) {
return d;
},
getColor: borderColor,
widthMinPixels: 4
}));
}
return layers;
}
function getRasterLayerPMTiles(props) {
var tile = props.tile,
data = props.data;
var bbox = tile.bbox;
var west = bbox.west,
south = bbox.south,
east = bbox.east,
north = bbox.north;
if (!(data !== null && data !== void 0 && data.image)) {
return [];
}
var images = {
imageRgba: {
data: data.image
}
};
var terrain = data.terrain;
var _getModules2 = (0, _gpuUtils.getModules)({
images: images
}),
modules = _getModules2.modules,
moduleProps = _getModules2.moduleProps;
return terrain ? new _deckglLayers.RasterMeshLayer(props, {
id: "raster-3d-layer-".concat(props.id),
// Dummy data
data: [1],
mesh: terrain,
images: images,
modules: modules,
moduleProps: moduleProps,
getPolygonOffset: null,
coordinateSystem: _typed.COORDINATE_SYSTEM.LNGLAT,
// Color to use if surfaceImage is unavailable
getColor: [255, 255, 255]
// material: false
}) : new _deckglLayers.RasterLayer(props, {
id: "raster-2d-layer-".concat(props.id),
data: null,
images: images,
modules: modules,
moduleProps: moduleProps,
bounds: [west, south, east, north],
_imageCoordinateSystem: _typed.COORDINATE_SYSTEM.CARTESIAN
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdHlwZWQiLCJyZXF1aXJlIiwiX3R5cGVkMiIsIl9wbXRpbGVzIiwiX21lbW9pemUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX3R5cGVkMyIsIl9jb25zdGFudHMiLCJfZGVja2dsTGF5ZXJzIiwiX2NvbW1vblV0aWxzIiwiX3V0aWxzIiwiX2NvbmZpZyIsIl9ncHVVdGlscyIsIl9pbWFnZSIsIl9yYXN0ZXJUaWxlSWNvbiIsIl9yYXN0ZXJUaWxlVXRpbHMiLCJfYmFzZUxheWVyIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJyIiwiZSIsInQiLCJTeW1ib2wiLCJpdGVyYXRvciIsIkFycmF5IiwiaXNBcnJheSIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsImxlbmd0aCIsIl9uIiwiRiIsInMiLCJuIiwiZG9uZSIsInZhbHVlIiwiZiIsIlR5cGVFcnJvciIsIm8iLCJhIiwidSIsImNhbGwiLCJuZXh0IiwiX2FycmF5TGlrZVRvQXJyYXkiLCJ0b1N0cmluZyIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiZnJvbSIsInRlc3QiLCJvd25LZXlzIiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiX2NhbGxTdXBlciIsIl9nZXRQcm90b3R5cGVPZjIiLCJfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIiLCJfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0IiwiUmVmbGVjdCIsImNvbnN0cnVjdCIsIkJvb2xlYW4iLCJwcm90b3R5cGUiLCJ2YWx1ZU9mIiwiX3N1cGVyUHJvcEdldCIsInAiLCJfZ2V0MiIsImRldmljZVBpeGVsUmF0aW8iLCJNYXRoIiwibWluIiwid2luZG93IiwidGlsZXNCZWluZ0xvYWRlZCIsImdldE51bVJhc3RlclRpbGVzQmVpbmdMb2FkZWQiLCJleHBvcnRzIiwiTE9BRF9FTEVWQVRJT05fQUZURVJfWk9PTSIsImdldFNob3VsZExvYWRUZXJyYWluIiwic3RhYyIsIm1hcFN0YXRlIiwidmlzQ29uZmlnIiwiX3N0YWMkcmFzdGVyVGlsZVNlcnZlIiwicmFzdGVyVGlsZVNlcnZlclVybHMiLCJlbmFibGVUZXJyYWluIiwiZHJhZ1JvdGF0ZSIsImdldEFwcGxpY2F0aW9uQ29uZmlnIiwicmFzdGVyU2VydmVyU3VwcG9ydHNFbGV2YXRpb24iLCJSYXN0ZXJUaWxlTGF5ZXIiLCJfS2VwbGVyTGF5ZXIiLCJwcm9wcyIsIl90aGlzIiwiX2NsYXNzQ2FsbENoZWNrMiIsIkluZmluaXR5IiwicmVnaXN0ZXJWaXNDb25maWciLCJyYXN0ZXJWaXNDb25maWdzIiwicmVzb2x2ZXIiLCJwcmVzZXQiLCJwcmVzZXRPcHRpb25zIiwiX3ByZXNldE9wdGlvbnMkc2luZ2xlIiwiX3ByZXNldE9wdGlvbnMkc2luZ2xlMiIsImNvbmNhdCIsImlkIiwiY29sbGVjdGlvbiIsInNpbmdsZUJhbmQiLCJhc3NldElkIiwiYmFuZEluZGV4IiwiZ2V0RGF0YVNvdXJjZVBhcmFtcyIsIm1lbW9pemUiLCJtZXRhIiwielJhbmdlIiwiX2luaGVyaXRzMiIsIl9jcmVhdGVDbGFzczIiLCJrZXkiLCJnZXQiLCJMQVlFUl9UWVBFUyIsInJhc3RlclRpbGUiLCJSYXN0ZXJJY29uIiwiRGF0YXNldFR5cGUiLCJSQVNURVJfVElMRSIsImNhdGVnb3JpY2FsQ29sb3JMZWdlbmRzIiwiY29uZmlnIiwiY29sb3JSYW5nZSIsImNvbG9yTGVnZW5kcyIsImNvbG9yIiwiZ2V0RGVmYXVsdExheWVyQ29uZmlnIiwiY29sb3JGaWVsZCIsImFuYWx5emVyVHlwZSIsImZvcm1hdCIsInR5cGUiLCJmaWVsZElkeCIsInZhbHVlQWNjZXNzb3IiLCJkaXNwbGF5TmFtZSIsImdldEhvdmVyRGF0YSIsInNob3VsZFJlbmRlckxheWVyIiwiaXNWaXNpYmxlIiwiZm9ybWF0TGF5ZXJEYXRhIiwiZGF0YXNldHMiLCJvbGRMYXllckRhdGEiLCJfZGF0YXNldCRtZXRhZGF0YSIsImRhdGFJZCIsIm5vdE51bGxvclVuZGVmaW5lZCIsImRhdGFzZXQiLCJkYXRhVXBkYXRlVHJpZ2dlcnMiLCJnZXREYXRhVXBkYXRlVHJpZ2dlcnMiLCJ0cmlnZ2VyQ2hhbmdlZCIsImdldENoYW5nZWRUcmlnZ2VycyIsImdldE1ldGEiLCJ1cGRhdGVMYXllck1ldGEiLCJ0aWxlU291cmNlIiwibWV0YWRhdGEiLCJwbXRpbGVzVHlwZSIsIlBNVGlsZXNUeXBlIiwiUkFTVEVSIiwibWV0YWRhdGFVcmwiLCJfcmVmIiwib2xkRGF0YXNldCIsIm9sZFRpbGVTb3VyY2UiLCJkYXRhIiwiUE1UaWxlc1NvdXJjZSIsImNyZWF0ZURhdGFTb3VyY2UiLCJ1cGRhdGVNZXRhIiwiYm91bmRzIiwiZ2V0U1RBQ0JvdW5kcyIsInNldEluaXRpYWxMYXllckNvbmZpZyIsInVwZGF0ZUxheWVyVmlzQ29uZmlnIiwidXNlU1RBQ1NlYXJjaGluZyIsImF2YWlsYWJsZUJhbmRzIiwiZ2V0RU9CYW5kcyIsInNpbmdsZUJhbmROYW1lIiwiYXZhaWxhYmxlUHJlc2V0cyIsImZpbHRlckF2YWlsYWJsZVByZXNldHMiLCJQUkVTRVRfT1BUSU9OUyIsImluY2x1ZGVzIiwidmlzQ29uZmlnU2V0dGluZ3MiLCJkZWZhdWx0VmFsdWUiLCJjb2xvckRlZmF1bHRzIiwiREFUQV9TT1VSQ0VfQ09MT1JfREVGQVVMVFMiLCJvblZpZXdwb3J0TG9hZCIsInRpbGVzIiwidXBkYXRlTWluTWF4UGl4ZWxWYWx1ZSIsIm5ld1pSYW5nZSIsImNvbXB1dGVaUmFuZ2UiLCJfZ2V0TWluTWF4RnJvbVRpbGUyREgiLCJnZXRNaW5NYXhGcm9tVGlsZTJESGVhZGVycyIsIl9nZXRNaW5NYXhGcm9tVGlsZTJESDIiLCJfc2xpY2VkVG9BcnJheTIiLCJtYXgiLCJtaW5WaWV3cG9ydFBpeGVsVmFsdWUiLCJtYXhWaWV3cG9ydFBpeGVsVmFsdWUiLCJnZXRNaW5NYXhQaXhlbFZhbHVlcyIsImltYWdlcyIsIm1pblBpeGVsVmFsdWUiLCJtYXhQaXhlbFZhbHVlIiwiX2l0ZXJhdG9yIiwiX3N0ZXAiLCJpbWFnZSIsIl9nZXRJbWFnZU1pbk1heCIsImdldEltYWdlTWluTWF4IiwiX2dldEltYWdlTWluTWF4MiIsImVyciIsInJlbmRlckxheWVyIiwib3B0cyIsIl9kYXRhJGRhdGFzZXQiLCJyZW5kZXJQTVRpbGVzTGF5ZXIiLCJyZW5kZXJTdGFjTGF5ZXIiLCJfZGF0YSRkYXRhc2V0MiIsIl90aGlzMiIsImV4cGVyaW1lbnRhbENvbnRleHQiLCJzdGFjX3ZlcnNpb24iLCJfdGhpcyRnZXREZWZhdWx0RGVja0wiLCJnZXREZWZhdWx0RGVja0xheWVyUHJvcHMiLCJvcGFjaXR5IiwidmlzaWJsZSIsImhhc1NoYWRvd0VmZmVjdCIsImNvbG9ybWFwSWQiLCJsaW5lYXJSZXNjYWxpbmciLCJsaW5lYXJSZXNjYWxpbmdGYWN0b3IiLCJub25MaW5lYXJSZXNjYWxpbmciLCJnYW1tYUNvbnRyYXN0RmFjdG9yIiwic2lnbW9pZGFsQ29udHJhc3RGYWN0b3IiLCJzaWdtb2lkYWxCaWFzRmFjdG9yIiwic2F0dXJhdGlvblZhbHVlIiwiZmlsdGVyRW5hYmxlZCIsImZpbHRlclJhbmdlIiwic3RhY1NlYXJjaFByb3ZpZGVyIiwic3RhcnREYXRlIiwiZW5kRGF0ZSIsIl9zdGFjUXVlcnkiLCJjYXRlZ29yaWNhbENvbG9yTWFwIiwiY29sb3JNYXAiLCJkeW5hbWljQ29sb3IiLCJzaG91bGRMb2FkVGVycmFpbiIsIkRhdGUiLCJiYW5kQ29tYmluYXRpb24iLCJnZXRTaW5nbGVCYW5kUHJlc2V0T3B0aW9ucyIsImRhdGFTb3VyY2VQYXJhbXMiLCJtaW5ab29tIiwibWF4Wm9vbSIsImdsb2JhbEJvdW5kcyIsImxvYWRBc3NldElkcyIsImxvYWRCYW5kSW5kZXhlcyIsInJlbmRlckJhbmRJbmRleGVzIiwiZGF0YVR5cGUiLCJkc01pblBpeGVsVmFsdWUiLCJkc01heFBpeGVsVmFsdWUiLCJtaW5DYXRlZ29yaWNhbEJhbmRWYWx1ZSIsIm1heENhdGVnb3JpY2FsQmFuZFZhbHVlIiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJnZXRUaWxlRGF0YUN1c3RvbVByb3BzIiwidGlsZUxheWVyIiwiVGlsZUxheWVyIiwidGlsZVNpemUiLCJnZXRUaWxlRGF0YSIsImFyZ3MiLCJiaW5kIiwicmVuZGVyU3ViTGF5ZXJzIiwicmVuZGVyU3ViTGF5ZXJzU3RhYyIsIm1heFJlcXVlc3RzIiwiZ2V0TWF4UmVxdWVzdHMiLCJ1cGRhdGVUcmlnZ2VycyIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJyZWZpbmVtZW50U3RyYXRlZ3kiLCJoYXNDYXRlZ29yaWNhbENvbG9yTWFwIiwiX2RhdGEkZGF0YXNldDMiLCJfdGhpczMiLCJfdGhpcyRnZXREZWZhdWx0RGVja0wyIiwic2hvd1RpbGVCb3JkZXJzIiwiZ2V0VGlsZURhdGFQTVRpbGVzIiwicGlja2FibGUiLCJhdXRvSGlnaGxpZ2h0Iiwiem9vbU9mZnNldCIsInJlbmRlclN1YkxheWVyc1BNVGlsZXMiLCJfZ2V0VGlsZURhdGEiLCJfYXN5bmNUb0dlbmVyYXRvcjIiLCJfcmVnZW5lcmF0b3IiLCJtYXJrIiwiX2NhbGxlZSIsIl9wcm9wcyRiYm94Iiwid2VzdCIsInNvdXRoIiwiZWFzdCIsIm5vcnRoIiwiem9vbSIsImFzc2V0UmVxdWVzdHMiLCJ0ZXJyYWluIiwiX3lpZWxkJFByb21pc2UkYWxsIiwiX3lpZWxkJFByb21pc2UkYWxsMiIsIl90ZXJyYWluIiwiX3RoaXMkZ2V0TWluTWF4UGl4ZWxWIiwiX3RoaXMkZ2V0TWluTWF4UGl4ZWxWMiIsIndyYXAiLCJfY2FsbGVlJCIsIl9jb250ZXh0IiwicHJldiIsImJib3giLCJpbmRleCIsInoiLCJiYm94SW50ZXJzZWN0cyIsImFicnVwdCIsImdldFNUQUNJbWFnZVJlcXVlc3RzIiwic2VudCIsInQwIiwibG9hZFRlcnJhaW4iLCJib3VuZHNGb3JHZW9tZXRyeSIsInNpZ25hbCIsIlByb21pc2UiLCJhbGwiLCJsb2FkSW1hZ2VzIiwibWluVmFsdWUiLCJtYXhWYWx1ZSIsImltYWdlQmFuZHMiLCJ0MSIsInN0b3AiLCJfeCIsIl9nZXRUaWxlRGF0YVBNVGlsZXMiLCJfY2FsbGVlMiIsIl9wcm9wcyRiYm94MiIsIl95aWVsZCRQcm9taXNlJGFsbDMiLCJfeWllbGQkUHJvbWlzZSRhbGw0IiwiX3RoaXMkZ2V0TWluTWF4UGl4ZWxWMyIsIl90aGlzJGdldE1pbk1heFBpeGVsVjQiLCJfY2FsbGVlMiQiLCJfY29udGV4dDIiLCJfeDIiLCJfeDMiLCJmaW5kRGVmYXVsdExheWVyUHJvcHMiLCJuZXdMYXllclByb3AiLCJsYWJlbCIsIktlcGxlckxheWVyIiwidGlsZSIsImdsb2JhbE1pblBpeGVsVmFsdWUiLCJnbG9iYWxNYXhQaXhlbFZhbHVlIiwidGlsZU1pblBpeGVsVmFsdWUiLCJ0aWxlTWF4UGl4ZWxWYWx1ZSIsIl9nZXRNb2R1bGVzIiwiZ2V0TW9kdWxlcyIsIm1vZHVsZXMiLCJtb2R1bGVQcm9wcyIsImlkU3VmZml4IiwiUmFzdGVyTWVzaExheWVyIiwibWVzaCIsImdldFBvbHlnb25PZmZzZXQiLCJjb29yZGluYXRlU3lzdGVtIiwiQ09PUkRJTkFURV9TWVNURU0iLCJMTkdMQVQiLCJnZXRDb2xvciIsIlJhc3RlckxheWVyIiwiX2ltYWdlQ29vcmRpbmF0ZVN5c3RlbSIsIkNBUlRFU0lBTiIsIl9wcm9wcyRkYXRhIiwiX3Byb3BzJHRpbGUiLCJfcHJvcHMkdGlsZSRiYm94IiwibGF5ZXJzIiwibWltZVR5cGUiLCJnZXRSYXN0ZXJMYXllclBNVGlsZXMiLCJib3JkZXJDb2xvciIsIlBhdGhMYXllciIsImdldFBhdGgiLCJkIiwid2lkdGhNaW5QaXhlbHMiLCJpbWFnZVJnYmEiLCJfZ2V0TW9kdWxlczIiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvcmFzdGVyLXRpbGUvcmFzdGVyLXRpbGUtbGF5ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IHtDT09SRElOQVRFX1NZU1RFTSwgTGF5ZXIgYXMgRGVja0xheWVyfSBmcm9tICdAZGVjay5nbC9jb3JlL3R5cGVkJztcbmltcG9ydCB7VGlsZUxheWVyLCBHZW9Cb3VuZGluZ0JveH0gZnJvbSAnQGRlY2suZ2wvZ2VvLWxheWVycy90eXBlZCc7XG5pbXBvcnQge1BNVGlsZXNTb3VyY2UsIFBNVGlsZXNUaWxlU291cmNlfSBmcm9tICdAbG9hZGVycy5nbC9wbXRpbGVzJztcbmltcG9ydCB7VGV4dHVyZTJEUHJvcHN9IGZyb20gJ0BsdW1hLmdsL3dlYmdsJztcbmltcG9ydCBtZW1vaXplIGZyb20gJ2xvZGFzaC9tZW1vaXplJztcblxuaW1wb3J0IHtQYXRoTGF5ZXJ9IGZyb20gJ0BkZWNrLmdsL2xheWVycy90eXBlZCc7XG5pbXBvcnQge0RhdGFzZXRUeXBlLCBQTVRpbGVzVHlwZSwgTEFZRVJfVFlQRVN9IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7UmFzdGVyTGF5ZXIsIFJhc3Rlck1lc2hMYXllcn0gZnJvbSAnQGtlcGxlci5nbC9kZWNrZ2wtbGF5ZXJzJztcbmltcG9ydCB7XG4gIExheWVyQmFzZUNvbmZpZyxcbiAgTGF5ZXJDb2xvckNvbmZpZyxcbiAgTGF5ZXJIZWlnaHRDb25maWcsXG4gIFZpc3VhbENoYW5uZWwsXG4gIFZpc0NvbmZpZ0NvbG9yUmFuZ2UsXG4gIFZpc0NvbmZpZ1NlbGVjdGlvbixcbiAgVmlzQ29uZmlnQm9vbGVhbixcbiAgVmlzQ29uZmlnSW5wdXQsXG4gIFZpc0NvbmZpZ1JhbmdlLFxuICBWaXNDb25maWdOdW1iZXJcbn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5cbmltcG9ydCB7bm90TnVsbG9yVW5kZWZpbmVkfSBmcm9tICdAa2VwbGVyLmdsL2NvbW1vbi11dGlscyc7XG5pbXBvcnQge0RhdGFzZXRzLCBLZXBsZXJUYWJsZSBhcyBLZXBsZXJEYXRhc2V0LCBWZWN0b3JUaWxlTWV0YWRhdGF9IGZyb20gJ0BrZXBsZXIuZ2wvdGFibGUnO1xuaW1wb3J0IHtnZXRBcHBsaWNhdGlvbkNvbmZpZ30gZnJvbSAnQGtlcGxlci5nbC91dGlscyc7XG5cbmltcG9ydCB7cmFzdGVyVmlzQ29uZmlncywgUFJFU0VUX09QVElPTlMsIERBVEFfU09VUkNFX0NPTE9SX0RFRkFVTFRTfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQge2dldE1vZHVsZXN9IGZyb20gJy4vZ3B1LXV0aWxzJztcbmltcG9ydCB7Z2V0U1RBQ0ltYWdlUmVxdWVzdHMsIGxvYWRJbWFnZXMsIGxvYWRUZXJyYWlufSBmcm9tICcuL2ltYWdlJztcbmltcG9ydCBSYXN0ZXJJY29uIGZyb20gJy4vcmFzdGVyLXRpbGUtaWNvbic7XG5pbXBvcnQge1xuICBnZXREYXRhU291cmNlUGFyYW1zLFxuICBnZXRNYXhSZXF1ZXN0cyxcbiAgYmJveEludGVyc2VjdHMsXG4gIGNvbXB1dGVaUmFuZ2UsXG4gIGdldFNUQUNCb3VuZHMsXG4gIGdldEVPQmFuZHMsXG4gIGZpbHRlckF2YWlsYWJsZVByZXNldHMsXG4gIGdldFNpbmdsZUJhbmRQcmVzZXRPcHRpb25zLFxuICBnZXRJbWFnZU1pbk1heCxcbiAgZ2V0TWluTWF4RnJvbVRpbGUyREhlYWRlcnNcbn0gZnJvbSAnLi9yYXN0ZXItdGlsZS11dGlscyc7XG5pbXBvcnQge1xuICBHZXRUaWxlRGF0YUN1c3RvbVByb3BzLFxuICBHZXRUaWxlRGF0YURlZmF1bHRQcm9wcyxcbiAgR2V0VGlsZURhdGFQcm9wcyxcbiAgUmVuZGVyU3ViTGF5ZXJzUHJvcHMsXG4gIEdldFRpbGVEYXRhT3V0cHV0LFxuICBEYXRhU291cmNlUGFyYW1zLFxuICBLZXBsZXJSYXN0ZXJEYXRhc2V0LFxuICBUaWxlMkRIZWFkZXIsXG4gIFByZXNldE9wdGlvbixcbiAgQ29tcGxldGVTVEFDT2JqZWN0XG59IGZyb20gJy4vdHlwZXMnO1xuXG5pbXBvcnQge0ZpbmREZWZhdWx0TGF5ZXJQcm9wc1JldHVyblZhbHVlfSBmcm9tICcuLi9sYXllci11dGlscyc7XG5pbXBvcnQge2RlZmF1bHQgYXMgS2VwbGVyTGF5ZXIsIExheWVyQmFzZUNvbmZpZ1BhcnRpYWx9IGZyb20gJy4uL2Jhc2UtbGF5ZXInO1xuXG4vLyBBZGp1c3QgdGlsZVNpemUgdG8gZGV2aWNlUGl4ZWxSYXRpbywgYnV0IG5vdCBoaWdoZXIgdGhhbiAyIHRvIHJlZHVjZSByZXF1ZXN0cyB0byBzZXJ2ZXJcbmNvbnN0IGRldmljZVBpeGVsUmF0aW86IG51bWJlciA9IE1hdGgubWluKFxuICAyLFxuICAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmRldmljZVBpeGVsUmF0aW8pIHx8IDFcbik7XG5cbi8vIEdsb2JhbCBjb3VudGVyIHRoYXQgcmVwcmVzZW50cyB0aGUgbnVtYmVyIG9mIHRpbGVzIGN1cnJlbnRseSBiZWluZyBsb2FkZWQgYWNyb3NzIGFsbCB0aGUgcmFzdGVyIHRpbGUgbGF5ZXJzXG5sZXQgdGlsZXNCZWluZ0xvYWRlZCA9IDA7XG5cbi8vIFRoaXMgaXMgYSB0ZW1wIHNvbHV0aW9uIHRvIHRyYWNrIGxvYWRpbmdcbmV4cG9ydCBjb25zdCBnZXROdW1SYXN0ZXJUaWxlc0JlaW5nTG9hZGVkID0gKCkgPT4ge1xuICByZXR1cm4gdGlsZXNCZWluZ0xvYWRlZDtcbn07XG5cbmV4cG9ydCBjb25zdCBMT0FEX0VMRVZBVElPTl9BRlRFUl9aT09NID0gOC45O1xuXG5jb25zdCBnZXRTaG91bGRMb2FkVGVycmFpbiA9IChzdGFjLCBtYXBTdGF0ZSwgdmlzQ29uZmlnKSA9PiB7XG4gIHJldHVybiBCb29sZWFuKFxuICAgIC8vIHdlIG5lZWQgYSByYXN0ZXIgdGlsZSBzZXJ2ZXIgZm9yIGVsZXZhdGlvbnMgZXZlbiB3aGVuIHdlIHVzZXIgUE1UaWxlc1xuICAgIHN0YWMucmFzdGVyVGlsZVNlcnZlclVybHM/Lmxlbmd0aCA+IDAgJiZcbiAgICAgIC8vIGNoZWNrIHRoZSBzd2l0Y2ggZnJvbSB0aGUgbGF5ZXIgY29uZmlndXJhdG9yXG4gICAgICB2aXNDb25maWcuZW5hYmxlVGVycmFpbiAmJlx