UNPKG

material-ui-datetime-range-picker

Version:

React Datetime Range Picker Component that Implements Google's Material Design Via Material-UI.

377 lines (328 loc) 39.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactEventListener = require('react-event-listener'); var _reactEventListener2 = _interopRequireDefault(_reactEventListener); var _keycode = require('keycode'); var _keycode2 = _interopRequireDefault(_keycode); var _transitions = require('../styles/transitions'); var _transitions2 = _interopRequireDefault(_transitions); var _RangeCalendarMonth = require('./RangeCalendarMonth'); var _RangeCalendarMonth2 = _interopRequireDefault(_RangeCalendarMonth); var _CalendarToolbar = require('./CalendarToolbar'); var _CalendarToolbar2 = _interopRequireDefault(_CalendarToolbar); var _RangeTimePicker = require('./RangeTimePicker'); var _RangeTimePicker2 = _interopRequireDefault(_RangeTimePicker); var _SlideIn = require('../internal/SlideIn'); var _SlideIn2 = _interopRequireDefault(_SlideIn); var _parseNum = require('parse-num'); var _parseNum2 = _interopRequireDefault(_parseNum); var _dateUtils = require('./dateUtils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var daysArray = [].concat(_toConsumableArray(Array(7))); var RangeCalendar = function (_Component) { _inherits(RangeCalendar, _Component); function RangeCalendar() { var _ref; var _temp, _this, _ret; _classCallCheck(this, RangeCalendar); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = RangeCalendar.__proto__ || Object.getPrototypeOf(RangeCalendar)).call.apply(_ref, [this].concat(args))), _this), _this.calendarRefs = {}, _this.handleWindowKeyDown = function (event) { if (_this.props.open) { switch ((0, _keycode2.default)(event)) { case 'up': if (event.altKey && event.shiftKey) { _this.addSelectedYears(-1); } else if (event.shiftKey) { _this.addSelectedMonths(-1); } else { _this.addSelectedDays(-7); } break; case 'down': if (event.altKey && event.shiftKey) { _this.addSelectedYears(1); } else if (event.shiftKey) { _this.addSelectedMonths(1); } else { _this.addSelectedDays(7); } break; case 'right': if (event.altKey && event.shiftKey) { _this.addSelectedYears(1); } else if (event.shiftKey) { _this.addSelectedMonths(1); } else { _this.addSelectedDays(1); } break; case 'left': if (event.altKey && event.shiftKey) { _this.addSelectedYears(-1); } else if (event.shiftKey) { _this.addSelectedMonths(-1); } else { _this.addSelectedDays(-1); } break; } } }, _temp), _possibleConstructorReturn(_this, _ret); } _createClass(RangeCalendar, [{ key: 'getMinDate', value: function getMinDate() { return this.props[this.props.edit].minDate || this.props.utils.addYears(new Date(), -100); } }, { key: 'getMaxDate', value: function getMaxDate() { return this.props[this.props.edit].maxDate || this.props.utils.addYears(new Date(), 100); } }, { key: 'getSelectedDate', value: function getSelectedDate() { return this.props[this.props.edit].selectedDate; } }, { key: 'isSelectedDateDisabled', value: function isSelectedDateDisabled() { if (this.calendarRefs.calendar) { return this.calendarRefs.calendar.isSelectedDateDisabled(); } else { return false; } } }, { key: 'addSelectedDays', value: function addSelectedDays(days) { this.props.setSelectedDate(this.props.utils.addDays(this.props[this.props.edit].selectedDate, days)); } }, { key: 'addSelectedMonths', value: function addSelectedMonths(months) { this.props.setSelectedDate(this.props.utils.addMonths(this.props[this.props.edit].selectedDate, months)); } }, { key: 'addSelectedYears', value: function addSelectedYears(years) { this.props.setSelectedDate(this.props.utils.addYears(this.props[this.props.edit].selectedDate, years)); } }, { key: 'getToolbarInteractions', value: function getToolbarInteractions() { var _props = this.props, edit = _props.edit, end = _props.end, start = _props.start; if (edit === 'end' && !end.displayDate) { return { prevMonth: this.props.utils.monthDiff(start.displayDate, this.getMinDate()) > 0, nextMonth: this.props.utils.monthDiff(start.displayDate, this.getMaxDate()) < 0 }; } else { return { prevMonth: this.props.utils.monthDiff(this.props[this.props.edit].displayDate, this.getMinDate()) > 0, nextMonth: this.props.utils.monthDiff(this.props[this.props.edit].displayDate, this.getMaxDate()) < 0 }; } } }, { key: 'render', value: function render() { var _this2 = this; var prepareStyles = this.context.muiTheme.prepareStyles; var toolbarInteractions = this.getToolbarInteractions(); var calendarTextColor = this.context.muiTheme.datePicker.calendarTextColor; var _props2 = this.props, blockedDateTimeRanges = _props2.blockedDateTimeRanges, calendarDateWidth = _props2.calendarDateWidth, calendarTimeWidth = _props2.calendarTimeWidth, cancelLabel = _props2.cancelLabel, DateTimeFormat = _props2.DateTimeFormat, dayButtonSize = _props2.dayButtonSize, displayTime = _props2.displayTime, edit = _props2.edit, end = _props2.end, firstDayOfWeek = _props2.firstDayOfWeek, locale = _props2.locale, okLabel = _props2.okLabel, onTouchTapCancel = _props2.onTouchTapCancel, onTouchTapOk = _props2.onTouchTapOk, start = _props2.start, utils = _props2.utils; var width = displayTime ? calendarTimeWidth || '125px' : calendarDateWidth || '310px'; var buttonStateSize = (0, _parseNum2.default)(dayButtonSize || '34px'); var unit = (dayButtonSize || 'px').replace(/[0-9.]/g, ''); var styles = { root: { color: calendarTextColor, userSelect: 'none', width: width }, calendar: { display: 'flex', flexDirection: 'column' }, calendarContainer: { display: 'flex', alignContent: 'space-between', justifyContent: 'space-between', flexDirection: 'column', fontSize: 12, fontWeight: 400, padding: '0px ' + buttonStateSize / 4 + unit, transition: _transitions2.default.easeOut() }, yearContainer: { display: 'flex', justifyContent: 'space-between', flexDirection: 'column', height: 272, marginTop: 10, overflow: 'hidden', width: calendarDateWidth || '310px' }, weekTitle: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', fontWeight: '500', height: 20, lineHeight: '15px', opacity: '0.5', textAlign: 'center' }, weekTitleDay: { margin: 'auto', minWidth: dayButtonSize || '34px', minHeight: dayButtonSize || '34px' }, transitionSlide: { height: 214 } }; var weekTitleDayStyle = prepareStyles(styles.weekTitleDay); return _react2.default.createElement( 'div', { style: prepareStyles(styles.root) }, _react2.default.createElement(_reactEventListener2.default, { target: 'window', onKeyDown: this.handleWindowKeyDown }), _react2.default.createElement( 'div', { style: prepareStyles(styles.calendar) }, !displayTime && _react2.default.createElement( 'div', { style: prepareStyles(styles.calendarContainer) }, _react2.default.createElement(_CalendarToolbar2.default, { DateTimeFormat: DateTimeFormat, locale: locale, displayDate: this.props[edit].displayDate ? this.props[edit].displayDate : start.displayDate, onMonthChange: this.props.onMonthChange, prevMonth: toolbarInteractions.prevMonth, nextMonth: toolbarInteractions.nextMonth }), _react2.default.createElement( 'div', { style: prepareStyles(styles.weekTitle) }, daysArray.map(function (event, i) { return _react2.default.createElement( 'span', { key: i, style: weekTitleDayStyle }, (0, _dateUtils.localizedWeekday)(DateTimeFormat, locale, i, firstDayOfWeek) ); }) ), _react2.default.createElement( _SlideIn2.default, { direction: this.props[edit].transitionDirection, style: styles.transitionSlide }, _react2.default.createElement(_RangeCalendarMonth2.default, { blockedDateTimeRanges: blockedDateTimeRanges, DateTimeFormat: DateTimeFormat, calendarDateWidth: calendarDateWidth, edit: edit, end: end, dayButtonSize: dayButtonSize, displayDate: this.props[edit].displayDate ? this.props[edit].displayDate : start.displayDate, firstDayOfWeek: this.props.firstDayOfWeek, key: this.props[edit].displayDate ? this.props[edit].displayDate.toDateString() : start.displayDate.toDateString(), locale: locale, onTouchTapDay: this.props.onTouchTapDay.bind(this), ref: function ref(_ref2) { return _this2.calendarRefs.calendar = _ref2; }, start: start, utils: utils }) ) ), displayTime && _react2.default.createElement(_RangeTimePicker2.default, { blockedDateTimeRanges: blockedDateTimeRanges, edit: edit, end: end, locale: locale, onTouchTapHour: this.props.onTouchTapHour.bind(this), start: start, utils: utils }) ) ); } }]); return RangeCalendar; }(_react.Component); RangeCalendar.propTypes = { DateTimeFormat: _propTypes2.default.func.isRequired, autoOk: _propTypes2.default.bool, blockedDateTimeRanges: _propTypes2.default.array, calendarDateWidth: _propTypes2.default.string, calendarTimeWidth: _propTypes2.default.string, cancelLabel: _propTypes2.default.node, dayButtonSize: _propTypes2.default.string, disableYearSelection: _propTypes2.default.bool, displayTime: _propTypes2.default.bool, edit: _propTypes2.default.string.isRequired, end: _propTypes2.default.object.isRequired, firstDayOfWeek: _propTypes2.default.number, initialDate: _propTypes2.default.object, locale: _propTypes2.default.string.isRequired, mode: _propTypes2.default.oneOf(['portrait', 'landscape']), okLabel: _propTypes2.default.node, onMonthChange: _propTypes2.default.func, onTouchTapCancel: _propTypes2.default.func, onTouchTapDay: _propTypes2.default.func, onTouchTapHour: _propTypes2.default.func, onTouchTapOk: _propTypes2.default.func, open: _propTypes2.default.bool, openToYearSelection: _propTypes2.default.bool, setSelectedDate: _propTypes2.default.func.isRequired, start: _propTypes2.default.object.isRequired, utils: _propTypes2.default.object }; RangeCalendar.defaultProps = { DateTimeFormat: _dateUtils.dateTimeFormat, disableYearSelection: false, displayTime: false, locale: 'en-US', utils: _dateUtils.defaultUtils }; RangeCalendar.contextTypes = { muiTheme: _propTypes2.default.object.isRequired }; exports.default = RangeCalendar; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9EYXRlUGlja2VyL1JhbmdlQ2FsZW5kYXIuanMiXSwibmFtZXMiOlsiZGF5c0FycmF5IiwiQXJyYXkiLCJSYW5nZUNhbGVuZGFyIiwiY2FsZW5kYXJSZWZzIiwiaGFuZGxlV2luZG93S2V5RG93biIsImV2ZW50IiwicHJvcHMiLCJvcGVuIiwiYWx0S2V5Iiwic2hpZnRLZXkiLCJhZGRTZWxlY3RlZFllYXJzIiwiYWRkU2VsZWN0ZWRNb250aHMiLCJhZGRTZWxlY3RlZERheXMiLCJlZGl0IiwibWluRGF0ZSIsInV0aWxzIiwiYWRkWWVhcnMiLCJEYXRlIiwibWF4RGF0ZSIsInNlbGVjdGVkRGF0ZSIsImNhbGVuZGFyIiwiaXNTZWxlY3RlZERhdGVEaXNhYmxlZCIsImRheXMiLCJzZXRTZWxlY3RlZERhdGUiLCJhZGREYXlzIiwibW9udGhzIiwiYWRkTW9udGhzIiwieWVhcnMiLCJlbmQiLCJzdGFydCIsImRpc3BsYXlEYXRlIiwicHJldk1vbnRoIiwibW9udGhEaWZmIiwiZ2V0TWluRGF0ZSIsIm5leHRNb250aCIsImdldE1heERhdGUiLCJwcmVwYXJlU3R5bGVzIiwiY29udGV4dCIsIm11aVRoZW1lIiwidG9vbGJhckludGVyYWN0aW9ucyIsImdldFRvb2xiYXJJbnRlcmFjdGlvbnMiLCJjYWxlbmRhclRleHRDb2xvciIsImRhdGVQaWNrZXIiLCJibG9ja2VkRGF0ZVRpbWVSYW5nZXMiLCJjYWxlbmRhckRhdGVXaWR0aCIsImNhbGVuZGFyVGltZVdpZHRoIiwiY2FuY2VsTGFiZWwiLCJEYXRlVGltZUZvcm1hdCIsImRheUJ1dHRvblNpemUiLCJkaXNwbGF5VGltZSIsImZpcnN0RGF5T2ZXZWVrIiwibG9jYWxlIiwib2tMYWJlbCIsIm9uVG91Y2hUYXBDYW5jZWwiLCJvblRvdWNoVGFwT2siLCJ3aWR0aCIsImJ1dHRvblN0YXRlU2l6ZSIsInVuaXQiLCJyZXBsYWNlIiwic3R5bGVzIiwicm9vdCIsImNvbG9yIiwidXNlclNlbGVjdCIsImRpc3BsYXkiLCJmbGV4RGlyZWN0aW9uIiwiY2FsZW5kYXJDb250YWluZXIiLCJhbGlnbkNvbnRlbnQiLCJqdXN0aWZ5Q29udGVudCIsImZvbnRTaXplIiwiZm9udFdlaWdodCIsInBhZGRpbmciLCJ0cmFuc2l0aW9uIiwidHJhbnNpdGlvbnMiLCJlYXNlT3V0IiwieWVhckNvbnRhaW5lciIsImhlaWdodCIsIm1hcmdpblRvcCIsIm92ZXJmbG93Iiwid2Vla1RpdGxlIiwibGluZUhlaWdodCIsIm9wYWNpdHkiLCJ0ZXh0QWxpZ24iLCJ3ZWVrVGl0bGVEYXkiLCJtYXJnaW4iLCJtaW5XaWR0aCIsIm1pbkhlaWdodCIsInRyYW5zaXRpb25TbGlkZSIsIndlZWtUaXRsZURheVN0eWxlIiwib25Nb250aENoYW5nZSIsIm1hcCIsImkiLCJ0cmFuc2l0aW9uRGlyZWN0aW9uIiwidG9EYXRlU3RyaW5nIiwib25Ub3VjaFRhcERheSIsImJpbmQiLCJyZWYiLCJvblRvdWNoVGFwSG91ciIsIkNvbXBvbmVudCIsInByb3BUeXBlcyIsIlByb3BUeXBlcyIsImZ1bmMiLCJpc1JlcXVpcmVkIiwiYXV0b09rIiwiYm9vbCIsImFycmF5Iiwic3RyaW5nIiwibm9kZSIsImRpc2FibGVZZWFyU2VsZWN0aW9uIiwib2JqZWN0IiwibnVtYmVyIiwiaW5pdGlhbERhdGUiLCJtb2RlIiwib25lT2YiLCJvcGVuVG9ZZWFyU2VsZWN0aW9uIiwiZGVmYXVsdFByb3BzIiwiZGF0ZVRpbWVGb3JtYXQiLCJkZWZhdWx0VXRpbHMiLCJjb250ZXh0VHlwZXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFFQTs7Ozs7Ozs7Ozs7O0FBTUEsSUFBTUEseUNBQWdCQyxNQUFNLENBQU4sQ0FBaEIsRUFBTjs7SUFFTUMsYTs7Ozs7Ozs7Ozs7Ozs7b01BMENKQyxZLEdBQWUsRSxRQWlEZkMsbUIsR0FBc0IsVUFB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QWU7QUFDcEIvRSxZQUFVNkQsb0JBQVVTLE1BQVYsQ0FBaUJQO0FBRFAsQztrQkErT1RuRyxhIiwiZmlsZSI6IlJhbmdlQ2FsZW5kYXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHtDb21wb25lbnR9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgRXZlbnRMaXN0ZW5lciBmcm9tICdyZWFjdC1ldmVudC1saXN0ZW5lcic7XG5pbXBvcnQga2V5Y29kZSBmcm9tICdrZXljb2RlJztcbmltcG9ydCB0cmFuc2l0aW9ucyBmcm9tICcuLi9zdHlsZXMvdHJhbnNpdGlvbnMnO1xuaW1wb3J0IFJhbmdlQ2FsZW5kYXJNb250aCBmcm9tICcuL1JhbmdlQ2FsZW5kYXJNb250aCc7XG5pbXBvcnQgQ2FsZW5kYXJUb29sYmFyIGZyb20gJy4vQ2FsZW5kYXJUb29sYmFyJztcbmltcG9ydCBSYW5nZVRpbWVQaWNrZXIgZnJvbSAnLi9SYW5nZVRpbWVQaWNrZXInO1xuaW1wb3J0IFNsaWRlSW5UcmFuc2l0aW9uR3JvdXAgZnJvbSAnLi4vaW50ZXJuYWwvU2xpZGVJbic7XG5pbXBvcnQgcGFyc2VOdW0gZnJvbSAncGFyc2UtbnVtJztcblxuaW1wb3J0IHtcbiAgZGVmYXVsdFV0aWxzLFxuICBkYXRlVGltZUZvcm1hdCxcbiAgbG9jYWxpemVkV2Vla2RheSxcbn0gZnJvbSAnLi9kYXRlVXRpbHMnO1xuXG5jb25zdCBkYXlzQXJyYXkgPSBbLi4uQXJyYXkoNyldO1xuXG5jbGFzcyBSYW5nZUNhbGVuZGFyIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICBEYXRlVGltZUZvcm1hdDogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICBhdXRvT2s6IFByb3BUeXBlcy5ib29sLFxuICAgIGJsb2NrZWREYXRlVGltZVJhbmdlczogUHJvcFR5cGVzLmFycmF5LFxuICAgIGNhbGVuZGFyRGF0ZVdpZHRoOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGNhbGVuZGFyVGltZVdpZHRoOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGNhbmNlbExhYmVsOiBQcm9wVHlwZXMubm9kZSxcbiAgICBkYXlCdXR0b25TaXplOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGRpc2FibGVZZWFyU2VsZWN0aW9uOiBQcm9wVHlwZXMuYm9vbCxcbiAgICBkaXNwbGF5VGltZTogUHJvcFR5cGVzLmJvb2wsXG4gICAgZWRpdDogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIGVuZDogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgIGZpcnN0RGF5T2ZXZWVrOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgIGluaXRpYWxEYXRlOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIGxvY2FsZTogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIG1vZGU6IFByb3BUeXBlcy5vbmVPZihbJ3BvcnRyYWl0JywgJ2xhbmRzY2FwZSddKSxcbiAgICBva0xhYmVsOiBQcm9wVHlwZXMubm9kZSxcbiAgICBvbk1vbnRoQ2hhbmdlOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvblRvdWNoVGFwQ2FuY2VsOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvblRvdWNoVGFwRGF5OiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvblRvdWNoVGFwSG91cjogUHJvcFR5cGVzLmZ1bmMsXG4gICAgb25Ub3VjaFRhcE9rOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvcGVuOiBQcm9wVHlwZXMuYm9vbCxcbiAgICBvcGVuVG9ZZWFyU2VsZWN0aW9uOiBQcm9wVHlwZXMuYm9vbCxcbiAgICBzZXRTZWxlY3RlZERhdGU6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgc3RhcnQ6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICB1dGlsczogUHJvcFR5cGVzLm9iamVjdCxcbiAgfTtcblxuICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgIERhdGVUaW1lRm9ybWF0OiBkYXRlVGltZUZvcm1hdCxcbiAgICBkaXNhYmxlWWVhclNlbGVjdGlvbjogZmFsc2UsXG4gICAgZGlzcGxheVRpbWU6IGZhbHNlLFxuICAgIGxvY2FsZTogJ2VuLVVTJyxcbiAgICB1dGlsczogZGVmYXVsdFV0aWxzLFxuICB9O1xuXG4gIHN0YXRpYyBjb250ZXh0VHlwZXMgPSB7XG4gICAgbXVpVGhlbWU6IFByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgfTtcblxuICBjYWxlbmRhclJlZnMgPSB7fTtcblxuICBnZXRNaW5EYXRlKCkge1xuICAgIHJldHVybiB0aGlzLnByb3BzW3RoaXMucHJvcHMuZWRpdF0ubWluRGF0ZSB8fCB0aGlzLnByb3BzLnV0aWxzLmFkZFllYXJzKG5ldyBEYXRlKCksIC0xMDApO1xuICB9XG5cbiAgZ2V0TWF4RGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wc1t0aGlzLnByb3BzLmVkaXRdLm1heERhdGUgfHwgdGhpcy5wcm9wcy51dGlscy5hZGRZZWFycyhuZXcgRGF0ZSgpLCAxMDApO1xuICB9XG5cbiAgZ2V0U2VsZWN0ZWREYXRlKCkge1xuICAgIHJldHVybiB0aGlzLnByb3BzW3RoaXMucHJvcHMuZWRpdF0uc2VsZWN0ZWREYXRlO1xuICB9XG5cbiAgaXNTZWxlY3RlZERhdGVEaXNhYmxlZCgpIHtcbiAgICBpZiAodGhpcy5jYWxlbmRhclJlZnMuY2FsZW5kYXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhbGVuZGFyUmVmcy5jYWxlbmRhci5pc1NlbGVjdGVkRGF0ZURpc2FibGVkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhZGRTZWxlY3RlZERheXMoZGF5cykge1xuICAgIHRoaXMucHJvcHMuc2V0U2VsZWN0ZWREYXRlKHRoaXMucHJvcHMudXRpbHMuYWRkRGF5cyh0aGlzLnByb3BzW3RoaXMucHJvcHMuZWRpdF0uc2VsZWN0ZWREYXRlLCBkYXlzKSk7XG4gIH1cblxuICBhZGRTZWxlY3RlZE1vbnRocyhtb250aHMpIHtcbiAgICB0aGlzLnByb3BzLnNldFNlbGVjdGVkRGF0ZSh0aGlzLnByb3BzLnV0aWxzLmFkZE1vbnRocyh0aGlzLnByb3BzW3RoaXMucHJvcHMuZWRpdF0uc2VsZWN0ZWREYXRlLCBtb250aHMpKTtcbiAgfVxuXG4gIGFkZFNlbGVjdGVkWWVhcnMoeWVhcnMpIHtcbiAgICB0aGlzLnByb3BzLnNldFNlbGVjdGVkRGF0ZSh0aGlzLnByb3BzLnV0aWxzLmFkZFllYXJzKHRoaXMucHJvcHNbdGhpcy5wcm9wcy5lZGl0XS5zZWxlY3RlZERhdGUsIHllYXJzKSk7XG4gIH1cblxuICBnZXRUb29sYmFySW50ZXJhY3Rpb25zKCkge1xuICAgIGNvbnN0IHtlZGl0LCBlbmQsIHN0YXJ0fSA9IHRoaXMucHJvcHM7XG4gICAgaWYgKGVkaXQgPT09ICdlbmQnICYmICFlbmQuZGlzcGxheURhdGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByZXZNb250aDogdGhpcy5wcm9wcy51dGlscy5tb250aERpZmYoc3RhcnQuZGlzcGxheURhdGUsIHRoaXMuZ2V0TWluRGF0ZSgpKSA+IDAsXG4gICAgICAgIG5leHRNb250aDogdGhpcy5wcm9wcy51dGlscy5tb250aERpZmYoc3RhcnQuZGlzcGxheURhdGUsIHRoaXMuZ2V0TWF4RGF0ZSgpKSA8IDAsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcmV2TW9udGg6IHRoaXMucHJvcHMudXRpbHMubW9udGhEaWZmKHRoaXMucHJvcHNbdGhpcy5wcm9wcy5lZGl0XS5kaXNwbGF5RGF0ZSwgdGhpcy5nZXRNaW5EYXRlKCkpID4gMCxcbiAgICAgICAgbmV4dE1vbnRoOiB0aGlzLnByb3BzLnV0aWxzLm1vbnRoRGlmZih0aGlzLnByb3BzW3RoaXMucHJvcHMuZWRpdF0uZGlzcGxheURhdGUsIHRoaXMuZ2V0TWF4RGF0ZSgpKSA8IDAsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZVdpbmRvd0tleURvd24gPSAoZXZlbnQpID0+IHtcbiAgICBpZiAodGhpcy5wcm9wcy5vcGVuKSB7XG4gICAgICBzd2l0Y2ggKGtleWNvZGUoZXZlbnQpKSB7XG4gICAgICAgIGNhc2UgJ3VwJzpcbiAgICAgICAgICBpZiAoZXZlbnQuYWx0S2V5ICYmIGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNlbGVjdGVkWWVhcnMoLTEpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkU2VsZWN0ZWRNb250aHMoLTEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNlbGVjdGVkRGF5cygtNyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ2Rvd24nOlxuICAgICAgICAgIGlmIChldmVudC5hbHRLZXkgJiYgZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkU2VsZWN0ZWRZZWFycygxKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNlbGVjdGVkTW9udGhzKDEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNlbGVjdGVkRGF5cyg3KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICAgIGlmIChldmVudC5hbHRLZXkgJiYgZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkU2VsZWN0ZWRZZWFycygxKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNlbGVjdGVkTW9udGhzKDEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNlbGVjdGVkRGF5cygxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSAmJiBldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgdGhpcy5hZGRTZWxlY3RlZFllYXJzKC0xKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZFNlbGVjdGVkTW9udGhzKC0xKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hZGRTZWxlY3RlZERheXMoLTEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IHtwcmVwYXJlU3R5bGVzfSA9IHRoaXMuY29udGV4dC5tdWlUaGVtZTtcbiAgICBjb25zdCB0b29sYmFySW50ZXJhY3Rpb25zID0gdGhpcy5nZXRUb29sYmFySW50ZXJhY3Rpb25zKCk7XG4gICAgY29uc3Qge2NhbGVuZGFyVGV4dENvbG9yfSA9IHRoaXMuY29udGV4dC5tdWlUaGVtZS5kYXRlUGlja2VyO1xuICAgIGNvbnN0IHtcbiAgICAgIGJsb2NrZWREYXRlVGltZVJhbmdlcyxcbiAgICAgIGNhbGVuZGFyRGF0ZVdpZHRoLFxuICAgICAgY2FsZW5kYXJUaW1lV2lkdGgsXG4gICAgICBjYW5jZWxMYWJlbCwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgRGF0ZVRpbWVGb3JtYXQsXG4gICAgICBkYXlCdXR0b25TaXplLFxuICAgICAgZGlzcGxheVRpbWUsXG4gICAgICBlZGl0LFxuICAgICAgZW5kLFxuICAgICAgZmlyc3REYXlPZldlZWssXG4gICAgICBsb2NhbGUsXG4gICAgICBva0xhYmVsLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICBvblRvdWNoVGFwQ2FuY2VsLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICBvblRvdWNoVGFwT2ssIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHN0YXJ0LFxuICAgICAgdXRpbHMsXG4gICAgfSA9IHRoaXMucHJvcHM7XG5cbiAgICBjb25zdCB3aWR0aCA9IChkaXNwbGF5VGltZSA/IChjYWxlbmRhclRpbWVXaWR0aCB8fCAnMTI1cHgnKSA6IChjYWxlbmRhckRhdGVXaWR0aCB8fCAnMzEwcHgnKSk7XG4gICAgY29uc3QgYnV0dG9uU3RhdGVTaXplID0gcGFyc2VOdW0oZGF5QnV0dG9uU2l6ZSB8fCAnMzRweCcpO1xuICAgIGNvbnN0IHVuaXQgPSAoZGF5QnV0dG9uU2l6ZSB8fCAncHgnKS5yZXBsYWNlKC9bMC05Ll0vZywgJycpO1xuXG4gICAgY29uc3Qgc3R5bGVzID0ge1xuICAgICAgcm9vdDoge1xuICAgICAgICBjb2xvcjogY2FsZW5kYXJUZXh0Q29sb3IsXG4gICAgICAgIHVzZXJTZWxlY3Q6ICdub25lJyxcbiAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgfSxcbiAgICAgIGNhbGVuZGFyOiB7XG4gICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgICB9LFxuICAgICAgY2FsZW5kYXJDb250YWluZXI6IHtcbiAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICBhbGlnbkNvbnRlbnQ6ICdzcGFjZS1iZXR3ZWVuJyxcbiAgICAgICAganVzdGlmeUNvbnRlbnQ6ICdzcGFjZS1iZXR3ZWVuJyxcbiAgICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsXG4gICAgICAgIGZvbnRTaXplOiAxMixcbiAgICAgICAgZm9udFdlaWdodDogNDAwLFxuICAgICAgICBwYWRkaW5nOiBgMHB4ICR7YnV0dG9uU3RhdGVTaXplIC8gNH0ke3VuaXR9YCxcbiAgICAgICAgdHJhbnNpdGlvbjogdHJhbnNpdGlvbnMuZWFzZU91dCgpLFxuICAgICAgfSxcbiAgICAgIHllYXJDb250YWluZXI6IHtcbiAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICBqdXN0aWZ5Q29udGVudDogJ3NwYWNlLWJldHdlZW4nLFxuICAgICAgICBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyxcbiAgICAgICAgaGVpZ2h0OiAyNzIsXG4gICAgICAgIG1hcmdpblRvcDogMTAsXG4gICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJyxcbiAgICAgICAgd2lkdGg6IChjYWxlbmRhckRhdGVXaWR0aCB8fCAnMzEwcHgnKSxcbiAgICAgIH0sXG4gICAgICB3ZWVrVGl0bGU6IHtcbiAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICBmbGV4RGlyZWN0aW9uOiAncm93JyxcbiAgICAgICAganVzdGlmeUNvbnRlbnQ6ICdzcGFjZS1iZXR3ZWVuJyxcbiAgICAgICAgZm9udFdlaWdodDogJzUwMCcsXG4gICAgICAgIGhlaWdodDogMjAsXG4gICAgICAgIGxpbmVIZWlnaHQ6ICcxNXB4JyxcbiAgICAgICAgb3BhY2l0eTogJzAuNScsXG4gICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICB9LFxuICAgICAgd2Vla1RpdGxlRGF5OiB7XG4gICAgICAgIG1hcmdpbjogJ2F1dG8nLFxuICAgICAgICBtaW5XaWR0aDogZGF5QnV0dG9uU2l6ZSB8fCAnMzRweCcsXG4gICAgICAgIG1pbkhlaWdodDogZGF5QnV0dG9uU2l6ZSB8fCAnMzRweCcsXG4gICAgICB9LFxuICAgICAgdHJhbnNpdGlvblNsaWRlOiB7XG4gICAgICAgIGhlaWdodDogMjE0LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3Qgd2Vla1RpdGxlRGF5U3R5bGUgPSBwcmVwYXJlU3R5bGVzKHN0eWxlcy53ZWVrVGl0bGVEYXkpO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgc3R5bGU9e3ByZXBhcmVTdHlsZXMoc3R5bGVzLnJvb3QpfT5cbiAgICAgICAgPEV2ZW50TGlzdGVuZXJcbiAgICAgICAgICB0YXJnZXQ9XCJ3aW5kb3dcIlxuICAgICAgICAgIG9uS2V5RG93bj17dGhpcy5oYW5kbGVXaW5kb3dLZXlEb3dufVxuICAgICAgICAvPlxuICAgICAgICA8ZGl2IHN0eWxlPXtwcmVwYXJlU3R5bGVzKHN0eWxlcy5jYWxlbmRhcil9PlxuICAgICAgICAgIHshZGlzcGxheVRpbWUgJiZcbiAgICAgICAgICAgIDxkaXYgc3R5bGU9e3ByZXBhcmVTdHlsZXMoc3R5bGVzLmNhbGVuZGFyQ29udGFpbmVyKX0+XG4gICAgICAgICAgICAgIDxDYWxlbmRhclRvb2xiYXJcbiAgICAgICAgICAgICAgICBEYXRlVGltZUZvcm1hdD17RGF0ZVRpbWVGb3JtYXR9XG4gICAgICAgICAgICAgICAgbG9jYWxlPXtsb2NhbGV9XG4gICAgICAgICAgICAgICAgZGlzcGxheURhdGU9eyh0aGlzLnByb3BzW2VkaXRdLmRpc3BsYXlEYXRlID8gdGhpcy5wcm9wc1tlZGl0XS5kaXNwbGF5RGF0ZSA6IHN0YXJ0LmRpc3BsYXlEYXRlKX1cbiAgICAgICAgICAgICAgICBvbk1vbnRoQ2hhbmdlPXt0aGlzLnByb3BzLm9uTW9udGhDaGFuZ2V9XG4gICAgICAgICAgICAgICAgcHJldk1vbnRoPXt0b29sYmFySW50ZXJhY3Rpb25zLnByZXZNb250aH1cbiAgICAgICAgICAgICAgICBuZXh0TW9udGg9e3Rvb2xiYXJJbnRlcmFjdGlvbnMubmV4dE1vbnRofVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPXtwcmVwYXJlU3R5bGVzKHN0eWxlcy53ZWVrVGl0bGUpfT5cbiAgICAgICAgICAgICAgICB7ZGF5c0FycmF5Lm1hcCgoZXZlbnQsIGkpID0+IChcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGtleT17aX0gc3R5bGU9e3dlZWtUaXRsZURheVN0eWxlfT5cbiAgICAgICAgICAgICAgICAgICAge2xvY2FsaXplZFdlZWtkYXkoRGF0ZVRpbWVGb3JtYXQsIGxvY2FsZSwgaSwgZmlyc3REYXlPZldlZWspfVxuICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICkpfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPFNsaWRlSW5UcmFuc2l0aW9uR3JvdXAgZGlyZWN0aW9uPXt0aGlzLnByb3BzW2VkaXRdLnRyYW5zaXRpb25EaXJlY3Rpb259IHN0eWxlPXtzdHlsZXMudHJhbnNpdGlvblNsaWRlfT5cbiAgICAgICAgICAgICAgICA8UmFuZ2VDYWxlbmRhck1vbnRoXG4gICAgICAgICAgICAgICAgICBibG9ja2VkRGF0ZVRpbWVSYW5nZXM9e2Jsb2NrZWREYXRlVGltZVJhbmdlc31cbiAgICAgICAgICAgICAgICAgIERhdGVUaW1lRm9ybWF0PXtEYXRlVGltZUZvcm1hdH1cbiAgICAgICAgICAgICAgICAgIGNhbGVuZGFyRGF0ZVdpZHRoPXtjYWxlbmRhckRhdGVXaWR0aH1cbiAgICAgICAgICAgICAgICAgIGVkaXQ9e2VkaXR9XG4gICAgICAgICAgICAgICAgICBlbmQ9e2VuZH1cbiAgICAgICAgICAgICAgICAgIGRheUJ1dHRvblNpemU9e2RheUJ1dHRvblNpemV9XG4gICAgICAgICAgICAgICAgICBkaXNwbGF5RGF0ZT17KHRoaXMucHJvcHNbZWRpdF0uZGlzcGxheURhdGUgPyB0aGlzLnByb3BzW2VkaXRdLmRpc3BsYXlEYXRlIDogc3RhcnQuZGlzcGxheURhdGUpfVxuICAgICAgICAgICAgICAgICAgZmlyc3REYXlPZldlZWs9e3RoaXMucHJvcHMuZmlyc3REYXlPZldlZWt9XG4gICAgICAgICAgICAgICAgICBrZXk9eyh0aGlzLnByb3BzW2VkaXRdLmRpc3BsYXlEYXRlID9cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wc1tlZGl0XS5kaXNwbGF5RGF0ZS50b0RhdGVTdHJpbmcoKSA6IHN0YXJ0LmRpc3BsYXlEYXRlLnRvRGF0ZVN0cmluZygpKX1cbiAgICAgICAgICAgICAgICAgIGxvY2FsZT17bG9jYWxlfVxuICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcERheT17dGhpcy5wcm9wcy5vblRvdWNoVGFwRGF5LmJpbmQodGhpcyl9XG4gICAgICAgICAgICAgICAgICByZWY9eyhyZWYpID0+IHRoaXMuY2FsZW5kYXJSZWZzLmNhbGVuZGFyID0gcmVmfVxuICAgICAgICAgICAgICAgICAgc3RhcnQ9e3N0YXJ0fVxuICAgICAgICAgICAgICAgICAgdXRpbHM9e3V0aWxzfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvU2xpZGVJblRyYW5zaXRpb25Hcm91cD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgICB7ZGlzcGxheVRpbWUgJiZcbiAgICAgICAgICAgIDxSYW5nZVRpbWVQaWNrZXJcbiAgICAgICAgICAgICAgYmxvY2tlZERhdGVUaW1lUmFuZ2VzPXtibG9ja2VkRGF0ZVRpbWVSYW5nZXN9XG4gICAgICAgICAgICAgIGVkaXQ9e2VkaXR9XG4gICAgICAgICAgICAgIGVuZD17ZW5kfVxuICAgICAgICAgICAgICBsb2NhbGU9e2xvY2FsZX1cbiAgICAgICAgICAgICAgb25Ub3VjaFRhcEhvdXI9e3RoaXMucHJvcHMub25Ub3VjaFRhcEhvdXIuYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgc3RhcnQ9e3N0YXJ0fVxuICAgICAgICAgICAgICB1dGlscz17dXRpbHN9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJhbmdlQ2FsZW5kYXI7XG4iXX0=