UNPKG

kepler.gl.geoiq

Version:

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

300 lines (245 loc) 36.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = TimeRangeSliderFactory; 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 _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _moment = _interopRequireDefault(require("moment")); var _window = require("global/window"); var _lodash = _interopRequireDefault(require("lodash.throttle")); var _styledComponents = _interopRequireDefault(require("styled-components")); var _reselect = require("reselect"); var _icons = require("./icons"); var _styledComponents2 = require("./styled-components"); var _rangeSlider = _interopRequireDefault(require("./range-slider")); var _timeSliderMarker = _interopRequireDefault(require("./time-slider-marker")); var _playbackControls = _interopRequireDefault(require("./animation-control/playback-controls")); var _defaultSettings = require("../../constants/default-settings"); var _templateObject, _templateObject2; function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var animationControlWidth = 140; var StyledSliderContainer = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n align-items: flex-end;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n .time-range-slider__control {\n margin-bottom: 12px;\n margin-right: 30px;\n }\n\n .playback-control-button {\n padding: 9px 12px;\n }\n"]))); TimeRangeSliderFactory.deps = [_playbackControls["default"]]; function TimeRangeSliderFactory(PlaybackControls) { var TimeRangeSlider = /*#__PURE__*/function (_Component) { (0, _inherits2["default"])(TimeRangeSlider, _Component); var _super = _createSuper(TimeRangeSlider); function TimeRangeSlider(_props) { var _this; (0, _classCallCheck2["default"])(this, TimeRangeSlider); _this = _super.call(this, _props); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "timeSelector", function (props) { return props.currentTime; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "formatSelector", function (props) { return props.format; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "displayTimeSelector", (0, _reselect.createSelector)(_this.timeSelector, _this.formatSelector, function (currentTime, format) { var groupTime = Array.isArray(currentTime) ? currentTime : [currentTime]; return groupTime.reduce(function (accu, curr) { var displayDateTime = _moment["default"].utc(curr).format(format); var _displayDateTime$spli = displayDateTime.split(' '), _displayDateTime$spli2 = (0, _slicedToArray2["default"])(_displayDateTime$spli, 2), displayDate = _displayDateTime$spli2[0], displayTime = _displayDateTime$spli2[1]; if (!accu.displayDate.includes(displayDate)) { accu.displayDate.push(displayDate); } accu.displayTime.push(displayTime); return accu; }, { displayDate: [], displayTime: [] }); })); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_sliderUpdate", function (args) { _this._sliderThrottle.cancel(); _this._sliderThrottle(args); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_resetAnimation", function () { var _this$props = _this.props, domain = _this$props.domain, value = _this$props.value; var value0 = domain[0]; var value1 = value0 + value[1] - value[0]; _this.props.onChange([value0, value1]); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_startAnimation", function () { _this._pauseAnimation(); _this.props.toggleAnimation(); _this.setState({ isAnimating: true }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_pauseAnimation", function () { if (_this._animation) { (0, _window.cancelAnimationFrame)(_this._animation); _this.props.toggleAnimation(); _this._animation = null; } _this.setState({ isAnimating: false }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_nextFrame", function () { _this._animation = null; var _this$props2 = _this.props, domain = _this$props2.domain, value = _this$props2.value; var speed = (domain[1] - domain[0]) / _defaultSettings.BASE_SPEED * _this.props.speed; // loop when reaches the end var value0 = value[1] + speed > domain[1] ? domain[0] : value[0] + speed; var value1 = value0 + value[1] - value[0]; _this.props.onChange([value0, value1]); }); _this.state = { isAnimating: false, width: 288 }; _this._animation = null; _this._sliderThrottle = (0, _lodash["default"])(function () { var _this$props3; return (_this$props3 = _this.props).onChange.apply(_this$props3, arguments); }, 20); return _this; } (0, _createClass2["default"])(TimeRangeSlider, [{ key: "componentDidUpdate", value: function componentDidUpdate() { if (!this._animation && this.state.isAnimating) { this._animation = (0, _window.requestAnimationFrame)(this._nextFrame); } } }, { key: "render", value: function render() { var _this$props4 = this.props, domain = _this$props4.domain, value = _this$props4.value, isEnlarged = _this$props4.isEnlarged, isLargeData = _this$props4.isLargeData, hideTimeTitle = _this$props4.hideTimeTitle; var isAnimating = this.state.isAnimating; return (/*#__PURE__*/_react["default"].createElement("div", { className: "time-range-slider" }, !hideTimeTitle ? /*#__PURE__*/_react["default"].createElement(TimeTitle, { timeFormat: this.props.timeFormat, value: value, isEnlarged: isEnlarged }) : null, /*#__PURE__*/_react["default"].createElement(StyledSliderContainer, { className: "time-range-slider__container", isEnlarged: isEnlarged }, !isLargeData && isEnlarged ? /*#__PURE__*/_react["default"].createElement(PlaybackControls, { isAnimatable: this.props.isAnimatable, isEnlarged: isEnlarged, isAnimating: isAnimating, pauseAnimation: this._pauseAnimation, resetAnimation: this._resetAnimation, startAnimation: this._startAnimation, buttonHeight: "12px", buttonStyle: "secondary" }) : null, /*#__PURE__*/_react["default"].createElement("div", { style: { width: isEnlarged ? "calc(100% - ".concat(animationControlWidth, "px)") : '100%' } }, /*#__PURE__*/_react["default"].createElement(_rangeSlider["default"], { range: domain, value0: value[0], value1: value[1], histogram: this.props.histogram, lineChart: this.props.lineChart, plotType: this.props.plotType, isEnlarged: isEnlarged, showInput: false, step: this.props.step, onChange: this._sliderUpdate, xAxis: _timeSliderMarker["default"] })))) ); } }]); return TimeRangeSlider; }(_react.Component); (0, _defineProperty2["default"])(TimeRangeSlider, "propTypes", { onChange: _propTypes["default"].func.isRequired, domain: _propTypes["default"].arrayOf(_propTypes["default"].number).isRequired, value: _propTypes["default"].arrayOf(_propTypes["default"].number).isRequired, step: _propTypes["default"].number.isRequired, plotType: _propTypes["default"].string, histogram: _propTypes["default"].arrayOf(_propTypes["default"].any), lineChart: _propTypes["default"].object, toggleAnimation: _propTypes["default"].func.isRequired, isAnimatable: _propTypes["default"].bool, isEnlarged: _propTypes["default"].bool, speed: _propTypes["default"].number, timeFormat: _propTypes["default"].string, hideTimeTitle: _propTypes["default"].bool }); TimeRangeSlider.defaultProps = { timeFormat: _defaultSettings.DEFAULT_TIME_FORMAT }; return TimeRangeSlider; } var TimeValueWrapper = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n align-items: center;\n font-size: 11px;\n justify-content: ", ";\n\n .horizontal-bar {\n padding: 0 12px;\n color: ", ";\n }\n\n .time-value {\n display: flex;\n flex-direction: ", ";\n align-items: flex-start;\n\n span {\n color: ", ";\n }\n }\n\n .time-value:last-child {\n align-items: flex-end;\n }\n"])), function (props) { return props.isEnlarged ? 'center' : 'space-between'; }, function (props) { return props.theme.titleTextColor; }, function (props) { return props.isEnlarged ? 'row' : 'column'; }, function (props) { return props.theme.titleTextColor; }); var TimeTitle = function TimeTitle(_ref) { var value = _ref.value, isEnlarged = _ref.isEnlarged, _ref$timeFormat = _ref.timeFormat, timeFormat = _ref$timeFormat === void 0 ? _defaultSettings.DEFAULT_TIME_FORMAT : _ref$timeFormat; return (/*#__PURE__*/_react["default"].createElement(TimeValueWrapper, { isEnlarged: isEnlarged, className: "time-range-slider__time-title" }, /*#__PURE__*/_react["default"].createElement(TimeValue, { key: 0, value: _moment["default"].utc(value[0]).format(timeFormat), split: !isEnlarged }), isEnlarged ? /*#__PURE__*/_react["default"].createElement("div", { className: "horizontal-bar" }, /*#__PURE__*/_react["default"].createElement(_icons.Minus, { height: "12px" })) : null, /*#__PURE__*/_react["default"].createElement(TimeValue, { key: 1, value: _moment["default"].utc(value[1]).format(timeFormat), split: !isEnlarged })) ); }; var TimeValue = function TimeValue(_ref2) { var value = _ref2.value, split = _ref2.split; return ( /*#__PURE__*/ // render two lines if not enlarged _react["default"].createElement("div", { className: "time-value" }, split ? value.split(' ').map(function (v, i) { return (/*#__PURE__*/_react["default"].createElement("div", { key: i }, i === 0 ? /*#__PURE__*/_react["default"].createElement(_styledComponents2.SelectText, null, v) : /*#__PURE__*/_react["default"].createElement(_styledComponents2.SelectTextBold, null, v)) ); }) : /*#__PURE__*/_react["default"].createElement(_styledComponents2.SelectTextBold, null, value)) ); }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2NvbW1vbi90aW1lLXJhbmdlLXNsaWRlci5qcyJdLCJuYW1lcyI6WyJhbmltYXRpb25Db250cm9sV2lkdGgiLCJTdHlsZWRTbGlkZXJDb250YWluZXIiLCJzdHlsZWQiLCJkaXYiLCJUaW1lUmFuZ2VTbGlkZXJGYWN0b3J5IiwiZGVwcyIsIlBsYXliYWNrQ29udHJvbHNGYWN0b3J5IiwiUGxheWJhY2tDb250cm9scyIsIlRpbWVSYW5nZVNsaWRlciIsInByb3BzIiwiY3VycmVudFRpbWUiLCJmb3JtYXQiLCJ0aW1lU2VsZWN0b3IiLCJmb3JtYXRTZWxlY3RvciIsImdyb3VwVGltZSIsIkFycmF5IiwiaXNBcnJheSIsInJlZHVjZSIsImFjY3UiLCJjdXJyIiwiZGlzcGxheURhdGVUaW1lIiwibW9tZW50IiwidXRjIiwic3BsaXQiLCJkaXNwbGF5RGF0ZSIsImRpc3BsYXlUaW1lIiwiaW5jbHVkZXMiLCJwdXNoIiwiYXJncyIsIl9zbGlkZXJUaHJvdHRsZSIsImNhbmNlbCIsImRvbWFpbiIsInZhbHVlIiwidmFsdWUwIiwidmFsdWUxIiwib25DaGFuZ2UiLCJfcGF1c2VBbmltYXRpb24iLCJ0b2dnbGVBbmltYXRpb24iLCJzZXRTdGF0ZSIsImlzQW5pbWF0aW5nIiwiX2FuaW1hdGlvbiIsInNwZWVkIiwiQkFTRV9TUEVFRCIsInN0YXRlIiwid2lkdGgiLCJfbmV4dEZyYW1lIiwiaXNFbmxhcmdlZCIsImlzTGFyZ2VEYXRhIiwiaGlkZVRpbWVUaXRsZSIsInRpbWVGb3JtYXQiLCJpc0FuaW1hdGFibGUiLCJfcmVzZXRBbmltYXRpb24iLCJfc3RhcnRBbmltYXRpb24iLCJoaXN0b2dyYW0iLCJsaW5lQ2hhcnQiLCJwbG90VHlwZSIsInN0ZXAiLCJfc2xpZGVyVXBkYXRlIiwiVGltZVNsaWRlck1hcmtlciIsIkNvbXBvbmVudCIsIlByb3BUeXBlcyIsImZ1bmMiLCJpc1JlcXVpcmVkIiwiYXJyYXlPZiIsIm51bWJlciIsInN0cmluZyIsImFueSIsIm9iamVjdCIsImJvb2wiLCJkZWZhdWx0UHJvcHMiLCJERUZBVUxUX1RJTUVfRk9STUFUIiwiVGltZVZhbHVlV3JhcHBlciIsInRoZW1lIiwidGl0bGVUZXh0Q29sb3IiLCJUaW1lVGl0bGUiLCJUaW1lVmFsdWUiLCJtYXAiLCJ2IiwiaSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBLElBQU1BLHFCQUFxQixHQUFHLEdBQTlCOztBQUVBLElBQU1DLHFCQUFxQixHQUFHQyw2QkFBT0MsR0FBVix1VkFBM0I7O0FBZ0JBQyxzQkFBc0IsQ0FBQ0MsSUFBdkIsR0FBOEIsQ0FBQ0MsNEJBQUQsQ0FBOUI7O0FBRWUsU0FBU0Ysc0JBQVQsQ0FBZ0NHLGdCQUFoQyxFQUFrRDtBQUFBLE1BQ3pEQyxlQUR5RDtBQUFBOztBQUFBOztBQWtCN0QsNkJBQVlDLE1BQVosRUFBbUI7QUFBQTs7QUFBQTtBQUNqQixnQ0FBTUEsTUFBTjtBQURpQix1R0FtQkosVUFBQUEsS0FBSztBQUFBLGVBQUlBLEtBQUssQ0FBQ0MsV0FBVjtBQUFBLE9BbkJEO0FBQUEseUdBb0JGLFVBQUFELEtBQUs7QUFBQSxlQUFJQSxLQUFLLENBQUNFLE1BQVY7QUFBQSxPQXBCSDtBQUFBLDhHQXFCRyw4QkFDcEIsTUFBS0MsWUFEZSxFQUVwQixNQUFLQyxjQUZlLEVBR3BCLFVBQUNILFdBQUQsRUFBY0MsTUFBZCxFQUF5QjtBQUN2QixZQUFNRyxTQUFTLEdBQUdDLEtBQUssQ0FBQ0MsT0FBTixDQUFjTixXQUFkLElBQ2RBLFdBRGMsR0FFZCxDQUFDQSxXQUFELENBRko7QUFHQSxlQUFPSSxTQUFTLENBQUNHLE1BQVYsQ0FDTCxVQUFDQyxJQUFELEVBQU9DLElBQVAsRUFBZ0I7QUFDZCxjQUFNQyxlQUFlLEdBQUdDLG1CQUFP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LEVBRUdxRCxHQUZILENBRU8sVUFBQ0MsQ0FBRCxFQUFJQyxDQUFKO0FBQUEsMkJBQ0g7QUFBSyxVQUFBLEdBQUcsRUFBRUE7QUFBVixXQUNHQSxDQUFDLEtBQUssQ0FBTixnQkFDQyxnQ0FBQyw2QkFBRCxRQUFhRCxDQUFiLENBREQsZ0JBR0MsZ0NBQUMsaUNBQUQsUUFBaUJBLENBQWpCLENBSko7QUFERztBQUFBLEtBRlAsQ0FESSxnQkFhSixnQ0FBQyxpQ0FBRCxRQUFpQjdDLEtBQWpCLENBZEo7QUFGZ0I7QUFBQSxDQUFsQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCBSZWFjdCwge0NvbXBvbmVudH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7cmVxdWVzdEFuaW1hdGlvbkZyYW1lLCBjYW5jZWxBbmltYXRpb25GcmFtZX0gZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQgdGhyb3R0bGUgZnJvbSAnbG9kYXNoLnRocm90dGxlJztcbmltcG9ydCBzdHlsZWQgZnJvbSAnc3R5bGVkLWNvbXBvbmVudHMnO1xuaW1wb3J0IHtjcmVhdGVTZWxlY3Rvcn0gZnJvbSAncmVzZWxlY3QnO1xuXG5pbXBvcnQge01pbnVzfSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9pY29ucyc7XG5pbXBvcnQge1NlbGVjdFRleHRCb2xkLCBTZWxlY3RUZXh0fSBmcm9tICdjb21wb25lbnRzL2NvbW1vbi9zdHlsZWQtY29tcG9uZW50cyc7XG5pbXBvcnQgUmFuZ2VTbGlkZXIgZnJvbSAnY29tcG9uZW50cy9jb21tb24vcmFuZ2Utc2xpZGVyJztcbmltcG9ydCBUaW1lU2xpZGVyTWFya2VyIGZyb20gJ2NvbXBvbmVudHMvY29tbW9uL3RpbWUtc2xpZGVyLW1hcmtlcic7XG5pbXBvcnQgUGxheWJhY2tDb250cm9sc0ZhY3RvcnkgZnJvbSAnY29tcG9uZW50cy9jb21tb24vYW5pbWF0aW9uLWNvbnRyb2wvcGxheWJhY2stY29udHJvbHMnO1xuaW1wb3J0IHtCQVNFX1NQRUVELCBERUZBVUxUX1RJTUVfRk9STUFUfSBmcm9tICdjb25zdGFudHMvZGVmYXVsdC1zZXR0aW5ncyc7XG5cbmNvbnN0IGFuaW1hdGlvbkNvbnRyb2xXaWR0aCA9IDE0MDtcblxuY29uc3QgU3R5bGVkU2xpZGVyQ29udGFpbmVyID0gc3R5bGVkLmRpdmBcbiAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG5cbiAgLnRpbWUtcmFuZ2Utc2xpZGVyX19jb250cm9sIHtcbiAgICBtYXJnaW4tYm90dG9tOiAxMnB4O1xuICAgIG1hcmdpbi1yaWdodDogMzBweDtcbiAgfVxuXG4gIC5wbGF5YmFjay1jb250cm9sLWJ1dHRvbiB7XG4gICAgcGFkZGluZzogOXB4IDEycHg7XG4gIH1cbmA7XG5cblRpbWVSYW5nZVNsaWRlckZhY3RvcnkuZGVwcyA9IFtQbGF5YmFja0NvbnRyb2xzRmFjdG9yeV07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRpbWVSYW5nZVNsaWRlckZhY3RvcnkoUGxheWJhY2tDb250cm9scykge1xuICBjbGFzcyBUaW1lUmFuZ2VTbGlkZXIgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgICBvbkNoYW5nZTogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgIGRvbWFpbjogUHJvcFR5cGVzLmFycmF5T2YoUHJvcFR5cGVzLm51bWJlcikuaXNSZXF1aXJlZCxcbiAgICAgIHZhbHVlOiBQcm9wVHlwZXMuYXJyYXlPZihQcm9wVHlwZXMubnVtYmVyKS5pc1JlcXVpcmVkLFxuICAgICAgc3RlcDogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxuICAgICAgcGxvdFR5cGU6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgICBoaXN0b2dyYW06IFByb3BUeXBlcy5hcnJheU9mKFByb3BUeXBlcy5hbnkpLFxuICAgICAgbGluZUNoYXJ0OiBQcm9wVHlwZXMub2JqZWN0LFxuICAgICAgdG9nZ2xlQW5pbWF0aW9uOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgaXNBbmltYXRhYmxlOiBQcm9wVHlwZXMuYm9vbCxcbiAgICAgIGlzRW5sYXJnZWQ6IFByb3BUeXBlcy5ib29sLFxuICAgICAgc3BlZWQ6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgICB0aW1lRm9ybWF0OiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgaGlkZVRpbWVUaXRsZTogUHJvcFR5cGVzLmJvb2xcbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICAgIHN1cGVyKHByb3BzKTtcbiAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgIGlzQW5pbWF0aW5nOiBmYWxzZSxcbiAgICAgICAgd2lkdGg6IDI4OFxuICAgICAgfTtcbiAgICAgIHRoaXMuX2FuaW1hdGlvbiA9IG51bGw7XG4gICAgICB0aGlzLl9zbGlkZXJUaHJvdHRsZSA9IHRocm90dGxlKFxuICAgICAgICAoLi4udmFsdWUpID0+IHRoaXMucHJvcHMub25DaGFuZ2UoLi4udmFsdWUpLFxuICAgICAgICAyMFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb21wb25lbnREaWRVcGRhdGUoKSB7XG4gICAgICBpZiAoIXRoaXMuX2FuaW1hdGlvbiAmJiB0aGlzLnN0YXRlLmlzQW5pbWF0aW5nKSB7XG4gICAgICAgIHRoaXMuX2FuaW1hdGlvbiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLl9uZXh0RnJhbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRpbWVTZWxlY3RvciA9IHByb3BzID0+IHByb3BzLmN1cnJlbnRUaW1lO1xuICAgIGZvcm1hdFNlbGVjdG9yID0gcHJvcHMgPT4gcHJvcHMuZm9ybWF0O1xuICAgIGRpc3BsYXlUaW1lU2VsZWN0b3IgPSBjcmVhdGVTZWxlY3RvcihcbiAgICAgIHRoaXMudGltZVNlbGVjdG9yLFxuICAgICAgdGhpcy5mb3JtYXRTZWxlY3RvcixcbiAgICAgIChjdXJyZW50VGltZSwgZm9ybWF0KSA9PiB7XG4gICAgICAgIGNvbnN0IGdyb3VwVGltZSA9IEFycmF5LmlzQXJyYXkoY3VycmVudFRpbWUpXG4gICAgICAgICAgPyBjdXJyZW50VGltZVxuICAgICAgICAgIDogW2N1cnJlbnRUaW1lXTtcbiAgICAgICAgcmV0dXJuIGdyb3VwVGltZS5yZWR1Y2UoXG4gICAgICAgICAgKGFjY3UsIGN1cnIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRpc3BsYXlEYXRlVGltZSA9IG1vbWVudC51dGMoY3VycikuZm9ybWF0KGZvcm1hdCk7XG4gICAgICAgICAgICBjb25zdCBbZGlzcGxheURhdGUsIGRpc3BsYXlUaW1lXSA9IGRpc3BsYXlEYXRlVGltZS5zcGxpdCgnICcpO1xuXG4gICAgICAgICAgICBpZiAoIWFjY3UuZGlzcGxheURhdGUuaW5jbHVkZXMoZGlzcGxheURhdGUpKSB7XG4gICAgICAgICAgICAgIGFjY3UuZGlzcGxheURhdGUucHVzaChkaXNwbGF5RGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhY2N1LmRpc3BsYXlUaW1lLnB1c2goZGlzcGxheVRpbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gYWNjdTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtkaXNwbGF5RGF0ZTogW10sIGRpc3BsYXlUaW1lOiBbXX1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgX3NsaWRlclVwZGF0ZSA9IGFyZ3MgPT4ge1xuICAgICAgdGhpcy5fc2xpZGVyVGhyb3R0bGUuY2FuY2VsKCk7XG4gICAgICB0aGlzLl9zbGlkZXJUaHJvdHRsZShhcmdzKTtcbiAgICB9O1xuXG4gICAgX3Jlc2V0QW5pbWF0aW9uID0gKCkgPT4ge1xuICAgICAgY29uc3Qge2RvbWFpbiwgdmFsdWV9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHZhbHVlMCA9IGRvbWFpblswXTtcbiAgICAgIGNvbnN0IHZhbHVlMSA9IHZhbHVlMCArIHZhbHVlWzFdIC0gdmFsdWVbMF07XG4gICAgICB0aGlzLnByb3BzLm9uQ2hhbmdlKFt2YWx1ZTAsIHZhbHVlMV0pO1xuICAgIH07XG5cbiAgICBfc3RhcnRBbmltYXRpb24gPSAoKSA9PiB7XG4gICAgICB0aGlzLl9wYXVzZUFuaW1hdGlvbigpO1xuICAgICAgdGhpcy5wcm9wcy50b2dnbGVBbmltYXRpb24oKTtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe2lzQW5pbWF0aW5nOiB0cnVlfSk7XG4gICAgfTtcblxuICAgIF9wYXVzZUFuaW1hdGlvbiA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9hbmltYXRpb24pIHtcbiAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5fYW5pbWF0aW9uKTtcbiAgICAgICAgdGhpcy5wcm9wcy50b2dnbGVBbmltYXRpb24oKTtcbiAgICAgICAgdGhpcy5fYW5pbWF0aW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoe2lzQW5pbWF0aW5nOiBmYWxzZX0pO1xuICAgIH07XG5cbiAgICBfbmV4dEZyYW1lID0gKCkgPT4ge1xuICAgICAgdGhpcy5fYW5pbWF0aW9uID0gbnVsbDtcblxuICAgICAgY29uc3Qge2RvbWFpbiwgdmFsdWV9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHNwZWVkID0gKChkb21haW5bMV0gLSBkb21haW5bMF0pIC8gQkFTRV9TUEVFRCkgKiB0aGlzLnByb3BzLnNwZWVkO1xuXG4gICAgICAvLyBsb29wIHdoZW4gcmVhY2hlcyB0aGUgZW5kXG4gICAgICBjb25zdCB2YWx1ZTAgPVxuICAgICAgICB2YWx1ZVsxXSArIHNwZWVkID4gZG9tYWluWzFdID8gZG9tYWluWzBdIDogdmFsdWVbMF0gKyBzcGVlZDtcbiAgICAgIGNvbnN0IHZhbHVlMSA9IHZhbHVlMCArIHZhbHVlWzFdIC0gdmFsdWVbMF07XG4gICAgICB0aGlzLnByb3BzLm9uQ2hhbmdlKFt2YWx1ZTAsIHZhbHVlMV0pO1xuICAgIH07XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGRvbWFpbixcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGlzRW5sYXJnZWQsXG4gICAgICAgIGlzTGFyZ2VEYXRhLFxuICAgICAgICBoaWRlVGltZVRpdGxlXG4gICAgICB9ID0gdGhpcy5wcm9wcztcbiAgICAgIGNvbnN0IHtpc0FuaW1hdGluZ30gPSB0aGlzLnN0YXRlO1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInRpbWUtcmFuZ2Utc2xpZGVyXCI+XG4gICAgICAgICAgeyFoaWRlVGltZVRpdGxlID8gKFxuICAgICAgICAgICAgPFRpbWVUaXRsZVxuICAgICAgICAgICAgICB0aW1lRm9ybWF0PXt0aGlzLnByb3BzLnRpbWVGb3JtYXR9XG4gICAgICAgICAgICAgIHZhbHVlPXt2YWx1ZX1cbiAgICAgICAgICAgICAgaXNFbmxhcmdlZD17aXNFbmxhcmdlZH1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSA6IG51bGx9XG4gICAgICAgICAgPFN0eWxlZFNsaWRlckNvbnRhaW5lclxuICAgICAgICAgICAgY2xhc3NOYW1lPVwidGltZS1yYW5nZS1zbGlkZXJfX2NvbnRhaW5lclwiXG4gICAgICAgICAgICBpc0VubGFyZ2VkPXtpc0VubGFyZ2VkfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIHshaXNMYXJnZURhdGEgJiYgaXNFbmxhcmdlZCA/IChcbiAgICAgICAgICAgICAgPFBsYXliYWNrQ29udHJvbHNcbiAgICAgICAgICAgICAgICBpc0FuaW1hdGFibGU9e3RoaXMucHJvcHMuaXNBbmltYXRhYmxlfVxuICAgICAgICAgICAgICAgIGlzRW5sYXJnZWQ9e2lzRW5sYXJnZWR9XG4gICAgICAgICAgICAgICAgaXNBbmltYXRpbmc9e2lzQW5pbWF0aW5nfVxuICAgICAgICAgICAgICAgIHBhdXNlQW5pbWF0aW9uPXt0aGlzLl9wYXVzZUFuaW1hdGlvbn1cbiAgICAgICAgICAgICAgICByZXNldEFuaW1hdGlvbj17dGhpcy5fcmVzZXRBbmltYXRpb259XG4gICAgICAgICAgICAgICAgc3RhcnRBbmltYXRpb249e3RoaXMuX3N0YXJ0QW5pbWF0aW9ufVxuICAgICAgICAgICAgICAgIGJ1dHRvbkhlaWdodD1cIjEycHhcIlxuICAgICAgICAgICAgICAgIGJ1dHRvblN0eWxlPVwic2Vjb25kYXJ5XCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgIHdpZHRoOiBpc0VubGFyZ2VkXG4gICAgICAgICAgICAgICAgICA/IGBjYWxjKDEwMCUgLSAke2FuaW1hdGlvbkNvbnRyb2xXaWR0aH1weClgXG4gICAgICAgICAgICAgICAgICA6ICcxMDAlJ1xuICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8UmFuZ2VTbGlkZXJcbiAgICAgICAgICAgICAgICByYW5nZT17ZG9tYWlufVxuICAgICAgICAgICAgICAgIHZhbHVlMD17dmFsdWVbMF19XG4gICAgICAgICAgICAgICAgdmFsdWUxPXt2YWx1ZVsxXX1cbiAgICAgICAgICAgICAgICBoaXN0b2dyYW09e3RoaXMucHJvcHMuaGlzdG9ncmFtfVxuICAgICAgICAgICAgICAgIGxpbmVDaGFydD17dGhpcy5wcm9wcy5saW5lQ2hhcnR9XG4gICAgICAgICAgICAgICAgcGxvdFR5cGU9e3RoaXMucHJvcHMucGxvdFR5cGV9XG4gICAgICAgICAgICAgICAgaXNFbmxhcmdlZD17aXNFbmxhcmdlZH1cbiAgICAgICAgICAgICAgICBzaG93SW5wdXQ9e2ZhbHNlfVxuICAgICAgICAgICAgICAgIHN0ZXA9e3RoaXMucHJvcHMuc3RlcH1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5fc2xpZGVyVXBkYXRlfVxuICAgICAgICAgICAgICAgIHhBeGlzPXtUaW1lU2xpZGVyTWFya2VyfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9TdHlsZWRTbGlkZXJDb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBUaW1lUmFuZ2VTbGlkZXIuZGVmYXVsdFByb3BzID0ge1xuICAgIHRpbWVGb3JtYXQ6IERFRkFVTFRfVElNRV9GT1JNQVRcbiAgfTtcblxuICByZXR1cm4gVGltZVJhbmdlU2xpZGVyO1xufVxuXG5jb25zdCBUaW1lVmFsdWVXcmFwcGVyID0gc3R5bGVkLmRpdmBcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6ICR7cHJvcHMgPT4gKHByb3BzLmlzRW5sYXJnZWQgPyAnY2VudGVyJyA6ICdzcGFjZS1iZXR3ZWVuJyl9O1xuXG4gIC5ob3Jpem9udGFsLWJhciB7XG4gICAgcGFkZGluZzogMCAxMnB4O1xuICAgIGNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLnRpdGxlVGV4dENvbG9yfTtcbiAgfVxuXG4gIC50aW1lLXZhbHVlIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiAke3Byb3BzID0+IChwcm9wcy5pc0VubGFyZ2VkID8gJ3JvdycgOiAnY29sdW1uJyl9O1xuICAgIGFsaWduLWl0ZW1zOiBmbGV4LXN0YXJ0O1xuXG4gICAgc3BhbiB7XG4gICAgICBjb2xvcjogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS50aXRsZVRleHRDb2xvcn07XG4gICAgfVxuICB9XG5cbiAgLnRpbWUtdmFsdWU6bGFzdC1jaGlsZCB7XG4gICAgYWxpZ24taXRlbXM6IGZsZXgtZW5kO1xuICB9XG5gO1xuXG5jb25zdCBUaW1lVGl0bGUgPSAoe3ZhbHVlLCBpc0VubGFyZ2VkLCB0aW1lRm9ybWF0ID0gREVGQVVMVF9USU1FX0ZPUk1BVH0pID0+IChcbiAgPFRpbWVWYWx1ZVdyYXBwZXJcbiAgICBpc0VubGFyZ2VkPXtpc0VubGFyZ2VkfVxuICAgIGNsYXNzTmFtZT1cInRpbWUtcmFuZ2Utc2xpZGVyX190aW1lLXRpdGxlXCJcbiAgPlxuICAgIDxUaW1lVmFsdWVcbiAgICAgIGtleT17MH1cbiAgICAgIHZhbHVlPXttb21lbnQudXRjKHZhbHVlWzBdKS5mb3JtYXQodGltZUZvcm1hdCl9XG4gICAgICBzcGxpdD17IWlzRW5sYXJnZWR9XG4gICAgLz5cbiAgICB7aXNFbmxhcmdlZCA/IChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaG9yaXpvbnRhbC1iYXJcIj5cbiAgICAgICAgPE1pbnVzIGhlaWdodD1cIjEycHhcIiAvPlxuICAgICAgPC9kaXY+XG4gICAgKSA6IG51bGx9XG4gICAgPFRpbWVWYWx1ZVxuICAgICAga2V5PXsxfVxuICAgICAgdmFsdWU9e21vbWVudC51dGModmFsdWVbMV0pLmZvcm1hdCh0aW1lRm9ybWF0KX1cbiAgICAgIHNwbGl0PXshaXNFbmxhcmdlZH1cbiAgICAvPlxuICA8L1RpbWVWYWx1ZVdyYXBwZXI+XG4pO1xuXG5jb25zdCBUaW1lVmFsdWUgPSAoe3ZhbHVlLCBzcGxpdH0pID0+IChcbiAgLy8gcmVuZGVyIHR3byBsaW5lcyBpZiBub3QgZW5sYXJnZWRcbiAgPGRpdiBjbGFzc05hbWU9XCJ0aW1lLXZhbHVlXCI+XG4gICAge3NwbGl0ID8gKFxuICAgICAgdmFsdWVcbiAgICAgICAgLnNwbGl0KCcgJylcbiAgICAgICAgLm1hcCgodiwgaSkgPT4gKFxuICAgICAgICAgIDxkaXYga2V5PXtpfT5cbiAgICAgICAgICAgIHtpID09PSAwID8gKFxuICAgICAgICAgICAgICA8U2VsZWN0VGV4dD57dn08L1NlbGVjdFRleHQ+XG4gICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICA8U2VsZWN0VGV4dEJvbGQ+e3Z9PC9TZWxlY3RUZXh0Qm9sZD5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICkpXG4gICAgKSA6IChcbiAgICAgIDxTZWxlY3RUZXh0Qm9sZD57dmFsdWV9PC9TZWxlY3RUZXh0Qm9sZD5cbiAgICApfVxuICA8L2Rpdj5cbik7XG4iXX0=