kepler.gl
Version:
kepler.gl is a webgl based application to visualize large scale location data in the browser
158 lines (156 loc) • 27.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));
var _react = _interopRequireWildcard(require("react"));
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _classnames = _interopRequireDefault(require("classnames"));
var _icons = require("../icons");
var _constants = require("@kepler.gl/constants");
var _animationSpeedSlider = _interopRequireDefault(require("./animation-speed-slider"));
var _windowActionControl = _interopRequireDefault(require("./window-action-control"));
var _animationWindowControl = _interopRequireDefault(require("./animation-window-control"));
var _resetControl = _interopRequireDefault(require("./reset-control"));
var _playControl = _interopRequireDefault(require("./play-control"));
var _speedControl = _interopRequireDefault(require("./speed-control"));
var _templateObject; // SPDX-License-Identifier: MIT
// Copyright contributors to the kepler.gl project
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
var DEFAULT_BUTTON_HEIGHT = '20px';
var StyledAnimationControls = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n position: relative;\n width: ", "px;\n &.disabled {\n opacity: 0.4;\n pointer-events: none;\n }\n"])), function (props) {
return props.width;
});
var DEFAULT_ICONS = {
/* eslint-disable react/display-name */
reset: function reset() {
return /*#__PURE__*/_react["default"].createElement(_icons.Reset, {
height: "18px"
});
},
play: function play() {
return /*#__PURE__*/_react["default"].createElement(_icons.Play, {
height: "18px"
});
},
pause: function pause() {
return /*#__PURE__*/_react["default"].createElement(_icons.Pause, {
height: "18px"
});
},
"export": function _export() {
return /*#__PURE__*/_react["default"].createElement(_icons.Save, {
height: "18px"
});
},
/* eslint-enable react/display-name */
speed: _icons.Rocket,
animationFree: _icons.FreeWindow,
animationIncremental: _icons.AnchorWindow
};
function nop() {
return;
}
var DEFAULT_ANIMATE_ITEMS = (0, _defineProperty2["default"])((0, _defineProperty2["default"])({}, _constants.ANIMATION_WINDOW.free, {
id: _constants.ANIMATION_WINDOW.free,
icon: DEFAULT_ICONS.animationFree,
tooltip: 'tooltip.animationByWindow'
}), _constants.ANIMATION_WINDOW.incremental, {
id: _constants.ANIMATION_WINDOW.incremental,
icon: DEFAULT_ICONS.animationIncremental,
tooltip: 'tooltip.animationByIncremental'
});
PlaybackControlsFactory.deps = [
// keeping this for backwards compatibility but we can decide to drop it later
_animationSpeedSlider["default"], _windowActionControl["default"], _animationWindowControl["default"], _resetControl["default"], _playControl["default"]];
function PlaybackControlsFactory(AnimationSpeedSlider, WindowActionControl, AnimationWindowControl, ResetControl, PlayControl) {
var PLAYBACK_CONTROLS_DEFAULT_ACTION_COMPONENTS = [PlayControl, (0, _speedControl["default"])(AnimationSpeedSlider), ResetControl, WindowActionControl, AnimationWindowControl];
// eslint-disable-next-line complexity
var PlaybackControls = function PlaybackControls(_ref) {
var filter = _ref.filter,
_ref$isAnimatable = _ref.isAnimatable,
isAnimatable = _ref$isAnimatable === void 0 ? true : _ref$isAnimatable,
isAnimating = _ref.isAnimating,
width = _ref.width,
speed = _ref.speed,
_ref$animationWindow = _ref.animationWindow,
animationWindow = _ref$animationWindow === void 0 ? _constants.ANIMATION_WINDOW.free : _ref$animationWindow,
setFilterAnimationWindow = _ref.setFilterAnimationWindow,
updateAnimationSpeed = _ref.updateAnimationSpeed,
_ref$pauseAnimation = _ref.pauseAnimation,
pauseAnimation = _ref$pauseAnimation === void 0 ? nop : _ref$pauseAnimation,
_ref$resetAnimation = _ref.resetAnimation,
resetAnimation = _ref$resetAnimation === void 0 ? nop : _ref$resetAnimation,
_ref$startAnimation = _ref.startAnimation,
startAnimation = _ref$startAnimation === void 0 ? nop : _ref$startAnimation,
_ref$playbackIcons = _ref.playbackIcons,
playbackIcons = _ref$playbackIcons === void 0 ? DEFAULT_ICONS : _ref$playbackIcons,
_ref$animationItems = _ref.animationItems,
animationItems = _ref$animationItems === void 0 ? DEFAULT_ANIMATE_ITEMS : _ref$animationItems,
_ref$buttonStyle = _ref.buttonStyle,
buttonStyle = _ref$buttonStyle === void 0 ? 'secondary' : _ref$buttonStyle,
_ref$buttonHeight = _ref.buttonHeight,
buttonHeight = _ref$buttonHeight === void 0 ? DEFAULT_BUTTON_HEIGHT : _ref$buttonHeight,
_ref$playbackActionIt = _ref.playbackActionItems,
playbackActionItems = _ref$playbackActionIt === void 0 ? PLAYBACK_CONTROLS_DEFAULT_ACTION_COMPONENTS : _ref$playbackActionIt;
var _useState = (0, _react.useState)(false),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
isSpeedControlVisible = _useState2[0],
toggleSpeedControl = _useState2[1];
var _useState3 = (0, _react.useState)(false),
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
showAnimationWindowControl = _useState4[0],
setShowAnimationWindowControl = _useState4[1];
var toggleAnimationWindowControl = (0, _react.useCallback)(function () {
setShowAnimationWindowControl(!showAnimationWindowControl);
}, [showAnimationWindowControl, setShowAnimationWindowControl]);
var btnStyle = buttonStyle ? (0, _defineProperty2["default"])({}, buttonStyle, true) : {};
var hideAndShowSpeedControl = (0, _react.useCallback)(function () {
if (!isSpeedControlVisible) {
toggleSpeedControl(true);
} else {
// TODO: A HACK to allow input onblur get triggered before the input is unmounted
// A better solution should be invested, see https://github.com/facebook/react/issues/12363
window.setTimeout(function () {
return toggleSpeedControl(false);
}, 200);
}
}, [isSpeedControlVisible, toggleSpeedControl]);
return /*#__PURE__*/_react["default"].createElement(StyledAnimationControls, {
className: (0, _classnames["default"])('playback-controls', {
disabled: !isAnimatable
}),
width: width
}, playbackActionItems.map(function (ActionComponent, index) {
return /*#__PURE__*/_react["default"].createElement(ActionComponent, {
key: index,
toggleAnimationWindowControl: toggleAnimationWindowControl,
showAnimationWindowControl: showAnimationWindowControl,
btnStyle: btnStyle,
hideAndShowSpeedControl: hideAndShowSpeedControl,
animationItems: animationItems,
animationWindow: animationWindow,
buttonHeight: buttonHeight,
filter: filter,
setFilterAnimationWindow: setFilterAnimationWindow,
updateAnimationSpeed: updateAnimationSpeed,
isAnimating: isAnimating,
pauseAnimation: pauseAnimation,
resetAnimation: resetAnimation,
startAnimation: startAnimation,
playbackIcons: playbackIcons,
isSpeedControlVisible: isSpeedControlVisible,
speed: speed
});
}));
};
return PlaybackControls;
}
var _default = exports["default"] = PlaybackControlsFactory;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfc3R5bGVkQ29tcG9uZW50cyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfY2xhc3NuYW1lcyIsIl9pY29ucyIsIl9jb25zdGFudHMiLCJfYW5pbWF0aW9uU3BlZWRTbGlkZXIiLCJfd2luZG93QWN0aW9uQ29udHJvbCIsIl9hbmltYXRpb25XaW5kb3dDb250cm9sIiwiX3Jlc2V0Q29udHJvbCIsIl9wbGF5Q29udHJvbCIsIl9zcGVlZENvbnRyb2wiLCJfdGVtcGxhdGVPYmplY3QiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsIl90eXBlb2YiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJERUZBVUxUX0JVVFRPTl9IRUlHSFQiLCJTdHlsZWRBbmltYXRpb25Db250cm9scyIsInN0eWxlZCIsImRpdiIsIl90YWdnZWRUZW1wbGF0ZUxpdGVyYWwyIiwicHJvcHMiLCJ3aWR0aCIsIkRFRkFVTFRfSUNPTlMiLCJyZXNldCIsImNyZWF0ZUVsZW1lbnQiLCJSZXNldCIsImhlaWdodCIsInBsYXkiLCJQbGF5IiwicGF1c2UiLCJQYXVzZSIsImV4cG9ydCIsIlNhdmUiLCJzcGVlZCIsIlJvY2tldCIsImFuaW1hdGlvbkZyZWUiLCJGcmVlV2luZG93IiwiYW5pbWF0aW9uSW5jcmVtZW50YWwiLCJBbmNob3JXaW5kb3ciLCJub3AiLCJERUZBVUxUX0FOSU1BVEVfSVRFTVMiLCJfZGVmaW5lUHJvcGVydHkyIiwiQU5JTUFUSU9OX1dJTkRPVyIsImZyZWUiLCJpZCIsImljb24iLCJ0b29sdGlwIiwiaW5jcmVtZW50YWwiLCJQbGF5YmFja0NvbnRyb2xzRmFjdG9yeSIsImRlcHMiLCJBbmltYXRpb25TcGVlZFNsaWRlckZhY3RvcnkiLCJXaW5kb3dBY3Rpb25Db250cm9sRmFjdG9yeSIsIkFuaW1hdGlvbldpbmRvd0NvbnRyb2xGYWN0b3J5IiwiUmVzZXRDb250cm9sRmFjdG9yeSIsIlBsYXlDb250cm9sRmFjdG9yeSIsIkFuaW1hdGlvblNwZWVkU2xpZGVyIiwiV2luZG93QWN0aW9uQ29udHJvbCIsIkFuaW1hdGlvbldpbmRvd0NvbnRyb2wiLCJSZXNldENvbnRyb2wiLCJQbGF5Q29udHJvbCIsIlBMQVlCQUNLX0NPTlRST0xTX0RFRkFVTFRfQUNUSU9OX0NPTVBPTkVOVFMiLCJTcGVlZENvbnRyb2xGYWN0b3J5IiwiUGxheWJhY2tDb250cm9scyIsIl9yZWYiLCJmaWx0ZXIiLCJfcmVmJGlzQW5pbWF0YWJsZSIsImlzQW5pbWF0YWJsZSIsImlzQW5pbWF0aW5nIiwiX3JlZiRhbmltYXRpb25XaW5kb3ciLCJhbmltYXRpb25XaW5kb3ciLCJzZXRGaWx0ZXJBbmltYXRpb25XaW5kb3ciLCJ1cGRhdGVBbmltYXRpb25TcGVlZCIsIl9yZWYkcGF1c2VBbmltYXRpb24iLCJwYXVzZUFuaW1hdGlvbiIsIl9yZWYkcmVzZXRBbmltYXRpb24iLCJyZXNldEFuaW1hdGlvbiIsIl9yZWYkc3RhcnRBbmltYXRpb24iLCJzdGFydEFuaW1hdGlvbiIsIl9yZWYkcGxheWJhY2tJY29ucyIsInBsYXliYWNrSWNvbnMiLCJfcmVmJGFuaW1hdGlvbkl0ZW1zIiwiYW5pbWF0aW9uSXRlbXMiLCJfcmVmJGJ1dHRvblN0eWxlIiwiYnV0dG9uU3R5bGUiLCJfcmVmJGJ1dHRvbkhlaWdodCIsImJ1dHRvbkhlaWdodCIsIl9yZWYkcGxheWJhY2tBY3Rpb25JdCIsInBsYXliYWNrQWN0aW9uSXRlbXMiLCJfdXNlU3RhdGUiLCJ1c2VTdGF0ZSIsIl91c2VTdGF0ZTIiLCJfc2xpY2VkVG9BcnJheTIiLCJpc1NwZWVkQ29udHJvbFZpc2libGUiLCJ0b2dnbGVTcGVlZENvbnRyb2wiLCJfdXNlU3RhdGUzIiwiX3VzZVN0YXRlNCIsInNob3dBbmltYXRpb25XaW5kb3dDb250cm9sIiwic2V0U2hvd0FuaW1hdGlvbldpbmRvd0NvbnRyb2wiLCJ0b2dnbGVBbmltYXRpb25XaW5kb3dDb250cm9sIiwidXNlQ2FsbGJhY2siLCJidG5TdHlsZSIsImhpZGVBbmRTaG93U3BlZWRDb250cm9sIiwid2luZG93Iiwic2V0VGltZW91dCIsImNsYXNzTmFtZSIsImNsYXNzbmFtZXMiLCJkaXNhYmxlZCIsIm1hcCIsIkFjdGlvbkNvbXBvbmVudCIsImluZGV4Iiwia2V5IiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1vbi9hbmltYXRpb24tY29udHJvbC9wbGF5YmFjay1jb250cm9scy50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVFxuLy8gQ29weXJpZ2h0IGNvbnRyaWJ1dG9ycyB0byB0aGUga2VwbGVyLmdsIHByb2plY3RcblxuaW1wb3J0IFJlYWN0LCB7dXNlU3RhdGUsIHVzZUNhbGxiYWNrfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgc3R5bGVkLCB7SVN0eWxlZENvbXBvbmVudH0gZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IGNsYXNzbmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQge1Jlc2V0LCBQbGF5LCBQYXVzZSwgU2F2ZSwgUm9ja2V0LCBBbmNob3JXaW5kb3csIEZyZWVXaW5kb3d9IGZyb20gJy4uL2ljb25zJztcbmltcG9ydCB7QU5JTUFUSU9OX1dJTkRPV30gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtGaWx0ZXIsIFRpbWVSYW5nZUZpbHRlcn0gZnJvbSAnQGtlcGxlci5nbC90eXBlcyc7XG5pbXBvcnQgQW5pbWF0aW9uU3BlZWRTbGlkZXJGYWN0b3J5IGZyb20gJy4vYW5pbWF0aW9uLXNwZWVkLXNsaWRlcic7XG5pbXBvcnQgV2luZG93QWN0aW9uQ29udHJvbEZhY3RvcnkgZnJvbSAnLi93aW5kb3ctYWN0aW9uLWNvbnRyb2wnO1xuaW1wb3J0IEFuaW1hdGlvbldpbmRvd0NvbnRyb2xGYWN0b3J5LCB7QW5pbWF0aW9uSXRlbX0gZnJvbSAnLi9hbmltYXRpb24td2luZG93LWNvbnRyb2wnO1xuaW1wb3J0IFJlc2V0Q29udHJvbEZhY3RvcnkgZnJvbSAnLi9yZXNldC1jb250cm9sJztcbmltcG9ydCBQbGF5Q29udHJvbEZhY3RvcnkgZnJvbSAnLi9wbGF5LWNvbnRyb2wnO1xuaW1wb3J0IFNwZWVkQ29udHJvbEZhY3RvcnkgZnJvbSAnLi9zcGVlZC1jb250cm9sJztcbmltcG9ydCB7QmFzZUNvbXBvbmVudFByb3BzfSBmcm9tICcuLi8uLi90eXBlcyc7XG5cbmNvbnN0IERFRkFVTFRfQlVUVE9OX0hFSUdIVCA9ICcyMHB4JztcblxuZXhwb3J0IHR5cGUgU3R5bGVkQW5pbWF0aW9uQ29udHJvbHNQcm9wcyA9IEJhc2VDb21wb25lbnRQcm9wcyAmIHtcbiAgd2lkdGg/OiBudW1iZXI7XG59O1xuXG5jb25zdCBTdHlsZWRBbmltYXRpb25Db250cm9sczogSVN0eWxlZENvbXBvbmVudDxcbiAgJ3dlYicsXG4gIFN0eWxlZEFuaW1hdGlvbkNvbnRyb2xzUHJvcHNcbj4gPSBzdHlsZWQuZGl2PFN0eWxlZEFuaW1hdGlvbkNvbnRyb2xzUHJvcHM+YFxuICBkaXNwbGF5OiBmbGV4O1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIHdpZHRoOiAke3Byb3BzID0+IHByb3BzLndpZHRofXB4O1xuICAmLmRpc2FibGVkIHtcbiAgICBvcGFjaXR5OiAwLjQ7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gIH1cbmA7XG5cbmNvbnN0IERFRkFVTFRfSUNPTlMgPSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIHJlYWN0L2Rpc3BsYXktbmFtZSAqL1xuICByZXNldDogKCkgPT4gPFJlc2V0IGhlaWdodD1cIjE4cHhcIiAvPixcbiAgcGxheTogKCkgPT4gPFBsYXkgaGVpZ2h0PVwiMThweFwiIC8+LFxuICBwYXVzZTogKCkgPT4gPFBhdXNlIGhlaWdodD1cIjE4cHhcIiAvPixcbiAgZXhwb3J0OiAoKSA9PiA8U2F2ZSBoZWlnaHQ9XCIxOHB4XCIgLz4sXG4gIC8qIGVzbGludC1lbmFibGUgcmVhY3QvZGlzcGxheS1uYW1lICovXG4gIHNwZWVkOiBSb2NrZXQsXG4gIGFuaW1hdGlvbkZyZWU6IEZyZWVXaW5kb3csXG4gIGFuaW1hdGlvbkluY3JlbWVudGFsOiBBbmNob3JXaW5kb3dcbn07XG5cbmZ1bmN0aW9uIG5vcCgpIHtcbiAgcmV0dXJuO1xufVxuXG5jb25zdCBERUZBVUxUX0FOSU1BVEVfSVRFTVMgPSB7XG4gIFtBTklNQVRJT05fV0lORE9XLmZyZWVdOiB7XG4gICAgaWQ6IEFOSU1BVElPTl9XSU5ET1cuZnJlZSxcbiAgICBpY29uOiBERUZBVUxUX0lDT05TLmFuaW1hdGlvbkZyZWUsXG4gICAgdG9vbHRpcDogJ3Rvb2x0aXAuYW5pbWF0aW9uQnlXaW5kb3cnXG4gIH0sXG4gIFtBTklNQVRJT05fV0lORE9XLmluY3JlbWVudGFsXToge1xuICAgIGlkOiBBTklNQVRJT05fV0lORE9XLmluY3JlbWVudGFsLFxuICAgIGljb246IERFRkFVTFRfSUNPTlMuYW5pbWF0aW9uSW5jcmVtZW50YWwsXG4gICAgdG9vbHRpcDogJ3Rvb2x0aXAuYW5pbWF0aW9uQnlJbmNyZW1lbnRhbCdcbiAgfVxufTtcbmV4cG9ydCBpbnRlcmZhY2UgUGxheWJhY2tDb250cm9sc1Byb3BzIHtcbiAgZmlsdGVyPzogRmlsdGVyO1xuICBpc0FuaW1hdGFibGU/OiBib29sZWFuO1xuICBpc0FuaW1hdGluZz86IGJvb2xlYW47XG4gIHdpZHRoPzogbnVtYmVyO1xuICBzcGVlZDogbnVtYmVyO1xuICBhbmltYXRpb25XaW5kb3c/OiBudWxsIHwgVGltZVJhbmdlRmlsdGVyWydhbmltYXRpb25XaW5kb3cnXTtcbiAgc2V0RmlsdGVyQW5pbWF0aW9uV2luZG93PzogKGlkOiBzdHJpbmcpID0+IHZvaWQ7XG4gIHVwZGF0ZUFuaW1hdGlvblNwZWVkPzogKGlkeDogbnVtYmVyLCBzcGVlZDogbnVtYmVyKSA9PiB2b2lkO1xuICBwYXVzZUFuaW1hdGlvbj86ICgpID0+IHZvaWQ7XG4gIHJlc2V0QW5pbWF0aW9uPzogKCkgPT4gdm9pZDtcbiAgc3RhcnRBbmltYXRpb246ICgpID0+IHZvaWQ7XG4gIHBsYXliYWNrSWNvbnM/OiBSZWNvcmQ8c3RyaW5nLCBSZWFjdC5GQzx7aGVpZ2h0OiBudW1iZXJ9Pj47XG4gIGFuaW1hdGlvbkl0ZW1zPzoge1trZXk6IHN0cmluZ106IEFuaW1hdGlvbkl0ZW19O1xuICBidXR0b25TdHlsZT86IHN0cmluZztcbiAgYnV0dG9uSGVpZ2h0Pzogc3RyaW5nO1xuICBwbGF5YmFja0FjdGlvbkl0ZW1zPzogUmVhY3QuRkNbXTtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xufVxuXG5QbGF5YmFja0NvbnRyb2xzRmFjdG9yeS5kZXBzID0gW1xuICAvLyBrZWVwaW5nIHRoaXMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGJ1dCB3ZSBjYW4gZGVjaWRlIHRvIGRyb3AgaXQgbGF0ZXJcbiAgQW5pbWF0aW9uU3BlZWRTbGlkZXJGYWN0b3J5LFxuICBXaW5kb3dBY3Rpb25Db250cm9sRmFjdG9yeSxcbiAgQW5pbWF0aW9uV2luZG93Q29udHJvbEZhY3RvcnksXG4gIFJlc2V0Q29udHJvbEZhY3RvcnksXG4gIFBsYXlDb250cm9sRmFjdG9yeVxuXTtcblxuZnVuY3Rpb24gUGxheWJhY2tDb250cm9sc0ZhY3RvcnkoXG4gIEFuaW1hdGlvblNwZWVkU2xpZGVyOiBSZXR1cm5UeXBlPHR5cGVvZiBBbmltYXRpb25TcGVlZFNsaWRlckZhY3Rvcnk+LFxuICBXaW5kb3dBY3Rpb25Db250cm9sLFxuICBBbmltYXRpb25XaW5kb3dDb250cm9sLFxuICBSZXNldENvbnRyb2wsXG4gIFBsYXlDb250cm9sXG4pIHtcbiAgY29uc3QgUExBWUJBQ0tfQ09OVFJPTFNfREVGQVVMVF9BQ1RJT05fQ09NUE9ORU5UUyA9IFtcbiAgICBQbGF5Q29udHJvbCxcbiAgICBTcGVlZENvbnRyb2xGYWN0b3J5KEFuaW1hdGlvblNwZWVkU2xpZGVyKSxcbiAgICBSZXNldENvbnRyb2wsXG4gICAgV2luZG93QWN0aW9uQ29udHJvbCxcbiAgICBBbmltYXRpb25XaW5kb3dDb250cm9sXG4gIF07XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHlcbiAgY29uc3QgUGxheWJhY2tDb250cm9sczogUmVhY3QuRkM8UGxheWJhY2tDb250cm9sc1Byb3BzPiA9ICh7XG4gICAgZmlsdGVyLFxuICAgIGlzQW5pbWF0YWJsZSA9IHRydWUsXG4gICAgaXNBbmltYXRpbmcsXG4gICAgd2lkdGgsXG4gICAgc3BlZWQsXG4gICAgYW5pbWF0aW9uV2luZG93ID0gQU5JTUFUSU9OX1dJTkRPVy5mcmVlLFxuICAgIHNldEZpbHRlckFuaW1hdGlvbldpbmRvdyxcbiAgICB1cGRhdGVBbmltYXRpb25TcGVlZCxcbiAgICBwYXVzZUFuaW1hdGlvbiA9IG5vcCxcbiAgICByZXNldEFuaW1hdGlvbiA9IG5vcCxcbiAgICBzdGFydEFuaW1hdGlvbiA9IG5vcCxcbiAgICBwbGF5YmFja0ljb25zID0gREVGQVVMVF9JQ09OUyxcbiAgICBhbmltYXRpb25JdGVtcyA9IERFRkFVTFRfQU5JTUFURV9JVEVNUyxcbiAgICBidXR0b25TdHlsZSA9ICdzZWNvbmRhcnknLFxuICAgIGJ1dHRvbkhlaWdodCA9IERFRkFVTFRfQlVUVE9OX0hFSUdIVCxcbiAgICBwbGF5YmFja0FjdGlvbkl0ZW1zID0gUExBWUJBQ0tfQ09OVFJPTFNfREVGQVVMVF9BQ1RJT05fQ09NUE9ORU5UU1xuICB9KSA9PiB7XG4gICAgY29uc3QgW2lzU3BlZWRDb250cm9sVmlzaWJsZSwgdG9nZ2xlU3BlZWRDb250cm9sXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgICBjb25zdCBbc2hvd0FuaW1hdGlvbldpbmRvd0NvbnRyb2wsIHNldFNob3dBbmltYXRpb25XaW5kb3dDb250cm9sXSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICAgIGNvbnN0IHRvZ2dsZUFuaW1hdGlvbldpbmRvd0NvbnRyb2wgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgICBzZXRTaG93QW5pbWF0aW9uV2luZG93Q29udHJvbCghc2hvd0FuaW1hdGlvbldpbmRvd0NvbnRyb2wpO1xuICAgIH0sIFtzaG93QW5pbWF0aW9uV2luZG93Q29udHJvbCwgc2V0U2hvd0FuaW1hdGlvbldpbmRvd0NvbnRyb2xdKTtcbiAgICBjb25zdCBidG5TdHlsZSA9IGJ1dHRvblN0eWxlID8ge1tidXR0b25TdHlsZV06IHRydWV9IDoge307XG5cbiAgICBjb25zdCBoaWRlQW5kU2hvd1NwZWVkQ29udHJvbCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICAgIGlmICghaXNTcGVlZENvbnRyb2xWaXNpYmxlKSB7XG4gICAgICAgIHRvZ2dsZVNwZWVkQ29udHJvbCh0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IEEgSEFDSyB0byBhbGxvdyBpbnB1dCBvbmJsdXIgZ2V0IHRyaWdnZXJlZCBiZWZvcmUgdGhlIGlucHV0IGlzIHVubW91bnRlZFxuICAgICAgICAvLyBBIGJldHRlciBzb2x1dGlvbiBzaG91bGQgYmUgaW52ZXN0ZWQsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEyMzYzXG4gICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHRvZ2dsZVNwZWVkQ29udHJvbChmYWxzZSksIDIwMCk7XG4gICAgICB9XG4gICAgfSwgW2lzU3BlZWRDb250cm9sVmlzaWJsZSwgdG9nZ2xlU3BlZWRDb250cm9sXSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPFN0eWxlZEFuaW1hdGlvbkNvbnRyb2xzXG4gICAgICAgIGNsYXNzTmFtZT17Y2xhc3NuYW1lcygncGxheWJhY2stY29udHJvbHMnLCB7XG4gICAgICAgICAgZGlzYWJsZWQ6ICFpc0FuaW1hdGFibGVcbiAgICAgICAgfSl9XG4gICAgICAgIHdpZHRoPXt3aWR0aH1cbiAgICAgID5cbiAgICAgICAgey8qKiBXaW5kb3cgKi99XG4gICAgICAgIHtwbGF5YmFja0FjdGlvbkl0ZW1zLm1hcCgoQWN0aW9uQ29tcG9uZW50LCBpbmRleCkgPT4gKFxuICAgICAgICAgIDxBY3Rpb25Db21wb25lbnRcbiAgICAgICAgICAgIGtleT17aW5kZXh9XG4gICAgICAgICAgICB0b2dnbGVBbmltYXRpb25XaW5kb3dDb250cm9sPXt0b2dnbGVBbmltYXRpb25XaW5kb3dDb250cm9sfVxuICAgICAgICAgICAgc2hvd0FuaW1hdGlvbldpbmRvd0NvbnRyb2w9e3Nob3dBbmltYXRpb25XaW5kb3dDb250cm9sfVxuICAgICAgICAgICAgYnRuU3R5bGU9e2J0blN0eWxlfVxuICAgICAgICAgICAgaGlkZUFuZFNob3dTcGVlZENvbnRyb2w9e2hpZGVBbmRTaG93U3BlZWRDb250cm9sfVxuICAgICAgICAgICAgYW5pbWF0aW9uSXRlbXM9e2FuaW1hdGlvbkl0ZW1zfVxuICAgICAgICAgICAgYW5pbWF0aW9uV2luZG93PXthbmltYXRpb25XaW5kb3d9XG4gICAgICAgICAgICBidXR0b25IZWlnaHQ9e2J1dHRvbkhlaWdodH1cbiAgICAgICAgICAgIGZpbHRlcj17ZmlsdGVyfVxuICAgICAgICAgICAgc2V0RmlsdGVyQW5pbWF0aW9uV2luZG93PXtzZXRGaWx0ZXJBbmltYXRpb25XaW5kb3d9XG4gICAgICAgICAgICB1cGRhdGVBbmltYXRpb25TcGVlZD17dXBkYXRlQW5pbWF0aW9uU3BlZWR9XG4gICAgICAgICAgICBpc0FuaW1hdGluZz17aXNBbmltYXRpbmd9XG4gICAgICAgICAgICBwYXVzZUFuaW1hdGlvbj17cGF1c2VBbmltYXRpb259XG4gICAgICAgICAgICByZXNldEFuaW1hdGlvbj17cmVzZXRBbmltYXRpb259XG4gICAgICAgICAgICBzdGFydEFuaW1hdGlvbj17c3RhcnRBbmltYXRpb259XG4gICAgICAgICAgICBwbGF5YmFja0ljb25zPXtwbGF5YmFja0ljb25zfVxuICAgICAgICAgICAgaXNTcGVlZENvbnRyb2xWaXNpYmxlPXtpc1NwZWVkQ29udHJvbFZpc2libGV9XG4gICAgICAgICAgICBzcGVlZD17c3BlZWR9XG4gICAgICAgICAgLz5cbiAgICAgICAgKSl9XG4gICAgICA8L1N0eWxlZEFuaW1hdGlvbkNvbnRyb2xzPlxuICAgICk7XG4gIH07XG5cbiAgcmV0dXJuIFBsYXliYWNrQ29udHJvbHM7XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBsYXliYWNrQ29udHJvbHNGYWN0b3J5O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUdBLElBQUFBLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLGlCQUFBLEdBQUFDLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBRyxXQUFBLEdBQUFELHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBSSxNQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxVQUFBLEdBQUFMLE9BQUE7QUFFQSxJQUFBTSxxQkFBQSxHQUFBSixzQkFBQSxDQUFBRixPQUFBO0FBQ0EsSUFBQU8sb0JBQUEsR0FBQUwsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFRLHVCQUFBLEdBQUFOLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBUyxhQUFBLEdBQUFQLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBVSxZQUFBLEdBQUFSLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBVyxhQUFBLEdBQUFULHNCQUFBLENBQUFGLE9BQUE7QUFBa0QsSUFBQVksZUFBQSxFQWRsRDtBQUNBO0FBQUEsU0FBQUMseUJBQUFDLENBQUEsNkJBQUFDLE9BQUEsbUJBQUFDLENBQUEsT0FBQUQsT0FBQSxJQUFBRSxDQUFBLE9BQUFGLE9BQUEsWUFBQUYsd0JBQUEsWUFBQUEseUJBQUFDLENBQUEsV0FBQUEsQ0FBQSxHQUFBRyxDQUFBLEdBQUFELENBQUEsS0FBQUYsQ0FBQTtBQUFBLFNBQUFm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