UNPKG

matrix-react-sdk

Version:
323 lines (313 loc) 46.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "RovingAccessibleButton", { enumerable: true, get: function () { return _RovingAccessibleButton.RovingAccessibleButton; } }); exports.RovingTabIndexProvider = exports.RovingTabIndexContext = void 0; Object.defineProperty(exports, "RovingTabIndexWrapper", { enumerable: true, get: function () { return _RovingTabIndexWrapper.RovingTabIndexWrapper; } }); exports.Type = void 0; exports.checkInputableElement = checkInputableElement; exports.useRovingTabIndex = exports.reducer = exports.findSiblingElement = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _KeyBindingsManager = require("../KeyBindingsManager"); var _KeyboardShortcuts = require("./KeyboardShortcuts"); var _RovingTabIndexWrapper = require("./roving/RovingTabIndexWrapper"); var _RovingAccessibleButton = require("./roving/RovingAccessibleButton"); 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; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* Copyright 2024 New Vector Ltd. Copyright 2020 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ /** * 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 */ // Check for form elements which utilize the arrow keys for native functions // like many of the text input varieties. // // i.e. it's ok to press the down arrow on a radio button to move to the next // radio. But it's not ok to press the down arrow on a <input type="text"> to // move away because the down arrow should move the cursor to the end of the // input. function checkInputableElement(el) { return el.matches('input:not([type="radio"]):not([type="checkbox"]), textarea, select, [contenteditable=true]'); } const RovingTabIndexContext = exports.RovingTabIndexContext = /*#__PURE__*/(0, _react.createContext)({ state: { refs: [] // list of refs in DOM order }, dispatch: () => {} }); RovingTabIndexContext.displayName = "RovingTabIndexContext"; let Type = exports.Type = /*#__PURE__*/function (Type) { Type["Register"] = "REGISTER"; Type["Unregister"] = "UNREGISTER"; Type["SetFocus"] = "SET_FOCUS"; Type["Update"] = "UPDATE"; return Type; }({}); const refSorter = (a, b) => { if (a === b) { return 0; } const position = a.current.compareDocumentPosition(b.current); if (position & Node.DOCUMENT_POSITION_FOLLOWING || position & Node.DOCUMENT_POSITION_CONTAINED_BY) { return -1; } else if (position & Node.DOCUMENT_POSITION_PRECEDING || position & Node.DOCUMENT_POSITION_CONTAINS) { return 1; } else { return 0; } }; const reducer = (state, action) => { switch (action.type) { case Type.Register: { if (!state.activeRef) { // Our list of refs was empty, set activeRef to this first item state.activeRef = action.payload.ref; } // Sadly due to the potential of DOM elements swapping order we can't do anything fancy like a binary insert state.refs.push(action.payload.ref); state.refs.sort(refSorter); return _objectSpread({}, state); } case Type.Unregister: { const oldIndex = state.refs.findIndex(r => r === action.payload.ref); if (oldIndex === -1) { return state; // already removed, this should not happen } if (state.refs.splice(oldIndex, 1)[0] === state.activeRef) { // we just removed the active ref, need to replace it // pick the ref closest to the index the old ref was in if (oldIndex >= state.refs.length) { state.activeRef = findSiblingElement(state.refs, state.refs.length - 1, true); } else { state.activeRef = findSiblingElement(state.refs, oldIndex) || findSiblingElement(state.refs, oldIndex, true); } if (document.activeElement === document.body) { // if the focus got reverted to the body then the user was likely focused on the unmounted element setTimeout(() => state.activeRef?.current?.focus(), 0); } } // update the refs list return _objectSpread({}, state); } case Type.SetFocus: { // if the ref doesn't change just return the same object reference to skip a re-render if (state.activeRef === action.payload.ref) return state; // update active ref state.activeRef = action.payload.ref; return _objectSpread({}, state); } case Type.Update: { state.refs.sort(refSorter); return _objectSpread({}, state); } default: return state; } }; exports.reducer = reducer; const findSiblingElement = (refs, startIndex, backwards = false, loop = false) => { if (backwards) { for (let i = startIndex; i < refs.length && i >= 0; i--) { if (refs[i].current?.offsetParent !== null) { return refs[i]; } } if (loop) { return findSiblingElement(refs.slice(startIndex + 1), refs.length - 1, true, false); } } else { for (let i = startIndex; i < refs.length && i >= 0; i++) { if (refs[i].current?.offsetParent !== null) { return refs[i]; } } if (loop) { return findSiblingElement(refs.slice(0, startIndex), 0, false, false); } } }; exports.findSiblingElement = findSiblingElement; const RovingTabIndexProvider = ({ children, handleHomeEnd, handleUpDown, handleLeftRight, handleLoop, handleInputFields, scrollIntoView, onKeyDown }) => { const [state, dispatch] = (0, _react.useReducer)(reducer, { refs: [] }); const context = (0, _react.useMemo)(() => ({ state, dispatch }), [state]); const onKeyDownHandler = (0, _react.useCallback)(ev => { if (onKeyDown) { onKeyDown(ev, context.state, context.dispatch); if (ev.defaultPrevented) { return; } } let handled = false; const action = (0, _KeyBindingsManager.getKeyBindingsManager)().getAccessibilityAction(ev); let focusRef; // Don't interfere with input default keydown behaviour // but allow people to move focus from it with Tab. if (!handleInputFields && checkInputableElement(ev.target)) { switch (action) { case _KeyboardShortcuts.KeyBindingAction.Tab: handled = true; if (context.state.refs.length > 0) { const idx = context.state.refs.indexOf(context.state.activeRef); focusRef = findSiblingElement(context.state.refs, idx + (ev.shiftKey ? -1 : 1), ev.shiftKey); } break; } } else { // check if we actually have any items switch (action) { case _KeyboardShortcuts.KeyBindingAction.Home: if (handleHomeEnd) { handled = true; // move focus to first (visible) item focusRef = findSiblingElement(context.state.refs, 0); } break; case _KeyboardShortcuts.KeyBindingAction.End: if (handleHomeEnd) { handled = true; // move focus to last (visible) item focusRef = findSiblingElement(context.state.refs, context.state.refs.length - 1, true); } break; case _KeyboardShortcuts.KeyBindingAction.ArrowDown: case _KeyboardShortcuts.KeyBindingAction.ArrowRight: if (action === _KeyboardShortcuts.KeyBindingAction.ArrowDown && handleUpDown || action === _KeyboardShortcuts.KeyBindingAction.ArrowRight && handleLeftRight) { handled = true; if (context.state.refs.length > 0) { const idx = context.state.refs.indexOf(context.state.activeRef); focusRef = findSiblingElement(context.state.refs, idx + 1, false, handleLoop); } } break; case _KeyboardShortcuts.KeyBindingAction.ArrowUp: case _KeyboardShortcuts.KeyBindingAction.ArrowLeft: if (action === _KeyboardShortcuts.KeyBindingAction.ArrowUp && handleUpDown || action === _KeyboardShortcuts.KeyBindingAction.ArrowLeft && handleLeftRight) { handled = true; if (context.state.refs.length > 0) { const idx = context.state.refs.indexOf(context.state.activeRef); focusRef = findSiblingElement(context.state.refs, idx - 1, true, handleLoop); } } break; } } if (handled) { ev.preventDefault(); ev.stopPropagation(); } if (focusRef) { focusRef.current?.focus(); // programmatic focus doesn't fire the onFocus handler, so we must do the do ourselves dispatch({ type: Type.SetFocus, payload: { ref: focusRef } }); if (scrollIntoView) { focusRef.current?.scrollIntoView(scrollIntoView); } } }, [context, onKeyDown, handleHomeEnd, handleUpDown, handleLeftRight, handleLoop, handleInputFields, scrollIntoView]); const onDragEndHandler = (0, _react.useCallback)(() => { dispatch({ type: Type.Update }); }, []); return /*#__PURE__*/_react.default.createElement(RovingTabIndexContext.Provider, { value: context }, children({ onKeyDownHandler, onDragEndHandler })); }; // 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 => { 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.useEffect)(() => { 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 } }); }, []); // eslint-disable-line react-hooks/exhaustive-deps 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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfS2V5QmluZGluZ3NNYW5hZ2VyIiwiX0tleWJvYXJkU2hvcnRjdXRzIiwiX1JvdmluZ1RhYkluZGV4V3JhcHBlciIsIl9Sb3ZpbmdBY2Nlc3NpYmxlQnV0dG9uIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0Iiwib3duS2V5cyIsImtleXMiLCJnZXRPd25Qcm9wZXJ0eVN5bWJvbHMiLCJvIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5MiIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiY2hlY2tJbnB1dGFibGVFbGVtZW50IiwiZWwiLCJtYXRjaGVzIiwiUm92aW5nVGFiSW5kZXhDb250ZXh0IiwiZXhwb3J0cyIsImNyZWF0ZUNvbnRleHQiLCJzdGF0ZSIsInJlZnMiLCJkaXNwYXRjaCIsImRpc3BsYXlOYW1lIiwiVHlwZSIsInJlZlNvcnRlciIsImIiLCJwb3NpdGlvbiIsImN1cnJlbnQiLCJjb21wYXJlRG9jdW1lbnRQb3NpdGlvbiIsIk5vZGUiLCJET0NVTUVOVF9QT1NJVElPTl9GT0xMT1dJTkciLCJET0NVTUVOVF9QT1NJVElPTl9DT05UQUlORURfQlkiLCJET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkciLCJET0NVTUVOVF9QT1NJVElPTl9DT05UQUlOUyIsInJlZHVjZXIiLCJhY3Rpb24iLCJ0eXBlIiwiUmVnaXN0ZXIiLCJhY3RpdmVSZWYiLCJwYXlsb2FkIiwicmVmIiwic29ydCIsIlVucmVnaXN0ZXIiLCJvbGRJbmRleCIsImZpbmRJbmRleCIsInNwbGljZSIsImZpbmRTaWJsaW5nRWxlbWVudCIsImRvY3VtZW50IiwiYWN0aXZlRWxlbWVudCIsImJvZHkiLCJzZXRUaW1lb3V0IiwiZm9jdXMiLCJTZXRGb2N1cyIsIlVwZGF0ZSIsInN0YXJ0SW5kZXgiLCJiYWNrd2FyZHMiLCJsb29wIiwib2Zmc2V0UGFyZW50Iiwic2xpY2UiLCJSb3ZpbmdUYWJJbmRleFByb3ZpZGVyIiwiY2hpbGRyZW4iLCJoYW5kbGVIb21lRW5kIiwiaGFuZGxlVXBEb3duIiwiaGFuZGxlTGVmdFJpZ2h0IiwiaGFuZGxlTG9vcCIsImhhbmRsZUlucHV0RmllbGRzIiwic2Nyb2xsSW50b1ZpZXciLCJvbktleURvd24iLCJ1c2VSZWR1Y2VyIiwiY29udGV4dCIsInVzZU1lbW8iLCJvbktleURvd25IYW5kbGVyIiwidXNlQ2FsbGJhY2siLCJldiIsImRlZmF1bHRQcmV2ZW50ZWQiLCJoYW5kbGVkIiwiZ2V0S2V5QmluZGluZ3NNYW5hZ2VyIiwiZ2V0QWNjZXNzaWJpbGl0eUFjdGlvbiIsImZvY3VzUmVmIiwidGFyZ2V0IiwiS2V5QmluZGluZ0FjdGlvbiIsIlRhYiIsImlkeCIsImluZGV4T2YiLCJzaGlmdEtleSIsIkhvbWUiLCJFbmQiLCJBcnJvd0Rvd24iLCJBcnJvd1JpZ2h0IiwiQXJyb3dVcCIsIkFycm93TGVmdCIsInByZXZlbnREZWZhdWx0Iiwic3RvcFByb3BhZ2F0aW9uIiwib25EcmFnRW5kSGFuZGxlciIsImNyZWF0ZUVsZW1lbnQiLCJQcm92aWRlciIsInZhbHVlIiwidXNlUm92aW5nVGFiSW5kZXgiLCJpbnB1dFJlZiIsInVzZUNvbnRleHQiLCJ1c2VSZWYiLCJ1c2VFZmZlY3QiLCJvbkZvY3VzIiwiaXNBY3RpdmUiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvYWNjZXNzaWJpbGl0eS9Sb3ZpbmdUYWJJbmRleC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7XG4gICAgY3JlYXRlQ29udGV4dCxcbiAgICB1c2VDYWxsYmFjayxcbiAgICB1c2VDb250ZXh0LFxuICAgIHVzZUVmZmVjdCxcbiAgICB1c2VNZW1vLFxuICAgIHVzZVJlZixcbiAgICB1c2VSZWR1Y2VyLFxuICAgIFJlZHVjZXIsXG4gICAgRGlzcGF0Y2gsXG4gICAgUmVmT2JqZWN0LFxuICAgIFJlYWN0Tm9kZSxcbn0gZnJvbSBcInJlYWN0XCI7XG5cbmltcG9ydCB7IGdldEtleUJpbmRpbmdzTWFuYWdlciB9IGZyb20gXCIuLi9LZXlCaW5kaW5nc01hbmFnZXJcIjtcbmltcG9ydCB7IEtleUJpbmRpbmdBY3Rpb24gfSBmcm9tIFwiLi9LZXlib2FyZFNob3J0Y3V0c1wiO1xuaW1wb3J0IHsgRm9jdXNIYW5kbGVyLCBSZWYgfSBmcm9tIFwiLi9yb3ZpbmcvdHlwZXNcIjtcblxuLyoqXG4gKiBNb2R1bGUgdG8gc2ltcGxpZnkgaW1wbGVtZW50aW5nIHRoZSBSb3ZpbmcgVGFiSW5kZXggYWNjZXNzaWJpbGl0eSB0ZWNobmlxdWVcbiAqXG4gKiBXcmFwIHRoZSBXaWRnZXQgaW4gYW4gUm92aW5nVGFiSW5kZXhDb250ZXh0UHJvdmlkZXJcbiAqIGFuZCB0aGVuIGZvciBhbGwgYnV0dG9ucyBtYWtlIHVzZSBvZiB1c2VSb3ZpbmdUYWJJbmRleCBvciBSb3ZpbmdUYWJJbmRleFdyYXBwZXIuXG4gKiBUaGUgY29kZSB3aWxsIGtlZXAgdHJhY2sgb2Ygd2hpY2ggdGFiSW5kZXggd2FzIG1vc3QgcmVjZW50bHkgZm9jdXNlZCBhbmQgZXhwb3NlIHRoYXQgaW5mb3JtYXRpb24gYXMgYGlzQWN0aXZlYCB3aGljaFxuICogY2FuIHRoZW4gYmUgdXNlZCB0byBvbmx5IHNldCB0aGUgdGFiSW5kZXggdG8gMCBhcyBleHBlY3RlZCBieSB0aGUgcm92aW5nIHRhYmluZGV4IHRlY2huaXF1ZS5cbiAqIFdoZW4gdGhlIGFjdGl2ZSBidXR0b24gZ2V0cyB1bm1vdW50ZWQgdGhlIGNsb3Nlc3QgYnV0dG9uIHdpbGwgYmUgY2hvc2VuIGFzIGV4cGVjdGVkLlxuICogSW5pdGlhbGx5IHRoZSBmaXJzdCBidXR0b24gdG8gbW91bnQgd2lsbCBiZSBnaXZlbiBhY3RpdmUgc3RhdGUuXG4gKlxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQWNjZXNzaWJpbGl0eS9LZXlib2FyZC1uYXZpZ2FibGVfSmF2YVNjcmlwdF93aWRnZXRzI1RlY2huaXF1ZV8xX1JvdmluZ190YWJpbmRleFxuICovXG5cbi8vIENoZWNrIGZvciBmb3JtIGVsZW1lbnRzIHdoaWNoIHV0aWxpemUgdGhlIGFycm93IGtleXMgZm9yIG5hdGl2ZSBmdW5jdGlvbnNcbi8vIGxpa2UgbWFueSBvZiB0aGUgdGV4dCBpbnB1dCB2YXJpZXRpZXMuXG4vL1xuLy8gaS5lLiBpdCdzIG9rIHRvIHByZXNzIHRoZSBkb3duIGFycm93IG9uIGEgcmFkaW8gYnV0dG9uIHRvIG1vdmUgdG8gdGhlIG5leHRcbi8vIHJhZGlvLiBCdXQgaXQncyBub3Qgb2sgdG8gcHJlc3MgdGhlIGRvd24gYXJyb3cgb24gYSA8aW5wdXQgdHlwZT1cInRleHRcIj4gdG9cbi8vIG1vdmUgYXdheSBiZWNhdXNlIHRoZSBkb3duIGFycm93IHNob3VsZCBtb3ZlIHRoZSBjdXJzb3IgdG8gdGhlIGVuZCBvZiB0aGVcbi8vIGlucHV0LlxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrSW5wdXRhYmxlRWxlbWVudChlbDogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZWwubWF0Y2hlcygnaW5wdXQ6bm90KFt0eXBlPVwicmFkaW9cIl0pOm5vdChbdHlwZT1cImNoZWNrYm94XCJdKSwgdGV4dGFyZWEsIHNlbGVjdCwgW2NvbnRlbnRlZGl0YWJsZT10cnVlXScpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgYWN0aXZlUmVmPzogUmVmO1xuICAgIHJlZnM6IFJlZltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElDb250ZXh0IHtcbiAgICBzdGF0ZTogSVN0YXRlO1xuICAgIGRpc3BhdGNoOiBEaXNwYXRjaDxJQWN0aW9uPjtcbn1cblxuZXhwb3J0IGNvbnN0IFJvdmluZ1RhYkluZGV4Q29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8SUNvbnRleHQ+KHtcbiAgICBzdGF0ZToge1xuICAgICAgICByZWZzOiBbXSwgLy8gbGlzdCBvZiByZWZzIGluIERPTSBvcmRlclxuICAgIH0sXG4gICAgZGlzcGF0Y2g6ICgpID0+IHt9LFxufSk7XG5Sb3ZpbmdUYWJJbmRleENvbnRleHQuZGlzcGxheU5hbWUgPSBcIlJvdmluZ1RhYkluZGV4Q29udGV4dFwiO1xuXG5leHBvcnQgZW51bSBUeXBlIHtcbiAgICBSZWdpc3RlciA9IFwiUkVHSVNURVJcIixcbiAgICBVbnJlZ2lzdGVyID0gXCJVTlJFR0lTVEVSXCIsXG4gICAgU2V0Rm9jdXMgPSBcIlNFVF9GT0NVU1wiLFxuICAgIFVwZGF0ZSA9IFwiVVBEQVRFXCIsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUFjdGlvbiB7XG4gICAgdHlwZTogRXhjbHVkZTxUeXBlLCBUeXBlLlVwZGF0ZT47XG4gICAgcGF5bG9hZDoge1xuICAgICAgICByZWY6IFJlZjtcbiAgICB9O1xufVxuXG5pbnRlcmZhY2UgVXBkYXRlQWN0aW9uIHtcbiAgICB0eXBlOiBUeXBlLlVwZGF0ZTtcbiAgICBwYXlsb2FkPzogdW5kZWZpbmVkO1xufVxuXG50eXBlIEFjdGlvbiA9IElBY3Rpb24gfCBVcGRhdGVBY3Rpb247XG5cbmNvbnN0IHJlZlNvcnRlciA9IChhOiBSZWYsIGI6IFJlZik6IG51bWJlciA9PiB7XG4gICAgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgY29uc3QgcG9zaXRpb24gPSBhLmN1cnJlbnQhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGIuY3VycmVudCEpO1xuXG4gICAgaWYgKHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9GT0xMT1dJTkcgfHwgcG9zaXRpb24gJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5FRF9CWSkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgfSBlbHNlIGlmIChwb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HIHx8IHBvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9DT05UQUlOUykge1xuICAgICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlcjogUmVkdWNlcjxJU3RhdGUsIEFjdGlvbj4gPSAoc3RhdGU6IElTdGF0ZSwgYWN0aW9uOiBBY3Rpb24pID0+IHtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgVHlwZS5SZWdpc3Rlcjoge1xuICAgICAgICAgICAgaWYgKCFzdGF0ZS5hY3RpdmVSZWYpIHtcbiAgICAgICAgICAgICAgICAvLyBPdXIgbGlzdCBvZiByZWZzIHdhcyBlbXB0eSwgc2V0IGFjdGl2ZVJlZiB0byB0aGlzIGZpcnN0IGl0ZW1cbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmVSZWYgPSBhY3Rpb24ucGF5bG9hZC5yZWY7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNhZGx5IGR1ZSB0byB0aGUgcG90ZW50aWFsIG9mIERPTSBlbGVtZW50cyBzd2FwcGluZyBvcmRlciB3ZSBjYW4ndCBkbyBhbnl0aGluZyBmYW5jeSBsaWtlIGEgYmluYXJ5IGluc2VydFxuICAgICAgICAgICAgc3RhdGUucmVmcy5wdXNoKGFjdGlvbi5wYXlsb2FkLnJlZik7XG4gICAgICAgICAgICBzdGF0ZS5yZWZzLnNvcnQocmVmU29ydGVyKTtcblxuICAgICAgICAgICAgcmV0dXJuIHsgLi4uc3RhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgVHlwZS5VbnJlZ2lzdGVyOiB7XG4gICAgICAgICAgICBjb25zdCBvbGRJbmRleCA9IHN0YXRlLnJlZnMuZmluZEluZGV4KChyKSA9PiByID09PSBhY3Rpb24ucGF5bG9hZC5yZWYpO1xuXG4gICAgICAgICAgICBpZiAob2xkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlOyAvLyBhbHJlYWR5IHJlbW92ZWQsIHRoaXMgc2hvdWxkIG5vdCBoYXBwZW5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN0YXRlLnJlZnMuc3BsaWNlKG9sZEluZGV4LCAxKVswXSA9PT0gc3RhdGUuYWN0aXZlUmVmKSB7XG4gICAgICAgICAgICAgICAgLy8gd2UganVzdCByZW1vdmVkIHRoZSBhY3RpdmUgcmVmLCBuZWVkIHRvIHJlcGxhY2UgaXRcbiAgICAgICAgICAgICAgICAvLyBwaWNrIHRoZSByZWYgY2xvc2VzdCB0byB0aGUgaW5kZXggdGhlIG9sZCByZWYgd2FzIGluXG4gICAgICAgICAgICAgICAgaWYgKG9sZEluZGV4ID49IHN0YXRlLnJlZnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZVJlZiA9IGZpbmRTaWJsaW5nRWxlbWVudChzdGF0ZS5yZWZzLCBzdGF0ZS5yZWZzLmxlbmd0aCAtIDEsIHRydWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZVJlZiA9XG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5kU2libGluZ0VsZW1lbnQoc3RhdGUucmVmcywgb2xkSW5kZXgpIHx8IGZpbmRTaWJsaW5nRWxlbWVudChzdGF0ZS5yZWZzLCBvbGRJbmRleCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBkb2N1bWVudC5ib2R5KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBmb2N1cyBnb3QgcmV2ZXJ0ZWQgdG8gdGhlIGJvZHkgdGhlbiB0aGUgdXNlciB3YXMgbGlrZWx5IGZvY3VzZWQgb24gdGhlIHVubW91bnRlZCBlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc3RhdGUuYWN0aXZlUmVmPy5jdXJyZW50Py5mb2N1cygpLCAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgcmVmcyBsaXN0XG4gICAgICAgICAgICByZXR1cm4geyAuLi5zdGF0ZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBUeXBlLlNldEZvY3VzOiB7XG4gICAgICAgICAgICAvLyBpZiB0aGUgcmVmIGRvZXNuJ3QgY2hhbmdlIGp1c3QgcmV0dXJuIHRoZSBzYW1lIG9iamVjdCByZWZlcmVuY2UgdG8gc2tpcCBhIHJlLXJlbmRlclxuICAgICAgICAgICAgaWYgKHN0YXRlLmFjdGl2ZVJlZiA9PT0gYWN0aW9uLnBheWxvYWQucmVmKSByZXR1cm4gc3RhdGU7XG4gICAgICAgICAgICAvLyB1cGRhdGUgYWN0aXZlIHJlZlxuICAgICAgICAgICAgc3RhdGUuYWN0aXZlUmVmID0gYWN0aW9uLnBheWxvYWQucmVmO1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4uc3RhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgVHlwZS5VcGRhdGU6IHtcbiAgICAgICAgICAgIHN0YXRlLnJlZnMuc29ydChyZWZTb3J0ZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4uc3RhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfVxufTtcblxuaW50ZXJmYWNlIElQcm9wcyB7XG4gICAgaGFuZGxlTG9vcD86IGJvb2xlYW47XG4gICAgaGFuZGxlSG9tZUVuZD86IGJvb2xlYW47XG4gICAgaGFuZGxlVXBEb3duPzogYm9vbGVhbjtcbiAgICBoYW5kbGVMZWZ0UmlnaHQ/OiBib29sZWFuO1xuICAgIGhhbmRsZUlucHV0RmllbGRzPzogYm9vbGVhbjtcbiAgICBzY3JvbGxJbnRvVmlldz86IGJvb2xlYW4gfCBTY3JvbGxJbnRvVmlld09wdGlvbnM7XG4gICAgY2hpbGRyZW4ocmVuZGVyUHJvcHM6IHsgb25LZXlEb3duSGFuZGxlcihldjogUmVhY3QuS2V5Ym9hcmRFdmVudCk6IHZvaWQ7IG9uRHJhZ0VuZEhhbmRsZXIoKTogdm9pZCB9KTogUmVhY3ROb2RlO1xuICAgIG9uS2V5RG93bj8oZXY6IFJlYWN0LktleWJvYXJkRXZlbnQsIHN0YXRlOiBJU3RhdGUsIGRpc3BhdGNoOiBEaXNwYXRjaDxJQWN0aW9uPik6IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCBmaW5kU2libGluZ0VsZW1lbnQgPSAoXG4gICAgcmVmczogUmVmT2JqZWN0PEhUTUxFbGVtZW50PltdLFxuICAgIHN0YXJ0SW5kZXg6IG51bWJlcixcbiAgICBiYWNrd2FyZHMgPSBmYWxzZSxcbiAgICBsb29wID0gZmFsc2UsXG4pOiBSZWZPYmplY3Q8SFRNTEVsZW1lbnQ+IHwgdW5kZWZpbmVkID0+IHtcbiAgICBpZiAoYmFja3dhcmRzKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydEluZGV4OyBpIDwgcmVmcy5sZW5ndGggJiYgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGlmIChyZWZzW2ldLmN1cnJlbnQ/Lm9mZnNldFBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWZzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChsb29wKSB7XG4gICAgICAgICAgICByZXR1cm4gZmluZFNpYmxpbmdFbGVtZW50KHJlZnMuc2xpY2Uoc3RhcnRJbmRleCArIDEpLCByZWZzLmxlbmd0aCAtIDEsIHRydWUsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydEluZGV4OyBpIDwgcmVmcy5sZW5ndGggJiYgaSA+PSAwOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChyZWZzW2ldLmN1cnJlbnQ/Lm9mZnNldFBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWZzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChsb29wKSB7XG4gICAgICAgICAgICByZXR1cm4gZmluZFNpYmxpbmdFbGVtZW50KHJlZnMuc2xpY2UoMCwgc3RhcnRJbmRleCksIDAsIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5leHBvcnQgY29uc3QgUm92aW5nVGFiSW5kZXhQcm92aWRlcjogUmVhY3QuRkM8SVByb3BzPiA9ICh7XG4gICAgY2hpbGRyZW4sXG4gICAgaGFuZGxlSG9tZUVuZCxcbiAgICBoYW5kbGVVcERvd24sXG4gICAgaGFuZGxlTGVmdFJpZ2h0LFxuICAgIGhhbmRsZUxvb3AsXG4gICAgaGFuZGxlSW5wdXRGaWVsZHMsXG4gICAgc2Nyb2xsSW50b1ZpZXcsXG4gICAgb25LZXlEb3duLFxufSkgPT4ge1xuICAgIGNvbnN0IFtzdGF0ZSwgZGlzcGF0Y2hdID0gdXNlUmVkdWNlcjxSZWR1Y2VyPElTdGF0ZSwgQWN0aW9uPj4ocmVkdWNlciwge1xuICAgICAgICByZWZzOiBbXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNvbnRleHQgPSB1c2VNZW1vPElDb250ZXh0PigoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSksIFtzdGF0ZV0pO1xuXG4gICAgY29uc3Qgb25LZXlEb3duSGFuZGxlciA9IHVzZUNhbGxiYWNrKFxuICAgICAgICAoZXY6IFJlYWN0LktleWJvYXJkRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChvbktleURvd24pIHtcbiAgICAgICAgICAgICAgICBvbktleURvd24oZXYsIGNvbnRleHQuc3RhdGUsIGNvbnRleHQuZGlzcGF0Y2gpO1xuICAgICAgICAgICAgICAgIGlmIChldi5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBoYW5kbGVkID0gZmFsc2U7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb24gPSBnZXRLZXlCaW5kaW5nc01hbmFnZXIoKS5nZXRBY2Nlc3NpYmlsaXR5QWN0aW9uKGV2KTtcbiAgICAgICAgICAgIGxldCBmb2N1c1JlZjogUmVmT2JqZWN0PEhUTUxFbGVtZW50PiB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIC8vIERvbid0IGludGVyZmVyZSB3aXRoIGlucHV0IGRlZmF1bHQga2V5ZG93biBiZWhhdmlvdXJcbiAgICAgICAgICAgIC8vIGJ1dCBhbGxvdyBwZW9wbGUgdG8gbW92ZSBmb2N1cyBmcm9tIGl0IHdpdGggVGFiLlxuICAgICAgICAgICAgaWYgKCFoYW5kbGVJbnB1dEZpZWxkcyAmJiBjaGVja0lucHV0YWJsZUVsZW1lbnQoZXYudGFyZ2V0IGFzIEhUTUxFbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5QmluZGluZ0FjdGlvbi5UYWI6XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LnN0YXRlLnJlZnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkeCA9IGNvbnRleHQuc3RhdGUucmVmcy5pbmRleE9mKGNvbnRleHQuc3RhdGUuYWN0aXZlUmVmISk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9jdXNSZWYgPSBmaW5kU2libGluZ0VsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuc3RhdGUucmVmcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4ICsgKGV2LnNoaWZ0S2V5ID8gLTEgOiAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXYuc2hpZnRLZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgYWN0dWFsbHkgaGF2ZSBhbnkgaXRlbXNcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGFjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUJpbmRpbmdBY3Rpb24uSG9tZTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVIb21lRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW92ZSBmb2N1cyB0byBmaXJzdCAodmlzaWJsZSkgaXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvY3VzUmVmID0gZmluZFNpYmxpbmdFbGVtZW50KGNvbnRleHQuc3RhdGUucmVmcywgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUJpbmRpbmdBY3Rpb24uRW5kOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhbmRsZUhvbWVFbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIGZvY3VzIHRvIGxhc3QgKHZpc2libGUpIGl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb2N1c1JlZiA9IGZpbmRTaWJsaW5nRWxlbWVudChjb250ZXh0LnN0YXRlLnJlZnMsIGNvbnRleHQuc3RhdGUucmVmcy5sZW5ndGggLSAxLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5QmluZGluZ0FjdGlvbi5BcnJvd0Rvd246XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5QmluZGluZ0FjdGlvbi5BcnJvd1JpZ2h0OlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhY3Rpb24gPT09IEtleUJpbmRpbmdBY3Rpb24uQXJyb3dEb3duICYmIGhhbmRsZVVwRG93bikgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYWN0aW9uID09PSBLZXlCaW5kaW5nQWN0aW9uLkFycm93UmlnaHQgJiYgaGFuZGxlTGVmdFJpZ2h0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuc3RhdGUucmVmcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkeCA9IGNvbnRleHQuc3RhdGUucmVmcy5pbmRleE9mKGNvbnRleHQuc3RhdGUuYWN0aXZlUmVmISk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvY3VzUmVmID0gZmluZFNpYmxpbmdFbGVtZW50KGNvbnRleHQuc3RhdGUucmVmcywgaWR4ICsgMSwgZmFsc2UsIGhhbmRsZUxvb3ApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgS2V5QmluZGluZ0FjdGlvbi5BcnJvd1VwOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIEtleUJpbmRpbmdBY3Rpb24uQXJyb3dMZWZ0OlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhY3Rpb24gPT09IEtleUJpbmRpbmdBY3Rpb24uQXJyb3dVcCAmJiBoYW5kbGVVcERvd24pIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFjdGlvbiA9PT0gS2V5QmluZGluZ0FjdGlvbi5BcnJvd0xlZnQgJiYgaGFuZGxlTGVmdFJpZ2h0KVxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuc3RhdGUucmVmcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkeCA9IGNvbnRleHQuc3RhdGUucmVmcy5pbmRleE9mKGNvbnRleHQuc3RhdGUuYWN0aXZlUmVmISk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvY3VzUmVmID0gZmluZFNpYmxpbmdFbGVtZW50KGNvbnRleHQuc3RhdGUucmVmcywgaWR4IC0gMSwgdHJ1ZSwgaGFuZGxlTG9vcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaGFuZGxlZCkge1xuICAgICAgICAgICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChmb2N1c1JlZikge1xuICAgICAgICAgICAgICAgIGZvY3VzUmVmLmN1cnJlbnQ/LmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgLy8gcHJvZ3JhbW1hdGljIGZvY3VzIGRvZXNuJ3QgZmlyZSB0aGUgb25Gb2N1cyBoYW5kbGVyLCBzbyB3ZSBtdXN0IGRvIHRoZSBkbyBvdXJzZWx2ZXNcbiAgICAgICAgICAgICAgICBkaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFR5cGUuU2V0Rm9jdXMsXG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZjogZm9jdXNSZWYsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKHNjcm9sbEludG9WaWV3KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvY3VzUmVmLmN1cnJlbnQ/LnNjcm9sbEludG9WaWV3KHNjcm9sbEludG9WaWV3KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFtcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBvbktleURvd24sXG4gICAgICAgICAgICBoYW5kbGVIb21lRW5kLFxuICAgICAgICAgICAgaGFuZGxlVXBEb3duLFxuICAgICAgICAgICAgaGFuZGxlTGVmdFJpZ2h0LFxuICAgICAgICAgICAgaGFuZGxlTG9vcCxcbiAgICAgICAgICAgIGhhbmRsZUlucHV0RmllbGRzLFxuICAgICAgICAgICAgc2Nyb2xsSW50b1ZpZXcsXG4gICAgICAgIF0sXG4gICAgKTtcblxuICAgIGNvbnN0IG9uRHJhZ0VuZEhhbmRsZXIgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgICAgIGRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6IFR5cGUuVXBkYXRlLFxuICAgICAgICB9KTtcbiAgICB9LCBbXSk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8Um92aW5nVGFiSW5kZXhDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXtjb250ZXh0fT5cbiAgICAgICAgICAgIHtjaGlsZHJlbih7IG9uS2V5RG93bkhhbmRsZXIsIG9uRHJhZ0VuZEhhbmRsZXIgfSl9XG4gICAgICAgIDwvUm92aW5nVGFiSW5kZXhDb250ZXh0LlByb3ZpZGVyPlxuICAgICk7XG59O1xuXG4vLyBIb29rIHRvIHJlZ2lzdGVyIGEgcm92aW5nIHRhYiBpbmRleFxuLy8gaW5wdXRSZWYgcGFyYW1ldGVyIHNwZWNpZmllcyB0aGUgcmVmIHRvIHVzZVxuLy8gb25Gb2N1cyBzaG91bGQgYmUgY2FsbGVkIHdoZW4gdGhlIGluZGV4IGdhaW5lZCBmb2N1cyBpbiBhbnkgbWFubmVyXG4vLyBpc0FjdGl2ZSBzaG91bGQgYmUgdXNlZCB0byBzZXQgdGFiSW5kZXggaW4gYSBtYW5uZXIgc3VjaCBhcyBgdGFiSW5kZXg9e2lzQWN0aXZlID8gMCA6IC0xfWBcbi8vIHJlZiBzaG91bGQgYmUgcGFzc2VkIHRvIGEgRE9NIG5vZGUgd2hpY2ggd2lsbCBiZSB1c2VkIGZvciBET00gY29tcGFyZURvY3VtZW50UG9zaXRpb25cbmV4cG9ydCBjb25zdCB1c2VSb3ZpbmdUYWJJbmRleCA9IDxUIGV4dGVuZHMgSFRNTEVsZW1lbnQ+KFxuICAgIGlucHV0UmVmPzogUmVmT2JqZWN0PFQ+LFxuKTogW0ZvY3VzSGFuZGxlciwgYm9vbGVhbiwgUmVmT2JqZWN0PFQ+XSA9PiB7XG4gICAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoUm92aW5nVGFiSW5kZXhDb250ZXh0KTtcbiAgICBsZXQgcmVmID0gdXNlUmVmPFQ+KG51bGwpO1xuXG4gICAgaWYgKGlucHV0UmVmKSB7XG4gICAgICAgIC8vIGlmIHdlIGFyZSBnaXZlbiBhIHJlZiwgdXNlIGl0IGluc3RlYWQgb2Ygb3Vyc1xuICAgICAgICByZWYgPSBpbnB1dFJlZjtcbiAgICB9XG5cbiAgICAvLyBzZXR1cCAoYWZ0ZXIgcmVmcylcbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBjb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6IFR5cGUuUmVnaXN0ZXIsXG4gICAgICAgICAgICBwYXlsb2FkOiB7IHJlZiB9LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gdGVhcmRvd25cbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IFR5cGUuVW5yZWdpc3RlcixcbiAgICAgICAgICAgICAgICBwYXlsb2FkOiB7IHJlZiB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfSwgW10pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuXG4gICAgY29uc3Qgb25Gb2N1cyA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICB0eXBlOiBUeXBlLlNldEZvY3VzLFxuICAgICAgICAgICAgcGF5bG9hZDogeyByZWYgfSxcbiAgICAgICAgfSk7XG4gICAgfSwgW10pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuXG4gICAgY29uc3QgaXNBY3RpdmUgPSBjb250ZXh0LnN0YXRlLmFjdGl2ZVJlZiA9PT0gcmVmO1xuICAgIHJldHVybiBbb25Gb2N1cywgaXNBY3RpdmUsIHJlZl07XG59O1xuXG4vLyByZS1leHBvcnQgdGhlIHNlbWFudGljIGhlbHBlciBjb21wb25lbnRzIGZvciBzaW1wbGljaXR5XG5leHBvcnQgeyBSb3ZpbmdUYWJJbmRleFdyYXBwZXIgfSBmcm9tIFwiLi9yb3ZpbmcvUm92aW5nVGFiSW5kZXhXcmFwcGVyXCI7XG5leHBvcnQgeyBSb3ZpbmdBY2Nlc3NpYmxlQnV0dG9uIH0gZnJvbSBcIi4vcm92aW5nL1JvdmluZ0FjY2Vzc2libGVCdXR0b25cIjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFjQSxJQUFBQyxtQkFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsa0JBQUEsR0FBQUYsT0FBQTtBQXVXQSxJQUFBRyxzQkFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksdUJBQUEsR0FBQUosT0FBQTtBQUF5RSxTQUFBSyx5QkFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxtQkFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBRix3QkFBQSxZQUFBQSxDQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBUCx3QkFBQU8sQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFdBQUFLLE9BQUEsRUFBQUwsQ0FBQSxRQUFBRyxDQUFBLEdBQUFKLHdCQUFBLENBQUFHLENBQUEsT0FBQUMsQ0FBQSxJQUFBQSxDQUFBLENBQUFHLEdBQUEsQ0FBQU4sQ0FBQSxVQUFBRyxDQUFBLENBQUFJLEdBQUEsQ0FBQVAsQ0FBQSxPQUFBUSxDQUFBLEtBQUFDLFNBQUEsVUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLGNBQUEsSUFBQUQsTUFBQSxDQUFBRSx3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