UNPKG

botframework-webchat-component

Version:
491 lines (405 loc) 56.1 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.useTextBoxSubmit = useTextBoxSubmit; exports.useTextBoxValue = useTextBoxValue; exports.connectSendTextBox = exports.default = void 0; var _botframeworkWebchatApi = require("botframework-webchat-api"); var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireWildcard(require("react")); var _AccessibleInputText = _interopRequireDefault(require("../Utils/AccessibleInputText")); var _AutoResizeTextArea = _interopRequireDefault(require("./AutoResizeTextArea")); var _connectToWebChat = _interopRequireDefault(require("../connectToWebChat")); var _navigableEvent = _interopRequireDefault(require("../Utils/TypeFocusSink/navigableEvent")); var _useFocus = _interopRequireDefault(require("../hooks/useFocus")); var _useRegisterFocusSendBox = _interopRequireDefault(require("../hooks/internal/useRegisterFocusSendBox")); var _useReplaceEmoticon = _interopRequireDefault(require("../hooks/internal/useReplaceEmoticon")); var _useScrollDown = _interopRequireDefault(require("../hooks/useScrollDown")); var _useScrollToEnd = _interopRequireDefault(require("../hooks/useScrollToEnd")); var _useScrollUp = _interopRequireDefault(require("../hooks/useScrollUp")); var _useStyleSet3 = _interopRequireDefault(require("../hooks/useStyleSet")); var _useStyleToEmotionObject = _interopRequireDefault(require("../hooks/internal/useStyleToEmotionObject")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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) { _defineProperty(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; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return 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) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_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 useDisabled = _botframeworkWebchatApi.hooks.useDisabled, useLocalizer = _botframeworkWebchatApi.hooks.useLocalizer, useSendBoxValue = _botframeworkWebchatApi.hooks.useSendBoxValue, useStopDictate = _botframeworkWebchatApi.hooks.useStopDictate, useStyleOptions = _botframeworkWebchatApi.hooks.useStyleOptions, useSubmitSendBox = _botframeworkWebchatApi.hooks.useSubmitSendBox; var ROOT_STYLE = { '&.webchat__send-box-text-box': { display: 'flex', '& .webchat__send-box-text-box__input, & .webchat__send-box-text-box__text-area': { flex: 1 } } }; var connectSendTextBox = function connectSendTextBox() { for (var _len = arguments.length, selectors = new Array(_len), _key = 0; _key < _len; _key++) { selectors[_key] = arguments[_key]; } return _connectToWebChat.default.apply(void 0, [function (_ref) { var disabled = _ref.disabled, focusSendBox = _ref.focusSendBox, language = _ref.language, scrollToEnd = _ref.scrollToEnd, sendBoxValue = _ref.sendBoxValue, setSendBox = _ref.setSendBox, stopDictate = _ref.stopDictate, submitSendBox = _ref.submitSendBox; return { disabled: disabled, language: language, onChange: function onChange(_ref2) { var value = _ref2.target.value; setSendBox(value); stopDictate(); }, onKeyPress: function onKeyPress(event) { var key = event.key, shiftKey = event.shiftKey; if (key === 'Enter' && !shiftKey) { event.preventDefault(); if (sendBoxValue) { scrollToEnd(); submitSendBox(); focusSendBox(); } } }, onSubmit: function onSubmit(event) { event.preventDefault(); // Consider clearing the send box only after we received POST_ACTIVITY_PENDING // E.g. if the connection is bad, sending the message essentially do nothing but just clearing the send box if (sendBoxValue) { scrollToEnd(); submitSendBox(); } }, value: sendBoxValue }; }].concat(selectors)); }; exports.connectSendTextBox = connectSendTextBox; function useTextBoxSubmit() { var _useSendBoxValue = useSendBoxValue(), _useSendBoxValue2 = _slicedToArray(_useSendBoxValue, 1), sendBoxValue = _useSendBoxValue2[0]; var focus = (0, _useFocus.default)(); var scrollToEnd = (0, _useScrollToEnd.default)(); var submitSendBox = useSubmitSendBox(); return (0, _react.useCallback)(function (setFocus) { if (sendBoxValue) { scrollToEnd(); submitSendBox(); if (setFocus) { if (setFocus === true) { console.warn("\"botframework-webchat: Passing \"true\" to \"useTextBoxSubmit\" is deprecated and will be removed on or after 2022-04-23. Please pass \"sendBox\" instead.\""); focus('sendBox'); } else { focus(setFocus); } } } return !!sendBoxValue; }, [focus, scrollToEnd, sendBoxValue, submitSendBox]); } function useTextBoxValue() { var _useSendBoxValue3 = useSendBoxValue(), _useSendBoxValue4 = _slicedToArray(_useSendBoxValue3, 2), value = _useSendBoxValue4[0], setValue = _useSendBoxValue4[1]; var replaceEmoticon = (0, _useReplaceEmoticon.default)(); var stopDictate = useStopDictate(); var setter = (0, _react.useCallback)(function (nextValue) { var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, selectionEnd = _ref3.selectionEnd, selectionStart = _ref3.selectionStart; if (typeof nextValue !== 'string') { throw new Error('botframework-webchat: First argument passed to useTextBoxValue() must be a string.'); } // Currently, we cannot detect whether the change is due to clipboard paste or pressing a key on the keyboard. // We should not change to emoji when the user is pasting text. // We would assume, for a single character addition, the user must be pressing a key. if (nextValue.length === value.length + 1) { var _replaceEmoticon = replaceEmoticon({ selectionEnd: selectionEnd, selectionStart: selectionStart, value: nextValue }), nextSelectionEnd = _replaceEmoticon.selectionEnd, nextSelectionStart = _replaceEmoticon.selectionStart, nextValueWithEmoji = _replaceEmoticon.value; selectionEnd = nextSelectionEnd; selectionStart = nextSelectionStart; nextValue = nextValueWithEmoji; } setValue(nextValue); stopDictate(); return { selectionEnd: selectionEnd, selectionStart: selectionStart, value: nextValue }; }, [replaceEmoticon, setValue, stopDictate, value]); return [value, setter]; } var PREVENT_DEFAULT_HANDLER = function PREVENT_DEFAULT_HANDLER(event) { return event.preventDefault(); }; var TextBox = function TextBox(_ref4) { var className = _ref4.className; var _useSendBoxValue5 = useSendBoxValue(), _useSendBoxValue6 = _slicedToArray(_useSendBoxValue5, 2), setSendBox = _useSendBoxValue6[1]; var _useStyleSet = (0, _useStyleSet3.default)(), _useStyleSet2 = _slicedToArray(_useStyleSet, 1), sendBoxTextBoxStyleSet = _useStyleSet2[0].sendBoxTextBox; var _useStyleOptions = useStyleOptions(), _useStyleOptions2 = _slicedToArray(_useStyleOptions, 1), sendBoxTextWrap = _useStyleOptions2[0].sendBoxTextWrap; var _useDisabled = useDisabled(), _useDisabled2 = _slicedToArray(_useDisabled, 1), disabled = _useDisabled2[0]; var _useTextBoxValue = useTextBoxValue(), _useTextBoxValue2 = _slicedToArray(_useTextBoxValue, 2), textBoxValue = _useTextBoxValue2[0], setTextBoxValue = _useTextBoxValue2[1]; var inputElementRef = (0, _react.useRef)(); var localize = useLocalizer(); var placeCheckpointOnChangeRef = (0, _react.useRef)(false); var prevInputStateRef = (0, _react.useRef)(); var rootClassName = (0, _useStyleToEmotionObject.default)()(ROOT_STYLE) + ''; var scrollDown = (0, _useScrollDown.default)(); var scrollUp = (0, _useScrollUp.default)(); var submitTextBox = useTextBoxSubmit(); var undoStackRef = (0, _react.useRef)([]); var sendBoxString = localize('TEXT_INPUT_ALT'); var typeYourMessageString = localize('TEXT_INPUT_PLACEHOLDER'); var rememberInputState = (0, _react.useCallback)(function () { var _inputElementRef$curr = inputElementRef.current, selectionEnd = _inputElementRef$curr.selectionEnd, selectionStart = _inputElementRef$curr.selectionStart, value = _inputElementRef$curr.value; prevInputStateRef.current = { selectionEnd: selectionEnd, selectionStart: selectionStart, value: value }; }, [inputElementRef, prevInputStateRef]); // This is for TypeFocusSink. When the focus in on the script, then starting press "a", without this line, it would cause errors. // We call rememberInputState() when "onFocus" event is fired, but since this is from TypeFocusSink, we are not able to receive "onFocus" event before it happen. (0, _react.useEffect)(rememberInputState, [rememberInputState]); // This is for moving the selection while setting the send box value. // If we only use setSendBox, we will need to wait for the next render cycle to get the value in, before we can set selectionEnd/Start. var setSelectionRangeAndValue = (0, _react.useCallback)(function (_ref5) { var selectionEnd = _ref5.selectionEnd, selectionStart = _ref5.selectionStart, value = _ref5.value; if (inputElementRef.current) { // We need to set the value, before selectionStart/selectionEnd. inputElementRef.current.value = value; inputElementRef.current.selectionStart = selectionStart; inputElementRef.current.selectionEnd = selectionEnd; } setSendBox(value); }, [inputElementRef, setSendBox]); var handleChange = (0, _react.useCallback)(function (event) { var _event$target = event.target, selectionEnd = _event$target.selectionEnd, selectionStart = _event$target.selectionStart, value = _event$target.value; if (placeCheckpointOnChangeRef.current) { undoStackRef.current.push(_objectSpread({}, prevInputStateRef.current)); placeCheckpointOnChangeRef.current = false; } var nextInputState = setTextBoxValue(value, { selectionEnd: selectionEnd, selectionStart: selectionStart }); // If an emoticon is converted to emoji, place another checkpoint. if (nextInputState.value !== value) { undoStackRef.current.push({ selectionEnd: selectionEnd, selectionStart: selectionStart, value: value }); placeCheckpointOnChangeRef.current = true; setSelectionRangeAndValue(nextInputState); } }, [placeCheckpointOnChangeRef, prevInputStateRef, setSelectionRangeAndValue, setTextBoxValue, undoStackRef]); var handleFocus = (0, _react.useCallback)(function () { rememberInputState(); placeCheckpointOnChangeRef.current = true; }, [placeCheckpointOnChangeRef, rememberInputState]); var handleKeyDown = (0, _react.useCallback)(function (event) { var ctrlKey = event.ctrlKey, key = event.key, metaKey = event.metaKey; if ((ctrlKey || metaKey) && (key === 'Z' || key === 'z')) { event.preventDefault(); var poppedInputState = undoStackRef.current.pop(); if (poppedInputState) { prevInputStateRef.current = _objectSpread({}, poppedInputState); } else { prevInputStateRef.current = { selectionEnd: 0, selectionStart: 0, value: '' }; } setSelectionRangeAndValue(prevInputStateRef.current); } }, [prevInputStateRef, setSelectionRangeAndValue, undoStackRef]); var handleKeyPress = (0, _react.useCallback)(function (event) { var key = event.key, shiftKey = event.shiftKey; if (key === 'Enter' && !shiftKey) { event.preventDefault(); // If text box is submitted, focus on the send box submitTextBox('sendBox'); // After submit, we will clear the undo stack. undoStackRef.current = []; } }, [submitTextBox, undoStackRef]); var handleSelect = (0, _react.useCallback)(function (_ref6) { var _ref6$target = _ref6.target, selectionEnd = _ref6$target.selectionEnd, selectionStart = _ref6$target.selectionStart, value = _ref6$target.value; if (value === prevInputStateRef.current.value) { // When caret move, we should push to undo stack on change. placeCheckpointOnChangeRef.current = true; } prevInputStateRef.current = { selectionEnd: selectionEnd, selectionStart: selectionStart, value: value }; }, [placeCheckpointOnChangeRef, prevInputStateRef]); var handleSubmit = (0, _react.useCallback)(function (event) { event.preventDefault(); // Consider clearing the send box only after we received POST_ACTIVITY_PENDING // E.g. if the connection is bad, sending the message essentially do nothing but just clearing the send box submitTextBox(); // After submit, we will clear the undo stack. undoStackRef.current = []; }, [submitTextBox, undoStackRef]); var handleKeyDownCapture = (0, _react.useCallback)(function (event) { var ctrlKey = event.ctrlKey, metaKey = event.metaKey, shiftKey = event.shiftKey; if (ctrlKey || metaKey || shiftKey) { return; } // Navigable event means the end-user is focusing on an inputtable element, but it is okay to capture the arrow keys. if ((0, _navigableEvent.default)(event)) { var handled = true; switch (event.key) { case 'End': scrollDown({ displacement: Infinity }); break; case 'Home': scrollUp({ displacement: Infinity }); break; case 'PageDown': scrollDown(); break; case 'PageUp': scrollUp(); break; default: handled = false; break; } if (handled) { event.preventDefault(); event.stopPropagation(); } } }, [scrollDown, scrollUp]); var focusCallback = (0, _react.useCallback)(function () { var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, noKeyboard = _ref7.noKeyboard; var current = inputElementRef.current; if (current) { if (noKeyboard) { // To not activate the virtual keyboard while changing focus to an input, we will temporarily set it as read-only and flip it back. // https://stackoverflow.com/questions/7610758/prevent-iphone-default-keyboard-when-focusing-an-input/7610923 var readOnly = current.getAttribute('readonly'); current.setAttribute('readonly', 'readonly'); setTimeout(function () { var current = inputElementRef.current; if (current) { current.focus(); readOnly ? current.setAttribute('readonly', readOnly) : current.removeAttribute('readonly'); } }, 0); } else { current.focus(); } } }, [inputElementRef]); (0, _useRegisterFocusSendBox.default)(focusCallback); return /*#__PURE__*/_react.default.createElement("form", { "aria-disabled": disabled, className: (0, _classnames.default)('webchat__send-box-text-box', rootClassName, sendBoxTextBoxStyleSet + '', (className || '') + ''), onSubmit: disabled ? PREVENT_DEFAULT_HANDLER : handleSubmit }, !sendBoxTextWrap ? /*#__PURE__*/_react.default.createElement(_AccessibleInputText.default, { "aria-label": sendBoxString, className: "webchat__send-box-text-box__input", "data-id": "webchat-sendbox-input", disabled: disabled, enterKeyHint: "send", inputMode: "text", onChange: disabled ? undefined : handleChange, onFocus: disabled ? undefined : handleFocus, onKeyDown: disabled ? undefined : handleKeyDown, onKeyDownCapture: disabled ? undefined : handleKeyDownCapture, onKeyPress: disabled ? undefined : handleKeyPress, onSelect: disabled ? undefined : handleSelect, placeholder: typeYourMessageString, readOnly: disabled, ref: inputElementRef, type: "text", value: textBoxValue }) : /*#__PURE__*/_react.default.createElement(_AutoResizeTextArea.default, { "aria-label": sendBoxString, className: "webchat__send-box-text-box__text-area", "data-id": "webchat-sendbox-input", disabled: disabled, enterKeyHint: "send", inputMode: "text", onChange: disabled ? undefined : handleChange, onFocus: disabled ? undefined : handleFocus, onKeyDown: disabled ? undefined : handleKeyDown, onKeyDownCapture: disabled ? undefined : handleKeyDownCapture, onKeyPress: disabled ? undefined : handleKeyPress, onSelect: disabled ? undefined : handleSelect, placeholder: typeYourMessageString, readOnly: disabled, ref: inputElementRef, rows: "1", textAreaClassName: "webchat__send-box-text-box__html-text-area", value: textBoxValue }), disabled && /*#__PURE__*/_react.default.createElement("div", { className: "webchat__send-box-text-box__glass" })); }; TextBox.defaultProps = { className: '' }; TextBox.propTypes = { className: _propTypes.default.string }; var _default = TextBox; exports.default = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TZW5kQm94L1RleHRCb3guanMiXSwibmFtZXMiOlsidXNlRGlzYWJsZWQiLCJob29rcyIsInVzZUxvY2FsaXplciIsInVzZVNlbmRCb3hWYWx1ZSIsInVzZVN0b3BEaWN0YXRlIiwidXNlU3R5bGVPcHRpb25zIiwidXNlU3VibWl0U2VuZEJveCIsIlJPT1RfU1RZTEUiLCJkaXNwbGF5IiwiZmxleCIsImNvbm5lY3RTZW5kVGV4dEJveCIsInNlbGVjdG9ycyIsImNvbm5lY3RUb1dlYkNoYXQiLCJkaXNhYmxlZCIsImZvY3VzU2VuZEJveCIsImxhbmd1YWdlIiwic2Nyb2xsVG9FbmQiLCJzZW5kQm94VmFsdWUiLCJzZXRTZW5kQm94Iiwic3RvcERpY3RhdGUiLCJzdWJtaXRTZW5kQm94Iiwib25DaGFuZ2UiLCJ2YWx1ZSIsInRhcmdldCIsIm9uS2V5UHJlc3MiLCJldmVudCIsImtleSIsInNoaWZ0S2V5IiwicHJldmVudERlZmF1bHQiLCJvblN1Ym1pdCIsInVzZVRleHRCb3hTdWJtaXQiLCJmb2N1cyIsInNldEZvY3VzIiwiY29uc29sZSIsIndhcm4iLCJ1c2VUZXh0Qm94VmFsdWUiLCJzZXRWYWx1ZSIsInJlcGxhY2VFbW90aWNvbiIsInNldHRlciIsIm5leHRWYWx1ZSIsInNlbGVjdGlvbkVuZCIsInNlbGVjdGlvblN0YXJ0IiwiRXJyb3IiLCJsZW5ndGgiLCJuZXh0U2VsZWN0aW9uRW5kIiwibmV4dFNlbGVjdGlvblN0YXJ0IiwibmV4dFZhbHVlV2l0aEVtb2ppIiwiUFJFVkVOVF9ERUZBVUxUX0hBTkRMRVIiLCJUZXh0Qm94IiwiY2xhc3NOYW1lIiwic2VuZEJveFRleHRCb3hTdHlsZVNldCIsInNlbmRCb3hUZXh0Qm94Iiwic2VuZEJveFRleHRXcmFwIiwidGV4dEJveFZhbHVlIiwic2V0VGV4dEJveFZhbHVlIiwiaW5wdXRFbGVtZW50UmVmIiwibG9jYWxpemUiLCJwbGFjZUNoZWNrcG9pbnRPbkNoYW5nZVJlZiIsInByZXZJbnB1dFN0YXRlUmVmIiwicm9vdENsYXNzTmFtZSIsInNjcm9sbERvd24iLCJzY3JvbGxVcCIsInN1Ym1pdFRleHRCb3giLCJ1bmRvU3RhY2tSZWYiLCJzZW5kQm94U3RyaW5nIiwidHlwZVlvdXJNZXNzYWdlU3RyaW5nIiwicmVtZW1iZXJJbnB1dFN0YXRlIiwiY3VycmVudCIsInNldFNlbGVjdGlvblJhbmdlQW5kVmFsdWUiLCJoYW5kbGVDaGFuZ2UiLCJwdXNoIiwibmV4dElucHV0U3RhdGUiLCJoYW5kbGVGb2N1cyIsImhhbmRsZUtleURvd24iLCJjdHJsS2V5IiwibWV0YUtleSIsInBvcHBlZElucHV0U3RhdGUiLCJwb3AiLCJoYW5kbGVLZXlQcmVzcyIsImhhbmRsZVNlbGVjdCIsImhhbmRsZVN1Ym1pdCIsImhhbmRsZUtleURvd25DYXB0dXJlIiwiaGFuZGxlZCIsImRpc3BsYWNlbWVudCIsIkluZmluaXR5Iiwic3RvcFByb3BhZ2F0aW9uIiwiZm9jdXNDYWxsYmFjayIsIm5vS2V5Ym9hcmQiLCJyZWFkT25seSIsImdldEF0dHJpYnV0ZSIsInNldEF0dHJpYnV0ZSIsInNldFRpbWVvdXQiLCJyZW1vdmVBdHRyaWJ1dGUiLCJ1bmRlZmluZWQiLCJkZWZhdWx0UHJvcHMiLCJwcm9wVHlwZXMiLCJQcm9wVHlwZXMiLCJzdHJpbmciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBRVFBLFcsR0FBa0dDLDZCLENBQWxHRCxXO0lBQWFFLFksR0FBcUZELDZCLENBQXJGQyxZO0lBQWNDLGUsR0FBdUVGLDZCLENBQXZFRSxlO0lBQWlCQyxjLEdBQXNESCw2QixDQUF0REcsYztJQUFnQkMsZSxHQUFzQ0osNkIsQ0FBdENJLGU7SUFBaUJDLGdCLEdBQXFCTCw2QixDQUFyQkssZ0I7QUFFckYsSUFB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QVEsRUFBRWpFLFFBQVEsR0FBR2dGLFNBQUgsR0FBZWQsWUFabkM7QUFhRSxJQUFBLFdBQVcsRUFBRWQscUJBYmY7QUFjRSxJQUFBLFFBQVEsRUFBRXBELFFBZFo7QUFlRSxJQUFBLEdBQUcsRUFBRTBDLGVBZlA7QUFnQkUsSUFBQSxJQUFJLEVBQUMsR0FoQlA7QUFpQkUsSUFBQSxpQkFBaUIsRUFBQyw0Q0FqQnBCO0FBa0JFLElBQUEsS0FBSyxFQUFFRjtBQWxCVCxJQS9CSixFQW9ER3hDLFFBQVEsaUJBQUk7QUFBSyxJQUFBLFNBQVMsRUFBQztBQUFmLElBcERmLENBREY7QUF3REQsQ0FqUkQ7O0FBbVJBbUMsT0FBTyxDQUFDOEMsWUFBUixHQUF1QjtBQUNyQjdDLEVBQUFBLFNBQVMsRUFBRTtBQURVLENBQXZCO0FBSUFELE9BQU8sQ0FBQytDLFNBQVIsR0FBb0I7QUFDbEI5QyxFQUFBQSxTQUFTLEVBQUUrQyxtQkFBVUM7QUFESCxDQUFwQjtlQUllakQsTyIsInNvdXJjZVJvb3QiOiJjb21wb25lbnQ6Ly8vIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaG9va3MgfSBmcm9tICdib3RmcmFtZXdvcmstd2ViY2hhdC1hcGknO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuaW1wb3J0IFJlYWN0LCB7IHVzZUNhbGxiYWNrLCB1c2VFZmZlY3QsIHVzZVJlZiB9IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IEFjY2Vzc2libGVJbnB1dFRleHQgZnJvbSAnLi4vVXRpbHMvQWNjZXNzaWJsZUlucHV0VGV4dCc7XG5pbXBvcnQgQXV0b1Jlc2l6ZVRleHRBcmVhIGZyb20gJy4vQXV0b1Jlc2l6ZVRleHRBcmVhJztcbmltcG9ydCBjb25uZWN0VG9XZWJDaGF0IGZyb20gJy4uL2Nvbm5lY3RUb1dlYkNoYXQnO1xuaW1wb3J0IG5hdmlnYWJsZUV2ZW50IGZyb20gJy4uL1V0aWxzL1R5cGVGb2N1c1NpbmsvbmF2aWdhYmxlRXZlbnQnO1xuaW1wb3J0IHVzZUZvY3VzIGZyb20gJy4uL2hvb2tzL3VzZUZvY3VzJztcbmltcG9ydCB1c2VSZWdpc3RlckZvY3VzU2VuZEJveCBmcm9tICcuLi9ob29rcy9pbnRlcm5hbC91c2VSZWdpc3RlckZvY3VzU2VuZEJveCc7XG5pbXBvcnQgdXNlUmVwbGFjZUVtb3RpY29uIGZyb20gJy4uL2hvb2tzL2ludGVybmFsL3VzZVJlcGxhY2VFbW90aWNvbic7XG5pbXBvcnQgdXNlU2Nyb2xsRG93biBmcm9tICcuLi9ob29rcy91c2VTY3JvbGxEb3duJztcbmltcG9ydCB1c2VTY3JvbGxUb0VuZCBmcm9tICcuLi9ob29rcy91c2VTY3JvbGxUb0VuZCc7XG5pbXBvcnQgdXNlU2Nyb2xsVXAgZnJvbSAnLi4vaG9va3MvdXNlU2Nyb2xsVXAnO1xuaW1wb3J0IHVzZVN0eWxlU2V0IGZyb20gJy4uL2hvb2tzL3VzZVN0eWxlU2V0JztcbmltcG9ydCB1c2VTdHlsZVRvRW1vdGlvbk9iamVjdCBmcm9tICcuLi9ob29rcy9pbnRlcm5hbC91c2VTdHlsZVRvRW1vdGlvbk9iamVjdCc7XG5cbmNvbnN0IHsgdXNlRGlzYWJsZWQsIHVzZUxvY2FsaXplciwgdXNlU2VuZEJveFZhbHVlLCB1c2VTdG9wRGljdGF0ZSwgdXNlU3R5bGVPcHRpb25zLCB1c2VTdWJtaXRTZW5kQm94IH0gPSBob29rcztcblxuY29uc3QgUk9PVF9TVFlMRSA9IHtcbiAgJyYud2ViY2hhdF9fc2VuZC1ib3gtdGV4dC1ib3gnOiB7XG4gICAgZGlzcGxheTogJ2ZsZXgnLFxuXG4gICAgJyYgLndlYmNoYXRfX3NlbmQtYm94LXRleHQtYm94X19pbnB1dCwgJiAud2ViY2hhdF9fc2VuZC1ib3gtdGV4dC1ib3hfX3RleHQtYXJlYSc6IHtcbiAgICAgIGZsZXg6IDFcbiAgICB9XG4gIH1cbn07XG5cbmNvbnN0IGNvbm5lY3RTZW5kVGV4dEJveCA9ICguLi5zZWxlY3RvcnMpID0+XG4gIGNvbm5lY3RUb1dlYkNoYXQoXG4gICAgKHsgZGlzYWJsZWQsIGZvY3VzU2VuZEJveCwgbGFuZ3VhZ2UsIHNjcm9sbFRvRW5kLCBzZW5kQm94VmFsdWUsIHNldFNlbmRCb3gsIHN0b3BEaWN0YXRlLCBzdWJtaXRTZW5kQm94IH0pID0+ICh7XG4gICAgICBkaXNhYmxlZCxcbiAgICAgIGxhbmd1YWdlLFxuICAgICAgb25DaGFuZ2U6ICh7IHRhcmdldDogeyB2YWx1ZSB9IH0pID0+IHtcbiAgICAgICAgc2V0U2VuZEJveCh2YWx1ZSk7XG4gICAgICAgIHN0b3BEaWN0YXRlKCk7XG4gICAgICB9LFxuICAgICAgb25LZXlQcmVzczogZXZlbnQgPT4ge1xuICAgICAgICBjb25zdCB7IGtleSwgc2hpZnRLZXkgfSA9IGV2ZW50O1xuXG4gICAgICAgIGlmIChrZXkgPT09ICdFbnRlcicgJiYgIXNoaWZ0S2V5KSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgIGlmIChzZW5kQm94VmFsdWUpIHtcbiAgICAgICAgICAgIHNjcm9sbFRvRW5kKCk7XG4gICAgICAgICAgICBzdWJtaXRTZW5kQm94KCk7XG4gICAgICAgICAgICBmb2N1c1NlbmRCb3goKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvblN1Ym1pdDogZXZlbnQgPT4ge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIC8vIENvbnNpZGVyIGNsZWFyaW5nIHRoZSBzZW5kIGJveCBvbmx5IGFmdGVyIHdlIHJlY2VpdmVkIFBPU1RfQUNUSVZJVFlfUEVORElOR1xuICAgICAgICAvLyBFLmcuIGlmIHRoZSBjb25uZWN0aW9uIGlzIGJhZCwgc2VuZGluZyB0aGUgbWVzc2FnZSBlc3NlbnRpYWxseSBkbyBub3RoaW5nIGJ1dCBqdXN0IGNsZWFyaW5nIHRoZSBzZW5kIGJveFxuXG4gICAgICAgIGlmIChzZW5kQm94VmFsdWUpIHtcbiAgICAgICAgICBzY3JvbGxUb0VuZCgpO1xuICAgICAgICAgIHN1Ym1pdFNlbmRCb3goKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHZhbHVlOiBzZW5kQm94VmFsdWVcbiAgICB9KSxcbiAgICAuLi5zZWxlY3RvcnNcbiAgKTtcblxuZnVuY3Rpb24gdXNlVGV4dEJveFN1Ym1pdCgpIHtcbiAgY29uc3QgW3NlbmRCb3hWYWx1ZV0gPSB1c2VTZW5kQm94VmFsdWUoKTtcbiAgY29uc3QgZm9jdXMgPSB1c2VGb2N1cygpO1xuICBjb25zdCBzY3JvbGxUb0VuZCA9IHVzZVNjcm9sbFRvRW5kKCk7XG4gIGNvbnN0IHN1Ym1pdFNlbmRCb3ggPSB1c2VTdWJtaXRTZW5kQm94KCk7XG5cbiAgcmV0dXJuIHVzZUNhbGxiYWNrKFxuICAgIHNldEZvY3VzID0+IHtcbiAgICAgIGlmIChzZW5kQm94VmFsdWUpIHtcbiAgICAgICAgc2Nyb2xsVG9FbmQoKTtcbiAgICAgICAgc3VibWl0U2VuZEJveCgpO1xuXG4gICAgICAgIGlmIChzZXRGb2N1cykge1xuICAgICAgICAgIGlmIChzZXRGb2N1cyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBgXCJib3RmcmFtZXdvcmstd2ViY2hhdDogUGFzc2luZyBcInRydWVcIiB0byBcInVzZVRleHRCb3hTdWJtaXRcIiBpcyBkZXByZWNhdGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgb24gb3IgYWZ0ZXIgMjAyMi0wNC0yMy4gUGxlYXNlIHBhc3MgXCJzZW5kQm94XCIgaW5zdGVhZC5cImBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGZvY3VzKCdzZW5kQm94Jyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvY3VzKHNldEZvY3VzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuICEhc2VuZEJveFZhbHVlO1xuICAgIH0sXG4gICAgW2ZvY3VzLCBzY3JvbGxUb0VuZCwgc2VuZEJveFZhbHVlLCBzdWJtaXRTZW5kQm94XVxuICApO1xufVxuXG5mdW5jdGlvbiB1c2VUZXh0Qm94VmFsdWUoKSB7XG4gIGNvbnN0IFt2YWx1ZSwgc2V0VmFsdWVdID0gdXNlU2VuZEJveFZhbHVlKCk7XG4gIGNvbnN0IHJlcGxhY2VFbW90aWNvbiA9IHVzZVJlcGxhY2VFbW90aWNvbigpO1xuICBjb25zdCBzdG9wRGljdGF0ZSA9IHVzZVN0b3BEaWN0YXRlKCk7XG5cbiAgY29uc3Qgc2V0dGVyID0gdXNlQ2FsbGJhY2soXG4gICAgKG5leHRWYWx1ZSwgeyBzZWxlY3Rpb25FbmQsIHNlbGVjdGlvblN0YXJ0IH0gPSB7fSkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiBuZXh0VmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYm90ZnJhbWV3b3JrLXdlYmNoYXQ6IEZpcnN0IGFyZ3VtZW50IHBhc3NlZCB0byB1c2VUZXh0Qm94VmFsdWUoKSBtdXN0IGJlIGEgc3RyaW5nLicpO1xuICAgICAgfVxuXG4gICAgICAvLyBDdXJyZW50bHksIHdlIGNhbm5vdCBkZXRlY3Qgd2hldGhlciB0aGUgY2hhbmdlIGlzIGR1ZSB0byBjbGlwYm9hcmQgcGFzdGUgb3IgcHJlc3NpbmcgYSBrZXkgb24gdGhlIGtleWJvYXJkLlxuICAgICAgLy8gV2Ugc2hvdWxkIG5vdCBjaGFuZ2UgdG8gZW1vamkgd2hlbiB0aGUgdXNlciBpcyBwYXN0aW5nIHRleHQuXG4gICAgICAvLyBXZSB3b3VsZCBhc3N1bWUsIGZvciBhIHNpbmdsZSBjaGFyYWN0ZXIgYWRkaXRpb24sIHRoZSB1c2VyIG11c3QgYmUgcHJlc3NpbmcgYSBrZXkuXG4gICAgICBpZiAobmV4dFZhbHVlLmxlbmd0aCA9PT0gdmFsdWUubGVuZ3RoICsgMSkge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgc2VsZWN0aW9uRW5kOiBuZXh0U2VsZWN0aW9uRW5kLFxuICAgICAgICAgIHNlbGVjdGlvblN0YXJ0OiBuZXh0U2VsZWN0aW9uU3RhcnQsXG4gICAgICAgICAgdmFsdWU6IG5leHRWYWx1ZVdpdGhFbW9qaVxuICAgICAgICB9ID0gcmVwbGFjZUVtb3RpY29uKHsgc2VsZWN0aW9uRW5kLCBzZWxlY3Rpb25TdGFydCwgdmFsdWU6IG5leHRWYWx1ZSB9KTtcblxuICAgICAgICBzZWxlY3Rpb25FbmQgPSBuZXh0U2VsZWN0aW9uRW5kO1xuICAgICAgICBzZWxlY3Rpb25TdGFydCA9IG5leHRTZWxlY3Rpb25TdGFydDtcbiAgICAgICAgbmV4dFZhbHVlID0gbmV4dFZhbHVlV2l0aEVtb2ppO1xuICAgICAgfVxuXG4gICAgICBzZXRWYWx1ZShuZXh0VmFsdWUpO1xuICAgICAgc3RvcERpY3RhdGUoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2VsZWN0aW9uRW5kLFxuICAgICAgICBzZWxlY3Rpb25TdGFydCxcbiAgICAgICAgdmFsdWU6IG5leHRWYWx1ZVxuICAgICAgfTtcbiAgICB9LFxuICAgIFtyZXBsYWNlRW1vdGljb24sIHNldFZhbHVlLCBzdG9wRGljdGF0ZSwgdmFsdWVdXG4gICk7XG5cbiAgcmV0dXJuIFt2YWx1ZSwgc2V0dGVyXTtcbn1cblxuY29uc3QgUFJFVkVOVF9ERUZBVUxUX0hBTkRMRVIgPSBldmVudCA9PiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG5jb25zdCBUZXh0Qm94ID0gKHsgY2xhc3NOYW1lIH0pID0+IHtcbiAgY29uc3QgWywgc2V0U2VuZEJveF0gPSB1c2VTZW5kQm94VmFsdWUoKTtcbiAgY29uc3QgW3sgc2VuZEJveFRleHRCb3g6IHNlbmRCb3hUZXh0Qm94U3R5bGVTZXQgfV0gPSB1c2VTdHlsZVNldCgpO1xuICBjb25zdCBbeyBzZW5kQm94VGV4dFdyYXAgfV0gPSB1c2VTdHlsZU9wdGlvbnMoKTtcbiAgY29uc3QgW2Rpc2FibGVkXSA9IHVzZURpc2FibGVkKCk7XG4gIGNvbnN0IFt0ZXh0Qm94VmFsdWUsIHNldFRleHRCb3hWYWx1ZV0gPSB1c2VUZXh0Qm94VmFsdWUoKTtcbiAgY29uc3QgaW5wdXRFbGVtZW50UmVmID0gdXNlUmVmKCk7XG4gIGNvbnN0IGxvY2FsaXplID0gdXNlTG9jYWxpemVyKCk7XG4gIGNvbnN0IHBsYWNlQ2hlY2twb2ludE9uQ2hhbmdlUmVmID0gdXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgcHJldklucHV0U3RhdGVSZWYgPSB1c2VSZWYoKTtcbiAgY29uc3Qgcm9vdENsYXNzTmFtZSA9IHVzZVN0eWxlVG9FbW90aW9uT2JqZWN0KCkoUk9PVF9TVFlMRSkgKyAnJztcbiAgY29uc3Qgc2Nyb2xsRG93biA9IHVzZVNjcm9sbERvd24oKTtcbiAgY29uc3Qgc2Nyb2xsVXAgPSB1c2VTY3JvbGxVcCgpO1xuICBjb25zdCBzdWJtaXRUZXh0Qm94ID0gdXNlVGV4dEJveFN1Ym1pdCgpO1xuICBjb25zdCB1bmRvU3RhY2tSZWYgPSB1c2VSZWYoW10pO1xuXG4gIGNvbnN0IHNlbmRCb3hTdHJpbmcgPSBsb2NhbGl6ZSgnVEVYVF9JTlBVVF9BTFQnKTtcbiAgY29uc3QgdHlwZVlvdXJNZXNzYWdlU3RyaW5nID0gbG9jYWxpemUoJ1RFWFRfSU5QVVRfUExBQ0VIT0xERVInKTtcblxuICBjb25zdCByZW1lbWJlcklucHV0U3RhdGUgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgY3VycmVudDogeyBzZWxlY3Rpb25FbmQsIHNlbGVjdGlvblN0YXJ0LCB2YWx1ZSB9XG4gICAgfSA9IGlucHV0RWxlbWVudFJlZjtcblxuICAgIHByZXZJbnB1dFN0YXRlUmVmLmN1cnJlbnQgPSB7IHNlbGVjdGlvbkVuZCwgc2VsZWN0aW9uU3RhcnQsIHZhbHVlIH07XG4gIH0sIFtpbnB1dEVsZW1lbnRSZWYsIHByZXZJbnB1dFN0YXRlUmVmXSk7XG5cbiAgLy8gVGhpcyBpcyBmb3IgVHlwZUZvY3VzU2luay4gV2hlbiB0aGUgZm9jdXMgaW4gb24gdGhlIHNjcmlwdCwgdGhlbiBzdGFydGluZyBwcmVzcyBcImFcIiwgd2l0aG91dCB0aGlzIGxpbmUsIGl0IHdvdWxkIGNhdXNlIGVycm9ycy5cbiAgLy8gV2UgY2FsbCByZW1lbWJlcklucHV0U3RhdGUoKSB3aGVuIFwib25Gb2N1c1wiIGV2ZW50IGlzIGZpcmVkLCBidXQgc2luY2UgdGhpcyBpcyBmcm9tIFR5cGVGb2N1c1NpbmssIHdlIGFyZSBub3QgYWJsZSB0byByZWNlaXZlIFwib25Gb2N1c1wiIGV2ZW50IGJlZm9yZSBpdCBoYXBwZW4uXG4gIHVzZUVmZmVjdChyZW1lbWJlcklucHV0U3RhdGUsIFtyZW1lbWJlcklucHV0U3RhdGVdKTtcblxuICAvLyBUaGlzIGlzIGZvciBtb3ZpbmcgdGhlIHNlbGVjdGlvbiB3aGlsZSBzZXR0aW5nIHRoZSBzZW5kIGJveCB2YWx1ZS5cbiAgLy8gSWYgd2Ugb25seSB1c2Ugc2V0U2VuZEJveCwgd2Ugd2lsbCBuZWVkIHRvIHdhaXQgZm9yIHRoZSBuZXh0IHJlbmRlciBjeWNsZSB0byBnZXQgdGhlIHZhbHVlIGluLCBiZWZvcmUgd2UgY2FuIHNldCBzZWxlY3Rpb25FbmQvU3RhcnQuXG4gIGNvbnN0IHNldFNlbGVjdGlvblJhbmdlQW5kVmFsdWUgPSB1c2VDYWxsYmFjayhcbiAgICAoeyBzZWxlY3Rpb25FbmQsIHNlbGVjdGlvblN0YXJ0LCB2YWx1ZSB9KSA9PiB7XG4gICAgICBpZiAoaW5wdXRFbGVtZW50UmVmLmN1cnJlbnQpIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBzZXQgdGhlIHZhbHVlLCBiZWZvcmUgc2VsZWN0aW9uU3RhcnQvc2VsZWN0aW9uRW5kLlxuICAgICAgICBpbnB1dEVsZW1lbnRSZWYuY3VycmVudC52YWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgIGlucHV0RWxlbWVudFJlZi5jdXJyZW50LnNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQ7XG4gICAgICAgIGlucHV0RWxlbWVudFJlZi5jdXJyZW50LnNlbGVjdGlvbkVuZCA9IHNlbGVjdGlvbkVuZDtcbiAgICAgIH1cblxuICAgICAgc2V0U2VuZEJveCh2YWx1ZSk7XG4gICAgfSxcbiAgICBbaW5wdXRFbGVtZW50UmVmLCBzZXRTZW5kQm94XVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZUNoYW5nZSA9IHVzZUNhbGxiYWNrKFxuICAgIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgdGFyZ2V0OiB7IHNlbGVjdGlvbkVuZCwgc2VsZWN0aW9uU3RhcnQsIHZhbHVlIH1cbiAgICAgIH0gPSBldmVudDtcblxuICAgICAgaWYgKHBsYWNlQ2hlY2twb2ludE9uQ2hhbmdlUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgdW5kb1N0YWNrUmVmLmN1cnJlbnQucHVzaCh7IC4uLnByZXZJbnB1dFN0YXRlUmVmLmN1cnJlbnQgfSk7XG5cbiAgICAgICAgcGxhY2VDaGVja3BvaW50T25DaGFuZ2VSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXh0SW5wdXRTdGF0ZSA9IHNldFRleHRCb3hWYWx1ZSh2YWx1ZSwgeyBzZWxlY3Rpb25FbmQsIHNlbGVjdGlvblN0YXJ0IH0pO1xuXG4gICAgICAvLyBJZiBhbiBlbW90aWNvbiBpcyBjb252ZXJ0ZWQgdG8gZW1vamksIHBsYWNlIGFub3RoZXIgY2hlY2twb2ludC5cbiAgICAgIGlmIChuZXh0SW5wdXRTdGF0ZS52YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgdW5kb1N0YWNrUmVmLmN1cnJlbnQucHVzaCh7IHNlbGVjdGlvbkVuZCwgc2VsZWN0aW9uU3RhcnQsIHZhbHVlIH0pO1xuXG4gICAgICAgIHBsYWNlQ2hlY2twb2ludE9uQ2hhbmdlUmVmLmN1cnJlbnQgPSB0cnVlO1xuXG4gICAgICAgIHNldFNlbGVjdGlvblJhbmdlQW5kVmFsdWUobmV4dElucHV0U3RhdGUpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW3BsYWNlQ2hlY2twb2ludE9uQ2hhbmdlUmVmLCBwcmV2SW5wdXRTdGF0ZVJlZiwgc2V0U2VsZWN0aW9uUmFuZ2VBbmRWYWx1ZSwgc2V0VGV4dEJveFZhbHVlLCB1bmRvU3RhY2tSZWZdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlRm9jdXMgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgcmVtZW1iZXJJbnB1dFN0YXRlKCk7XG5cbiAgICBwbGFjZUNoZWNrcG9pbnRPbkNoYW5nZVJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgfSwgW3BsYWNlQ2hlY2twb2ludE9uQ2hhbmdlUmVmLCByZW1lbWJlcklucHV0U3RhdGVdKTtcblxuICBjb25zdCBoYW5kbGVLZXlEb3duID0gdXNlQ2FsbGJhY2soXG4gICAgZXZlbnQgPT4ge1xuICAgICAgY29uc3QgeyBjdHJsS2V5LCBrZXksIG1ldGFLZXkgfSA9IGV2ZW50O1xuXG4gICAgICBpZiAoKGN0cmxLZXkgfHwgbWV0YUtleSkgJiYgKGtleSA9PT0gJ1onIHx8IGtleSA9PT0gJ3onKSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGNvbnN0IHBvcHBlZElucHV0U3RhdGUgPSB1bmRvU3RhY2tSZWYuY3VycmVudC5wb3AoKTtcblxuICAgICAgICBpZiAocG9wcGVkSW5wdXRTdGF0ZSkge1xuICAgICAgICAgIHByZXZJbnB1dFN0YXRlUmVmLmN1cnJlbnQgPSB7IC4uLnBvcHBlZElucHV0U3RhdGUgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2SW5wdXRTdGF0ZVJlZi5jdXJyZW50ID0geyBzZWxlY3Rpb25FbmQ6IDAsIHNlbGVjdGlvblN0YXJ0OiAwLCB2YWx1ZTogJycgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldFNlbGVjdGlvblJhbmdlQW5kVmFsdWUocHJldklucHV0U3RhdGVSZWYuY3VycmVudCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbcHJldklucHV0U3RhdGVSZWYsIHNldFNlbGVjdGlvblJhbmdlQW5kVmFsdWUsIHVuZG9TdGFja1JlZl1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVLZXlQcmVzcyA9IHVzZUNhbGxiYWNrKFxuICAgIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IHsga2V5LCBzaGlmdEtleSB9ID0gZXZlbnQ7XG5cbiAgICAgIGlmIChrZXkgPT09ICdFbnRlcicgJiYgIXNoaWZ0S2V5KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgLy8gSWYgdGV4dCBib3ggaXMgc3VibWl0dGVkLCBmb2N1cyBvbiB0aGUgc2VuZCBib3hcbiAgICAgICAgc3VibWl0VGV4dEJveCgnc2VuZEJveCcpO1xuXG4gICAgICAgIC8vIEFmdGVyIHN1Ym1pdCwgd2Ugd2lsbCBjbGVhciB0aGUgdW5kbyBzdGFjay5cbiAgICAgICAgdW5kb1N0YWNrUmVmLmN1cnJlbnQgPSBbXTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtzdWJtaXRUZXh0Qm94LCB1bmRvU3RhY2tSZWZdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlU2VsZWN0ID0gdXNlQ2FsbGJhY2soXG4gICAgKHsgdGFyZ2V0OiB7IHNlbGVjdGlvbkVuZCwgc2VsZWN0aW9uU3RhcnQsIHZhbHVlIH0gfSkgPT4ge1xuICAgICAgaWYgKHZhbHVlID09PSBwcmV2SW5wdXRTdGF0ZVJlZi5jdXJyZW50LnZhbHVlKSB7XG4gICAgICAgIC8vIFdoZW4gY2FyZXQgbW92ZSwgd2Ugc2hvdWxkIHB1c2ggdG8gdW5kbyBzdGFjayBvbiBjaGFuZ2UuXG4gICAgICAgIHBsYWNlQ2hlY2twb2ludE9uQ2hhbmdlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBwcmV2SW5wdXRTdGF0ZVJlZi5jdXJyZW50ID0geyBzZWxlY3Rpb25FbmQsIHNlbGVjdGlvblN0YXJ0LCB2YWx1ZSB9O1xuICAgIH0sXG4gICAgW3BsYWNlQ2hlY2twb2ludE9uQ2hhbmdlUmVmLCBwcmV2SW5wdXRTdGF0ZVJlZl1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVTdWJtaXQgPSB1c2VDYWxsYmFjayhcbiAgICBldmVudCA9PiB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAvLyBDb25zaWRlciBjbGVhcmluZyB0aGUgc2VuZCBib3ggb25seSBhZnRlciB3ZSByZWNlaXZlZCBQT1NUX0FDVElWSVRZX1BFTkRJTkdcbiAgICAgIC8vIEUuZy4gaWYgdGhlIGNvbm5lY3Rpb24gaXMgYmFk