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
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"] = 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=