UNPKG

apeman-react-select

Version:
431 lines (373 loc) 34.4 kB
/** * apeman react package for select component. * @class ApSelect */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApSelect = undefined; var _assign = require('babel-runtime/core-js/object/assign'); var _assign2 = _interopRequireDefault(_assign); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _ap_select_item = require('./ap_select_item'); var _ap_select_item2 = _interopRequireDefault(_ap_select_item); var _ap_select_label = require('./ap_select_label'); var _ap_select_label2 = _interopRequireDefault(_ap_select_label); var _numcal = require('numcal'); var _numcal2 = _interopRequireDefault(_numcal); var _bwindow = require('bwindow'); var _apemanReactMixinLayout = require('apeman-react-mixin-layout'); var _apemanReactTouchable = require('apeman-react-touchable'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** @lends ApSelect */ var ApSelect = _react2.default.createClass({ displayName: 'ApSelect', // -------------------- // Specs // -------------------- propTypes: { /** Options of select */ options: _react.PropTypes.object.isRequired, /** Option elements to render */ optionElements: _react.PropTypes.object, /** Name of select element */ name: _react.PropTypes.string, /** Value of select element */ value: _react.PropTypes.string, /** Allow multiple select */ multiple: _react.PropTypes.bool, /** Handler for change event */ onChange: _react.PropTypes.func, /** Icon to toggle select */ openIcon: _react.PropTypes.string, /** Placeholder of select element */ placeholder: _react.PropTypes.string }, mixins: [_apemanReactMixinLayout.ApLayoutMixin], statics: {}, getInitialState: function getInitialState() { var s = this; return { focused: false, focusIndex: s.getIndexForValue(s.props.value) }; }, getDefaultProps: function getDefaultProps() { return { optionElements: null, value: '', name: null, multiple: false, onChange: null, openIcon: 'ion ion-arrow-down-b', placeholder: null }; }, render: function render() { var s = this; var state = s.state, props = s.props, layouts = s.layouts; var options = props.options, optionElements = props.optionElements; var values = s.getOptionValues(); var hasOption = options && (0, _keys2.default)(options).length > 0; if (!hasOption) { return null; } var _option = function _option(value) { return optionElements && optionElements[value] || options[value] || null; }; return _react2.default.createElement( 'span', { className: (0, _classnames2.default)('ap-select-wrap') }, _react2.default.createElement( 'span', { className: (0, _classnames2.default)('ap-select-options-list', { 'ap-select-options-list-visible': state.focused }), ref: function ref(list) { return s.registerNode(list, 'list'); } }, _react2.default.createElement( 'ul', { className: 'ap-select-options-list-inner', style: layouts.listInner }, values.map(function (value, i) { return _react2.default.createElement( 'li', { key: value, value: value, className: (0, _classnames2.default)('ap-select-options-list-item') }, _react2.default.createElement( _ap_select_item2.default, { onTap: s.handleItemTap, data: value, focused: state.focusIndex === i, label: options[value] }, _option(value) || null ) ); }) ) ), _react2.default.createElement( 'select', { id: props.id, name: props.name, placeholder: props.placeholder, onChange: props.onChange, className: (0, _classnames2.default)('ap-select', props.className), onFocus: function onFocus() { return s.setFocus(true); }, style: (0, _assign2.default)({}, props.style), tabIndex: '-1' }, values.map(function (value) { return _react2.default.createElement( 'option', { key: value, value: value }, options[value] ); }), props.children ), _react2.default.createElement('input', { type: 'text', ref: function ref(text) { return s.registerNode(text, 'text'); }, className: 'ap-select-dummy-text', onKeyUp: s.handleKeyUp, onKeyDown: s.handleKeyDown, onFocus: function onFocus() { return s.setFocus(true); }, onBlur: function onBlur() { return s.setFocus(false); } }), _react2.default.createElement(_ap_select_label2.default, { value: _option(props.value), placeholder: props.placeholder, icon: props.openIcon, onTap: s.handleLabelTap }) ); }, // -------------------- // Lifecycle // -------------------- componentWillMount: function componentWillMount() { var s = this; s.nodes = {}; }, componentDidMount: function componentDidMount() { var s = this; var body = (0, _bwindow.get)('document.body'); body.addEventListener('click', s.handleClickForOutside); }, componentWillUnmount: function componentWillUnmount() { var s = this; var body = (0, _bwindow.get)('document.body'); body.removeEventListener('click', s.handleClickForOutside); }, // ------------------ // Custom // ------------------ moveFocusIndex: function moveFocusIndex(i) { var s = this; var state = s.state; var values = s.getOptionValues(); var index = state.focusIndex + i; var over = index === -1 || index === values.length; if (over) { return; } s.setState({ focusIndex: index }); }, enterFocused: function enterFocused(e) { var s = this; var state = s.state, props = s.props; if (!state.focused) { return; } var values = s.getOptionValues(); var value = values[state.focusIndex]; s.setState({ focused: false, focusIndex: s.getIndexForValue(value) }); e.target.value = value; if (props.onChange) { props.onChange(e); } }, getOptionValues: function getOptionValues() { var s = this; var props = s.props; return (0, _keys2.default)(props.options || {}); }, getIndexForValue: function getIndexForValue(value) { var s = this; return s.getOptionValues().indexOf(value); }, registerNode: function registerNode(elm, name) { var s = this; s.nodes[name] = _reactDom2.default.findDOMNode(elm); }, // -------------------- // Handle // -------------------- handleLabelTap: function handleLabelTap(e) { var s = this; var state = s.state; var text = s.nodes.text; var focused = !state.focused; if (focused) { s.layout(); text.focus(); } else { text.blur(); } s.setState({ focused: focused, focusIndex: s.getIndexForValue(s.props.value) }); }, setFocus: function setFocus(focused) { var s = this; if (focused === s.state.focused) { return; } if (s._focusAt) { var fromLastFocusAt = new Date() - s._focusAt; if (fromLastFocusAt < 500) { return; } } s._focusAt = new Date(); s.setState({ focused: focused }); }, handleKeyDown: function handleKeyDown(e) { var s = this; var props = s.props; if (!s.state.focused) { s.setState({ focused: true }); return; } switch (e.keyCode) { case 38: // UP s.moveFocusIndex(-1); break; case 40: // DOWN s.moveFocusIndex(+1); break; case 13: // Enter s.enterFocused(e); break; case 9: // Tab break; default: e.preventDefault(); e.stopPropagation(); break; } if (props.onKeyDown) { props.onKeyDown(e); } }, handleKeyUp: function handleKeyUp(e) { var s = this; var props = s.props; if (props.onKeyUp) { props.onKeyUp(e); } e.stopPropagation(); }, handleItemTap: function handleItemTap(e) { var s = this; var props = s.props; (0, _assign2.default)(e.target, { value: e.target.value || e.data || null, name: e.target.name || props.name }); if (props.onChange) { props.onChange(e); } s.setState({ focused: false, focusIndex: s.getIndexForValue(s.props.value) }); }, handleClickForOutside: function handleClickForOutside(e) { var s = this; var node = _reactDom2.default.findDOMNode(s); if (!node) { return; } var contained = node.contains(e.target); if (!contained) { s.outsideDidTap(e); } }, outsideDidTap: function outsideDidTap(e) { var s = this; s.setFocus(false); }, // ------------------ // ApLayoutMixin // ------------------ getInitialLayouts: function getInitialLayouts() { return { listInner: { transform: 'initial' } }; }, calcLayouts: function calcLayouts() { var s = this; var _window = window, innerHeight = _window.innerHeight, innerWidth = _window.innerWidth; var list = s.nodes.list; if (!list) { return {}; } return { listInner: s._listInnerLayout(list.getBoundingClientRect(), innerWidth, innerHeight) }; }, // ------------------ // Private // ------------------ _listInnerLayout: function _listInnerLayout(rect, boundsWidth, boundsHeight) { var x = _numcal2.default.min(boundsWidth - rect.right, 0); var y = _numcal2.default.min(boundsHeight - rect.bottom, 0); var maxHeight = _numcal2.default.min(boundsHeight, 280) + 'px'; return { transform: 'translate(' + x + 'px, ' + y + 'px)', maxHeight: maxHeight }; } }); exports.ApSelect = ApSelect; exports.default = (0, _apemanReactTouchable.withOutside)(ApSelect); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwX3NlbGVjdC5qc3giXSwibmFtZXMiOlsiQXBTZWxlY3QiLCJjcmVhdGVDbGFzcyIsInByb3BUeXBlcyIsIm9wdGlvbnMiLCJvYmplY3QiLCJpc1JlcXVpcmVkIiwib3B0aW9uRWxlbWVudHMiLCJuYW1lIiwic3RyaW5nIiwidmFsdWUiLCJtdWx0aXBsZSIsImJvb2wiLCJvbkNoYW5nZSIsImZ1bmMiLCJvcGVuSWNvbiIsInBsYWNlaG9sZGVyIiwibWl4aW5zIiwic3RhdGljcyIsImdldEluaXRpYWxTdGF0ZSIsInMiLCJmb2N1c2VkIiwiZm9jdXNJbmRleCIsImdldEluZGV4Rm9yVmFsdWUiLCJwcm9wcyIsImdldERlZmF1bHRQcm9wcyIsInJlbmRlciIsInN0YXRlIiwibGF5b3V0cyIsInZhbHVlcyIsImdldE9wdGlvblZhbHVlcyIsImhhc09wdGlvbiIsImxlbmd0aCIsIl9vcHRpb24iLCJsaXN0IiwicmVnaXN0ZXJOb2RlIiwibGlzdElubmVyIiwibWFwIiwiaSIsImhhbmRsZUl0ZW1UYXAiLCJpZCIsImNsYXNzTmFtZSIsInNldEZvY3VzIiwic3R5bGUiLCJjaGlsZHJlbiIsInRleHQiLCJoYW5kbGVLZXlVcCIsImhhbmRsZUtleURvd24iLCJoYW5kbGVMYWJlbFRhcCIsImNvbXBvbmVudFdpbGxNb3VudCIsIm5vZGVzIiwiY29tcG9uZW50RGlkTW91bnQiLCJib2R5IiwiYWRkRXZlbnRMaXN0ZW5lciIsImhhbmRsZUNsaWNrRm9yT3V0c2lkZSIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsIm1vdmVGb2N1c0luZGV4IiwiaW5kZXgiLCJvdmVyIiwic2V0U3RhdGUiLCJlbnRlckZvY3VzZWQiLCJlIiwidGFyZ2V0IiwiaW5kZXhPZiIsImVsbSIsImZpbmRET01Ob2RlIiwibGF5b3V0IiwiZm9jdXMiLCJibHVyIiwiX2ZvY3VzQXQiLCJmcm9tTGFzdEZvY3VzQXQiLCJEYXRlIiwia2V5Q29kZSIsInByZXZlbnREZWZhdWx0Iiwic3RvcFByb3BhZ2F0aW9uIiwib25LZXlEb3duIiwib25LZXlVcCIsImRhdGEiLCJub2RlIiwiY29udGFpbmVkIiwiY29udGFpbnMiLCJvdXRzaWRlRGlkVGFwIiwiZ2V0SW5pdGlhbExheW91dHMiLCJ0cmFuc2Zvcm0iLCJjYWxjTGF5b3V0cyIsIndpbmRvdyIsImlubmVySGVpZ2h0IiwiaW5uZXJXaWR0aCIsIl9saXN0SW5uZXJMYXlvdXQiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJyZWN0IiwiYm91bmRzV2lkdGgiLCJib3VuZHNIZWlnaHQiLCJ4IiwibWluIiwicmlnaHQiLCJ5IiwiYm90dG9tIiwibWF4SGVpZ2h0Il0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7QUFLQTs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQTtBQUNBLElBQU1BLFdBQVcsZ0JBQU1DLFdBQU4sQ0FBa0I7QUFBQTs7O0FBRWpDO0FBQ0E7QUFDQTs7QUFFQUMsYUFBVztBQUNUO0FBQ0FDLGFBQVMsaUJBQU1DLE1BQU4sQ0FBYUMsVUFGYjtBQUdUO0FBQ0FDLG9CQUFnQixpQkFBTUYsTUFKYjtBQUtUO0FBQ0FHLFVBQU0saUJBQU1DLE1BTkg7QUFPVDtBQUNBQyxXQUFPLGlCQUFNRCxNQVJKO0FBU1Q7QUFDQUUsY0FBVSxpQkFBTUMsSUFWUDtBQVdUO0FBQ0FDLGNBQVUsaUJBQU1DLElBWlA7QUFhVDtBQUNBQyxjQUFVLGlCQUFNTixNQWRQO0FBZVQ7QUFDQU8saUJBQWEsaUJBQU1QO0FBaEJWLEdBTnNCOztBQXlCakNRLFVBQVEsdUNBekJ5Qjs7QUE2QmpDQyxXQUFTLEVBN0J3Qjs7QUErQmpDQyxpQkEvQmlDLDZCQStCZDtBQUNqQixRQUFNQyxJQUFJLElBQVY7QUFDQSxXQUFPO0FBQ0xDLGVBQVMsS0FESjtBQUVMQyxrQkFBWUYsRUFBRUcsZ0JBQUYsQ0FBbUJILEVBQUVJLEtBQUYsQ0FBUWQsS0FBM0I7QUFGUCxLQUFQO0FBSUQsR0FyQ2dDO0FBdUNqQ2UsaUJBdkNpQyw2QkF1Q2Q7QUFDakIsV0FBTztBQUNMbEIsc0JBQWdCLElBRFg7QUFFTEcsYUFBTyxFQUZGO0FBR0xGLFlBQU0sSUFIRDtBQUlMRyxnQkFBVSxLQUpMO0FBS0xFLGdCQUFVLElBTEw7QUFNTEUsZ0JBQVUsc0JBTkw7QUFPTEMsbUJBQWE7QUFQUixLQUFQO0FBU0QsR0FqRGdDO0FBbURqQ1UsUUFuRGlDLG9CQW1EdkI7QUFDUixRQUFNTixJQUFJLElBQVY7QUFEUSxRQUVGTyxLQUZFLEdBRXdCUCxDQUZ4QixDQUVGTyxLQUZFO0FBQUEsUUFFS0gsS0FGTCxHQUV3QkosQ0FGeEIsQ0FFS0ksS0FGTDtBQUFBLFFBRVlJLE9BRlosR0FFd0JSLENBRnhCLENBRVlRLE9BRlo7QUFBQSxRQUlGeEIsT0FKRSxHQUkwQm9CLEtBSjFCLENBSUZwQixPQUpFO0FBQUEsUUFJT0csY0FKUCxHQUkwQmlCLEtBSjFCLENBSU9qQixjQUpQOztBQUtSLFFBQUlzQixTQUFTVCxFQUFFVSxlQUFGLEVBQWI7O0FBRUEsUUFBSUMsWUFBWTNCLFdBQVcsb0JBQVlBLE9BQVosRUFBcUI0QixNQUFyQixHQUE4QixDQUF6RDtBQUNBLFFBQUksQ0FBQ0QsU0FBTCxFQUFnQjtBQUNkLGFBQU8sSUFBUDtBQUNEOztBQUVELFFBQUlFLFVBQVUsU0FBVkEsT0FBVSxDQUFDdkIsS0FBRDtBQUFBLGFBQVdILGtCQUFrQkEsZUFBZ0JHLEtBQWhCLENBQWxCLElBQTZDTixRQUFTTSxLQUFULENBQTdDLElBQWlFLElBQTVFO0FBQUEsS0FBZDs7QUFFQSxXQUNFO0FBQUE7QUFBQSxRQUFNLFdBQVksMEJBQVcsZ0JBQVgsQ0FBbEI7QUFDSTtBQUFBO0FBQUEsVUFBTSxXQUFZLDBCQUFXLHdCQUFYLEVBQXFDO0FBQ3JELDhDQUFrQ2lCLE1BQU1OO0FBRGEsV0FBckMsQ0FBbEIsRUFFSyxLQUFNLGFBQUNhLElBQUQ7QUFBQSxtQkFBVWQsRUFBRWUsWUFBRixDQUFlRCxJQUFmLEVBQXFCLE1BQXJCLENBQVY7QUFBQTtBQUZYO0FBSUk7QUFBQTtBQUFBLFlBQUksV0FBVSw4QkFBZDtBQUNJLG1CQUFRTixRQUFRUSxTQURwQjtBQUVNUCxpQkFBT1EsR0FBUCxDQUFXLFVBQUMzQixLQUFELEVBQVE0QixDQUFSO0FBQUEsbUJBQ1g7QUFBQTtBQUFBLGdCQUFJLEtBQU01QixLQUFWO0FBQ0ksdUJBQVFBLEtBRFo7QUFFSSwyQkFBWSwwQkFBVyw2QkFBWCxDQUZoQjtBQUdFO0FBQUE7QUFBQSxrQkFBYyxPQUFRVSxFQUFFbUIsYUFBeEI7QUFDYyx3QkFBTzdCLEtBRHJCO0FBRWMsMkJBQVVpQixNQUFNTCxVQUFOLEtBQXFCZ0IsQ0FGN0M7QUFHYyx5QkFBUWxDLFFBQVNNLEtBQVQ7QUFIdEI7QUFLSXVCLHdCQUFRdkIsS0FBUixLQUFrQjtBQUx0QjtBQUhGLGFBRFc7QUFBQSxXQUFYO0FBRk47QUFKSixPQURKO0FBc0JJO0FBQUE7QUFBQSxVQUFRLElBQUtjLE1BQU1nQixFQUFuQjtBQUNRLGdCQUFPaEIsTUFBTWhCLElBRHJCO0FBRVEsdUJBQWNnQixNQUFNUixXQUY1QjtBQUdRLG9CQUFXUSxNQUFNWCxRQUh6QjtBQUlRLHFCQUFZLDBCQUFXLFdBQVgsRUFBd0JXLE1BQU1pQixTQUE5QixDQUpwQjtBQUtRLG1CQUFVO0FBQUEsbUJBQU1yQixFQUFFc0IsUUFBRixDQUFXLElBQVgsQ0FBTjtBQUFBLFdBTGxCO0FBTVEsaUJBQVEsc0JBQWMsRUFBZCxFQUFrQmxCLE1BQU1tQixLQUF4QixDQU5oQjtBQU9RLG9CQUFTO0FBUGpCO0FBU01kLGVBQU9RLEdBQVAsQ0FBVyxVQUFDM0IsS0FBRDtBQUFBLGlCQUNYO0FBQUE7QUFBQSxjQUFRLEtBQU1BLEtBQWQsRUFBc0IsT0FBUUEsS0FBOUI7QUFBd0NOLG9CQUFTTSxLQUFUO0FBQXhDLFdBRFc7QUFBQSxTQUFYLENBVE47QUFZSWMsY0FBTW9CO0FBWlYsT0F0Qko7QUFvQ0ksK0NBQU8sTUFBSyxNQUFaO0FBQ08sYUFBTSxhQUFDQyxJQUFEO0FBQUEsaUJBQVV6QixFQUFFZSxZQUFGLENBQWVVLElBQWYsRUFBcUIsTUFBckIsQ0FBVjtBQUFBLFNBRGI7QUFFTyxtQkFBVSxzQkFGakI7QUFHTyxpQkFBVXpCLEVBQUUwQixXQUhuQjtBQUlPLG1CQUFZMUIsRUFBRTJCLGFBSnJCO0FBS08saUJBQVU7QUFBQSxpQkFBTTNCLEVBQUVzQixRQUFGLENBQVcsSUFBWCxDQUFOO0FBQUEsU0FMakI7QUFNTyxnQkFBUztBQUFBLGlCQUFNdEIsRUFBRXNCLFFBQUYsQ0FBVyxLQUFYLENBQU47QUFBQTtBQU5oQixRQXBDSjtBQTRDSSxpRUFBZSxPQUFRVCxRQUFRVCxNQUFNZCxLQUFkLENBQXZCO0FBQ2UscUJBQWNjLE1BQU1SLFdBRG5DO0FBRWUsY0FBT1EsTUFBTVQsUUFGNUI7QUFHZSxlQUFRSyxFQUFFNEI7QUFIekI7QUE1Q0osS0FERjtBQXFERCxHQXRIZ0M7OztBQXdIakM7QUFDQTtBQUNBOztBQUVBQyxvQkE1SGlDLGdDQTRIWDtBQUNwQixRQUFNN0IsSUFBSSxJQUFWO0FBQ0FBLE1BQUU4QixLQUFGLEdBQVUsRUFBVjtBQUNELEdBL0hnQztBQWlJakNDLG1CQWpJaUMsK0JBaUlaO0FBQ25CLFFBQU0vQixJQUFJLElBQVY7QUFDQSxRQUFJZ0MsT0FBTyxrQkFBSSxlQUFKLENBQVg7QUFDQUEsU0FBS0MsZ0JBQUwsQ0FBc0IsT0FBdEIsRUFBK0JqQyxFQUFFa0MscUJBQWpDO0FBQ0QsR0FySWdDO0FBdUlqQ0Msc0JBdklpQyxrQ0F1SVQ7QUFDdEIsUUFBTW5DLElBQUksSUFBVjtBQUNBLFFBQUlnQyxPQUFPLGtCQUFJLGVBQUosQ0FBWDtBQUNBQSxTQUFLSSxtQkFBTCxDQUF5QixPQUF6QixFQUFrQ3BDLEVBQUVrQyxxQkFBcEM7QUFFRCxHQTVJZ0M7O0FBNklqQztBQUNBO0FBQ0E7O0FBRUFHLGdCQWpKaUMsMEJBaUpqQm5CLENBakppQixFQWlKZDtBQUNqQixRQUFNbEIsSUFBSSxJQUFWO0FBRGlCLFFBRVhPLEtBRlcsR0FFRFAsQ0FGQyxDQUVYTyxLQUZXOztBQUdqQixRQUFJRSxTQUFTVCxFQUFFVSxlQUFGLEVBQWI7QUFDQSxRQUFJNEIsUUFBUS9CLE1BQU1MLFVBQU4sR0FBbUJnQixDQUEvQjtBQUNBLFFBQUlxQixPQUFRRCxVQUFVLENBQUMsQ0FBWixJQUFtQkEsVUFBVTdCLE9BQU9HLE1BQS9DO0FBQ0EsUUFBSTJCLElBQUosRUFBVTtBQUNSO0FBQ0Q7QUFDRHZDLE1BQUV3QyxRQUFGLENBQVc7QUFDVHRDLGtCQUFZb0M7QUFESCxLQUFYO0FBR0QsR0E3SmdDO0FBK0pqQ0csY0EvSmlDLHdCQStKbkJDLENBL0ptQixFQStKaEI7QUFDZixRQUFNMUMsSUFBSSxJQUFWO0FBRGUsUUFFVE8sS0FGUyxHQUVRUCxDQUZSLENBRVRPLEtBRlM7QUFBQSxRQUVGSCxLQUZFLEdBRVFKLENBRlIsQ0FFRkksS0FGRTs7QUFHZixRQUFJLENBQUNHLE1BQU1OLE9BQVgsRUFBb0I7QUFDbEI7QUFDRDtBQUNELFFBQUlRLFNBQVNULEVBQUVVLGVBQUYsRUFBYjtBQUNBLFFBQUlwQixRQUFRbUIsT0FBUUYsTUFBTUwsVUFBZCxDQUFaO0FBQ0FGLE1BQUV3QyxRQUFGLENBQVc7QUFDVHZDLGVBQVMsS0FEQTtBQUVUQyxrQkFBWUYsRUFBRUcsZ0JBQUYsQ0FBbUJiLEtBQW5CO0FBRkgsS0FBWDtBQUlBb0QsTUFBRUMsTUFBRixDQUFTckQsS0FBVCxHQUFpQkEsS0FBakI7QUFDQSxRQUFJYyxNQUFNWCxRQUFWLEVBQW9CO0FBQ2xCVyxZQUFNWCxRQUFOLENBQWVpRCxDQUFmO0FBQ0Q7QUFDRixHQS9LZ0M7QUFpTGpDaEMsaUJBakxpQyw2QkFpTGQ7QUFDakIsUUFBTVYsSUFBSSxJQUFWO0FBRGlCLFFBRVhJLEtBRlcsR0FFREosQ0FGQyxDQUVYSSxLQUZXOztBQUdqQixXQUFPLG9CQUFZQSxNQUFNcEIsT0FBTixJQUFpQixFQUE3QixDQUFQO0FBQ0QsR0FyTGdDO0FBdUxqQ21CLGtCQXZMaUMsNEJBdUxmYixLQXZMZSxFQXVMUjtBQUN2QixRQUFNVSxJQUFJLElBQVY7QUFDQSxXQUFPQSxFQUFFVSxlQUFGLEdBQW9Ca0MsT0FBcEIsQ0FBNEJ0RCxLQUE1QixDQUFQO0FBQ0QsR0ExTGdDO0FBNExqQ3lCLGNBNUxpQyx3QkE0TG5COEIsR0E1TG1CLEVBNExkekQsSUE1TGMsRUE0TFI7QUFDdkIsUUFBTVksSUFBSSxJQUFWO0FBQ0FBLE1BQUU4QixLQUFGLENBQVMxQyxJQUFULElBQWtCLG1CQUFTMEQsV0FBVCxDQUFxQkQsR0FBckIsQ0FBbEI7QUFDRCxHQS9MZ0M7OztBQWlNakM7QUFDQTtBQUNBOztBQUVBakIsZ0JBck1pQywwQkFxTWpCYyxDQXJNaUIsRUFxTWQ7QUFDakIsUUFBTTFDLElBQUksSUFBVjtBQURpQixRQUVYTyxLQUZXLEdBRURQLENBRkMsQ0FFWE8sS0FGVztBQUFBLFFBSVhrQixJQUpXLEdBSUZ6QixFQUFFOEIsS0FKQSxDQUlYTCxJQUpXOzs7QUFNakIsUUFBSXhCLFVBQVUsQ0FBQ00sTUFBTU4sT0FBckI7QUFDQSxRQUFJQSxPQUFKLEVBQWE7QUFDWEQsUUFBRStDLE1BQUY7QUFDQXRCLFdBQUt1QixLQUFMO0FBQ0QsS0FIRCxNQUdPO0FBQ0x2QixXQUFLd0IsSUFBTDtBQUNEO0FBQ0RqRCxNQUFFd0MsUUFBRixDQUFXO0FBQ1R2QyxzQkFEUztBQUVUQyxrQkFBWUYsRUFBRUcsZ0JBQUYsQ0FBbUJILEVBQUVJLEtBQUYsQ0FBUWQsS0FBM0I7QUFGSCxLQUFYO0FBSUQsR0F0TmdDO0FBd05qQ2dDLFVBeE5pQyxvQkF3TnZCckIsT0F4TnVCLEVBd05kO0FBQ2pCLFFBQU1ELElBQUksSUFBVjtBQUNBLFFBQUlDLFlBQVlELEVBQUVPLEtBQUYsQ0FBUU4sT0FBeEIsRUFBaUM7QUFDL0I7QUFDRDtBQUNELFFBQUdELEVBQUVrRCxRQUFMLEVBQWM7QUFDWixVQUFNQyxrQkFBa0IsSUFBSUMsSUFBSixLQUFjcEQsRUFBRWtELFFBQXhDO0FBQ0EsVUFBR0Msa0JBQWtCLEdBQXJCLEVBQXlCO0FBQ3ZCO0FBQ0Q7QUFDRjtBQUNEbkQsTUFBRWtELFFBQUYsR0FBYSxJQUFJRSxJQUFKLEVBQWI7QUFDQXBELE1BQUV3QyxRQUFGLENBQVc7QUFDVHZDO0FBRFMsS0FBWDtBQUdELEdBdk9nQztBQXlPakMwQixlQXpPaUMseUJBeU9sQmUsQ0F6T2tCLEVBeU9mO0FBQ2hCLFFBQU0xQyxJQUFJLElBQVY7QUFEZ0IsUUFFVkksS0FGVSxHQUVBSixDQUZBLENBRVZJLEtBRlU7O0FBR2hCLFFBQUksQ0FBQ0osRUFBRU8sS0FBRixDQUFRTixPQUFiLEVBQXNCO0FBQ3BCRCxRQUFFd0MsUUFBRixDQUFXLEVBQUV2QyxTQUFTLElBQVgsRUFBWDtBQUNBO0FBQ0Q7QUFDRCxZQUFReUMsRUFBRVcsT0FBVjtBQUNFLFdBQUssRUFBTDtBQUFTO0FBQ1ByRCxVQUFFcUMsY0FBRixDQUFpQixDQUFDLENBQWxCO0FBQ0E7QUFDRixXQUFLLEVBQUw7QUFBUztBQUNQckMsVUFBRXFDLGNBQUYsQ0FBaUIsQ0FBQyxDQUFsQjtBQUNBO0FBQ0YsV0FBSyxFQUFMO0FBQVM7QUFDUHJDLFVBQUV5QyxZQUFGLENBQWVDLENBQWY7QUFDQTtBQUNGLFdBQUssQ0FBTDtBQUFRO0FBQ047QUFDRjtBQUNFQSxVQUFFWSxjQUFGO0FBQ0FaLFVBQUVhLGVBQUY7QUFDQTtBQWZKO0FBaUJBLFFBQUluRCxNQUFNb0QsU0FBVixFQUFxQjtBQUNuQnBELFlBQU1vRCxTQUFOLENBQWdCZCxDQUFoQjtBQUNEO0FBQ0YsR0FwUWdDO0FBc1FqQ2hCLGFBdFFpQyx1QkFzUXBCZ0IsQ0F0UW9CLEVBc1FqQjtBQUNkLFFBQU0xQyxJQUFJLElBQVY7QUFEYyxRQUVSSSxLQUZRLEdBRUVKLENBRkYsQ0FFUkksS0FGUTs7QUFHZCxRQUFJQSxNQUFNcUQsT0FBVixFQUFtQjtBQUNqQnJELFlBQU1xRCxPQUFOLENBQWNmLENBQWQ7QUFDRDtBQUNEQSxNQUFFYSxlQUFGO0FBQ0QsR0E3UWdDO0FBK1FqQ3BDLGVBL1FpQyx5QkErUWxCdUIsQ0EvUWtCLEVBK1FmO0FBQ2hCLFFBQU0xQyxJQUFJLElBQVY7QUFEZ0IsUUFFVkksS0FGVSxHQUVBSixDQUZBLENBRVZJLEtBRlU7O0FBR2hCLDBCQUFjc0MsRUFBRUMsTUFBaEIsRUFBd0I7QUFDdEJyRCxhQUFPb0QsRUFBRUMsTUFBRixDQUFTckQsS0FBVCxJQUFrQm9ELEVBQUVnQixJQUFwQixJQUE0QixJQURiO0FBRXRCdEUsWUFBTXNELEVBQUVDLE1BQUYsQ0FBU3ZELElBQVQsSUFBaUJnQixNQUFNaEI7QUFGUCxLQUF4QjtBQUlBLFFBQUlnQixNQUFNWCxRQUFWLEVBQW9CO0FBQ2xCVyxZQUFNWCxRQUFOLENBQWVpRCxDQUFmO0FBQ0Q7QUFDRDFDLE1BQUV3QyxRQUFGLENBQVc7QUFDVHZDLGVBQVMsS0FEQTtBQUVUQyxrQkFBWUYsRUFBRUcsZ0JBQUYsQ0FBbUJILEVBQUVJLEtBQUYsQ0FBUWQsS0FBM0I7QUFGSCxLQUFYO0FBSUQsR0E3UmdDO0FBK1JqQzRDLHVCQS9SaUMsaUNBK1JWUSxDQS9SVSxFQStSUDtBQUN4QixRQUFNMUMsSUFBSSxJQUFWO0FBQ0EsUUFBSTJELE9BQU8sbUJBQVNiLFdBQVQsQ0FBcUI5QyxDQUFyQixDQUFYO0FBQ0EsUUFBSSxDQUFDMkQsSUFBTCxFQUFXO0FBQ1Q7QUFDRDtBQUNELFFBQUlDLFlBQVlELEtBQUtFLFFBQUwsQ0FBY25CLEVBQUVDLE1BQWhCLENBQWhCO0FBQ0EsUUFBSSxDQUFDaUIsU0FBTCxFQUFnQjtBQUNkNUQsUUFBRThELGFBQUYsQ0FBZ0JwQixDQUFoQjtBQUNEO0FBQ0YsR0F6U2dDO0FBMlNqQ29CLGVBM1NpQyx5QkEyU2xCcEIsQ0EzU2tCLEVBMlNmO0FBQ2hCLFFBQU0xQyxJQUFJLElBQVY7QUFDQUEsTUFBRXNCLFFBQUYsQ0FBVyxLQUFYO0FBQ0QsR0E5U2dDOzs7QUFnVGpDO0FBQ0E7QUFDQTs7QUFFQXlDLG1CQXBUaUMsK0JBb1RaO0FBQ25CLFdBQU87QUFDTC9DLGlCQUFXO0FBQ1RnRCxtQkFBVztBQURGO0FBRE4sS0FBUDtBQUtELEdBMVRnQztBQTRUakNDLGFBNVRpQyx5QkE0VGxCO0FBQ2IsUUFBTWpFLElBQUksSUFBVjtBQURhLGtCQUVxQmtFLE1BRnJCO0FBQUEsUUFFUEMsV0FGTyxXQUVQQSxXQUZPO0FBQUEsUUFFTUMsVUFGTixXQUVNQSxVQUZOO0FBQUEsUUFHUHRELElBSE8sR0FHRWQsRUFBRThCLEtBSEosQ0FHUGhCLElBSE87O0FBSWIsUUFBSSxDQUFDQSxJQUFMLEVBQVc7QUFDVCxhQUFPLEVBQVA7QUFDRDtBQUNELFdBQU87QUFDTEUsaUJBQVdoQixFQUFFcUUsZ0JBQUYsQ0FBbUJ2RCxLQUFLd0QscUJBQUwsRUFBbkIsRUFBaURGLFVBQWpELEVBQTZERCxXQUE3RDtBQUROLEtBQVA7QUFHRCxHQXRVZ0M7OztBQXdVakM7QUFDQTtBQUNBOztBQUVBRSxrQkE1VWlDLDRCQTRVZkUsSUE1VWUsRUE0VVRDLFdBNVVTLEVBNFVJQyxZQTVVSixFQTRVa0I7QUFDakQsUUFBSUMsSUFBSSxpQkFBT0MsR0FBUCxDQUFXSCxjQUFjRCxLQUFLSyxLQUE5QixFQUFxQyxDQUFyQyxDQUFSO0FBQ0EsUUFBSUMsSUFBSSxpQkFBT0YsR0FBUCxDQUFXRixlQUFlRixLQUFLTyxNQUEvQixFQUF1QyxDQUF2QyxDQUFSOztBQUVBLFFBQUlDLFlBQWUsaUJBQU9KLEdBQVAsQ0FBV0YsWUFBWCxFQUF5QixHQUF6QixDQUFmLE9BQUo7QUFDQSxXQUFPO0FBQ0xULGdDQUF3QlUsQ0FBeEIsWUFBZ0NHLENBQWhDLFFBREs7QUFFTEU7QUFGSyxLQUFQO0FBSUQ7QUFyVmdDLENBQWxCLENBQWpCOztRQXdWU2xHLFEsR0FBQUEsUTtrQkFDTSx1Q0FBWUEsUUFBWixDIiwiZmlsZSI6ImFwX3NlbGVjdC5qc3giLCJzb3VyY2VSb290IjoibGliIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBhcGVtYW4gcmVhY3QgcGFja2FnZSBmb3Igc2VsZWN0IGNvbXBvbmVudC5cbiAqIEBjbGFzcyBBcFNlbGVjdFxuICovXG5cbid1c2Ugc3RyaWN0J1xuXG5pbXBvcnQgUmVhY3QsIHsgQ29tcG9uZW50LCBQcm9wVHlwZXMgYXMgdHlwZXMgfSBmcm9tICdyZWFjdCdcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nXG5pbXBvcnQgY2xhc3NuYW1lcyBmcm9tICdjbGFzc25hbWVzJ1xuaW1wb3J0IEFwU2VsZWN0SXRlbSBmcm9tICcuL2FwX3NlbGVjdF9pdGVtJ1xuaW1wb3J0IEFwU2VsZWN0TGFiZWwgZnJvbSAnLi9hcF9zZWxlY3RfbGFiZWwnXG5pbXBvcnQgbnVtY2FsIGZyb20gJ251bWNhbCdcbmltcG9ydCB7IGdldCB9IGZyb20gJ2J3aW5kb3cnXG5pbXBvcnQgeyBBcExheW91dE1peGluIH0gZnJvbSAnYXBlbWFuLXJlYWN0LW1peGluLWxheW91dCdcbmltcG9ydCB7IHdpdGhPdXRzaWRlIH0gZnJvbSAnYXBlbWFuLXJlYWN0LXRvdWNoYWJsZSdcblxuLyoqIEBsZW5kcyBBcFNlbGVjdCAqL1xuY29uc3QgQXBTZWxlY3QgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gU3BlY3NcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcm9wVHlwZXM6IHtcbiAgICAvKiogT3B0aW9ucyBvZiBzZWxlY3QgKi9cbiAgICBvcHRpb25zOiB0eXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAvKiogT3B0aW9uIGVsZW1lbnRzIHRvIHJlbmRlciAqL1xuICAgIG9wdGlvbkVsZW1lbnRzOiB0eXBlcy5vYmplY3QsXG4gICAgLyoqIE5hbWUgb2Ygc2VsZWN0IGVsZW1lbnQgKi9cbiAgICBuYW1lOiB0eXBlcy5zdHJpbmcsXG4gICAgLyoqIFZhbHVlIG9mIHNlbGVjdCBlbGVtZW50ICovXG4gICAgdmFsdWU6IHR5cGVzLnN0cmluZyxcbiAgICAvKiogQWxsb3cgbXVsdGlwbGUgc2VsZWN0ICovXG4gICAgbXVsdGlwbGU6IHR5cGVzLmJvb2wsXG4gICAgLyoqIEhhbmRsZXIgZm9yIGNoYW5nZSBldmVudCAqL1xuICAgIG9uQ2hhbmdlOiB0eXBlcy5mdW5jLFxuICAgIC8qKiBJY29uIHRvIHRvZ2dsZSBzZWxlY3QgKi9cbiAgICBvcGVuSWNvbjogdHlwZXMuc3RyaW5nLFxuICAgIC8qKiBQbGFjZWhvbGRlciBvZiBzZWxlY3QgZWxlbWVudCAqL1xuICAgIHBsYWNlaG9sZGVyOiB0eXBlcy5zdHJpbmdcbiAgfSxcblxuICBtaXhpbnM6IFtcbiAgICBBcExheW91dE1peGluXG4gIF0sXG5cbiAgc3RhdGljczoge30sXG5cbiAgZ2V0SW5pdGlhbFN0YXRlICgpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIHJldHVybiB7XG4gICAgICBmb2N1c2VkOiBmYWxzZSxcbiAgICAgIGZvY3VzSW5kZXg6IHMuZ2V0SW5kZXhGb3JWYWx1ZShzLnByb3BzLnZhbHVlKVxuICAgIH1cbiAgfSxcblxuICBnZXREZWZhdWx0UHJvcHMgKCkge1xuICAgIHJldHVybiB7XG4gICAgICBvcHRpb25FbGVtZW50czogbnVsbCxcbiAgICAgIHZhbHVlOiAnJyxcbiAgICAgIG5hbWU6IG51bGwsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBvbkNoYW5nZTogbnVsbCxcbiAgICAgIG9wZW5JY29uOiAnaW9uIGlvbi1hcnJvdy1kb3duLWInLFxuICAgICAgcGxhY2Vob2xkZXI6IG51bGxcbiAgICB9XG4gIH0sXG5cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCB7IHN0YXRlLCBwcm9wcywgbGF5b3V0cyB9ID0gc1xuXG4gICAgbGV0IHsgb3B0aW9ucywgb3B0aW9uRWxlbWVudHMgfSA9IHByb3BzXG4gICAgbGV0IHZhbHVlcyA9IHMuZ2V0T3B0aW9uVmFsdWVzKClcblxuICAgIGxldCBoYXNPcHRpb24gPSBvcHRpb25zICYmIE9iamVjdC5rZXlzKG9wdGlvbnMpLmxlbmd0aCA+IDBcbiAgICBpZiAoIWhhc09wdGlvbikge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICBsZXQgX29wdGlvbiA9ICh2YWx1ZSkgPT4gb3B0aW9uRWxlbWVudHMgJiYgb3B0aW9uRWxlbWVudHNbIHZhbHVlIF0gfHwgb3B0aW9uc1sgdmFsdWUgXSB8fCBudWxsXG5cbiAgICByZXR1cm4gKFxuICAgICAgPHNwYW4gY2xhc3NOYW1lPXsgY2xhc3NuYW1lcygnYXAtc2VsZWN0LXdyYXAnKSB9PlxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT17IGNsYXNzbmFtZXMoJ2FwLXNlbGVjdC1vcHRpb25zLWxpc3QnLCB7XG4gICAgICAgICAgICAnYXAtc2VsZWN0LW9wdGlvbnMtbGlzdC12aXNpYmxlJzogc3RhdGUuZm9jdXNlZFxuICAgICAgICAgIH0pIH0gcmVmPXsgKGxpc3QpID0+IHMucmVnaXN0ZXJOb2RlKGxpc3QsICdsaXN0JykgfVxuICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHVsIGNsYXNzTmFtZT0nYXAtc2VsZWN0LW9wdGlvbnMtbGlzdC1pbm5lcidcbiAgICAgICAgICAgICAgICAgIHN0eWxlPXsgbGF5b3V0cy5saXN0SW5uZXIgfT5cbiAgICAgICAgICAgICAgICAgIHsgdmFsdWVzLm1hcCgodmFsdWUsIGkpID0+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBrZXk9eyB2YWx1ZSB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17IHZhbHVlIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17IGNsYXNzbmFtZXMoJ2FwLXNlbGVjdC1vcHRpb25zLWxpc3QtaXRlbScpIH0+XG4gICAgICAgICAgICAgICAgICAgICAgPEFwU2VsZWN0SXRlbSBvblRhcD17IHMuaGFuZGxlSXRlbVRhcCB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPXsgdmFsdWUgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9jdXNlZD17IHN0YXRlLmZvY3VzSW5kZXggPT09IGkgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9eyBvcHRpb25zWyB2YWx1ZSBdIH1cbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7IF9vcHRpb24odmFsdWUpIHx8IG51bGwgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvQXBTZWxlY3RJdGVtPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgKSB9XG4gICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDxzZWxlY3QgaWQ9eyBwcm9wcy5pZCB9XG4gICAgICAgICAgICAgICAgICBuYW1lPXsgcHJvcHMubmFtZSB9XG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj17IHByb3BzLnBsYWNlaG9sZGVyIH1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsgcHJvcHMub25DaGFuZ2UgfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsgY2xhc3NuYW1lcygnYXAtc2VsZWN0JywgcHJvcHMuY2xhc3NOYW1lKSB9XG4gICAgICAgICAgICAgICAgICBvbkZvY3VzPXsgKCkgPT4gcy5zZXRGb2N1cyh0cnVlKSB9XG4gICAgICAgICAgICAgICAgICBzdHlsZT17IE9iamVjdC5hc3NpZ24oe30sIHByb3BzLnN0eWxlKSB9XG4gICAgICAgICAgICAgICAgICB0YWJJbmRleD1cIi0xXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICAgIHsgdmFsdWVzLm1hcCgodmFsdWUpID0+XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBrZXk9eyB2YWx1ZSB9IHZhbHVlPXsgdmFsdWUgfT57IG9wdGlvbnNbIHZhbHVlIF0gfTwvb3B0aW9uPlxuICAgICAgICAgICAgICApIH1cbiAgICAgICAgICAgIHsgcHJvcHMuY2hpbGRyZW4gfVxuICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0J1xuICAgICAgICAgICAgICAgICByZWY9eyAodGV4dCkgPT4gcy5yZWdpc3Rlck5vZGUodGV4dCwgJ3RleHQnKSB9XG4gICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0nYXAtc2VsZWN0LWR1bW15LXRleHQnXG4gICAgICAgICAgICAgICAgIG9uS2V5VXA9eyBzLmhhbmRsZUtleVVwIH1cbiAgICAgICAgICAgICAgICAgb25LZXlEb3duPXsgcy5oYW5kbGVLZXlEb3duIH1cbiAgICAgICAgICAgICAgICAgb25Gb2N1cz17ICgpID0+IHMuc2V0Rm9jdXModHJ1ZSkgfVxuICAgICAgICAgICAgICAgICBvbkJsdXI9eyAoKSA9PiBzLnNldEZvY3VzKGZhbHNlKSB9XG4gICAgICAgICAgLz5cbiAgICAgICAgICA8QXBTZWxlY3RMYWJlbCB2YWx1ZT17IF9vcHRpb24ocHJvcHMudmFsdWUpIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj17IHByb3BzLnBsYWNlaG9sZGVyIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICBpY29uPXsgcHJvcHMub3Blbkljb24gfVxuICAgICAgICAgICAgICAgICAgICAgICAgIG9uVGFwPXsgcy5oYW5kbGVMYWJlbFRhcCB9XG4gICAgICAgICAgLz5cblxuICAgICAgPC9zcGFuPlxuICAgIClcbiAgfSxcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBMaWZlY3ljbGVcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBjb21wb25lbnRXaWxsTW91bnQgKCkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgcy5ub2RlcyA9IHt9XG4gIH0sXG5cbiAgY29tcG9uZW50RGlkTW91bnQgKCkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IGJvZHkgPSBnZXQoJ2RvY3VtZW50LmJvZHknKVxuICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBzLmhhbmRsZUNsaWNrRm9yT3V0c2lkZSlcbiAgfSxcblxuICBjb21wb25lbnRXaWxsVW5tb3VudCAoKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgYm9keSA9IGdldCgnZG9jdW1lbnQuYm9keScpXG4gICAgYm9keS5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHMuaGFuZGxlQ2xpY2tGb3JPdXRzaWRlKVxuXG4gIH0sXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBDdXN0b21cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgbW92ZUZvY3VzSW5kZXggKGkpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCB7IHN0YXRlIH0gPSBzXG4gICAgbGV0IHZhbHVlcyA9IHMuZ2V0T3B0aW9uVmFsdWVzKClcbiAgICBsZXQgaW5kZXggPSBzdGF0ZS5mb2N1c0luZGV4ICsgaVxuICAgIGxldCBvdmVyID0gKGluZGV4ID09PSAtMSkgfHwgKGluZGV4ID09PSB2YWx1ZXMubGVuZ3RoKVxuICAgIGlmIChvdmVyKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgcy5zZXRTdGF0ZSh7XG4gICAgICBmb2N1c0luZGV4OiBpbmRleFxuICAgIH0pXG4gIH0sXG5cbiAgZW50ZXJGb2N1c2VkIChlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBzdGF0ZSwgcHJvcHMgfSA9IHNcbiAgICBpZiAoIXN0YXRlLmZvY3VzZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBsZXQgdmFsdWVzID0gcy5nZXRPcHRpb25WYWx1ZXMoKVxuICAgIGxldCB2YWx1ZSA9IHZhbHVlc1sgc3RhdGUuZm9jdXNJbmRleCBdXG4gICAgcy5zZXRTdGF0ZSh7XG4gICAgICBmb2N1c2VkOiBmYWxzZSxcbiAgICAgIGZvY3VzSW5kZXg6IHMuZ2V0SW5kZXhGb3JWYWx1ZSh2YWx1ZSlcbiAgICB9KVxuICAgIGUudGFyZ2V0LnZhbHVlID0gdmFsdWVcbiAgICBpZiAocHJvcHMub25DaGFuZ2UpIHtcbiAgICAgIHByb3BzLm9uQ2hhbmdlKGUpXG4gICAgfVxuICB9LFxuXG4gIGdldE9wdGlvblZhbHVlcyAoKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBwcm9wcyB9ID0gc1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhwcm9wcy5vcHRpb25zIHx8IHt9KVxuICB9LFxuXG4gIGdldEluZGV4Rm9yVmFsdWUgKHZhbHVlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICByZXR1cm4gcy5nZXRPcHRpb25WYWx1ZXMoKS5pbmRleE9mKHZhbHVlKVxuICB9LFxuXG4gIHJlZ2lzdGVyTm9kZSAoZWxtLCBuYW1lKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBzLm5vZGVzWyBuYW1lIF0gPSBSZWFjdERPTS5maW5kRE9NTm9kZShlbG0pXG4gIH0sXG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gSGFuZGxlXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgaGFuZGxlTGFiZWxUYXAgKGUpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCB7IHN0YXRlIH0gPSBzXG5cbiAgICBsZXQgeyB0ZXh0IH0gPSBzLm5vZGVzXG5cbiAgICBsZXQgZm9jdXNlZCA9ICFzdGF0ZS5mb2N1c2VkXG4gICAgaWYgKGZvY3VzZWQpIHtcbiAgICAgIHMubGF5b3V0KClcbiAgICAgIHRleHQuZm9jdXMoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0ZXh0LmJsdXIoKVxuICAgIH1cbiAgICBzLnNldFN0YXRlKHtcbiAgICAgIGZvY3VzZWQsXG4gICAgICBmb2N1c0luZGV4OiBzLmdldEluZGV4Rm9yVmFsdWUocy5wcm9wcy52YWx1ZSlcbiAgICB9KVxuICB9LFxuXG4gIHNldEZvY3VzIChmb2N1c2VkKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBpZiAoZm9jdXNlZCA9PT0gcy5zdGF0ZS5mb2N1c2VkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYocy5fZm9jdXNBdCl7XG4gICAgICBjb25zdCBmcm9tTGFzdEZvY3VzQXQgPSBuZXcgRGF0ZSgpICAtIHMuX2ZvY3VzQXRcbiAgICAgIGlmKGZyb21MYXN0Rm9jdXNBdCA8IDUwMCl7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cbiAgICBzLl9mb2N1c0F0ID0gbmV3IERhdGUoKVxuICAgIHMuc2V0U3RhdGUoe1xuICAgICAgZm9jdXNlZFxuICAgIH0pXG4gIH0sXG5cbiAgaGFuZGxlS2V5RG93biAoZSkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IHsgcHJvcHMgfSA9IHNcbiAgICBpZiAoIXMuc3RhdGUuZm9jdXNlZCkge1xuICAgICAgcy5zZXRTdGF0ZSh7IGZvY3VzZWQ6IHRydWUgfSlcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBzd2l0Y2ggKGUua2V5Q29kZSkge1xuICAgICAgY2FzZSAzODogLy8gVVBcbiAgICAgICAgcy5tb3ZlRm9jdXNJbmRleCgtMSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgNDA6IC8vIERPV05cbiAgICAgICAgcy5tb3ZlRm9jdXNJbmRleCgrMSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgMTM6IC8vIEVudGVyXG4gICAgICAgIHMuZW50ZXJGb2N1c2VkKGUpXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIDk6IC8vIFRhYlxuICAgICAgICBicmVha1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gICAgaWYgKHByb3BzLm9uS2V5RG93bikge1xuICAgICAgcHJvcHMub25LZXlEb3duKGUpXG4gICAgfVxuICB9LFxuXG4gIGhhbmRsZUtleVVwIChlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBwcm9wcyB9ID0gc1xuICAgIGlmIChwcm9wcy5vbktleVVwKSB7XG4gICAgICBwcm9wcy5vbktleVVwKGUpXG4gICAgfVxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcbiAgfSxcblxuICBoYW5kbGVJdGVtVGFwIChlKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBwcm9wcyB9ID0gc1xuICAgIE9iamVjdC5hc3NpZ24oZS50YXJnZXQsIHtcbiAgICAgIHZhbHVlOiBlLnRhcmdldC52YWx1ZSB8fCBlLmRhdGEgfHwgbnVsbCxcbiAgICAgIG5hbWU6IGUudGFyZ2V0Lm5hbWUgfHwgcHJvcHMubmFtZVxuICAgIH0pXG4gICAgaWYgKHByb3BzLm9uQ2hhbmdlKSB7XG4gICAgICBwcm9wcy5vbkNoYW5nZShlKVxuICAgIH1cbiAgICBzLnNldFN0YXRlKHtcbiAgICAgIGZvY3VzZWQ6IGZhbHNlLFxuICAgICAgZm9jdXNJbmRleDogcy5nZXRJbmRleEZvclZhbHVlKHMucHJvcHMudmFsdWUpXG4gICAgfSlcbiAgfSxcblxuICBoYW5kbGVDbGlja0Zvck91dHNpZGUgKGUpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIGxldCBub2RlID0gUmVhY3RET00uZmluZERPTU5vZGUocylcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBsZXQgY29udGFpbmVkID0gbm9kZS5jb250YWlucyhlLnRhcmdldClcbiAgICBpZiAoIWNvbnRhaW5lZCkge1xuICAgICAgcy5vdXRzaWRlRGlkVGFwKGUpXG4gICAgfVxuICB9LFxuXG4gIG91dHNpZGVEaWRUYXAgKGUpIHtcbiAgICBjb25zdCBzID0gdGhpc1xuICAgIHMuc2V0Rm9jdXMoZmFsc2UpXG4gIH0sXG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIEFwTGF5b3V0TWl4aW5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgZ2V0SW5pdGlhbExheW91dHMgKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsaXN0SW5uZXI6IHtcbiAgICAgICAgdHJhbnNmb3JtOiAnaW5pdGlhbCdcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgY2FsY0xheW91dHMgKCkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IHsgaW5uZXJIZWlnaHQsIGlubmVyV2lkdGggfSA9IHdpbmRvd1xuICAgIGxldCB7IGxpc3QgfSA9IHMubm9kZXNcbiAgICBpZiAoIWxpc3QpIHtcbiAgICAgIHJldHVybiB7fVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbGlzdElubmVyOiBzLl9saXN0SW5uZXJMYXlvdXQobGlzdC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgaW5uZXJXaWR0aCwgaW5uZXJIZWlnaHQpXG4gICAgfVxuICB9LFxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBQcml2YXRlXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIF9saXN0SW5uZXJMYXlvdXQgKHJlY3QsIGJvdW5kc1dpZHRoLCBib3VuZHNIZWlnaHQpIHtcbiAgICBsZXQgeCA9IG51bWNhbC5taW4oYm91bmRzV2lkdGggLSByZWN0LnJpZ2h0LCAwKVxuICAgIGxldCB5ID0gbnVtY2FsLm1pbihib3VuZHNIZWlnaHQgLSByZWN0LmJvdHRvbSwgMClcblxuICAgIGxldCBtYXhIZWlnaHQgPSBgJHtudW1jYWwubWluKGJvdW5kc0hlaWdodCwgMjgwKX1weGBcbiAgICByZXR1cm4ge1xuICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlKCR7eH1weCwgJHt5fXB4KWAsXG4gICAgICBtYXhIZWlnaHRcbiAgICB9XG4gIH1cbn0pXG5cbmV4cG9ydCB7IEFwU2VsZWN0IH1cbmV4cG9ydCBkZWZhdWx0IHdpdGhPdXRzaWRlKEFwU2VsZWN0KVxuIl19