UNPKG

matrix-react-sdk

Version:
204 lines (168 loc) 27.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _AutoHideScrollbar = _interopRequireDefault(require("./AutoHideScrollbar")); var _replaceableComponent = require("../../utils/replaceableComponent"); var _dec, _class, _class2, _temp; let IndicatorScrollbar = (_dec = (0, _replaceableComponent.replaceableComponent)("structures.IndicatorScrollbar"), _dec(_class = (_temp = _class2 = class IndicatorScrollbar extends _react.default.Component { constructor(props) { super(props); (0, _defineProperty2.default)(this, "onMouseWheel", e => { if (this.props.verticalScrollsHorizontally && this._scrollElement) { // xyThreshold is the amount of horizontal motion required for the component to // ignore the vertical delta in a scroll. Used to stop trackpads from acting in // strange ways. Should be positive. const xyThreshold = 0; // yRetention is the factor multiplied by the vertical delta to try and reduce // the harshness of the scroll behaviour. Should be a value between 0 and 1. const yRetention = 1.0; // whenever we see horizontal scrolling, assume the user is on a trackpad // for at least the next 1 minute. const now = new Date().getTime(); if (Math.abs(e.deltaX) > 0) { this._likelyTrackpadUser = true; this._checkAgainForTrackpad = now + 1 * 60 * 1000; } else { // if we haven't seen any horizontal scrolling for a while, assume // the user might have plugged in a mousewheel if (this._likelyTrackpadUser && now >= this._checkAgainForTrackpad) { this._likelyTrackpadUser = false; } } // don't mess with the horizontal scroll for trackpad users // See https://github.com/vector-im/element-web/issues/10005 if (this._likelyTrackpadUser) { return; } if (Math.abs(e.deltaX) <= xyThreshold) { // we are vertically scrolling. // HACK: We increase the amount of scroll to counteract smooth scrolling browsers. // Smooth scrolling browsers (Firefox) use the relative area to determine the scroll // amount, which means the likely small area of content results in a small amount of // movement - not what people expect. We pick arbitrary values for when to apply more // scroll, and how much to apply. On Windows 10, Chrome scrolls 100 units whereas // Firefox scrolls just 3 due to smooth scrolling. const additionalScroll = e.deltaY < 0 ? -50 : 50; // noinspection JSSuspiciousNameCombination const val = Math.abs(e.deltaY) < 25 ? e.deltaY + additionalScroll : e.deltaY; this._scrollElement.scrollLeft += val * yRetention; } } }); this._collectScroller = this._collectScroller.bind(this); this._collectScrollerComponent = this._collectScrollerComponent.bind(this); this.checkOverflow = this.checkOverflow.bind(this); this._scrollElement = null; this._autoHideScrollbar = null; this._likelyTrackpadUser = null; this._checkAgainForTrackpad = 0; // ts in milliseconds to recheck this._likelyTrackpadUser this.state = { leftIndicatorOffset: 0, rightIndicatorOffset: 0 }; } moveToOrigin() { if (!this._scrollElement) return; this._scrollElement.scrollLeft = 0; this._scrollElement.scrollTop = 0; } _collectScroller(scroller) { if (scroller && !this._scrollElement) { this._scrollElement = scroller; this._scrollElement.addEventListener("scroll", this.checkOverflow); this.checkOverflow(); } } _collectScrollerComponent(autoHideScrollbar) { this._autoHideScrollbar = autoHideScrollbar; } componentDidUpdate(prevProps) { const prevLen = prevProps && prevProps.children && prevProps.children.length || 0; const curLen = this.props.children && this.props.children.length || 0; // check overflow only if amount of children changes. // if we don't guard here, we end up with an infinite // render > componentDidUpdate > checkOverflow > setState > render loop if (prevLen !== curLen) { this.checkOverflow(); } } componentDidMount() { this.checkOverflow(); } checkOverflow() { const hasTopOverflow = this._scrollElement.scrollTop > 0; const hasBottomOverflow = this._scrollElement.scrollHeight > this._scrollElement.scrollTop + this._scrollElement.clientHeight; const hasLeftOverflow = this._scrollElement.scrollLeft > 0; const hasRightOverflow = this._scrollElement.scrollWidth > this._scrollElement.scrollLeft + this._scrollElement.clientWidth; if (hasTopOverflow) { this._scrollElement.classList.add("mx_IndicatorScrollbar_topOverflow"); } else { this._scrollElement.classList.remove("mx_IndicatorScrollbar_topOverflow"); } if (hasBottomOverflow) { this._scrollElement.classList.add("mx_IndicatorScrollbar_bottomOverflow"); } else { this._scrollElement.classList.remove("mx_IndicatorScrollbar_bottomOverflow"); } if (hasLeftOverflow) { this._scrollElement.classList.add("mx_IndicatorScrollbar_leftOverflow"); } else { this._scrollElement.classList.remove("mx_IndicatorScrollbar_leftOverflow"); } if (hasRightOverflow) { this._scrollElement.classList.add("mx_IndicatorScrollbar_rightOverflow"); } else { this._scrollElement.classList.remove("mx_IndicatorScrollbar_rightOverflow"); } if (this.props.trackHorizontalOverflow) { this.setState({ // Offset from absolute position of the container leftIndicatorOffset: hasLeftOverflow ? `${this._scrollElement.scrollLeft}px` : '0', // Negative because we're coming from the right rightIndicatorOffset: hasRightOverflow ? `-${this._scrollElement.scrollLeft}px` : '0' }); } } getScrollTop() { return this._autoHideScrollbar.getScrollTop(); } componentWillUnmount() { if (this._scrollElement) { this._scrollElement.removeEventListener("scroll", this.checkOverflow); } } render() { const leftIndicatorStyle = { left: this.state.leftIndicatorOffset }; const rightIndicatorStyle = { right: this.state.rightIndicatorOffset }; const leftOverflowIndicator = this.props.trackHorizontalOverflow ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_IndicatorScrollbar_leftOverflowIndicator", style: leftIndicatorStyle }) : null; const rightOverflowIndicator = this.props.trackHorizontalOverflow ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_IndicatorScrollbar_rightOverflowIndicator", style: rightIndicatorStyle }) : null; return /*#__PURE__*/_react.default.createElement(_AutoHideScrollbar.default, (0, _extends2.default)({ ref: this._collectScrollerComponent, wrappedRef: this._collectScroller, onWheel: this.onMouseWheel }, this.props), leftOverflowIndicator, this.props.children, rightOverflowIndicator); } }, (0, _defineProperty2.default)(_class2, "propTypes", { // If true, the scrollbar will append mx_IndicatorScrollbar_leftOverflowIndicator // and mx_IndicatorScrollbar_rightOverflowIndicator elements to the list for positioning // by the parent element. trackHorizontalOverflow: _propTypes.default.bool, // If true, when the user tries to use their mouse wheel in the component it will // scroll horizontally rather than vertically. This should only be used on components // with no vertical scroll opportunity. verticalScrollsHorizontally: _propTypes.default.bool }), _temp)) || _class); exports.default = IndicatorScrollbar; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3N0cnVjdHVyZXMvSW5kaWNhdG9yU2Nyb2xsYmFyLmpzIl0sIm5hbWVzIjpbIkluZGljYXRvclNjcm9sbGJhciIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsImUiLCJ2ZXJ0aWNhbFNjcm9sbHNIb3Jpem9udGFsbHkiLCJfc2Nyb2xsRWxlbWVudCIsInh5VGhyZXNob2xkIiwieVJldGVudGlvbiIsIm5vdyIsIkRhdGUiLCJnZXRUaW1lIiwiTWF0aCIsImFicyIsImRlbHRhWCIsIl9saWtlbHlUcmFja3BhZFVzZXIiLCJfY2hlY2tBZ2FpbkZvclRyYWNrcGFkIiwiYWRkaXRpb25hbFNjcm9sbCIsImRlbHRhWSIsInZhbCIsInNjcm9sbExlZnQiLCJfY29sbGVjdFNjcm9sbGVyIiwiYmluZCIsIl9jb2xsZWN0U2Nyb2xsZXJDb21wb25lbnQiLCJjaGVja092ZXJmbG93IiwiX2F1dG9IaWRlU2Nyb2xsYmFyIiwic3RhdGUiLCJsZWZ0SW5kaWNhdG9yT2Zmc2V0IiwicmlnaHRJbmRpY2F0b3JPZmZzZXQiLCJtb3ZlVG9PcmlnaW4iLCJzY3JvbGxUb3AiLCJzY3JvbGxlciIsImFkZEV2ZW50TGlzdGVuZXIiLCJhdXRvSGlkZVNjcm9sbGJhciIsImNvbXBvbmVudERpZFVwZGF0ZSIsInByZXZQcm9wcyIsInByZXZMZW4iLCJjaGlsZHJlbiIsImxlbmd0aCIsImN1ckxlbiIsImNvbXBvbmVudERpZE1vdW50IiwiaGFzVG9wT3ZlcmZsb3ciLCJoYXNCb3R0b21PdmVyZmxvdyIsInNjcm9sbEhlaWdodCIsImNsaWVudEhlaWdodCIsImhhc0xlZnRPdmVyZmxvdyIsImhhc1JpZ2h0T3ZlcmZsb3ciLCJzY3JvbGxXaWR0aCIsImNsaWVudFdpZHRoIiwiY2xhc3NMaXN0IiwiYWRkIiwicmVtb3ZlIiwidHJhY2tIb3Jpem9udGFsT3ZlcmZsb3ciLCJzZXRTdGF0ZSIsImdldFNjcm9sbFRvcCIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsInJlbmRlciIsImxlZnRJbmRpY2F0b3JTdHlsZSIsImxlZnQiLCJyaWdodEluZGljYXRvclN0eWxlIiwicmlnaHQiLCJsZWZ0T3ZlcmZsb3dJbmRpY2F0b3IiLCJyaWdodE92ZXJmbG93SW5kaWNhdG9yIiwib25Nb3VzZVdoZWVsIiwiUHJvcFR5cGVzIiwiYm9vbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQWdCQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztJQUdxQkEsa0IsV0FEcEIsZ0RBQXFCLCtCQUFyQixDLG1DQUFELE1BQ3FCQSxrQkFEckIsU0FDZ0RDLGVBQU1DLFNBRHRELENBQ2dFO0FBYTVEQyxFQUFBQSxXQUFXLENBQUNDLEtBQUQsRUFBUTtBQUNmLFVBQU1BLEtBQU47QUFEZSx3REFxR0hDLENBQUQsSUFBTztBQUNsQixVQUFJLEtBQUtELEtBQUwsQ0FBV0UsMkJBQVgsSUFBMEMsS0FBS0MsY0FBbkQsRUFBbUU7QUFDL0Q7QUFDQTtBQUNBO0FBQ0EsY0FBTUMsV0FBVyxHQUFHLENBQXBCLENBSitELENBTS9EO0FBQ0E7O0FBQ0EsY0FBTUMsVUFBVSxHQUFHLEdBQW5CLENBUitELENBVS9EO0FBQ0E7O0FBQ0EsY0FBTUMsR0FBRyxHQUFHLElBQUlDLElBQUosR0FBV0MsT0FBWCxFQUFaOztBQUNBLFlBQUlDLElBQUksQ0FBQ0MsR0FBTCxDQUFTVCxDQUFDLENBQUNVLE1BQVgsSUFBcUIsQ0FBekIsRUFBNEI7QUFDeEIsZUFBS0MsbUJBQUwsR0FBMkIsSUFBM0I7QUFDQSxlQUFLQyxzQkFBTCxHQUE4QlAsR0FBRyxHQUFJLElBQUksRUFBSixHQUFTLElBQTlDO0FBQ0gsU0FIRCxNQUdPO0FBQ0g7QUFDQTtBQUNBLGNBQUksS0FBS00sbUJBQUwsSUFBNEJOLEdBQUcsSUFBSSxLQUFLTyxzQkFBNUMsRUFBb0U7QUFDaEUsaUJBQUtELG1CQUFMLEdBQTJCLEtBQTNCO0FBQ0g7QUFDSixTQXRCOEQsQ0F3Qi9EO0FB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RUosTUFBQSxVQUFVLEVBQUUsS0FBS0YsZ0JBRmI7QUFHSixNQUFBLE9BQU8sRUFBRSxLQUFLMkM7QUFIVixPQUlBLEtBQUs3RCxLQUpMLEdBTUYyRCxxQkFORSxFQU9GLEtBQUszRCxLQUFMLENBQVdrQyxRQVBULEVBUUYwQixzQkFSRSxDQUFSO0FBVUg7O0FBcEwyRCxDLHNEQUN6QztBQUNmO0FBQ0E7QUFDQTtBQUNBWCxFQUFBQSx1QkFBdUIsRUFBRWEsbUJBQVVDLElBSnBCO0FBTWY7QUFDQTtBQUNBO0FBQ0E3RCxFQUFBQSwyQkFBMkIsRUFBRTRELG1CQUFVQztBQVR4QixDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE4IE5ldyBWZWN0b3IgTHRkXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tIFwicHJvcC10eXBlc1wiO1xuaW1wb3J0IEF1dG9IaWRlU2Nyb2xsYmFyIGZyb20gXCIuL0F1dG9IaWRlU2Nyb2xsYmFyXCI7XG5pbXBvcnQge3JlcGxhY2VhYmxlQ29tcG9uZW50fSBmcm9tIFwiLi4vLi4vdXRpbHMvcmVwbGFjZWFibGVDb21wb25lbnRcIjtcblxuQHJlcGxhY2VhYmxlQ29tcG9uZW50KFwic3RydWN0dXJlcy5JbmRpY2F0b3JTY3JvbGxiYXJcIilcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEluZGljYXRvclNjcm9sbGJhciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gICAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICAgICAgLy8gSWYgdHJ1ZSwgdGhlIHNjcm9sbGJhciB3aWxsIGFwcGVuZCBteF9JbmRpY2F0b3JTY3JvbGxiYXJfbGVmdE92ZXJmbG93SW5kaWNhdG9yXG4gICAgICAgIC8vIGFuZCBteF9JbmRpY2F0b3JTY3JvbGxiYXJfcmlnaHRPdmVyZmxvd0luZGljYXRvciBlbGVtZW50cyB0byB0aGUgbGlzdCBmb3IgcG9zaXRpb25pbmdcbiAgICAgICAgLy8gYnkgdGhlIHBhcmVudCBlbGVtZW50LlxuICAgICAgICB0cmFja0hvcml6b250YWxPdmVyZmxvdzogUHJvcFR5cGVzLmJvb2wsXG5cbiAgICAgICAgLy8gSWYgdHJ1ZSwgd2hlbiB0aGUgdXNlciB0cmllcyB0byB1c2UgdGhlaXIgbW91c2Ugd2hlZWwgaW4gdGhlIGNvbXBvbmVudCBpdCB3aWxsXG4gICAgICAgIC8vIHNjcm9sbCBob3Jpem9udGFsbHkgcmF0aGVyIHRoYW4gdmVydGljYWxseS4gVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIG9uIGNvbXBvbmVudHNcbiAgICAgICAgLy8gd2l0aCBubyB2ZXJ0aWNhbCBzY3JvbGwgb3Bwb3J0dW5pdHkuXG4gICAgICAgIHZlcnRpY2FsU2Nyb2xsc0hvcml6b250YWxseTogUHJvcFR5cGVzLmJvb2wsXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcbiAgICAgICAgdGhpcy5fY29sbGVjdFNjcm9sbGVyID0gdGhpcy5fY29sbGVjdFNjcm9sbGVyLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuX2NvbGxlY3RTY3JvbGxlckNvbXBvbmVudCA9IHRoaXMuX2NvbGxlY3RTY3JvbGxlckNvbXBvbmVudC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmNoZWNrT3ZlcmZsb3cgPSB0aGlzLmNoZWNrT3ZlcmZsb3cuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2F1dG9IaWRlU2Nyb2xsYmFyID0gbnVsbDtcbiAgICAgICAgdGhpcy5fbGlrZWx5VHJhY2twYWRVc2VyID0gbnVsbDtcbiAgICAgICAgdGhpcy5fY2hlY2tBZ2FpbkZvclRyYWNrcGFkID0gMDsgLy8gdHMgaW4gbWlsbGlzZWNvbmRzIHRvIHJlY2hlY2sgdGhpcy5fbGlrZWx5VHJhY2twYWRVc2VyXG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGxlZnRJbmRpY2F0b3JPZmZzZXQ6IDAsXG4gICAgICAgICAgICByaWdodEluZGljYXRvck9mZnNldDogMCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBtb3ZlVG9PcmlnaW4oKSB7XG4gICAgICAgIGlmICghdGhpcy5fc2Nyb2xsRWxlbWVudCkgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuX3Njcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCA9IDA7XG4gICAgICAgIHRoaXMuX3Njcm9sbEVsZW1lbnQuc2Nyb2xsVG9wID0gMDtcbiAgICB9XG5cbiAgICBfY29sbGVjdFNjcm9sbGVyKHNjcm9sbGVyKSB7XG4gICAgICAgIGlmIChzY3JvbGxlciAmJiAhdGhpcy5fc2Nyb2xsRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudCA9IHNjcm9sbGVyO1xuICAgICAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMuY2hlY2tPdmVyZmxvdyk7XG4gICAgICAgICAgICB0aGlzLmNoZWNrT3ZlcmZsb3coKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9jb2xsZWN0U2Nyb2xsZXJDb21wb25lbnQoYXV0b0hpZGVTY3JvbGxiYXIpIHtcbiAgICAgICAgdGhpcy5fYXV0b0hpZGVTY3JvbGxiYXIgPSBhdXRvSGlkZVNjcm9sbGJhcjtcbiAgICB9XG5cblxuICAgIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgICAgY29uc3QgcHJldkxlbiA9IHByZXZQcm9wcyAmJiBwcmV2UHJvcHMuY2hpbGRyZW4gJiYgcHJldlByb3BzLmNoaWxkcmVuLmxlbmd0aCB8fCAwO1xuICAgICAgICBjb25zdCBjdXJMZW4gPSB0aGlzLnByb3BzLmNoaWxkcmVuICYmIHRoaXMucHJvcHMuY2hpbGRyZW4ubGVuZ3RoIHx8IDA7XG4gICAgICAgIC8vIGNoZWNrIG92ZXJmbG93IG9ubHkgaWYgYW1vdW50IG9mIGNoaWxkcmVuIGNoYW5nZXMuXG4gICAgICAgIC8vIGlmIHdlIGRvbid0IGd1YXJkIGhlcmUsIHdlIGVuZCB1cCB3aXRoIGFuIGluZmluaXRlXG4gICAgICAgIC8vIHJlbmRlciA+IGNvbXBvbmVudERpZFVwZGF0ZSA+IGNoZWNrT3ZlcmZsb3cgPiBzZXRTdGF0ZSA+IHJlbmRlciBsb29wXG4gICAgICAgIGlmIChwcmV2TGVuICE9PSBjdXJMZW4pIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tPdmVyZmxvdygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuY2hlY2tPdmVyZmxvdygpO1xuICAgIH1cblxuICAgIGNoZWNrT3ZlcmZsb3coKSB7XG4gICAgICAgIGNvbnN0IGhhc1RvcE92ZXJmbG93ID0gdGhpcy5fc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgPiAwO1xuICAgICAgICBjb25zdCBoYXNCb3R0b21PdmVyZmxvdyA9IHRoaXMuX3Njcm9sbEVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID5cbiAgICAgICAgICAgICh0aGlzLl9zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCArIHRoaXMuX3Njcm9sbEVsZW1lbnQuY2xpZW50SGVpZ2h0KTtcbiAgICAgICAgY29uc3QgaGFzTGVmdE92ZXJmbG93ID0gdGhpcy5fc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0ID4gMDtcbiAgICAgICAgY29uc3QgaGFzUmlnaHRPdmVyZmxvdyA9IHRoaXMuX3Njcm9sbEVsZW1lbnQuc2Nyb2xsV2lkdGggPlxuICAgICAgICAgICAgKHRoaXMuX3Njcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCArIHRoaXMuX3Njcm9sbEVsZW1lbnQuY2xpZW50V2lkdGgpO1xuXG4gICAgICAgIGlmIChoYXNUb3BPdmVyZmxvdykge1xuICAgICAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QuYWRkKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX3RvcE92ZXJmbG93XCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX3RvcE92ZXJmbG93XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNCb3R0b21PdmVyZmxvdykge1xuICAgICAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QuYWRkKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX2JvdHRvbU92ZXJmbG93XCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX2JvdHRvbU92ZXJmbG93XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNMZWZ0T3ZlcmZsb3cpIHtcbiAgICAgICAgICAgIHRoaXMuX3Njcm9sbEVsZW1lbnQuY2xhc3NMaXN0LmFkZChcIm14X0luZGljYXRvclNjcm9sbGJhcl9sZWZ0T3ZlcmZsb3dcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zY3JvbGxFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCJteF9JbmRpY2F0b3JTY3JvbGxiYXJfbGVmdE92ZXJmbG93XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNSaWdodE92ZXJmbG93KSB7XG4gICAgICAgICAgICB0aGlzLl9zY3JvbGxFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJteF9JbmRpY2F0b3JTY3JvbGxiYXJfcmlnaHRPdmVyZmxvd1wiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3Njcm9sbEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcIm14X0luZGljYXRvclNjcm9sbGJhcl9yaWdodE92ZXJmbG93XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMudHJhY2tIb3Jpem9udGFsT3ZlcmZsb3cpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIC8vIE9mZnNldCBmcm9tIGFic29sdXRlIHBvc2l0aW9uIG9mIHRoZSBjb250YWluZXJcbiAgICAgICAgICAgICAgICBsZWZ0SW5kaWNhdG9yT2Zmc2V0OiBoYXNMZWZ0T3ZlcmZsb3cgPyBgJHt0aGlzLl9zY3JvbGxFbGVtZW50LnNjcm9sbExlZnR9cHhgIDogJzAnLFxuXG4gICAgICAgICAgICAgICAgLy8gTmVnYXRpdmUgYmVjYXVzZSB3ZSdyZSBjb21pbmcgZnJvbSB0aGUgcmlnaHRcbiAgICAgICAgICAgICAgICByaWdodEluZGljYXRvck9mZnNldDogaGFzUmlnaHRPdmVyZmxvdyA/IGAtJHt0aGlzLl9zY3JvbGxFbGVtZW50LnNjcm9sbExlZnR9cHhgIDogJzAnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRTY3JvbGxUb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hdXRvSGlkZVNjcm9sbGJhci5nZXRTY3JvbGxUb3AoKTtcbiAgICB9XG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Njcm9sbEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX3Njcm9sbEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLmNoZWNrT3ZlcmZsb3cpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Nb3VzZVdoZWVsID0gKGUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMudmVydGljYWxTY3JvbGxzSG9yaXpvbnRhbGx5ICYmIHRoaXMuX3Njcm9sbEVsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIHh5VGhyZXNob2xkIGlzIHRoZSBhbW91bnQgb2YgaG9yaXpvbnRhbCBtb3Rpb24gcmVxdWlyZWQgZm9yIHRoZSBjb21wb25lbnQgdG9cbiAgICAgICAgICAgIC8vIGlnbm9yZSB0aGUgdmVydGljYWwgZGVsdGEgaW4gYSBzY3JvbGwuIFVzZWQgdG8gc3RvcCB0cmFja3BhZHMgZnJvbSBhY3RpbmcgaW5cbiAgICAgICAgICAgIC8vIHN0cmFuZ2Ugd2F5cy4gU2hvdWxkIGJlIHBvc2l0aXZlLlxuICAgICAgICAgICAgY29uc3QgeHlUaHJlc2hvbGQgPSAwO1xuXG4gICAgICAgICAgICAvLyB5UmV0ZW50aW9uIGlzIHRoZSBmYWN0b3IgbXVsdGlwbGllZCBieSB0aGUgdmVydGljYWwgZGVsdGEgdG8gdHJ5IGFuZCByZWR1Y2VcbiAgICAgICAgICAgIC8vIHRoZSBoYXJzaG5lc3Mgb2YgdGhlIHNjcm9sbCBiZWhhdmlvdXIuIFNob3VsZCBiZSBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMS5cbiAgICAgICAgICAgIGNvbnN0IHlSZXRlbnRpb24gPSAxLjA7XG5cbiAgICAgICAgICAgIC8vIHdoZW5ldmVyIHdlIHNlZSBob3Jpem9udGFsIHNjcm9sbGluZywgYXNzdW1lIHRoZSB1c2VyIGlzIG9uIGEgdHJhY2twYWRcbiAgICAgICAgICAgIC8vIGZvciBhdCBsZWFzdCB0aGUgbmV4dCAxIG1pbnV0ZS5cbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKGUuZGVsdGFYKSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9saWtlbHlUcmFja3BhZFVzZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrQWdhaW5Gb3JUcmFja3BhZCA9IG5vdyArICgxICogNjAgKiAxMDAwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZW4ndCBzZWVuIGFueSBob3Jpem9udGFsIHNjcm9sbGluZyBmb3IgYSB3aGlsZSwgYXNzdW1lXG4gICAgICAgICAgICAgICAgLy8gdGhlIHVzZXIgbWlnaHQgaGF2ZSBwbHVnZ2VkIGluIGEgbW91c2V3aGVlbFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9saWtlbHlUcmFja3BhZFVzZXIgJiYgbm93ID49IHRoaXMuX2NoZWNrQWdhaW5Gb3JUcmFja3BhZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9saWtlbHlUcmFja3BhZFVzZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGRvbid0IG1lc3Mgd2l0aCB0aGUgaG9yaXpvbnRhbCBzY3JvbGwgZm9yIHRyYWNrcGFkIHVzZXJzXG4gICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3ZlY3Rvci1pbS9lbGVtZW50LXdlYi9pc3N1ZXMvMTAwMDVcbiAgICAgICAgICAgIGlmICh0aGlzLl9saWtlbHlUcmFja3BhZFVzZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhlLmRlbHRhWCkgPD0geHlUaHJlc2hvbGQpIHsgLy8gd2UgYXJlIHZlcnRpY2FsbHkgc2Nyb2xsaW5nLlxuICAgICAgICAgICAgICAgIC8vIEhBQ0s6IFdlIGluY3JlYXNlIHRoZSBhbW91bnQgb2Ygc2Nyb2xsIHRvIGNvdW50ZXJhY3Qgc21vb3RoIHNjcm9sbGluZyBicm93c2Vycy5cbiAgICAgICAgICAgICAgICAvLyBTbW9vdGggc2Nyb2xsaW5nIGJyb3dzZXJzIChGaXJlZm94KSB1c2UgdGhlIHJlbGF0aXZlIGFyZWEgdG8gZGV0ZXJtaW5lIHRoZSBzY3JvbGxcbiAgICAgICAgICAgICAgICAvLyBhbW91bnQsIHdoaWNoIG1lYW5zIHRoZSBsaWtlbHkgc21hbGwgYXJlYSBvZiBjb250ZW50IHJlc3VsdHMgaW4gYSBzbWFsbCBhbW91bnQgb2ZcbiAgICAgICAgICAgICAgICAvLyBtb3ZlbWVudCAtIG5vdCB3aGF0IHBlb3BsZSBleHBlY3QuIFdlIHBpY2sgYXJiaXRyYXJ5IHZhbHVlcyBmb3Igd2hlbiB0byBhcHBseSBtb3JlXG4gICAgICAgICAgICAgICAgLy8gc2Nyb2xsLCBhbmQgaG93IG11Y2ggdG8gYXBwbHkuIE9uIFdpbmRvd3MgMTAsIENocm9tZSBzY3JvbGxzIDEwMCB1bml0cyB3aGVyZWFzXG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveCBzY3JvbGxzIGp1c3QgMyBkdWUgdG8gc21vb3RoIHNjcm9sbGluZy5cblxuICAgICAgICAgICAgICAgIGNvbnN0IGFkZGl0aW9uYWxTY3JvbGwgPSBlLmRlbHRhWSA8IDAgPyAtNTAgOiA1MDtcblxuICAgICAgICAgICAgICAgIC8vIG5vaW5zcGVjdGlvbiBKU1N1c3BpY2lvdXNOYW1lQ29tYmluYXRpb25cbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSBNYXRoLmFicyhlLmRlbHRhWSkgPCAyNSA/IChlLmRlbHRhWSArIGFkZGl0aW9uYWxTY3JvbGwpIDogZS5kZWx0YVk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0ICs9IHZhbCAqIHlSZXRlbnRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCBsZWZ0SW5kaWNhdG9yU3R5bGUgPSB7bGVmdDogdGhpcy5zdGF0ZS5sZWZ0SW5kaWNhdG9yT2Zmc2V0fTtcbiAgICAgICAgY29uc3QgcmlnaHRJbmRpY2F0b3JTdHlsZSA9IHtyaWdodDogdGhpcy5zdGF0ZS5yaWdodEluZGljYXRvck9mZnNldH07XG4gICAgICAgIGNvbnN0IGxlZnRPdmVyZmxvd0luZGljYXRvciA9IHRoaXMucHJvcHMudHJhY2tIb3Jpem9udGFsT3ZlcmZsb3dcbiAgICAgICAgICAgID8gPGRpdiBjbGFzc05hbWU9XCJteF9JbmRpY2F0b3JTY3JvbGxiYXJfbGVmdE92ZXJmbG93SW5kaWNhdG9yXCIgc3R5bGU9e2xlZnRJbmRpY2F0b3JTdHlsZX0gLz4gOiBudWxsO1xuICAgICAgICBjb25zdCByaWdodE92ZXJmbG93SW5kaWNhdG9yID0gdGhpcy5wcm9wcy50cmFja0hvcml6b250YWxPdmVyZmxvd1xuICAgICAgICAgICAgPyA8ZGl2IGNsYXNzTmFtZT1cIm14X0luZGljYXRvclNjcm9sbGJhcl9yaWdodE92ZXJmbG93SW5kaWNhdG9yXCIgc3R5bGU9e3JpZ2h0SW5kaWNhdG9yU3R5bGV9IC8+IDogbnVsbDtcblxuICAgICAgICByZXR1cm4gKDxBdXRvSGlkZVNjcm9sbGJhclxuICAgICAgICAgICAgcmVmPXt0aGlzLl9jb2xsZWN0U2Nyb2xsZXJDb21wb25lbnR9XG4gICAgICAgICAgICB3cmFwcGVkUmVmPXt0aGlzLl9jb2xsZWN0U2Nyb2xsZXJ9XG4gICAgICAgICAgICBvbldoZWVsPXt0aGlzLm9uTW91c2VXaGVlbH1cbiAgICAgICAgICAgIHsuLi50aGlzLnByb3BzfVxuICAgICAgICA+XG4gICAgICAgICAgICB7IGxlZnRPdmVyZmxvd0luZGljYXRvciB9XG4gICAgICAgICAgICB7IHRoaXMucHJvcHMuY2hpbGRyZW4gfVxuICAgICAgICAgICAgeyByaWdodE92ZXJmbG93SW5kaWNhdG9yIH1cbiAgICAgICAgPC9BdXRvSGlkZVNjcm9sbGJhcj4pO1xuICAgIH1cbn1cbiJdfQ==