UNPKG

kepler.gl

Version:

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

461 lines (430 loc) 56.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.addCustomPaletteColor = addCustomPaletteColor; exports.addNewQuantativeColorBreakAtIndex = addNewQuantativeColorBreakAtIndex; exports.colorMaybeToHex = colorMaybeToHex; exports.colorMaybeToRGB = colorMaybeToRGB; exports.colorRangeBackwardCompatibility = colorRangeBackwardCompatibility; exports.createLinearGradient = createLinearGradient; exports.hasColorMap = hasColorMap; exports.hexToRgb = hexToRgb; exports.initializeCustomPalette = initializeCustomPalette; exports.interpolateHex = interpolateHex; exports.isHexColor = isHexColor; exports.isQuaPalette = isQuaPalette; exports.isRgbColor = isRgbColor; exports.normalizeColor = normalizeColor; exports.paletteIsColorBlindSafe = paletteIsColorBlindSafe; exports.paletteIsSteps = paletteIsSteps; exports.paletteIsType = paletteIsType; exports.removeCustomPaletteColor = removeCustomPaletteColor; exports.reverseColorRange = reverseColorRange; exports.rgbToHex = rgbToHex; exports.sortCustomPaletteColor = sortCustomPaletteColor; exports.updateColorRangeByMatchingPalette = updateColorRangeByMatchingPalette; exports.updateColorRangeBySelectedPalette = updateColorRangeBySelectedPalette; exports.updateCustomColorRangeByColorUI = updateCustomColorRangeByColorUI; exports.updateCustomPaletteColor = updateCustomPaletteColor; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _constants = require("@kepler.gl/constants"); var _d3Color = require("d3-color"); var _d3Interpolate = require("d3-interpolate"); var _utils = require("./utils"); var _console = _interopRequireDefault(require("global/console")); var _excluded = ["colors"]; 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 /** * get r g b from hex code * * @param hex * @returns array of r g bs */ function hexToRgb(hex) { var result = isHexColor(hex); if (!result) { return [0, 0, 0]; } var r = parseInt(result[1], 16); var g = parseInt(result[2], 16); var b = parseInt(result[3], 16); return [r, g, b]; } function isHexColor(hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result; } function PadNum(c) { var hex = c.toString(16); return hex.length === 1 ? "0".concat(hex) : hex; } /** * get hex from r g b * * @param rgb * @returns hex string */ function rgbToHex(_ref) { var _ref2 = (0, _slicedToArray2["default"])(_ref, 3), r = _ref2[0], g = _ref2[1], b = _ref2[2]; return "#".concat([r, g, b].map(function (n) { return PadNum(n); }).join('')).toUpperCase(); } /** * Whether color range has custom color map */ function hasColorMap(colorRange) { return Array.isArray(colorRange.colorMap) && Boolean(colorRange.colorMap.length); } /** * given a list of rgb arrays it will generate a linear gradient css rule * @param direction * @param colors * @return */ function createLinearGradient(direction, colors) { var step = parseFloat((100.0 / colors.length).toFixed(2)); var bands = colors.map(function (rgb, index) { return "rgba(".concat(rgb.join(','), ", 1) ").concat(step * index, "%, rgba(").concat(rgb.join(','), ", 1) ").concat(step * (index + 1), "%"); }); return "linear-gradient(to ".concat(direction, ", ").concat(bands.join(','), ")"); } /** * Convert color to RGB */ function colorMaybeToRGB(color) { if (isRgbColor(color)) { return color; } if (typeof color === 'string') { var rgbObj = (0, _d3Color.rgb)(color); if (Number.isFinite(rgbObj === null || rgbObj === void 0 ? void 0 : rgbObj.r) && Number.isFinite(rgbObj === null || rgbObj === void 0 ? void 0 : rgbObj.g) && Number.isFinite(rgbObj === null || rgbObj === void 0 ? void 0 : rgbObj.b)) { return [rgbObj.r, rgbObj.g, rgbObj.b]; } } return null; } /** * Whether color is rgb * @returns */ function isRgbColor(color) { return Boolean(color && Array.isArray(color) && color.length === 3 && color.every(function (n) { return Number.isFinite(n) && n <= 255 && n >= 0; })); } /** * Take color values in 0-255 range and map to [0, 1] */ function normalizeColor(color) { return color.map(function (component) { return component / 255.0; }); } /** * Convert color to Hex */ function colorMaybeToHex(color) { var rgbColor = colorMaybeToRGB(color); if (rgbColor) return rgbToHex(rgbColor); return '#000000'; } /** * Convert color to Hex */ function interpolateHex(hex1, hex2) { return (0, _d3Color.rgb)((0, _d3Interpolate.interpolate)(hex1, hex2)(0.5)).hex().toUpperCase(); } function addNewCategoricalStepAtIndex(colorMap, index, newColor) { if (!Array.isArray(colorMap) || !colorMap.length) { return colorMap; } var newColorMap = colorMap.map(function (_ref3) { var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2), val = _ref4[0], c = _ref4[1]; return [Array.isArray(val) ? (0, _toConsumableArray2["default"])(val) : val, c]; }); newColorMap = (0, _utils.arrayInsert)(newColorMap, index + 1, [null, newColor]); return newColorMap; } function addNewQuantativeColorBreakAtIndex(colorMap, index, newColors) { if (!Array.isArray(colorMap) || !colorMap.length) { return colorMap; } if (colorMap.length < 2) { // less then 2, add 1 at end // however shouldn't allow delete when there are 2 return newColors.map(function (c, i) { return i === 0 ? colorMap[i] : [null, c]; }); } // breaks should be 1 less than colors var breaks = colorMap.map(function (cm) { return cm[0]; }).slice(0, colorMap.length - 1); // insert new break var newValue = index >= breaks.length - 1 ? breaks[breaks.length - 1] + (breaks.length > 1 ? breaks[breaks.length - 1] - breaks[breaks.length - 2] : 0) : (breaks[index] + breaks[index + 1]) / 2; var newBreaks = (0, _utils.arrayInsert)(breaks, index + 1, newValue); // asign breaks to color return newColors.map(function (c, i) { return i === newColors.length - 1 ? [null, c] : [newBreaks[i] === undefined ? null : newBreaks[i], c]; }); } /** * Add a new color to custom palette */ function addCustomPaletteColor(customPalette, index) { var colors = customPalette.colors, colorMap = customPalette.colorMap; var update = {}; var newColor = index === colors.length - 1 ? colors[index] : interpolateHex(colors[index], colors[index + 1]); update.colors = (0, _utils.arrayInsert)(colors, index + 1, newColor); // add color to colorMap if (colorMap) { update.colorMap = customPalette.type === 'customOrdinal' ? addNewCategoricalStepAtIndex(colorMap, index, newColor) : addNewQuantativeColorBreakAtIndex(colorMap, index, update.colors); } return _objectSpread(_objectSpread({}, customPalette), update); } function replaceColorsInColorRange(colorRange, newColors) { var oldColors = colorRange.colors; var updated = _objectSpread(_objectSpread({}, colorRange), {}, { colors: newColors }); // update color map // keep value, replace color if (Array.isArray(updated.colorMap)) { updated.colorMap = updated.colorMap.map(function (cm, i) { return [cm[0], newColors[i]]; }); } // update colorlegends // keep value, replace color if (updated.colorLegends) { updated.colorLegends = Object.keys(updated.colorLegends).reduce(function (accu, key) { var colorIdx = oldColors.findIndex(function (c) { return c === key; }); var newColor = newColors[colorIdx]; return newColor ? _objectSpread(_objectSpread({}, accu), {}, (0, _defineProperty2["default"])({}, newColor, updated.colorLegends[key])) : accu; }, {}); } return updated; } /** * Sort custom palette */ function sortCustomPaletteColor(customPalette, oldIndex, newIndex) { var colors = customPalette.colors; var newColors = (0, _utils.arrayMove)(colors, oldIndex, newIndex); var update = replaceColorsInColorRange(customPalette, newColors); // @ts-ignore return _objectSpread(_objectSpread({}, customPalette), update); } /** * remove a color in custom palette at index */ function removeCustomPaletteColor(customPalette, index) { var colors = customPalette.colors, colorMap = customPalette.colorMap, colorLegends = customPalette.colorLegends; var oldValue = colors[index]; var update = {}; update.colors = (0, _toConsumableArray2["default"])(colors); if (update.colors.length > 1) { update.colors.splice(index, 1); } // update color map if (Array.isArray(colorMap)) { // find colorMap index var colorMapIndex = colorMap.findIndex(function (cm) { return cm[1] === oldValue; }); if (colorMapIndex >= 0) { update.colorMap = (0, _toConsumableArray2["default"])(colorMap); update.colorMap.splice(colorMapIndex, 1); } } // update color legend if (colorLegends !== null && colorLegends !== void 0 && colorLegends[oldValue]) { update.colorLegends = _objectSpread({}, colorLegends); delete update.colorLegends[oldValue]; } return _objectSpread(_objectSpread({}, customPalette), update); } /** * Update a color in custom palette at index */ function updateCustomPaletteColor(customPalette, index, newValue) { var colors = customPalette.colors; var hex = newValue.toUpperCase(); var newColors = (0, _toConsumableArray2["default"])(colors); newColors[index] = hex; var update = replaceColorsInColorRange(customPalette, newColors); // @ts-ignore return _objectSpread(_objectSpread({}, customPalette), update); } /** * Get a reversed colorRange */ function reverseColorRange(reversed, colorRange) { var newColors = colorRange === null || colorRange === void 0 ? void 0 : colorRange.colors.slice().reverse(); var updated = replaceColorsInColorRange(colorRange, newColors); updated.reversed = reversed; return updated; } /** * Whether palette matches current ColorBlindSafe config */ function paletteIsColorBlindSafe(palette, colorBlindSafe) { return !colorBlindSafe || colorBlindSafe && palette.colorBlindSafe; } /** * Whether palette matches current steps config */ function isQuaPalette(palette) { return palette.type === _constants.PALETTE_TYPES.QUA; } /** * Whether palette matches current steps config */ function paletteIsSteps(palette, steps) { return !isQuaPalette(palette) || palette.maxStep >= steps; } /** * Whether palette matches current type config */ function paletteIsType(palette, type) { return type === 'all' || type === palette.type; } /** * Find best match palette based on config, update color range by it */ function updateColorRangeByMatchingPalette(currentColorRange, config) { var steps = config.steps, colorBlindSafe = config.colorBlindSafe, type = config.type; var matchingPalette = _constants.KEPLER_COLOR_PALETTES.filter(function (palette) { return ( // palette match type paletteIsType(palette, type) && // palette has same step paletteIsSteps(palette, steps) && // palette is colorBlindSafe paletteIsColorBlindSafe(palette, colorBlindSafe) ); }); var bestMatch = matchingPalette.length ? matchingPalette.find(function (p) { return p.name === currentColorRange.name; }) || matchingPalette[0] : null; if (bestMatch) { return updateColorRangeBySelectedPalette(currentColorRange, bestMatch, config); } // we do nothing _console["default"].warn("we cant find any preset palette matches requirments: steps=".concat(steps, " && colorBlindSafe=").concat(colorBlindSafe)); return currentColorRange; } /** * Update custom palette when reverse the colors in custom palette, since changing 'steps', * 'colorBindSafe', 'type' should fall back to predefined palette. */ function updateCustomColorRangeByColorUI(oldColorRange, colorConfig) { var reversed = colorConfig.reversed; var colors = oldColorRange.colors; // for custom palette, one can only 'reverse' the colors in custom palette. colors.reverse(); var colorRange = _objectSpread(_objectSpread(_objectSpread({ name: oldColorRange.name, type: oldColorRange.type, category: oldColorRange.category, colors: colors }, reversed ? { reversed: reversed } : {}), oldColorRange.colorMap ? { colorMap: oldColorRange.colorMap } : {}), oldColorRange.colorLegends ? { colorLegends: oldColorRange.colorLegends } : {}); return replaceColorsInColorRange(colorRange, colorRange.colors); } /** * Update color range after selecting a palette from color range selectoer * Copy over colorMap and colorLegends */ function updateColorRangeBySelectedPalette(oldColorRange, colorPalette, colorConfig) { var _colorPaletteToColorR = (0, _constants.colorPaletteToColorRange)(colorPalette, colorConfig), newColors = _colorPaletteToColorR.colors, newColorRange = (0, _objectWithoutProperties2["default"])(_colorPaletteToColorR, _excluded); var colorRange = _objectSpread(_objectSpread(_objectSpread({ colors: oldColorRange.colors }, newColorRange), oldColorRange.colorMap ? { colorMap: oldColorRange.colorMap } : {}), oldColorRange.colorLegends ? { colorLegends: oldColorRange.colorLegends } : {}); return replaceColorsInColorRange(colorRange, newColors); } var UberNameRegex = new RegExp(/^([A-Za-z ])+/g); var ColorBrewerRegex = new RegExp(/^ColorBrewer ([A-Za-z1-9])+/g); /** * convert saved colorRange to colorPalette objevt type/name/category/isColorBlind */ function colorRangeBackwardCompatibility(colorRange) { if (!colorRange || colorRange.type === 'custom' || colorRange.colorMap) { // don't do anything to custom color palette, or palette with custom breaks return colorRange; } var trimName; if (colorRange.category === 'Uber') { var _colorRange$name; var matchName = ((_colorRange$name = colorRange.name) !== null && _colorRange$name !== void 0 ? _colorRange$name : '').match(UberNameRegex); trimName = matchName ? matchName[0].trim() : null; // match Uber Viz Qualitative 1.4 -> Uber Viz Qualitative } else if (colorRange.category === 'ColorBrewer') { var _colorRange$name2; var _matchName = ((_colorRange$name2 = colorRange.name) !== null && _colorRange$name2 !== void 0 ? _colorRange$name2 : '').match(ColorBrewerRegex); trimName = _matchName ? _matchName[0].replace('ColorBrewer ', '').trim() : null; } if (trimName) { var matchingPalette = _constants.KEPLER_COLOR_PALETTES.find(function (p) { return p.name === trimName; }); if (matchingPalette) { return _objectSpread(_objectSpread({}, colorRange), {}, { name: trimName, type: matchingPalette === null || matchingPalette === void 0 ? void 0 : matchingPalette.type, category: matchingPalette.category }); } } return colorRange; } /** * Initialize custom palette from current standard color range object */ function initializeCustomPalette(colorRange, colorMap) { // TODO: check on `isReversed` key, whether we can remove it here var customPalette = _objectSpread(_objectSpread({}, colorRange), {}, { name: _constants.DEFAULT_CUSTOM_PALETTE.name, type: _constants.DEFAULT_CUSTOM_PALETTE.type, category: _constants.DEFAULT_CUSTOM_PALETTE.category }, colorMap ? { colorMap: colorMap } : {}); // only customPalette.colors are needed for custom palette editor with custom ordinal scale if (!colorMap && colorRange.type === _constants.SCALE_TYPES.customOrdinal) { delete customPalette.colorMap; } return customPalette; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29uc3RhbnRzIiwicmVxdWlyZSIsIl9kM0NvbG9yIiwiX2QzSW50ZXJwb2xhdGUiLCJfdXRpbHMiLCJfY29uc29sZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfZXhjbHVkZWQiLCJvd25LZXlzIiwiZSIsInIiLCJ0IiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsImhleFRvUmdiIiwiaGV4IiwicmVzdWx0IiwiaXNIZXhDb2xvciIsInBhcnNlSW50IiwiZyIsImIiLCJleGVjIiwiUGFkTnVtIiwiYyIsInRvU3RyaW5nIiwiY29uY2F0IiwicmdiVG9IZXgiLCJfcmVmIiwiX3JlZjIiLCJfc2xpY2VkVG9BcnJheTIiLCJtYXAiLCJuIiwiam9pbiIsInRvVXBwZXJDYXNlIiwiaGFzQ29sb3JNYXAiLCJjb2xvclJhbmdlIiwiQXJyYXkiLCJpc0FycmF5IiwiY29sb3JNYXAiLCJCb29sZWFuIiwiY3JlYXRlTGluZWFyR3JhZGllbnQiLCJkaXJlY3Rpb24iLCJjb2xvcnMiLCJzdGVwIiwicGFyc2VGbG9hdCIsInRvRml4ZWQiLCJiYW5kcyIsInJnYiIsImluZGV4IiwiY29sb3JNYXliZVRvUkdCIiwiY29sb3IiLCJpc1JnYkNvbG9yIiwicmdiT2JqIiwiZDNSZ2IiLCJOdW1iZXIiLCJpc0Zpbml0ZSIsImV2ZXJ5Iiwibm9ybWFsaXplQ29sb3IiLCJjb21wb25lbnQiLCJjb2xvck1heWJlVG9IZXgiLCJyZ2JDb2xvciIsImludGVycG9sYXRlSGV4IiwiaGV4MSIsImhleDIiLCJpbnRlcnBvbGF0ZSIsImFkZE5ld0NhdGVnb3JpY2FsU3RlcEF0SW5kZXgiLCJuZXdDb2xvciIsIm5ld0NvbG9yTWFwIiwiX3JlZjMiLCJfcmVmNCIsInZhbCIsIl90b0NvbnN1bWFibGVBcnJheTIiLCJhcnJheUluc2VydCIsImFkZE5ld1F1YW50YXRpdmVDb2xvckJyZWFrQXRJbmRleCIsIm5ld0NvbG9ycyIsImkiLCJicmVha3MiLCJjbSIsInNsaWNlIiwibmV3VmFsdWUiLCJuZXdCcmVha3MiLCJ1bmRlZmluZWQiLCJhZGRDdXN0b21QYWxldHRlQ29sb3IiLCJjdXN0b21QYWxldHRlIiwidXBkYXRlIiwidHlwZSIsInJlcGxhY2VDb2xvcnNJbkNvbG9yUmFuZ2UiLCJvbGRDb2xvcnMiLCJ1cGRhdGVkIiwiY29sb3JMZWdlbmRzIiwicmVkdWNlIiwiYWNjdSIsImtleSIsImNvbG9ySWR4IiwiZmluZEluZGV4Iiwic29ydEN1c3RvbVBhbGV0dGVDb2xvciIsIm9sZEluZGV4IiwibmV3SW5kZXgiLCJhcnJheU1vdmUiLCJyZW1vdmVDdXN0b21QYWxldHRlQ29sb3IiLCJvbGRWYWx1ZSIsInNwbGljZSIsImNvbG9yTWFwSW5kZXgiLCJ1cGRhdGVDdXN0b21QYWxldHRlQ29sb3IiLCJyZXZlcnNlQ29sb3JSYW5nZSIsInJldmVyc2VkIiwicmV2ZXJzZSIsInBhbGV0dGVJc0NvbG9yQmxpbmRTYWZlIiwicGFsZXR0ZSIsImNvbG9yQmxpbmRTYWZlIiwiaXNRdWFQYWxldHRlIiwiUEFMRVRURV9UWVBFUyIsIlFVQSIsInBhbGV0dGVJc1N0ZXBzIiwic3RlcHMiLCJtYXhTdGVwIiwicGFsZXR0ZUlzVHlwZSIsInVwZGF0ZUNvbG9yUmFuZ2VCeU1hdGNoaW5nUGFsZXR0ZSIsImN1cnJlbnRDb2xvclJhbmdlIiwiY29uZmlnIiwibWF0Y2hpbmdQYWxldHRlIiwiS0VQTEVSX0NPTE9SX1BBTEVUVEVTIiwiYmVzdE1hdGNoIiwiZmluZCIsInAiLCJuYW1lIiwidXBkYXRlQ29sb3JSYW5nZUJ5U2VsZWN0ZWRQYWxldHRlIiwiQ29uc29sZSIsIndhcm4iLCJ1cGRhdGVDdXN0b21Db2xvclJhbmdlQnlDb2xvclVJIiwib2xkQ29sb3JSYW5nZSIsImNvbG9yQ29uZmlnIiwiY2F0ZWdvcnkiLCJjb2xvclBhbGV0dGUiLCJfY29sb3JQYWxldHRlVG9Db2xvclIiLCJjb2xvclBhbGV0dGVUb0NvbG9yUmFuZ2UiLCJuZXdDb2xvclJhbmdlIiwiX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzMiIsIlViZXJOYW1lUmVnZXgiLCJSZWdFeHAiLCJDb2xvckJyZXdlclJlZ2V4IiwiY29sb3JSYW5nZUJhY2t3YXJkQ29tcGF0aWJpbGl0eSIsInRyaW1OYW1lIiwiX2NvbG9yUmFuZ2UkbmFtZSIsIm1hdGNoTmFtZSIsIm1hdGNoIiwidHJpbSIsIl9jb2xvclJhbmdlJG5hbWUyIiwicmVwbGFjZSIsImluaXRpYWxpemVDdXN0b21QYWxldHRlIiwiREVGQVVMVF9DVVNUT01fUEFMRVRURSIsIlNDQUxFX1RZUEVTIiwiY3VzdG9tT3JkaW5hbCJdLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xvci11dGlscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTUlUXG4vLyBDb3B5cmlnaHQgY29udHJpYnV0b3JzIHRvIHRoZSBrZXBsZXIuZ2wgcHJvamVjdFxuXG5pbXBvcnQge1xuICBDYXRlZ29yaWNhbFBhbGV0dGUsXG4gIENvbG9yUGFsZXR0ZSxcbiAgREVGQVVMVF9DVVNUT01fUEFMRVRURSxcbiAgY29sb3JQYWxldHRlVG9Db2xvclJhbmdlXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIENvbG9yTWFwLFxuICBDb2xvclJhbmdlLFxuICBDb2xvclJhbmdlQ29uZmlnLFxuICBIZXhDb2xvcixcbiAgUkdCQUNvbG9yLFxuICBSR0JDb2xvclxufSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB7cmdiIGFzIGQzUmdifSBmcm9tICdkMy1jb2xvcic7XG5pbXBvcnQge2ludGVycG9sYXRlfSBmcm9tICdkMy1pbnRlcnBvbGF0ZSc7XG5pbXBvcnQge2FycmF5SW5zZXJ0LCBhcnJheU1vdmV9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IENvbnNvbGUgZnJvbSAnZ2xvYmFsL2NvbnNvbGUnO1xuaW1wb3J0IHtLRVBMRVJfQ09MT1JfUEFMRVRURVMsIFBBTEVUVEVfVFlQRVMsIFNDQUxFX1RZUEVTfSBmcm9tICdAa2VwbGVyLmdsL2NvbnN0YW50cyc7XG5cbi8qKlxuICogZ2V0IHIgZyBiIGZyb20gaGV4IGNvZGVcbiAqXG4gKiBAcGFyYW0gaGV4XG4gKiBAcmV0dXJucyBhcnJheSBvZiByIGcgYnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhleFRvUmdiKGhleDogc3RyaW5nKTogUkdCQ29sb3Ige1xuICBjb25zdCByZXN1bHQgPSBpc0hleENvbG9yKGhleCk7XG5cbiAgaWYgKCFyZXN1bHQpIHtcbiAgICByZXR1cm4gWzAsIDAsIDBdO1xuICB9XG5cbiAgY29uc3QgciA9IHBhcnNlSW50KHJlc3VsdFsxXSwgMTYpO1xuICBjb25zdCBnID0gcGFyc2VJbnQocmVzdWx0WzJdLCAxNik7XG4gIGNvbnN0IGIgPSBwYXJzZUludChyZXN1bHRbM10sIDE2KTtcblxuICByZXR1cm4gW3IsIGcsIGJdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNIZXhDb2xvcihoZXg6IHN0cmluZyk6IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGwge1xuICBjb25zdCByZXN1bHQgPSAvXiM/KFthLWZcXGRdezJ9KShbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pJC9pLmV4ZWMoaGV4KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBQYWROdW0oYykge1xuICBjb25zdCBoZXggPSBjLnRvU3RyaW5nKDE2KTtcbiAgcmV0dXJuIGhleC5sZW5ndGggPT09IDEgPyBgMCR7aGV4fWAgOiBoZXg7XG59XG5cbi8qKlxuICogZ2V0IGhleCBmcm9tIHIgZyBiXG4gKlxuICogQHBhcmFtIHJnYlxuICogQHJldHVybnMgaGV4IHN0cmluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmdiVG9IZXgoW3IsIGcsIGJdOiBSR0JDb2xvciB8IFJHQkFDb2xvcik6IEhleENvbG9yIHtcbiAgcmV0dXJuIGAjJHtbciwgZywgYl0ubWFwKG4gPT4gUGFkTnVtKG4pKS5qb2luKCcnKX1gLnRvVXBwZXJDYXNlKCk7XG59XG5cbi8qKlxuICogV2hldGhlciBjb2xvciByYW5nZSBoYXMgY3VzdG9tIGNvbG9yIG1hcFxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzQ29sb3JNYXAoY29sb3JSYW5nZTogQ29sb3JSYW5nZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShjb2xvclJhbmdlLmNvbG9yTWFwKSAmJiBCb29sZWFuKGNvbG9yUmFuZ2UuY29sb3JNYXAubGVuZ3RoKTtcbn1cblxuLyoqXG4gKiBnaXZlbiBhIGxpc3Qgb2YgcmdiIGFycmF5cyBpdCB3aWxsIGdlbmVyYXRlIGEgbGluZWFyIGdyYWRpZW50IGNzcyBydWxlXG4gKiBAcGFyYW0gZGlyZWN0aW9uXG4gKiBAcGFyYW0gY29sb3JzXG4gKiBAcmV0dXJuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMaW5lYXJHcmFkaWVudChkaXJlY3Rpb246IHN0cmluZywgY29sb3JzOiBSR0JDb2xvcltdKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RlcCA9IHBhcnNlRmxvYXQoKDEwMC4wIC8gY29sb3JzLmxlbmd0aCkudG9GaXhlZCgyKSk7XG4gIGNvbnN0IGJhbmRzID0gY29sb3JzLm1hcCgocmdiLCBpbmRleCkgPT4ge1xuICAgIHJldHVybiBgcmdiYSgke3JnYi5qb2luKCcsJyl9LCAxKSAke3N0ZXAgKiBpbmRleH0lLCByZ2JhKCR7cmdiLmpvaW4oJywnKX0sIDEpICR7XG4gICAgICBzdGVwICogKGluZGV4ICsgMSlcbiAgICB9JWA7XG4gIH0pO1xuXG4gIHJldHVybiBgbGluZWFyLWdyYWRpZW50KHRvICR7ZGlyZWN0aW9ufSwgJHtiYW5kcy5qb2luKCcsJyl9KWA7XG59XG5cbi8qKlxuICogQ29udmVydCBjb2xvciB0byBSR0JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yTWF5YmVUb1JHQihjb2xvcjogdW5rbm93bik6IFJHQkNvbG9yIHwgbnVsbCB7XG4gIGlmIChpc1JnYkNvbG9yKGNvbG9yKSkge1xuICAgIHJldHVybiBjb2xvciBhcyBSR0JDb2xvcjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgY29sb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgcmdiT2JqID0gZDNSZ2IoY29sb3IpO1xuICAgIGlmIChOdW1iZXIuaXNGaW5pdGUocmdiT2JqPy5yKSAmJiBOdW1iZXIuaXNGaW5pdGUocmdiT2JqPy5nKSAmJiBOdW1iZXIuaXNGaW5pdGUocmdiT2JqPy5iKSkge1xuICAgICAgcmV0dXJuIFtyZ2JPYmouciwgcmdiT2JqLmcsIHJnYk9iai5iXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGNvbG9yIGlzIHJnYlxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUmdiQ29sb3IoY29sb3I6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgY29sb3IgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkoY29sb3IpICYmXG4gICAgICBjb2xvci5sZW5ndGggPT09IDMgJiZcbiAgICAgIGNvbG9yLmV2ZXJ5KG4gPT4gTnVtYmVyLmlzRmluaXRlKG4pICYmIG4gPD0gMjU1ICYmIG4gPj0gMClcbiAgKTtcbn1cblxuLyoqXG4gKiBUYWtlIGNvbG9yIHZhbHVlcyBpbiAwLTI1NSByYW5nZSBhbmQgbWFwIHRvIFswLCAxXVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQ29sb3IoY29sb3I6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICByZXR1cm4gY29sb3IubWFwKGNvbXBvbmVudCA9PiBjb21wb25lbnQgLyAyNTUuMCk7XG59XG5cbi8qKlxuICogQ29udmVydCBjb2xvciB0byBIZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yTWF5YmVUb0hleChjb2xvcjogdW5rbm93bik6IEhleENvbG9yIHtcbiAgY29uc3QgcmdiQ29sb3IgPSBjb2xvck1heWJlVG9SR0IoY29sb3IpO1xuICBpZiAocmdiQ29sb3IpIHJldHVybiByZ2JUb0hleChyZ2JDb2xvcik7XG4gIHJldHVybiAnIzAwMDAwMCc7XG59XG5cbi8qKlxuICogQ29udmVydCBjb2xvciB0byBIZXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJwb2xhdGVIZXgoaGV4MTogSGV4Q29sb3IsIGhleDI6IEhleENvbG9yKTogSGV4Q29sb3Ige1xuICByZXR1cm4gZDNSZ2IoaW50ZXJwb2xhdGUoaGV4MSwgaGV4MikoMC41KSkuaGV4KCkudG9VcHBlckNhc2UoKTtcbn1cblxuZnVuY3Rpb24gYWRkTmV3Q2F0ZWdvcmljYWxTdGVwQXRJbmRleChjb2xvck1hcCwgaW5kZXgsIG5ld0NvbG9yKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShjb2xvck1hcCkgfHwgIWNvbG9yTWFwLmxlbmd0aCkge1xuICAgIHJldHVybiBjb2xvck1hcDtcbiAgfVxuXG4gIGxldCBuZXdDb2xvck1hcCA9IGNvbG9yTWFwLm1hcCgoW3ZhbCwgY10pID0+IFtBcnJheS5pc0FycmF5KHZhbCkgPyBbLi4udmFsXSA6IHZhbCwgY10pO1xuICBuZXdDb2xvck1hcCA9IGFycmF5SW5zZXJ0KG5ld0NvbG9yTWFwLCBpbmRleCArIDEsIFtudWxsLCBuZXdDb2xvcl0pO1xuXG4gIHJldHVybiBuZXdDb2xvck1hcDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZE5ld1F1YW50YXRpdmVDb2xvckJyZWFrQXRJbmRleChjb2xvck1hcCwgaW5kZXgsIG5ld0NvbG9ycykge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoY29sb3JNYXApIHx8ICFjb2xvck1hcC5sZW5ndGgpIHtcbiAgICByZXR1cm4gY29sb3JNYXA7XG4gIH1cblxuICBpZiAoY29sb3JNYXAubGVuZ3RoIDwgMikge1xuICAgIC8vIGxlc3MgdGhlbiAyLCBhZGQgMSBhdCBlbmRcbiAgICAvLyBob3dldmVyIHNob3VsZG4ndCBhbGxvdyBkZWxldGUgd2hlbiB0aGVyZSBhcmUgMlxuICAgIHJldHVybiBuZXdDb2xvcnMubWFwKChjLCBpKSA9PiAoaSA9PT0gMCA/IGNvbG9yTWFwW2ldIDogW251bGwsIGNdKSk7XG4gIH1cblxuICAvLyBicmVha3Mgc2hvdWxkIGJlIDEgbGVzcyB0aGFuIGNvbG9yc1xuICBjb25zdCBicmVha3MgPSBjb2xvck1hcC5tYXAoY20gPT4gY21bMF0pLnNsaWNlKDAsIGNvbG9yTWFwLmxlbmd0aCAtIDEpO1xuXG4gIC8vIGluc2VydCBuZXcgYnJlYWtcbiAgY29uc3QgbmV3VmFsdWUgPVxuICAgIGluZGV4ID49IGJyZWFrcy5sZW5ndGggLSAxXG4gICAgICA/IGJyZWFrc1ticmVha3MubGVuZ3RoIC0gMV0gK1xuICAgICAgICAoYnJlYWtzLmxlbmd0aCA+IDEgPyBicmVha3NbYnJlYWtzLmxlbmd0aCAtIDFdIC0gYnJlYWtzW2JyZWFrcy5sZW5ndGggLSAyXSA6IDApXG4gICAgICA6IChicmVha3NbaW5kZXhdICsgYnJlYWtzW2luZGV4ICsgMV0pIC8gMjtcblxuICBjb25zdCBuZXdCcmVha3MgPSBhcnJheUluc2VydChicmVha3MsIGluZGV4ICsgMSwgbmV3VmFsdWUpO1xuXG4gIC8vIGFzaWduIGJyZWFrcyB0byBjb2xvclxuICByZXR1cm4gbmV3Q29sb3JzLm1hcCgoYywgaSkgPT5cbiAgICBpID09PSBuZXdDb2xvcnMubGVuZ3RoIC0gMSA/IFtudWxsLCBjXSA6IFtuZXdCcmVha3NbaV0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBuZXdCcmVha3NbaV0sIGNdXG4gICk7XG59XG5cbi8qKlxuICogQWRkIGEgbmV3IGNvbG9yIHRvIGN1c3RvbSBwYWxldHRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRDdXN0b21QYWxldHRlQ29sb3IoY3VzdG9tUGFsZXR0ZTogQ29sb3JSYW5nZSwgaW5kZXg6IG51bWJlcik6IENvbG9yUmFuZ2Uge1xuICBjb25zdCB7Y29sb3JzLCBjb2xvck1hcH0gPSBjdXN0b21QYWxldHRlO1xuICBjb25zdCB1cGRhdGU6IFBhcnRpYWw8Q29sb3JSYW5nZT4gPSB7fTtcblxuICBjb25zdCBuZXdDb2xvciA9XG4gICAgaW5kZXggPT09IGNvbG9ycy5sZW5ndGggLSAxID8gY29sb3JzW2luZGV4XSA6IGludGVycG9sYXRlSGV4KGNvbG9yc1tpbmRleF0sIGNvbG9yc1tpbmRleCArIDFdKTtcblxuICB1cGRhdGUuY29sb3JzID0gYXJyYXlJbnNlcnQoY29sb3JzLCBpbmRleCArIDEsIG5ld0NvbG9yKTtcblxuICAvLyBhZGQgY29sb3IgdG8gY29sb3JNYXBcbiAgaWYgKGNvbG9yTWFwKSB7XG4gICAgdXBkYXRlLmNvbG9yTWFwID1cbiAgICAgIGN1c3RvbVBhbGV0dGUudHlwZSA9PT0gJ2N1c3RvbU9yZGluYWwnXG4gICAgICAgID8gYWRkTmV3Q2F0ZWdvcmljYWxTdGVwQXRJbmRleChjb2xvck1hcCwgaW5kZXgsIG5ld0NvbG9yKVxuICAgICAgICA6IGFkZE5ld1F1YW50YXRpdmVDb2xvckJyZWFrQXRJbmRleChjb2xvck1hcCwgaW5kZXgsIHVwZGF0ZS5jb2xvcnMpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5jdXN0b21QYWxldHRlLFxuICAgIC4uLnVwZGF0ZVxuICB9O1xufVxuXG5mdW5jdGlvbiByZXBsYWNlQ29sb3JzSW5Db2xvclJhbmdlKGNvbG9yUmFuZ2UsIG5ld0NvbG9ycykge1xuICBjb25zdCBvbGRDb2xvcnMgPSBjb2xvclJhbmdlLmNvbG9ycztcbiAgY29uc3QgdXBkYXRlZCA9IHtcbiAgICAuLi5jb2xvclJhbmdlLFxuICAgIGNvbG9yczogbmV3Q29sb3JzXG4gIH07XG5cbiAgLy8gdXBkYXRlIGNvbG9yIG1hcFxuICAvLyBrZWVwIHZhbHVlLCByZXBsYWNlIGNvbG9yXG4gIGlmIChBcnJheS5pc0FycmF5KHVwZGF0ZWQuY29sb3JNYXApKSB7XG4gICAgdXBkYXRlZC5jb2xvck1hcCA9IHVwZGF0ZWQuY29sb3JNYXAubWFwKChjbSwgaSkgPT4gW2NtWzBdLCBuZXdDb2xvcnNbaV1dKTtcbiAgfVxuICAvLyB1cGRhdGUgY29sb3JsZWdlbmRzXG4gIC8vIGtlZXAgdmFsdWUsIHJlcGxhY2UgY29sb3JcbiAgaWYgKHVwZGF0ZWQuY29sb3JMZWdlbmRzKSB7XG4gICAgdXBkYXRlZC5jb2xvckxlZ2VuZHMgPSBPYmplY3Qua2V5cyh1cGRhdGVkLmNvbG9yTGVnZW5kcykucmVkdWNlKChhY2N1LCBrZXkpID0+IHtcbiAgICAgIGNvbnN0IGNvbG9ySWR4ID0gb2xkQ29sb3JzLmZpbmRJbmRleChjID0+IGMgPT09IGtleSk7XG4gICAgICBjb25zdCBuZXdDb2xvciA9IG5ld0NvbG9yc1tjb2xvcklkeF07XG5cbiAgICAgIHJldHVybiBuZXdDb2xvclxuICAgICAgICA/IHtcbiAgICAgICAgICAgIC4uLmFjY3UsXG4gICAgICAgICAgICBbbmV3Q29sb3JdOiB1cGRhdGVkLmNvbG9yTGVnZW5kc1trZXldXG4gICAgICAgICAgfVxuICAgICAgICA6IGFjY3U7XG4gICAgfSwge30pO1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZWQ7XG59XG5cbi8qKlxuICogU29ydCBjdXN0b20gcGFsZXR0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc29ydEN1c3RvbVBhbGV0dGVDb2xvcihcbiAgY3VzdG9tUGFsZXR0ZTogQ29sb3JSYW5nZSxcbiAgb2xkSW5kZXg6IG51bWJlcixcbiAgbmV3SW5kZXg6IG51bWJlclxuKTogQ29sb3JSYW5nZSB7XG4gIGNvbnN0IHtjb2xvcnN9ID0gY3VzdG9tUGFsZXR0ZTtcblxuICBjb25zdCBuZXdDb2xvcnMgPSBhcnJheU1vdmUoY29sb3JzLCBvbGRJbmRleCwgbmV3SW5kZXgpO1xuICBjb25zdCB1cGRhdGUgPSByZXBsYWNlQ29sb3JzSW5Db2xvclJhbmdlKGN1c3RvbVBhbGV0dGUsIG5ld0NvbG9ycyk7XG5cbiAgLy8gQHRzLWlnbm9yZVxuICByZXR1cm4ge1xuICAgIC4uLmN1c3RvbVBhbGV0dGUsXG4gICAgLi4udXBkYXRlXG4gIH07XG59XG5cbi8qKlxuICogcmVtb3ZlIGEgY29sb3IgaW4gY3VzdG9tIHBhbGV0dGUgYXQgaW5kZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUN1c3RvbVBhbGV0dGVDb2xvcihjdXN0b21QYWxldHRlOiBDb2xvclJhbmdlLCBpbmRleDogbnVtYmVyKTogQ29sb3JSYW5nZSB7XG4gIGNvbnN0IHtjb2xvcnMsIGNvbG9yTWFwLCBjb2xvckxlZ2VuZHN9ID0gY3VzdG9tUGFsZXR0ZTtcbiAgY29uc3Qgb2xkVmFsdWUgPSBjb2xvcnNbaW5kZXhdO1xuICBjb25zdCB1cGRhdGU6IFBhcnRpYWw8Q29sb3JSYW5nZT4gPSB7fTtcbiAgdXBkYXRlLmNvbG9ycyA9IFsuLi5jb2xvcnNdO1xuXG4gIGlmICh1cGRhdGUuY29sb3JzLmxlbmd0aCA+IDEpIHtcbiAgICB1cGRhdGUuY29sb3JzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cbiAgLy8gdXBkYXRlIGNvbG9yIG1hcFxuICBpZiAoQXJyYXkuaXNBcnJheShjb2xvck1hcCkpIHtcbiAgICAvLyBmaW5kIGNvbG9yTWFwIGluZGV4XG4gICAgY29uc3QgY29sb3JNYXBJbmRleCA9IGNvbG9yTWFwLmZpbmRJbmRleChjbSA9PiBjbVsxXSA9PT0gb2xkVmFsdWUpO1xuICAgIGlmIChjb2xvck1hcEluZGV4ID49IDApIHtcbiAgICAgIHVwZGF0ZS5jb2xvck1hcCA9IFsuLi5jb2xvck1hcF07XG4gICAgICB1cGRhdGUuY29sb3JNYXAuc3BsaWNlKGNvbG9yTWFwSW5kZXgsIDEpO1xuICAgIH1cbiAgfVxuICAvLyB1cGRhdGUgY29sb3IgbGVnZW5kXG4gIGlmIChjb2xvckxlZ2VuZHM/LltvbGRWYWx1ZV0pIHtcbiAgICB1cGRhdGUuY29sb3JMZWdlbmRzID0gey4uLmNvbG9yTGVnZW5kc307XG4gICAgZGVsZXRlIHVwZGF0ZS5jb2xvckxlZ2VuZHNbb2xkVmFsdWVdO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5jdXN0b21QYWxldHRlLFxuICAgIC4uLnVwZGF0ZVxuICB9O1xufVxuXG4vKipcbiAqIFVwZGF0ZSBhIGNvbG9yIGluIGN1c3RvbSBwYWxldHRlIGF0IGluZGV4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVDdXN0b21QYWxldHRlQ29sb3IoXG4gIGN1c3RvbVBhbGV0dGU6IENvbG9yUmFuZ2UsXG4gIGluZGV4OiBudW1iZXIsXG4gIG5ld1ZhbHVlOiBIZXhDb2xvclxuKTogQ29sb3JSYW5nZSB7XG4gIGNvbnN0IHtjb2xvcnN9ID0gY3VzdG9tUGFsZXR0ZTtcbiAgY29uc3QgaGV4ID0gbmV3VmFsdWUudG9VcHBlckNhc2UoKTtcbiAgY29uc3QgbmV3Q29sb3JzID0gWy4uLmNvbG9yc107XG4gIG5ld0NvbG9yc1tpbmRleF0gPSBoZXg7XG5cbiAgY29uc3QgdXBkYXRlID0gcmVwbGFjZUNvbG9yc0luQ29sb3JSYW5nZShjdXN0b21QYWxldHRlLCBuZXdDb2xvcnMpO1xuXG4gIC8vIEB0cy1pZ25vcmVcbiAgcmV0dXJuIHtcbiAgICAuLi5jdXN0b21QYWxldHRlLFxuICAgIC4uLnVwZGF0ZVxuICB9O1xufVxuXG4vKipcbiAqIEdldCBhIHJldmVyc2VkIGNvbG9yUmFuZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJldmVyc2VDb2xvclJhbmdlKHJldmVyc2VkOiBib29sZWFuLCBjb2xvclJhbmdlOiBDb2xvclJhbmdlKTogQ29sb3JSYW5nZSB7XG4gIGNvbnN0IG5ld0NvbG9ycyA9IGNvbG9yUmFuZ2U/LmNvbG9ycy5zbGljZSgpLnJldmVyc2UoKTtcbiAgY29uc3QgdXBkYXRlZCA9IHJlcGxhY2VDb2xvcnNJbkNvbG9yUmFuZ2UoY29sb3JSYW5nZSwgbmV3Q29sb3JzKTtcbiAgdXBkYXRlZC5yZXZlcnNlZCA9IHJldmVyc2VkO1xuXG4gIHJldHVybiB1cGRhdGVkO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgcGFsZXR0ZSBtYXRjaGVzIGN1cnJlbnQgQ29sb3JCbGluZFNhZmUgY29uZmlnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYWxldHRlSXNDb2xvckJsaW5kU2FmZShwYWxldHRlOiBDb2xvclBhbGV0dGUsIGNvbG9yQmxpbmRTYWZlOiBib29sZWFuKSB7XG4gIHJldHVybiAhY29sb3JCbGluZFNhZmUgfHwgKGNvbG9yQmxpbmRTYWZlICYmIHBhbGV0dGUuY29sb3JCbGluZFNhZmUpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgcGFsZXR0ZSBtYXRjaGVzIGN1cnJlbnQgc3RlcHMgY29uZmlnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1F1YVBhbGV0dGUocGFsZXR0ZTogQ29sb3JQYWxldHRlKTogcGFsZXR0ZSBpcyBDYXRlZ29yaWNhbFBhbGV0dGUge1xuICByZXR1cm4gcGFsZXR0ZS50eXBlID09PSBQQUxFVFRFX1RZUEVTLlFVQTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIHBhbGV0dGUgbWF0Y2hlcyBjdXJyZW50IHN0ZXBzIGNvbmZpZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFsZXR0ZUlzU3RlcHMocGFsZXR0ZTogQ29sb3JQYWxldHRlLCBzdGVwczogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiAhaXNRdWFQYWxldHRlKHBhbGV0dGUpIHx8IHBhbGV0dGUubWF4U3RlcCA+PSBzdGVwcztcbn1cblxuLyoqXG4gKiBXaGV0aGVyIHBhbGV0dGUgbWF0Y2hlcyBjdXJyZW50IHR5cGUgY29uZmlnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYWxldHRlSXNUeXBlKHBhbGV0dGU6IENvbG9yUGFsZXR0ZSwgdHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlID09PSAnYWxsJyB8fCB0eXBlID09PSBwYWxldHRlLnR5cGU7XG59XG4vKipcbiAqIEZpbmQgYmVzdCBtYXRjaCBwYWxldHRlIGJhc2VkIG9uIGNvbmZpZywgdXBkYXRlIGNvbG9yIHJhbmdlIGJ5IGl0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVDb2xvclJhbmdlQnlNYXRjaGluZ1BhbGV0dGUoXG4gIGN1cnJlbnRDb2xvclJhbmdlOiBDb2xvclJhbmdlLFxuICBjb25maWc6IENvbG9yUmFuZ2VDb25maWdcbik6IENvbG9yUmFuZ2Uge1xuICBjb25zdCB7c3RlcHMsIGNvbG9yQmxpbmRTYWZlLCB0eXBlfSA9IGNvbmZpZztcblxuICBjb25zdCBtYXRjaGluZ1BhbGV0dGUgPSBLRVBMRVJfQ09MT1JfUEFMRVRURVMuZmlsdGVyKFxuICAgIHBhbGV0dGUgPT5cbiAgICAgIC8vIHBhbGV0dGUgbWF0Y2ggdHlwZVxuICAgICAgcGFsZXR0ZUlzVHlwZShwYWxldHRlLCB0eXBlKSAmJlxuICAgICAgLy8gcGFsZXR0ZSBoYXMgc2FtZSBzdGVwXG4gICAgICBwYWxldHRlSXNTdGVwcyhwYWxldHRlLCBzdGVwcykgJiZcbiAgICAgIC8vIHBhbGV0dGUgaXMgY29sb3JCbGluZFNhZmVcbiAgICAgIHBhbGV0dGVJc0NvbG9yQmxpbmRTYWZlKHBhbGV0dGUsIGNvbG9yQmxpbmRTYWZlKVxuICApO1xuXG4gIGNvbnN0IGJlc3RNYXRjaCA9IG1hdGNoaW5nUGFsZXR0ZS5sZW5ndGhcbiAgICA/IG1hdGNoaW5nUGFsZXR0ZS5maW5kKHAgPT4gcC5uYW1lID09PSBjdXJyZW50Q29sb3JSYW5nZS5uYW1lKSB8fCBtYXRjaGluZ1BhbGV0dGVbMF1cbiAgICA6IG51bGw7XG5cbiAgaWYgKGJlc3RNYXRjaCkge1xuICAgIHJldHVybiB1cGRhdGVDb2xvclJhbmdlQnlTZWxlY3RlZFBhbGV0dGUoY3VycmVudENvbG9yUmFuZ2UsIGJlc3RNYXRjaCwgY29uZmlnKTtcbiAgfVxuICAvLyB3ZSBkbyBub3RoaW5nXG4gIENvbnNvbGUud2FybihcbiAgICBgd2UgY2FudCBmaW5kIGFueSBwcmVzZXQgcGFsZXR0ZSBtYXRjaGVzIHJlcXVpcm1lbnRzOiBzdGVwcz0ke3N0ZXBzfSAmJiBjb2xvckJsaW5kU2FmZT0ke2NvbG9yQmxpbmRTYWZlfWBcbiAgKTtcblxuICByZXR1cm4gY3VycmVudENvbG9yUmFuZ2U7XG59XG5cbi8qKlxuICogVXBkYXRlIGN1c3RvbSBwYWxldHRlIHdoZW4gcmV2ZXJzZSB0aGUgY29sb3JzIGluIGN1c3RvbSBwYWxldHRlLCBzaW5jZSBjaGFuZ2luZyAnc3RlcHMnLFxuICogJ2NvbG9yQmluZFNhZmUnLCAndHlwZScgc2hvdWxkIGZhbGwgYmFjayB0byBwcmVkZWZpbmVkIHBhbGV0dGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVDdXN0b21Db2xvclJhbmdlQnlDb2xvclVJKFxuICBvbGRDb2xvclJhbmdlOiBDb2xvclJhbmdlLFxuICBjb2xvckNvbmZpZzogQ29sb3JSYW5nZUNvbmZpZ1xuKTogQ29sb3JSYW5nZSB7XG4gIGNvbnN0IHtyZXZlcnNlZH0gPSBjb2xvckNvbmZpZztcbiAgY29uc3QgY29sb3JzID0gb2xkQ29sb3JSYW5nZS5jb2xvcnM7XG4gIC8vIGZvciBjdXN0b20gcGFsZXR0ZSwgb25lIGNhbiBvbmx5ICdyZXZlcnNlJyB0aGUgY29sb3JzIGluIGN1c3RvbSBwYWxldHRlLlxuICBjb2xvcnMucmV2ZXJzZSgpO1xuXG4gIGNvbnN0IGNvbG9yUmFuZ2UgPSB7XG4gICAgbmFtZTogb2xkQ29sb3JSYW5nZS5uYW1lLFxuICAgIHR5cGU6IG9sZENvbG9yUmFuZ2UudHlwZSxcbiAgICBjYXRlZ29yeTogb2xkQ29sb3JSYW5nZS5jYXRlZ29yeSxcbiAgICBjb2xvcnMsXG4gICAgLi4uKHJldmVyc2VkID8ge3JldmVyc2VkfSA6IHt9KSxcbiAgICAuLi4ob2xkQ29sb3JSYW5nZS5jb2xvck1hcCA/IHtjb2xvck1hcDogb2xkQ29sb3JSYW5nZS5jb2xvck1hcH0gOiB7fSksXG4gICAgLi4uKG9sZENvbG9yUmFuZ2UuY29sb3JMZWdlbmRzID8ge2NvbG9yTGVnZW5kczogb2xkQ29sb3JSYW5nZS5jb2xvckxlZ2VuZHN9IDoge30pXG4gIH07XG5cbiAgcmV0dXJuIHJlcGxhY2VDb2xvcnNJbkNvbG9yUmFuZ2UoY29sb3JSYW5nZSwgY29sb3JSYW5nZS5jb2xvcnMpO1xufVxuXG4vKipcbiAqIFVwZGF0ZSBjb2xvciByYW5nZSBhZnRlciBzZWxlY3RpbmcgYSBwYWxldHRlIGZyb20gY29sb3IgcmFuZ2Ugc2VsZWN0b2VyXG4gKiBDb3B5IG92ZXIgY29sb3JNYXAgYW5kIGNvbG9yTGVnZW5kc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQ29sb3JSYW5nZUJ5U2VsZWN0ZWRQYWxldHRlKG9sZENvbG9yUmFuZ2UsIGNvbG9yUGFsZXR0ZSwgY29sb3JDb25maWcpIHtcbiAgY29uc3Qge2NvbG9yczogbmV3Q29sb3JzLCAuLi5uZXdDb2xvclJhbmdlfSA9IGNvbG9yUGFsZXR0ZVRvQ29sb3JSYW5nZShjb2xvclBhbGV0dGUsIGNvbG9yQ29uZmlnKTtcblxuICBjb25zdCBjb2xvclJhbmdlID0ge1xuICAgIGNvbG9yczogb2xkQ29sb3JSYW5nZS5jb2xvcnMsXG4gICAgLi4ubmV3Q29sb3JSYW5nZSxcbiAgICAuLi4ob2xkQ29sb3JSYW5nZS5jb2xvck1hcCA/IHtjb2xvck1hcDogb2xkQ29sb3JSYW5nZS5jb2xvck1hcH0gOiB7fSksXG4gICAgLi4uKG9sZENvbG9yUmFuZ2UuY29sb3JMZWdlbmRzID8ge2NvbG9yTGVnZW5kczogb2xkQ29sb3JSYW5nZS5jb2xvckxlZ2VuZHN9IDoge30pXG4gIH07XG5cbiAgcmV0dXJuIHJlcGxhY2VDb2xvcnNJbkNvbG9yUmFuZ2UoY29sb3JSYW5nZSwgbmV3Q29sb3JzKTtcbn1cblxuY29uc3QgVWJlck5hbWVSZWdleCA9IG5ldyBSZWdFeHAoL14oW0EtWmEteiBdKSsvZyk7XG5jb25zdCBDb2xvckJyZXdlclJlZ2V4ID0gbmV3IFJlZ0V4cCgvXkNvbG9yQnJld2VyIChbQS1aYS16MS05XSkrL2cpO1xuXG4vKipcbiAqIGNvbnZlcnQgc2F2ZWQgY29sb3JSYW5nZSB0byBjb2xvclBhbGV0dGUgb2JqZXZ0IHR5cGUvbmFtZS9jYXRlZ29yeS9pc0NvbG9yQmxpbmRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbG9yUmFuZ2VCYWNrd2FyZENvbXBhdGliaWxpdHkoY29sb3JSYW5nZTogQ29sb3JSYW5nZSk6IENvbG9yUmFuZ2Uge1xuICBpZiAoIWNvbG9yUmFuZ2UgfHwgY29sb3JSYW5nZS50eXBlID09PSAnY3VzdG9tJyB8fCBjb2xvclJhbmdlLmNvbG9yTWFwKSB7XG4gICAgLy8gZG9uJ3QgZG8gYW55dGhpbmcgdG8gY3VzdG9tIGNvbG9yIHBhbGV0dGUsIG9yIHBhbGV0dGUgd2l0aCBjdXN0b20gYnJlYWtzXG4gICAgcmV0dXJuIGNvbG9yUmFuZ2U7XG4gIH1cbiAgbGV0IHRyaW1OYW1lO1xuICBpZiAoY29sb3JSYW5nZS5jYXRlZ29yeSA9PT0gJ1ViZXInKSB7XG4gICAgY29uc3QgbWF0Y2hOYW1lID0gKGNvbG9yUmFuZ2UubmFtZSA/PyAnJykubWF0Y2goVWJlck5hbWVSZWdleCk7XG4gICAgdHJpbU5hbWUgPSBtYXRjaE5hbWUgPyBtYXRjaE5hbWVbMF0udHJpbSgpIDogbnVsbDtcbiAgICAvLyBtYXRjaCBVYmVyIFZpeiBRdWFsaXRhdGl2ZSAxLjQgLT4gVWJlciBWaXogUXVhbGl0YXRpdmVcbiAgfSBlbHNlIGlmIChjb2xvclJhbmdlLmNhdGVnb3J5ID09PSAnQ29sb3JCcmV3ZXInKSB7XG4gICAgY29uc3QgbWF0Y2hOYW1lID0gKGNvbG9yUmFuZ2UubmFtZSA/PyAnJykubWF0Y2goQ29sb3JCcmV3ZXJSZWdleCk7XG4gICAgdHJpbU5hbWUgPSBtYXRjaE5hbWUgPyBtYXRjaE5hbWVbMF0ucmVwbGFjZSgnQ29sb3JCcmV3ZXIgJywgJycpLnRyaW0oKSA6IG51bGw7XG4gIH1cblxuICBpZiAodHJpbU5hbWUpIHtcbiAgICBjb25zdCBtYXRjaGluZ1BhbGV0dGUgPSBLRVBMRVJfQ09MT1JfUEFMRVRURVMuZmluZChwID0+IHAubmFtZSA9PT0gdHJpbU5hbWUpO1xuICAgIGlmIChtYXRjaGluZ1BhbGV0dGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmNvbG9yUmFuZ2UsXG4gICAgICAgIG5hbWU6IHRyaW1OYW1lLFxuICAgICAgICB0eXBlOiBtYXRjaGluZ1BhbGV0dGU/LnR5cGUsXG4gICAgICAgIGNhdGVnb3J5OiBtYXRjaGluZ1BhbGV0dGUuY2F0ZWdvcnlcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbG9yUmFuZ2U7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBjdXN0b20gcGFsZXR0ZSBmcm9tIGN1cnJlbnQgc3RhbmRhcmQgY29sb3IgcmFuZ2Ugb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsaXplQ3VzdG9tUGFsZXR0ZShjb2xvclJhbmdlOiBDb2xvclJhbmdlLCBjb2xvck1hcD86IENvbG9yTWFwKTogQ29sb3JSYW5nZSB7XG4gIC8vIFRPRE86IGNoZWNrIG9uIGBpc1JldmVyc2VkYCBrZXksIHdoZXRoZXIgd2UgY2FuIHJlbW92ZSBpdCBoZXJlXG4gIGNvbnN0IGN1c3RvbVBhbGV0dGUgPSB7XG4gICAgLi4uY29sb3JSYW5nZSxcbiAgICBuYW1lOiBERUZBVUxUX0NVU1RPTV9QQUxFVFRFLm5hbWUsXG4gICAgdHlwZTogREVGQVVMVF9DVVNUT01fUEFMRVRURS50eXBlLFxuICAgIGNhdGVnb3J5OiBERUZBVUxUX0NVU1RPTV9QQUxFVFRFLmNhdGVnb3J5LFxuICAgIC4uLihjb2xvck1hcCA/IHtjb2xvck1hcH0gOiB7fSlcbiAgfTtcblxuICAvLyBvbmx5IGN1c3RvbVBhbGV0dGUuY29sb3JzIGFyZSBuZWVkZWQgZm9yIGN1c3RvbSBwYWxldHRlIGVkaXRvciB3aXRoIGN1c3RvbSBvcmRpbmFsIHNjYWxlXG4gIGlmICghY29sb3JNYXAgJiYgY29sb3JSYW5nZS50eXBlID09PSBTQ0FMRV9UWVBFUy5jdXN0b21PcmRpbmFsKSB7XG4gICAgZGVsZXRlIGN1c3RvbVBhbGV0dGUuY29sb3JNYXA7XG4gIH1cbiAgcmV0dXJuIGN1c3RvbVBhbGV0dGU7XG59XG4iXSwibWFwcGluZ3MiOiI7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