UNPKG

matrix-react-sdk

Version:
180 lines (172 loc) 30.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 _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _AutoHideScrollbar = _interopRequireDefault(require("./AutoHideScrollbar")); var _UIStore = _interopRequireWildcard(require("../../stores/UIStore")); const _excluded = ["children", "trackHorizontalOverflow", "verticalScrollsHorizontally"]; /* Copyright 2018-2024 New Vector Ltd. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } class IndicatorScrollbar extends _react.default.Component { // ts in milliseconds to recheck this._likelyTrackpadUser constructor(props) { super(props); (0, _defineProperty2.default)(this, "autoHideScrollbar", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "scrollElement", void 0); (0, _defineProperty2.default)(this, "likelyTrackpadUser", null); (0, _defineProperty2.default)(this, "checkAgainForTrackpad", 0); (0, _defineProperty2.default)(this, "collectScroller", scroller => { this.props.wrappedRef?.(scroller); if (scroller && !this.scrollElement) { this.scrollElement = scroller; // Using the passive option to not block the main thread // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners this.scrollElement.addEventListener("scroll", this.checkOverflow, { passive: true }); this.checkOverflow(); } }); (0, _defineProperty2.default)(this, "checkOverflow", () => { if (!this.scrollElement) return; 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" }); } }); (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.state = { leftIndicatorOffset: "0", rightIndicatorOffset: "0" }; } componentDidUpdate(prevProps) { const prevLen = _react.default.Children.count(prevProps.children); const curLen = _react.default.Children.count(this.props.children); // 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(); _UIStore.default.instance.on(_UIStore.UI_EVENTS.Resize, this.checkOverflow); } componentWillUnmount() { this.scrollElement?.removeEventListener("scroll", this.checkOverflow); _UIStore.default.instance.off(_UIStore.UI_EVENTS.Resize, this.checkOverflow); } render() { // eslint-disable-next-line @typescript-eslint/no-unused-vars const _this$props = this.props, { children, trackHorizontalOverflow, verticalScrollsHorizontally } = _this$props, otherProps = (0, _objectWithoutProperties2.default)(_this$props, _excluded); const leftIndicatorStyle = { left: this.state.leftIndicatorOffset }; const rightIndicatorStyle = { right: this.state.rightIndicatorOffset }; const leftOverflowIndicator = trackHorizontalOverflow ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_IndicatorScrollbar_leftOverflowIndicator", style: leftIndicatorStyle }) : null; const rightOverflowIndicator = trackHorizontalOverflow ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_IndicatorScrollbar_rightOverflowIndicator", style: rightIndicatorStyle }) : null; return /*#__PURE__*/_react.default.createElement(_AutoHideScrollbar.default, (0, _extends2.default)({}, otherProps, { ref: this.autoHideScrollbar, wrappedRef: this.collectScroller, onWheel: this.onMouseWheel }), leftOverflowIndicator, children, rightOverflowIndicator); } } exports.default = IndicatorScrollbar; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfQXV0b0hpZGVTY3JvbGxiYXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX1VJU3RvcmUiLCJfZXhjbHVkZWQiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJJbmRpY2F0b3JTY3JvbGxiYXIiLCJSZWFjdCIsIkNvbXBvbmVudCIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJfZGVmaW5lUHJvcGVydHkyIiwiY3JlYXRlUmVmIiwic2Nyb2xsZXIiLCJ3cmFwcGVkUmVmIiwic2Nyb2xsRWxlbWVudCIsImFkZEV2ZW50TGlzdGVuZXIiLCJjaGVja092ZXJmbG93IiwicGFzc2l2ZSIsImhhc1RvcE92ZXJmbG93Iiwic2Nyb2xsVG9wIiwiaGFzQm90dG9tT3ZlcmZsb3ciLCJzY3JvbGxIZWlnaHQiLCJjbGllbnRIZWlnaHQiLCJoYXNMZWZ0T3ZlcmZsb3ciLCJzY3JvbGxMZWZ0IiwiaGFzUmlnaHRPdmVyZmxvdyIsInNjcm9sbFdpZHRoIiwiY2xpZW50V2lkdGgiLCJjbGFzc0xpc3QiLCJhZGQiLCJyZW1vdmUiLCJ0cmFja0hvcml6b250YWxPdmVyZmxvdyIsInNldFN0YXRlIiwibGVmdEluZGljYXRvck9mZnNldCIsInJpZ2h0SW5kaWNhdG9yT2Zmc2V0IiwidmVydGljYWxTY3JvbGxzSG9yaXpvbnRhbGx5IiwieHlUaHJlc2hvbGQiLCJ5UmV0ZW50aW9uIiwibm93IiwiRGF0ZSIsImdldFRpbWUiLCJNYXRoIiwiYWJzIiwiZGVsdGFYIiwibGlrZWx5VHJhY2twYWRVc2VyIiwiY2hlY2tBZ2FpbkZvclRyYWNrcGFkIiwiYWRkaXRpb25hbFNjcm9sbCIsImRlbHRhWSIsInZhbCIsInN0YXRlIiwiY29tcG9uZW50RGlkVXBkYXRlIiwicHJldlByb3BzIiwicHJldkxlbiIsIkNoaWxkcmVuIiwiY291bnQiLCJjaGlsZHJlbiIsImN1ckxlbiIsImNvbXBvbmVudERpZE1vdW50IiwiVUlTdG9yZSIsImluc3RhbmNlIiwib24iLCJVSV9FVkVOVFMiLCJSZXNpemUiLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJvZmYiLCJyZW5kZXIiLCJfdGhpcyRwcm9wcyIsIm90aGVyUHJvcHMiLCJfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMyIiwibGVmdEluZGljYXRvclN0eWxlIiwibGVmdCIsInJpZ2h0SW5kaWNhdG9yU3R5bGUiLCJyaWdodCIsImxlZnRPdmVyZmxvd0luZGljYXRvciIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJzdHlsZSIsInJpZ2h0T3ZlcmZsb3dJbmRpY2F0b3IiLCJfZXh0ZW5kczIiLCJyZWYiLCJhdXRvSGlkZVNjcm9sbGJhciIsImNvbGxlY3RTY3JvbGxlciIsIm9uV2hlZWwiLCJvbk1vdXNlV2hlZWwiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvc3RydWN0dXJlcy9JbmRpY2F0b3JTY3JvbGxiYXIudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAxOC0yMDI0IE5ldyBWZWN0b3IgTHRkLlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHsgY3JlYXRlUmVmIH0gZnJvbSBcInJlYWN0XCI7XG5cbmltcG9ydCBBdXRvSGlkZVNjcm9sbGJhciwgeyBJUHJvcHMgYXMgQXV0b0hpZGVTY3JvbGxiYXJQcm9wcyB9IGZyb20gXCIuL0F1dG9IaWRlU2Nyb2xsYmFyXCI7XG5pbXBvcnQgVUlTdG9yZSwgeyBVSV9FVkVOVFMgfSBmcm9tIFwiLi4vLi4vc3RvcmVzL1VJU3RvcmVcIjtcblxuZXhwb3J0IHR5cGUgSVByb3BzPFQgZXh0ZW5kcyBrZXlvZiBKU1guSW50cmluc2ljRWxlbWVudHM+ID0gT21pdDxBdXRvSGlkZVNjcm9sbGJhclByb3BzPFQ+LCBcIm9uV2hlZWxcIiB8IFwiZWxlbWVudFwiPiAmIHtcbiAgICBlbGVtZW50PzogVDtcbiAgICAvLyBJZiB0cnVlLCB0aGUgc2Nyb2xsYmFyIHdpbGwgYXBwZW5kIG14X0luZGljYXRvclNjcm9sbGJhcl9sZWZ0T3ZlcmZsb3dJbmRpY2F0b3JcbiAgICAvLyBhbmQgbXhfSW5kaWNhdG9yU2Nyb2xsYmFyX3JpZ2h0T3ZlcmZsb3dJbmRpY2F0b3IgZWxlbWVudHMgdG8gdGhlIGxpc3QgZm9yIHBvc2l0aW9uaW5nXG4gICAgLy8gYnkgdGhlIHBhcmVudCBlbGVtZW50LlxuICAgIHRyYWNrSG9yaXpvbnRhbE92ZXJmbG93PzogYm9vbGVhbjtcblxuICAgIC8vIElmIHRydWUsIHdoZW4gdGhlIHVzZXIgdHJpZXMgdG8gdXNlIHRoZWlyIG1vdXNlIHdoZWVsIGluIHRoZSBjb21wb25lbnQgaXQgd2lsbFxuICAgIC8vIHNjcm9sbCBob3Jpem9udGFsbHkgcmF0aGVyIHRoYW4gdmVydGljYWxseS4gVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIG9uIGNvbXBvbmVudHNcbiAgICAvLyB3aXRoIG5vIHZlcnRpY2FsIHNjcm9sbCBvcHBvcnR1bml0eS5cbiAgICB2ZXJ0aWNhbFNjcm9sbHNIb3Jpem9udGFsbHk/OiBib29sZWFuO1xuXG4gICAgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZTtcbn07XG5cbmludGVyZmFjZSBJU3RhdGUge1xuICAgIGxlZnRJbmRpY2F0b3JPZmZzZXQ6IHN0cmluZztcbiAgICByaWdodEluZGljYXRvck9mZnNldDogc3RyaW5nO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbmRpY2F0b3JTY3JvbGxiYXI8VCBleHRlbmRzIGtleW9mIEpTWC5JbnRyaW5zaWNFbGVtZW50cz4gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8XG4gICAgSVByb3BzPFQ+LFxuICAgIElTdGF0ZVxuPiB7XG4gICAgcHJpdmF0ZSBhdXRvSGlkZVNjcm9sbGJhciA9IGNyZWF0ZVJlZjxBdXRvSGlkZVNjcm9sbGJhcjxhbnk+PigpO1xuICAgIHByaXZhdGUgc2Nyb2xsRWxlbWVudD86IEhUTUxEaXZFbGVtZW50O1xuICAgIHByaXZhdGUgbGlrZWx5VHJhY2twYWRVc2VyOiBib29sZWFuIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBjaGVja0FnYWluRm9yVHJhY2twYWQgPSAwOyAvLyB0cyBpbiBtaWxsaXNlY29uZHMgdG8gcmVjaGVjayB0aGlzLl9saWtlbHlUcmFja3BhZFVzZXJcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczogSVByb3BzPFQ+KSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgbGVmdEluZGljYXRvck9mZnNldDogXCIwXCIsXG4gICAgICAgICAgICByaWdodEluZGljYXRvck9mZnNldDogXCIwXCIsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb2xsZWN0U2Nyb2xsZXIgPSAoc2Nyb2xsZXI6IEhUTUxEaXZFbGVtZW50KTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMucHJvcHMud3JhcHBlZFJlZj8uKHNjcm9sbGVyKTtcbiAgICAgICAgaWYgKHNjcm9sbGVyICYmICF0aGlzLnNjcm9sbEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudCA9IHNjcm9sbGVyO1xuICAgICAgICAgICAgLy8gVXNpbmcgdGhlIHBhc3NpdmUgb3B0aW9uIHRvIG5vdCBibG9jayB0aGUgbWFpbiB0aHJlYWRcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9hZGRFdmVudExpc3RlbmVyI2ltcHJvdmluZ19zY3JvbGxpbmdfcGVyZm9ybWFuY2Vfd2l0aF9wYXNzaXZlX2xpc3RlbmVyc1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5jaGVja092ZXJmbG93LCB7IHBhc3NpdmU6IHRydWUgfSk7XG4gICAgICAgICAgICB0aGlzLmNoZWNrT3ZlcmZsb3coKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogSVByb3BzPFQ+KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHByZXZMZW4gPSBSZWFjdC5DaGlsZHJlbi5jb3VudChwcmV2UHJvcHMuY2hpbGRyZW4pO1xuICAgICAgICBjb25zdCBjdXJMZW4gPSBSZWFjdC5DaGlsZHJlbi5jb3VudCh0aGlzLnByb3BzLmNoaWxkcmVuKTtcbiAgICAgICAgLy8gY2hlY2sgb3ZlcmZsb3cgb25seSBpZiBhbW91bnQgb2YgY2hpbGRyZW4gY2hhbmdlcy5cbiAgICAgICAgLy8gaWYgd2UgZG9uJ3QgZ3VhcmQgaGVyZSwgd2UgZW5kIHVwIHdpdGggYW4gaW5maW5pdGVcbiAgICAgICAgLy8gcmVuZGVyID4gY29tcG9uZW50RGlkVXBkYXRlID4gY2hlY2tPdmVyZmxvdyA+IHNldFN0YXRlID4gcmVuZGVyIGxvb3BcbiAgICAgICAgaWYgKHByZXZMZW4gIT09IGN1ckxlbikge1xuICAgICAgICAgICAgdGhpcy5jaGVja092ZXJmbG93KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkTW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2hlY2tPdmVyZmxvdygpO1xuICAgICAgICBVSVN0b3JlLmluc3RhbmNlLm9uKFVJX0VWRU5UUy5SZXNpemUsIHRoaXMuY2hlY2tPdmVyZmxvdyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGVja092ZXJmbG93ID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuc2Nyb2xsRWxlbWVudCkgcmV0dXJuO1xuICAgICAgICBjb25zdCBoYXNUb3BPdmVyZmxvdyA9IHRoaXMuc2Nyb2xsRWxlbWVudC5zY3JvbGxUb3AgPiAwO1xuICAgICAgICBjb25zdCBoYXNCb3R0b21PdmVyZmxvdyA9XG4gICAgICAgICAgICB0aGlzLnNjcm9sbEVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gdGhpcy5zY3JvbGxFbGVtZW50LnNjcm9sbFRvcCArIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgICAgIGNvbnN0IGhhc0xlZnRPdmVyZmxvdyA9IHRoaXMuc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0ID4gMDtcbiAgICAgICAgY29uc3QgaGFzUmlnaHRPdmVyZmxvdyA9XG4gICAgICAgICAgICB0aGlzLnNjcm9sbEVsZW1lbnQuc2Nyb2xsV2lkdGggPiB0aGlzLnNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCArIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGllbnRXaWR0aDtcblxuICAgICAgICBpZiAoaGFzVG9wT3ZlcmZsb3cpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QuYWRkKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX3RvcE92ZXJmbG93XCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCJteF9JbmRpY2F0b3JTY3JvbGxiYXJfdG9wT3ZlcmZsb3dcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhc0JvdHRvbU92ZXJmbG93KSB7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbEVsZW1lbnQuY2xhc3NMaXN0LmFkZChcIm14X0luZGljYXRvclNjcm9sbGJhcl9ib3R0b21PdmVyZmxvd1wiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX2JvdHRvbU92ZXJmbG93XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNMZWZ0T3ZlcmZsb3cpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QuYWRkKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX2xlZnRPdmVyZmxvd1wiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX2xlZnRPdmVyZmxvd1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzUmlnaHRPdmVyZmxvdykge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJteF9JbmRpY2F0b3JTY3JvbGxiYXJfcmlnaHRPdmVyZmxvd1wiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX3JpZ2h0T3ZlcmZsb3dcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wcm9wcy50cmFja0hvcml6b250YWxPdmVyZmxvdykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgLy8gT2Zmc2V0IGZyb20gYWJzb2x1dGUgcG9zaXRpb24gb2YgdGhlIGNvbnRhaW5lclxuICAgICAgICAgICAgICAgIGxlZnRJbmRpY2F0b3JPZmZzZXQ6IGhhc0xlZnRPdmVyZmxvdyA/IGAke3RoaXMuc2Nyb2xsRWxlbWVudC5zY3JvbGxMZWZ0fXB4YCA6IFwiMFwiLFxuXG4gICAgICAgICAgICAgICAgLy8gTmVnYXRpdmUgYmVjYXVzZSB3ZSdyZSBjb21pbmcgZnJvbSB0aGUgcmlnaHRcbiAgICAgICAgICAgICAgICByaWdodEluZGljYXRvck9mZnNldDogaGFzUmlnaHRPdmVyZmxvdyA/IGAtJHt0aGlzLnNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdH1weGAgOiBcIjBcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHB1YmxpYyBjb21wb25lbnRXaWxsVW5tb3VudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50Py5yZW1vdmVFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMuY2hlY2tPdmVyZmxvdyk7XG4gICAgICAgIFVJU3RvcmUuaW5zdGFuY2Uub2ZmKFVJX0VWRU5UUy5SZXNpemUsIHRoaXMuY2hlY2tPdmVyZmxvdyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbk1vdXNlV2hlZWwgPSAoZTogUmVhY3QuV2hlZWxFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy52ZXJ0aWNhbFNjcm9sbHNIb3Jpem9udGFsbHkgJiYgdGhpcy5zY3JvbGxFbGVtZW50KSB7XG4gICAgICAgICAgICAvLyB4eVRocmVzaG9sZCBpcyB0aGUgYW1vdW50IG9mIGhvcml6b250YWwgbW90aW9uIHJlcXVpcmVkIGZvciB0aGUgY29tcG9uZW50IHRvXG4gICAgICAgICAgICAvLyBpZ25vcmUgdGhlIHZlcnRpY2FsIGRlbHRhIGluIGEgc2Nyb2xsLiBVc2VkIHRvIHN0b3AgdHJhY2twYWRzIGZyb20gYWN0aW5nIGluXG4gICAgICAgICAgICAvLyBzdHJhbmdlIHdheXMuIFNob3VsZCBiZSBwb3NpdGl2ZS5cbiAgICAgICAgICAgIGNvbnN0IHh5VGhyZXNob2xkID0gMDtcblxuICAgICAgICAgICAgLy8geVJldGVudGlvbiBpcyB0aGUgZmFjdG9yIG11bHRpcGxpZWQgYnkgdGhlIHZlcnRpY2FsIGRlbHRhIHRvIHRyeSBhbmQgcmVkdWNlXG4gICAgICAgICAgICAvLyB0aGUgaGFyc2huZXNzIG9mIHRoZSBzY3JvbGwgYmVoYXZpb3VyLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEuXG4gICAgICAgICAgICBjb25zdCB5UmV0ZW50aW9uID0gMS4wO1xuXG4gICAgICAgICAgICAvLyB3aGVuZXZlciB3ZSBzZWUgaG9yaXpvbnRhbCBzY3JvbGxpbmcsIGFzc3VtZSB0aGUgdXNlciBpcyBvbiBhIHRyYWNrcGFkXG4gICAgICAgICAgICAvLyBmb3IgYXQgbGVhc3QgdGhlIG5leHQgMSBtaW51dGUuXG4gICAgICAgICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhlLmRlbHRhWCkgPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saWtlbHlUcmFja3BhZFVzZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tBZ2FpbkZvclRyYWNrcGFkID0gbm93ICsgMSAqIDYwICogMTAwMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgd2UgaGF2ZW4ndCBzZWVuIGFueSBob3Jpem9udGFsIHNjcm9sbGluZyBmb3IgYSB3aGlsZSwgYXNzdW1lXG4gICAgICAgICAgICAgICAgLy8gdGhlIHVzZXIgbWlnaHQgaGF2ZSBwbHVnZ2VkIGluIGEgbW91c2V3aGVlbFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpa2VseVRyYWNrcGFkVXNlciAmJiBub3cgPj0gdGhpcy5jaGVja0FnYWluRm9yVHJhY2twYWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saWtlbHlUcmFja3BhZFVzZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGRvbid0IG1lc3Mgd2l0aCB0aGUgaG9yaXpvbnRhbCBzY3JvbGwgZm9yIHRyYWNrcGFkIHVzZXJzXG4gICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3ZlY3Rvci1pbS9lbGVtZW50LXdlYi9pc3N1ZXMvMTAwMDVcbiAgICAgICAgICAgIGlmICh0aGlzLmxpa2VseVRyYWNrcGFkVXNlcikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKE1hdGguYWJzKGUuZGVsdGFYKSA8PSB4eVRocmVzaG9sZCkge1xuICAgICAgICAgICAgICAgIC8vIHdlIGFyZSB2ZXJ0aWNhbGx5IHNjcm9sbGluZy5cbiAgICAgICAgICAgICAgICAvLyBIQUNLOiBXZSBpbmNyZWFzZSB0aGUgYW1vdW50IG9mIHNjcm9sbCB0byBjb3VudGVyYWN0IHNtb290aCBzY3JvbGxpbmcgYnJvd3NlcnMuXG4gICAgICAgICAgICAgICAgLy8gU21vb3RoIHNjcm9sbGluZyBicm93c2VycyAoRmlyZWZveCkgdXNlIHRoZSByZWxhdGl2ZSBhcmVhIHRvIGRldGVybWluZSB0aGUgc2Nyb2xsXG4gICAgICAgICAgICAgICAgLy8gYW1vdW50LCB3aGljaCBtZWFucyB0aGUgbGlrZWx5IHNtYWxsIGFyZWEgb2YgY29udGVudCByZXN1bHRzIGluIGEgc21hbGwgYW1vdW50IG9mXG4gICAgICAgICAgICAgICAgLy8gbW92ZW1lbnQgLSBub3Qgd2hhdCBwZW9wbGUgZXhwZWN0LiBXZSBwaWNrIGFyYml0cmFyeSB2YWx1ZXMgZm9yIHdoZW4gdG8gYXBwbHkgbW9yZVxuICAgICAgICAgICAgICAgIC8vIHNjcm9sbCwgYW5kIGhvdyBtdWNoIHRvIGFwcGx5LiBPbiBXaW5kb3dzIDEwLCBDaHJvbWUgc2Nyb2xscyAxMDAgdW5pdHMgd2hlcmVhc1xuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggc2Nyb2xscyBqdXN0IDMgZHVlIHRvIHNtb290aCBzY3JvbGxpbmcuXG5cbiAgICAgICAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsU2Nyb2xsID0gZS5kZWx0YVkgPCAwID8gLTUwIDogNTA7XG5cbiAgICAgICAgICAgICAgICAvLyBub2luc3BlY3Rpb24gSlNTdXNwaWNpb3VzTmFtZUNvbWJpbmF0aW9uXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gTWF0aC5hYnMoZS5kZWx0YVkpIDwgMjUgPyBlLmRlbHRhWSArIGFkZGl0aW9uYWxTY3JvbGwgOiBlLmRlbHRhWTtcbiAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbEVsZW1lbnQuc2Nyb2xsTGVmdCArPSB2YWwgKiB5UmV0ZW50aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgICBjb25zdCB7IGNoaWxkcmVuLCB0cmFja0hvcml6b250YWxPdmVyZmxvdywgdmVydGljYWxTY3JvbGxzSG9yaXpvbnRhbGx5LCAuLi5vdGhlclByb3BzIH0gPSB0aGlzLnByb3BzO1xuXG4gICAgICAgIGNvbnN0IGxlZnRJbmRpY2F0b3JTdHlsZSA9IHsgbGVmdDogdGhpcy5zdGF0ZS5sZWZ0SW5kaWNhdG9yT2Zmc2V0IH07XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5kaWNhdG9yU3R5bGUgPSB7IHJpZ2h0OiB0aGlzLnN0YXRlLnJpZ2h0SW5kaWNhdG9yT2Zmc2V0IH07XG4gICAgICAgIGNvbnN0IGxlZnRPdmVyZmxvd0luZGljYXRvciA9IHRyYWNrSG9yaXpvbnRhbE92ZXJmbG93ID8gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9JbmRpY2F0b3JTY3JvbGxiYXJfbGVmdE92ZXJmbG93SW5kaWNhdG9yXCIgc3R5bGU9e2xlZnRJbmRpY2F0b3JTdHlsZX0gLz5cbiAgICAgICAgKSA6IG51bGw7XG4gICAgICAgIGNvbnN0IHJpZ2h0T3ZlcmZsb3dJbmRpY2F0b3IgPSB0cmFja0hvcml6b250YWxPdmVyZmxvdyA/IChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfSW5kaWNhdG9yU2Nyb2xsYmFyX3JpZ2h0T3ZlcmZsb3dJbmRpY2F0b3JcIiBzdHlsZT17cmlnaHRJbmRpY2F0b3JTdHlsZX0gLz5cbiAgICAgICAgKSA6IG51bGw7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxBdXRvSGlkZVNjcm9sbGJhclxuICAgICAgICAgICAgICAgIHsuLi5vdGhlclByb3BzfVxuICAgICAgICAgICAgICAgIHJlZj17dGhpcy5hdXRvSGlkZVNjcm9sbGJhcn1cbiAgICAgICAgICAgICAgICB3cmFwcGVkUmVmPXt0aGlzLmNvbGxlY3RTY3JvbGxlcn1cbiAgICAgICAgICAgICAgICBvbldoZWVsPXt0aGlzLm9uTW91c2VXaGVlbH1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7bGVmdE92ZXJmbG93SW5kaWNhdG9yfVxuICAgICAgICAgICAgICAgIHtjaGlsZHJlbn1cbiAgICAgICAgICAgICAgICB7cmlnaHRPdmVyZmxvd0luZGljYXRvcn1cbiAgICAgICAgICAgIDwvQXV0b0hpZGVTY3JvbGxiYXI+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBT0EsSUFBQUEsTUFBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUMsa0JBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLFFBQUEsR0FBQUosdUJBQUEsQ0FBQUMsT0FBQTtBQUEwRCxNQUFBSSxTQUFBO0FBVjFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBLFNBQUFDLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLENBQUFDLENBQUEsV0FBQUEsQ0FBQSxHQUFBRyxDQUFBLEdBQUFELENBQUEsS0FBQUYsQ0FBQTtBQUFBLFNBQUFQLHdCQUFBTyxDQUFBLEVBQUFF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