UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

191 lines (187 loc) 23.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.DeckDistanceFogEffect = void 0; 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 _engine = require("@luma.gl/engine"); 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; } // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project var DISTANCE_FOG_UNIFORM_BLOCK = /* glsl */"uniform distanceFogUniforms {\n float density;\n float fogStart;\n float fogRange;\n float nearPlane;\n float farPlane;\n vec3 fogColor;\n} distanceFog;\n"; var DISTANCE_FOG_FS = /* glsl */"#version 300 es\nprecision highp float;\n\nuniform sampler2D texSrc;\nuniform sampler2D texDepth;\n\nin vec2 position;\nin vec2 coordinate;\nin vec2 uv;\n\nout vec4 fragColor;\n\nvoid main() {\n vec4 color = texture(texSrc, coordinate);\n float depth = texture(texDepth, coordinate).r;\n\n float n = distanceFog.nearPlane;\n float f = distanceFog.farPlane;\n float eyeZ = n * f / (f - depth * (f - n));\n float linearDepth = (eyeZ - n) / (f - n);\n\n vec3 fogColor = distanceFog.fogColor / 255.0;\n float end = distanceFog.fogStart + distanceFog.fogRange;\n float fogFactor = smoothstep(distanceFog.fogStart, end, linearDepth) * distanceFog.density;\n\n fragColor = vec4(mix(color.rgb, fogColor, fogFactor), color.a);\n}\n"; var screenModule = { name: 'screen', fs: /* glsl */"uniform screenUniforms {\n vec2 texSize;\n} screen;\n", uniformTypes: { texSize: 'vec2<f32>' } }; var distanceFogModule = { name: 'distanceFog', fs: DISTANCE_FOG_UNIFORM_BLOCK, uniformTypes: { density: 'f32', fogStart: 'f32', fogRange: 'f32', nearPlane: 'f32', farPlane: 'f32', fogColor: 'vec3<f32>' }, defaultUniforms: { density: 0.5, fogStart: 0.3, fogRange: 0.5, nearPlane: 0.1, farPlane: 1000, fogColor: [217, 222, 230] }, propTypes: { density: { value: 0.5, min: 0, max: 1 }, fogStart: { value: 0.3, min: 0, max: 1 }, fogRange: { value: 0.5, min: 0.01, max: 1 }, fogColor: { value: [217, 222, 230] }, nearPlane: { value: 0.1, "private": true }, farPlane: { value: 1000, "private": true } } }; /** * Distance Fog Effect - uses the depth buffer to apply fog based on * camera-to-fragment distance. The raw depth buffer values are linearized * using the camera's near/far planes (extracted from the viewport projection * matrix) so that the fog gradient is perceptually uniform with distance. */ var DeckDistanceFogEffect = exports.DeckDistanceFogEffect = /*#__PURE__*/function () { function DeckDistanceFogEffect() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; (0, _classCallCheck2["default"])(this, DeckDistanceFogEffect); (0, _defineProperty2["default"])(this, "id", 'distance-fog-effect'); (0, _defineProperty2["default"])(this, "props", void 0); (0, _defineProperty2["default"])(this, "module", distanceFogModule); (0, _defineProperty2["default"])(this, "model", null); this.props = _objectSpread({ density: 0.5, fogStart: 0.3, fogRange: 0.5, fogColor: [217, 222, 230] }, props); } return (0, _createClass2["default"])(DeckDistanceFogEffect, [{ key: "setup", value: function setup(_ref) { var device = _ref.device; this.model = new _engine.ClipSpace(device, { id: 'distance-fog-pass', fs: DISTANCE_FOG_FS, modules: [distanceFogModule, screenModule], parameters: { depthWriteEnabled: false, depthCompare: 'always', blend: true, blendColorSrcFactor: 'one', blendColorDstFactor: 'one-minus-src-alpha', blendAlphaSrcFactor: 'one', blendAlphaDstFactor: 'one-minus-src-alpha', blendColorOperation: 'add', blendAlphaOperation: 'add' } }); } }, { key: "setProps", value: function setProps(props) { Object.assign(this.props, props); } // eslint-disable-next-line @typescript-eslint/no-empty-function }, { key: "preRender", value: function preRender() {} }, { key: "postRender", value: function postRender(params) { var _params$viewports; var inputBuffer = params.inputBuffer, swapBuffer = params.swapBuffer, target = params.target; var outputBuffer = target !== undefined ? target : swapBuffer; if (!this.model) return inputBuffer; // Distance fog always runs first among post-processing effects // (enforced by fixEffectOrder), so inputBuffer is always the scene // render target with valid depth data. var depthAttachment = inputBuffer.depthStencilAttachment; if (!depthAttachment) return inputBuffer; var nearPlane = 0.1; var farPlane = 1000; if (((_params$viewports = params.viewports) === null || _params$viewports === void 0 ? void 0 : _params$viewports.length) > 0) { var pm = params.viewports[0].projectionMatrix; if (pm) { var n = pm[14] / (pm[10] - 1); var f = pm[14] / (pm[10] + 1); if (Number.isFinite(n) && Number.isFinite(f) && n > 0 && f > n) { nearPlane = n; farPlane = f; } } } var texSize = [inputBuffer.width, inputBuffer.height]; this.model.shaderInputs.setProps({ screen: { texSrc: inputBuffer.colorAttachments[0], texSize: texSize }, distanceFog: { texDepth: depthAttachment, density: this.props.density, fogStart: this.props.fogStart, fogRange: this.props.fogRange, nearPlane: nearPlane, farPlane: farPlane, fogColor: this.props.fogColor } }); var renderPass = this.model.device.beginRenderPass({ framebuffer: outputBuffer, parameters: { viewport: [0, 0].concat(texSize) }, clearColor: [0, 0, 0, 0], clearDepth: 1 }); this.model.draw(renderPass); renderPass.end(); return outputBuffer || inputBuffer; } }, { key: "cleanup", value: function cleanup() { if (this.model) { this.model.destroy(); this.model = null; } } }]); }(); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZW5naW5lIiwicmVxdWlyZSIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwiRElTVEFOQ0VfRk9HX1VOSUZPUk1fQkxPQ0siLCJESVNUQU5DRV9GT0dfRlMiLCJzY3JlZW5Nb2R1bGUiLCJuYW1lIiwiZnMiLCJ1bmlmb3JtVHlwZXMiLCJ0ZXhTaXplIiwiZGlzdGFuY2VGb2dNb2R1bGUiLCJkZW5zaXR5IiwiZm9nU3RhcnQiLCJmb2dSYW5nZSIsIm5lYXJQbGFuZSIsImZhclBsYW5lIiwiZm9nQ29sb3IiLCJkZWZhdWx0VW5pZm9ybXMiLCJwcm9wVHlwZXMiLCJ2YWx1ZSIsIm1pbiIsIm1heCIsIkRlY2tEaXN0YW5jZUZvZ0VmZmVjdCIsImV4cG9ydHMiLCJwcm9wcyIsInVuZGVmaW5lZCIsIl9jbGFzc0NhbGxDaGVjazIiLCJfY3JlYXRlQ2xhc3MyIiwia2V5Iiwic2V0dXAiLCJfcmVmIiwiZGV2aWNlIiwibW9kZWwiLCJDbGlwU3BhY2UiLCJpZCIsIm1vZHVsZXMiLCJwYXJhbWV0ZXJzIiwiZGVwdGhXcml0ZUVuYWJsZWQiLCJkZXB0aENvbXBhcmUiLCJibGVuZCIsImJsZW5kQ29sb3JTcmNGYWN0b3IiLCJibGVuZENvbG9yRHN0RmFjdG9yIiwiYmxlbmRBbHBoYVNyY0ZhY3RvciIsImJsZW5kQWxwaGFEc3RGYWN0b3IiLCJibGVuZENvbG9yT3BlcmF0aW9uIiwiYmxlbmRBbHBoYU9wZXJhdGlvbiIsInNldFByb3BzIiwiYXNzaWduIiwicHJlUmVuZGVyIiwicG9zdFJlbmRlciIsInBhcmFtcyIsIl9wYXJhbXMkdmlld3BvcnRzIiwiaW5wdXRCdWZmZXIiLCJzd2FwQnVmZmVyIiwidGFyZ2V0Iiwib3V0cHV0QnVmZmVyIiwiZGVwdGhBdHRhY2htZW50IiwiZGVwdGhTdGVuY2lsQXR0YWNobWVudCIsInZpZXdwb3J0cyIsInBtIiwicHJvamVjdGlvbk1hdHJpeCIsIm4iLCJmIiwiTnVtYmVyIiwiaXNGaW5pdGUiLCJ3aWR0aCIsImhlaWdodCIsInNoYWRlcklucHV0cyIsInNjcmVlbiIsInRleFNyYyIsImNvbG9yQXR0YWNobWVudHMiLCJkaXN0YW5jZUZvZyIsInRleERlcHRoIiwicmVuZGVyUGFzcyIsImJlZ2luUmVuZGVyUGFzcyIsImZyYW1lYnVmZmVyIiwidmlld3BvcnQiLCJjb25jYXQiLCJjbGVhckNvbG9yIiwiY2xlYXJEZXB0aCIsImRyYXciLCJlbmQiLCJjbGVhbnVwIiwiZGVzdHJveSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaGFkZXItcGFzc2VzL2Rpc3RhbmNlLWZvZy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge0NsaXBTcGFjZX0gZnJvbSAnQGx1bWEuZ2wvZW5naW5lJztcbmltcG9ydCB0eXBlIHtTaGFkZXJNb2R1bGV9IGZyb20gJ0BsdW1hLmdsL3NoYWRlcnRvb2xzJztcblxuZXhwb3J0IHR5cGUgRGlzdGFuY2VGb2dQcm9wcyA9IHtcbiAgZGVuc2l0eTogbnVtYmVyO1xuICBmb2dTdGFydDogbnVtYmVyO1xuICBmb2dSYW5nZTogbnVtYmVyO1xuICBmb2dDb2xvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xufTtcblxuY29uc3QgRElTVEFOQ0VfRk9HX1VOSUZPUk1fQkxPQ0sgPSAvKiBnbHNsICovIGBcXFxudW5pZm9ybSBkaXN0YW5jZUZvZ1VuaWZvcm1zIHtcbiAgZmxvYXQgZGVuc2l0eTtcbiAgZmxvYXQgZm9nU3RhcnQ7XG4gIGZsb2F0IGZvZ1JhbmdlO1xuICBmbG9hdCBuZWFyUGxhbmU7XG4gIGZsb2F0IGZhclBsYW5lO1xuICB2ZWMzIGZvZ0NvbG9yO1xufSBkaXN0YW5jZUZvZztcbmA7XG5cbmNvbnN0IERJU1RBTkNFX0ZPR19GUyA9IC8qIGdsc2wgKi8gYFxcXG4jdmVyc2lvbiAzMDAgZXNcbnByZWNpc2lvbiBoaWdocCBmbG9hdDtcblxudW5pZm9ybSBzYW1wbGVyMkQgdGV4U3JjO1xudW5pZm9ybSBzYW1wbGVyMkQgdGV4RGVwdGg7XG5cbmluIHZlYzIgcG9zaXRpb247XG5pbiB2ZWMyIGNvb3JkaW5hdGU7XG5pbiB2ZWMyIHV2O1xuXG5vdXQgdmVjNCBmcmFnQ29sb3I7XG5cbnZvaWQgbWFpbigpIHtcbiAgdmVjNCBjb2xvciA9IHRleHR1cmUodGV4U3JjLCBjb29yZGluYXRlKTtcbiAgZmxvYXQgZGVwdGggPSB0ZXh0dXJlKHRleERlcHRoLCBjb29yZGluYXRlKS5yO1xuXG4gIGZsb2F0IG4gPSBkaXN0YW5jZUZvZy5uZWFyUGxhbmU7XG4gIGZsb2F0IGYgPSBkaXN0YW5jZUZvZy5mYXJQbGFuZTtcbiAgZmxvYXQgZXllWiA9IG4gKiBmIC8gKGYgLSBkZXB0aCAqIChmIC0gbikpO1xuICBmbG9hdCBsaW5lYXJEZXB0aCA9IChleWVaIC0gbikgLyAoZiAtIG4pO1xuXG4gIHZlYzMgZm9nQ29sb3IgPSBkaXN0YW5jZUZvZy5mb2dDb2xvciAvIDI1NS4wO1xuICBmbG9hdCBlbmQgPSBkaXN0YW5jZUZvZy5mb2dTdGFydCArIGRpc3RhbmNlRm9nLmZvZ1JhbmdlO1xuICBmbG9hdCBmb2dGYWN0b3IgPSBzbW9vdGhzdGVwKGRpc3RhbmNlRm9nLmZvZ1N0YXJ0LCBlbmQsIGxpbmVhckRlcHRoKSAqIGRpc3RhbmNlRm9nLmRlbnNpdHk7XG5cbiAgZnJhZ0NvbG9yID0gdmVjNChtaXgoY29sb3IucmdiLCBmb2dDb2xvciwgZm9nRmFjdG9yKSwgY29sb3IuYSk7XG59XG5gO1xuXG5jb25zdCBzY3JlZW5Nb2R1bGUgPSB7XG4gIG5hbWU6ICdzY3JlZW4nLFxuICBmczogLyogZ2xzbCAqLyBgXFxcbnVuaWZvcm0gc2NyZWVuVW5pZm9ybXMge1xuICB2ZWMyIHRleFNpemU7XG59IHNjcmVlbjtcbmAsXG4gIHVuaWZvcm1UeXBlczoge1xuICAgIHRleFNpemU6ICd2ZWMyPGYzMj4nXG4gIH1cbn0gYXMgY29uc3Qgc2F0aXNmaWVzIFNoYWRlck1vZHVsZTtcblxuY29uc3QgZGlzdGFuY2VGb2dNb2R1bGUgPSB7XG4gIG5hbWU6ICdkaXN0YW5jZUZvZycsXG4gIGZzOiBESVNUQU5DRV9GT0dfVU5JRk9STV9CTE9DSyxcbiAgdW5pZm9ybVR5cGVzOiB7XG4gICAgZGVuc2l0eTogJ2YzMicsXG4gICAgZm9nU3RhcnQ6ICdmMzInLFxuICAgIGZvZ1JhbmdlOiAnZjMyJyxcbiAgICBuZWFyUGxhbmU6ICdmMzInLFxuICAgIGZhclBsYW5lOiAnZjMyJyxcbiAgICBmb2dDb2xvcjogJ3ZlYzM8ZjMyPidcbiAgfSxcbiAgZGVmYXVsdFVuaWZvcm1zOiB7XG4gICAgZGVuc2l0eTogMC41LFxuICAgIGZvZ1N0YXJ0OiAwLjMsXG4gICAgZm9nUmFuZ2U6IDAuNSxcbiAgICBuZWFyUGxhbmU6IDAuMSxcbiAgICBmYXJQbGFuZTogMTAwMCxcbiAgICBmb2dDb2xvcjogWzIxNywgMjIyLCAyMzBdXG4gIH0sXG4gIHByb3BUeXBlczoge1xuICAgIGRlbnNpdHk6IHt2YWx1ZTogMC41LCBtaW46IDAsIG1heDogMX0sXG4gICAgZm9nU3RhcnQ6IHt2YWx1ZTogMC4zLCBtaW46IDAsIG1heDogMX0sXG4gICAgZm9nUmFuZ2U6IHt2YWx1ZTogMC41LCBtaW46IDAuMDEsIG1heDogMX0sXG4gICAgZm9nQ29sb3I6IHt2YWx1ZTogWzIxNywgMjIyLCAyMzBdfSxcbiAgICBuZWFyUGxhbmU6IHt2YWx1ZTogMC4xLCBwcml2YXRlOiB0cnVlfSxcbiAgICBmYXJQbGFuZToge3ZhbHVlOiAxMDAwLCBwcml2YXRlOiB0cnVlfVxuICB9XG59IGFzIGNvbnN0IHNhdGlzZmllcyBTaGFkZXJNb2R1bGU7XG5cbi8qKlxuICogRGlzdGFuY2UgRm9nIEVmZmVjdCAtIHVzZXMgdGhlIGRlcHRoIGJ1ZmZlciB0byBhcHBseSBmb2cgYmFzZWQgb25cbiAqIGNhbWVyYS10by1mcmFnbWVudCBkaXN0YW5jZS4gVGhlIHJhdyBkZXB0aCBidWZmZXIgdmFsdWVzIGFyZSBsaW5lYXJpemVkXG4gKiB1c2luZyB0aGUgY2FtZXJhJ3MgbmVhci9mYXIgcGxhbmVzIChleHRyYWN0ZWQgZnJvbSB0aGUgdmlld3BvcnQgcHJvamVjdGlvblxuICogbWF0cml4KSBzbyB0aGF0IHRoZSBmb2cgZ3JhZGllbnQgaXMgcGVyY2VwdHVhbGx5IHVuaWZvcm0gd2l0aCBkaXN0YW5jZS5cbiAqL1xuZXhwb3J0IGNsYXNzIERlY2tEaXN0YW5jZUZvZ0VmZmVjdCB7XG4gIGlkID0gJ2Rpc3RhbmNlLWZvZy1lZmZlY3QnO1xuICBwcm9wczogRGlzdGFuY2VGb2dQcm9wcztcbiAgbW9kdWxlID0gZGlzdGFuY2VGb2dNb2R1bGU7XG4gIHByaXZhdGUgbW9kZWw6IEluc3RhbmNlVHlwZTx0eXBlb2YgQ2xpcFNwYWNlPiB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByb3BzOiBQYXJ0aWFsPERpc3RhbmNlRm9nUHJvcHM+ID0ge30pIHtcbiAgICB0aGlzLnByb3BzID0ge1xuICAgICAgZGVuc2l0eTogMC41LFxuICAgICAgZm9nU3RhcnQ6IDAuMyxcbiAgICAgIGZvZ1JhbmdlOiAwLjUsXG4gICAgICBmb2dDb2xvcjogWzIxNywgMjIyLCAyMzBdLFxuICAgICAgLi4ucHJvcHNcbiAgICB9O1xuICB9XG5cbiAgc2V0dXAoe2RldmljZX0pIHtcbiAgICB0aGlzLm1vZGVsID0gbmV3IENsaXBTcGFjZShkZXZpY2UsIHtcbiAgICAgIGlkOiAnZGlzdGFuY2UtZm9nLXBhc3MnLFxuICAgICAgZnM6IERJU1RBTkNFX0ZPR19GUyxcbiAgICAgIG1vZHVsZXM6IFtkaXN0YW5jZUZvZ01vZHVsZSwgc2NyZWVuTW9kdWxlXSxcbiAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgZGVwdGhXcml0ZUVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICBkZXB0aENvbXBhcmU6ICdhbHdheXMnIGFzIGNvbnN0LFxuICAgICAgICBibGVuZDogdHJ1ZSxcbiAgICAgICAgYmxlbmRDb2xvclNyY0ZhY3RvcjogJ29uZScgYXMgY29uc3QsXG4gICAgICAgIGJsZW5kQ29sb3JEc3RGYWN0b3I6ICdvbmUtbWludXMtc3JjLWFscGhhJyBhcyBjb25zdCxcbiAgICAgICAgYmxlbmRBbHBoYVNyY0ZhY3RvcjogJ29uZScgYXMgY29uc3QsXG4gICAgICAgIGJsZW5kQWxwaGFEc3RGYWN0b3I6ICdvbmUtbWludXMtc3JjLWFscGhhJyBhcyBjb25zdCxcbiAgICAgICAgYmxlbmRDb2xvck9wZXJhdGlvbjogJ2FkZCcgYXMgY29uc3QsXG4gICAgICAgIGJsZW5kQWxwaGFPcGVyYXRpb246ICdhZGQnIGFzIGNvbnN0XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzZXRQcm9wcyhwcm9wczogUGFydGlhbDxEaXN0YW5jZUZvZ1Byb3BzPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5wcm9wcywgcHJvcHMpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBwcmVSZW5kZXIoKTogdm9pZCB7fVxuXG4gIHBvc3RSZW5kZXIocGFyYW1zOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHtpbnB1dEJ1ZmZlciwgc3dhcEJ1ZmZlciwgdGFyZ2V0fSA9IHBhcmFtcztcbiAgICBjb25zdCBvdXRwdXRCdWZmZXIgPSB0YXJnZXQgIT09IHVuZGVmaW5lZCA/IHRhcmdldCA6IHN3YXBCdWZmZXI7XG5cbiAgICBpZiAoIXRoaXMubW9kZWwpIHJldHVybiBpbnB1dEJ1ZmZlcjtcblxuICAgIC8vIERpc3RhbmNlIGZvZyBhbHdheXMgcnVucyBmaXJzdCBhbW9uZyBwb3N0LXByb2Nlc3NpbmcgZWZmZWN0c1xuICAgIC8vIChlbmZvcmNlZCBieSBmaXhFZmZlY3RPcmRlciksIHNvIGlucHV0QnVmZmVyIGlzIGFsd2F5cyB0aGUgc2NlbmVcbiAgICAvLyByZW5kZXIgdGFyZ2V0IHdpdGggdmFsaWQgZGVwdGggZGF0YS5cbiAgICBjb25zdCBkZXB0aEF0dGFjaG1lbnQgPSBpbnB1dEJ1ZmZlci5kZXB0aFN0ZW5jaWxBdHRhY2htZW50O1xuICAgIGlmICghZGVwdGhBdHRhY2htZW50KSByZXR1cm4gaW5wdXRCdWZmZXI7XG5cbiAgICBsZXQgbmVhclBsYW5lID0gMC4xO1xuICAgIGxldCBmYXJQbGFuZSA9IDEwMDA7XG4gICAgaWYgKHBhcmFtcy52aWV3cG9ydHM/Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHBtID0gcGFyYW1zLnZpZXdwb3J0c1swXS5wcm9qZWN0aW9uTWF0cml4O1xuICAgICAgaWYgKHBtKSB7XG4gICAgICAgIGNvbnN0IG4gPSBwbVsxNF0gLyAocG1bMTBdIC0gMSk7XG4gICAgICAgIGNvbnN0IGYgPSBwbVsxNF0gLyAocG1bMTBdICsgMSk7XG4gICAgICAgIGlmIChOdW1iZXIuaXNGaW5pdGUobikgJiYgTnVtYmVyLmlzRmluaXRlKGYpICYmIG4gPiAwICYmIGYgPiBuKSB7XG4gICAgICAgICAgbmVhclBsYW5lID0gbjtcbiAgICAgICAgICBmYXJQbGFuZSA9IGY7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0ZXhTaXplOiBbbnVtYmVyLCBudW1iZXJdID0gW2lucHV0QnVmZmVyLndpZHRoLCBpbnB1dEJ1ZmZlci5oZWlnaHRdO1xuXG4gICAgdGhpcy5tb2RlbC5zaGFkZXJJbnB1dHMuc2V0UHJvcHMoe1xuICAgICAgc2NyZWVuOiB7XG4gICAgICAgIHRleFNyYzogaW5wdXRCdWZmZXIuY29sb3JBdHRhY2htZW50c1swXSxcbiAgICAgICAgdGV4U2l6ZVxuICAgICAgfSxcbiAgICAgIGRpc3RhbmNlRm9nOiB7XG4gICAgICAgIHRleERlcHRoOiBkZXB0aEF0dGFjaG1lbnQsXG4gICAgICAgIGRlbnNpdHk6IHRoaXMucHJvcHMuZGVuc2l0eSxcbiAgICAgICAgZm9nU3RhcnQ6IHRoaXMucHJvcHMuZm9nU3RhcnQsXG4gICAgICAgIGZvZ1JhbmdlOiB0aGlzLnByb3BzLmZvZ1JhbmdlLFxuICAgICAgICBuZWFyUGxhbmUsXG4gICAgICAgIGZhclBsYW5lLFxuICAgICAgICBmb2dDb2xvcjogdGhpcy5wcm9wcy5mb2dDb2xvclxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVuZGVyUGFzcyA9IHRoaXMubW9kZWwuZGV2aWNlLmJlZ2luUmVuZGVyUGFzcyh7XG4gICAgICBmcmFtZWJ1ZmZlcjogb3V0cHV0QnVmZmVyLFxuICAgICAgcGFyYW1ldGVyczoge3ZpZXdwb3J0OiBbMCwgMCwgLi4udGV4U2l6ZV19LFxuICAgICAgY2xlYXJDb2xvcjogWzAsIDAsIDAsIDBdLFxuICAgICAgY2xlYXJEZXB0aDogMVxuICAgIH0pO1xuICAgIHRoaXMubW9kZWwuZHJhdyhyZW5kZXJQYXNzKTtcbiAgICByZW5kZXJQYXNzLmVuZCgpO1xuXG4gICAgcmV0dXJuIG91dHB1dEJ1ZmZlciB8fCBpbnB1dEJ1ZmZlcjtcbiAgfVxuXG4gIGNsZWFudXAoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubW9kZWwpIHtcbiAgICAgIHRoaXMubW9kZWwuZGVzdHJveSgpO1xuICAgICAgdGhpcy5tb2RlbCA9IG51bGw7XG4gICAgfVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFHQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFBMEMsU0FBQUMsUUFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEsR0FBQUMsTUFBQSxDQUFBQyxJQUFBLENBQUFKLENBQUEsT0FBQUcsTUFBQSxDQUFBRSxxQkFBQSxRQUFBQyxDQUFBLEdBQUFI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