UNPKG

botframework-webchat-component

Version:
201 lines (193 loc) 35.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = useObserveFocusVisible; var _botframeworkWebchatApi = require("botframework-webchat-api"); var _react = require("react"); var _supportPseudoClass = _interopRequireDefault(require("../../Utils/supportPseudoClass")); var _useNonce3 = _interopRequireDefault(require("./useNonce")); var _useValueRef = _interopRequireDefault(require("./useValueRef")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } var usePonyfill = _botframeworkWebchatApi.hooks.usePonyfill; var INPUT_TYPES_ALLOW_LIST = ['date', 'datetime-local', 'datetime', 'email', 'month', 'number', 'password', 'search', 'tel', 'text', 'time', 'url', 'week']; /** * Computes whether the given element should automatically trigger the * `focus-visible` class being added, i.e. whether it should always match * `:focus-visible` when focused. * @param {Element} el * @return {boolean} */ function focusTriggersKeyboardModality(el) { var isContentEditable = el.isContentEditable, readOnly = el.readOnly, tagName = el.tagName, type = el.type; return tagName === 'INPUT' && INPUT_TYPES_ALLOW_LIST.includes(type) && !readOnly || tagName === 'TEXTAREA' && !readOnly || isContentEditable; } function createEventSubscription(target, types, handler) { var subscribed; var subscribe = function subscribe() { if (!subscribed) { types.forEach(function (type) { return target.addEventListener(type, handler); }); subscribed = true; } }; var unsubscribe = function unsubscribe() { if (subscribed) { types.forEach(function (type) { return target.removeEventListener(type, handler); }); subscribed = undefined; } }; return { pause: unsubscribe, resume: subscribe }; } // TODO: Add tests // 1. Focus via keyboard vs. mouse // 2. Focus via keyboard, switch app, switch back (expect to get another focusVisible after switch back) // 3. Focus via mouse, switch app, switch back (do NOT expect to get another focusVisible after switch back) function useObserveFocusVisibleForLegacyBrowsers(targetRef, onFocusVisibleRef) { var _usePonyfill = usePonyfill(), _usePonyfill2 = _slicedToArray(_usePonyfill, 1), Date = _usePonyfill2[0].Date; // This polyfill algorithm is adopted from https://github.com/WICG/focus-visible. var blurSinceRef = (0, _react.useRef)(0); var hadKeyboardEventRef = (0, _react.useRef)(true); var hasFocusVisibleRef = (0, _react.useRef)(false); var eventSubscription = (0, _react.useMemo)(function () { return createEventSubscription(document, ['mousemove', 'mousedown', 'mouseup', 'pointermove', 'pointerdown', 'pointerup', 'touchmove', 'touchstart', 'touchend'], function (event) { var _nodeName; if (((_nodeName = event.target.nodeName) === null || _nodeName === void 0 ? void 0 : _nodeName.toLowerCase()) !== 'html') { hadKeyboardEventRef.current = false; eventSubscription.pause(); } }); }, [hadKeyboardEventRef]); var setHasFocusVisible = (0, _react.useCallback)(function (nextHasFocusVisible) { if (hasFocusVisibleRef.current !== nextHasFocusVisible) { hasFocusVisibleRef.current = nextHasFocusVisible; nextHasFocusVisible && (onFocusVisibleRef === null || onFocusVisibleRef === void 0 ? void 0 : onFocusVisibleRef.current()); } }, [hasFocusVisibleRef, onFocusVisibleRef]); var handleKeyDown = (0, _react.useCallback)(function (event) { if (event.altKey || event.ctrlKey || event.metaKey) { return; } if (event.target === targetRef.current) { setHasFocusVisible(true); } hadKeyboardEventRef.current = true; }, [hadKeyboardEventRef, setHasFocusVisible, targetRef]); var handlePointerDown = (0, _react.useCallback)(function () { hadKeyboardEventRef.current = false; }, [hadKeyboardEventRef]); var handleFocus = (0, _react.useCallback)(function (_ref) { var target = _ref.target; target === targetRef.current && (hadKeyboardEventRef.current || focusTriggersKeyboardModality(target)) && setHasFocusVisible(true); }, [hadKeyboardEventRef, setHasFocusVisible, targetRef]); var handleBlur = (0, _react.useCallback)(function (event) { if (event.target === targetRef.current && hasFocusVisibleRef.current) { blurSinceRef.current = Date.now(); setHasFocusVisible(false); } }, [blurSinceRef, Date, hasFocusVisibleRef, setHasFocusVisible, targetRef]); var handleVisibilityChange = (0, _react.useCallback)(function () { if (document.visibilityState === 'hidden') { // The element is blurred due to "visibilityState" set to "hidden". // 100ms is referenced from the WICG polyfill. // eslint-disable-next-line no-magic-numbers if (Date.now() - blurSinceRef.current < 100) { hadKeyboardEventRef.current = true; } eventSubscription.resume(); } }, [blurSinceRef, Date, eventSubscription, hadKeyboardEventRef]); (0, _react.useEffect)(function () { document.addEventListener('keydown', handleKeyDown, true); document.addEventListener('mousedown', handlePointerDown, true); document.addEventListener('pointerdown', handlePointerDown, true); document.addEventListener('touchstart', handlePointerDown, true); document.addEventListener('visibilitychange', handleVisibilityChange, true); return function () { document.removeEventListener('keydown', handleKeyDown); document.removeEventListener('mousedown', handlePointerDown); document.removeEventListener('pointerdown', handlePointerDown); document.removeEventListener('touchstart', handlePointerDown); document.removeEventListener('visibilitychange', handleVisibilityChange); }; }, [handleKeyDown, handlePointerDown, handleVisibilityChange]); (0, _react.useEffect)(function () { var target = targetRef.current; target.addEventListener('blur', handleBlur, true); target.addEventListener('focus', handleFocus, true); return function () { target.removeEventListener('blur', handleBlur); target.removeEventListener('focus', handleFocus); }; // We specifically add "targetRef.current" here. // If the target element changed, we should reattach our event listeners. }, [handleBlur, handleFocus, targetRef]); (0, _react.useEffect)(function () { eventSubscription.resume(); return function () { return eventSubscription.pause(); }; }, [eventSubscription]); } function useObserveFocusVisibleForModernBrowsers(targetRef, onFocusVisibleRef) { var handleFocus = (0, _react.useCallback)(function () { var current = targetRef.current; if ( // "msMatchesSelector" is vendor-prefixed version of "matches". // eslint-disable-next-line dot-notation (current.matches || current['msMatchesSelector']).call(current, ':focus-visible')) { onFocusVisibleRef === null || onFocusVisibleRef === void 0 ? void 0 : onFocusVisibleRef.current(); } }, [onFocusVisibleRef, targetRef]); (0, _react.useEffect)(function () { var target = targetRef.current; target.addEventListener('focus', handleFocus); return function () { return target.removeEventListener('focus', handleFocus); }; // We specifically add "targetRef.current" here. // If the target element changed, we should reattach our event listeners. // eslint-disable-next-line react-hooks/exhaustive-deps }, [handleFocus, targetRef, targetRef.current]); } function useObserveFocusVisible(targetRef, onFocusVisible) { var _useNonce = (0, _useNonce3.default)(), _useNonce2 = _slicedToArray(_useNonce, 1), nonce = _useNonce2[0]; var onFocusVisibleRef = (0, _useValueRef.default)(onFocusVisible); // The nonce is use for browser capabilities. Just in case the "nonce" had changed unexpectedly, the capabilities of the browser should never change. // Thus, we are using an initial version of "nonce". In case web devs changed the "nonce" to an invalid value, we won't break rules of hooks (as stated below). var nonceRef = (0, _react.useRef)(nonce); // ":focus-visible" selector is supported from Chrome/Edge 86+ and not supported in IE11 or Safari. // Doing a capability check on pseudo classes requires injecting a stylesheet, thus nonce is needed. var supportFocusVisible = (0, _react.useMemo)(function () { return (0, _supportPseudoClass.default)(':focus-visible', nonceRef.current); }, [nonceRef]); // Since "supportPseudoClass" is a browser capability, the result should be constant during the page lifetime. // Thus, running hooks conditionally is okay here. if (supportFocusVisible) { // eslint-disable-next-line react-hooks/rules-of-hooks useObserveFocusVisibleForModernBrowsers(targetRef, onFocusVisibleRef); } else { // eslint-disable-next-line react-hooks/rules-of-hooks useObserveFocusVisibleForLegacyBrowsers(targetRef, onFocusVisibleRef); } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfYm90ZnJhbWV3b3JrV2ViY2hhdEFwaSIsInJlcXVpcmUiLCJfcmVhY3QiLCJfc3VwcG9ydFBzZXVkb0NsYXNzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl91c2VOb25jZTMiLCJfdXNlVmFsdWVSZWYiLCJvYmoiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsIl9zbGljZWRUb0FycmF5IiwiYXJyIiwiaSIsIl9hcnJheVdpdGhIb2xlcyIsIl9pdGVyYWJsZVRvQXJyYXlMaW1pdCIsIl91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSIsIl9ub25JdGVyYWJsZVJlc3QiLCJUeXBlRXJyb3IiLCJvIiwibWluTGVuIiwiX2FycmF5TGlrZVRvQXJyYXkiLCJuIiwiT2JqZWN0IiwicHJvdG90eXBlIiwidG9TdHJpbmciLCJjYWxsIiwic2xpY2UiLCJjb25zdHJ1Y3RvciIsIm5hbWUiLCJBcnJheSIsImZyb20iLCJ0ZXN0IiwibGVuIiwibGVuZ3RoIiwiYXJyMiIsIl9pIiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJfYXJyIiwiX24iLCJfZCIsIl9zIiwiX2UiLCJuZXh0IiwiZG9uZSIsInB1c2giLCJ2YWx1ZSIsImVyciIsImlzQXJyYXkiLCJ1c2VQb255ZmlsbCIsImhvb2tzIiwiSU5QVVRfVFlQRVNfQUxMT1dfTElTVCIsImZvY3VzVHJpZ2dlcnNLZXlib2FyZE1vZGFsaXR5IiwiZWwiLCJpc0NvbnRlbnRFZGl0YWJsZSIsInJlYWRPbmx5IiwidGFnTmFtZSIsInR5cGUiLCJpbmNsdWRlcyIsImNyZWF0ZUV2ZW50U3Vic2NyaXB0aW9uIiwidGFyZ2V0IiwidHlwZXMiLCJoYW5kbGVyIiwic3Vic2NyaWJlZCIsInN1YnNjcmliZSIsImZvckVhY2giLCJhZGRFdmVudExpc3RlbmVyIiwidW5zdWJzY3JpYmUiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwidW5kZWZpbmVkIiwicGF1c2UiLCJyZXN1bWUiLCJ1c2VPYnNlcnZlRm9jdXNWaXNpYmxlRm9yTGVnYWN5QnJvd3NlcnMiLCJ0YXJnZXRSZWYiLCJvbkZvY3VzVmlzaWJsZVJlZiIsIl91c2VQb255ZmlsbCIsIl91c2VQb255ZmlsbDIiLCJEYXRlIiwiYmx1clNpbmNlUmVmIiwidXNlUmVmIiwiaGFkS2V5Ym9hcmRFdmVudFJlZiIsImhhc0ZvY3VzVmlzaWJsZVJlZiIsImV2ZW50U3Vic2NyaXB0aW9uIiwidXNlTWVtbyIsImRvY3VtZW50IiwiZXZlbnQiLCJfbm9kZU5hbWUiLCJub2RlTmFtZSIsInRvTG93ZXJDYXNlIiwiY3VycmVudCIsInNldEhhc0ZvY3VzVmlzaWJsZSIsInVzZUNhbGxiYWNrIiwibmV4dEhhc0ZvY3VzVmlzaWJsZSIsImhhbmRsZUtleURvd24iLCJhbHRLZXkiLCJjdHJsS2V5IiwibWV0YUtleSIsImhhbmRsZVBvaW50ZXJEb3duIiwiaGFuZGxlRm9jdXMiLCJfcmVmIiwiaGFuZGxlQmx1ciIsIm5vdyIsImhhbmRsZVZpc2liaWxpdHlDaGFuZ2UiLCJ2aXNpYmlsaXR5U3RhdGUiLCJ1c2VFZmZlY3QiLCJ1c2VPYnNlcnZlRm9jdXNWaXNpYmxlRm9yTW9kZXJuQnJvd3NlcnMiLCJtYXRjaGVzIiwidXNlT2JzZXJ2ZUZvY3VzVmlzaWJsZSIsIm9uRm9jdXNWaXNpYmxlIiwiX3VzZU5vbmNlIiwidXNlTm9uY2UiLCJfdXNlTm9uY2UyIiwibm9uY2UiLCJ1c2VWYWx1ZVJlZiIsIm5vbmNlUmVmIiwic3VwcG9ydEZvY3VzVmlzaWJsZSIsInN1cHBvcnRQc2V1ZG9DbGFzcyJdLCJzb3VyY2VSb290IjoiY29tcG9uZW50Oi8vLyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hvb2tzL2ludGVybmFsL3VzZU9ic2VydmVGb2N1c1Zpc2libGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaG9va3MgfSBmcm9tICdib3RmcmFtZXdvcmstd2ViY2hhdC1hcGknO1xuaW1wb3J0IHsgTXV0YWJsZVJlZk9iamVjdCwgUmVmT2JqZWN0LCB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VNZW1vLCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5cbmltcG9ydCBzdXBwb3J0UHNldWRvQ2xhc3MgZnJvbSAnLi4vLi4vVXRpbHMvc3VwcG9ydFBzZXVkb0NsYXNzJztcbmltcG9ydCB1c2VOb25jZSBmcm9tICcuL3VzZU5vbmNlJztcbmltcG9ydCB1c2VWYWx1ZVJlZiBmcm9tICcuL3VzZVZhbHVlUmVmJztcblxuY29uc3QgeyB1c2VQb255ZmlsbCB9ID0gaG9va3M7XG5cbmNvbnN0IElOUFVUX1RZUEVTX0FMTE9XX0xJU1QgPSBbXG4gICdkYXRlJyxcbiAgJ2RhdGV0aW1lLWxvY2FsJyxcbiAgJ2RhdGV0aW1lJyxcbiAgJ2VtYWlsJyxcbiAgJ21vbnRoJyxcbiAgJ251bWJlcicsXG4gICdwYXNzd29yZCcsXG4gICdzZWFyY2gnLFxuICAndGVsJyxcbiAgJ3RleHQnLFxuICAndGltZScsXG4gICd1cmwnLFxuICAnd2Vlaydcbl07XG5cbi8qKlxuICogQ29tcHV0ZXMgd2hldGhlciB0aGUgZ2l2ZW4gZWxlbWVudCBzaG91bGQgYXV0b21hdGljYWxseSB0cmlnZ2VyIHRoZVxuICogYGZvY3VzLXZpc2libGVgIGNsYXNzIGJlaW5nIGFkZGVkLCBpLmUuIHdoZXRoZXIgaXQgc2hvdWxkIGFsd2F5cyBtYXRjaFxuICogYDpmb2N1cy12aXNpYmxlYCB3aGVuIGZvY3VzZWQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBmb2N1c1RyaWdnZXJzS2V5Ym9hcmRNb2RhbGl0eShlbDogSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQpOiBib29sZWFuIHtcbiAgY29uc3QgeyBpc0NvbnRlbnRFZGl0YWJsZSwgcmVhZE9ubHksIHRhZ05hbWUsIHR5cGUgfSA9IGVsO1xuXG4gIHJldHVybiAoXG4gICAgKHRhZ05hbWUgPT09ICdJTlBVVCcgJiYgSU5QVVRfVFlQRVNfQUxMT1dfTElTVC5pbmNsdWRlcyh0eXBlKSAmJiAhcmVhZE9ubHkpIHx8XG4gICAgKHRhZ05hbWUgPT09ICdURVhUQVJFQScgJiYgIXJlYWRPbmx5KSB8fFxuICAgIGlzQ29udGVudEVkaXRhYmxlXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUV2ZW50U3Vic2NyaXB0aW9uKFxuICB0YXJnZXQ6IEVsZW1lbnQgfCBOb2RlLFxuICB0eXBlczogc3RyaW5nW10sXG4gIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWRcbik6IHtcbiAgcGF1c2U6ICgpID0+IHZvaWQ7XG4gIHJlc3VtZTogKCkgPT4gdm9pZDtcbn0ge1xuICBsZXQgc3Vic2NyaWJlZDogdHJ1ZTtcblxuICBjb25zdCBzdWJzY3JpYmUgPSAoKSA9PiB7XG4gICAgaWYgKCFzdWJzY3JpYmVkKSB7XG4gICAgICB0eXBlcy5mb3JFYWNoKHR5cGUgPT4gdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlcikpO1xuICAgICAgc3Vic2NyaWJlZCA9IHRydWU7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHVuc3Vic2NyaWJlID0gKCkgPT4ge1xuICAgIGlmIChzdWJzY3JpYmVkKSB7XG4gICAgICB0eXBlcy5mb3JFYWNoKHR5cGUgPT4gdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlcikpO1xuICAgICAgc3Vic2NyaWJlZCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBwYXVzZTogdW5zdWJzY3JpYmUsXG4gICAgcmVzdW1lOiBzdWJzY3JpYmVcbiAgfTtcbn1cblxuLy8gVE9ETzogQWRkIHRlc3RzXG4vLyAgICAgICAxLiBGb2N1cyB2aWEga2V5Ym9hcmQgdnMuIG1vdXNlXG4vLyAgICAgICAyLiBGb2N1cyB2aWEga2V5Ym9hcmQsIHN3aXRjaCBhcHAsIHN3aXRjaCBiYWNrIChleHBlY3QgdG8gZ2V0IGFub3RoZXIgZm9jdXNWaXNpYmxlIGFmdGVyIHN3aXRjaCBiYWNrKVxuLy8gICAgICAgMy4gRm9jdXMgdmlhIG1vdXNlLCBzd2l0Y2ggYXBwLCBzd2l0Y2ggYmFjayAoZG8gTk9UIGV4cGVjdCB0byBnZXQgYW5vdGhlciBmb2N1c1Zpc2libGUgYWZ0ZXIgc3dpdGNoIGJhY2spXG5mdW5jdGlvbiB1c2VPYnNlcnZlRm9jdXNWaXNpYmxlRm9yTGVnYWN5QnJvd3NlcnMoXG4gIHRhcmdldFJlZjogUmVmT2JqZWN0PEhUTUxFbGVtZW50PixcbiAgb25Gb2N1c1Zpc2libGVSZWY6IE11dGFibGVSZWZPYmplY3Q8KCkgPT4gdm9pZD5cbikge1xuICBjb25zdCBbeyBEYXRlIH1dID0gdXNlUG9ueWZpbGwoKTtcbiAgLy8gVGhpcyBwb2x5ZmlsbCBhbGdvcml0aG0gaXMgYWRvcHRlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9XSUNHL2ZvY3VzLXZpc2libGUuXG4gIGNvbnN0IGJsdXJTaW5jZVJlZiA9IHVzZVJlZigwKTtcbiAgY29uc3QgaGFkS2V5Ym9hcmRFdmVudFJlZiA9IHVzZVJlZih0cnVlKTtcbiAgY29uc3QgaGFzRm9jdXNWaXNpYmxlUmVmID0gdXNlUmVmKGZhbHNlKTtcblxuICBjb25zdCBldmVudFN1YnNjcmlwdGlvbiA9IHVzZU1lbW8oXG4gICAgKCkgPT5cbiAgICAgIGNyZWF0ZUV2ZW50U3Vic2NyaXB0aW9uKFxuICAgICAgICBkb2N1bWVudCxcbiAgICAgICAgW1xuICAgICAgICAgICdtb3VzZW1vdmUnLFxuICAgICAgICAgICdtb3VzZWRvd24nLFxuICAgICAgICAgICdtb3VzZXVwJyxcbiAgICAgICAgICAncG9pbnRlcm1vdmUnLFxuICAgICAgICAgICdwb2ludGVyZG93bicsXG4gICAgICAgICAgJ3BvaW50ZXJ1cCcsXG4gICAgICAgICAgJ3RvdWNobW92ZScsXG4gICAgICAgICAgJ3RvdWNoc3RhcnQnLFxuICAgICAgICAgICd0b3VjaGVuZCdcbiAgICAgICAgXSxcbiAgICAgICAgZXZlbnQgPT4ge1xuICAgICAgICAgIGlmICgoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5ub2RlTmFtZT8udG9Mb3dlckNhc2UoKSAhPT0gJ2h0bWwnKSB7XG4gICAgICAgICAgICBoYWRLZXlib2FyZEV2ZW50UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgICAgIGV2ZW50U3Vic2NyaXB0aW9uLnBhdXNlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApLFxuICAgIFtoYWRLZXlib2FyZEV2ZW50UmVmXVxuICApO1xuXG4gIGNvbnN0IHNldEhhc0ZvY3VzVmlzaWJsZSA9IHVzZUNhbGxiYWNrKFxuICAgIG5leHRIYXNGb2N1c1Zpc2libGUgPT4ge1xuICAgICAgaWYgKGhhc0ZvY3VzVmlzaWJsZVJlZi5jdXJyZW50ICE9PSBuZXh0SGFzRm9jdXNWaXNpYmxlKSB7XG4gICAgICAgIGhhc0ZvY3VzVmlzaWJsZVJlZi5jdXJyZW50ID0gbmV4dEhhc0ZvY3VzVmlzaWJsZTtcbiAgICAgICAgbmV4dEhhc0ZvY3VzVmlzaWJsZSAmJiBvbkZvY3VzVmlzaWJsZVJlZj8uY3VycmVudCgpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW2hhc0ZvY3VzVmlzaWJsZVJlZiwgb25Gb2N1c1Zpc2libGVSZWZdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlS2V5RG93biA9IHVzZUNhbGxiYWNrKFxuICAgIChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50LmFsdEtleSB8fCBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQudGFyZ2V0ID09PSB0YXJnZXRSZWYuY3VycmVudCkge1xuICAgICAgICBzZXRIYXNGb2N1c1Zpc2libGUodHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIGhhZEtleWJvYXJkRXZlbnRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfSxcbiAgICBbaGFkS2V5Ym9hcmRFdmVudFJlZiwgc2V0SGFzRm9jdXNWaXNpYmxlLCB0YXJnZXRSZWZdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlUG9pbnRlckRvd24gPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgaGFkS2V5Ym9hcmRFdmVudFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gIH0sIFtoYWRLZXlib2FyZEV2ZW50UmVmXSk7XG5cbiAgY29uc3QgaGFuZGxlRm9jdXMgPSB1c2VDYWxsYmFjayhcbiAgICAoeyB0YXJnZXQgfTogRXZlbnQpID0+IHtcbiAgICAgIHRhcmdldCA9PT0gdGFyZ2V0UmVmLmN1cnJlbnQgJiZcbiAgICAgICAgKGhhZEtleWJvYXJkRXZlbnRSZWYuY3VycmVudCB8fCBmb2N1c1RyaWdnZXJzS2V5Ym9hcmRNb2RhbGl0eSh0YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkpICYmXG4gICAgICAgIHNldEhhc0ZvY3VzVmlzaWJsZSh0cnVlKTtcbiAgICB9LFxuICAgIFtoYWRLZXlib2FyZEV2ZW50UmVmLCBzZXRIYXNGb2N1c1Zpc2libGUsIHRhcmdldFJlZl1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVCbHVyID0gdXNlQ2FsbGJhY2soXG4gICAgKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gdGFyZ2V0UmVmLmN1cnJlbnQgJiYgaGFzRm9jdXNWaXNpYmxlUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgYmx1clNpbmNlUmVmLmN1cnJlbnQgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHNldEhhc0ZvY3VzVmlzaWJsZShmYWxzZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbYmx1clNpbmNlUmVmLCBEYXRlLCBoYXNGb2N1c1Zpc2libGVSZWYsIHNldEhhc0ZvY3VzVmlzaWJsZSwgdGFyZ2V0UmVmXVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZVZpc2liaWxpdHlDaGFuZ2UgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgaWYgKGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZSA9PT0gJ2hpZGRlbicpIHtcbiAgICAgIC8vIFRoZSBlbGVtZW50IGlzIGJsdXJyZWQgZHVlIHRvIFwidmlzaWJpbGl0eVN0YXRlXCIgc2V0IHRvIFwiaGlkZGVuXCIuXG4gICAgICAvLyAxMDBtcyBpcyByZWZlcmVuY2VkIGZyb20gdGhlIFdJQ0cgcG9seWZpbGwuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbWFnaWMtbnVtYmVyc1xuICAgICAgaWYgKERhdGUubm93KCkgLSBibHVyU2luY2VSZWYuY3VycmVudCA8IDEwMCkge1xuICAgICAgICBoYWRLZXlib2FyZEV2ZW50UmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBldmVudFN1YnNjcmlwdGlvbi5yZXN1bWUoKTtcbiAgICB9XG4gIH0sIFtibHVyU2luY2VSZWYsIERhdGUsIGV2ZW50U3Vic2NyaXB0aW9uLCBoYWRLZXlib2FyZEV2ZW50UmVmXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgaGFuZGxlS2V5RG93biwgdHJ1ZSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgaGFuZGxlUG9pbnRlckRvd24sIHRydWUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgaGFuZGxlUG9pbnRlckRvd24sIHRydWUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBoYW5kbGVQb2ludGVyRG93biwgdHJ1ZSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndmlzaWJpbGl0eWNoYW5nZScsIGhhbmRsZVZpc2liaWxpdHlDaGFuZ2UsIHRydWUpO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBoYW5kbGVLZXlEb3duKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGhhbmRsZVBvaW50ZXJEb3duKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgaGFuZGxlUG9pbnRlckRvd24pO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGhhbmRsZVBvaW50ZXJEb3duKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Zpc2liaWxpdHljaGFuZ2UnLCBoYW5kbGVWaXNpYmlsaXR5Q2hhbmdlKTtcbiAgICB9O1xuICB9LCBbaGFuZGxlS2V5RG93biwgaGFuZGxlUG9pbnRlckRvd24sIGhhbmRsZVZpc2liaWxpdHlDaGFuZ2VdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHsgY3VycmVudDogdGFyZ2V0IH0gPSB0YXJnZXRSZWY7XG5cbiAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIGhhbmRsZUJsdXIsIHRydWUpO1xuICAgIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIGhhbmRsZUZvY3VzLCB0cnVlKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmx1cicsIGhhbmRsZUJsdXIpO1xuICAgICAgdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgaGFuZGxlRm9jdXMpO1xuICAgIH07XG5cbiAgICAvLyBXZSBzcGVjaWZpY2FsbHkgYWRkIFwidGFyZ2V0UmVmLmN1cnJlbnRcIiBoZXJlLlxuICAgIC8vIElmIHRoZSB0YXJnZXQgZWxlbWVudCBjaGFuZ2VkLCB3ZSBzaG91bGQgcmVhdHRhY2ggb3VyIGV2ZW50IGxpc3RlbmVycy5cbiAgfSwgW2hhbmRsZUJsdXIsIGhhbmRsZUZvY3VzLCB0YXJnZXRSZWZdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGV2ZW50U3Vic2NyaXB0aW9uLnJlc3VtZSgpO1xuXG4gICAgcmV0dXJuICgpID0+IGV2ZW50U3Vic2NyaXB0aW9uLnBhdXNlKCk7XG4gIH0sIFtldmVudFN1YnNjcmlwdGlvbl0pO1xufVxuXG5mdW5jdGlvbiB1c2VPYnNlcnZlRm9jdXNWaXNpYmxlRm9yTW9kZXJuQnJvd3NlcnMoXG4gIHRhcmdldFJlZjogUmVmT2JqZWN0PEhUTUxFbGVtZW50PixcbiAgb25Gb2N1c1Zpc2libGVSZWY6IE11dGFibGVSZWZPYmplY3Q8KCkgPT4gdm9pZD5cbikge1xuICBjb25zdCBoYW5kbGVGb2N1cyA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBjb25zdCB7IGN1cnJlbnQgfSA9IHRhcmdldFJlZjtcblxuICAgIGlmIChcbiAgICAgIC8vIFwibXNNYXRjaGVzU2VsZWN0b3JcIiBpcyB2ZW5kb3ItcHJlZml4ZWQgdmVyc2lvbiBvZiBcIm1hdGNoZXNcIi5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkb3Qtbm90YXRpb25cbiAgICAgIChjdXJyZW50Lm1hdGNoZXMgfHwgKGN1cnJlbnRbJ21zTWF0Y2hlc1NlbGVjdG9yJ10gYXMgKHNlbGVjdG9yOiBzdHJpbmcpID0+IGJvb2xlYW4pKS5jYWxsKFxuICAgICAgICBjdXJyZW50LFxuICAgICAgICAnOmZvY3VzLXZpc2libGUnXG4gICAgICApXG4gICAgKSB7XG4gICAgICBvbkZvY3VzVmlzaWJsZVJlZj8uY3VycmVudCgpO1xuICAgIH1cbiAgfSwgW29uRm9jdXNWaXNpYmxlUmVmLCB0YXJnZXRSZWZdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHsgY3VycmVudDogdGFyZ2V0IH0gPSB0YXJnZXRSZWY7XG5cbiAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCBoYW5kbGVGb2N1cyk7XG5cbiAgICByZXR1cm4gKCkgPT4gdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgaGFuZGxlRm9jdXMpO1xuXG4gICAgLy8gV2Ugc3BlY2lmaWNhbGx5IGFkZCBcInRhcmdldFJlZi5jdXJyZW50XCIgaGVyZS5cbiAgICAvLyBJZiB0aGUgdGFyZ2V0IGVsZW1lbnQgY2hhbmdlZCwgd2Ugc2hvdWxkIHJlYXR0YWNoIG91ciBldmVudCBsaXN0ZW5lcnMuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCBbaGFuZGxlRm9jdXMsIHRhcmdldFJlZiwgdGFyZ2V0UmVmLmN1cnJlbnRdKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlT2JzZXJ2ZUZvY3VzVmlzaWJsZSh0YXJnZXRSZWY6IFJlZk9iamVjdDxIVE1MRWxlbWVudD4sIG9uRm9jdXNWaXNpYmxlOiAoKSA9PiB2b2lkKSB7XG4gIGNvbnN0IFtub25jZV0gPSB1c2VOb25jZSgpO1xuICBjb25zdCBvbkZvY3VzVmlzaWJsZVJlZiA9IHVzZVZhbHVlUmVmKG9uRm9jdXNWaXNpYmxlKTtcblxuICAvLyBUaGUgbm9uY2UgaXMgdXNlIGZvciBicm93c2VyIGNhcGFiaWxpdGllcy4gSnVzdCBpbiBjYXNlIHRoZSBcIm5vbmNlXCIgaGFkIGNoYW5nZWQgdW5leHBlY3RlZGx5LCB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSBicm93c2VyIHNob3VsZCBuZXZlciBjaGFuZ2UuXG4gIC8vIFRodXMsIHdlIGFyZSB1c2luZyBhbiBpbml0aWFsIHZlcnNpb24gb2YgXCJub25jZVwiLiBJbiBjYXNlIHdlYiBkZXZzIGNoYW5nZWQgdGhlIFwibm9uY2VcIiB0byBhbiBpbnZhbGlkIHZhbHVlLCB3ZSB3b24ndCBicmVhayBydWxlcyBvZiBob29rcyAoYXMgc3RhdGVkIGJlbG93KS5cbiAgY29uc3Qgbm9uY2VSZWYgPSB1c2VSZWYobm9uY2UpO1xuXG4gIC8vIFwiOmZvY3VzLXZpc2libGVcIiBzZWxlY3RvciBpcyBzdXBwb3J0ZWQgZnJvbSBDaHJvbWUvRWRnZSA4NisgYW5kIG5vdCBzdXBwb3J0ZWQgaW4gSUUxMSBvciBTYWZhcmkuXG4gIC8vIERvaW5nIGEgY2FwYWJpbGl0eSBjaGVjayBvbiBwc2V1ZG8gY2xhc3NlcyByZXF1aXJlcyBpbmplY3RpbmcgYSBzdHlsZXNoZWV0LCB0aHVzIG5vbmNlIGlzIG5lZWRlZC5cbiAgY29uc3Qgc3VwcG9ydEZvY3VzVmlzaWJsZSA9IHVzZU1lbW8oKCkgPT4gc3VwcG9ydFBzZXVkb0NsYXNzKCc6Zm9jdXMtdmlzaWJsZScsIG5vbmNlUmVmLmN1cnJlbnQpLCBbbm9uY2VSZWZdKTtcblxuICAvLyBTaW5jZSBcInN1cHBvcnRQc2V1ZG9DbGFzc1wiIGlzIGEgYnJvd3NlciBjYXBhYmlsaXR5LCB0aGUgcmVzdWx0IHNob3VsZCBiZSBjb25zdGFudCBkdXJpbmcgdGhlIHBhZ2UgbGlmZXRpbWUuXG4gIC8vIFRodXMsIHJ1bm5pbmcgaG9va3MgY29uZGl0aW9uYWxseSBpcyBva2F5IGhlcmUuXG4gIGlmIChzdXBwb3J0Rm9jdXNWaXNpYmxlKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL3J1bGVzLW9mLWhvb2tzXG4gICAgdXNlT2JzZXJ2ZUZvY3VzVmlzaWJsZUZvck1vZGVybkJyb3dzZXJzKHRhcmdldFJlZiwgb25Gb2N1c1Zpc2libGVSZWYpO1xuICB9IGVsc2Uge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9ydWxlcy1vZi1ob29rc1xuICAgIHVzZU9ic2VydmVGb2N1c1Zpc2libGVGb3JMZWdhY3lCcm93c2Vycyh0YXJnZXRSZWYsIG9uRm9jdXNWaXNpYmxlUmVmKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSx1QkFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsTUFBQSxHQUFBRCxPQUFBO0FBRUEsSUFBQUUsbUJBQUEsR0FBQUMsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFJLFVBQUEsR0FBQUQsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFLLFlBQUEsR0FBQUYsc0JBQUEsQ0FBQUgsT0FBQTtBQUF3QyxTQUFBRyx1QkFBQUcsR0FBQSxXQUFBQSxHQUFBLElBQUFBLEdBQUEsQ0FBQUMs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