UNPKG

matrix-react-sdk

Version:
262 lines (215 loc) 26.6 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "RovingTabIndexWrapper", { enumerable: true, get: function () { return _RovingTabIndexWrapper.RovingTabIndexWrapper; } }); Object.defineProperty(exports, "RovingAccessibleButton", { enumerable: true, get: function () { return _RovingAccessibleButton.RovingAccessibleButton; } }); Object.defineProperty(exports, "RovingAccessibleTooltipButton", { enumerable: true, get: function () { return _RovingAccessibleTooltipButton.RovingAccessibleTooltipButton; } }); exports.useRovingTabIndex = exports.RovingTabIndexProvider = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _Keyboard = require("../Keyboard"); var _RovingTabIndexWrapper = require("./roving/RovingTabIndexWrapper"); var _RovingAccessibleButton = require("./roving/RovingAccessibleButton"); var _RovingAccessibleTooltipButton = require("./roving/RovingAccessibleTooltipButton"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Module to simplify implementing the Roving TabIndex accessibility technique * * Wrap the Widget in an RovingTabIndexContextProvider * and then for all buttons make use of useRovingTabIndex or RovingTabIndexWrapper. * The code will keep track of which tabIndex was most recently focused and expose that information as `isActive` which * can then be used to only set the tabIndex to 0 as expected by the roving tabindex technique. * When the active button gets unmounted the closest button will be chosen as expected. * Initially the first button to mount will be given active state. * * https://developer.mozilla.org/en-US/docs/Web/Accessibility/Keyboard-navigable_JavaScript_widgets#Technique_1_Roving_tabindex */ const DOCUMENT_POSITION_PRECEDING = 2; /*:: export interface IState { activeRef: Ref; refs: Ref[]; }*/ const RovingTabIndexContext = /*#__PURE__*/(0, _react.createContext)({ state: { activeRef: null, refs: [] // list of refs in DOM order }, dispatch: () => {} }); RovingTabIndexContext.displayName = "RovingTabIndexContext"; var Type; (function (Type) { Type["Register"] = "REGISTER"; Type["Unregister"] = "UNREGISTER"; Type["SetFocus"] = "SET_FOCUS"; })(Type || (Type = {})); const reducer = (state /*: IState*/ , action /*: IAction*/ ) => { switch (action.type) { case Type.Register: { if (state.refs.length === 0) { // Our list of refs was empty, set activeRef to this first item return _objectSpread(_objectSpread({}, state), {}, { activeRef: action.payload.ref, refs: [action.payload.ref] }); } if (state.refs.includes(action.payload.ref)) { return state; // already in refs, this should not happen } // find the index of the first ref which is not preceding this one in DOM order let newIndex = state.refs.findIndex(ref => { return ref.current.compareDocumentPosition(action.payload.ref.current) & DOCUMENT_POSITION_PRECEDING; }); if (newIndex < 0) { newIndex = state.refs.length; // append to the end } // update the refs list return _objectSpread(_objectSpread({}, state), {}, { refs: [...state.refs.slice(0, newIndex), action.payload.ref, ...state.refs.slice(newIndex)] }); } case Type.Unregister: { // filter out the ref which we are removing const refs = state.refs.filter(r => r !== action.payload.ref); if (refs.length === state.refs.length) { return state; // already removed, this should not happen } if (state.activeRef === action.payload.ref) { // we just removed the active ref, need to replace it // pick the ref which is now in the index the old ref was in const oldIndex = state.refs.findIndex(r => r === action.payload.ref); return _objectSpread(_objectSpread({}, state), {}, { activeRef: oldIndex >= refs.length ? refs[refs.length - 1] : refs[oldIndex], refs }); } // update the refs list return _objectSpread(_objectSpread({}, state), {}, { refs }); } case Type.SetFocus: { // update active ref return _objectSpread(_objectSpread({}, state), {}, { activeRef: action.payload.ref }); } default: return state; } }; const RovingTabIndexProvider /*: React.FC<IProps>*/ = ({ children, handleHomeEnd, onKeyDown }) => { const [state, dispatch] = (0, _react.useReducer)(reducer, { activeRef: null, refs: [] }); const context = (0, _react.useMemo)(() => ({ state, dispatch }), [state]); const onKeyDownHandler = (0, _react.useCallback)(ev => { let handled = false; // Don't interfere with input default keydown behaviour if (handleHomeEnd && ev.target.tagName !== "INPUT" && ev.target.tagName !== "TEXTAREA") { // check if we actually have any items switch (ev.key) { case _Keyboard.Key.HOME: handled = true; // move focus to first item if (context.state.refs.length > 0) { context.state.refs[0].current.focus(); } break; case _Keyboard.Key.END: handled = true; // move focus to last item if (context.state.refs.length > 0) { context.state.refs[context.state.refs.length - 1].current.focus(); } break; } } if (handled) { ev.preventDefault(); ev.stopPropagation(); } else if (onKeyDown) { return onKeyDown(ev, context.state); } }, [context.state, onKeyDown, handleHomeEnd]); return /*#__PURE__*/_react.default.createElement(RovingTabIndexContext.Provider, { value: context }, children({ onKeyDownHandler })); }; // Hook to register a roving tab index // inputRef parameter specifies the ref to use // onFocus should be called when the index gained focus in any manner // isActive should be used to set tabIndex in a manner such as `tabIndex={isActive ? 0 : -1}` // ref should be passed to a DOM node which will be used for DOM compareDocumentPosition exports.RovingTabIndexProvider = RovingTabIndexProvider; const useRovingTabIndex = (inputRef /*: Ref*/ ) => /*: [FocusHandler, boolean, Ref]*/ { const context = (0, _react.useContext)(RovingTabIndexContext); let ref = (0, _react.useRef)(null); if (inputRef) { // if we are given a ref, use it instead of ours ref = inputRef; } // setup (after refs) (0, _react.useLayoutEffect)(() => { context.dispatch({ type: Type.Register, payload: { ref } }); // teardown return () => { context.dispatch({ type: Type.Unregister, payload: { ref } }); }; }, []); // eslint-disable-line react-hooks/exhaustive-deps const onFocus = (0, _react.useCallback)(() => { context.dispatch({ type: Type.SetFocus, payload: { ref } }); }, [ref, context]); const isActive = context.state.activeRef === ref; return [onFocus, isActive, ref]; }; // re-export the semantic helper components for simplicity exports.useRovingTabIndex = useRovingTabIndex; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hY2Nlc3NpYmlsaXR5L1JvdmluZ1RhYkluZGV4LnRzeCJdLCJuYW1lcyI6WyJET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkciLCJSb3ZpbmdUYWJJbmRleENvbnRleHQiLCJzdGF0ZSIsImFjdGl2ZVJlZiIsInJlZnMiLCJkaXNwYXRjaCIsImRpc3BsYXlOYW1lIiwiVHlwZSIsInJlZHVjZXIiLCJhY3Rpb24iLCJ0eXBlIiwiUmVnaXN0ZXIiLCJsZW5ndGgiLCJwYXlsb2FkIiwicmVmIiwiaW5jbHVkZXMiLCJuZXdJbmRleCIsImZpbmRJbmRleCIsImN1cnJlbnQiLCJjb21wYXJlRG9jdW1lbnRQb3NpdGlvbiIsInNsaWNlIiwiVW5yZWdpc3RlciIsImZpbHRlciIsInIiLCJvbGRJbmRleCIsIlNldEZvY3VzIiwiUm92aW5nVGFiSW5kZXhQcm92aWRlciIsImNoaWxkcmVuIiwiaGFuZGxlSG9tZUVuZCIsIm9uS2V5RG93biIsImNvbnRleHQiLCJvbktleURvd25IYW5kbGVyIiwiZXYiLCJoYW5kbGVkIiwidGFyZ2V0IiwidGFnTmFtZSIsImtleSIsIktleSIsIkhPTUUiLCJmb2N1cyIsIkVORCIsInByZXZlbnREZWZhdWx0Iiwic3RvcFByb3BhZ2F0aW9uIiwidXNlUm92aW5nVGFiSW5kZXgiLCJpbnB1dFJlZiIsIm9uRm9jdXMiLCJpc0FjdGl2ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdCQTs7QUFZQTs7QUF1TkE7O0FBQ0E7O0FBQ0E7Ozs7OztBQXROQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQSxNQUFNQSwyQkFBMkIsR0FBRyxDQUFwQzs7QUE1Q0E7QUFDQTtBQUNBOztBQXNEQSxNQUFNQyxxQkFBcUIsZ0JBQUcsMEJBQXdCO0FBQ2xEQyxFQUFBQSxLQUFLLEVBQUU7QUFDSEMsSUFBQUEsU0FBUyxFQUFFLElBRFI7QUFF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QixJQUFwQixDQUFWOztBQUVBLE1BQUk4QixRQUFKLEVBQWM7QUFDVjtBQUNBOUIsSUFBQUEsR0FBRyxHQUFHOEIsUUFBTjtBQUNILEdBUDhFLENBUy9FOzs7QUFDQSw4QkFBZ0IsTUFBTTtBQUNsQmQsSUFBQUEsT0FBTyxDQUFDekIsUUFBUixDQUFpQjtBQUNiSyxNQUFBQSxJQUFJLEVBQUVILElBQUksQ0FBQ0ksUUFERTtBQUViRSxNQUFBQSxPQUFPLEVBQUU7QUFBQ0MsUUFBQUE7QUFBRDtBQUZJLEtBQWpCLEVBRGtCLENBS2xCOztBQUNBLFdBQU8sTUFBTTtBQUNUZ0IsTUFBQUEsT0FBTyxDQUFDekIsUUFBUixDQUFpQjtBQUNiSyxRQUFBQSxJQUFJLEVBQUVILElBQUksQ0FBQ2MsVUFERTtBQUViUixRQUFBQSxPQUFPLEVBQUU7QUFBQ0MsVUFBQUE7QUFBRDtBQUZJLE9BQWpCO0FBSUgsS0FMRDtBQU1ILEdBWkQsRUFZRyxFQVpILEVBVitFLENBc0J2RTs7QUFFUixRQUFNK0IsT0FBTyxHQUFHLHdCQUFZLE1BQU07QUFDOUJmLElBQUFBLE9BQU8sQ0FBQ3pCLFFBQVIsQ0FBaUI7QUFDYkssTUFBQUEsSUFBSSxFQUFFSCxJQUFJLENBQUNrQixRQURFO0FBRWJaLE1BQUFBLE9BQU8sRUFBRTtBQUFDQyxRQUFBQTtBQUFEO0FBRkksS0FBakI7QUFJSCxHQUxlLEVBS2IsQ0FBQ0EsR0FBRCxFQUFNZ0IsT0FBTixDQUxhLENBQWhCO0FBT0EsUUFBTWdCLFFBQVEsR0FBR2hCLE9BQU8sQ0FBQzVCLEtBQVIsQ0FBY0MsU0FBZCxLQUE0QlcsR0FBN0M7QUFDQSxTQUFPLENBQUMrQixPQUFELEVBQVVDLFFBQVYsRUFBb0JoQyxHQUFwQixDQUFQO0FBQ0gsQ0FqQ00sQyxDQW1DUCIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyMCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBSZWFjdCwge1xuICAgIGNyZWF0ZUNvbnRleHQsXG4gICAgdXNlQ2FsbGJhY2ssXG4gICAgdXNlQ29udGV4dCxcbiAgICB1c2VMYXlvdXRFZmZlY3QsXG4gICAgdXNlTWVtbyxcbiAgICB1c2VSZWYsXG4gICAgdXNlUmVkdWNlcixcbiAgICBSZWR1Y2VyLFxuICAgIERpc3BhdGNoLFxufSBmcm9tIFwicmVhY3RcIjtcblxuaW1wb3J0IHtLZXl9IGZyb20gXCIuLi9LZXlib2FyZFwiO1xuaW1wb3J0IHtGb2N1c0hhbmRsZXIsIFJlZn0gZnJvbSBcIi4vcm92aW5nL3R5cGVzXCI7XG5cbi8qKlxuICogTW9kdWxlIHRvIHNpbXBsaWZ5IGltcGxlbWVudGluZyB0aGUgUm92aW5nIFRhYkluZGV4IGFjY2Vzc2liaWxpdHkgdGVjaG5pcXVlXG4gKlxuICogV3JhcCB0aGUgV2lkZ2V0IGluIGFuIFJvdmluZ1RhYkluZGV4Q29udGV4dFByb3ZpZGVyXG4gKiBhbmQgdGhlbiBmb3IgYWxsIGJ1dHRvbnMgbWFrZSB1c2Ugb2YgdXNlUm92aW5nVGFiSW5kZXggb3IgUm92aW5nVGFiSW5kZXhXcmFwcGVyLlxuICogVGhlIGNvZGUgd2lsbCBrZWVwIHRyYWNrIG9mIHdoaWNoIHRhYkluZGV4IHdhcyBtb3N0IHJlY2VudGx5IGZvY3VzZWQgYW5kIGV4cG9zZSB0aGF0IGluZm9ybWF0aW9uIGFzIGBpc0FjdGl2ZWAgd2hpY2hcbiAqIGNhbiB0aGVuIGJlIHVzZWQgdG8gb25seSBzZXQgdGhlIHRhYkluZGV4IHRvIDAgYXMgZXhwZWN0ZWQgYnkgdGhlIHJvdmluZyB0YWJpbmRleCB0ZWNobmlxdWUuXG4gKiBXaGVuIHRoZSBhY3RpdmUgYnV0dG9uIGdldHMgdW5tb3VudGVkIHRoZSBjbG9zZXN0IGJ1dHRvbiB3aWxsIGJlIGNob3NlbiBhcyBleHBlY3RlZC5cbiAqIEluaXRpYWxseSB0aGUgZmlyc3QgYnV0dG9uIHRvIG1vdW50IHdpbGwgYmUgZ2l2ZW4gYWN0aXZlIHN0YXRlLlxuICpcbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FjY2Vzc2liaWxpdHkvS2V5Ym9hcmQtbmF2aWdhYmxlX0phdmFTY3JpcHRfd2lkZ2V0cyNUZWNobmlxdWVfMV9Sb3ZpbmdfdGFiaW5kZXhcbiAqL1xuXG5jb25zdCBET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkcgPSAyO1xuXG5leHBvcnQgaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgYWN0aXZlUmVmOiBSZWY7XG4gICAgcmVmczogUmVmW107XG59XG5cbmludGVyZmFjZSBJQ29udGV4dCB7XG4gICAgc3RhdGU6IElTdGF0ZTtcbiAgICBkaXNwYXRjaDogRGlzcGF0Y2g8SUFjdGlvbj47XG59XG5cbmNvbnN0IFJvdmluZ1RhYkluZGV4Q29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8SUNvbnRleHQ+KHtcbiAgICBzdGF0ZToge1xuICAgICAgICBhY3RpdmVSZWY6IG51bGwsXG4gICAgICAgIHJlZnM6IFtdLCAvLyBsaXN0IG9mIHJlZnMgaW4gRE9NIG9yZGVyXG4gICAgfSxcbiAgICBkaXNwYXRjaDogKCkgPT4ge30sXG59KTtcblJvdmluZ1RhYkluZGV4Q29udGV4dC5kaXNwbGF5TmFtZSA9IFwiUm92aW5nVGFiSW5kZXhDb250ZXh0XCI7XG5cbmVudW0gVHlwZSB7XG4gICAgUmVnaXN0ZXIgPSBcIlJFR0lTVEVSXCIsXG4gICAgVW5yZWdpc3RlciA9IFwiVU5SRUdJU1RFUlwiLFxuICAgIFNldEZvY3VzID0gXCJTRVRfRk9DVVNcIixcbn1cblxuaW50ZXJmYWNlIElBY3Rpb24ge1xuICAgIHR5cGU6IFR5cGU7XG4gICAgcGF5bG9hZDoge1xuICAgICAgICByZWY6IFJlZjtcbiAgICB9O1xufVxuXG5jb25zdCByZWR1Y2VyID0gKHN0YXRlOiBJU3RhdGUsIGFjdGlvbjogSUFjdGlvbikgPT4ge1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSBUeXBlLlJlZ2lzdGVyOiB7XG4gICAgICAgICAgICBpZiAoc3RhdGUucmVmcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAvLyBPdXIgbGlzdCBvZiByZWZzIHdhcyBlbXB0eSwgc2V0IGFjdGl2ZVJlZiB0byB0aGlzIGZpcnN0IGl0ZW1cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlUmVmOiBhY3Rpb24ucGF5bG9hZC5yZWYsXG4gICAgICAgICAgICAgICAgICAgIHJlZnM6IFthY3Rpb24ucGF5bG9hZC5yZWZdLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdGF0ZS5yZWZzLmluY2x1ZGVzKGFjdGlvbi5wYXlsb2FkLnJlZikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGU7IC8vIGFscmVhZHkgaW4gcmVmcywgdGhpcyBzaG91bGQgbm90IGhhcHBlblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgcmVmIHdoaWNoIGlzIG5vdCBwcmVjZWRpbmcgdGhpcyBvbmUgaW4gRE9NIG9yZGVyXG4gICAgICAgICAgICBsZXQgbmV3SW5kZXggPSBzdGF0ZS5yZWZzLmZpbmRJbmRleChyZWYgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWYuY3VycmVudC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihhY3Rpb24ucGF5bG9hZC5yZWYuY3VycmVudCkgJiBET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkc7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKG5ld0luZGV4IDwgMCkge1xuICAgICAgICAgICAgICAgIG5ld0luZGV4ID0gc3RhdGUucmVmcy5sZW5ndGg7IC8vIGFwcGVuZCB0byB0aGUgZW5kXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgcmVmcyBsaXN0XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgICAgIHJlZnM6IFtcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUucmVmcy5zbGljZSgwLCBuZXdJbmRleCksXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbi5wYXlsb2FkLnJlZixcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUucmVmcy5zbGljZShuZXdJbmRleCksXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBUeXBlLlVucmVnaXN0ZXI6IHtcbiAgICAgICAgICAgIC8vIGZpbHRlciBvdXQgdGhlIHJlZiB3aGljaCB3ZSBhcmUgcmVtb3ZpbmdcbiAgICAgICAgICAgIGNvbnN0IHJlZnMgPSBzdGF0ZS5yZWZzLmZpbHRlcihyID0+IHIgIT09IGFjdGlvbi5wYXlsb2FkLnJlZik7XG5cbiAgICAgICAgICAgIGlmIChyZWZzLmxlbmd0aCA9PT0gc3RhdGUucmVmcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGU7IC8vIGFscmVhZHkgcmVtb3ZlZCwgdGhpcyBzaG91bGQgbm90IGhhcHBlblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3RhdGUuYWN0aXZlUmVmID09PSBhY3Rpb24ucGF5bG9hZC5yZWYpIHtcbiAgICAgICAgICAgICAgICAvLyB3ZSBqdXN0IHJlbW92ZWQgdGhlIGFjdGl2ZSByZWYsIG5lZWQgdG8gcmVwbGFjZSBpdFxuICAgICAgICAgICAgICAgIC8vIHBpY2sgdGhlIHJlZiB3aGljaCBpcyBub3cgaW4gdGhlIGluZGV4IHRoZSBvbGQgcmVmIHdhcyBpblxuICAgICAgICAgICAgICAgIGNvbnN0IG9sZEluZGV4ID0gc3RhdGUucmVmcy5maW5kSW5kZXgociA9PiByID09PSBhY3Rpb24ucGF5bG9hZC5yZWYpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVSZWY6IG9sZEluZGV4ID49IHJlZnMubGVuZ3RoID8gcmVmc1tyZWZzLmxlbmd0aCAtIDFdIDogcmVmc1tvbGRJbmRleF0sXG4gICAgICAgICAgICAgICAgICAgIHJlZnMsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSByZWZzIGxpc3RcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICAgICAgcmVmcyxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBUeXBlLlNldEZvY3VzOiB7XG4gICAgICAgICAgICAvLyB1cGRhdGUgYWN0aXZlIHJlZlxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBhY3RpdmVSZWY6IGFjdGlvbi5wYXlsb2FkLnJlZixcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9XG59O1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICBoYW5kbGVIb21lRW5kPzogYm9vbGVhbjtcbiAgICBjaGlsZHJlbihyZW5kZXJQcm9wczoge1xuICAgICAgICBvbktleURvd25IYW5kbGVyKGV2OiBSZWFjdC5LZXlib2FyZEV2ZW50KTtcbiAgICB9KTtcbiAgICBvbktleURvd24/KGV2OiBSZWFjdC5LZXlib2FyZEV2ZW50LCBzdGF0ZTogSVN0YXRlKTtcbn1cblxuZXhwb3J0IGNvbnN0IFJvdmluZ1RhYkluZGV4UHJvdmlkZXI6IFJlYWN0LkZDPElQcm9wcz4gPSAoe2NoaWxkcmVuLCBoYW5kbGVIb21lRW5kLCBvbktleURvd259KSA9PiB7XG4gICAgY29uc3QgW3N0YXRlLCBkaXNwYXRjaF0gPSB1c2VSZWR1Y2VyPFJlZHVjZXI8SVN0YXRlLCBJQWN0aW9uPj4ocmVkdWNlciwge1xuICAgICAgICBhY3RpdmVSZWY6IG51bGwsXG4gICAgICAgIHJlZnM6IFtdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY29udGV4dCA9IHVzZU1lbW88SUNvbnRleHQ+KCgpID0+ICh7c3RhdGUsIGRpc3BhdGNofSksIFtzdGF0ZV0pO1xuXG4gICAgY29uc3Qgb25LZXlEb3duSGFuZGxlciA9IHVzZUNhbGxiYWNrKChldikgPT4ge1xuICAgICAgICBsZXQgaGFuZGxlZCA9IGZhbHNlO1xuICAgICAgICAvLyBEb24ndCBpbnRlcmZlcmUgd2l0aCBpbnB1dCBkZWZhdWx0IGtleWRvd24gYmVoYXZpb3VyXG4gICAgICAgIGlmIChoYW5kbGVIb21lRW5kICYmIGV2LnRhcmdldC50YWdOYW1lICE9PSBcIklOUFVUXCIgJiYgZXYudGFyZ2V0LnRhZ05hbWUgIT09IFwiVEVYVEFSRUFcIikge1xuICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgYWN0dWFsbHkgaGF2ZSBhbnkgaXRlbXNcbiAgICAgICAgICAgIHN3aXRjaCAoZXYua2V5KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBLZXkuSE9NRTpcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIC8vIG1vdmUgZm9jdXMgdG8gZmlyc3QgaXRlbVxuICAgICAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5zdGF0ZS5yZWZzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuc3RhdGUucmVmc1swXS5jdXJyZW50LmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBLZXkuRU5EOlxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgLy8gbW92ZSBmb2N1cyB0byBsYXN0IGl0ZW1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuc3RhdGUucmVmcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnN0YXRlLnJlZnNbY29udGV4dC5zdGF0ZS5yZWZzLmxlbmd0aCAtIDFdLmN1cnJlbnQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoYW5kbGVkKSB7XG4gICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAob25LZXlEb3duKSB7XG4gICAgICAgICAgICByZXR1cm4gb25LZXlEb3duKGV2LCBjb250ZXh0LnN0YXRlKTtcbiAgICAgICAgfVxuICAgIH0sIFtjb250ZXh0LnN0YXRlLCBvbktleURvd24sIGhhbmRsZUhvbWVFbmRdKTtcblxuICAgIHJldHVybiA8Um92aW5nVGFiSW5kZXhDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtjb250ZXh0fT5cbiAgICAgICAgeyBjaGlsZHJlbih7b25LZXlEb3duSGFuZGxlcn0pIH1cbiAgICA8L1JvdmluZ1RhYkluZGV4Q29udGV4dC5Qcm92aWRlcj47XG59O1xuXG4vLyBIb29rIHRvIHJlZ2lzdGVyIGEgcm92aW5nIHRhYiBpbmRleFxuLy8gaW5wdXRSZWYgcGFyYW1ldGVyIHNwZWNpZmllcyB0aGUgcmVmIHRvIHVzZVxuLy8gb25Gb2N1cyBzaG91bGQgYmUgY2FsbGVkIHdoZW4gdGhlIGluZGV4IGdhaW5lZCBmb2N1cyBpbiBhbnkgbWFubmVyXG4vLyBpc0FjdGl2ZSBzaG91bGQgYmUgdXNlZCB0byBzZXQgdGFiSW5kZXggaW4gYSBtYW5uZXIgc3VjaCBhcyBgdGFiSW5kZXg9e2lzQWN0aXZlID8gMCA6IC0xfWBcbi8vIHJlZiBzaG91bGQgYmUgcGFzc2VkIHRvIGEgRE9NIG5vZGUgd2hpY2ggd2lsbCBiZSB1c2VkIGZvciBET00gY29tcGFyZURvY3VtZW50UG9zaXRpb25cbmV4cG9ydCBjb25zdCB1c2VSb3ZpbmdUYWJJbmRleCA9IChpbnB1dFJlZj86IFJlZik6IFtGb2N1c0hhbmRsZXIsIGJvb2xlYW4sIFJlZl0gPT4ge1xuICAgIGNvbnN0IGNvbnRleHQgPSB1c2VDb250ZXh0KFJvdmluZ1RhYkluZGV4Q29udGV4dCk7XG4gICAgbGV0IHJlZiA9IHVzZVJlZjxIVE1MRWxlbWVudD4obnVsbCk7XG5cbiAgICBpZiAoaW5wdXRSZWYpIHtcbiAgICAgICAgLy8gaWYgd2UgYXJlIGdpdmVuIGEgcmVmLCB1c2UgaXQgaW5zdGVhZCBvZiBvdXJzXG4gICAgICAgIHJlZiA9IGlucHV0UmVmO1xuICAgIH1cblxuICAgIC8vIHNldHVwIChhZnRlciByZWZzKVxuICAgIHVzZUxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogVHlwZS5SZWdpc3RlcixcbiAgICAgICAgICAgIHBheWxvYWQ6IHtyZWZ9LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gdGVhcmRvd25cbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IFR5cGUuVW5yZWdpc3RlcixcbiAgICAgICAgICAgICAgICBwYXlsb2FkOiB7cmVmfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH0sIFtdKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcblxuICAgIGNvbnN0IG9uRm9jdXMgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogVHlwZS5TZXRGb2N1cyxcbiAgICAgICAgICAgIHBheWxvYWQ6IHtyZWZ9LFxuICAgICAgICB9KTtcbiAgICB9LCBbcmVmLCBjb250ZXh0XSk7XG5cbiAgICBjb25zdCBpc0FjdGl2ZSA9IGNvbnRleHQuc3RhdGUuYWN0aXZlUmVmID09PSByZWY7XG4gICAgcmV0dXJuIFtvbkZvY3VzLCBpc0FjdGl2ZSwgcmVmXTtcbn07XG5cbi8vIHJlLWV4cG9ydCB0aGUgc2VtYW50aWMgaGVscGVyIGNvbXBvbmVudHMgZm9yIHNpbXBsaWNpdHlcbmV4cG9ydCB7Um92aW5nVGFiSW5kZXhXcmFwcGVyfSBmcm9tIFwiLi9yb3ZpbmcvUm92aW5nVGFiSW5kZXhXcmFwcGVyXCI7XG5leHBvcnQge1JvdmluZ0FjY2Vzc2libGVCdXR0b259IGZyb20gXCIuL3JvdmluZy9Sb3ZpbmdBY2Nlc3NpYmxlQnV0dG9uXCI7XG5leHBvcnQge1JvdmluZ0FjY2Vzc2libGVUb29sdGlwQnV0dG9ufSBmcm9tIFwiLi9yb3ZpbmcvUm92aW5nQWNjZXNzaWJsZVRvb2x0aXBCdXR0b25cIjtcbiJdfQ==